Fiware-Service HTTP header needed for Orion CB - fiware-orion

Trying to connect to my Orion CB which has entities created via IoTAgentCPP/IDAS. Both are of latest Docker version (okt 30 2015). All works fine using the FIGWAY Python scripts: Creating IDAS Service, Register Device, Send Observation, see Entity created and changed attributes via OCB.
But using any WireCloud Mashup widget like the NGSI Browser Widget that sends NSGI requests to the OCB the widget remains blanc, since the OCB sends back:
{
"errorCode" : {
"code" : "404",
"reasonPhrase" : "No context element found"
}
}
This reply is also received when querying via curl:
curl my_remote_ocb_host:1026/v1/contextEntities -S --header 'Accept: application/json'
If I add the header --header 'Fiware-Service: fiwareiot' (which was specified when creating the IoT service w IDAS) to the curl-command line, then I get expected responses from the OCB.
However, the Widgets and Operators in WC have no means to add the Fiware-Service HTTP-Header. This is what I receive from WC via the Lab proxy, using protocol capture, at the OCB host:
POST /v1/queryContext?limit=20&details=on&offset=0 HTTP/1.1
Host: <myhost>:1026
origin: https://mashup.lab.fiware.org
Cookie: ..
Content-Length: 45
via: 1.1 mashup.lab.fiware.org (Wirecloud-python-Proxy/1.1)
accept-language: en-US,en;q=0.8,de;q=0.6,fr;q=0.4,nl;q=0.2,it;q=0.2
accept-encoding: gzip, deflate
x-forwarded-host: <myhost>:1026
x-forwarded-for: ..
accept: application/json
user-agent: ..
connection: keep-alive
x-requested-with: XMLHttpRequest
referer: https://mashup.lab.fiware.org/justb4/GeonovumTemperature1
X-Auth-Token: ..
content-type: application/json
{"entities":[{"id":".*","isPattern":"true"}]}
Response: HTTP/1.1 200 OK
Content-Length: 94
Content-Type: application/json
Date: Sat, 31 Oct 2015 13:23:44 GMT
{
"errorCode" : {
"code" : "404",
"reasonPhrase" : "No context element found"
}
}
Possibly the settings for WC Widgets/Operators need to be extended to allow for Fiware-Service HTTP headers, or is there another way for doing this using the current possibilities?

WireCloud supports adding the FIWARE-Service header when programming widgets and operators (see the documentation for more info). So this can be fixed by updating the basic set of widgets and operators provided in FIWARE Lab to support the FIWARE-Service header.
I have created an ticket in the issue tracker of the NGSI Browser widget for you. Please, create such a ticket for the other widgets/operators.
NOTE: You can go to the issue tracker of a component if opening their details and clicking on the issue tracker button:

Related

sapui5 OData.V4.oDataModel with Teiid 11.2 / Wildfly

