You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@olingo.apache.org by Tim Wernick <ti...@wernick-net.de> on 2014/10/02 14:52:04 UTC

How to avoid urlencoding in datetime keys

Dear all,
I am currently trying to upsert an odata object which has a key like this:

payComponentCode='xyz',payDate=datetime'2013-10-31T00:00:00',userId='102'

The service I am connecting to is based on odata4j. Somehow olingo
urlencodes the datetime key part so that the key looks like

payComponentCode='xyz',payDate=datetime'2013-10-31T00%3A00%3A00',userId='102'

I am upserting the object using the following code:

ODataResponse response = computeUpdateResponse(edm, contentType,
		entitySetName, data);
String uri = "/odata/v2/upsert";
String sHost = getHostUrl();
StringBuilder url = new StringBuilder();
if (!uri.startsWith(sHost)) {
	url.append(sHost).append(uri);
} else {
	url.append(uri);
}
HttpPost post = new HttpPost(url.toString());
post.setEntity(new InputStreamEntity(
		(InputStream) response.getEntity(), -1));
if (!externalClient)
	post.addHeader(new BasicScheme().authenticate(basicCredentials,
			post));
post.addHeader("accept", contentType);
post.addHeader("content-type", contentType);
HttpResponse httpResponse = httpClient.execute(post);
HttpEntity entity = httpResponse.getEntity();
...
EntityUtils.consume(entity);

The computeUpdateResponse contains the following code:

EdmEntityContainer entityContainer = edm.getDefaultEntityContainer();
EdmEntitySet entitySet = entityContainer.getEntitySet(entitySetName);

// We only want to send the properties that need to be changed
List<SelectItem> select = buildSelectItemList(entitySet, entitySetName,
		data.keySet());
List<ArrayList<NavigationPropertySegment>> navProps = new
ArrayList<ArrayList<NavigationPropertySegment>>();

navProps.add((ArrayList<NavigationPropertySegment>)
buildNavigationPropertySegmentList(
		entitySet, entitySetName, data.keySet()));

ExpandSelectTreeNode expandSelectTreeNode = UriParser
		.createExpandSelectTree(select, navProps);

EntityProviderWriteProperties properties = EntityProviderWriteProperties
		.serviceRoot(new URI(""))
		.expandSelectTree(expandSelectTreeNode)
		.omitJsonWrapper(true)
		.build();
ODataResponse response = EntityProvider.writeEntry(contentType,
		entitySet, data, properties);

As a result I get the following message from the server:

bad valueString [datetime'2013-10-31T00%3A00%3A00'] as part of keyString
[payComponentCode='xyz',payDate=datetime'2013-10-31T00%3A00%3A00',userId='102']

How can I avoid the urlencoding of the datetime keypart?

Thanks in advance for your help!

kind regards


Tim

Re: How to avoid urlencoding in datetime keys

Posted by Tim Wernick <ti...@wernick-net.de>.
Dear Christian,
no problem @ late reply. We all need to earn some money and don't have
the time to monitor mailing lists all of our time ;-)

Thanks for your reply. To have the encoding be switched on / off has the
advantage that one would be able to have an olingo based client be able
to communicate e.g. with an odata4j based service which expects the
colon in the datetime keypart not to be encoded. Myself would of course
prefer the service to be based upon olingo but thats not something I am
able to influence as the service is provided by the branch of a big
software company.

