Search code examples
web-servicescxfonvifws-discovery

WS-Discovery with Apache CXF. How to specify device type?


I'm going to use Apache CXF for ONVIF-compatible ip camera service. It uses WS-Discovery to find devices and services and cxf supports it out-of-box:

The cxf-services-ws-discovery-service jar will register a ServerLifecyleListener that will automatically publish the "Hello" messages. It will also respond to any Probe requests that match the services it has published.

How will cxf detect device type to send in ProbeMatches response? How can i specify that my device is ip camera (i need to set concrete device type in ProbeMatches response, NetworkVideoTransmitter for example)?


Solution

  • After looking into CXF source code (WSDiscoveryServiceImpl class) i've found the answer:

    public ProbeMatchesType handleProbe(ProbeType pt) {
            List<HelloType> consider = new LinkedList<HelloType>(registered);
            //step one, consider the "types"
            //ALL types in the probe must be in the registered type
            if (pt.getTypes() != null && !pt.getTypes().isEmpty()) {
                ListIterator<HelloType> cit = consider.listIterator();
                while (cit.hasNext()) {
                    HelloType ht = cit.next();
                    boolean matches = true;
                    for (QName qn : pt.getTypes()) {
                        if (!ht.getTypes().contains(qn)) {
                            matches = false;
                        }
                    }
                    if (!matches) {
                        cit.remove();
                    }
                }
            }
            //next, consider the scopes
            matchScopes(pt, consider);
    
            if (consider.isEmpty()) {
                return null;
            }
            ProbeMatchesType pmt = new ProbeMatchesType();
            for (HelloType ht : consider) {
                ProbeMatchType m = new ProbeMatchType();
                m.setEndpointReference(ht.getEndpointReference());
                m.setScopes(ht.getScopes());
                m.setMetadataVersion(ht.getMetadataVersion());
                m.getTypes().addAll(ht.getTypes());
                m.getXAddrs().addAll(ht.getXAddrs());
                pmt.getProbeMatch().add(m);
            }
            return pmt;
        }
    

    In brief - it iterates published services and compares QNames. If searched qname is found in published it's added into ProbeMatch. So i should implement and publish service with needed QName to fix it.