Chat now with support
Chat with Support

erwin Enterprise Architect Agile v2 - User Guide

erwin EA Agile v2 - User Guide
Capabilities System Agile EA Tutorials Migration Developer API

SPP API

SPP API

Data Foundation Platform API

Role needed to use: Client Administrator

 

erwin provides an API (Application Programming Interface) for listing objects and object types that are available in a customer client area.

The API can extract data in a JSON format and help you integrate with your existing business applications.

You must be a client administrator to access the API service with authentication credentials.  The authentication uses basic username and password authentication.

The erwin API is available to all erwin EA agile clients.  To use the API, you will need to provide the following URL: api.myerwin.io and the valid method name for the API calls.

For example:  https://api.myerwin.io/object-types

API Calls

Workspaces

GET /workspaces

Retrieve all workspaces.

Implemented query parameters:

None

Expected query parameters:

None

Errors:

None

Example:

https://api.myerwin.io/workspaces

 

Object Types

GET /object-types

Retrieve all object types.

Implemented query parameters:

None

Expected query parameters:

None

Errors:

None

Example:

https://api.myerwin.io/object-types

 

GET /object-types/:type_id

Read the object type with id :type_id.

Errors:

404 if the object type does not exist.

Example:

https://api.myerwin.io/object-types/26555

 

Objects

GET /objects

Retrieve all objects on the default workspace.

Example:

https://api.myerwin.io/objects

 

Query parameters (mixable):

You can mix the following paramaters to further refine your queries.

GET /objects?workspace=ws

Retrieve all objects on the workspace ws by workspace id.

The workspace id can be retrieved by examining the URL in the platform when a workspace is open.

Example:

https://api.myerwin.io/objects?workspace=248

 

GET /objects?type=id

Retrieve all objects that are of type id.

Example:

https://api.myerwin.io/objects?type=26555

 

GET /objects?name=string

Retrieve all objects whose name (case sensitive) contains the given string.

Example:

https://api.myerwin.io/objects?name=Claim%20Handling%20Improvement

 

GET /objects/:id

Retrieve the object with id :id.

Example:

https://api.myerwin.io/objects/62397

 

Errors:

404 if the object type does not exist.

 

 

API Example

API Example

This example makes use of a google sheet to demonstrate how calls can be made to the SPP API.

We're making use of the set of google scripts supplied by 'Fast Fedora' available here.

For more information on the JSON parsing script click here.

 

Create a google sheet (sheets.google.com)

When in a sheet, open Tools... Script Editor

Ensure you embed a copy of the 'google-docs/scripts/ImportJSON/Code.gs' script from 'Fast Fedora' in the script window.  The code is also available here:  https://github.com/bradjasper/ImportJSON/blob/master/ImportJSON.gs

 

For authentication, you need to add the following code before the main section (SPP uses basic authentication):

function ImportJSONBasicAuthentication(url, query, parseOptions, username, password) {

   var fetchOptions = {
      "headers" : {
         "Authorization" : 'Basic ' + Utilities.base64Encode(username + ':' + password)
      },
      muteHttpExceptions: true
   };

  return ImportJSONAdvanced(url, fetchOptions, query, parseOptions, includeXPath_, defaultTransform_);
}

Save the script with the save button.

Now you can use our example google sheet with the Corso API by making your own copy of it (file... make a copy).

Change the username and password to your own username and password.

The sheet template contains a set of tabs which you can navigate through and see the examples working with your data.

The sheet is designed to give you a feel for the 'art of the possible' with the API.

For more information or more help, contact corso support.

 

 

API Limits

API Limits

The Corso SPP API is available to administrators of the Corso SPP.   The limits below are the commercial terms under which the API may be run. For additional usage and limit requests, please contact your account manager.

Corso SPP

API Requests - Upper Limit

Trial Users

100 requests/day/organization

Standard License

Max - 5000 requests/day/organization or 250 requests /user license whichever is lower

 

