Posts Tagged ‘apim’

This is a python code snippet I wrote to automate API creation in WSO2 API Manager. WSO2 API manager has exposed a API, Publisher API  using which we can perform APIM related task.

This python client first login to APIM and check weather there is already an API with the same name, if not it will create an API. This API has two resources each has unlimited throttling tier

  1. PUT /cart
  2. POST /checkout

In addition API has fail over endpoint, one production endpoint and one fail over endpoint. So once the API is invoked, API first try to reach the production endpoint, if production endpoint is not available it will try to reach fail over endpoint.

Once the API is created, this code will publishes the newly created API so users can subscribe to the API.

	log = LogFactory().get_log(__name__)
        log.info("Starting api creation plugin...")

        apim_domain = "localhost"
        apim_username = "admin"
        apim_password = "admin"

        endpoint = "http://api.openweathermap.org/data/2.5/weather?q=London"

        url =  'https://%s:9443/publisher/site/blocks/' %  apim_domain

        loging_url = urlparse.urljoin(url, 'user/login/ajax/login.jag')
        payload = {'action':'login', 'username':apim_username, 'password':apim_password }

        log.info("Login into APIManager %s " % loging_url)
        resp = requests.post(loging_url, data=payload, verify=False)
        log.info("APIM Logging response %s" % resp)
        cookie = resp.cookies

        swagger = {'paths': {'/cart': {'put': {'x-auth-type': 'None',
                                               'x-throttling-tier': 'Unlimited',
                                               'responses': {'200': {}}}}, '/checkout': {'post': {
            'parameters': [{
                               'schema': {'type': 'object'},
                               'description': 'Request Body',
                               'name': 'Payload',
                               'required': 'false',
                               'in': 'body',
                               }],
            'responses': {'200': {}},
            'x-auth-type': 'None',
            'x-throttling-tier': 'Unlimited',
            }}}}

        swager_json = json.dumps(swagger)

        api_url = urlparse.urljoin(url,'item-add/ajax/add.jag')

        endpoint_conf = \
            {'production_endpoints': {'url': 'http://ws.cdyne.com/phoneverify/phoneverify.asmx',
                                      'config': 'null'},
             'production_failovers': [{'url': 'http://failover_domain:30000/StorefrontDemo/api/customer'
                                          , 'config': 'null'}], 'endpoint_type': 'failover'}

        endpoint_conf['production_endpoints']['url']= endpoint
        endpoint_json = json.dumps(endpoint_conf)

        payload = {
            'action': 'addAPI',
            'name': 'Storefront',
            'context': 'storefront',
            'version': 'v1',
            'visibility': 'public',
            'endpointType': 'nonsecured',
            'tiersCollection': 'Unlimited',
            'http_checked': 'http',
            'https_checked': 'https',
            'resourceCount': 0,
            'resourceMethod-0': 'PUT',
            'resourceMethodAuthType-0': 'None',
            'resourceMethodThrottlingTier-0': 'Unlimited',
            'uriTemplate-0': 'cart',
            'resourceMethod-0': 'POST',
            'resourceMethodAuthType-0': 'None',
            'resourceMethodThrottlingTier-0': 'Unlimited',
            'uriTemplate-0': 'checkout',
            }

        payload['endpoint_config']=endpoint_json
        payload['swagger'] = swager_json

        exist_payload = {
        'action':'isAPINameExist',
        'apiName':'Storefront'
        }

        #check if API with the same name already exist
        resp = requests.post(api_url, data = exist_payload, verify = False, cookies = cookie)
        api_exist =  ('true' == json.loads(resp.text)['exist'])
        logging.info("API already exist %s " % api_exist)

        if not api_exist:            
            log.info("Creating API WebbAppAPI %s " % api_url)
            resp = requests.post(api_url, data=payload, verify=False, cookies=cookie)
            log.info("APIM api creation response %s" % resp)

            publish_url = urlparse.urljoin(url, 'life-cycles/ajax/life-cycles.jag')
            payload = {
            'action':'updateStatus',
            'name':'Storefront',
            'version':'v1',
            'provider':'admin',
            'status':'PUBLISHED',
            'publishToGateway':'true',
            'requireResubscription':'false'
            }
            log.info("Publishing API WebbAppAPI %s " % publish_url)
            resp = requests.post(publish_url, data=payload, verify=False, cookies=cookie)
            log.info("APIM api publishing response %s" % resp)

        log.info("*****************API creation plugin completed *****************")
	

Below is the created API

