rest api programming guide - ibm€¦ · chapter 1. introduction the ibm cloud managed services...

46
IBM Cloud Managed Services Release 1.4.1 REST API Programming Guide

Upload: duongkhuong

Post on 26-Apr-2018

225 views

Category:

Documents


0 download

TRANSCRIPT

IBM Cloud Managed ServicesRelease 1.4.1

REST API Programming Guide

���

IBM Cloud Managed ServicesRelease 1.4.1

REST API Programming Guide

���

NoteBefore using this information and the product it supports, read the information in “Notices” on page 35.

Book Edition Notice

This edition applies to release 1.4.1 of IBM Cloud Managed Services and to all subsequent releases andmodifications until otherwise indicated in new editions.

© Copyright IBM Corporation 2012, 2014.US Government Users Restricted Rights – Use, duplication or disclosure restricted by GSA ADP Schedule Contractwith IBM Corp.

Contents

About this document . . . . . . . . . vWho should use this document . . . . . . . . vHow this document is organized . . . . . . . vWhere to find more information . . . . . . . . vWe'd like to hear from you . . . . . . . . . v

Chapter 1. Introduction . . . . . . . . 1Resources and Representations . . . . . . . . 1References . . . . . . . . . . . . . . . 2Uniform Resource Locators . . . . . . . . . 2

Chapter 2. IBM Cloud Managed Servicessample client . . . . . . . . . . . . 3Adopting the sample code . . . . . . . . . . 3Passing data to the sample client . . . . . . . 4

Properties file . . . . . . . . . . . . . 4Data file . . . . . . . . . . . . . . . 4Command line options . . . . . . . . . . 6

Building a request header . . . . . . . . . . 6Specifying methods and payload types . . . . 7HTTP authentication. . . . . . . . . . . 8

Building a request body . . . . . . . . . . 8Creating a project by using XML API . . . . . 9Creating a project by using XML straight . . . 10Serializing by using JSON . . . . . . . . 11Serializing by using JSON straight . . . . . . 11

Running a request . . . . . . . . . . . . 12Retrieving information for a specific ID . . . . 12Retrieving information for a complete list ofgroups . . . . . . . . . . . . . . . 13Creating a group . . . . . . . . . . . 14Deleting a group . . . . . . . . . . . 15

Analyzing an REST API HTTP Response . . . . 16Response codes . . . . . . . . . . . . 16Analyzing the response header . . . . . . . 17Analyzing the response body . . . . . . . 17Analyzing an XML response. . . . . . . . 18Analyzing a JSON response . . . . . . . . 20Retrieving the ID of a resource by name . . . . 21Waiting for a request to complete . . . . . . 23

Matching user interface tasks to REST API calls . . 24Instructions to build a Cloud Managed Servicessample client . . . . . . . . . . . . . . 26

Compiling the sample Java files . . . . . . 26Configuring Secure Socket Layer connection . . 26Reading command line options . . . . . . . 28Reading external files . . . . . . . . . . 31

Chapter 3. Resources . . . . . . . . 33

Notices . . . . . . . . . . . . . . 35Trademarks . . . . . . . . . . . . . . 36

© Copyright IBM Corp. 2012, 2014 iii

iv IBM Cloud Managed Services Release 1.4.1: REST API Programming Guide

About this document

This Programmer's Guide is for the IBM Cloud Managed Services (CMS) RESTAPI. It supplements the IBM Cloud Managed Services User's Guide and the IBMCloud Managed Services Rest API Specification Guide. For each of the serviceofferings described in the IBM Cloud Managed Services User's Guide there is aresource in the REST API that provides the capability of the service offering. Thisguide provides sample Java code that illustrates how to use the REST APIresources programmatically to request CMS services.

Who should use this documentThis guide is intended for IBM Cloud Managed Services (CMS) developers whowant to manage service requests, servers, users, teams, projects and other resourcesof the CMS by means of a REST API. It provides support to build clients of CMSusing a RESTful application development style.

You should be familiar with:v RESTful web servicesv HTTP/1.1v JaveScript Object Notation (JSON) and/or XML data serialization formats

How this document is organizedThis document is organized as follows:v Chapter 1 is an introduction to the IBM Cloud Managed Services (CMS) REST

API.v Chapter 2 discusses a sample client written in Java.v Chapter 3 gives hints on how to work with the CMS REST API sample code.v Chapter 4 provides instructions to build a CMS sample client.

Where to find more informationDevelopers should review the online IBM Cloud Managed Services User's Guide.Much of the capabilities exposed through the web experience are available throughthe API. Developers should explore the web experience to gain a betterunderstanding of the overall solution.

We'd like to hear from youWe appreciate your comments about this publication. Please comment on specificerrors or omissions, accuracy, organization, subject matter, or completeness of thisbook. The comments you send should pertain to only the information in thismanual or product and the way in which the information is presented.

For technical questions and information about products and prices, please contactyour IBM® branch office, your IBM business partner, or your authorizedremarketer.

When you send comments to IBM, you grant IBM a nonexclusive right to use ordistribute your comments in any way it believes appropriate without incurring any

© Copyright IBM Corp. 2012, 2014 v

obligation to you. IBM or any other organizations will only use the personalinformation that you supply to contact you about the issues that you state on thisform.

Thank you for your support. Please send your comments via email to:[email protected]

vi IBM Cloud Managed Services Release 1.4.1: REST API Programming Guide

Chapter 1. Introduction

The IBM Cloud Managed Services (CMS)REST API is a RESTful applicationprogramming interface that complies with the IBM Infrastructure as a Service(IaaS) REST API (see Resources). It implements those parts of the API that apply tothe CMS set of offerings. It also adds several new resources beyond the ones thatare specified by the IBM IaaS REST API specification to support value-addedofferings that are unique to CMS.

For a complete list and description of CMS resources, see the IBM Cloud ManagedServices Rest API Specification Guide.

Client programs that use the IBM CMS REST API communicate over HTTPexchanging representations of CMS resources. These representations have the formof XML elements or JaveScript Object Notation (JSON) objects.

HTTP GET requests are used to retrieve the representation of aresource or a list of resources.

HTTP POST requests are used to create new resources.

HTTP PUT requests are used to update existing resources.

HTTP DELETE requests are used to delete resources.

Resources and RepresentationsThe IBM Cloud Managed Services API represents resources in two formats:

XML

Properties of a resource are encoded as elements and attributes. References to otherresources are encoded as Uniform Resource Identifier .

Example<team><id>432</id><name>Development1</name><description>Development team 1</description><lob uri=”/lobs/3” /></team>

JaveScript Object Notation

Properties of a resource are encoded as name and value pairs. References to otherresources are encoded as special objects (see References)

Example{ “team”:

{ “id”: “432”,“name”: “Development1”,“description”: “Development team 1”,“lob”: { “uri”: “/lobs/3” }

}}

© Copyright IBM Corp. 2012, 2014 1

ReferencesMany resources are not self-contained and are related to other resources. Thisrelation is manifested by properties that are of type Uniform Resource Identifier(URI). In XML representation, this property is expressed by an attributeuri="value" that specifies the URI. In JaveScript Object Notation (JSON)representation, this property is expressed by an object with the single name andvalue pair { "uri": "value"}. In the resource model, these resources are connectedby an arrow from the source resource to the referenced resource.

Uniform Resource LocatorsClients make HTTP requests to the URLs of the IBM Cloud Managed Services(CMS) API. Every resource has a well-known URL. A URL is built as follows:https://{host}:{port}/scep/v1/rest/{resource}/{id}/{operation}?{query_parameters}

Example:https://cloudserver.mycompany.com:9443/scep/v1/rest/jobs/1234

All parts in brackets are variables while the others are fixed parts.

Description of the URL parts

{host} The host name or the IP address of the server where the CMS REST API isrunning.

{port} The port on which the CMS RESTAPI is listening.

