question

Jacob G3 avatar image
0 Likes"
Jacob G3 asked Ben Wilson commented

Sending Http.request for json content type

Im trying to integrate a model with a WMS system. Communication is via http using post/get. In this case im trying a simple request that will return a lot information about the item being queried.

This is the call copied from postman that im trying to replicated from flexsim

POST //abcd/api/dcinventory/ilpn/ilpninventorysearch HTTP/1.1
Host: xyz.com
Content-Type: application/json
Authorization: bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyT3JncyI6WyJESy1UQVUiXSwidXNlcl9uYW1lIjoiREstVEFVLUFETUlOVVNFUiIsInVzZXJMb2NhdGlvbnMiOlt7ImxvY2F0aW9uSWQiOiJESy1UQVUiLCJsb2NhdGlvblR5cGUiOiJkdW1teSJ9XSwibG9jYWxlIjoiZW4iLCJleGNsdWRlZFVzZXJCdXNpbmVzc1VuaXRzIjpbXSwiYXV0aG9yaXRpZXMiOlsiUk9MRV9VU0VSIiwiUk9MRV9hZG1pbkBESy1UQVUiXSwiY2xpZW50X2lkIjoib21uaWNvbXBvbmVudC4xLjAuMCIsInVzZXJUaW1lWm9uZSI6IkV1cm9wZS9Db3BlbmhhZ2VuIiwiZWRnZSI6MCwic2NvcGUiOlsib21uaSIsImNvbXBvbmVudCJdLCJvcmdhbml6YXRpb24iOiJESy1UQVUiLCJhY2Nlc3N0b0FsbEJVcyI6ZmFsc2UsInRlbmFudElkIjoidWJ0c3NkZjExcCIsImV4cCI6MTY0Nzk4MjQyOSwidXNlckRlZmF1bHRzIjpbXSwianRpIjoiMWRhNmU3OTMtZTI4ZC00ZWVmLWIwYzctMWExM2E1Y2MxMTlhIiwidXNlckJ1c2luZXNzVW5pdHMiOltdfQ.b14AdIXNQfaC1jNxg1VW3kZSz-QnpqMJIInxktnXNiPCFOZfHn3A54rT8UcPcubOdGaUS43de869yQA_QcS7JE2xalwO6USqhHMfxj80ZPO6alvPUn0k4nDSErLf6LqJaACDuds95oYpELJPa1ULkw69AnHbqeP5rXcF3oIzubbMceLpzwSrUgO4wgbSeifRkIUhA8NNGiSJN36JMU127FbCZ7xlo6ZcUDgx3IlycyoMYgt268hSmKt18tXnCNn1W9dkMCkS3V1U9S7i7S1ETZfzrKoOqoIoGU2Li3WlNe_RfOus-G_SnbPOQcxhOjODZafdzOZU_fNJJHrnsq_d_g
SelectedLocation: aaaa
SelectedOrganization: aaaa
Content-Length: 49

{
    "Query" : "IlpnId = 0015700000000500CB60"
}


This is who I tried so far.

/**Custom Code*/
Object current = param(1);
treenode activity = param(2);
Token token = param(3);
treenode processFlow = ownerobject(activity);

Http.Request request = Http.Request("xyz.com/");
request.data = "Authorization: bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyT3JncyI6WyJESy1UQVUiXSwidXNlcl9uYW1lIjoiREstVEFVLUFETUlOVVNFUiIsInVzZXJMb2NhdGlvbnMiOlt7ImxvY2F0aW9uSWQiOiJESy1UQVUiLCJsb2NhdGlvblR5cGUiOiJkdW1teSJ9XSwibG9jYWxlIjoiZW4iLCJleGNsdWRlZFVzZXJCdXNpbmVzc1VuaXRzIjpbXSwiYXV0aG9yaXRpZXMiOlsiUk9MRV9VU0VSIiwiUk9MRV9hZG1pbkBESy1UQVUiXSwiY2xpZW50X2lkIjoib21uaWNvbXBvbmVudC4xLjAuMCIsInVzZXJUaW1lWm9uZSI6IkV1cm9wZS9Db3BlbmhhZ2VuIiwiZWRnZSI6MCwic2NvcGUiOlsib21uaSIsImNvbXBvbmVudCJdLCJvcmdhbml6YXRpb24iOiJESy1UQVUiLCJhY2Nlc3N0b0FsbEJVcyI6ZmFsc2UsInRlbmFudElkIjoidWJ0c3NkZjExcCIsImV4cCI6MTY0Nzg5NjgxOSwidXNlckRlZmF1bHRzIjpbXSwianRpIjoiOWQ2Nzg3ZDktNjkyMy00OTdhLTk3Y2UtNWJjMTljOWJiNTdmIiwidXNlckJ1c2luZXNzVW5pdHMiOltdfQ.QrKr4V85AP_BZju-GrCVorcn-YgKitWCKCLVcOrGfC4k5Bq9lpeSbzubUn5cape5oC4Qn2fYP53EWisEem0_CGbygZ5G99Y1dtK9xSuI1i4xwePIUxXqCvHkyebeeoAub36pqMGxoWteuGuMgA1hY19KA0gRcZcfVeW6nzJvtz01OFvhSuTZwrnOHg70FCRemZjlmTIblemcBFbQ6Urz8_9xMt9xYSxxm-8PSIJdk_arqjSmVpqSitSemcjtwM8PGEGeTosxK9F3H7soTrz374JGQS6AcE1nVpJkO1dAiooLsCdG3M1xGSdSb_qkepGemPoNornZiFUkS7jOsPnvBg
SelectedLocation: aaaa
SelectedOrganization: aaaa
Content-Length: 49