I am trying to use SAPUI5 in a SPA to display data from a TEIID/Wildfly ODataV4 service. When SAPUI5 ODATA V4 data model is bound to the service, I run into several errors. I thereby connect via proxy (grunt-connect-proxy2) to the odata service. Basic Auth works. The metadata file above the marked service folder in the attached image (screenshot1) is the actual metadata file of the service which, as you can see, is loaded correctly. So no CORS issue or authorization issue.
Screenshot1
The issue seems to be related to an CSRF Token request as far as I understand. Seems that Teiid/Wildfly is not answering the CSRF Token fetch request. Is there a way to configure Wildfly to answer the request or alternatively a way to disable CSRF requests for the odata V4 model? I have seen such an option in the constructor of the odata V2 model. How could a working configuration look like?
The following is a screenshot from the browser log:
I observed a further issue, from which I do not know if it is related to the previous one (there is also a X-CSRF-Token: Fetch involved), or if a have something more missing somewhere. The second issue happens when I use an aggregation binding to bind a odata collection to a sapui5 list. The response looks like
Request URL: http://localhost:9001/odata4/svc/my_nutri_diary/$batch
Request Method: POST Status Code: 406 Not Acceptable Remote Address:
[::1]:9001 Referrer Policy: no-referrer-when-downgrade Response
Headersview source access-control-allow-credentials: true
access-control-allow-origin: http://localhost:9001 cache-control:
no-cache, no-store, must-revalidate connection: close
content-encoding: gzip content-length: 125 content-type:
application/json;odata.metadata=minimal date: Mon, 12 Nov 2018
20:04:30 GMT expires: 0 odata-version: 4.0 pragma: no-cache server:
WildFly/11 x-powered-by: Undertow/1 Request Headersview source Accept:
multipart/mixed Accept-Encoding: gzip, deflate, br Accept-Language: de
Authorization: Basic SU1TVXNlcjpJTVM0Zm9ydW0l Connection: keep-alive
Content-Length: 329 Content-Type: multipart/mixed;
boundary=batch_id-1542053070786-11 Cookie: sidebar_collapsed=false;
cycle_analytics_help_dismissed=1;
__utmz=111872281.1539128843.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); __utma=111872281.767670437.1539128843.1541866362.1541870562.42 DNT: 1 Host: localhost:9001 MIME-Version: 1.0 OData-MaxVersion: 4.0
OData-Version: 4.0 Origin: http://localhost:9001 Referer:
http://localhost:9001/ User-Agent: Mozilla/5.0 (iPhone; CPU iPhone OS
11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko)
Version/11.0 Mobile/15A372 Safari/604.1 X-CSRF-Token: Fetch
X-Requested-With: XMLHttpRequest Request Payload
--batch_id-1542053070786-11 Content-Type:application/http Content-Transfer-Encoding:binary GET Profile?$skip=0&$top=100 HTTP/1.1
Accept:application/json;odata.metadata=minimal;IEEE754Compatible=true
Accept-Language:de
Content-Type:application/json;charset=UTF-8;IEEE754Compatible=true
--batch_id-1542053070786-11--
Thanks for your advice!
Best regards,
Christoph
Further note regarding search for a workaround: As I am currently searching for a workaround to be able to use the odata.v4 model, I found the following blog post:
https://blogs.sap.com/2015/08/05/disable-csrf-token-for-odata-calls-using-sap-netweaver-gateway/
However, the approach does not seem to work for the odata.v4 model as it has a different interface. There is no setHeaders() function to set custom headers on the datamodel. I therefore tried to set the header up via
$.ajaxSetup({headers: {'X-Requested-With': 'X'}});
Unfortunately, this also does not work. If someone has the odata.v4 Model running with TEIID or Olingo v4 it would be great if he could give me a feedback on how he had worked around this issue.

Azure REST API : oAuth2 authentication granted but invalid token on request

