Jump to content

Using Invoke()


Recommended Posts

I thought I'd spend some time tidying up my PHP implementation of Invoke() as I was using little in the way of error checking and was pretty much dumping the response back to the calling functions. It works, but it's not as I'd like.

So I started adding in some error checking on the responses and found that I'm at a loss as to what Invoke() is actually returning.

My initial understanding was that by submitting the headers and xml parameters I'd be getting back json as requested in the header.

'Accept' => 'Application/json',

But it looks like this isn't necessarily the case. If an error is returned then the response looks like xml. So then I thought I'd best check the response header for the type returned and use that to determine what I got back. So I didn't try parsing xml as json.

Seemed straight forward, but then I ran into apps/com.hornbill.servicemanager/Requests::smGetRequests() and apps/com.hornbill.core::getCoWorkersList() and that plan went out of the window. It seems these return xml with json embedded in it as params.

So the data returned, even though I ask for json, could be json, could be xml or could be xml with json in. That doesn't seem too smart. Is this really how it works or am I doing something wrong?

Link to comment
Share on other sites

51 minutes ago, TrevorKillick said:

Can you post the full response from the API call?

Sending the Accept Header of Application/json or text/json should always return JSON.

Kind Regards

Trevor Killick

I was hoping that was the case :D

This is what I get back from smGetRequests when I ask for SR00000087. Json embedded in <requests>

<?xml version="1.0" encoding="utf-8" ?>
<methodCallResult status="ok">
	<params>
		<requests>{"row":{"h_pk_reference":"SR00000087","h_fk_user_id":"paulb","h_requesttype":"Service Request","h_status":"status.open","h_datelogged":{"@raw":"2016-08-29 13:15:17","#text":"2016-08-29 14:15:17"},"h_fk_team_id":"CBC/CORP/RBCS/ICS/GENSUP/","h_datelastmodified":{"@raw":"2016-08-29 13:15:18","#text":"2016-08-29 14:15:18"},"h_isanalystunread":"1","h_container_id":"0","h_createdby":"paulb","h_customer_type":"0","customer_name":"Paul Bargewell","h_team_name":"General Support","h_fk_serviceid":"4","h_service_name":"Procurement","h_reopencount":"0","h_source_type":"Self Service","h_source_id":"paulb","h_site":"Southfield Road","h_site_id":"1","h_company_name":"Charnwood Borough Council","h_company_id":"CBC","h_catalog_id":"17","h_catalog":"Request a new laptop","h_catalog_title":"Request a new laptop","createdby_name":"Paul Bargewell"}}</requests>
		<count>1</count>
		<export>null</export>
	</params>
<flowCodeDebugState>
<step>d06f88c0-5676-4915-aaf3-2cbd41728dcf</step>
<executionId>25449</executionId>
<debugState></debugState>
</flowCodeDebugState>
</methodCallResult>

If I force an error I get back XML even with the Accept json header.

<?xml version="1.0" encoding="utf-8" ?>
<methodCallResult status="fail">
	<state>
		<code>0002</code>
		<error>The service specified is not available: apps1</error>
	</state>
</methodCallResult>

But when I call getRequestQuestions() I get what I expect:

{
	"@status": true,
	"params": {
		"rowsAffected": 0,
		"lastInsertId": 0,
		"rowData": {
			"row": [
				{
					"h_id": "151",
					"h_entity_ref": "SR00000087",
					"h_entity_type": "request",
					"h_question_id": "WhoFor",
					"h_question": "Who is this laptop for?",
					"h_answer": "John Smith",
					"h_field_type": "text",
					"h_form_id": "WhoFor"
				},
				{
					"h_id": "152",
					"h_entity_ref": "SR00000087",
					"h_entity_type": "request",
					"h_question_id": "existing_Chk",
					"h_question": "Is this a replacement for an existing laptop?",
					"h_answer": "No",
					"h_field_type": "select",
					"h_form_id": "Replace_exist"
				},
				{
					"h_id": "153",
					"h_entity_ref": "SR00000087",
					"h_entity_type": "request",
					"h_question_id": "field_1",
					"h_question": "Please provide reason for this request",
					"h_answer": "Why?",
					"h_field_type": "textarea",
					"h_form_id": "Bus_Justification"
				},
				{
					"h_id": "154",
					"h_entity_ref": "SR00000087",
					"h_entity_type": "request",
					"h_question_id": "CostCode",
					"h_question": "Cost Code",
					"h_answer": "G102",
					"h_field_type": "text",
					"h_form_id": "CostCode_details"
				},
				{
					"h_id": "155",
					"h_entity_ref": "SR00000087",
					"h_entity_type": "request",
					"h_question_id": "SubjCode",
					"h_question": "Subjective Code",
					"h_answer": "P3N15",
					"h_field_type": "text",
					"h_form_id": "CostCode_details"
				}
			]
		}
	}
}

 