{
    \"Query\" : \"IlpnId = 0015700000000500CB60\"
}
";

Http.Response response = request.sendAndWait();
string json = response.value;
Map map = JSON.parse(json);
return map;

But this is what I get

1647947611366.png

My guess is that it will never work because I need the content type to be "application/json" and that is not possible to change I think.


My question is, is it realistical to get this to work using the http.request method or do I need to go the route of doing a direct call via c++?


API call.fsm

FlexSim 22.1.0
http
1647947611366.png (14.8 KiB)
api-call.fsm (31.1 KiB)
· 1
5 |100000

Up to 12 attachments (including images) can be used with a maximum of 23.8 MiB each and 47.7 MiB total.

Ryan Clark avatar image Ryan Clark commented ·

Hi @Jacob G3, was Ben Wilson's answer helpful? If so, please click the "Accept" button at the bottom of their answer. Or if you still have questions, add a comment and we'll continue the conversation.

If we haven't heard back from you within 3 business days we'll auto-accept an answer, but you can always unaccept and comment back to reopen your question.

0 Likes 0 ·

1 Answer

Ben Wilson avatar image
0 Likes"
Ben Wilson answered Ben Wilson commented

Hi @Jacob G3 ,

Your error message simply indicates that you can't have a literal newline in your string. You define a string on line 8 to set to request.data, and you have newlines in that string. FlexSim's parser doesn't like that. Instead use the newline character \n.

Also, I think you'll need to specify your headers using request.headers, rather than putting it into request.data. Try tinkering with code that looks more like this:

Http.Request request;
request.host = "xyz.com";
request.path = "abcd/api/dcinventory/ilpn/ilpninventorysearch";
request.method = Http.Method.Post;
request.headers = "Content-Type: application/json\r\nSelectedLocation: aaaa\r\nSelectedOrganization: aaaa\r\nAuthorization: bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyT3JncyI6WyJESy1UQVUiXSwidXNlcl9uYW1lIjoiREstVEFVLUFETUlOVVNFUiIsInVzZXJMb2NhdGlvbnMiOlt7ImxvY2F0aW9uSWQiOiJESy1UQVUiLCJsb2NhdGlvblR5cGUiOiJkdW1teSJ9XSwibG9jYWxlIjoiZW4iLCJleGNsdWRlZFVzZXJCdXNpbmVzc1VuaXRzIjpbXSwiYXV0aG9yaXRpZXMiOlsiUk9MRV9VU0VSIiwiUk9MRV9hZG1pbkBESy1UQVUiXSwiY2xpZW50X2lkIjoib21uaWNvbXBvbmVudC4xLjAuMCIsInVzZXJUaW1lWm9uZSI6IkV1cm9wZS9Db3BlbmhhZ2VuIiwiZWRnZSI6MCwic2NvcGUiOlsib21uaSIsImNvbXBvbmVudCJdLCJvcmdhbml6YXRpb24iOiJESy1UQVUiLCJhY2Nlc3N0b0FsbEJVcyI6ZmFsc2UsInRlbmFudElkIjoidWJ0c3NkZjExcCIsImV4cCI6MTY0Nzk4MjQyOSwidXNlckRlZmF1bHRzIjpbXSwianRpIjoiMWRhNmU3OTMtZTI4ZC00ZWVmLWIwYzctMWExM2E1Y2MxMTlhIiwidXNlckJ1c2luZXNzVW5pdHMiOltdfQ.b14AdIXNQfaC1jNxg1VW3kZSz-QnpqMJIInxktnXNiPCFOZfHn3A54rT8UcPcubOdGaUS43de869yQA_QcS7JE2xalwO6USqhHMfxj80ZPO6alvPUn0k4nDSErLf6LqJaACDuds95oYpELJPa1ULkw69AnHbqeP5rXcF3oIzubbMceLpzwSrUgO4wgbSeifRkIUhA8NNGiSJN36JMU127FbCZ7xlo6ZcUDgx3IlycyoMYgt268hSmKt18tXnCNn1W9dkMCkS3V1U9S7i7S1ETZfzrKoOqoIoGU2Li3WlNe_RfOus-G_SnbPOQcxhOjODZafdzOZU_fNJJHrnsq_d_g";
request.data = "IlpnId=0015700000000500CB60";
request.send();

