Active IQ Unified Manager Discussions
Active IQ Unified Manager Discussions
I'm looking to get a WFA instance to respond via JSON when making REST-based calls to it. Right now when I query "https://server-name/rest/workflows" or any other REST-based URLs, I get back an XML response. The WFA REST primer shows that it supports JSON, but I'm unsure how to get it to talk this way. Do I need to configure or enable something? Appreciate the help.
Solved! See The Solution
Support for JSON was added in WFA v4.1.
Hi,
You need to specify the Content-Type in the http header as - Content-Type: application/json.
If you are invoking REST APIs from a script or an application, you can easily set the header but i don't think there is a way to do it from a broswer.
Hey. First off, thanks for the quick response. I've already tried setting the Content-Type to application/json and get a "500 cannot consume content-type" status code. Similarly, if I set the Accept header to application/json, I get a "500 no match for accept header". I'm thinking I need to enable something server-side, or that perhaps WFA wasn't installed properly. Thanks
Which WFA version are you using ? If possible, please add a code snippet of your REST API call using JSON
What language are you using to write your code? Can help if it is either PowerShell or Python.
Yaron
I'm using Python, in fact. Here's the snippet of code:
connection = httplib.HTTPSConnection(WFAServer)
connection.request('GET', '/rest/workflows?name=' + workflowName, headers = {"Authorization" : "Basic %s" % encodedCredentials, "Accept" : "application/json"})
It works when Accept is application/xml, but I'd prefer to use JSON. Thanks
Here is a code snippet in Python getting all available workflows using json. Hope this helps.
import requests
from requests.auth import HTTPBasicAuth
from requests.adapters import HTTPAdapter
from requests.packages.urllib3.poolmanager import PoolManager
import ssl
from requests.packages.urllib3.util.ssl_ import create_urllib3_context
import json
#============================================================================
# CHANGE IF NEEDED PRIOR TO IMPORTING
url = "https://wfa.demo.netapp.com/rest/workflows"
#============================================================================
#============================================================================
# THE CODE BELOW IS NEEDED TO AVOID SSL3 HANDSHAKE ERRORS WHEN RUNNING REST
# API AGAINST NETAPP ONCOMMAND WORKFLOW AUTOMATION SERVER
CIPHERS = (
'ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+HIGH:'
'DH+HIGH:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+HIGH:RSA+3DES:!aNULL:'
'!eNULL:!MD5:DES-CBC3-SHA'
)
class DESAdapter(HTTPAdapter):
def init_poolmanager(self, connections, maxsize, block=False,*args, **kwargs):
context = create_urllib3_context(ciphers=CIPHERS)
kwargs['ssl_context'] = context
self.poolmanager = PoolManager(
num_pools=connections, maxsize=maxsize,
block=block, ssl_version=ssl.PROTOCOL_SSLv3,*args, **kwargs)
#============================================================================
# Function GetListOfWorkflows queries WFA server for available APIs (workflows) based on user's role
def GetListOfWorkflows(username,password):
requests.packages.urllib3.disable_warnings()
s = requests.Session()
s.mount(url, DESAdapter())
head = {"Content-type": "application/json","Accept":"application/json"}
ret=s.get(url,headers=head,auth=HTTPBasicAuth(username,password),verify=False)
if (ret.status_code != 200):
print ("Could not connect to API server.")
else:
d = []
for wf in ret.json():
try:
# Check if workflow has description defined
tmp = wf['description']
d.append({
'name':wf['name'],
'description':wf['description']
})
except:
d.append({
'name':wf['name']
})
print (json.dumps(d,indent=4))
Not sure why the smiley faces are there. Change the smiley face with : and D without the spaces (or the word and). Essentially the two charactes colon and upper case D.
Yaron
You need to add the following key-value pair in your GET Request header.
'Accept'='application/json'
for POST/PUT you need to additionally provide Content-Type='Application/json'
You language is python so I suggest you use the Apache requests lib. Its the best one for calling http web requests.
EXample:
import requests url = 'http://localhost/rest/system' session = requests.Session() session.auth = ('sinhaa', 'Netapp') session.headers.update({'content-type': 'application/json'}) session.headers.update({'Accept': 'application/json'}) resp = session.get(url) print "STATUS : %s \n" % resp.status_code print "CONTENT : %s \n" % resp.content
I've tried setting the Content-Type and Accept headers to application/json and the server keeps responding with a 500 code. It only works with these headers set to application/xml.
What version of WFA are you using?
Support for JSON was added in WFA v4.1.
That looks like it's the problem. I'll have to upgrade it since I'm using 4.0. Thanks a bunch.
Hi there,
What is the format of entries parameters in JSON, I tried that with error 500
data = { "workflowInput": { "userInputValues": { "userInputEntry": [ { "key": "serversource", "value": src }, { "key": "serverdest", "value": dst } ] } } }
It should be something like this, no need of mentioning 'workflowInputs' and 'userInputEntry' elements for JSON.
{
"userInputValues": [
{
"key": "dsname",
"value": "datasource-1"
},
{
"key": "address",
"value": "1.2.3.4"
}
]
}
I got the same, here the wfa.log error
2017-06-23 14:57:41,720 ERROR [com.netapp.wfa.rs.validation.WfaExceptionMapper] (default task-32) REST service got exception, returning: Internal Server Error (500): com.fasterxml.jackson.core.JsonParseException: Unrecognized token 'userInputValues': was expecting ('true', 'false' or 'null') at [Source: io.undertow.servlet.spec.ServletInputStreamImpl@74151ccb; line: 1, column: 17]
After doubled check, I realized I have as well a problem in my code, because your solution runs fine with postman.
Thanks!
Get json is easy, but what about posting it ? Is that possible ?
And what is the layout ?
@mirko find an example in python, hope that helps.
I use requests Session to process.
from requests import Session
from requests.auth import HTTPBasicAuth
session = Session() session.auth = HTTPBasicAuth(UNAME, PASSWORD) session.headers.update({'content-type': 'application/json'}) session.headers.update({'Accept': 'application/json'}) session.verify = False
uuid is the id of the workflow I want retrieved.
WORKFLOWTOEXECUTE = 'Name of workflow' payload = {'name': WORKFLOWTOEXECUTE} urlquery = 'https://{}/rest/workflows'.format(WFASERVER) workflowsget = session.get(urlquery, params=payload) workflows = workflowsget.json() uuid = workflows[0].get('uuid')
urlrun = 'https://{}/rest/workflows/{}/jobs'.format(WFASERVER, uuid) data = {"userInputValues": [ { "key": "serversource", "value": src }, { "key": "serverdest", "value": dst } ] } execstatus = session.post(urlrun, data=json.dumps(data))
serversource and serverdest are input parameters of my workflow in WFA.
Get json is easy, but what about posting it ? Is that possible ?
And what is the layout ?
-----
WFA4.1 uses swagger for API documentation which is very helpful.
GET/POST/PUT all are available for JSON as well..
The body layout is available in rest docs at: https://wfa-server/rest/docs
go to your particular API and select the Parameter Content Type to be : application/json
You will see an example body being given to you on th right side.
I have did below as i wanted to get filter output
$workflow_execution_uri = "https://xxxxx/rest/filters/372c5151-bd22-4b48-a610-dfec86e0fd92/test_no_reservations?Location=xxxx"
$cred= Get-Credential
$output = Invoke-RestMethod -Method get -Uri $workflow_execution_uri -Credential $cred -ContentType 'application/json'
its still showing up as xml as output
what i may be doing wrong?