Swirrl / cubiql

CubiQL: A GraphQL service for querying multidimensional Linked Data Cubes
Eclipse Public License 1.0
41 stars 2 forks source link

No implementation of method: :transform-result of protocol: #'graphql-qb.schema/ResultTransform found for class: graphql_qb.types.EnumType #150

Open agustingp opened 6 years ago

agustingp commented 6 years ago

Data converted following the instructions at https://github.com/Swirrl/graphql-qb/blob/master/doc/table2qb-cubiql.md is producing an "Internal server error: exception" when retrieving the observations with the query :

{cubiql{ dataset_iwavebnetworkzerocrossing{ observations{ page(first: 2000){ observation{ station_id latitude havg } } } } }}

Find attached the CSVs and ttl files resulting from the conversion zerocrossing_ttl.zip

In the logs file the error is:

clojure.lang.ExceptionInfo: java.lang.IllegalArgumentException in Interceptor :com.walmartlabs.lacinia.pedestal/query-executor - No implementation of method: :transform-result of protocol: #'graphql-qb.schema/ResultTransform found for class: graphql_qb.types.EnumType at clojure.core$ex_info.invokeStatic(core.clj:4739) ~[graphql-qb-0.4.0-standalone.jar:?] at clojure.core$ex_info.invoke(core.clj:4739) ~[graphql-qb-0.4.0-standalone.jar:?] at io.pedestal.interceptor.chain$throwableGT_ex_info.invokeStatic(chain.clj:35) ~[graphql-qb-0.4.0-standalone.jar:?] at io.pedestal.interceptor.chain$throwableGT_ex_info.invoke(chain.clj:32) ~[graphql-qb-0.4.0-standalone.jar:?] at io.pedestal.interceptor.chain$try_f.invokeStatic(chain.clj:57) ~[graphql-qb-0.4.0-standalone.jar:?] at io.pedestal.interceptor.chain$try_f.invoke(chain.clj:44) ~[graphql-qb-0.4.0-standalone.jar:?] at io.pedestal.interceptor.chain$process_all_with_binding.invokeStatic(chain.clj:171) ~[graphql-qb-0.4.0-standalone.jar:?] at io.pedestal.interceptor.chain$process_all_with_binding.invoke(chain.clj:146) ~[graphql-qb-0.4.0-standalone.jar:?] at io.pedestal.interceptor.chain$process_all$fn__15853.invoke(chain.clj:188) ~[graphql-qb-0.4.0-standalone.jar:?] at clojure.lang.AFn.applyToHelper(AFn.java:152) ~[graphql-qb-0.4.0-standalone.jar:?] at clojure.lang.AFn.applyTo(AFn.java:144) ~[graphql-qb-0.4.0-standalone.jar:?] at clojure.core$apply.invokeStatic(core.clj:657) ~[graphql-qb-0.4.0-standalone.jar:?] at clojure.core$with_bindingsSTAR.invokeStatic(core.clj:1965) ~[graphql-qb-0.4.0-standalone.jar:?] at clojure.core$with_bindingsSTAR.doInvoke(core.clj:1965) ~[graphql-qb-0.4.0-standalone.jar:?] at clojure.lang.RestFn.invoke(RestFn.java:425) ~[graphql-qb-0.4.0-standalone.jar:?] at io.pedestal.interceptor.chain$process_all.invokeStatic(chain.clj:186) ~[graphql-qb-0.4.0-standalone.jar:?] at io.pedestal.interceptor.chain$process_all.invoke(chain.clj:182) ~[graphql-qb-0.4.0-standalone.jar:?] at io.pedestal.interceptor.chain$enter_all.invokeStatic(chain.clj:235) ~[graphql-qb-0.4.0-standalone.jar:?] at io.pedestal.interceptor.chain$enter_all.invoke(chain.clj:229) ~[graphql-qb-0.4.0-standalone.jar:?] at io.pedestal.interceptor.chain$execute.invokeStatic(chain.clj:379) [graphql-qb-0.4.0-standalone.jar:?] at io.pedestal.interceptor.chain$execute.invoke(chain.clj:352) [graphql-qb-0.4.0-standalone.jar:?] at io.pedestal.interceptor.chain$execute.invokeStatic(chain.clj:389) [graphql-qb-0.4.0-standalone.jar:?] at io.pedestal.interceptor.chain$execute.invoke(chain.clj:352) [graphql-qb-0.4.0-standalone.jar:?] at io.pedestal.http.impl.servlet_interceptor$interceptor_service_fn$fn__19447.invoke(servlet_interceptor.clj:350) [graphql-qb-0.4.0-standalone.jar:?] at io.pedestal.http.servlet.FnServlet.service(servlet.clj:28) [graphql-qb-0.4.0-standalone.jar:?] at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:838) [graphql-qb-0.4.0-standalone.jar:?] at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:543) [graphql-qb-0.4.0-standalone.jar:?] at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:188) [graphql-qb-0.4.0-standalone.jar:?] at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1228) [graphql-qb-0.4.0-standalone.jar:?] at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:168) [graphql-qb-0.4.0-standalone.jar:?] at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:481) [graphql-qb-0.4.0-standalone.jar:?] at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:166) [graphql-qb-0.4.0-standalone.jar:?] at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1130) [graphql-qb-0.4.0-standalone.jar:?] at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141) [graphql-qb-0.4.0-standalone.jar:?] at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:132) [graphql-qb-0.4.0-standalone.jar:?] at org.eclipse.jetty.server.Server.handle(Server.java:564) [graphql-qb-0.4.0-standalone.jar:?] at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:318) [graphql-qb-0.4.0-standalone.jar:?] at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:251) [graphql-qb-0.4.0-standalone.jar:?] at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:279) [graphql-qb-0.4.0-standalone.jar:?] at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:112) [graphql-qb-0.4.0-standalone.jar:?] at org.eclipse.jetty.io.ChannelEndPoint$2.run(ChannelEndPoint.java:124) [graphql-qb-0.4.0-standalone.jar:?] at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:672) [graphql-qb-0.4.0-standalone.jar:?] at org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:590) [graphql-qb-0.4.0-standalone.jar:?] at java.lang.Thread.run(Thread.java:748) [?:1.8.0_181] Caused by: java.lang.IllegalArgumentException: No implementation of method: :transform-result of protocol: #'graphql-qb.schema/ResultTransform found for class: graphql_qb.types.EnumType