Besides that I am not able to find anything in the spec that explicitely
states that the id/uri in the metadata part of the JSON payload should
be URLencoded (maybe I've been blind ;-)).

The only other possibility would be to build up my own jackson based
framework for accessing the service and stop using olingo for requests
where the encoding is an issue.

If you want to I can give you some additional info about the service in
a private mail as this may not be of interest for the rest of the
mailing list.

kind regards


Tim

Am 07.10.2014 16:36, schrieb Amend, Christian:
> Hi Tim,
> 
> sorry for my late reply.
> 
> The json payload does not need encoding for the colon if it is part of the json document. So a property with a datetimevalue called "Date" would be represented like this:
> "Date":" 1999-01-01T00:00:00"
> This is based on the json specification for json documents and the ABNF you posted with your previous mail. As you can see there is no encoding.
> 
> The reason we encode the content of the __metadata id and uri field is that they contain URLs. Here an example from our reference scenario. 
> 		"__metadata" : {
> 			"id" : "http://localhost:8080/olingo/ReferenceScenario.svc/Rooms('1')",
> 			"uri" : "http://localhost:8080/olingo/ReferenceScenario.svc/Rooms('1')",
> 			"type" : "RefScenario.Room",
> 			"etag" : "W/\"1\""
> 		},
> The key here is a simple String but if it would be a date like in your example the key would be encoded based on the URL specification. Nonetheless both fields should be taken as simple Strings and should not be used to extract the key values as they are present inside the payload or the URL which was used to access this resource. So right now I do not think that Olingo needs a feature where we can switch off the encoding. WDYT?
> 
> Issues can always be opened here: https://issues.apache.org/jira/browse/OLINGO/?selectedTab=com.atlassian.jira.jira-projects-plugin:summary-panel
> 
> Best Regards,
> Christian
> 
> -----Original Message-----
> From: Tim Wernick [mailto:tim.wernick@wernick-net.de] 
> Sent: Dienstag, 7. Oktober 2014 15:29
> To: user@olingo.apache.org
> Subject: Re: How to avoid urlencoding in datetime keys
> 
> Dear all,
> I've had a look at the ABNF of the Odata Protocol hosted at OASIS
> (https://tools.oasis-open.org/version-control/browse/wsvn/odata/trunk/spec/ABNF/odata-abnf-construction-rules.txt)
> regarding the topic of the ID (took only the parts related to the id in
> my case I am following the path of the compoundKey):
> 
> keyPredicate = simpleKey / compoundKey
> 
> compoundKey = OPEN keyValuePair *( COMMA keyValuePair ) CLOSE
> 
> keyValuePair = ( primitiveKeyProperty / keyPropertyAlias ) EQ 	
> keyPropertyValue
> 
> keyPropertyValue = primitiveLiteral
> 
> keyPropertyAlias = odataIdentifier
> 
> primitiveLiteral = nullValue
>                  / booleanValue
>                  / ...
>                  / dateTimeOffsetValue
>                  / ...
>                  / geometryPolygon
> 
> dateTimeOffsetValue = year "-" month "-" day "T" hour ":" minute [ ":"
> second [ "." fractionalSeconds ] ] ( "Z" / sign hour ":" minute )
> 
> That said my assumption is that encoding the colon as it is done using
> the class org.apache.olingo.odata2.core.commons.Encoder inside the
> AtomEntryEntityProducer.createEntryKey is a bug, right?
> 
> Is there any chance that this will be fixed in the future? Where's the
> correct place to file such a bug report?
> 
> kind regards
> 
> 
> Tim
> 
> Am 02.10.2014 17:11, schrieb Tim Wernick:
>> Thanks Christian for your prompt reply!
>>
>> What I don't quite understand is why olingo generates a urlencoded
>> datetime for the key contained in the json payload. The complete
>> generated json data looks like this (partly anonymized ;-)):
>>
>> {
>> 	"__metadata":
>> 	
>> {"id":"entity(payComponentCode='xyz',payDate=datetime'2013-10-31T00%3A00%3A00',userId='102')",
>> 	
>> "uri":"entity(payComponentCode='xyz',payDate=datetime'2013-10-31T00%3A00%3A00',userId='102')",
>> 		"type":"ABC.entity"},
>> 	"payComponentCode":"xyz",
>> 	"payDate":"\/Date(1383177600000)\/",
>> 	"userId":"102",
>> 	"value":"1000.0"
>> }
>>
>> As the colons in the rest of the json payload seem not to be any problem
>> I would have expected that especially the key would be left untouched
>> and still have the colon instead of the urlencoding of the colon. Or at
>> least that there would be a method in the EntityProviderWriteProperties
>> where I would be able to switch on/off the urlencoding.
>>
>> kind regards
>>
>>
>> Tim
>>
>> Am 02.10.2014 15:03, schrieb Amend, Christian:
>>> Hi Tim,
>>>
>>> there is no way to do this. We once saw this behavior because OData4J tried to interpret the atom:id tag where we put this encoded URL. But the atom:id tag should not be interpreted because you cannot be sure that it always contains an URL. Some services might write a GUID in there. This is why we have put not any effort in this issue. The atom:id tag should be treated as a unique String within the atom document and should not be interpreted.
>>>
>>> Best Regards,
>>> Christian
>>>
>>> -----Original Message-----
>>> From: Tim Wernick [mailto:tim.wernick@wernick-net.de] 
>>> Sent: Donnerstag, 2. Oktober 2014 14:52
>>> To: user@olingo.apache.org
>>> Subject: How to avoid urlencoding in datetime keys
>>>
>>> Dear all,
>>> I am currently trying to upsert an odata object which has a key like this:
>>>
>>> payComponentCode='xyz',payDate=datetime'2013-10-31T00:00:00',userId='102'
>>>
>>> The service I am connecting to is based on odata4j. Somehow olingo
>>> urlencodes the datetime key part so that the key looks like
>>>
>>> payComponentCode='xyz',payDate=datetime'2013-10-31T00%3A00%3A00',userId='102'
>>>
>>> I am upserting the object using the following code:
>>>
>>> ODataResponse response = computeUpdateResponse(edm, contentType,
>>> 		entitySetName, data);
>>> String uri = "/odata/v2/upsert";
>>> String sHost = getHostUrl();
>>> StringBuilder url = new StringBuilder();
>>> if (!uri.startsWith(sHost)) {
>>> 	url.append(sHost).append(uri);
>>> } else {
>>> 	url.append(uri);
>>> }
>>> HttpPost post = new HttpPost(url.toString());
>>> post.setEntity(new InputStreamEntity(
>>> 		(InputStream) response.getEntity(), -1));
>>> if (!externalClient)
>>> 	post.addHeader(new BasicScheme().authenticate(basicCredentials,
>>> 			post));
>>> post.addHeader("accept", contentType);
>>> post.addHeader("content-type", contentType);
>>> HttpResponse httpResponse = httpClient.execute(post);
>>> HttpEntity entity = httpResponse.getEntity();
>>> ...
>>> EntityUtils.consume(entity);
>>>
>>> The computeUpdateResponse contains the following code:
>>>
>>> EdmEntityContainer entityContainer = edm.getDefaultEntityContainer();
>>> EdmEntitySet entitySet = entityContainer.getEntitySet(entitySetName);
>>>
>>> // We only want to send the properties that need to be changed
>>> List<SelectItem> select = buildSelectItemList(entitySet, entitySetName,
>>> 		data.keySet());
>>> List<ArrayList<NavigationPropertySegment>> navProps = new
>>> ArrayList<ArrayList<NavigationPropertySegment>>();
>>>
>>> navProps.add((ArrayList<NavigationPropertySegment>)
>>> buildNavigationPropertySegmentList(
>>> 		entitySet, entitySetName, data.keySet()));
>>>
>>> ExpandSelectTreeNode expandSelectTreeNode = UriParser
>>> 		.createExpandSelectTree(select, navProps);
>>>
>>> EntityProviderWriteProperties properties = EntityProviderWriteProperties
>>> 		.serviceRoot(new URI(""))
>>> 		.expandSelectTree(expandSelectTreeNode)
>>> 		.omitJsonWrapper(true)
>>> 		.build();
>>> ODataResponse response = EntityProvider.writeEntry(contentType,
>>> 		entitySet, data, properties);
>>>
>>> As a result I get the following message from the server:
>>>
>>> bad valueString [datetime'2013-10-31T00%3A00%3A00'] as part of keyString
>>> [payComponentCode='xyz',payDate=datetime'2013-10-31T00%3A00%3A00',userId='102']
>>>
>>> How can I avoid the urlencoding of the datetime keypart?
>>>
>>> Thanks in advance for your help!
>>>
>>> kind regards
>>>
>>>
>>> Tim
>>>
>>
>>
> 
> 



RE: How to avoid urlencoding in datetime keys

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

sorry for my late reply.

The json payload does not need encoding for the colon if it is part of the json document. So a property with a datetimevalue called "Date" would be represented like this:
"Date":" 1999-01-01T00:00:00"
This is based on the json specification for json documents and the ABNF you posted with your previous mail. As you can see there is no encoding.

The reason we encode the content of the __metadata id and uri field is that they contain URLs. Here an example from our reference scenario. 
		"__metadata" : {
			"id" : "http://localhost:8080/olingo/ReferenceScenario.svc/Rooms('1')",
			"uri" : "http://localhost:8080/olingo/ReferenceScenario.svc/Rooms('1')",
			"type" : "RefScenario.Room",
			"etag" : "W/\"1\""
		},
The key here is a simple String but if it would be a date like in your example the key would be encoded based on the URL specification. Nonetheless both fields should be taken as simple Strings and should not be used to extract the key values as they are present inside the payload or the URL which was used to access this resource. So right now I do not think that Olingo needs a feature where we can switch off the encoding. WDYT?

Issues can always be opened here: https://issues.apache.org/jira/browse/OLINGO/?selectedTab=com.atlassian.jira.jira-projects-plugin:summary-panel

Best Regards,
Christian

-----Original Message-----
From: Tim Wernick [mailto:tim.wernick@wernick-net.de] 
Sent: Dienstag, 7. Oktober 2014 15:29
To: user@olingo.apache.org
Subject: Re: How to avoid urlencoding in datetime keys

Dear all,
I've had a look at the ABNF of the Odata Protocol hosted at OASIS
(https://tools.oasis-open.org/version-control/browse/wsvn/odata/trunk/spec/ABNF/odata-abnf-construction-rules.txt)
regarding the topic of the ID (took only the parts related to the id in
my case I am following the path of the compoundKey):

keyPredicate = simpleKey / compoundKey

compoundKey = OPEN keyValuePair *( COMMA keyValuePair ) CLOSE

keyValuePair = ( primitiveKeyProperty / keyPropertyAlias ) EQ 	
keyPropertyValue

keyPropertyValue = primitiveLiteral

keyPropertyAlias = odataIdentifier

primitiveLiteral = nullValue
                 / booleanValue
                 / ...
                 / dateTimeOffsetValue
                 / ...
                 / geometryPolygon

dateTimeOffsetValue = year "-" month "-" day "T" hour ":" minute [ ":"
second [ "." fractionalSeconds ] ] ( "Z" / sign hour ":" minute )

That said my assumption is that encoding the colon as it is done using
the class org.apache.olingo.odata2.core.commons.Encoder inside the
AtomEntryEntityProducer.createEntryKey is a bug, right?

Is there any chance that this will be fixed in the future? Where's the
correct place to file such a bug report?

kind regards


Tim

Am 02.10.2014 17:11, schrieb Tim Wernick:
> Thanks Christian for your prompt reply!
> 
> What I don't quite understand is why olingo generates a urlencoded
> datetime for the key contained in the json payload. The complete
> generated json data looks like this (partly anonymized ;-)):
> 
> {
> 	"__metadata":
> 	
> {"id":"entity(payComponentCode='xyz',payDate=datetime'2013-10-31T00%3A00%3A00',userId='102')",
> 	
> "uri":"entity(payComponentCode='xyz',payDate=datetime'2013-10-31T00%3A00%3A00',userId='102')",
> 		"type":"ABC.entity"},
> 	"payComponentCode":"xyz",
> 	"payDate":"\/Date(1383177600000)\/",
> 	"userId":"102",
> 	"value":"1000.0"
> }
> 
> As the colons in the rest of the json payload seem not to be any problem
> I would have expected that especially the key would be left untouched
> and still have the colon instead of the urlencoding of the colon. Or at
> least that there would be a method in the EntityProviderWriteProperties
> where I would be able to switch on/off the urlencoding.
> 
> kind regards
> 
> 
> Tim
> 
> Am 02.10.2014 15:03, schrieb Amend, Christian:
>> Hi Tim,
>>
>> there is no way to do this. We once saw this behavior because OData4J tried to interpret the atom:id tag where we put this encoded URL. But the atom:id tag should not be interpreted because you cannot be sure that it always contains an URL. Some services might write a GUID in there. This is why we have put not any effort in this issue. The atom:id tag should be treated as a unique String within the atom document and should not be interpreted.
>>
>> Best Regards,
>> Christian
>>
>> -----Original Message-----
>> From: Tim Wernick [mailto:tim.wernick@wernick-net.de] 
>> Sent: Donnerstag, 2. Oktober 2014 14:52
>> To: user@olingo.apache.org
>> Subject: How to avoid urlencoding in datetime keys
>>
>> Dear all,
>> I am currently trying to upsert an odata object which has a key like this:
>>
>> payComponentCode='xyz',payDate=datetime'2013-10-31T00:00:00',userId='102'
>>
>> The service I am connecting to is based on odata4j. Somehow olingo
>> urlencodes the datetime key part so that the key looks like
>>
>> payComponentCode='xyz',payDate=datetime'2013-10-31T00%3A00%3A00',userId='102'
>>
>> I am upserting the object using the following code:
>>
>> ODataResponse response = computeUpdateResponse(edm, contentType,
>> 		entitySetName, data);
>> String uri = "/odata/v2/upsert";
>> String sHost = getHostUrl();
>> StringBuilder url = new StringBuilder();
>> if (!uri.startsWith(sHost)) {
>> 	url.append(sHost).append(uri);
>> } else {
>> 	url.append(uri);
>> }
>> HttpPost post = new HttpPost(url.toString());
>> post.setEntity(new InputStreamEntity(
>> 		(InputStream) response.getEntity(), -1));
>> if (!externalClient)
>> 	post.addHeader(new BasicScheme().authenticate(basicCredentials,
>> 			post));
>> post.addHeader("accept", contentType);
>> post.addHeader("content-type", contentType);
>> HttpResponse httpResponse = httpClient.execute(post);
>> HttpEntity entity = httpResponse.getEntity();
>> ...
>> EntityUtils.consume(entity);
>>
>> The computeUpdateResponse contains the following code:
>>
>> EdmEntityContainer entityContainer = edm.getDefaultEntityContainer();
>> EdmEntitySet entitySet = entityContainer.getEntitySet(entitySetName);
>>
>> // We only want to send the properties that need to be changed
>> List<SelectItem> select = buildSelectItemList(entitySet, entitySetName,
>> 		data.keySet());
>> List<ArrayList<NavigationPropertySegment>> navProps = new
>> ArrayList<ArrayList<NavigationPropertySegment>>();
>>
>> navProps.add((ArrayList<NavigationPropertySegment>)
>> buildNavigationPropertySegmentList(
>> 		entitySet, entitySetName, data.keySet()));
>>
>> ExpandSelectTreeNode expandSelectTreeNode = UriParser
>> 		.createExpandSelectTree(select, navProps);
>>
>> EntityProviderWriteProperties properties = EntityProviderWriteProperties
>> 		.serviceRoot(new URI(""))
>> 		.expandSelectTree(expandSelectTreeNode)
>> 		.omitJsonWrapper(true)
>> 		.build();
>> ODataResponse response = EntityProvider.writeEntry(contentType,
>> 		entitySet, data, properties);
>>
>> As a result I get the following message from the server:
>>
>> bad valueString [datetime'2013-10-31T00%3A00%3A00'] as part of keyString
>> [payComponentCode='xyz',payDate=datetime'2013-10-31T00%3A00%3A00',userId='102']
>>
>> How can I avoid the urlencoding of the datetime keypart?
>>
>> Thanks in advance for your help!
>>
>> kind regards
>>
>>
>> Tim
>>
> 
> 


Re: How to avoid urlencoding in datetime keys

Posted by Tim Wernick <ti...@wernick-net.de>.
Dear all,
I've had a look at the ABNF of the Odata Protocol hosted at OASIS
(https://tools.oasis-open.org/version-control/browse/wsvn/odata/trunk/spec/ABNF/odata-abnf-construction-rules.txt)
regarding the topic of the ID (took only the parts related to the id in
my case I am following the path of the compoundKey):

keyPredicate = simpleKey / compoundKey

compoundKey = OPEN keyValuePair *( COMMA keyValuePair ) CLOSE

keyValuePair = ( primitiveKeyProperty / keyPropertyAlias ) EQ 	
keyPropertyValue

keyPropertyValue = primitiveLiteral

keyPropertyAlias = odataIdentifier

primitiveLiteral = nullValue
                 / booleanValue
                 / ...
                 / dateTimeOffsetValue
                 / ...
                 / geometryPolygon

dateTimeOffsetValue = year "-" month "-" day "T" hour ":" minute [ ":"
second [ "." fractionalSeconds ] ] ( "Z" / sign hour ":" minute )

That said my assumption is that encoding the colon as it is done using
the class org.apache.olingo.odata2.core.commons.Encoder inside the
AtomEntryEntityProducer.createEntryKey is a bug, right?

Is there any chance that this will be fixed in the future? Where's the
correct place to file such a bug report?

kind regards


Tim

Am 02.10.2014 17:11, schrieb Tim Wernick:
> Thanks Christian for your prompt reply!
> 
> What I don't quite understand is why olingo generates a urlencoded
> datetime for the key contained in the json payload. The complete
> generated json data looks like this (partly anonymized ;-)):
> 
> {
> 	"__metadata":
> 	
> {"id":"entity(payComponentCode='xyz',payDate=datetime'2013-10-31T00%3A00%3A00',userId='102')",
> 	
> "uri":"entity(payComponentCode='xyz',payDate=datetime'2013-10-31T00%3A00%3A00',userId='102')",
> 		"type":"ABC.entity"},
> 	"payComponentCode":"xyz",
> 	"payDate":"\/Date(1383177600000)\/",
> 	"userId":"102",
> 	"value":"1000.0"
> }
> 
> As the colons in the rest of the json payload seem not to be any problem
> I would have expected that especially the key would be left untouched
> and still have the colon instead of the urlencoding of the colon. Or at
> least that there would be a method in the EntityProviderWriteProperties
> where I would be able to switch on/off the urlencoding.
> 
> kind regards
> 
> 
> Tim
> 
> Am 02.10.2014 15:03, schrieb Amend, Christian:
>> Hi Tim,
>>
>> there is no way to do this. We once saw this behavior because OData4J tried to interpret the atom:id tag where we put this encoded URL. But the atom:id tag should not be interpreted because you cannot be sure that it always contains an URL. Some services might write a GUID in there. This is why we have put not any effort in this issue. The atom:id tag should be treated as a unique String within the atom document and should not be interpreted.
>>
>> Best Regards,
>> Christian
>>
>> -----Original Message-----
>> From: Tim Wernick [mailto:tim.wernick@wernick-net.de] 
>> Sent: Donnerstag, 2. Oktober 2014 14:52
>> To: user@olingo.apache.org
>> Subject: How to avoid urlencoding in datetime keys
>>
>> Dear all,
>> I am currently trying to upsert an odata object which has a key like this:
>>
>> payComponentCode='xyz',payDate=datetime'2013-10-31T00:00:00',userId='102'
>>
>> The service I am connecting to is based on odata4j. Somehow olingo
>> urlencodes the datetime key part so that the key looks like
>>
>> payComponentCode='xyz',payDate=datetime'2013-10-31T00%3A00%3A00',userId='102'
>>
>> I am upserting the object using the following code:
>>
>> ODataResponse response = computeUpdateResponse(edm, contentType,
>> 		entitySetName, data);
>> String uri = "/odata/v2/upsert";
>> String sHost = getHostUrl();
>> StringBuilder url = new StringBuilder();
>> if (!uri.startsWith(sHost)) {
>> 	url.append(sHost).append(uri);
>> } else {
>> 	url.append(uri);
>> }
>> HttpPost post = new HttpPost(url.toString());
>> post.setEntity(new InputStreamEntity(
>> 		(InputStream) response.getEntity(), -1));
>> if (!externalClient)
>> 	post.addHeader(new BasicScheme().authenticate(basicCredentials,
>> 			post));
>> post.addHeader("accept", contentType);
>> post.addHeader("content-type", contentType);
>> HttpResponse httpResponse = httpClient.execute(post);
>> HttpEntity entity = httpResponse.getEntity();
>> ...
>> EntityUtils.consume(entity);
>>
>> The computeUpdateResponse contains the following code:
>>
>> EdmEntityContainer entityContainer = edm.getDefaultEntityContainer();
>> EdmEntitySet entitySet = entityContainer.getEntitySet(entitySetName);
>>
>> // We only want to send the properties that need to be changed
>> List<SelectItem> select = buildSelectItemList(entitySet, entitySetName,
>> 		data.keySet());
>> List<ArrayList<NavigationPropertySegment>> navProps = new
>> ArrayList<ArrayList<NavigationPropertySegment>>();
>>
>> navProps.add((ArrayList<NavigationPropertySegment>)
>> buildNavigationPropertySegmentList(
>> 		entitySet, entitySetName, data.keySet()));
>>
>> ExpandSelectTreeNode expandSelectTreeNode = UriParser
>> 		.createExpandSelectTree(select, navProps);
>>
>> EntityProviderWriteProperties properties = EntityProviderWriteProperties
>> 		.serviceRoot(new URI(""))
>> 		.expandSelectTree(expandSelectTreeNode)
>> 		.omitJsonWrapper(true)
>> 		.build();
>> ODataResponse response = EntityProvider.writeEntry(contentType,
>> 		entitySet, data, properties);
>>
>> As a result I get the following message from the server:
>>
>> bad valueString [datetime'2013-10-31T00%3A00%3A00'] as part of keyString
>> [payComponentCode='xyz',payDate=datetime'2013-10-31T00%3A00%3A00',userId='102']
>>
>> How can I avoid the urlencoding of the datetime keypart?
>>
>> Thanks in advance for your help!
>>
>> kind regards
>>
>>
>> Tim
>>
> 
> 


Re: How to avoid urlencoding in datetime keys

Posted by Tim Wernick <ti...@wernick-net.de>.
Thanks Christian for your prompt reply!

What I don't quite understand is why olingo generates a urlencoded
datetime for the key contained in the json payload. The complete
generated json data looks like this (partly anonymized ;-)):