Important Notes

The PST Time zone will be considered.

We notify SPP administrators (Users with "Administrator" profile) if your organization exceeds the API limit. We also provide API Statistics for better assessment of your integration requirements.

To optimize your API usage, get maximum 200 records with each request and in future editions of the API; insert, update or delete maximum 100 records with each request.

Example: If you have purchased 10 user licenses, you are allowed 2500 requests per day. Using each of those 2500 requests, you can read a maximum 200 records.

That would be 2500 x 200 i.e., 500,000 records can be read per day.

In case, your application requires more than the upper limit, your additional API requests will not be processed. To avoid data transfer issues, please assess your API requirements well in advance. If you need any help, please contact our Support at support@corsosoftware.com

Check API Request Usage (Future Edition)

You can view the total limit for API calls and the current day's API usage in Corso.

1.In Corso SPP click Admin > Developer Space > SPP API.

2.In the SPP API page, the Usage statistics of API section represents the per day usage and total limit for the API calls.

3.When the user calls the API, Check Calls button will be displayed. Click the button to find number of API calls made in your client based on client and username. All the active and confirmed usernames will be displayed in the dropdown list. You can select any username to know the API call count details of that user.

These UI changes will be shown only when the user has made at least one api call. If users did not call any API, then these details will not be displayed.

 

 

 

Reporting with JS Reports

Reporting with JS Reports

 

The example below was constructed using the on-premise version of JS Reports - Installation information can be found at https://jsreport.net/on-prem

The example below explains how JSReports can use JavaScript calls to the API to create a report.

 

The Example Report

The report above show an application component object and some of its attributes, as well as related work package objects (projects), picking out some of those attributes and then a related actor object (project manager)

 

JS Reports

For this example, it is assumed that JSReports has been installed locally, with access to ‘jsreport studio’.

JSReports creates output using a ‘template’, which is composed mainly of HTML.  The template identifies an ‘engine’, a ‘recipe’, any required JavaScript, and some sample JSON test data.  The engine refers to the syntax used in locating data for insertion, and the recipe refers to the way the output is formatted, e.g. PDF.

Supporting Files

Users can download the template, data, and script used for this example.  The content of each file can then be copied and pasted into the appropriate feature of jsreport studio.  The test data can be linked to the template and run without alteration, however the script will require changing before it will run successfully.  Once the required modifications have been made to the script, it can be linked to the template.

The Template

The following template (download file from above) describes a table of Applications and their related Projects;

 