Link to comment
Share on other sites

OK So first up the embedded JSON this is where we return a JSON object as a string for use in the client if the response was correctly being returned as JSON then that embedded JSON would show as stringified JSON the Flowcode Operations should be documented on where these responses contain JSON strings.
Edit: I checked and the Operation is not documented correctly I have raised this with the relevant development team.

Secondly the forced error is the one exception to the rule of when i ask for JSON i always get JSON back something out server team have on the backlog to fix.

As for why the first request is coming back as XML and not JSON can you dump the debug of CURL so i can see the exact HTTP request please?

Kind Regards

Trevor Killick

Link to comment
Share on other sites

16 minutes ago, TrevorKillick said:

OK So first up the embedded JSON this is where we return a JSON object as a string for use in the client if the response was correctly being returned as JSON then that embedded JSON would show as stringified JSON the Flowcode Operations should be documented on where these responses contain JSON strings.

Secondly the forced error is the one exception to the rule of when i ask for JSON i always get JSON back something out server team have on the backlog to fix.

As for why the first request is coming back as XML and not JSON can you dump the debug of CURL so i can see the exact HTTP request please?

Kind Regards

Trevor Killick

The embedded json was "stringified" but the paste to code seems to have replace the html entities with their html equivalent - eg. string was full of &apos; but pasted here got changed to '

With the error I'll have to check the return response header. But because the http response is 200 it's not as obvious an error occurred and relies on checking the data.

Lol, you make it sound easy for me to drop the curl in :D I'm going to have to poke around with Guzzle to figure that out :D

Link to comment
Share on other sites

Not sure if this is any help? I create the Request object and send that to the Guzzle client

Request {#372 
  -method: "POST"
  -requestTarget: null
  -uri: Uri {#369 
    -scheme: "https"
    -userInfo: ""
    -host: "eurapi.hornbill.com"
    -port: null
    -path: "/charnwoodbc/xmlmc/apps/com.hornbill.servicemanager/Requests/"
    -query: ""
    -fragment: ""
  }
  -headers: array:5 [▼
    "Host" => array:1 [▼
      0 => "eurapi.hornbill.com"
    ]
    "Content-type" => array:1 [▼
      0 => "text/xmlmc"
    ]
    "Authorization" => array:1 [▶]
    "Accept" => array:1 [▼
      0 => "Application/json"
    ]
    "Content-length" => array:1 [▼
      0 => "230"
    ]
  ]
  -headerNames: array:5 [▼
    "content-type" => "Content-type"
    "authorization" => "Authorization"
    "accept" => "Accept"
    "content-length" => "Content-length"
    "host" => "Host"
  ]
  -protocol: "1.1"
  -stream: Stream {#370 
    -stream: stream resource @16 
      wrapper_type: "PHP"
      stream_type: "TEMP"
      mode: "w+b"
      unread_bytes: 0
      seekable: true
      uri: "php://temp"
      options: []
    }
    -size: 230
    -seekable: true
    -readable: true
    -writable: true
    -uri: "php://temp"
    -customMetadata: []
  }
}

With the XML content method call:

<methodCall service="apps/com.hornbill.servicemanager/Requests" method="smGetRequests">
  <params>
    <requestNumberEquals>SR00000087</requestNumberEquals>
    <rowstart>0</rowstart>
    <limit>1</limit>
  </params>
</methodCall>