{
	"__metadata":
	
{"id":"entity(payComponentCode='xyz',payDate=datetime'2013-10-31T00%3A00%3A00',userId='102')",
	
"uri":"entity(payComponentCode='xyz',payDate=datetime'2013-10-31T00%3A00%3A00',userId='102')",
		"type":"ABC.entity"},
	"payComponentCode":"xyz",
	"payDate":"\/Date(1383177600000)\/",
	"userId":"102",
	"value":"1000.0"
}

As the colons in the rest of the json payload seem not to be any problem
I would have expected that especially the key would be left untouched
and still have the colon instead of the urlencoding of the colon. Or at
least that there would be a method in the EntityProviderWriteProperties
where I would be able to switch on/off the urlencoding.

kind regards


Tim

Am 02.10.2014 15:03, schrieb Amend, Christian:
> Hi Tim,
> 
> there is no way to do this. We once saw this behavior because OData4J tried to interpret the atom:id tag where we put this encoded URL. But the atom:id tag should not be interpreted because you cannot be sure that it always contains an URL. Some services might write a GUID in there. This is why we have put not any effort in this issue. The atom:id tag should be treated as a unique String within the atom document and should not be interpreted.
> 
> Best Regards,
> Christian
> 
> -----Original Message-----
> From: Tim Wernick [mailto:tim.wernick@wernick-net.de] 
> Sent: Donnerstag, 2. Oktober 2014 14:52
> To: user@olingo.apache.org
> Subject: How to avoid urlencoding in datetime keys
> 
> Dear all,
> I am currently trying to upsert an odata object which has a key like this:
> 
> payComponentCode='xyz',payDate=datetime'2013-10-31T00:00:00',userId='102'
> 
> The service I am connecting to is based on odata4j. Somehow olingo
> urlencodes the datetime key part so that the key looks like
> 
> payComponentCode='xyz',payDate=datetime'2013-10-31T00%3A00%3A00',userId='102'
> 
> I am upserting the object using the following code:
> 
> ODataResponse response = computeUpdateResponse(edm, contentType,
> 		entitySetName, data);
> String uri = "/odata/v2/upsert";
> String sHost = getHostUrl();
> StringBuilder url = new StringBuilder();
> if (!uri.startsWith(sHost)) {
> 	url.append(sHost).append(uri);
> } else {
> 	url.append(uri);
> }
> HttpPost post = new HttpPost(url.toString());
> post.setEntity(new InputStreamEntity(
> 		(InputStream) response.getEntity(), -1));
> if (!externalClient)
> 	post.addHeader(new BasicScheme().authenticate(basicCredentials,
> 			post));
> post.addHeader("accept", contentType);
> post.addHeader("content-type", contentType);
> HttpResponse httpResponse = httpClient.execute(post);
> HttpEntity entity = httpResponse.getEntity();
> ...
> EntityUtils.consume(entity);
> 
> The computeUpdateResponse contains the following code:
> 
> EdmEntityContainer entityContainer = edm.getDefaultEntityContainer();
> EdmEntitySet entitySet = entityContainer.getEntitySet(entitySetName);
> 
> // We only want to send the properties that need to be changed
> List<SelectItem> select = buildSelectItemList(entitySet, entitySetName,
> 		data.keySet());
> List<ArrayList<NavigationPropertySegment>> navProps = new
> ArrayList<ArrayList<NavigationPropertySegment>>();
> 
> navProps.add((ArrayList<NavigationPropertySegment>)
> buildNavigationPropertySegmentList(
> 		entitySet, entitySetName, data.keySet()));
> 
> ExpandSelectTreeNode expandSelectTreeNode = UriParser
> 		.createExpandSelectTree(select, navProps);
> 
> EntityProviderWriteProperties properties = EntityProviderWriteProperties
> 		.serviceRoot(new URI(""))
> 		.expandSelectTree(expandSelectTreeNode)
> 		.omitJsonWrapper(true)
> 		.build();
> ODataResponse response = EntityProvider.writeEntry(contentType,
> 		entitySet, data, properties);
> 
> As a result I get the following message from the server:
> 
> bad valueString [datetime'2013-10-31T00%3A00%3A00'] as part of keyString
> [payComponentCode='xyz',payDate=datetime'2013-10-31T00%3A00%3A00',userId='102']
> 
> How can I avoid the urlencoding of the datetime keypart?
> 
> Thanks in advance for your help!
> 
> kind regards
> 
> 
> Tim
> 


