arrowhead-f / core-java

Arrowhead Core Framework Implementation in Java
https://forge.soa4d.org/plugins/mediawiki/wiki/arrowhead-f/index.php/Main_Page
Apache License 2.0
4 stars 12 forks source link

ServiceRegistry exception when metadata is defined but empty #35

Closed cochicde closed 5 years ago

cochicde commented 5 years ago

I register a service and send:

{ "providedService" : { "serviceDefinition" : "emergencyLight1", "interfaces" : [ ] }, "provider" : { "systemName" : "DEPOSIT1", "address" : "127.0.0.1", "port" : 80, "authenticationInfo" : "" }, "serviceURI" : "emergencyLight", "version" : 1, "metadata" : "", "udp" : false }

the SR register the service but returns an error message because:

java.lang.ArrayIndexOutOfBoundsException: 1
    at eu.arrowhead.common.database.ServiceRegistryEntry.fromDatabase(ServiceRegistryEntry.java:202)
    at eu.arrowhead.core.serviceregistry_sql.ServiceRegistryResource.registerService(ServiceRegistryResource.java:86)
    at sun.reflect.GeneratedMethodAccessor29.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.glassfish.jersey.server.model.internal.ResourceMethodInvocationHandlerFactory.lambda$static$0(ResourceMethodInvocationHandlerFactory.java:76)
    at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher$1.run(AbstractJavaResourceMethodDispatcher.java:148)
    at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.invoke(AbstractJavaResourceMethodDispatcher.java:191)
    at org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$ResponseOutInvoker.doDispatch(JavaResourceMethodDispatcherProvider.java:200)
    at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.dispatch(AbstractJavaResourceMethodDispatcher.java:103)
    at org.glassfish.jersey.server.model.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:493)
    at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:415)
    at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:104)
    at org.glassfish.jersey.server.ServerRuntime$1.run(ServerRuntime.java:277)
    at org.glassfish.jersey.internal.Errors$1.call(Errors.java:272)
    at org.glassfish.jersey.internal.Errors$1.call(Errors.java:268)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:316)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:298)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:268)
    at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:289)
    at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:256)
    at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:703)
    at org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpContainer.service(GrizzlyHttpContainer.java:377)
    at org.glassfish.grizzly.http.server.HttpHandler$1.run(HttpHandler.java:224)
    at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:593)
    at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:573)
    at java.lang.Thread.run(Unknown Source)

the problem seems to be that metadata : "", because if I don't send the field or send a "key=value" it returns a good reponse. I think the SR should treat an empty string in the metadata as if the field wasn't there.

uzoltan commented 5 years ago

Thanks, will fix tomorrow along with the other one you opened today.

uzoltan commented 5 years ago

Hey, so commit a46a72e24e15a1fd9a2f804c753bf27d9ba4c621 fixes this issue, 2-fold kinda.

The fromDatabase method where the exception happened now handles empty strings too.

But: the metadata field is not part of the REST interface (see the SD), that was just an internal field towards the database. This field was ignored by the JSON library in the 4.0 version, but somewhere along the refactoring, this got deleted because of an oversight. So now I also reintroduced ignoring the metadata field of the SREntry to the library, service metadata should be passed through the providedService, like so:

"providedService": {
    "serviceDefinition": "string",
    "interfaces": [
      "string"
    ],
    "serviceMetadata": {
      "additionalProp1": "string",
      "additionalProp2": "string",
      "additionalProp3": "string"
    }
  }
cochicde commented 5 years ago

hi, thanks for the fix. Tested and worked smoothly. Regarding the presence of the metadata in the serviceRegistryEntry level, I followed the SD where it's defined. In the IDD for REST-JSON it doesn't appear in the example for the interfaces in the SDs, but it these are just examples of the dataypes defined in the SD. I'm not sure if the IDD can just discard fields of the SD which aren't explictely tagged as optional. But I think in the Bilbao meeting there would be some talks about the metadata

uzoltan commented 5 years ago

It should have been said in the SD, that this metadata field is there to be a "replacement" (or better said, as a helper field) to the serviceMetadata field inside the ArrowheadService class. Logically it makes sense to have the serviceMetadata inside the ArrowheadService class, and it's fine to have it there when the object is passed around between systems, because that is a concrete instance of an ArrowheadService there.

But we needed that extra metadata field in the SREntry to convert between JSON and database format, because in the database the metadata should belong to the SREntry, allowing it to providers to provide the same ArrowheadServices with different metadata.