{resource}The name of the resource on which the request must act.

{id} The identifier of the resource on which the request must act.

{operation}An optional operation specifies an operation on a resource beyond the baseresource operations that are provided (create, retrieve, update, delete). Forexample: https://cloudserver.mycompany.com:9443/scep/V1/rest/instances/42/incremental_backup where incremental_backup requests thecreation of an incremental file backup.

{query_parameters}Optional query parameters to filter the complete list of resources thatwould be returned with an unqualified query. Query parameters can bespecified only with HTTP GET requests.

2 IBM Cloud Managed Services Release 1.4.1: REST API Programming Guide

Chapter 2. IBM Cloud Managed Services sample client

You can create a sample Java client program that issues IBM Cloud ManagedServices (CMS) REST API requests to an CMS server.

To create a sample Java client program, you need to construct an HTTP request,send it to the CMS server, receive the response, analyze the response, and addauthentication to the CMS server.

Prerequisites:v Java SDK 1.6

The Cloud Managed Services_REST_API_Sample_Client.zip file contains thefollowing files:v control.properties: Properties to access the CMS REST API server.v post_incidents.csv: Data needed to create incidents.v post_instance.csv: Sample data that is needed to create an instance. (You must

update the IDs.)v SampleClient.java: Sample Java client code that is elaborated in this document.v RetrieveSSLCert.java: Java code to retrieve the server certificate of the CMS

REST API server.v SimpleJSONParser.java: Java code for a simple JaveScript Object Notation

(JSON) parser.

Note: You can get the Cloud Managed Services_REST_API_Sample_Client.zip filefrom the Delivery Program Executive (DPE) team.

Adopting the sample codeIf you want use the sample client code to write your own Java code, then youmust complete the following steps:1. From the list of tasks that are provided in “Matching user interface tasks to

REST API calls” on page 24 choose the task that you want to perform.2. If you plan to work on resources other than groups or instances, then you must

provide methods to serialize and deserialize the resources. The methods thatyou provide must be analogous to the following methods: SampleClient,createGroupPayloadJSON, createGroupPayloadXML, analyzeGroupJSON, andanalyzeGroupXML.

3. Create an instance of the SampleClient class by using the following command:SampleClient client = new SampleClient();

4. Read the controlling properties from an existing file or create an instance of theclass Properties and add the properties in your Java code.Properties control = client.readProperties(propertiesFileName);

5. Create a data file that contains all the data that is needed to create a payload.The data file is a file that contains comma-separated values. For moreinformation, see the sample files, post_instance.csv and post_projects.csv,and section Passing data to the Sample Client.

6. If the task is non REST API, GET request read the payload data from a file orcreate the necessary data structure and add it to your Java code.

© Copyright IBM Corp. 2012, 2014 3

|

||

List<HashMap<String, Object>> data = client.readData(dataFileName);

7. Run the following command to initialize the networking environment:client.initNetEnvironment(control);

8. Depending on the request, call the SampleClient method:client.issueGetRequest(data, control,

(String)options.get("resource"),(List<String>)options.get("ids"));

client.issueGetListRequest(data, control, (String)options.get("resource"));

client.issuePostRequest(data, control,(String)options.get("resource"),(Boolean)options.get("wait"));

client.issuePutRequest(data, control, (String)options.get("resource"));

client.issueDeleteRequest(data, control,(String)options.get("resource"),(List<String>)options.get("ids"),(Boolean)options.get("wait"));

You can adapt code for every type of resource by using Java code that is providedin the sample client and the utility classes. The provided Java code intentionallydoes not use any external library beside the Java Development Kit (JDK) library.However, you can use libraries that are available and support JSON, XML, andREST APIs. For details on the payload data that is sent to server by using IBMCloud Managed Services (CMS) REST API and the payload data that is returnedfrom the server, see IBM Cloud Managed Services Rest API Specification Guide.

Passing data to the sample clientYou can pass data to the sample client program by adding a properties file and adata file. For more information about reading and validating these files,see.“Instructions to build a Cloud Managed Services sample client” on page 26.

Properties fileA properties file contains configuration information that is needed to connect tothe server that is running the IBM Cloud Managed Services (CMS) REST API. Thisfile uses the Java standard properties utility and classes by storing the data asname-value pairs in the file.

The properties file contains the following properties:v keyStore: This property stores file name of a Keystore file that contains a

certificate that is needed to connect to the server.v user: This property stores user ID by using which you can log on to the server

through the CMS REST API.v password: This property stores password for the user ID.v url: This property stores the URL to the CMS REST API.keyStore=/home/user/[email protected]=secreturl=https://myserver.com:9443/scep/v1/rest/

Data fileA data file contains data for the request in comma-separated values (csv) format.This format allows the creation of the data as a spreadsheet by any spreadsheetprogram that allows the export of the data in csv format. Also, it is possible toissue an arbitrary number of Cloud Managed Services (CMS ) REST API requests

4 IBM Cloud Managed Services Release 1.4.1: REST API Programming Guide

for one resource and request method. For example, creating as many users asrequired with one single execution of the sample client program. The data file isonly used for requests that send payload data to the server that is post requests tocreate new resources and put requests to update resources.

The following sample data file issues requests to create incidents if method is postand resource is incident:"Summary","Details","Impact",”Urgency”,”Type”SampleIncident1,details for one sample,LOW,LOW,GENERAL_ISSUESampleIncident2,test for another sample,LOW,MEDIUM,SCE+_INFRASTRUCTURE_ISSUE

To create a new instance by using a data file, you must first retrieve IDs for thefollowing parameters, and then create content for the data file:

Configuration items URL for API GET call and sample output

VM configuration https://rest_srv.com/scep/v1/rest/vm_configurations?_ultracompact=true

<vm_configuration> <id>1</id><name>Small</name>

Image https://rest_srv.com/scep/v1/rest/images?_ultracompact=true

<image> <id>720</id> <name>MS WindowsServer 2012 R2 Datacenter Edition(64bit)</name>

Group https://rest_srv.com/scep/v1/rest/groups?_ultracompact=true

<group> <id>1458</id> <name>Rickproject google</name>

Security Zone https://rest_srv.com/scep/v1/rest/security_zones

<security_zone> <id>56</id> <name>WebZone</name>

SLA https://rest_srv.com/scep/v1/rest/slas

<sla> <id>53</id> <name>Bronze</name>

Patch_schedule https://rest_srv.com/scep/v1/rest/patch_schedule_categories

<patch_schedule_category> <id>57</id><name>Test</name> <description>Test</description>

Domain https://rest_srv.com/scep/v1/rest/domains

<domain> <id>A37</id><name>ehn.ssm.sdc.gts.ibm.com</name>

Server_type Fixed values

unmanaged, managed, cluster anchor,cluster node, image repository

This data file creates a virtual machine (instance), if the method is post andresource is instances.

Chapter 2. IBM Cloud Managed Services sample client 5

"VM_configuration","Image","group","security_zone","sla","patch_schedule_category","domain","server_type"1,720,1458,56,53,57,A37,”managed”

Command line optionsYou must pass the method, resource, file names, and other options of the RESTresource that you want to use by using the following command line options:

-r Specifies the resource that you want to work on. Use plural forms so thatyou can use the provided string to build a URL.

For example: "groups", "instances".

-m Specifies the method that you can use for the HTTP request against theCMS REST API. Following are the valid values:v get to retrieve a specific instance of a resource.v get.list to retrieve all instances of a resource.v post to create a new instance of a resource.v put to update a specific instance of a resource.v delete to delete a specific instance of a resource.

-i Specifies a list of identifiers to be used for a single get request and deleterequests.

For example: -i "1,13,17,19".

-n Specifies the name that must be used to retrieve the ID of a specificresource.

-w Specifies that the program must wait until the initiated service request (job)is completed. This option is ignored for API GET requests.

Building a request headerYou must build a request header to connect to the server that runs the IBM CloudManaged Services REST API.