RE: How to avoid urlencoding in datetime keys

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

there is no way to do this. We once saw this behavior because OData4J tried to interpret the atom:id tag where we put this encoded URL. But the atom:id tag should not be interpreted because you cannot be sure that it always contains an URL. Some services might write a GUID in there. This is why we have put not any effort in this issue. The atom:id tag should be treated as a unique String within the atom document and should not be interpreted.

Best Regards,
Christian

-----Original Message-----
From: Tim Wernick [mailto:tim.wernick@wernick-net.de] 
Sent: Donnerstag, 2. Oktober 2014 14:52
To: user@olingo.apache.org
Subject: How to avoid urlencoding in datetime keys

Dear all,
I am currently trying to upsert an odata object which has a key like this:

payComponentCode='xyz',payDate=datetime'2013-10-31T00:00:00',userId='102'

The service I am connecting to is based on odata4j. Somehow olingo
urlencodes the datetime key part so that the key looks like

payComponentCode='xyz',payDate=datetime'2013-10-31T00%3A00%3A00',userId='102'

I am upserting the object using the following code:

ODataResponse response = computeUpdateResponse(edm, contentType,
		entitySetName, data);
String uri = "/odata/v2/upsert";
String sHost = getHostUrl();
StringBuilder url = new StringBuilder();
if (!uri.startsWith(sHost)) {
	url.append(sHost).append(uri);
} else {
	url.append(uri);
}
HttpPost post = new HttpPost(url.toString());
post.setEntity(new InputStreamEntity(
		(InputStream) response.getEntity(), -1));
