sane-city / wot-servient

W3C Web of Things implementation for Java
MIT License
30 stars 5 forks source link

ExposedThing::destroy will throw NullPointerException if called after Wot::destroy #7

Closed Dnnd closed 4 years ago

Dnnd commented 4 years ago

Expected behavior

ExposedThing::destroy invocation after Wot::destroy is a no-op (or a warning).

Observed Behavior

ExposedThing::destroy invocation after Wot::destroy is a NullPointerException.

Consider the following code:

public class Test {
    public static void main(String[] args) throws WotException, ExecutionException, InterruptedException {
        Config config = ConfigFactory
                .parseString("wot.servient.servers = [\"city.sane.wot.binding.mqtt.MqttProtocolServer\"]");

        config = config.withFallback(ConfigFactory.load());
        Wot wot = DefaultWot.serverOnly(config);
        Thing thing = new Thing.Builder().build();
        ExposedThing exposedThing = wot.produce(thing).expose().get();
        wot.destroy();
        exposedThing.destroy().get();
    }
}

Output:

21:41:16.078 | main | DEBUG | city.sane.wot.ServientConfig | Servient storing credentials for '[]'
21:41:16.080 | main | INFO  | city.sane.wot.Servient | Start Servient
21:41:16.083 | main | INFO  | c.s.w.b.mqtt.MqttProtocolServer | Start MqttServer
21:41:16.090 | ForkJoinPool.commonPool-worker-3 | DEBUG | city.sane.RefCountResource | First Reference. Create Resource.
21:41:16.218 | ForkJoinPool.commonPool-worker-3 | INFO  | c.s.w.b.mqtt.MqttProtocolSettings | MqttClient trying to connect to broker at 'tcp://localhost:1883' with client ID 'wot29755222508026'
21:41:16.540 | ForkJoinPool.commonPool-worker-3 | INFO  | c.s.w.b.mqtt.MqttProtocolSettings | MqttClient connected to broker at 'tcp://localhost:1883'
21:41:16.680 | main | DEBUG | city.sane.wot.thing.ExposedThing | 'null' created
21:41:16.682 | main | WARN  | city.sane.wot.Servient | Servient generating ID for 'ExposedThing{objectType='null', objectContext=null, id='null', title='null', titles=null, description='null', descriptions=null, properties={}, actions={}, events={}, forms=[], security=[], securityDefinitions={}, base='null'}'
21:41:16.714 | main | DEBUG | city.sane.wot.thing.ExposedThing | Expose all Interactions and TD for 'urn:uuid:5b13492d-78aa-48b6-abcf-9ca6329a6d84'
21:41:16.714 | main | INFO  | city.sane.wot.Servient | Servient exposing 'urn:uuid:5b13492d-78aa-48b6-abcf-9ca6329a6d84'
21:41:16.717 | main | INFO  | c.s.w.b.mqtt.MqttProtocolServer | MqttServer exposes 'urn:uuid:5b13492d-78aa-48b6-abcf-9ca6329a6d84' at 'mqtt://localhost:1883/urn:uuid:5b13492d-78aa-48b6-abcf-9ca6329a6d84/*'
21:41:16.718 | main | DEBUG | c.s.w.b.mqtt.MqttProtocolServer | Publish 'urn:uuid:5b13492d-78aa-48b6-abcf-9ca6329a6d84' Thing Description to topic 'urn:uuid:5b13492d-78aa-48b6-abcf-9ca6329a6d84'
21:41:16.803 | main | DEBUG | city.sane.wot.content.ContentManager | Content serializing to 'application/json'
21:41:16.808 | main | DEBUG | city.sane.wot.thing.ExposedThing | TD has changed. Inform observers.
21:41:16.809 | main | INFO  | city.sane.wot.Servient | Stop Servient
21:41:16.810 | main | INFO  | c.s.w.b.mqtt.MqttProtocolServer | Stop MqttServer
21:41:16.810 | main | DEBUG | city.sane.wot.thing.ExposedThing | Stop exposing all Interactions and TD for 'urn:uuid:5b13492d-78aa-48b6-abcf-9ca6329a6d84'
21:41:16.810 | main | INFO  | city.sane.wot.Servient | Servient stop exposing 'ExposedThing{objectType='null', objectContext=null, id='urn:uuid:5b13492d-78aa-48b6-abcf-9ca6329a6d84', title='null', titles=null, description='null', descriptions=null, properties={}, actions={}, events={}, forms=[], security=[], securityDefinitions={}, base=''}'
21:41:16.812 | main | INFO  | c.s.w.b.mqtt.MqttProtocolServer | MqttServer stop exposing 'urn:uuid:5b13492d-78aa-48b6-abcf-9ca6329a6d84' as unique '/urn:uuid:5b13492d-78aa-48b6-abcf-9ca6329a6d84/*'
21:41:16.812 | main | DEBUG | c.s.w.b.mqtt.MqttProtocolServer | Remove published 'urn:uuid:5b13492d-78aa-48b6-abcf-9ca6329a6d84' Thing Description at topic 'urn:uuid:5b13492d-78aa-48b6-abcf-9ca6329a6d84'
21:41:16.811 | ForkJoinPool.commonPool-worker-3 | DEBUG | city.sane.RefCountResource | No more References. Cleanup Resource: Pair{first=city.sane.wot.binding.mqtt.MqttProtocolSettings@d46d7f4, second=org.eclipse.paho.client.mqttv3.MqttClient@2edcc234}
Exception in thread "main" java.lang.NullPointerException
    at city.sane.wot.binding.mqtt.MqttProtocolServer.unexposeTD(MqttProtocolServer.java:260)
    at city.sane.wot.binding.mqtt.MqttProtocolServer.destroy(MqttProtocolServer.java:130)
    at city.sane.wot.Servient.lambda$destroy$16(Servient.java:213)
    at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:195)
    at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1655)
    at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484)
    at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474)
    at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:550)
    at java.base/java.util.stream.AbstractPipeline.evaluateToArrayNode(AbstractPipeline.java:260)
    at java.base/java.util.stream.ReferencePipeline.toArray(ReferencePipeline.java:517)
    at city.sane.wot.Servient.destroy(Servient.java:213)
    at city.sane.wot.thing.ExposedThing.destroy(ExposedThing.java:561)
    at ru.mipt.wot.cloud.example.Test.main(Test.java:23)

Exception is raised because settingsClientPair field is null on the following line inside MqttProtocolServer::unexposeTD: https://github.com/sane-city/wot-servient/blob/490d03304cfb8b95a9a38e866016fa316ff7541d/wot-servient-binding-mqtt/src/main/java/city/sane/wot/binding/mqtt/MqttProtocolServer.java#L260 Its happening because MqttProtocolServer::destroy won't check settingsClientPair != null before unexposeTD invocation. I believe, that in the case of settingsClientPair == null it's safe to simply exit MqttProtocolServer::destroy, as destroyed ProtocolServer shoudn't have any exposed things (which isn't completly true due to https://github.com/sane-city/wot-servient/issues/6).