Embedded in the HTML are statements from the ‘handlebars’ engine, which locates data using delimiters {{ and }}, e.g. {{name}}.  Iterations and decisions can be introduced using {{#each � }} and {{#if � }} statements.  The template should be associated with some test data.

 

 

Example JSON Test Data

Some simple JSON test data is not only essential for testing and developing the template, but will act as a useful reference when generating the JavaScript JSON output;

{

    "application": [

        {

            "name": "Back Office Suite",

            "description": "Integrated back-office automation replaces the separate back-office applications.",

            "startDate": "06/02/2017",

            "endDate": "30/11/2020",

            "project": [

                {

                    "name": "CRM System Integration",

                    "startDate": "31/10/2016",

                    "endDate": "30/09/2017",

                    "manager": "Perry White"

                },

                {

                    "name": "Back Office System Integration",

                    "startDate": "01/01/2016",

                    "endDate": "30/11/2017",

                    "manager": "Martha Kent"

                }

            ]

        }

    ]

}

 

The JSON object above contains an “application” array of objects.  Each ‘application’ object has a “name”, “description”, “startDate”, “endDate”, and a “project” array of objects.  Each ‘project’ object has a “name”, “startDate”, “endDate”, and a “manager”.

PDF Output

Using the ‘phantom-pdf’ recipe, the sample data can be rendered into a PDF document, as shown below

 

 

Required Modifications to the Script

Replace the “username” and “password” in erwinGlobals(), with valid access details for your own Agile EA area.

Each of the three object type ids, “692”, “736”, and “719”, will need to be changed to the appropriate ids of ‘Business Actor’, ‘Work Package’ (Project), and ‘Application Component’ from the users client area.

Both of the Project property ids, "1289", and "1293" need to be changed to ‘Date Range’ attribute property ids.  The "457378" id will need changing to a ‘Relationship List’ attribute that references ‘Business Actors’ from the users client area.

Both of the Application property ids, "1104", and "1107" need to be changed to ‘Date’ attribute property ids. The "457377" id will need changing to a ‘Relationship List’ attribute that references ‘Work Packages’ from the users client area.

The object types can be substituted, but the example script expects that ‘Applications’ will have an attribute that is a list of ‘Projects’, which have an attribute that is a list of ‘Actors’.  The example script also requires that the property types of ‘Date Range’ and ‘Date’ remain unchanged.

Users may need to create some of these attributes if they do not exist within the client area already.

 

Below are some API calls to show how the needed script information (Object types, attribute and attribute property ID's) can be gathered.

Identifying Object Type IDs

In this example, three object type ids have been used; 692 (business actor), 736 (work package), and 719 (application component).  These ID's will be unique to a particular users ‘client area’ and you will need to find them.

To identify the id of any object-type in an open workspace in Agile EA; access the ‘User’ menu, its “System” submenu, and select the “Object Types” option.

Upon selecting an object type such as “Application Component”, the displayed URL will look something like; https://myerwin.io/?workspace=448#object-types/719.

  

Identifying Object Type Attributes

Although the getActorNames function (used in the script) checks for the existence of an “id” and “name”, it is expected that they exist.  This expectation comes from identifying the properties of the Object Type by using an API URL, e.g. “https://api.myerwin.io/object-types/692”.

{

  "id": "692",

  "name": "Business actor",

  "description": "A business actor is an organizational entity that is capable of performing behavior.  Examples are humans, departments and business units.",

  "logo": "spp-icon-mt-actor",

  "attributes": [�],

  "relations": [�]

}

 The generated JSON shows that the object has “id” and “name” attributes, as well as “description”, “logo”, and “attributes” and “relations” arrays.  Note that the detail of the “attributes” and “relations” has been hidden to simplify the output.

Identifying Object Type Attribute Properties

In this example, the attributes are referenced using their “id” rather than their “name”.  An extract of the “attributes” array from the URL returning object-type 736, is shown below;

"attributes": [

    {

      "id": "1289",

      "name": "SU. Starting up a Project",

      "objectTypeId": "736",

      "type": "DATE_RANGE_ATTRIBUTE"

    },

    {

      "id": "1293",

      "name": "CP. Closing a Project",

      "objectTypeId": "736",

      "type": "DATE_RANGE_ATTRIBUTE"

    },

    {

      "id": "457378",

      "name": "Manager",

      "objectTypeId": "736",

      "relationshipType": {

        "id": "39864"

      },

      "direction": "B2A",

      "relationshipTypeId": "39864",

      "type": "RELATION_LIST_ATTRIBUTE"

    },

  ],

 

It is also useful to view the JSON generated for an instance of the object-type.  The following extract of the “attributes” object was taken from the JSON returned by the URL “https://api.corso.io/objects/227093”.

 

"attributes": {

    "1289": {

      "type": {

        "id": "1289",

        "name": "SU. Starting up a Project",

        "objectTypeId": "736",

        "type": "DATE_RANGE_ATTRIBUTE"

      },

      "value": {

        "start": "2016-01-01T17:05:00.000+0000",

        "end": "2017-06-30T16:05:00.000+0000"

      }

    },

    "1293": {

      "type": {

        "id": "1293",

        "name": "CP. Closing a Project",

        "objectTypeId": "736",

        "type": "DATE_RANGE_ATTRIBUTE"

      },

      "value": {

        "start": "2016-01-01T17:16:00.000+0000",

        "end": "2017-06-29T15:18:00.000+0000"

      }

    },

    "457378": {

      "type": {

        "id": "457378",

        "name": "Manager",

        "objectTypeId": "736",

        "relationshipType": {

          "id": "39864"

        },

        "direction": "B2A",

        "relationshipTypeId": "39864",

        "type": "RELATION_LIST_ATTRIBUTE"

    },

  }

 

 

Agile EA API JSON Output

Pieces of the script to update

The test JSON data can now be substituted with data from Agile EA.  This is achieved by JavaScript routines that are triggered by JSReport’s ‘beforeRender’ event.  The output from Agile EA can then be restructured to mirror the format of the test data.

 

beforeRender()

When the template ‘runs’, it will execute the “beforeRender” function in the associated ‘script’.

 

// Request data to be used in report before rendering.

function beforeRender(req, res, done) {

    erwinGlobals();

    setData(req, done);

}

In this example, ‘global’ values are established before setting the “data” object in “req”.  The “done()” function will be called upon completion of the script.

 

erwinGlobals()

 

var erwin = {}; // Used to store global constants

// Establish some global constants for source Workspace

function erwinGlobals() {

    var userName = "userName"; // The API will require a login

    var password = "password"; // The password will be encoded

    erwin.requestHeader = "Basic " + encodeCredentials(userName, password);

    erwin.workspace = ""; // A workspace “id” can override the ‘default’.

}

 

It will be necessary to replace the “username” and “password”, before any JSON will be returned.   This detail will be encoded and used in the request header.  Note that data will be returned from the ‘default’ workspace, unless a workspace “id” is used.

 

setData()

The purpose of the script is to replace the “data” object in the ‘request’, with data from a workspace within Agile EA.

 

// Get the Report Data to overwrite 'req.data'

// 1. Request Actors - storing their names

// 2. Request Projects - updating the Manager's name

// 3. Request Applications - linking related Projects.

function setData(req, done) {

    var apiActors = getApiUrl("692"); // 692 = Business Actor

    require('request')( prepareRequest(apiActors), function(err, actorRes, body) {

        var actors = {};

        if (checkForError(req, err, actorRes, body, "Error requesting Actors:")) {

            done(); // terminate early

        } else {

            getActorNames(body, actors);

            processProjects(req, done, actors);

        }

    } );

}

In this example the intension is to build a ‘collection’ of Business Actor Names, which will be used to update the “manager” detail of a collection of Projects, which in turn will be linked to the “project” detail of a collection of Applications.

A ‘URL’ is created from the id of the Business Actor object type, in this case “692”. This is then used to ‘prepare the request’ for JSON data.

f an error occurs, the “done” function is called, terminating the “beforeRender” event, otherwise the “actors” object is built from the detail in the “body”, and passed to the processing of the Projects.

 

processProjects()

The processing of the Projects is similar to the Actors;

 

// Create a collection of Projects and update their manager's name.

function processProjects(req, done, actors) {

    var apiProjects = getApiUrl("736"); // 736 = Work Package (Project)

    require('request')( prepareRequest(apiProjects), function(err, projectRes, body) {

        var projects = {};

        if (checkForError(req, err, projectRes, body, "Error requesting Projects:")) {

            done(); // terminate early

        } else {

            getProjectDetail(body, projects, actors);

            processApplications(req, done, projects);

        }

    } );

}

 

Projects are represented by Work Package object types; “736”.

If no error occurs the “projects” object is built from detail in the “body” and names from the “actors” object, before being passed to the processing of the Applications.

 

processApplications()

The processing of the Applications will conclude with the update of “req.data”;

 

// Create a collection of Applications linked to associated Projects

function processApplications(req, done, projects) {

    var apiApplications = getApiUrl("719"); // 719 = Application Component

    require('request')( prepareRequest(apiApplications), function(err, appRes, body) {

        var applications = [];

        if (checkForError(req, err, appRes, body, "Error requesting Applications:")) {

            done(); // terminate early

        } else {

            getApplicationDetail(body, applications, projects);

            nameSort(applications);

            // Substitute the req.data with the sorted application array object

            req.data = {

                application: applications

            };

        }

        done(); // successful completion

    } );

}

The Application Component object type, “719” is used to request Application data.

If no error occurs the “applications” array is built from detail in the “body” and related Projects, before sorting, and being used to override the existing ‘test data’.

 

getActorNames()

A simple function is required to extract the required “name” property from the detail returned from the request for Business Actors, and build a collection that can be accessed using its “id”.

 

// Extract the Names from the returned Actor detail.

function getActorNames(body, actors) {

    body.forEach(function (object) {

        var actor = {};

        if (object.id) {

            if (object.name) {

                actor.name = object.name;

                actors[object.id] = actor;

            }

        }

    } );

}

For each of the objects in the “body” that has an “id” and “name” property, create an object consisting of the “name” value keyed by the “id” value, and append it to “actors”.

 

getProjectDetail()

In addition to its name, the Project requires a ‘start date’, ‘end date’, and the name of its manager.  This additional detail comes from objects within the “attributes” array.

 

// Update the 'projects' object with details;

// Name, Start Date, End Date, and Manager.

function getProjectDetail(body, projects, actors) {

    var startDateAttributeId = "1289",

        endDateAttributeId = "1293",

        managersAttributeId = "457378";

    var nameIds = [];

    body.forEach(function (object) {

        var project = {};

        if (object.name) {

            project.name = object.name;

        }

        if (object.attributes[startDateAttributeId]) {

            project.startDate = getDate(object.attributes[startDateAttributeId].value.start);

        }

        if (object.attributes[endDateAttributeId]) {

            project.endDate = getDate(object.attributes[endDateAttributeId].value.end);

        }

        if (object.attributes[managersAttributeId]) {

            namesIds = getOtherIds(object.attributes[managersAttributeId].value, object.id);

            project.manager = getIdName(namesIds, actors);

        }

        projects[object.id] = project;

    } );

}

Three variables have been assigned values that identify the required attributes.  A “project” object is created for each of the Projects in the “body”, and updated with a “name”, “startDate”, “endDate”, and “manager”.  The dates are to be formatted differently to the way that they appear in the exported JSON, and the name of the manager(s) is to be returned from the “actors” using the “id” from the exported JSON.

 

 

getApplicationDetail()

The detail required for the Application is its name, description, start and end dates, and the related Projects.

 

// Update the 'applications' object with details;

// Name, Description, Start Date, End Date, and related Projects.

function getApplicationDetail(body, applications, projects) {

    var startDateAttributeId = "1104",

        endDateAttributeId = "1107",

        projectsAttributeId = "457377";

    body.forEach(function (object) {

        var appObject = {};

        if (object.name) {

            appObject.name = object.name;

        }

        if (object.description) {

            appObject.description = object.description;

        }

        if (object.attributes[startDateAttributeId]) {

            appObject.startDate = getDate(object.attributes[startDateAttributeId].value);

        }

        if (object.attributes[endDateAttributeId]) {

            appObject.endDate = getDate(object.attributes[endDateAttributeId].value);

        }

        appObject.project = [];

        if (object.attributes[projectsAttributeId]) {

            objectValue = object.attributes[projectsAttributeId].value;

            linkProjects(appObject, objectValue, object.id, projects);

        }

        if (appObject.project.length === 0) {

            appObject.project = [{}];

        }

        applications.push(appObject);

    } );

}

This function is very similar to GetProjectDetail() except that it contains additional code that builds the application’s project array.

 

An Example Report using data from the API

Once the script has completed, the report is rendered with the substituted data, and could look something like this;

 

 

Related Documents

The document was helpful.

Select Rating

I easily found the information I needed.

Select Rating