I have a question about authenticating to azure mobile management API, to send push informations to the API.
I well manage to authentify and receive a token bearer matching to the provided data (tenant id, client id, client secret...), but when I try to create a campaign, I receive the following response :
[2016-10-25 11:45:51] (::1) fail to send send request https://management.azure.com/subscriptions/fb8226dc-194f-4562-9dc9-c72f56bd728a/resourcegroups/MobileEngagement/providers/Microsoft.MobileEngagement/appcollections/XX-Collection/apps/XX-TEST-android/campaigns/announcements?api-version=2014-12-01
with {"name":"The Evian Championship 20... - 25/10/2016
11:45:50","type":"only_notif","deliveryTime":"any","pushMode":"one-shot","notificationTickerIcon":true,"notificationIcon":true,"notificationCloseable":true,"notificationSound":true,"notificationVibrate":false,"notificationTitle":"Soci\u00e9t\u00e9
G\u00e9n\u00e9rale","notificationMessage":"The Evian Championship
2016","actionUrl":"://webviews/main/build/events.html","notificationType":"system"}
| "HTTP/1.1 401 Unauthorized
Cache-Control: no-cache
Pragma: no-cache
Content-Type: application/json; charset=utf-8
Expires: -1
x-ms-failure-cause: gateway
x-ms-request-id: 40e30675-2144-452a-9ab9-632a393d8783
x-ms-correlation-request-id: 40e30675-2144-452a-9ab9-632a393d8783
x-ms-routing-request-id: WESTEUROPE:20161025T094550Z:40e30675-2144-452a-9ab9-632a393d8783
Strict-Transport-Security: max-age=31536000; includeSubDomains
Date: Tue, 25 Oct 2016 09:45:49 GMT
Connection: close
Content-Length: 281
{"error":{"code":"InvalidAuthenticationToken","message":"The received access token is not valid: at least one of the claims 'puid'
or 'altsecid' or 'oid' should be present. If you are accessing as
application please make sure service principal is properly created in
the tenant."}}" was returned
Here's the request :
POST
/subscriptions/fb8226dc-194f-4562-9dc9-c72f56bd728a/resourcegroups/MobileEngagement/providers/Microsoft.MobileEngagement/appcollections/XX-Collection/apps/XX-TEST-android/campaigns/announcements?api-version=2014-12-01
HTTP/1.1 Host: management.azure.com Authorization: bearer
eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ikk2b0J3NFZ6QkhPcWxlR3JWMkFKZEE1RW1YYyIsImtpZCI6Ikk2b0J3NFZ6QkhPcWxlR3JWMkFKZEE1RW1YYyJ9.eyJhdWQiOiJodHRwczovL21hbmFnZW1lbnQuYXp1cmUuY29tLyIsImlzcyI6Imh0dHBzOi8vc3RzLndpbmRvd3MubmV0LzRmNGFkYjA3LWU5OWQtNDg5NC04OGZjLTZkYzc4ODAzNDI3Zi8iLCJpYXQiOjE0NzczOTUxNzEsIm5iZiI6MTQ3NzM5NTE3MSwiZXhwIjoxNDc3Mzk5MDcxLCJhcHBpZCI6IjUzNzMyOTAwLTU2NGMtNGI2OS1hNGRhLTU0OTQ0ODVkYTFhNiIsImFwcGlkYWNyIjoiMSIsImlkcCI6Imh0dHBzOi8vc3RzLndpbmRvd3MubmV0LzRmNGFkYjA3LWU5OWQtNDg5NC04OGZjLTZkYzc4ODAzNDI3Zi8iLCJ0aWQiOiI0ZjRhZGIwNy1lOTlkLTQ4OTQtODhmYy02ZGM3ODgwMzQyN2YiLCJ2ZXIiOiIxLjAifQ.WvWXETt9IFy_eX2Q8LlguTec9KA2TLgILUs10QULNMYgf1sHUpXdnRhDBqq5Foo_gwF_u2zl1NNYRLmdN3Q0IR3LPspiutAhC_KXvGXmJH2TtxTi9U2bt1Zvf5BsafHkxDdlDG6vymu-3O4cK9HQMu7l0XtPqzcEHcQny94xAq66_TSNa3FhZclwEBnaTI81B5g9NzvET10C0j8ZW0OsRNzc0-czS8RqtXulp1rkIEQc7VhTTDx9feSPi3BJlyhiKxUzfnEn8xUkfqlUEQuqyerqUoRIlbFvhhOT7Gjo6_WJN21Wn-23gcEchaRETWzYh-nTJSeKFzwA-mROOdmUzw
User-Agent: Guzzle/5.3.1 curl/7.50.0 PHP/5.6.25 Content-Length: 455
(note : I changed some characters in this displayed bearer by security reasons)
The (real) bearer was obtained requesting https://login.microsoftonline.com/{TENANT_ID}/oauth2/token, using this body :
grant_type=client_credentials&client_id={CLIENT_ID}&client_secret={CLIENT_SECRET}&resource=https://management.azure.com/
Would you have an idea about the reason why the API returned this message ?
Thanks a lot !
The received access token is not valid: at least one of the claims 'puid' or 'altsecid' or 'oid' should be present. If you are accessing as application please make sure service principal is properly created in the tenant
It seems that your access token is not valid. I would suggest you follow with this article to get a new token then try again.

Questions on proper REST api design specifically on the PUT action when updating a resource

I'm creating a REST interface (aren't we all), and I want to UPDATE a resource.
So, I think to use a PUT.
So, i read this.
My take away is that i PUT to a URL like this
/hc/api/v1/organizer/event/762d36c2-afc5-4c51-84eb-9b5b0ef2990c
with a payload, then a permanent redirect to the URL that it can GET an updated version of the resource.
In this case it happens to be the same URL, different action.
So my questions are:
Is my understanding of updating a resource correct in using a PUT, and is my understanding of the use of the PUT correct.
When a client gets a redirect does it do the same action on the redirected URL as it did on the original URL? If its "depends" is there a standard most clients follow?
I ask the 2nd question, because POSTMAN and my JQuery AJAX calls are choking. JQuery because of net::ERR_TOO_MANY_REDIRECTS. So is it redirecting and trying the PUT again, which it will get another REDIRECT?
curl blows up too but even though it says if it gets a 301 it will switch to a GET, it doesn't really seem to do that when i look at the output (below).
When curl follows a redirect and the request is not a plain GET (for example POST or PUT), it will do the following request with a GET if the HTTP response was 301, 302, or 303. If the response code was any other 3xx code, curl will re-send the following request using the same unmodified method.
CURL OUTPUT (edited for brevity) (also note how it says its going to switch to a GET [incorrectly from a POST], but then it seems to do a PUT anyway):
curl -X PUT -H "Authorization: Basic AUTHZ==" -H "Content-Type: application/json" -H "Cache-Control: no-cache" -H "Postman-Token: e80657f0-a8f5-af77-1d9d-d7bc22ed0b30" -d '{ JSONDATA"}' http://localhost:8080/hc/api/v1/organizer/event/762d36c2-afc5-4c51-84eb-9b5b0ef2990c -v -L
* Hostname was NOT found in DNS cache
* Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 8080 (#0)
> PUT /hc/api/v1/organizer/event/762d36c2-afc5-4c51-84eb-9b5b0ef2990c HTTP/1.1
> User-Agent: curl/7.37.1
> Host: localhost:8080
> Accept: */*
> Authorization: Basic AUTHZ==
> Content-Type: application/json
> Cache-Control: no-cache
> Postman-Token: e80657f0-a8f5-af77-1d9d-d7bc22ed0b30
> Content-Length: 203
>
* upload completely sent off: 203 out of 203 bytes
< HTTP/1.1 301 Moved Permanently
< Connection: keep-alive
< X-Powered-By: Undertow/1
< Set-Cookie: rememberMe=deleteMe; Path=/hc; Max-Age=0; Expires=Fri, 20-Feb-2015 03:53:28 GMT
< Set-Cookie: JSESSIONID=uwI3_41LAa7vlvapTsrZdw10.macbook-air; path=/hc
* Server WildFly/8 is not blacklisted
< Server: WildFly/8
< Location: /hc/api/v1/organizer/event/762d36c2-afc5-4c51-84eb-9b5b0ef2990c
< Content-Length: 0
< Date: Sat, 21 Feb 2015 03:53:28 GMT
<
* Connection #0 to host localhost left intact
* Issue another request to this URL: 'http://localhost:8080/hc/api/v1/organizer/event/762d36c2-afc5-4c51-84eb-9b5b0ef2990c'
* Switch from POST to GET
* Found bundle for host localhost: 0x7f9e4b415430
* Re-using existing connection! (#0) with host localhost
* Connected to localhost (127.0.0.1) port 8080 (#0)
> PUT /hc/api/v1/organizer/event/762d36c2-afc5-4c51-84eb-9b5b0ef2990c HTTP/1.1
> User-Agent: curl/7.37.1
> Host: localhost:8080
> Accept: */*
> Authorization: Basic dGVzdHVzZXIxOlBhc3N3b3JkMQ==
> Content-Type: application/json
> Cache-Control: no-cache
> Postman-Token: e80657f0-a8f5-af77-1d9d-d7bc22ed0b30
>
< HTTP/1.1 500 Internal Server Error
< Connection: keep-alive
< Set-Cookie: JSESSIONID=fDXxlH2xI-0-DEaC6Dj5EhD9.macbook-air; path=/hc
< Content-Type: text/html; charset=UTF-8
< Content-Length: 8593
< Date: Sat, 21 Feb 2015 03:53:28 GMT
<
...failure ensues... It actually does a PUT
thanks in advance.
I think you're reading too much into the 301 redirect section.
If you want to update a resource using PUT, return:
201: if the resource was created
200: with the updated resource
The 301 in question only applies if there actually is a redirect in question - like, if something can be identified by name, and you need to redirect it to a url that has the id or something. (Maybe you refactor and people are still consuming the old endpoint).
So, do you really need to redirect your PUT requests? Because you should be sending back the updated resource within the same loop using 200, like stated above, instead of "redirecting to GET".
EDIT: Fix some spelling.

curl, play & expect 100 continue header

consider a web service written in play, which excepts POST request (for uploads). now, when testing this with a medium size image (~75K) I've found out a strange behaviour. well, code speaks more clearly than long explanations, so:
$ curl -vX POST localhost:9000/path/to/upload/API -H "Content-Type: image/jpeg" -d #/path/to/mascot.jpg
* Hostname was NOT found in DNS cache
* Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 9000 (#0)
> POST /path/to/upload/API HTTP/1.1
> User-Agent: curl/7.35.0
> Host: localhost:9000
> Accept: */*
> Content-Type: image/jpeg
> Content-Length: 27442
> Expect: 100-continue
>
< HTTP/1.1 100 Continue
< HTTP/1.1 200 OK
< Content-Type: application/json; charset=utf-8
< Content-Length: 16
<
* Connection #0 to host localhost left intact
{"success":true}
as you can see, curl decides to add the header Content-Length: 27442, but it's not true, the real size is 75211, and in play, I indeed got a body in size only 27442. of coarse, this is not the intended behaviour. so I tried a different tool, instead of curl I used the POST tool from libwww-perl:
cat /path/to/mascot.jpg | POST -uUsSeE -c image/jpeg http://localhost:9000/path/to/upload/API
POST http://localhost:9000/path/to/upload/API
User-Agent: lwp-request/6.03 libwww-perl/6.05
Content-Length: 75211
Content-Type: image/jpeg
200 OK
Content-Length: 16
Content-Type: application/json; charset=utf-8
Client-Date: Mon, 16 Jun 2014 09:21:00 GMT
Client-Peer: 127.0.0.1:9000
Client-Response-Num: 1
{"success":true}
this request succeeded. so I started to pay more attention to the differences between the tools. for starter: the Content-Length header was correct, but also, the Expect header was missing from the second try. I want the request to succeed either way. so the full list of headers as seen in play (via request.headers) is:
for curl:
ArrayBuffer((Content-Length,ArrayBuffer(27442)),
(Accept,ArrayBuffer(*/*)),
(Content-Type,ArrayBuffer(image/jpeg)),
(Expect,ArrayBuffer(100-continue)),
(User-Agent,ArrayBuffer(curl/7.35.0)),
(Host,ArrayBuffer(localhost:9000)))
for the libwww-perl POST:
ArrayBuffer((TE,ArrayBuffer(deflate,gzip;q=0.3)),
(Connection,ArrayBuffer(TE, close)),
(Content-Length,ArrayBuffer(75211)),
(Content-Type,ArrayBuffer(image/jpeg)),
(User-Agent,ArrayBuffer(lwp-request/6.03 libwww-perl/6.05)),
(Host,ArrayBuffer(localhost:9000)))
So my current thoughts are: the simpler perl tool used a single request, which is bad practice. the better way would be to wait for a 100 continue confirmation (especially if you gonna' upload a several GB of data...). curl would continue to send data until it receives a 200 OK or some bad request error code. So why play sends the 200 OK response without waiting for the next chunk? is it because curl specifies the wrong Content-Length? if it's wrong at all... (perhaps this refers to the size of the current chunk?).
so where's the problem lies? in curl or in the play webapp? and how do I fix it?
the problem was in my curl command. I used the -d argument, which is a short for --data or --data-ascii, when I should have used --data-binary argument.

AbsoluteURI support in Play Framework 2.1

As stated here:
http://www.w3.org/Protocols/rfc2616/rfc2616-sec5.html
To allow for transition to absoluteURIs in all requests in future versions of HTTP, all HTTP/1.1 servers MUST accept the absoluteURI form in requests, even though HTTP/1.1 clients will only generate them in requests to proxies.
I have client which sends POST-requests to my play-2.1.1 server. He sends it this way:
POST http://172.16.1.227:9000/A8%3aF9%3a4B%3a20%3a89%3a40/1089820966/ HTTP/1.1
Content-Length: 473
Content-Type: application/json
Date: Thu, 25 Apr 2013 15:44:43 GMT
Host: 172.16.1.227:9000
User-Agent: my-client
...some data...
All requests are rejected with "Action not found" error. The very same request which I send using curl is just fine and the only difference between them is curl send it with relative URI:
POST /A8%3aF9%3a4B%3a20%3a89%3a40/1089820966/ HTTP/1.1
Accept: */*
Content-Length: 593
Content-Type: application/json
Host: 172.16.1.227:9000
User-Agent: curl/7.30.0
I created the following simple workaround in Global.scala:
override def onRouteRequest(request: RequestHeader): Option[Handler] = {
if (request.path.startsWith("http://")) {
super.onRouteRequest(request.copy(
path = request.path.replace("http://"+request.host, "")
))
} else super.onRouteRequest(request)
}
And with this workaround all requests from my client are handled correctly.
So, is there more straightforward way to do it in Play Framework or thats the only way?
Thanks to #nraychaudhuri Play 2.2 supports absoluteURI-style request headers.
Here's the issue and pull request: https://github.com/playframework/playframework/pull/1060