Menu

getting device endpoint reference of the device that fired an event

Help
Martin
2014-03-02
2014-03-10
  • Martin

    Martin - 2014-03-02

    Hi everyone,

    I try to write a client that receives events from several event sources. At programming time I do not know how many instances of the event source there will be. So I have to know for example the device endpoint reference to identify the event source. The way to distinguish between the sources like in the documentation example cannot be used I think. So I tried to use the following construct:

    subscription.getService().getParentDeviceReference(SecurityKey.EMPTY_KEY).getDevice().getEndpointReference().getAddress().toString();
    

    It works fine for a certain time (in the documentation example about 5 event receives or round about 10 seconds). But then I get the following null pointer exception (I'm using JMEDS beta 10.):

    Notification event received from me (46)
    [ERROR] null
    java.lang.NullPointerException
        at org.ws4d.java.DocuExampleEventClient.eventReceived(DocuExampleEventClient.java:248)
        at org.ws4d.java.eventing.DefaultEventSink$EventSinkMessageListener.handle(Unknown Source)
        at org.ws4d.java.communication.receiver.IncomingSOAPReceiver.receive(Unknown Source)
        at org.ws4d.java.communication.protocol.soap.generator.DefaultSOAP2MessageGenerator.sendInvokeMessageToReceiver(Unknown Source)
        at org.ws4d.java.communication.protocol.soap.generator.DefaultSOAP2MessageGenerator.deliverBody(Unknown Source)
        at org.ws4d.java.communication.protocol.soap.generator.DefaultSOAP2MessageGenerator.deliverMessage(Unknown Source)
        at org.ws4d.java.communication.protocol.soap.generator.DefaultSOAP2MessageGenerator.deliverMessage(Unknown Source)
        at org.ws4d.java.communication.protocol.soap.server.SOAPServer$SOAPHandler.handle(Unknown Source)
        at org.ws4d.java.communication.protocol.http.server.HTTPServer$HTTPConnectionHandler.handle(Unknown Source)
        at org.ws4d.java.communication.connection.tcp.TCPListener$TCPConnectionThread.run(Unknown Source)
        at org.ws4d.java.concurrency.ThreadPool$WorkerThread.run(Unknown Source)
    

    As a minimum example the documentation example can be used with following lines inserted in the "eventReceived" method in the "if (subscription.equals(notificationSub))" block:

    try {
        System.err.println("**** " + subscription.getService().getParentDeviceReference(SecurityKey.EMPTY_KEY).getDevice().getEndpointReference().getAddress().toString());
    } catch (CommunicationException e) {
        e.printStackTrace();
    }
    

    Can anybody help me with this? Or / and is there a smarter way to get a reference to the device that fired the event in the eventReceived method?

    Thanks and regards,
    Martin

     
  • Chris

    Chris - 2014-03-04

    Hello Martin,
    thank you for your bug report. We were able to reproduce the error and will look into it to fix it as soon as possible.

    Best regards,
    Chris

     
  • Ingo Lück

    Ingo Lück - 2014-03-10

    Hi Martin,

    DeviceReferences that do not have at least one DeviceListener are automatically cleaned up by the framework after 20 seconds. If you want to keep the DeviceReferences which are created during service search you have to change the line “SearchManager.searchService(search, client, null);” to “SearchManager.searchService(search, client, client);”

    Generally service searches generate much network traffic because the DPWS protocol does only support device searches. Thus the framework performs a service search as follows:
    - searching for all available devices without any restriction
    - get the metadata of all devices found
    - check the metadata for the service types and propagate only the matching ones
    From that point of view the example is not so good and we will change it with the next release in the following way:

    public class DocuExampleEventServiceProvider {
    
        private final static String namespace   = "http://www.mydemo.com/tutorial";
    
        final static QName          deviceQName = new QName("BasicDevice", namespace);
    
        /**
         * @param args
         */
        public static void main(String[] args) {
    
            // mandatory: Starting the DPWS Framework
            JMEDSFramework.start(args);
    
            // first we need a device
            DefaultDevice device = new DefaultDevice(DPWSCommunicationManager.COMMUNICATION_MANAGER_ID);
    
            // and it needs a type to find it easily
            device.setPortTypes(new QNameSet(deviceQName));
    
    ...     
    


    public class DocuExampleEventClient extends DefaultClient {
    
        final static String         namespace                   = "http://www.mydemo.com/tutorial";
    
        final static QName          serviceQName                = new QName("BasicServices", namespace);
    
        final static QName          deviceQName                 = new QName("BasicDevice", namespace);
    
        private ClientSubscription  solicitSub                  = null;
    
        private ClientSubscription  notificationSub             = null;
    
        private EventSource         eventSourceSolicitResponse  = null;
    
        public static void main(String[] args) {
    
            // mandatory starting of DPWS framework
            JMEDSFramework.start(args);
    
            DPWSProperties.getInstance().removeSupportedDPWSVersion(DPWSProtocolVersion.DPWS_VERSION_2006);
    
            // create client
            DocuExampleEventClient client = new DocuExampleEventClient();
    
            // search for event and subscribe
            SearchParameter search = new SearchParameter();
            search.setDeviceTypes(new QNameSet(deviceQName), DPWSCommunicationManager.COMMUNICATION_MANAGER_ID);
            SearchManager.searchDevice(search, client, client);
        }
    
        public void deviceFound(DeviceReference devRef, SearchParameter search, String comManId) {
            Iterator iter;
            try {
                iter = devRef.getDevice().getServiceReferences(new QNameSet(serviceQName), SecurityKey.EMPTY_KEY);
            } catch (CommunicationException e) {
                e.printStackTrace();
                return;
            }
    
            while (iter.hasNext()) {
                ServiceReference servRef = (ServiceReference) iter.next();
                try {
                    // use this code to subscribe to the simple event
                    {
                        // get event source
                        EventSource eventSource = servRef.getService().getEventSource(serviceQName, "DocuExampleSimpleEvent", null, null);
    
                        if (eventSource != null) {
                            // add binding
                            DataStructure bindings = new org.ws4d.java.structures.ArrayList();
                            HTTPBinding binding = new HTTPBinding(IPNetworkDetection.getInstance().getIPAddressOfAnyLocalInterface("127.0.0.1", false), 10235, "/EventSink", DPWSCommunicationManager.COMMUNICATION_MANAGER_ID);
                            bindings.add(binding);
    
                            // subscribe
                            notificationSub = eventSource.subscribe(this, 0, bindings, CredentialInfo.EMPTY_CREDENTIAL_INFO);
                        }
                    }
                    // use this code to subscribe to the solicit-response event
                    {
                        // get event source
                        eventSourceSolicitResponse = servRef.getService().getEventSource(serviceQName, "DocuExampleComplexEvent", null, null);
    
                        if (eventSourceSolicitResponse != null) {
                            // add binding
                            DataStructure bindings = new org.ws4d.java.structures.ArrayList();
                            HTTPBinding binding = new HTTPBinding(IPNetworkDetection.getInstance().getIPAddressOfAnyLocalInterface("127.0.0.1", false), 7896, "/EventSink", DPWSCommunicationManager.COMMUNICATION_MANAGER_ID);
                            bindings.add(binding);
    
                            // subscribe
                            solicitSub = eventSourceSolicitResponse.subscribe(this, 0, bindings, CredentialInfo.EMPTY_CREDENTIAL_INFO);
                        }
                    }
                } catch (CommunicationException e) {
                    e.printStackTrace();
                } catch (InvocationException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    
    ...
    



    Best regards,
    Ingo

     

Log in to post a comment.