6 IBM Cloud Managed Services Release 1.4.1: REST API Programming Guide

Specifying methods and payload typesYou must specify request methods and set their types. Following are sampleheaders for GET and POST methods:

GET with JSON output// we want to issue a GET requestconnection.setRequestMethod("GET");// specify the format of the returned dataconnection.setRequestProperty("Accept", "application/json");// connection.setRequestProperty("Accept", "application/xml");// we expect data in the response bodyconnection.setDoOutput(true);

POST with XML payload// we want to POST content to the serverconnection.setRequestMethod("POST");// the payload is encoded as JSON// connection.setRequestProperty("Content-Type","application/json");// the payload is encoded as XMLconnection.setRequestProperty("Content-Type","application/xml");

Figure 1. Building a request header

Chapter 2. IBM Cloud Managed Services sample client 7

// we expect data back (maybe some error information)connection.setDoOutput(true);// we will provide payloadconnection.setDoInput(true);

HTTP authenticationTo create a connection you must introduce another function that can be usedregardless of the resource that you want to interact with. The function opens aconnection for the provided URL, and adds the request header information to logon with the user ID and password that is provided in the control properties file.The function encodes the string user:password with the base64 algorithm for theHTTP Basic Authentication.public static HttpsURLConnection createConnection(URL url, Properties control) {HttpsURLConnection connection = null;try {connection = (HttpsURLConnection) url.openConnection();String encodedCredentials =

encodeCredentials(control.getProperty("user"),control.getProperty("password"));

connection.setRequestProperty("Authorization", "Basic " +encodedCredentials);

System.out.println("Connecting to " + url.toString());} catch (IOException e) {System.err.println("Error while opening connection: " + e.getMessage());

}return connection;}

Building a request bodyYou must serialize the data that is coming in from a data csv file and that is storedin a list of name-value pairs. The XML and JSON samples in the following sectionsshow serialization of data that is needed to create a project.

The listed code assumes that all required data is available.

Figure 2. Building a request body

8 IBM Cloud Managed Services Release 1.4.1: REST API Programming Guide

Creating a project by using XML APIThe following sample code uses XML Java API from the w3c contained in the JavaDevelopment Kit. It constructs the DOM tree for the XML structure that is neededto create a project.public static String createGroupPayloadXML(HashMap<String, Object> properties) {String result = null;// build an XML structure and then serialize ittry {// initialize the XML APIDOMImplementationRegistry registry =

DOMImplementationRegistry.newInstance();DOMImplementation domImpl = registry.getDOMImplementation("XML 3.0");DOMImplementationLS domImplLS = null;if (domImpl instanceof DOMImplementationLS) {domImplLS = (DOMImplementationLS) domImpl;}// create the root nodeDocument root = domImpl.createDocument(null, null, null);// create the group nodeElement groupElement = root.createElement("group");// add the project name informationif (properties.containsKey("name")) {Element nameElement = root.createElement("name");groupElement.appendChild(nameElement);Text nameValue =root.createTextNode((String) properties.get("name"));nameElement.appendChild(nameValue);

}// add the description informationif (properties.containsKey("description")) {Element descriptionElement = root.createElement("description");groupElement.appendChild(descriptionElement);Text descriptionValue =root.createTextNode((String) properties.get("description"));descriptionElement.appendChild(descriptionValue);}// add the team id informationif (properties.containsKey("team id")) {// for this information we first need an options tagElement optionsElement = root.createElement("options");groupElement.appendChild(optionsElement);// ... that contains an option tagElement optionElement = root.createElement("option");optionsElement.appendChild(optionElement);// now create the option information itselfElement nameElement = root.createElement("name");optionElement.appendChild(nameElement);Text nameValue = root.createTextNode("team");nameElement.appendChild(nameValue);Element valueElement = root.createElement("value");optionElement.appendChild(valueElement);// construct the uri and append itString teamUri = "/teams/" + (String) properties.get("team id");Element teamElement = root.createElement("team");// attention: uri is an attribute not an element!teamElement.setAttribute("uri", teamUri);valueElement.appendChild(teamElement);}// now try to serialize the whole into a stringif (domImplLS != null) {LSSerializer serializer = domImplLS.createLSSerializer();if (serializer.getDomConfig().canSetParameter("xml-declaration", Boolean.FALSE)) {serializer.getDomConfig().setParameter("xml-declaration", Boolean.FALSE);}result = serializer.writeToString(groupElement);

Chapter 2. IBM Cloud Managed Services sample client 9

}} catch (IllegalAccessException e) {// from DOMImplementationRegistry.newInstance} catch (ClassNotFoundException e) {// from DOMImplementationRegistry.newInstance} catch (InstantiationException e) {// from DOMImplementationRegistry.newInstance}return result;}

Creating a project by using XML straightThe following sample code displays another way of creating a project where youcan directly create a string without building an XML structure, and then serializeit. You can do this method when you create a payload to create an instance.public static String createInstancePayloadXML(HashMap<String, Object> properties) {

StringBuilder result = new StringBuilder();

// Build the string straight forward from the provided data// without creating an XML structureresult.append("<instance>");

if (properties.containsKey("VM Configuration id")) {result.append("<vm_configuration>");result.append("/vm_configurations/" + properties.get("VM Configuration id"));result.append("</vm_configuration>");}

if (properties.containsKey("Image id")) {result.append("<image uri=\"");result.append("/images/" + properties.get("Image id"));result.append("\"/>");}

result.append("<options>");

if (properties.containsKey("Group id")) {result.append("<option><name>group</name><value><group uri=\"");result.append("/groups/" + properties.get("Group id"));result.append("\"/></value></option>");}

if (properties.containsKey("Security zone id")) {result.append("<option><name>security_zone</name><value><security_zone uri=\"");result.append("/security_zones/" + properties.get("Security zone id"));result.append("\"/></value></option>");}

if (properties.containsKey("SLA id")) {result.append("<option><name>sla</name><value><sla uri=\"");result.append("/slas/" + properties.get("SLA id"));result.append("\"/></value></option>");}

if (properties.containsKey("Patch schedule category id")) {result.append("<option><name>patch_schedule_category</name><value>

<patch_schedule_category uri=\"");result.append("/patch_schedule_categories/" + properties.get("Patch schedule category id"));result.append("\"/></value></option>");}

result.append("</options>");

10 IBM Cloud Managed Services Release 1.4.1: REST API Programming Guide

result.append("</instance>");

return result.toString();}

Serializing by using JSONThe following sample code shows serialization of the provided data to JSON. Youdo not necessarily need an API. You can use the provided data as shown in thefollowing sample.public String createGroupPayloadJSON(HashMap<String, Object> properties) {

String result = null;

// build a JSON structure and then serialize itHashMap<String, Object> groupObject = new HashMap<String, Object>();

// add the project name informationif (properties.containsKey("name")) {groupObject.put("name", properties.get("name"));}

// add the description informationif (properties.containsKey("description")) {groupObject.put("description", properties.get("description"));}

// add the team id informationif (properties.containsKey("team id")) {String teamUri = "/teams/" + properties.get("team id");HashMap<String, Object> teamUriObject = new HashMap<String, Object>();teamUriObject.put("uri", teamUri);

// options are nested JSON objectsHashMap<String, Object> optionsObject = new HashMap<String, Object>();optionsObject.put("team", teamUriObject);groupObject.put("options", optionsObject);}

HashMap<String, Object> rootObject = new HashMap<String, Object>();rootObject.put("group", groupObject);

// now serialize the mapresult = parser.serializeAsJson(rootObject);

return result;}

Serializing by using JSON straightThe following sample code shows another way of data serialization. You can writethe JSON data directly to a string without creating data structures, and thenserialize it.public static String createInstancePayloadJSON(HashMap<String, Object> properties) {

StringBuilder result = new StringBuilder();

// build the pay load string directly without// creating an intermediate data structureresult.append("{\"instance\":{");

if (properties.containsKey("VM Configuration id")) {result.append("\"vm_configuration\":\"");result.append("/vm_configurations/" + properties.get("VM Configuration id"));result.append("\",");}

Chapter 2. IBM Cloud Managed Services sample client 11

if (properties.containsKey("Image id")) {result.append("\"image\":{\"uri\":\"");result.append("/images/" + properties.get("Image id"));result.append("\"},");}

result.append("\"options\":{");

if (properties.containsKey("Group id")) {result.append("\"group\":{\"uri\":\"");result.append("/groups/" + properties.get("Group id"));result.append("\"},");}

if (properties.containsKey("Security zone id")) {result.append("\"security_zone\":{\"uri\":\"");result.append("/security_zones/" + properties.get("Security zone id"));result.append("\"},");}

if (properties.containsKey("SLA id")) {result.append("\"sla\":{\"uri\":\"");result.append("/slas/" + properties.get("SLA id"));result.append("\"},");}

if (properties.containsKey("Patch schedule category id")) {result.append("\"patch_schedule_category\":{\"uri\":\"");result.append("/patch_schedule_categories/" + properties.get("Patch schedule category id"));result.append("\"}");}

// close the optionsresult.append("}");

// close the instance objectresult.append("}");

// close the root objectresult.append("}");

return result.toString();}

The result of either of the two serialization routines is written to the HTTP request.

Running a requestAfter everything is prepared, it is time to run the request.

Retrieving information for a specific IDThe following sample code displays a GET request to retrieve information for asingle group:// if it is a single get requestif (control.getProperty("method").equalsIgnoreCase("GET")) {

client.issueGetRequest(data, control,(String)options.get("resource"),(List<String>)options.get("ids"));

} // end if it is a get request