zeginis commented 6 years ago

@agustingp there are some inconsistencies between the URIs used at the cube and the URIs used at the codelists:

lkitching commented 6 years ago

@agustingp - I pushed a fix for that issue earlier today, can you try the latest version on master to see if that works for you?

agustingp commented 6 years ago

@zeginis These missing "_" were just an attempt to see if that was the error (In the documentation there is this example: http://example.gr/def/concept/stationid/{station_id}) @lkitching I run the last update of the API and it works now as expected. Thanks a million

zeginis commented 6 years ago

@agustingp if there is no matching between the cube and the codelist the API will work, but when quering the observations you will get the URI of the values instead of the enum.

e.g. at the data you have at the SPARQL endpoint, the time value URIs do not exist at the codelist

{cubiql{dataset_iwavebnetwork_spectral{
  observations{
    page{
      observation{        
        station_id
        time        
 }    }  }}}}
 "observation": [
         { "station_id": "BELMULLET_WAVE_BUOY_BERTH_B",
            "time": "http://www.opengovintelligence.eu/statistics/marine-institute/def/concept/time/2010-01-01T12:06:00Z"
              },
...
agustingp commented 6 years ago

@zeginis regarding your last comment I realized that what you say is happening, but the values are matching. For instance, Cube <http://www.opengovintelligence.eu/statistics/marine-institute/def/concept/station_id/howth-harbour> . Codelist <http://www.opengovintelligence.eu/statistics/marine-institute/def/concept/station_id/howth-harbour> rdfs:label "Howth Harbour" .

Querying the API:

{ "data": { "cubiql": { "dataset_irishnationaltidegaugenetwork": { "observations": { "page": { "observation": [ { "uri": "http://www.opengovintelligence.eu/statistics/marine-institute/data/irishnationaltidegaugenetwork/-6.0683/53.3915/0/2010-01-01T00:00:00Z/howth-harbour/10/qc_flag", "altitude": "A_0", "station_id": "HOWTH_HARBOUR", "water_level_lat": "", "water_level_od_malin": "", "datasourceid": "A_10" },

zeginis commented 6 years ago

@agustingp the problem occurs only when there is not matching. e.g. at the time dimension. The station_id is ok.

agustingp commented 6 years ago

@zeginis Oh I got it. Thanks!

agustingp commented 6 years ago

@zeginis I modified our script for creating the codelists based on the input file to only slugize the values of the dimensions that have "slugize" as "value_transformation" value. Now time is being retrieved (not the URI) but I still see that the values are being modified:

"observation": [ { "altitude": "A_0", "time": "A_2010_01_01T00_00_00Z", "station_id": "HOWTH_HARBOUR" },

whereas in the Cube definition the values are defined as:

<http://www.opengovintelligence.eu/statistics/marine-institute/def/concept/time/2010-01-01T05:42:00Z> .

The same with Latitude and Longitude dimensions

zeginis commented 6 years ago

@lkitching any idea if this can be fixed somehow?

label: 2010-01-01T05:42:00Z enum: A_2010_01_01T00_00_00Z

lkitching commented 6 years ago

@zeginis @agustingp - At the moment, dimensions with an associated codelist are mapped to a GraphQL enum type. GraphQL enum values must begin with a letter or _ (see the definition in the specification). At the moment, we prefix A_ to enum values that start with an invalid starting character to make the name valid, we could change this to just use an _ alone.

Are you using the codelist values to filter the results? Currently we create an enum type for all dimensions with a codelist but we could change this to look at the rdfs:range first and only generate enum types for certain types. This would allow you to set the rdfs:range to a type which is mapped to a string instead.

arekstasiewicz commented 6 years ago

@lkitching what is there the reason for disallowing numbers at the beginning? Is it possible to have a workaround? There are a lot of cases where the dimension value will start with a number (including the ones mentioned by @agustingp):

<http://data.cso.ie/census-2011/classification/size-of-family/6_or_more> <http://www.w3.org/2000/01/rdf-schema#label> "6 or more" .

<http://data.cso.ie/census-2011/classification/number-of-motor-cars/3> <http://www.w3.org/2000/01/rdf-schema#label> "3" .

lkitching commented 6 years ago

@arekstasiewicz - This is a restriction GraphQL puts on enum values that they must begin with either a letter or underscore. If you query the dimensions for the dataset you can retrieve the label for each enum value and perform the mapping yourself. We could change the way enum types are output in the schema so you can select the mapped value along with the associated label, this would mean your queries for those dimensions would need to change from

observation {
   uri
   enum_dimension
}

to

observation {
  uri
  enum_dimension {
    value
    schema_label
  }
}

this approach might be a little confusing since it would ignore the lang_preference set for the query.