Storefront API

Storefront API

Advertisements

In order to understand and test APIs created, WSO2 API manager provides interactive documentation. WSO2AM incoparates swagger[https://developers.helloreverb.com/swagger] for this puprpose.In Swagger, we can define a API using a static JSON file. In APIM, when we create an API, it automatically generates the JSON representation of the API which is loaded by the Swagger. In this tutorial, let’s see how we can edit the JSON representation in order to add some custom header to when calling the API. Below are the steps that are going to do in this tutorial.

  • create an API
  • Use Swagger to invoke the API
  • Describe Swagger documantation
  • Edit Swagger documentation to add a custom header named “username”
  • Invoke the API using Swagger with the newly added header

 

Step1 : Create an API

Design API

 

APi Design

APi Design

Implement API

api-implement

Manage API

api manager

 

Swagger doc.

To view the swagger documentation
Locate to APIM store  ->select the API -> Click on “API Console” tab.

swagger doc

Here you see a header called “Authorization” and a query parameter named “Query Parameter”. However if you want to add another header or query parameter, you have to edit the Swagger documentation of the API.

 

Step2:

Edit Swagger doc

To edit the Swagger documentation
Locate to APIMPublisher -> Select API -> click Docs tab -> Edit Content link

edit

 

swagger doc edit

 

Below is the existing JSON representation of the API we created.

{
    "apiVersion": "1.0.0",
    "swaggerVersion": "1.1",
    "basePath": "http://192.168.122.1:8280",
    "resourcePath": "/swagger",
    "apis": [
        {
            "path": "/swagger/1.0.0/users",
            "description": "",
            "operations": [
                {
                    "httpMethod": "GET",
                    "summary": "",
                    "nickname": "",
                    "parameters": [
                        {
                            "name": "Query Parameters",
                            "description": "Request Query Parameters",
                            "paramType": "body",
                            "required": false,
                            "allowMultiple": false,
                            "dataType": "String"
                        },
                        {
                            "name": "Authorization",
                            "description": "OAuth2 Authorization Header",
                            "paramType": "header",
                            "required": false,
                            "allowMultiple": false,
                            "dataType": "String"
                        }

                    ]
                }
            ]
        }
    ]
}

Under parameters section you can see the already defined header “Authorization”. Let’s add another header “username” by adding the below parameter definition under the “parameters” section.

		{
                            "name": "username",
                            "description": "username of the user",
                            "paramType": "header",
                            "required": false,
                            "allowMultiple": false,
                            "dataType": "String"
                        }

After adding the header representation, whole Swagger documentation of the API is

{
    "apiVersion": "1.0.0",
    "swaggerVersion": "1.1",
    "basePath": "http://192.168.122.1:8280",
    "resourcePath": "/swagger",
    "apis": [
        {
            "path": "/swagger/1.0.0/users",
            "description": "",
            "operations": [
                {
                    "httpMethod": "GET",
                    "summary": "",
                    "nickname": "",
                    "parameters": [
                        {
                            "name": "Query Parameters",
                            "description": "Request Query Parameters",
                            "paramType": "body",
                            "required": false,
                            "allowMultiple": false,
                            "dataType": "String"
                        },
                        {
                            "name": "Authorization",
                            "description": "OAuth2 Authorization Header",
                            "paramType": "header",
                            "required": false,
                            "allowMultiple": false,
                            "dataType": "String"
                        },
{
                            "name": "username",
                            "description": "username of the user",
                            "paramType": "header",
                            "required": false,
                            "allowMultiple": false,
                            "dataType": "String"
                        }

                    ]
                }
            ]
        }
    ]
}

New Swagger Doc

new swagger

 

Now add the new header name to Access-Control-Allow-Headers section of repository/conf/api-manager.xml as below

<Access-Control-Allow-Headers>authorization,Access-Control-Allow-Origin,Content-Type, CustomHeader</Access-Control-Allow-Headers>

 

HTTP request before and after

Request to the API before

udara@udara$ nc -l 7777
GET http://localhost:7777/users HTTP/1.1
Accept: */*
Host: localhost:7777
Connection: Keep-Alive
User-Agent: Synapse-PT-HttpComponents-NIO

Request to the API after adding the header to the Swagger documentation

udara@udara$ nc -l 7777
GET http://192.168.122.1:7777/users HTTP/1.1
username: udara
Accept: */*
Host: 192.168.122.1:7777
Connection: Keep-Alive
User-Agent: Synapse-PT-HttpComponents-NIO