Active IQ Unified Manager Discussions

WFA - Enabling JSON Responses

lil_baby_james
13,367 Views

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.

1 ACCEPTED SOLUTION

yaron
12,862 Views

Support for JSON was added in WFA v4.1.

View solution in original post

26 REPLIES 26

ag
NetApp
11,898 Views

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.

lil_baby_james
11,874 Views

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

rkiran
11,851 Views

Which WFA version are you using ?  If possible, please add a code snippet of your REST API call using JSON

yaron
12,408 Views

What language are you using to write your code? Can help if it is either PowerShell or Python.

 

Yaron

lil_baby_james
12,402 Views

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

yaron
12,400 Views

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))

yaron
12,398 Views

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

sinhaa
12,318 Views

@lil_baby_james

 

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
If this post resolved your issue, help others by selecting ACCEPT AS SOLUTION or adding a KUDO.

lil_baby_james
12,302 Views

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.

yaron
12,063 Views

What version of WFA are you using?

yaron
12,863 Views

Support for JSON was added in WFA v4.1.

lil_baby_james
11,492 Views

That looks like it's the problem. I'll have to upgrade it since I'm using 4.0. Thanks a bunch.

francoisbnc
11,965 Views

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
                        }
                    ]
                }
            }
        }

rkiran
11,961 Views

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"
    }
  ]
}

francoisbnc
11,378 Views

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]

 

francoisbnc
9,965 Views

After doubled check, I realized I have as well a problem in my code, because your solution runs fine with postman.

 

Thanks!

mirko
10,089 Views

Get json is easy, but what about posting it ?  Is that possible ?

And what is the layout ?

 

francoisbnc
10,056 Views

@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.

 

sinhaa
9,955 Views

@mirko

 

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.

 

 

JSON.png

If this post resolved your issue, help others by selecting ACCEPT AS SOLUTION or adding a KUDO.

CAPATEL_NET1984
7,922 Views

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?

Public