Active IQ Unified Manager Discussions

WFA - Enabling JSON Responses

lil_baby_james
9,369 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
8,864 Views

Support for JSON was added in WFA v4.1.

View solution in original post

26 REPLIES 26

ag
NetApp
8,332 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
8,308 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
8,285 Views

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

yaron
8,842 Views

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

 

Yaron

lil_baby_james
8,836 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
8,834 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
8,832 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
8,752 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
8,736 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
8,497 Views

What version of WFA are you using?

yaron
8,865 Views

Support for JSON was added in WFA v4.1.

lil_baby_james
7,926 Views

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

francoisbnc
8,399 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
8,395 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
7,812 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
6,399 Views

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

 

Thanks!

mirko
6,523 Views

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

And what is the layout ?

 

francoisbnc
6,490 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
6,389 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
4,356 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