On the server side, you would access the IlpnId data directly by name. The way you would do this differs by server platform language. Or if you need to send the entire JSON hunk, Just use your entire JSON string without any newlines, like this:

request.data = "{\"Query\":\"IlpnId = 0015700000000500CB60\"}";


· 8
5 |100000

Up to 12 attachments (including images) can be used with a maximum of 23.8 MiB each and 47.7 MiB total.

Jacob G3 avatar image Jacob G3 commented ·

That solved one problem. But I still I have an issue because the content type of the request is not application/json , see this topic

Im getting a reponse as if I typed in the url in the browser (which just directs me to a standard login site).


0 Likes 0 ·
Ben Wilson avatar image Ben Wilson ♦♦ Jacob G3 commented ·

"that solved one problem" - are you referring to the exception, or something else?

The 22.1 beta (which it appears you're using?) has a new request.headers property (which I used in my example code) that sends headers to the remote server.

I tested that sample code with a server under my control and examined the headers. They were all there in the received request. You may just need to tweak the format of your headers to get your server to recognize what you're passing. My guess is to start with the authentication header. Or you may need to delimit the various headers with \r\n instead of just \n. Different server platforms may have different idiosyncrasies with how they handle the received request.

The headers that my server recognized were newline separated key:value pairs.

0 Likes 0 ·
Jacob G3 avatar image Jacob G3 commented ·

Hmm. When I point it to a mock server in postman and examine the request header, this is what I get. I dont see the actual header that I specified is being send

x-forwarded-proto: "xxxxxxxxx"
host: "3186b286-f9be-4062-ae74-f75451234e222.mock.pstmn.io"
x-real-ip: "xxxxxxxxx"
x-forwarded-for: "xxxxxxxxx"
x-request-start: "t=1647965252.278"
content-length: "203"
x-forwarded-port: "xxxxxxxxx"
x-amzn-trace-id: "Root=1-6239f444-0bd29683489ae2471f4ca56b"
cache-control: "no-cache"
pragma: "no-cache"
content-type: "application/x-www-form-urlencoded"
user-agent: "Flexsim"


Looking at the code, I dont understand why the request.headers is not in purple like the rest. Also I cannot capture the headers to a string like I can do with the rest of the parameters.

1647965881413.png

Is there something wrong with my installations? Or maybe a bug?

0 Likes 0 ·
1647965881413.png (31.8 KiB)
Ben Wilson avatar image Ben Wilson ♦♦ Jacob G3 commented ·

Http.Request.headers is a new property in the latest FlexSim beta, version 22.1. Here is the version info from the latest beta, released yesterday:

1647966407002.png

If you are using an older version, the headers property is not sent to the remote server, but instead is used as a custom labelProperties property - basically a way to store information on the request (kind of like a label on other objects in the software) that will be available from the response. labelProperties are not actually sent to the remote server with the request.

If you want to use the beta, you'll need to download it from a licensed account. Guest accounts can't access older versions or betas.

From a licensed account, on the download page, click the More Versions button, then find the entry for the beta. Download, install, test.

Let us know how it goes.

0 Likes 0 ·
1647966407002.png (26.4 KiB)
Jacob G3 avatar image Jacob G3 Ben Wilson ♦♦ commented ·

He. Isnt that my luck that I found that specific function to use that havent even been released yet :-D


I'll have to wait for it to become public available and re-test. I'll update this thread then to let you know how it went. But thank you for your help so far

0 Likes 0 ·
Show more comments
Jacob G3 avatar image Jacob G3 commented ·

It works with the 22.1, pretty darn cool.


Got me thinking, whats the simplest approach to acting as the API server, basically doing the opposite? Does it require an external function receiving the actual call and passing it on to flexsim in a useful manner? Or are there anything build into flexsim that could be used for this?

0 Likes 0 ·
Ben Wilson avatar image Ben Wilson ♦♦ Jacob G3 commented ·

@Jacob G3 ,

FlexSim has a web server that can be used to accept incoming HTTP requests. This is a separate installation package that should be installed alongside your FlexSim installation. You can find FlexSim Webserver 2021 (the latest version) on your FlexSim account's downloads page.

Read more about the FlexSim Webserver in the user manual:

Webserver (flexsim.com)

The Webserver accepts incoming HTTP requests and let's you use them to control aspects of a simulation model.

It looks like your top post has a correct answer now, so as you work through the web server documentation and try your own implementation, please be sure to open new questions for new topics.

Or comment back for any further follow-up on this topic "Sending Http.request for json content type", HTTP headers, etc.

0 Likes 0 ·