Authenticating OnlineRouteTask qt10.2.3, oauth2.0.. and which URL

3756
8
Jump to solution
09-22-2015 06:49 AM
JakobGaardsted
New Contributor III

(executive summary: I'm looking for working samples of how to (oauth2-)authenticate 10.2.3-OnlineRouteTask to work with

online routing services; additionally what the correct URLs of those are.)

Actually, the oauth2 part is the only thing not causing me problems..?

It's the issue of how to pass that info on to ESRI/OnlineRouteTask  in a way that works?


I can correctly get an access_token from
https://www.arcgis.com/sharing/rest/oauth2/token/

with QNetworkRequest.

But I don't know how to instantiate ER::OnlineRouteTask with this info?

(note: my code succeeds in getting an online route, if I use

the public sampleserver6.arcgisonline.com service without authentication.)

OnlineRouteTask accepts an ER::UserCredentials argument,

but UC requires a 'referer', which I don't know what is?

  The docs for  'UserCredentials' are quite unclear,

but suggest it would contact the oauth server itself? (ie so I can't init it with data I've procured?)

(I also don't know, if it's for oauth1.0 or oauth2.0?)

The only 'docs' I've found are https: //developers.arcgis.com/qt/cpp/api-reference/class_esri_runtime_qt_1_1_user_credentials.html

The whole thing is worsened by, that none of it gives proper error messages;

instead, the 3 kinds of "responses" I get from ArcGisRuntime are

(1) whole map square turns blue? (this seems to happen if you attempt to configure

a RouteTask wrongly?)

(2) "routetask.solve" is started silently, but nothing every returns, neither success nor failure.

(3) some spurious stack trace crash in some "validateLicenseEsriforEmail??".

Also, I can't figure out which URL to actually use for online routing?

The ones I suspect to be correct, reply with "directory listing has been disabled for this item"

if I try to access them from a browser?

e.g. http: //route.arcgis.com/arcgis/rest/services/World/Route/NAServer/Route_World