And the response object I get back (definitely states it's text/xmlmc):

Response {#395 
  -reasonPhrase: "OK"
  -statusCode: 200
  -headers: array:14 [▼
    "Server" => array:1 [▼
      0 => "nginx"
    ]
    "Date" => array:1 [▼
      0 => "Thu, 01 Sep 2016 10:02:06 GMT"
    ]
    "Content-Type" => array:1 [▼
      0 => "text/xmlmc; charset=utf-8"
    ]
    "Content-Length" => array:1 [▼
      0 => "1771"
    ]
    "Connection" => array:1 [▼
      0 => "keep-alive"
    ]
    "Accept-Ranges" => array:1 [▼
      0 => "bytes"
    ]
    "Cache-Control" => array:1 [▼
      0 => "no-cache"
    ]
    "X-esp-instance" => array:1 [▼
      0 => "charnwoodbc"
    ]
    "X-esp-service-build-date" => array:1 [▼
      0 => "2016-07-12"
    ]
    "X-esp-service-name" => array:1 [▼
      0 => "Esp.charnwoodbc.ServerService"
    ]
    "X-esp-service-version" => array:1 [▼
      0 => "8.0.0.2578"
    ]
    "X-esp-transaction-id" => array:1 [▼
      0 => "cd02894d-6693-45a5-a6f0-e167e25a8e98"
    ]
    "X-esp-transaction-perf" => array:1 [▼
      0 => "t=2016-09-01 10:02:06Z, tt=85.296ms"
    ]
    "Strict-Transport-Security" => array:1 [▼
      0 => "max-age=31536000; includeSubDomains"
    ]
  ]
  -headerNames: array:14 [▼
    "server" => "Server"
    "date" => "Date"
    "content-type" => "Content-Type"
    "content-length" => "Content-Length"
    "connection" => "Connection"
    "accept-ranges" => "Accept-Ranges"
    "cache-control" => "Cache-Control"
    "x-esp-instance" => "X-esp-instance"
    "x-esp-service-build-date" => "X-esp-service-build-date"
    "x-esp-service-name" => "X-esp-service-name"
    "x-esp-service-version" => "X-esp-service-version"
    "x-esp-transaction-id" => "X-esp-transaction-id"
    "x-esp-transaction-perf" => "X-esp-transaction-perf"
    "strict-transport-security" => "Strict-Transport-Security"
  ]
  -protocol: "1.1"
  -stream: Stream {#396 
    -stream: stream resource @18 
      wrapper_type: "PHP"
      stream_type: "TEMP"
      mode: "w+b"
      unread_bytes: 0
      seekable: true
      uri: "php://temp"
      options: []
    }
    -size: null
    -seekable: true
    -readable: true
    -writable: true
    -uri: "php://temp"
    -customMetadata: []
  }
}

 

Link to comment
Share on other sites

* Hostname was found in DNS cache
*   Trying 78.129.173.117...
* Connected to eurapi.hornbill.com (78.129.173.117) port 443 (#0)
* successfully set certificate verify locations:
*   CAfile: none
  CApath: /etc/ssl/certs
* SSL connection using TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384
* Server certificate:
* 	 subject: C=GB; ST=Middlesex; L=Ruislip; O=Hornbill Service Management Limited; OU=Marketing; CN=*.hornbill.com
* 	 start date: 2014-10-29 00:00:00 GMT
* 	 expire date: 2017-03-24 23:59:59 GMT
* 	 subjectAltName: eurapi.hornbill.com matched
* 	 issuer: C=US; O=GeoTrust Inc.; CN=GeoTrust SSL CA - G3
* 	 SSL certificate verify ok.
> POST /charnwoodbc/xmlmc/apps/com.hornbill.servicemanager/Requests/ HTTP/1.1
User-Agent: GuzzleHttp/6.2.1 curl/7.38.0 PHP/5.6.24-0+deb8u1
Host: eurapi.hornbill.com
Content-type: text/xmlmc
Authorization: ESP-APIKEY xxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Accept: Application/json
Content-Length: 230

* upload completely sent off: 230 out of 230 bytes
< HTTP/1.1 200 OK
* Server nginx is not blacklisted
< Server: nginx
< Date: Thu, 01 Sep 2016 10:08:35 GMT
< Content-Type: text/xmlmc; charset=utf-8
< Content-Length: 1771
< Connection: keep-alive
< Accept-Ranges: bytes
< Cache-Control: no-cache
< X-esp-instance: charnwoodbc
< X-esp-service-build-date: 2016-07-12
< X-esp-service-name: Esp.charnwoodbc.ServerService
< X-esp-service-version: 8.0.0.2578
< X-esp-transaction-id: 1c537af0-07e0-4554-a3b3-bfbbe400ceb0
< X-esp-transaction-perf: t=2016-09-01 10:08:35Z, tt=88.831ms
< Strict-Transport-Security: max-age=31536000; includeSubDomains
< 
* Connection #0 to host eurapi.hornbill.com left intact

Just saying it in a different way?

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...