Matlab RESTful PUT Command - net.http - nesting body values - matlab

I am using Matlab's matlab.net.http library to launch get, put and post commands to a website. I can successfully launch get and post commands.
For example:
MyBody = matlab.net.http.MessageBody(struct('Id',YYYYYY,'WindfarmId',XXX,'Month','YYYY-MM-DD'));
Request = matlab.net.http.RequestMessage;
Request.Method = 'POST';
Request.Header = matlab.net.http.HeaderField('Content-Type','application/json','Authorization',['Basic ' matlab.net.base64encode([Username ':' Password])]);
Request.Body = MyBody;
uri = matlab.net.URI(ENTERURLHERE);
Response = Request.send(uri,MyHTTPOptions);
This works well. However using a PUT command I have to enter the equiavlent of this body (written in curl syntax):
-d '{ "InputValues": [ {"MetricLevelAId": 1, "MetricLevelBId": 1, "InputMetricId": 7, "Value": 56 } ] }'
I tried this:
data_InputValues = struct ('MetricLevelAId',1,'MetricLevelBId',1,'InputMetricId',7,'Value',56);
MyBody = matlab.net.http.MessageBody(struct('InputValues',dataInputValues));
However I keep receiving the following 'Bad Request' response from the server:
"Input values required"
I think this is linked to the way Matlab interprets the body part of the request and passes it to the server, i.e. it cannot pass the nested struct correctly. Anyone got any ideas how to solve this?
N.B. potentially linked to Translating curl into Matlab/Webwrite (it is dealing with a nested value)

Related

How to check for proper format in my API response

Currently running tests for my REST API which:
takes an endpoint from the user
using that endpoint, grabs info from a server
sends it to another server to be translated
then proceeds to jsonify the data.
I've written a series of automated tests running and I cannot get one to pass - the test that actually identifies the content of the response. I've tried including several variations of what the test is expecting but I feel it's the actual implementation that's the issue. Here's the expected API response from the client request:
{ "name": "random_character", "description": "Translated description of requested character is output here" }
Here is the testing class inside my test_main.py:
class Test_functions(unittest.TestCase):
# checking if response of 200 is returned
def test_healthcheck_PokeAPI(self):
manualtest = app.test_client(self)
response = manualtest.get("/pokemon/")
status_code = response.status_code
self.assertEqual(status_code, 200)
# the status code should be a redirect i.e. 308; so I made a separate test for this
def test_healthcheck_ShakesprAPI(self):
manualtest = app.test_client(self)
response = manualtest.get("/pokemon/charizard")
self.assertEqual(response.status_code, 308)
def test_response_content(self):
manualtest = app.test_client(self)
response = manualtest.get("/pokemon/charizard")
self.assertEqual(response.content_type,
'application/json') <<<< this test is failing
def test_trans_shakespeare_response(self):
manualtest = app.test_client(self)
response = manualtest.get("/pokemon/charizard")
self.assertFalse(b"doth" in response.data)
Traceback:
AssertionError: 'text/html; charset=utf-8' != 'application/json' - text/html; charset=utf-8 + application/json
Any help would be greatly appreciated

Getting restrictions from Confluence page

I'm not very savvy with web API calls, but I've been using the following powershell code (this site in this example is one I found that has some public data... my site is internal and requires I pass the credential, which has been working for me without issue):
If(-not (Get-InstalledModule -Name 'ConfluencePS')){Install-Module ConfluencePS}
Import-Module ConfluencePS
Set-ConfluenceInfo -BaseUri "https://wiki.opnfv.org"
$space = Get-confluencepage -Spacekey ds
ForEach($item in $space)
{
$splatParams = #{
Uri = "https://wiki.opnfv.org/rest/api/content/$($item.ID)/restriction"
ContentType = 'application/json'
method = 'GET'
}
#reference https://developer.atlassian.com/cloud/confluence/rest/#api-api-content-id-restriction-get
Invoke-RestMethod #splatParams
}
The documentation for the ConfluencePS shows that restrictions is still an open feature request but I need to get this working for a project.
I put a breakpoint in on line 982 from ConfluencePS.psm1 and was able to see the various calls and how the params are structured but when I try to mimic it (and change the URI based on the confluence documentation) I get an error "HTTP error 405 - MethodNotAllowed". Anyone have suggestions on how I can get this working? I'm trying to return back the permissions applied for all pages in a specific space.
Get Restrictions by Content ID
As you found out by yourself, it is required to add "byOperation".
I was able to get the restrictions of a specific page with the following code:
# for testing purposes ONLY, I've specified the URL and ID
$wikiUrl = "https://wiki.opnfv.org"
$itemId = "6820746"
$splatParams = #{
Uri = "$wikiUrl/rest/api/content/$itemId/restriction/byOperation"
ContentType = 'application/json'
method = 'GET'
}
$result = Invoke-RestMethod #splatParams
Tested on version 6.0.4 and 6.15.9
Filter by user name
If you like to filter the result by a specific username, you can use the following URI:
"$wikiUrl/rest/api/content/$itemId/restriction/byOperation/.../user?userName=".
Bt, there's an open bug on this way of action:
restriction returns ambiguous responses

MultiPart PUT request not working in spring boot