(I'm using 10.2.3, because porting to 10.2.6 require more changes to our code base

than we have time for in our app release timeframe, e.g. 'graphicIds' changed from sync to async.

I have already ported our code to 10.2.6 (in a separate branch), which taught me

that it will take us a long time to fully port to 10.2.6 (ie where all features are working again.)

My outset is the ArcGIS Runtime-SDK-for-Qt samples,

specifically the "Routing(Online)" sample.

However, it makes no hint at how to authenticate,

and it uses demo server

http: //sampleserver6.arcgisonline.com/arcgis/rest/services/NetworkAnalysis/SanDiego/NAServer/Route

(also, I see the same example in 10.2.6 demos?)

Some URL's I've found are

http: //logistics.arcgis.com/arcgis/rest/services/World/Route/GPServer/FindRoutes

(but can this be used for Qt, or this intended for other sdk's? How does one find this out?)

This is the one I suspect is the right one to use:

http://route.arcgis.com/arcgis/rest/services/World/Route/NAServer/Route_World

but probably it should be https' -

https://route.arcgis.com/arcgis/rest/services/World/Route/NAServer/Route_World

However, if I try it, I don't get any errors.. I just never get any response from '.solve()' :-(.

Currently, my code looks like this:

  QString token, ref;

  token = EgisProj2::access_token;

  ref = "https://www.arcgis.com/sharing/rest/oauth2/token/";

  ER::UserCredentials creds;

  creds.setUserToken(token, ref);

  m_routingTask = ER::OnlineRouteTask(actualURL, creds);

which, when used with "https://route.arcgis.com/arcgis/rest/services/World/Route/NAServer/Route_World",

yields.. nada.. no error msg, no reply.

I'm finding I'm almost spending more time trying to resolve the authentication aspects of the app,

than I'm spending doing business logic app development with ESRI for my companies' actual domain

- not exactly what I was hoping for in a productivity library :-(.

What puzzles me the most, is that I get no hits when googling any of this

- it feels as if I'm the last man on earth still using Qt.   Which I don't quite understand,

because it's a wonderful library.

0 Kudos
1 Solution

Accepted Solutions
JakobGaardsted
New Contributor III

"Solution": I have now gotten it to work (10.2.6..), field report here:

I tried the suggestion for 10.2.3, but it doesn't appear it will work.

The remainder here, what I learned about getting it (a demo) to work on 10.2.6:

( - info I wish I could have googled, and which would have been very helpful to myself, over the past month

struggling with "not" getting this to work)

I ended up with this code:

//////////////////////////////////////////////////////////////////////////////////////////////

  // OACI apparently doesn't have to be long-lived?

  ER::OAuthClientInfo oauth(ttp_ClientID, ttp_secret, ER::OAuthMode::App);

  creds.setOAuthClientInfo(oauth); // (ER::UserCredentials)

  // ER::IdentityManager::setCredential(&creds, actualURL); 

  m_routingTask = new ER::OnlineRouteTask(actualURL, &creds);

  // NB - even though docs say 'const', it has to be NOT const  here.

  connect( m_routingTask, SIGNAL(solveTaskComplete(EsriRuntimeQt::RoutingResult*)), this, SLOT(onSolveTaskComplete(EsriRuntimeQt::RoutingResult*))); // const  const

//////////////////////////////////////////////////////////////////////////////////////////////

comments/ the lessons learned from this:

1 - (beware that this is for 'app' (not 'user'  mode - YMMV if not for app-mode.)

2 - IdentityManager is non-essential, it's a 'convenience' mechanism to isolate authentication aspects out of your app code.

3 - the lifetime of UserCredentials obj. is critical, it has to be longlived: If you use a stack-allocated obj, the app will crash and burn in mysterious ways (ie the OnlineRouteTask expects it to live as long as it does.) However, OAuthClientInfo can be shortlived stack-item.

4 - 'OAuthClientInfo' handles 'everything' on behalf of UserCredentials (in this specific context..), so no need to set any of the many other properties of UserCredentials (e.g. no 'token', no 'referer').

5 - the ER::Graphics items eventually added to your graphics-layer, must be heap-allocated.. If not, you CAN add them to your layer, and you won't get an error, but nothing will appear to work :-(.

6 - the 'solveTaskComplete' signal, in practice, is different from what the documentation says (doc says 'const', but it only works if you remove const.)

I'm not looking forward to porting our entire application from 10.2.3 to 10.2.6 in under a week,

given the different pointer-semantics,

especially given item 5, I expect a mountain of heap-allocation bugs 😞

Interestingly, on our running 10.2.3 development, I experience about zero heap corruption bugs 😞

View solution in original post

0 Kudos
8 Replies
JakobGaardsted
New Contributor III

Additional info: Actually, one of the assumed URL's I've found for the online routing service, from googling and older examples, is this one:

http://tasks.arcgisonline.com/ArcGIS/rest/services/NetworkAnalysis/ESRI_Route_NA/NAServer/Route

however, trying to use it with Esri 10.2.3, I just get this error:

'There was an error solving the route.  Unable to complete  operation.  'attributeParameterValues' parameter is invalid'

Given that the same service can be easily used 'by hand' (ie by just filling out the REST arguments by hand),

this error suggests that arcgis-10.2.3 is somehow filling out the request parameters wrongly..

And I can't figure out, what I can control/change, that would affect 'invalid attributeParameterValues'.

My impression is that 'http://tasks.arcgisonline.com' is just an older demo version of the API that is not currently relevant.  To me, I thought it might help to figure out how to authenticate this service my company is paying for the allegedly  privilege of accessing 🙂

0 Kudos
JakobGaardsted
New Contributor III

Further: based on current web docs, this is (approx..) the URL I assume to be correct for async online routing:

https://logistics.arcgis.com/arcgis/rest/services/World/Route/GPServer/FindRoutes

// submitJob?parameters");

(here I assume that the 'submitJob/parameters' part will be handled by arcGisRuntime..?)

based on this link:

ArcGIS REST API - Route servicewith asynchronous execution

http: //resources.arcgis.com/en/help/arcgis-rest-api/02r3/02r300000275000000.htm

But using that doesn't give any result, not even an error.

0 Kudos
JakobGaardsted
New Contributor III

For fun and out of desperation, I even tried this -

https://logistics.arcgis.com/arcgis/rest/services/World/Route/GPServer/FindRoutes/submitJob?token=in...

as argument for OnlineRouteTask , but it gave as little result as everything else.

To sum up: the only things I get "working"/reacting with OnlineRouteTask, are

http: //sampleserver6.arcgisonline.com/arcgis/rest/services/NetworkAnalysis/SanDiego/NAServer/Route

(the sandiego sample)

and

http://tasks.arcgisonline.com/ArcGIS/rest/services/NetworkAnalysis/ESRI_Route_NA/NAServer/Route

.. because it at least reacts with an error.

Sadly, our clients live everywhere else but San Diego 😞

0 Kudos
JakobGaardsted
New Contributor III

Another thing: I noticed, that the code hangs already in

m_routingTask.defaultParameters();

(which makes sense, as it presumably needs correct connection to online service for this info.)

Weirdly, if I use this 'bogus' URL for the routetask init:

https://logistics.arcgis.com/arcgis/rest/services/World/Route/GPServer/FindRoutes/submitJob?token=a_...

then it actually gets past 'defaultParameters' - (but fails on the actual service call, silently.)

0 Kudos
JakobGaardsted
New Contributor III

A thought: I wonder, if the problem is bogus SSL in my Qt - I've installed an openSSL driver, but haven't verified it is robust with this QT.

0 Kudos
LucasDanzinger
Esri Frequent Contributor

Hi Jakob,

You are right that you should be using the following service: https://route.arcgis.com/arcgis/rest/services/World/Route/NAServer/Route_World

You have a few options with UserCredentials. The first is to determine if you need to use OAuth authentication or if regular http tokens will suffice. If so, you can obtain the username and password from your user, and set those on the user credentials, and then set the route task's credential property to that instance of UserCredentials. This is the simplest option.

If you do need to use OAuth, then we didn't officially support this until 10.2.6. You might be able to get this to work still be manually acquiring the token like you are doing. The referer should refer to the App ID that you get when you register your app on developers.arcgis.com.

Thanks,

Luke

JakobGaardsted
New Contributor III

Thank you very much for your informative reply!

  The username/password option I don't believe is valid for us - our clients run on 25-seat arcgis-standard deployment licenses, which I set with 'ER::ArcGISRuntime::License::setLicense'.

When I get back to our work computers (I'm in Europe), I'll try your 'referer' suggestion (I thought it was a URL field). Cross my fingers.

Otherwise, I can guess the option left is 10.2.6..

It's not that I mind 10.2.6, I just don't like to switch to 10.2.6 a week before releasing to clients,

which renders all our mouse application code relying on 'graphicsIds()'  being synchronous, not asynchronous :-(., and all references turned into pointers :-).

< I had a rant here, which I've removed again, since it's not of use to anyone 🙂 >

thank you for your assistance!

0 Kudos
JakobGaardsted
New Contributor III

"Solution": I have now gotten it to work (10.2.6..), field report here:

I tried the suggestion for 10.2.3, but it doesn't appear it will work.

The remainder here, what I learned about getting it (a demo) to work on 10.2.6:

( - info I wish I could have googled, and which would have been very helpful to myself, over the past month

struggling with "not" getting this to work)

I ended up with this code:

//////////////////////////////////////////////////////////////////////////////////////////////

  // OACI apparently doesn't have to be long-lived?

  ER::OAuthClientInfo oauth(ttp_ClientID, ttp_secret, ER::OAuthMode::App);

  creds.setOAuthClientInfo(oauth); // (ER::UserCredentials)

  // ER::IdentityManager::setCredential(&creds, actualURL); 

  m_routingTask = new ER::OnlineRouteTask(actualURL, &creds);

  // NB - even though docs say 'const', it has to be NOT const  here.

  connect( m_routingTask, SIGNAL(solveTaskComplete(EsriRuntimeQt::RoutingResult*)), this, SLOT(onSolveTaskComplete(EsriRuntimeQt::RoutingResult*))); // const  const

//////////////////////////////////////////////////////////////////////////////////////////////

comments/ the lessons learned from this:

1 - (beware that this is for 'app' (not 'user'  mode - YMMV if not for app-mode.)

2 - IdentityManager is non-essential, it's a 'convenience' mechanism to isolate authentication aspects out of your app code.

3 - the lifetime of UserCredentials obj. is critical, it has to be longlived: If you use a stack-allocated obj, the app will crash and burn in mysterious ways (ie the OnlineRouteTask expects it to live as long as it does.) However, OAuthClientInfo can be shortlived stack-item.

4 - 'OAuthClientInfo' handles 'everything' on behalf of UserCredentials (in this specific context..), so no need to set any of the many other properties of UserCredentials (e.g. no 'token', no 'referer').

5 - the ER::Graphics items eventually added to your graphics-layer, must be heap-allocated.. If not, you CAN add them to your layer, and you won't get an error, but nothing will appear to work :-(.

6 - the 'solveTaskComplete' signal, in practice, is different from what the documentation says (doc says 'const', but it only works if you remove const.)

I'm not looking forward to porting our entire application from 10.2.3 to 10.2.6 in under a week,

given the different pointer-semantics,

especially given item 5, I expect a mountain of heap-allocation bugs 😞

Interestingly, on our running 10.2.3 development, I experience about zero heap corruption bugs 😞

0 Kudos