public void issueGetRequest(List<HashMap<String, Object>> data, Properties control,String resource,

12 IBM Cloud Managed Services Release 1.4.1: REST API Programming Guide

List<String> ids) throws MalformedURLException, ProtocolException, IOException {

// for each of the provided idsIterator<String> it = ids.iterator();while (it.hasNext()) {String value = it.next();

// build the URL from the parts of the control// properties file and the id we just readURL url = new URL(control.getProperty("url") + resource + "/" + value);

// create the connection to the serverHttpsURLConnection connection = createConnection(url, control);

// we want to issue a GET requestconnection.setRequestMethod("GET");

// specify the format of the returned dataconnection.setRequestProperty("Accept", "application/json");// connection.setRequestProperty("Accept", "application/xml");

// we expect data in the response bodyconnection.setDoOutput(true);

// if the request was successfulif (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {

// retrieve the response i.e. the data for// the resourceString response = getResponse(connection);

// analyze the response// we didn’t specify that we want the output// in JSON representation so we get XML// HashMap<String, Object> result =// client.analyzeSingleResourceResponseXML(response);HashMap<String, Object> result = analyzeSingleResourceResponseJSON(response);

// do what you want with the resultdumpData(result);} else { // end response is okSystem.err.println("Could not finish processing. Response code:

" + connection.getResponseCode());}}}

Retrieving information for a complete list of groupsThe following sample code displays a GET request to retrieve information of acomplete list of groups.if (control.getProperty("method").equalsIgnoreCase("GET.LIST")) {

client.issueGetListRequest(data, control,(String)options.get("resource"));

}

The following sample code reads the data as a string and does no further analysis.public static void issueGetListRequest(List<HashMap<String, Object>> data,Properties control, String resource)

throws MalformedURLException, ProtocolException, IOException {URL url = new URL(control.getProperty("url") + resource);HttpsURLConnection connection = createConnection(url, control);connection.setRequestMethod("GET");connection.setDoOutput(true);

System.out.println("Resp Code:" + connection.getResponseCode());

Chapter 2. IBM Cloud Managed Services sample client 13

System.out.println("Resp Message:" + connection.getResponseMessage());System.out.println("Content type:" + connection.getContentType());String response = getResponse(connection);System.out.println("Response:\n" + response);

}

Creating a groupThe following sample code displays a POST request. You must provide somepayload to create a group on the server.if (control.getProperty("method").equalsIgnoreCase("POST")) {

client.issuePostRequest(data, control,(String)options.get("resource"),(Boolean)options.get("wait"));

}

public static void issuePostRequest(List<HashMap<String, Object>> data, Properties control,String resource,

Boolean wait) throws IOException, InterruptedException {

// take the provided data and create the payloadfor (HashMap<String, Object> outer : data) {

String xmlPayLoad = null;

// create the pay load to be sentif (resource.equals("groups")) {xmlPayLoad = createGroupPayloadXML(outer);} else if (resource.equals("instances")) {xmlPayLoad = createInstancePayloadXML(outer);} else if (resource.equals("incidents")) {xmlPayLoad = createIncidentPayloadXML(outer);}

// create the URLURL url = new URL(control.getProperty("url") + resource);

// create the URLHttpsURLConnection connection = createConnection(url, control);try {// we expect data back (maybe some error information)connection.setDoOutput(true);

// we will provide payloadconnection.setDoInput(true);

// we want to POST content to the serverconnection.setRequestMethod("POST");

// the payload is encoded as JSON// connection.setRequestProperty("Content-Type",// "application/json");

// the payload is encoded as XMLconnection.setRequestProperty("Content-Type", "application/xml");

// send the request to the serverpostContent(connection, xmlPayLoad);

// get the response from the servergetResponse(connection);

// if the request was successful

14 IBM Cloud Managed Services Release 1.4.1: REST API Programming Guide

if (connection.getResponseCode() == HttpURLConnection.HTTP_ACCEPTED) {

// retrieve the job URI aka the information for the service// requestString jobUri = connection.getHeaderField("Job_URI");

if (jobUri != null) {System.out.println("Create in progress with job: " + jobUri);

}} else {System.err.println("Response code: " + connection.getResponseCode());// seems that the payload had an error// so let’s print the information on thatSystem.err.println("Response:\n" + getConnectionError(connection));}} catch (IOException e) {System.err.println("Response code: " + connection.getResponseCode());System.err.println("Response:\n" + getConnectionError(connection));}}}

Note: The PUT request is similar to a POST request. The only difference is thatyou send the payload for a certain resource that is determined by an identifier.

Deleting a groupA DELETE request is similar to a GET request beside the fact that no payload isreturned. Instead, the response header contains information about the servicerequest that fulfills the delete request on the server.

The following sample code displays a DELETE request:if (control.getProperty("method").equalsIgnoreCase("DELETE")) {

client.issueDeleteRequest(data, control,(String)options.get("resource"),(List<String>)options.get("ids"),(Boolean)options.get("wait"));

} // end DELETE request

public static void issueDeleteRequest(List<HashMap<String, Object>> data,Properties control, String resource,

List<String> ids, Boolean wait) throws MalformedURLException, ProtocolException,IOException,

InterruptedException {

// for each of the provided idsIterator<String> it = ids.iterator();

while (it.hasNext()) {String value = it.next();// build the URLURL url = new URL(control.getProperty("url") + resource + "/" + value);

HttpsURLConnection connection = null;

try {

// create the connectionconnection = createConnection(url, control);

// we want to delete the resourceconnection.setRequestMethod("DELETE");

Chapter 2. IBM Cloud Managed Services sample client 15

// get the response from servergetResponse(connection);

// HTTP_ACCEPTED means a job was created// to delete the resourceif (connection.getResponseCode() == HttpURLConnection.HTTP_ACCEPTED) {

// get the job informationString jobUri = connection.getHeaderField("Job_URI");if (jobUri != null) {System.out.println("Delete in progress with job: " + jobUri);

} // end job uri available} // end response code is HTTP_ACCEPTED} catch (IOException e) {System.err.println("Response code: " + connection.getResponseCode());System.err.println("Response:\n" + getConnectionError(connection));}} // end for every row of the input data

}

Analyzing an REST API HTTP ResponseSeveral parts of the response must be checked step-by-step and depended actionsmust be completed.

Response codesEvery request returns a response code in the response header. Run the followingcommand to get a response code:

Figure 3. Analyzing REST API Response

16 IBM Cloud Managed Services Release 1.4.1: REST API Programming Guide

int responseCode = connection.getResponseCode();

The response code indicates whether the request was successful or failed. Theresponse codes at times provide additional information that helps in identifyingand rectifying failures in requests.

Status Description

200 Success

201 Created

202 Accepted (for asynchronous operations)

400 Resource Invalid (improperly formatted request)

401 Unauthorized (failed authentication)

404 Resource not found

406 Not acceptable (for example, invalid Accept Header)

415 Unsupported Media Type

500 Application Error

For response code 400 (invalid request), the response body contains detailedinformation on the detected problem.

For detailed list of response codes for any resource and method, see CMS Rest APISpecification Guide.

Analyzing the response headerResponse headers contain information that can be used to obtain furtherinformation of a request.

If the response code is ACCEPTED (202), then the response header containsinformation about a job that is running to fulfill the request. Run the followingcommand to retrieve information about the corresponding header field:String jobUri = connection.getHeaderField(“Job_URI”);

The command displays a string that contains the Uniform Resource Identifier (URI)for the job. You can directly use the URI to query the status of the job.

If the HTTP response code is INVALID_RESOURCE (400), you can run thegetConnectionError command to retrieve information, in plain text format, of theexact cause of the problem. You can then use that information to build a newrequest that conforms to the IBM Cloud Managed Services REST API.

Analyzing the response bodyUse the following function to store the response body that is returned by a request:public static String getConnectionContent(InputStream is) {

StringBuilder sb = new StringBuilder();try {DataInputStream input = new DataInputStream(is);

// read in each character until end-of-stream is detectedfor (int c = input.read(); c != -1; c = input.read()) {sb.append((char) c);}

input.close();

Chapter 2. IBM Cloud Managed Services sample client 17

} catch (IOException e) {System.err.println("Error while reading response: " + e.getMessage());}return sb.toString();}

// read the content of the HTTP response if we got a 200 or 202public static String getResponse(HttpsURLConnection connection) throws IOException {

return getConnectionContent(connection.getInputStream());}

// we need this if we get an error response codepublic static String getConnectionError(HttpsURLConnection connection) throws IOException {

try {InputStream is = connection.getErrorStream();return getConnectionContent(is);} finally {// connected}}

The response body returns a string either in XML or JSON format, which you cananalyze further.

Analyzing an XML responseYou can analyze XML content by using w3c DOM API that is included in the JavaDevelopment Kit (JDK). The following three functions separate the code in smallerchunks:

analyzeSingleResourceResponseXMLDoes some initialization and checks the resource that you plan to analyze.

analyzeGroupXMLGets the group-specific data out of the XML DOM tree.

analyzeOptionXMLGets the data that is provided in the options part.

public static HashMap<String, Object> analyzeSingleResourceResponseXML(String response) {HashMap<String, Object> data = new HashMap<String, Object>();

try {// initialize the w3c DOM APIDOMImplementationRegistry registry = DOMImplementationRegistry.newInstance();DOMImplementation domImpl = registry.getDOMImplementation("XML 3.0");DOMImplementationLS domImplLS = null;if (domImpl instanceof DOMImplementationLS) {domImplLS = (DOMImplementationLS) domImpl;}

// if we got an implementation let’s start the parsingif (domImplLS != null) {

// create the parserLSParser xmlParser = domImplLS.createLSParser(DOMImplementationLS.MODE_SYNCHRONOUS, null);

// create a container for the input dataLSInput xmlInput = domImplLS.createLSInput();xmlInput.setStringData(response);

// let the parser do its workDocument xmlDocument = xmlParser.parse(xmlInput);

// analyze the XML DOM treeNodeList rootNodes = xmlDocument.getChildNodes();

18 IBM Cloud Managed Services Release 1.4.1: REST API Programming Guide

if (rootNodes.getLength() == 1) {Node rootNode = rootNodes.item(0);String resourceName = rootNode.getNodeName();

// if the resource we want to analyze is really a groupif (resourceName.equalsIgnoreCase("group")) {data = analyzeGroupXML(rootNode);}} // if root node contains exactly one element} // DOM API implementation available

} catch (IllegalAccessException e) {// from DOMImplementationRegistry.newInstance} catch (ClassNotFoundException e) {// from DOMImplementationRegistry.newInstance} catch (InstantiationException e) {// from DOMImplementationRegistry.newInstance}

return data;}

public static HashMap<String, Object> analyzeGroupXML(Node rootNode) {HashMap<String, Object> data = new HashMap<String, Object>();

// iterate over all child nodesNodeList childNodes = rootNode.getChildNodes();for (int i = 0; i < childNodes.getLength(); i++) {

// get the current nodeNode currentNode = childNodes.item(i);String nodeName = currentNode.getNodeName();

// it is an “id”, a “name” or “description”if (nodeName.equalsIgnoreCase("id") || nodeName.equalsIgnoreCase("name")

|| nodeName.equalsIgnoreCase("description")) {// simply add the data to the resultdata.put(nodeName, currentNode.getTextContent());

// handle the options} else if (nodeName.equalsIgnoreCase("options")) {

// go deeper in the options DOM treeNodeList optionsNodes = currentNode.getChildNodes();for (int j = 0; j < optionsNodes.getLength(); j++) {

// analyze the option nodeStringBuilder optionName = new StringBuilder();StringBuilder optionValue = new StringBuilder();analyzeOptionXML(optionsNodes.item(j), optionName, optionValue);if (optionName.length() > 0) {data.put(optionName.toString(), optionValue.toString());}}}}return data;}

public static void analyzeOptionXML(Node optionNode, StringBuilder optionName,StringBuilder optionValue) {Node nameNode = null;Node valueNode = null;

// analyze the option node and write the result to the// passed StringBuildersNodeList optionNodes = optionNode.getChildNodes();

Chapter 2. IBM Cloud Managed Services sample client 19

for (int k = 0; k < optionNodes.getLength(); k++) {

// extract the name node and the value nodeNode currentOptionNode = optionNodes.item(k);if (currentOptionNode.getNodeName().equalsIgnoreCase("name")) {nameNode = currentOptionNode;} else if (currentOptionNode.getNodeName().equalsIgnoreCase("value")) {valueNode = currentOptionNode;}}

// if we have both nodes availableif (nameNode != null && valueNode != null) {

// team referenceif (nameNode.getTextContent().equalsIgnoreCase("team")) {optionName.append(nameNode.getTextContent());optionValue.append(valueNode.getFirstChild().getAttributes().getNamedItem("uri")

.getTextContent());

// team reference} else if (nameNode.getTextContent().equalsIgnoreCase("team_name")) {optionName.append(nameNode.getTextContent());optionValue.append(valueNode.getTextContent());}}

}

Analyzing a JSON responseTo analyze a JSON response you need a simple JSON parser that has the followinginterfaces:v SimpleParser(String dataStream): Constructor that takes the data to be

analyzed (in the following example it is the response string of the HTTPrequest).

v parse(): Returns a JSON object (as shown in the following example).

The source code for the simple JSON parser is not listed here but is included in thesample client code. A JSON object can be interpreted as an associative map ofproperties that is, a list of properties that are identified by a name and a value. Forexample:{

"name": "John Smith","phone number": "001-991-1234345"

}

The property names are name and phone number with the respective values. Avalue can be of a simple type, for example a string or a number, or of a complextype, for example an array or another JSON object. For details on the JSON syntax,see the website http://www.json.org. The sample client uses a Java HashMap torepresent a JSON object. By using a parser for JSON, you can start to analyze theresponse for a HTTP request, if the request contains a header entry that is acceptedin the response body to be encoded in JSON (Accept: application/json).public HashMap<String, Object> analyzeSingleResourceResponseJSON(String response) {

if (verbose) {System.out.println("Analyzing in format JSON:\n" + response);}

HashMap<String, Object> data = null;

20 IBM Cloud Managed Services Release 1.4.1: REST API Programming Guide

// create a parser for the provided stringparser.init(response);

// parse the string and return the JSON object aka HashMapHashMap<String, Object> parserResult = parser.parse();

String objectType = parserResult.keySet().iterator().next();

if (objectType.equals("\"group\"")) {// get the dataHashMap<String, Object> groupData = (HashMap<String, Object>)

parserResult.get("\"group\"");data = analyzeGroupJSON(groupData);// for single resource result return the raw data} else if (parserResult.size() == 1) {data = (HashMap<String, Object>) parserResult.values().toArray()[0];}

return data;

}

public static HashMap<String, Object> analyzeGroupJSON(HashMap<String, Object> jsonObject){HashMap<String, Object> data = new HashMap<String, Object>();

// get the iddata.put("id", jsonObject.get("\"id\""));

// get the namedata.put("name", jsonObject.get("\"name\""));

// get the descriptiondata.put("description", jsonObject.get("\"description\""));

// get the optionsHashMap<String, Object> options = (HashMap<String, Object>) jsonObject.get("\"options\"");

// get the team uridata.put("team_uri", ((HashMap<String, Object>) options.get("\"team\"")).get("\"uri\""));

// get the team namedata.put("team_name", options.get("\"team_name\""));

return data;}

Regardless of whether the response body is encoded in XML or JSON, you get aflat list of properties and their values that now can be processed further. Forexample, stored in a csv file.

Retrieving the ID of a resource by nameOften only the name of a resource is known but for further processing or to buildUniform Resource Identifier (URI)s, you need the ID of that resource . Forexample, while creating an instance you need the name of the following requiredparameters: VM configuration, image, group, security zone, Service LevelAgreement, and patch schedule category. If only names of the resources areknown, such as 'Small' for a VM configuration or 'Do NOT patch' for a patchschedule category, then you can retrieve their IDs by using thegetResourceIdByName method, and then build the URIs for the create instance RESTAPI:

Chapter 2. IBM Cloud Managed Services sample client 21

public int getResourceIdByName(Properties control, String resource, String attributeName,String name)

throws IOException {int result = -1;

// build the URL from the parts of the control// properties file and the passed resource and attribute nameURL url = new URL(control.getProperty("url") + resource + "?" + attributeName + "=~eq~"

+ name);

// create the connection to the serverHttpsURLConnection connection = createConnection(url, control);

// we want to issue a GET requestconnection.setRequestMethod("GET");

// specify the format of the returned dataconnection.setRequestProperty("Accept", "application/json");// connection.setRequestProperty("Accept", "application/xml");

// we expect data in the response bodyconnection.setDoOutput(true);

// get the query result from the serverint respCode = connection.getResponseCode();

// if the request was successfulif (respCode == HttpURLConnection.HTTP_OK) {

// retrieve the response i.e. the data for// the resourceString response = getResponse(connection);

// create a JSON parser for the provided stringparser.init(response);

// parse the stringHashMap<String, Object> parserResult = parser.parse();

// the parserResult is a single entry in the HashMap with the key <resource>// get the array of all found resourcesArrayList<HashMap<String, Object>> resources = (ArrayList<HashMap<String, Object>>)

parserResult.get("\""+ resource + "\"");

// if exactly one resource was foundif (resources.size() == 1) {

// take the first oneHashMap<String, Object> rawData = resources.get(0);

// extract the idObject oId = rawData.get("\"id\"");

// convert it to intif (oId instanceof String) {String idString = (String) oId;// strip off the surrounding double quotesidString = idString.replaceAll("\"", "");result = Integer.parseInt(idString);}}} else {System.out.println("Response code=" + respCode);}return result;}

22 IBM Cloud Managed Services Release 1.4.1: REST API Programming Guide

This method can easily be adapted to implement any kind of filters as described inthe IBM Cloud Managed Services Rest API Specification Guide.

Waiting for a request to completeIn all POST, PUT, and DELETE API requests, a service request is generated tofulfill the requested function. As the API request immediately returns and onlyprovides the service request ID in the response header, you can add anothermethod that waits until the service request is completed. This normally is indicatedby a state that has the SUCCESSFUL or FAILED values. Therefore, the followingmethod waitForFinish issues queries on the passed job Uniform ResourceIdentifier until it finds that a state that has one of the following described values:public String waitForFinish(Properties control, String jobUri) throws

IOException, InterruptedException {String result = null;

// contruct the URL to query the jobURL url = new URL(control.getProperty("url")+ jobUri);

// while we have not detected that the job has finishedboolean finished = false;while (!finished) {

// create a connection to query the jobHttpsURLConnection connection = createConnection(url, control);connection.setRequestMethod("GET");// specify the format of the returned dataconnection.setRequestProperty("Accept", "application/json");connection.setDoOutput(true);

// get the job informationString response = getResponse(connection);

// initialize the parserparser.init(response);

// parse the responseHashMap<String, Object> parserResult = parser.parse();

// get the raw dataHashMap<String, Object> rawData =

(HashMap<String, Object>)parserResult.get("\"job\"");

// extract the state information of the jobObject state = rawData.get("\"state\"");

if (state != null && state instanceof String) {String stateString = (String)state;

// if the state is successful or failed the job has finishedif (stateString.equals("\"SUCCESSFUL\"") ||

stateString.equals("\"FAILED\"")) {finished = true;result = stateString;

}}connection.disconnect();

// if we have not yet detected that the job has finished// we will wait 5 secondsif (!finished) {

Thread.sleep(5000);}

Chapter 2. IBM Cloud Managed Services sample client 23

}return result;

}

This method is used to optionally wait for a request to complete. If the -wparameter is specified when calling the main program the issuePostRequestmethod waits until the request has completed its processing in IBM CloudManaged Services:// if the request was successfulif (connection.getResponseCode() == HttpURLConnection.HTTP_ACCEPTED) {

// retrieve the job URI aka the information for the service// requestString jobUri = connection.getHeaderField("Job_URI");

if (jobUri != null) {System.out.println("Create in progress with job: "

+ jobUri);if (wait) {

String finalState = waitForFinish(control, jobUri.substring(1));}

}

Matching user interface tasks to REST API callsThis chapter lists tasks that a user can perform by using the REST API. The resultof various retrieve operations depend on the role of the requesting user. For moredetails about the tasks, see IBM Cloud Managed Services Rest API SpecificationGuide.

Task HTTPrequest type

URL (resource) IBM CloudManaged Services(CMS) ServiceOffering

Project management

Create a new project POST /groups Create project

Update a project PUT /groups/{id} Modify project

Delete a project DELETE /groups/{id} Remove project

Retrieve informationfor all projects

GET /groups View project list

Retrieve informationfor a single project

GET /groups/{id} View details of asingle specifiedproject

Server management

Create a server POST /instances Create server

Modify the serverconfiguration

PUT /instances/{id} Modify serverconfiguration

Start a server which iseither in FAILED orSTOPPED state

PUT /instances/{id}/start Start Server

Patch management

24 IBM Cloud Managed Services Release 1.4.1: REST API Programming Guide

|||

Retrieve informationfor all patches

GET /patches

Update a patch for aninstance

PUT /patches/{id}

Approve a patchupdate for an instance

PUT /patches/{id}/approve Approve Patch

User management

Create a new user POST /users Create user

Update properties of auser

PUT /users/{id} Modify user

Reset password for auser

PUT /users/{id}/reset_password Reset userpassword

Retrieve informationfor current users

GET /users/self -

Retrieve informationfor all roles

GET /roles -

Team management

Create a new team POST /teams Create a new team

Change description orline of business of ateam

PUT /teams/{id} Modify team

Approve or reject aservice request

PUT /approvals/{id} Approve or rejectservice request

Manage Monitors

Create new monitor POST /monitors Subscribe toMonitoring

Manage Incidents

Create an incident POST /incidents -

Update an incident PUT /incidents/{id} -

Create a new worklogentry for an incident

POST /incidents/{id}/worklog -

Manage Flash CopyPolicy

Create a new flashcopy policy

POST /flash_copy_policies Activate FlashcopyPolicy

Execute a flash copypolicy

PUT /flash_copy_policies/{fcp123}/execute

Execute FlashcopyPolicy

Miscellaneous

Retrieve informationfor all images

GET /images -

Chapter 2. IBM Cloud Managed Services sample client 25

||||

|||||

|||||

|||||

||||

||||

|||||

||||||

|||||||

Retrieve informationfor all service requests

GET /jobs (My Requests boxin the Self ServiceCenter)

Retrieve informationfor a single servicerequest

GET /jobs/{id} (My Requests boxin the Self ServiceCenter)

Retrieve informationfor all Service LevelAgreements (SLA)s

GET /slas -

Retrieve informationfor all security zones

GET /security_zones -

Retrieve informationfor all patch schedulecategories

GET /patch_schedule_categories

-

Retrieve informationfor all Line of Business

GET /lobs -

Retrieve informationfor all IPs

GET /addresses

Retrieve informationfor all domainswithoutroot_organization

GET domains?_include_root_organization_units=false

Instructions to build a Cloud Managed Services sample clientThis section describes general tasks and helper functions.

Compiling the sample Java filesThe Java code files are contained in com.ibm.sppc.iaas.api.samples package in thesrc folder. The provided Java files can be compiled by using the javac compilerthat is contained within the Java SDK 1.6:javac -classpath . com/ibm/sppc/iaas/api/samples/*.java

Configuring Secure Socket Layer connectionConnections to the IBM Cloud Managed Services (CMS) REST API server are onlyavailable by using HTTP. To communicate with the server you first need the SecureSocket Layer (SSL) certificate from the server. Whenever you try to connect to asecure web server with a web browser, you are prompted to trust the server andaccept the certificate. You must store the certificate in the web browsers certificatedatabase.

One way to retrieve the SSL certificate is to use a browser with the URL that youwant to connect to and export the certificate to a local file.

Use the following Java program to retrieve the SSL certificate:public class RetrieveSSLCert {

public static void main(String[] args) throws Exception {if (args.length != 3) {System.out.println("Usage: java RetrieveSSLCert <host> <port> <output filename>");return;}

// get the information from the command line

26 IBM Cloud Managed Services Release 1.4.1: REST API Programming Guide

|||||

||||

||||

String host = args[0];int port = Integer.parseInt(args[1]);String outputFileName = args[2];

// initializations for the SSL connectionSSLContext sc = SSLContext.getInstance("SSL");sc.init(null, new TrustManager[] { trm} , null);SSLSocketFactory factory = sc.getSocketFactory();SSLSocket socket = (SSLSocket) factory.createSocket(host, port);socket.startHandshake();

// connect to the serverSSLSession session = socket.getSession();

// retrieve the certificatejava.security.cert.Certificate[] servercerts =session.getPeerCertificates();

// write the certificate to a fileFileOutputStream fos =new FileOutputStream(outputFileName);fos.write("-----BEGIN CERTIFICATE-----\n".getBytes());fos.write(new sun.misc.BASE64Encoder().encode(servercerts[0].getEncoded()).getBytes());fos.write(’\n’);fos.write("-----END CERTIFICATE-----\n".getBytes());fos.close();socket.close();}}

After exporting the certificate, you must read the necessary data from thecommand line, store the data into variables, and then create a dummy trustmanager class that accepts all incoming certificates.

The SSL connection can also be enhanced to a stronger checking by doing someinitialization for the SSL connections that you want to establish with the server andconnect to the server. You must retrieve the certificates from the server and writethe content of the first received certificate to a file whose file name was passed asparameter.

For example,

java -classpath . com.ibm.sppc.iaas.api.samples.RetrieveSSLCertmyserver.com 9443 restapicert

Adding a certificate to KeystoreAfter storing the certificate on the file system, you need to add it to Keystore sothat you can use it when you connect to the server later after issuing REST APIrequests. To add the certificate to Keystore you must use the Keytool program thatis part of every Java Runtime Environment (JRE). Before issuing the followingcommand ensure that the PATH variable contains an entry for the JRE bindirectory.keytool -import -alias <name of your choice> -keystore <file name for the key store>-file <path to the file stored in the previous step>

This command adds the certificate that is stored in the previous step into aKeystore with an alias name that you provide. For example:keytool -import -alias EhningenTestEnv -keystore /home/user/mykeystore -file restapicert

Chapter 2. IBM Cloud Managed Services sample client 27

If Keystore does not exists, then it is created and it contains the passed certificateas the only certificate. While storing the certificate, you have to enter yourpassword. Remember this password well, as only this password will allow you toaccess Keystore further on.

Establishing an SSL connectionFirst of all we have to initialize some SSL settings so that the sample clientapplication can connect to IBM Cloud Managed Services REST API server ininitNetEnvironment method:

Following sample shows the SSL settings:public void initNetEnvironment(Properties control)

throws NoSuchAlgorithmException, KeyManagementException {// use the keystore for certificatesSystem.setProperty("javax.net.ssl.trustStore",

control .getProperty("keyStore"));

// get the SSL contextSSLContext sc = SSLContext.getInstance("SSL");

// initialize the contextsc.init(null, null, new java.security.SecureRandom());

// set the socket factory for the communicationHttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());

// set the host name verifier to a dummy implementationHttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {

public boolean verify(String hostname, SSLSession session) {// do not really check the host namereturn true;

}

});}

Reading command line optionsComplete the following steps to read the command line options:1. To read the options passed to the main program, use the following readOptions

function:public HashMap<String, Object> readOptions(String... args) {

// create a new store for the optionsHashMap<String, Object> options = new HashMap<String, Object>();

// default: do not waitoptions.put("wait", false);

// read the options and store themfor (int i = 0; i < args.length; i++) {

if (args[i].equals("-p")) {options.put("properties", args[i + 1]);i++;

}if (args[i].equals("-d")) {

options.put("data", args[i + 1]);i++;

}if (args[i].equals("-h")) {

options.put("help", null);}

28 IBM Cloud Managed Services Release 1.4.1: REST API Programming Guide

if (args[i].equals("-v")) {verbose = true;

}

if (args[i].equals("-i")) {// put all the ids into a listoptions.put("ids", getIdsFromOption(args[i + 1]));i++;

}

if (args[i].equals("-m")) {options.put("method", args[i + 1]);i++;

}

if (args[i].equals("-r")) {options.put("resource", args[i + 1]);i++;

}

if (args[i].equals("-n")) {options.put("name", args[i + 1]);i++;

}

if (args[i].equals("-w")) {options.put("wait", true);

}

}return options;

}

This function reads the options and stores them in a hash map. The hash mapcan be called at the beginning of the main function, as shown in the followingcode sample:HashMap<String, Object> options = readOptions(args);

2. Check if all necessary parameters are provided, and store the value of theoptions in local variables in checkOptions methods, as follows:boolean checkOptions(HashMap<String, Object> options,

StringBuilder propertiesSB, StringBuilder dataSB) {boolean result = true;

// if the caller only wants help on the usage of the programif (options.containsKey("help")) {

printUsage();result = false;

} else {// get the data from the options into local variablesif (options.containsKey("properties")) {

propertiesSB.append(options.get("properties"));if (verbose) {

System.out.println("Properties file: " + propertiesSB);}

}if (options.containsKey("data")) {

dataSB.append(options.get("data"));if (verbose) {

System.out.println("Data file: " + dataSB);}

}}

// for simple retrieval calls with provided nameif (options.containsKey("name") &&

Chapter 2. IBM Cloud Managed Services sample client 29

propertiesSB.length() > 0 &&options.containsKey("resource")) {result = true;

} else// check if all necessary data has been providedif (propertiesSB.length() == 0 ||

!options.containsKey("resource") ||(dataSB.length() == 0 &&(((String)options.get("method")).equals("put") ||((String)options.get("method")).equals("post")))) {

System.err.println("Missing parameters");printUsage();result = false;

}

return result;}

The returned result of this method indicates whether to continue or stopprocessing because there were problems found:StringBuilder propertiesSB = new StringBuilder();StringBuilder dataSB = new StringBuilder();

boolean continueWithProcessing = client.checkOptions(options,propertiesSB, dataSB);

if (!continueWithProcessing) {System.exit(1);

}

String propertiesFileName = propertiesSB.toString();String dataFileName = dataSB.toString();

After all required options are provided, you must try to load and check theproperties to access the server:Properties control = client.readProperties(propertiesFileName);// if reading the properties file failed stop the processingif (control == null) {

System.exit(1);}

// check the propertiesboolean validInput = client.validateProperties(control);

// if something is missing stop the processingif (!validInput) {

System.exit(1);}

The readProperties and validateProperties functions validate the content ofthe properties file and display alerts about missing keywords and parameters:public Properties readProperties (String propertiesFileName) {

Properties result = null;

try {result = new Properties();result.load(new FileInputStream(propertiesFileName));

} catch (IOException e) {System.err.println("Error in reading properties from " +

propertiesFileName);result = null;

}return result;

}

static boolean validateProperties(Properties properties) {boolean isValid = true;

30 IBM Cloud Managed Services Release 1.4.1: REST API Programming Guide

if (!properties.containsKey("keyStore")) {System.err.println("Properties do not contain entry for: "+

"keyStore");isValid = false;

}// also check the other propertiesreturn isValid;

}

Reading external filesUse the following command to read an external file and reformat the file forfurther use:

List<HashMap<String, Object>> data = client.readData(dataFileName);

You can interpret the first line of the csv file as the header line that contains thenames of the data properties. Each row in the csv file can be considered as a list ofname-value pairs. The complete file can then be considered as a list of lists ofname-value pairs. You can store the data in a HashMap where name is the key andvalue is the corresponding object. Now you can transfer the data from an externalfile into a nested list of name-value pairs:

The following sample code shows reading of an external file data:public List<HashMap<String, Object>> readData(String dataFileName) {

List<HashMap<String, Object>> result =new ArrayList<HashMap<String, Object>>();

try {// open the fileBufferedReader bis =

new BufferedReader(new FileReader(dataFileName));

// read the header lineString headerLine = bis.readLine();String[] headers = headerLine.split(",");

// read the next line until end of datawhile (bis.ready()) {

String nextLine = bis.readLine();String[] content = nextLine.split(",");HashMap<String, Object> newEntry =

new HashMap<String, Object>();

// store the data// (enclosing double quotes of the headers are removed// and string is normalized to lower case)for (int i = 0; i < headers.length; i++) {

String lowerHeader = headers[i].substring(1,headers[i].length() - 1).toLowerCase();

newEntry.put(lowerHeader, content[i]);}result.add(newEntry);

}

} catch (IOException e) {System.err.println("Error while reading data "+"file at " + dataFileName);

}return result;

}

Chapter 2. IBM Cloud Managed Services sample client 31

32 IBM Cloud Managed Services Release 1.4.1: REST API Programming Guide

Chapter 3. Resourcesv IBM Infrastructure as a Service (IaaS) REST API Specification v3:

http://publib.boulder.ibm.com/infocenter/tivihelp/v48r1/topic/com.ibm.hslt.doc_1.0.0/IBM_Iaas_APIs_spec_v3.pdf

v IBM Cloud Managed Services Rest API Specification Guide.v IBM Cloud Managed Services User's Guide

© Copyright IBM Corp. 2012, 2014 33

34 IBM Cloud Managed Services Release 1.4.1: REST API Programming Guide

Notices

IBM may not offer the products, services, or features discussed in this document inall countries. Consult your local IBM representative for information on theproducts and services currently available in your area. Any reference to an IBMproduct, program, or service is not intended to state or imply that only that IBMproduct, program, or service may be used. Any functionally equivalent product,program, or service that does not infringe any IBM intellectual property right maybe used instead. However, it is the user's responsibility to evaluate and verify theoperation of any non-IBM product, program, or service.

IBM may have patents or pending patent applications covering subject matterdescribed in this document. The furnishing of this document does not grant youany license to these patents. You can send license inquiries, in writing, to:

IBM Director of LicensingIBM CorporationNorth Castle DriveArmonk, NY10504-17855U.S.A.

For license inquiries regarding double-byte (DBCS) information, contact the IBMIntellectual Property Department in your country or send inquiries, in writing, to:

Intellectual Property LicensingLegal and Intellectual Property LawIBM Japan, Ltd.1623-14, Shimotsuruma, Yamato-shi, Kanagawa-ken 242-8502Japan

The following paragraph does not apply to the United Kingdom or any othercountry where such provisions are inconsistent with local law: INTERNATIONALBUSINESS MACHINES CORPORATION PROVIDES THIS PUBLICATION "AS IS"WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED,INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OFNON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULARPURPOSE. Some states do not allow disclaimer of express or implied warranties incertain transactions, therefore, this statement may not apply to you.

This information could include technical inaccuracies or typographical errors.Changes are periodically made to the information herein; these changes will beincorporated in new editions of the publication. IBM may make improvementsand/or changes in the product(s) and/or the program(s) described in thispublication at any time without notice.

Any references in this information to non-IBM Web sites are provided forconvenience only and do not in any manner serve as an endorsement of those Websites. The materials at those Web sites are not part of the materials for this IBMproduct and use of those Web sites is at your own risk.

IBM may use or distribute any of the information you supply in any way itbelieves appropriate without incurring any obligation to you.

© Copyright IBM Corp. 2012, 2014 35

Information concerning non-IBM products was obtained from the suppliers ofthose products, their published announcements or other publicly available sources.IBM has not tested those products and cannot confirm the accuracy ofperformance, compatibility or any other claims related to non-IBM products.Questions on the capabilities of non-IBM products should be addressed to thesuppliers of those products.

All statements regarding IBM's future direction or intent are subject to change orwithdrawal without notice, and represent goals and objectives only.

All IBM prices shown are IBM's suggested retail prices, are current and are subjectto change without notice. Dealer prices may vary.

This information is for planning purposes only. The information herein is subject tochange before the products described become available.

This information contains examples of data and reports used in daily businessoperations. To illustrate them as completely as possible, the examples include thenames of individuals, companies, brands, and products. All of these names arefictitious and any similarity to the names and addresses used by an actual businessenterprise is entirely coincidental.

If you are viewing this information softcopy, the photographs and colorillustrations may not appear.

TrademarksIBM, the IBM logo, and ibm.com are trademarks or registered trademarks ofInternational Business Machines Corp., registered in many jurisdictions worldwide.Other product and service names might be trademarks of IBM or other companies.A current list of IBM trademarks is available on the Web at “Copyright andtrademark information” at www.ibm.com/legal/copytrade.shtml.

Intel is a trademark of Intel Corporation in the United States and other countries.

Linux is a trademark of Linus Torvalds in the United States, other countries, orboth.

Microsoft, Windows, and the Windows logo are trademarks of MicrosoftCorporation in the United States, other countries, or both.

Java™ and all Java-based trademarks and logos are trademarks or registeredtrademarks of Oracle and/or its affiliates.

36 IBM Cloud Managed Services Release 1.4.1: REST API Programming Guide

����

Printed in USA