I have the following curl request
curl -X PUT http://localhost:50005/did:corda:tcn:77ccbf5e-4ddd-4092-b813-ac06084a3eb0 -H 'content-type:multipart/form-data' -F 'instruction=hgfhhf'
I am trying to read the instruction in my spring boot controller as seen below
#PutMapping(value = "{id}",
produces = arrayOf(MediaType.APPLICATION_JSON_VALUE),
consumes = arrayOf(MediaType.MULTIPART_FORM_DATA_VALUE))
fun createID(#PathVariable(value = "id") id: String,
#RequestParam("instruction") instruction: String ) : ResponseEntity<Any?>
But the code above returns
"status":400,"error":"Bad Request","exception":"org.springframework.web.multipart.support.MissingServletRequestPartException","message":"Required request part 'instruction' is not present"
remove unused:
consumes = arrayOf(MediaType.MULTIPART_FORM_DATA_VALUE)
you have missed request param instruction (in reqeust), try this:
curl -X PUT -G 'http://localhost:50005/did:corda:tcn:77ccbf5e-4ddd-4092-b813-ac06084a3eb0' -d 'instruction=hgfhhf'
also take a look at CURL Command Line URL Parameters

Translating curl into Matlab/Webwrite

I have the following curl command I need to sent to a web server using Matlab and webwrite using POST. My problem is that I always get a "Bad request" answer so my syntax must be wrong somehow. Does anybody have an idea how this curl command, sending the body could look like in Matlab using webwrite in a correct way ?
body=$(cat << EOF
{
"order": {
"units": "100",
"instrument": "EUR_USD",
"timeInForce": "FOK",
"type": "MARKET",
"positionFill": "DEFAULT"
}
}
EOF
)
curl \
-X POST \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <AUTHENTICATION TOKEN>" \
-d "$body" \
"https://api-fxtrade.oanda.com/v3/accounts/<ACCOUNT>/orders"
I have just asked a potentially similar question so this may not work first time. However I cannot test without knowing some login details so I can but hope this helps.
data_InputValues = struct ('units',100,'instrument','EUR_USD','timeInForce','FOK','type','MARKET','positionFill','DEFAULT');
MyBody = matlab.net.http.MessageBody(struct('order',data_InputValues));
MyHTTPOptions = matlab.net.http.HTTPOptions(); % use this to change the options if necessary (e.g. extend timeout)
Request = matlab.net.http.RequestMessage;
Request.Method = 'POST';
Request.Header = matlab.net.http.HeaderField('Content-Type','application/json','Authorization: Bearer',AUTHENTICATION TOKEN);
Request.Body = MyBody;
uri = matlab.net.URI('https://api-fxtrade.oanda.com/v3/accounts/<ACCOUNT>/orders');
[response a ~] = Request.send(uri,MyHTTPOptions);
The part I struggle with is generating the MyBody part (in your case this is parsing the order variable's sub-variables). If you get this to work I would be keen to know how! P.S. my question in case it helps: Matlab RESTful PUT Command - net.http - nesting body values
The correct format for the body is as follows:
body = struct('units',100,'instrument','EUR_USD','timeInForce','FOK',...
'type','MARKET','positionFill','DEFAULT');
As for the HTTP headers that you require you can specify them with weboptions when using webwrite.
The syntax for an additional header:
options = weboptions('KeyName','Name','KeyValue','Value')
Where Name and Value are the name of the header and its value respectively.
You must add the headers that you require in weboptions.
For the code you provided, the correct syntax would be as follows:
options = weboptions('MediaType','application/json',...
'KeyName','Authorization: Bearer','KeyValue','Token');
You can then perform the POST request at the URL of interest.
response = webwrite(url,body,options);

Can't able to view a transform in browser using REST in Marklogic 9?

I tried to install below Server-Side JavaScript using this documentation and saved below as rest-sjs
function insertTimestamp(context, params, content)
{
if (context.inputType.search('json') >= 0) {
var result = content.toObject();
if (context.acceptTypes) { /* read */
result.readTimestamp = fn.currentDateTime();
} else { /* write */
result.writeTimestamp = fn.currentDateTime();
}
return result;
} else {
/* Pass thru for non-JSON documents */
return content;
}
};
exports.transform = insertTimestamp;
I tried to push this using below curl cmd:
curl --anyauth --user public\admin:admin -X PUT -i --data-binary #"C:/Users/name/Desktop/rest.sjs" -H "Content-type: application/vnd.marklogic-javascript" 'http://localhost:9963/v1/config/transforms/js-example'
When I used localhost:9963 and went to /v1/config/transforms I can see:
<rapi:transforms xmlns:rapi="http://marklogic.com/rest-api">
<rapi:transform>
<rapi:name>rest-tsm</rapi:name>
<rapi:source-format>javascript</rapi:source-format>
<rapi:transform-parameters/>
<rapi:transform-source>/v1/config/transforms/rest-tsm</rapi:transform-source>
</rapi:transform>
</rapi:transforms>
But when I went though the module /v1/config/transforms/rest-tsm I am seeing an error response:
<error-response xmlns="http://marklogic.com/xdmp/error">
<status-code>406</status-code>
<status>Unacceptable Type</status>
<message-code>REST-UNACCEPTABLETYPE</message-code>
<message>
REST-UNACCEPTABLETYPE: (err:FOER0000) No acceptable content type: None of the requested types text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8 can be provided
</message>
</error-response>
I can see the the module in Modules db. Which worked fine when I try to insert a document by using the transform.
Why can't I view the transform in the browser?
Unfortunately, that rest endpoint isn't very browser friendly. The required/acceptable Accept header values do not match what browsers will normally send.
When you made the GET request through your browser, it was sending the following Accept header:
text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept
This field contains a semicolon-separated list of representation schemes ( Content-Type metainformation values) which will be accepted in the response to this request.
Unfortunately, the v1/config/transform/{name} (GET) REST endpoint is strict in what it will accept for the Accept header and expects a specific value:
The MIME type of the data expected in the response, either application/xslt+xml or application/xquery.
If you use the example CURL command from the documentation, and customize for your transform URI, it will return the expected response.
curl --anyauth --user public\admin:admin -X GET -i \
-H "Accept: application/xquery" \
http://localhost:9963/v1/config/transforms/rest-tsm