if (!externalClient)
	post.addHeader(new BasicScheme().authenticate(basicCredentials,
			post));
post.addHeader("accept", contentType);
post.addHeader("content-type", contentType);
HttpResponse httpResponse = httpClient.execute(post);
HttpEntity entity = httpResponse.getEntity();
...
EntityUtils.consume(entity);

The computeUpdateResponse contains the following code:

EdmEntityContainer entityContainer = edm.getDefaultEntityContainer();
EdmEntitySet entitySet = entityContainer.getEntitySet(entitySetName);

// We only want to send the properties that need to be changed
List<SelectItem> select = buildSelectItemList(entitySet, entitySetName,
		data.keySet());
List<ArrayList<NavigationPropertySegment>> navProps = new
ArrayList<ArrayList<NavigationPropertySegment>>();

navProps.add((ArrayList<NavigationPropertySegment>)
buildNavigationPropertySegmentList(
		entitySet, entitySetName, data.keySet()));

ExpandSelectTreeNode expandSelectTreeNode = UriParser
		.createExpandSelectTree(select, navProps);

EntityProviderWriteProperties properties = EntityProviderWriteProperties
		.serviceRoot(new URI(""))
		.expandSelectTree(expandSelectTreeNode)
		.omitJsonWrapper(true)
		.build();
ODataResponse response = EntityProvider.writeEntry(contentType,
		entitySet, data, properties);

As a result I get the following message from the server:

bad valueString [datetime'2013-10-31T00%3A00%3A00'] as part of keyString
[payComponentCode='xyz',payDate=datetime'2013-10-31T00%3A00%3A00',userId='102']

How can I avoid the urlencoding of the datetime keypart?

Thanks in advance for your help!

kind regards


Tim