You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@olingo.apache.org by Vinayak Joshi <wi...@gmail.com> on 2016/05/03 15:00:42 UTC

ODATA v4 - @odata.context in service document

I am trying to use an ODATA V4 service I created as an OData Feed data
source in MS Excel.

It doesn't work (excel complains about the URI/hostname) and I believe it's
because my service returns a service document where the @odata.context fiel
does not include the service root URI:

{
   "@odata.context": "$metadata",
   "value":    [
            {
         "name": "EMPLOYEES",
         "url": "EMPLOYEES"
      },
            {
         "name": "DEPTS",
         "url": "DEPTS"
      }
   ]
}

I tested the same excel feature with the OData V4 TripPin sample service
and things seem to work fine. The only difference between my service and
the TripPin service appears to be that the TripPin service sends a full URI
in the @odata.context:

"@odata.context":"http://services.odata.org/V4/(S(fejk1l2eeaqcm2pbqdv0ly01))/TripPinServiceRW/$metadata"


Now I am trying to determine how my service built with Olingo could do the same.

I followed the Olingo Odata 4 tutorial to build my service and
register a EdmProvider etc.

I am running my service on localhost - not sure if that affects this
in some way.

I don't see any code in the EdmProvider sample to build/return a
ContextURL for the service document.How do I make this happen?

Second, in the other registered Entity / EntityCollection / Primitive
processors, should I embed my service root URI in the @odata.context,
by using the .serviceRoot( ) option in ContextURL like so :

ContextURL.with()

.*serviceRoot(new URI(request.getRawBaseUri()))*

.other options

.entitySet(edmEntitySet).build();

Is this the intended purpose of the the serviceRoot ( ) method on the
ContextURL ?

Regards,
Vin

RE: ODATA v4 - @odata.context in service document

Posted by Steven Veum <St...@progress.com>.
I encountered a similar issue when testing my service with the OData Client for .NET.  The error message from the client was:

The response payload is a not a valid response payload. Please make sure that the top level element is a valid Atom or JSON element or belongs to 'http://docs.oasis-open.org/odata/ns/data' namespace.

By debugging the .NET client library, I determined that it requires an absolute path for the context URL.  A relative path will trigger the above error.

My fix was to set the service root when building the context URI as described below.  I did have to append a slash to the end of the service root to get the context URI builder to correctly build the URI.  Otherwise, I was getting the $metadata appended to service root without the slash separator.

From: Amend, Christian [mailto:christian.amend@sap.com]
Sent: Wednesday, May 04, 2016 5:19 AM
To: user@olingo.apache.org
Subject: RE: ODATA v4 - @odata.context in service document

Hi Vin,

according to the specification a client should be able to handle the relative URLs. Yet if this is not the case you can always set the service root with the context URL builder. Olingo makes no assumption about the service root because you cloud be behind a proxy. This is why we do not set it as a default.

For the service document you have to register your own ServiceDocumentProzessor. There you have the ability to call the serializer yourself and set the service root for the service document. If you need guidance on how to implement this method have a look at the DefaultProcessor implementation: https://github.com/apache/olingo-odata4/blob/3786699f018ac2deb1df9571d12bb61ab57f2d8a/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/DefaultProcessor.java#L58

In line 76 you can pass the service root instead of null.

Best Regards,
Christian

From: Vinayak Joshi [mailto:winjoshi4@gmail.com]
Sent: Dienstag, 3. Mai 2016 15:01
To: user@olingo.apache.org<ma...@olingo.apache.org>
Subject: ODATA v4 - @odata.context in service document

I am trying to use an ODATA V4 service I created as an OData Feed data source in MS Excel.

It doesn't work (excel complains about the URI/hostname) and I believe it's because my service returns a service document where the @odata.context fiel does not include the service root URI:

{
   "@odata.context": "$metadata",
   "value":    [
            {
         "name": "EMPLOYEES",
         "url": "EMPLOYEES"
      },
            {
         "name": "DEPTS",
         "url": "DEPTS"
      }
   ]
}

I tested the same excel feature with the OData V4 TripPin sample service and things seem to work fine. The only difference between my service and the TripPin service appears to be that the TripPin service sends a full URI in the @odata.context:


"@odata.context":"http://services.odata.org/V4/(S(fejk1l2eeaqcm2pbqdv0ly01))/TripPinServiceRW/$metadata"



Now I am trying to determine how my service built with Olingo could do the same.

I followed the Olingo Odata 4 tutorial to build my service and register a EdmProvider etc.

I am running my service on localhost - not sure if that affects this in some way.

I don't see any code in the EdmProvider sample to build/return a ContextURL for the service document.How do I make this happen?

Second, in the other registered Entity / EntityCollection / Primitive processors, should I embed my service root URI in the @odata.context, by using the .serviceRoot( ) option in ContextURL like so :

ContextURL.with()

.serviceRoot(new URI(request.getRawBaseUri()))

.other options

.entitySet(edmEntitySet).build();
Is this the intended purpose of the the serviceRoot ( ) method on the ContextURL ?

Regards,
Vin

RE: ODATA v4 - @odata.context in service document

Posted by "Amend, Christian" <ch...@sap.com>.
Hi Vin,

according to the specification a client should be able to handle the relative URLs. Yet if this is not the case you can always set the service root with the context URL builder. Olingo makes no assumption about the service root because you cloud be behind a proxy. This is why we do not set it as a default.

For the service document you have to register your own ServiceDocumentProzessor. There you have the ability to call the serializer yourself and set the service root for the service document. If you need guidance on how to implement this method have a look at the DefaultProcessor implementation: https://github.com/apache/olingo-odata4/blob/3786699f018ac2deb1df9571d12bb61ab57f2d8a/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/DefaultProcessor.java#L58

In line 76 you can pass the service root instead of null.

Best Regards,
Christian

From: Vinayak Joshi [mailto:winjoshi4@gmail.com]
Sent: Dienstag, 3. Mai 2016 15:01
To: user@olingo.apache.org
Subject: ODATA v4 - @odata.context in service document

I am trying to use an ODATA V4 service I created as an OData Feed data source in MS Excel.

It doesn't work (excel complains about the URI/hostname) and I believe it's because my service returns a service document where the @odata.context fiel does not include the service root URI:

{
   "@odata.context": "$metadata",
   "value":    [
            {
         "name": "EMPLOYEES",
         "url": "EMPLOYEES"
      },
            {
         "name": "DEPTS",
         "url": "DEPTS"
      }
   ]
}

I tested the same excel feature with the OData V4 TripPin sample service and things seem to work fine. The only difference between my service and the TripPin service appears to be that the TripPin service sends a full URI in the @odata.context:


"@odata.context":"http://services.odata.org/V4/(S(fejk1l2eeaqcm2pbqdv0ly01))/TripPinServiceRW/$metadata"



Now I am trying to determine how my service built with Olingo could do the same.

I followed the Olingo Odata 4 tutorial to build my service and register a EdmProvider etc.

I am running my service on localhost - not sure if that affects this in some way.

I don't see any code in the EdmProvider sample to build/return a ContextURL for the service document.How do I make this happen?

Second, in the other registered Entity / EntityCollection / Primitive processors, should I embed my service root URI in the @odata.context, by using the .serviceRoot( ) option in ContextURL like so :

ContextURL.with()

.serviceRoot(new URI(request.getRawBaseUri()))

.other options

.entitySet(edmEntitySet).build();
Is this the intended purpose of the the serviceRoot ( ) method on the ContextURL ?

Regards,
Vin