Custom Change Management System
FlexDeploy has out of box integration with ServiceNow, but you can easily integrate with other change management systems. Such third party Change Management System integration can be enabled using Java or Groovy implementation.
Go to Change Management Systems page using Administration - Integrations - Change Management Systems menu.
Let's look at more details on how to create a custom change management system integration with Flex Deploy. Click Create to implement integration with custom change management system.
- Provide a unique name and description
- Define properties for the new change management system. Properties are configuration values used by FlexDeploy to connect to the new system.
- If you define properties, you can indicate display and validation details. You can also indicate if property is required and/or encrypted.
- Enter a unique Name before adding any properties
- Provide either Java Implementation or Groovy API.
- Click Save.
Let's define an example change management system in FlexDeploy. You can provide implementation as Java class or just Groovy script. Groovy script would allow for dynamic update whereas use of Java code will require restart of server.
Here we are creating custom change management system with the properties, you can add more as necessary.
API Implementation
Implementation must implement the following API operations to integrate with FlexDeploy.
Method Name | Parameter(s) | Return Type | Description |
---|---|---|---|
createRequest | String pDescription, String pComment | void | Creates a Change Request ticket using the pDescription and pComment |
createIncident | String pDescription, String pComment | String | Creates an Incident ticket using the pDescription and pComment |
findRequestByType | String pRequestNumber, RequestType pRequestType | void | Find a Change Request using the request number and type. Custome CMS services should cast other types like QUESTION, PROBLEM to pRequestType when returning the matching Request object Note : FlexDeploy supports the following RequestType enum REQUEST - Use if the ticket is a change request INCIDENT - Use if the ticket is an incident due to any failure in an env OTHER - If the ticket doesn't fall in the above two categories |
isRequestApproved | String pRequestNumber, String pEnvironmentCode | void | Checks if the given change request number (pRequestNumber) is approved in the environment (pEnvironmentCode) |
isRequestRejected | String pRequestNumber, String pEnvironmentCode | String | Checks if the given change request number (pRequestNumber) is rejected in the environment (pEnvironmentCode) |
checkConnection | void | This should invoke any status or heath check URL of the change management system to ensure the system is up and running | |
isDoPolling | void | Return flag true or false. Disable automatic polling (every minute) of change management tickets for status changes. |
Java Implementation
Here are high level steps for Java implementation. You can use any IDE to prepare this implementation.Â
- Create java class that extends flexagon.fd.model.integration.cms.api.ChangeManagementSystem. Example shown below has the methods implemented which uses properties map to retrieve the configuration values to connect to the change management system.
- All properties defined are available in Map returned by getProperties method.
- We are using Zendesk as a usecase
package mycompany.extension.flexdeploy.zendesk; import com.sun.jersey.api.client.Client; import com.sun.jersey.api.client.ClientResponse; import com.sun.jersey.api.client.WebResource; import com.sun.jersey.api.client.filter.LoggingFilter; import flexagon.fd.model.integration.cms.api.ChangeManagementSystem; import flexagon.fd.model.integration.cms.api.Request; import flexagon.fd.model.integration.util.ApiException; import java.io.Serializable; import java.io.StringReader; import java.util.HashMap; import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; import javax.json.Json; import javax.json.JsonObject; import javax.json.JsonObjectBuilder; import javax.json.JsonReader; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; public class ZendeskServiceIntegration extends ChangeManagementSystem { private static final String CLZ_NAM = ZendeskServiceIntegration.class.getName(); private Client mRestClient; private String mAccessToken; private Logger mLogger; public ZendeskServiceIntegration() { super(); this.mLogger = Logger.getLogger(CLZ_NAM); } private void getOAuthAccessToken(String pScope) throws ApiException { JsonObjectBuilder zenOAuthRequestJson = Json.createObjectBuilder(); zenOAuthRequestJson.add("grant_type", "password"); zenOAuthRequestJson.add("client_id", getClientId()); zenOAuthRequestJson.add("client_secret", getClientSecret()); zenOAuthRequestJson.add("username", getUserName()); zenOAuthRequestJson.add("password", getPassword()); zenOAuthRequestJson.add("scope", pScope); String payLoad = zenOAuthRequestJson.build().toString(); ClientResponse clientResponse = getRestClient().resource(getZendeskDomain()).path(getOAuthURI()).accept(MediaType.APPLICATION_JSON_TYPE).type(MediaType.APPLICATION_JSON_TYPE).post(ClientResponse.class, payLoad); checkResponse(clientResponse); JsonObject jsonResponseObject = readJsonObject(clientResponse.getEntity(String.class)); print("OAuth Response " + jsonResponseObject); mAccessToken = jsonResponseObject.getString("access_token"); } private String getAccessToken(String pScope) throws ApiException { getOAuthAccessToken(pScope); return "Bearer " + mAccessToken; } private String getOAuthURI() { return getPropertyAsString("ZD_OAUTH_URI"); } private String getClientId() { return getPropertyAsString("ZD_CLIENT_ID"); } private String getClientSecret() { return getPropertyAsString("ZD_CLIENT_SECRET"); } @Override public Request createRequest(String pDescription, String pComment) throws ApiException { String methodName = "createRequest"; print(methodName + String.format(" Creating new Request using the description [%s] and comment[%s]", pDescription, pComment)); return postTicket("request", "ZD_REQUEST_CREATE_PATTERN", "question", pDescription, pComment, "requests:write read"); } private Request postTicket(String pObjectType, String pURLKey, String pTicketType, String pDescription, String pComment, String pScope) throws ApiException { String methodName = "postTicket"; print(methodName + String.format(" Creating new Request using the description [%s] and comment[%s]", pDescription, pComment)); JsonObjectBuilder zenInputJson = Json.createObjectBuilder(); JsonObjectBuilder inputParamJsonBuider = Json.createObjectBuilder(); inputParamJsonBuider.add("subject", pDescription); JsonObjectBuilder descriptionJsonBuider = Json.createObjectBuilder(); descriptionJsonBuider.add("body", pComment); inputParamJsonBuider.add("comment", descriptionJsonBuider.build()); inputParamJsonBuider.add("type", pTicketType); zenInputJson.add(pObjectType, inputParamJsonBuider.build()); WebResource postRequest = getWebResource(getPropertyAsString(pURLKey)); String payLoad = zenInputJson.build().toString(); print(methodName + String.format(" Creating new %s %s", pObjectType, payLoad)); ClientResponse clientResponse = postRequest.accept(MediaType.APPLICATION_JSON_TYPE).type(MediaType.APPLICATION_JSON_TYPE).header("Authorization", getAccessToken(pScope)).post(ClientResponse.class, payLoad); checkResponse(clientResponse); JsonObject jsonResponseObject = readJsonObject(clientResponse.getEntity(String.class)); JsonObject requestResponseJson = jsonResponseObject.getJsonObject(pObjectType); RequestImpl request = new RequestImpl(String.valueOf(requestResponseJson.getInt("id")), requestResponseJson.getString("description"), requestResponseJson.getString("status"), requestResponseJson.getString("type"), true, requestResponseJson); print(methodName + String.format(" Successfully created ticket %s", request.getNumber())); return request; } private JsonObject readJsonObject(String source) { String methodName = "readJsonObject"; JsonReader jsonReader = Json.createReader(new StringReader(source)); JsonObject object = null; try { object = jsonReader.readObject(); print(methodName + String.format(" Json object created for response = %s", source)); } catch (Exception e) { mLogger.logp(Level.INFO, mLogger.getName(), methodName, String.format(" Exception while creating response json object, error %s, response = %s", e.getMessage(), source), e); } finally { if (jsonReader != null) { jsonReader.close(); } } return object; } @Override public Request createIncident(String pDescription, String pComment) { String methodName = "createIncident"; Request request = null; try { request = postTicket("ticket", "ZD_TICKET_CREATE_PATTERN", "incident", pDescription, pComment, "tickets:write read"); } catch (ApiException e) { mLogger.logp(Level.INFO, mLogger.getName(), methodName, String.format(" Exception while creating incident, error %s", e.getMessage()), e); } return request; } @Override public Request findRequestByType(String pRequestNumber, ChangeManagementSystem.RequestType pRequestType) throws ApiException { Request changeRequest = getChangeRequest(pRequestNumber); if (changeRequest != null && changeRequest.getTypeName().equalsIgnoreCase("QUESTION") && pRequestType.equals(ChangeManagementSystem.RequestType.REQUEST)) { print(pRequestNumber + " is of type QUESTION, setting it as REQUEST for FD"); ((RequestImpl) changeRequest).setType(ChangeManagementSystem.RequestType.REQUEST.name()); } return getChangeRequest(pRequestNumber); } private Request getChangeRequest(String pRequestNumber) throws ApiException { return getTicket("request", "ZD_REQUEST_GET_PATTERN", pRequestNumber, "{ZENDESK_REQUEST}"); } private Request getTicket(String pObjectType, String pURLKey, String pRequestNumber, String pSearchPattern) throws ApiException { String methodName = "getTicket"; print(methodName + String.format(" Find Ticket [%s] ", pRequestNumber)); //Zendesk Get Request URL Pattern (/api/v2/requests/{ZENDESK_REQUEST}.json) String urlString = getPropertyAsString(pURLKey); urlString = urlString.replace(pSearchPattern, pRequestNumber); ClientResponse clientResponse = getWebResource(urlString).header("Authorization", getAccessToken("tickets:write read")).get(ClientResponse.class); checkResponse(clientResponse); JsonObject jsonResponseObject = readJsonObject(clientResponse.getEntity(String.class)); JsonObject ticketResponseJson = jsonResponseObject.getJsonObject(pObjectType); RequestImpl request = new RequestImpl(String.valueOf(ticketResponseJson.getInt("id")), ticketResponseJson.getString("description"), ticketResponseJson.getString("status"), ticketResponseJson.getString("type"), true, ticketResponseJson); print(methodName + String.format(" Successfully found ticket %s", request.getNumber())); return request; } @Override public Boolean isRequestApproved(String requestNumber, String environmentCode) { Request findRequest = null; Boolean approved = false; try { findRequest = getChangeRequest(requestNumber); if (findRequest != null) { String status = findRequest.getStatus(); print(String.format("#[%s] status [%s]", requestNumber, status)); if ("solved".equalsIgnoreCase(status)) { approved = true; } } } catch (Exception e) { mLogger.logp(Level.INFO, mLogger.getName(), "isRequestApproved", "Unable to check the status, failed - " + e.getMessage(), e); } return approved; } @Override public Boolean isRequestRejected(String requestNumber, String environmentCode) { Request findRequest = null; Boolean rejected = false; try { findRequest = getChangeRequest(requestNumber); if (findRequest != null) { String status = findRequest.getStatus(); print(String.format("#[%s] status [%s]", requestNumber, status)); if ((!"New".equalsIgnoreCase(status)) && ("on-hold".equalsIgnoreCase(status) || "Closed".equalsIgnoreCase(status))) { rejected = true; } } } catch (Exception e) { mLogger.logp(Level.INFO, mLogger.getName(), "isRequestRejected", "Unable to check the status, failed - " + e.getMessage(), e); } return rejected; } @Override public Boolean isDoPolling() { return false; } @Override public void checkConnection() throws ApiException { String methodName = "checkConnection"; print(methodName + " getting user details to check connection"); ClientResponse clientResponse = getWebResource("/api/v2/users/me.json").header("Authorization", getAccessToken("organizations:write read")).get(ClientResponse.class); checkResponse(clientResponse); print(methodName + " Test connection response code looks valid, check content of response"); String responseString = clientResponse.getEntity(String.class); print(methodName + "responseString=" + responseString + ", Validated that JSON data was received from test connction URL invocation."); } private StringBuilder getZendeskURLBuilder() { StringBuilder urlBuilder = new StringBuilder(getPropertyAsString("ZD_DOMAIN_NAME")); return urlBuilder; } private void checkResponse(ClientResponse clientResponse) throws ApiException { String methodName = "checkResponse"; print(methodName + String.format(" Invoked connection URL %s", clientResponse)); int statusCode = clientResponse.getStatusInfo().getStatusCode(); if (statusCode == 401) { throw new ApiException("Invalid credentials.", ""); } if (!(clientResponse.getStatusInfo().getFamily() == Response.Status.Family.SUCCESSFUL)) { throw new ApiException(clientResponse.getEntity(String.class), clientResponse.getStatusInfo().getReasonPhrase()); } } private String getZendeskDomain() { return getZendeskURLBuilder().toString(); } private String getUserName() { String userName = getPropertyAsString("ZD_USER_NAME"); print("userName=" + userName); return userName; } private void print(String pMessage) { mLogger.logp(Level.INFO, mLogger.getName(), "print", pMessage); } private String getPassword() { return getPropertyAsString("ZD_PASSWORD"); } private String getPropertyAsString(String pKey) { return (String) getProperties().get(pKey); } private Client getRestClient() throws ApiException { if (mRestClient == null) { mRestClient = Client.create(); mRestClient.addFilter(new LoggingFilter(System.out)); mRestClient.setReadTimeout(20000); mRestClient.setConnectTimeout(10000); } return mRestClient; } public WebResource getWebResource(String resource) throws ApiException { if (resource != null && !resource.isEmpty() && !resource.startsWith("/")) { resource += "/" + resource; } WebResource webResource = null; try { webResource = getRestClient().resource(getZendeskDomain()).path(resource); } catch (Exception e) { throw new ApiException(e.getMessage(), e.getMessage()); } return webResource; } }
- In order to compile your java class, you will need FlexDeployAPI.jar on classpath.
- Implement all the methods described in the table in the API Implementation section.
- For any failure connecting to the system or if any issues with the data, then you can throw exception. For example throw new ApiException("Invalid credentials.", "");
- Once you are ready with unit testing, you can prepare Jar file for your credential store java class and other utility classes. This jar file can be placed on server classpath now.
- For Tomcat, put this jar file in apache-tomcat-flexdeploy/lib folder.
- For WebLogic, put this jar file in Domain lib folder.
- If you are using any third party libraries from your Java implementation, then those jar files will also need to be added to same lib folder. Keep in mind that this can cause issues with server functioning, so be prepared to remove your additional library files.
Groovy Implementation
Here are high level steps for Groovy implementation. You can use any IDE to prepare this implementation.Â
As groovy is able to access FlexDeploy variables and Java classes, you can take advantage of Java libraries from Groovy script. For example, if there is Java library used to access the change management system, you can places those in lib folder and use those classes from Groovy script. This allows you to keep dynamic part of implementation in Groovy and use Java library.
- Create a groovy class. Example shown below has the methods implemented.
- We are using BMC Helix Remedy Force as a usecase
- All properties defined are available as groovy binding variables. For example, properties can be accessed directly like BMC_DOMAIN_NAME, BMC_SALESFORCE_HOST_NAME or BMC_USER_NAME etc
import flexagon.fd.model.integration.cms.api.ChangeManagementSystem; import flexagon.fd.model.integration.cms.api.Request; import flexagon.fd.model.integration.util.ApiException; import com.sun.jersey.api.client.Client; import com.sun.jersey.api.client.ClientResponse; import com.sun.jersey.api.client.WebResource; import com.sun.jersey.api.client.filter.LoggingFilter import com.sun.jersey.api.representation.Form; import javax.ws.rs.core.Response; import javax.ws.rs.core.MediaType; import groovy.json.JsonOutput; import flexagon.fd.model.integration.cms.impl.RequestImpl class BMCRemedyChangeManagementSystem { def className = BMCRemedyChangeManagementSystem.class.getName(); def jsonSlurper = new groovy.json.JsonSlurper() def accessToken = "" def createClient() { Client restClient = Client.create(); restClient.addFilter(new LoggingFilter(System.out)); restClient.setReadTimeout(20000); restClient.setConnectTimeout(10000); return restClient; } private void checkResponse(ClientResponse clientResponse) throws ApiException { String methodName = "checkResponse"; log.logInfo(methodName, String.format(" Invoked connection URL %s", clientResponse)); int statusCode = clientResponse.getStatusInfo().getStatusCode(); if (statusCode == 401) { throw new ApiException("Invalid credentials.", ""); } if (!(clientResponse.getStatusInfo().getFamily() == Response.Status.Family.SUCCESSFUL)) { throw new ApiException(clientResponse.getEntity(String.class), clientResponse.getStatusInfo().getReasonPhrase()); } } def createRequest(String pDescription, String pComment) { String methodName = "createRequest()"; log.logFinestEntering(methodName, pDescription, pComment); Request request = null; try { getAccessToken() Client mRestClient = createClient() String changeRequestURI = BMC_REMEDY_OBJECT_NAME_URI.replaceAll("\\{OBJECT_NAME\\}", "BMCServiceDesk__Change_Request__c") def jsonLiteral = ["BMCServiceDesk__Change_Description__c": "${pDescription}", "BMCServiceDesk__Reason_for_Change_Details__c" : "${pComment}"] ClientResponse clientResponse = mRestClient.resource(BMC_DOMAIN_NAME).path(changeRequestURI).accept(MediaType.APPLICATION_JSON_TYPE) .type(MediaType.APPLICATION_JSON_TYPE).header("Authorization", "Bearer " + accessToken) .post(ClientResponse.class, JsonOutput.toJson(jsonLiteral)); checkResponse(clientResponse) String responseString = clientResponse.getEntity(String.class); log.logInfo(methodName, "response from CR creation =" + responseString); def jsonSlurper = new groovy.json.JsonSlurper() def response = jsonSlurper.parseText(responseString) log.logInfo(methodName, "created change request unique id=" + response.id); clientResponse = mRestClient.resource(BMC_DOMAIN_NAME).path(changeRequestURI + "/" + response.id) .type(MediaType.APPLICATION_JSON_TYPE).header("Authorization", "Bearer " + accessToken) .get(ClientResponse.class); responseString = clientResponse.getEntity(String.class); response = jsonSlurper.parseText(responseString) log.logInfo(methodName, "change request=" + response); request = createRequestForChange(response); } catch (Exception e) { log.logInfo(methodName, " Change Request creation failed " + e.getMessage() + " " + e) throw new ApiException("Change Request creation failed. " + e.getMessage()); } log.logFinestExiting(methodName, request); return request; } def createRequestForChange(response) { Request request = new RequestImpl(response.Name, response.BMCServiceDesk__Change_Description__c, response.BMCServiceDesk__Status__c, ChangeManagementSystem.RequestType.REQUEST, null, "" + response.BMCServiceDesk__Approved__c, (!"Rejected".equalsIgnoreCase(response.BMCServiceDesk__ClosureCategory__c) && !response.BMCServiceDesk__Inactive__c), null); return request } def createIncident(String pDescription, String pComment) { String methodName = "createIncident()"; log.logFinestEntering(methodName, pDescription, pComment); Request request = null; try { getAccessToken() Client mRestClient = createClient() String incidentURI = BMC_REMEDY_OBJECT_NAME_URI.replaceAll("\\{OBJECT_NAME\\}", "BMCServiceDesk__Incident__c") def jsonLiteral = ["BMCServiceDesk__shortDescription__c": "${pDescription}", "BMCServiceDesk__FKCategory__c": "a216g0000005NvDAAU", "BMCServiceDesk__incidentDescription__c": "${pComment}"] ClientResponse clientResponse = mRestClient.resource(BMC_DOMAIN_NAME).path(incidentURI).accept(MediaType.APPLICATION_JSON_TYPE) .type(MediaType.APPLICATION_JSON_TYPE).header("Authorization", "Bearer " + accessToken) .post(ClientResponse.class, JsonOutput.toJson(jsonLiteral)); checkResponse(clientResponse) String responseString = clientResponse.getEntity(String.class); log.logInfo(methodName, "response from incident creation =" + responseString); def jsonSlurper = new groovy.json.JsonSlurper() def response = jsonSlurper.parseText(responseString) log.logInfo(methodName, "created incident unique id=" + response.id); clientResponse = mRestClient.resource(BMC_DOMAIN_NAME).path(incidentURI + "/" + response.id) .type(MediaType.APPLICATION_JSON_TYPE).header("Authorization", "Bearer " + accessToken) .get(ClientResponse.class); responseString = clientResponse.getEntity(String.class); response = jsonSlurper.parseText(responseString) log.logInfo(methodName, "incident details=" + response); request = createRequestForIncident(response); } catch (Exception e) { log.logInfo(methodName, "Incident creation failed " + e.getMessage() + " " + e) throw new ApiException("Incident creation failed. " + e.getMessage()); } log.logFinestExiting(methodName, request); return request; } def createRequestForIncident(response) { Request request = new RequestImpl(response.Name, response.BMCServiceDesk__incidentDescription__c, response.BMCServiceDesk__Status__c, ChangeManagementSystem.RequestType.INCIDENT, null, "" + response.BMCServiceDesk__Approved__c, true, null); return request } def findRequestByType(String pRequestNumber, ChangeManagementSystem.RequestType pRequestType) { String methodName = "findRequest()"; log.logFinestEntering(methodName, pRequestNumber); Request request = null; try { getAccessToken() Client mRestClient = createClient() String incidentURI = BMC_REMEDY_OBJECT_NAME_URI.replaceAll("\\{OBJECT_NAME\\}", "BMCServiceDesk__Change_Request__c") incidentURI += "/Name/" + pRequestNumber ClientResponse clientResponse = mRestClient.resource(BMC_DOMAIN_NAME).path(incidentURI).accept(MediaType.APPLICATION_JSON_TYPE) .header("Authorization", "Bearer " + this.accessToken) .get(ClientResponse.class); checkResponse(clientResponse) def jsonSlurper = new groovy.json.JsonSlurper() def response = jsonSlurper.parseText(clientResponse.getEntity(String.class)) log.logInfo(methodName, " change request=" + response); request = createRequestForChange(response); } catch (Exception e) { log.logInfo(methodName, "Get request failed - " + e.getMessage() + " " + e) throw new ApiException("Get request failed. " + e.getMessage()); } log.logFinestExiting(methodName, request); return request; } def isRequestApproved(String pRequestNumber, String pEnvironmentCode) { String methodName = "isRequestApproved()"; log.logFinestEntering(methodName, pRequestNumber, pEnvironmentCode); Boolean approved = false; getAccessToken() RequestImpl request = findRequestByType(pRequestNumber, ChangeManagementSystem.RequestType.REQUEST); if (request != null) { if (request.getApproval() != null && request.getApproval().trim().length() > 0 && Boolean.valueOf(request.getApproval()) && request.isActive()) { approved = true; } } log.logFinestExiting(methodName, approved); return approved; } def isRequestRejected(String pRequestNumber, String pEnvironmentCode) { String methodName = "isRequestRejected()"; log.logFinestEntering(methodName, pRequestNumber, pEnvironmentCode); Boolean rejected = false; getAccessToken() RequestImpl request = findRequestByType(pRequestNumber, ChangeManagementSystem.RequestType.REQUEST); if (request != null) { if (request.getApproval() != null && request.getApproval().trim().length() > 0 && ((!"OPENED".equalsIgnoreCase(request.getStatus()) && !Boolean.valueOf(request.getApproval())) || !request.isActive())) { rejected = true; } } log.logFinestExiting(methodName, rejected); return rejected; } def isDoPolling() { String methodName = "isDoPolling()"; log.logFinestEntering(methodName); return false; log.logFinestExiting(methodName); } def getAccessToken() { String methodName = "getAccessToken()"; log.logFinestEntering(methodName); try { if (accessToken == null || accessToken.trim().length() == 0) { Client mRestClient = createClient() log.logInfo(methodName, "BMC_USER_NAME=$BMC_USER_NAME, BMC_PASSWORD=$BMC_PASSWORD") Form form = new Form(); form.add("grant_type", "password"); form.add("client_id", BMC_CLIENT_ID) form.add("client_secret", BMC_CLIENT_SECRET) form.add("username", BMC_USER_NAME) form.add("password", BMC_PASSWORD) ClientResponse clientResponse = mRestClient.resource(BMC_SALESFORCE_HOST_NAME).path(BMC_SALESFORCE_OAUTH2_URI) .type(MediaType.APPLICATION_FORM_URLENCODED_TYPE) .accept(MediaType.APPLICATION_JSON_TYPE) .post(ClientResponse.class, form); checkResponse(clientResponse) String responseString = clientResponse.getEntity(String.class); log.logInfo(methodName, "responseString=" + responseString); def response = jsonSlurper.parseText(responseString) accessToken = response.access_token String instanceUrl = response.instance_url if (!instanceUrl.equals(BMC_DOMAIN_NAME)) { String message = "Instance URL from OAuth2 is different from what is configured in FlexDeploy, URL[${BMC_DOMAIN_NAME}] is changed to [${instanceUrl}]" log.logInfo(methodName, message); BMC_DOMAIN_NAME = instanceUrl } if (accessToken == null || accessToken.trim().length() == 0) { throw new ApiException("Couldn't get acess token from BMC. Please check the properties in the CMS config"); } log.logInfo(methodName, "Access Token=" + accessToken + ",instanceUrl=" + instanceUrl); } log.logFinestExiting(methodName); } catch (Exception e) { log.logInfo(methodName, "Not able to get access token failed " + e.getMessage() + " " + e) throw new ApiException("Not able to get access token failed. " + e.getMessage()); } } def checkConnection() { String methodName = "checkConnection()"; log.logFinestEntering(methodName); try { getAccessToken() Client mRestClient = createClient() ///services/data/v33.0/sobjects/User String aboutMeURI = BMC_REMEDY_OBJECT_NAME_URI.replaceAll("\\{OBJECT_NAME\\}", "User") ClientResponse clientResponse = mRestClient.resource(BMC_DOMAIN_NAME).path(aboutMeURI) .type(MediaType.APPLICATION_JSON_TYPE).header("Authorization", "Bearer " + accessToken) .get(ClientResponse.class); checkResponse(clientResponse) def jsonSlurper = new groovy.json.JsonSlurper() def response = jsonSlurper.parseText(clientResponse.getEntity(String.class)) log.logInfo(methodName, "Response from aboutMeURI =" + response); } catch (Exception e) { log.logInfo(methodName, " Test connection failed " + e.getMessage() + " " + e) throw new ApiException("Connection failed. " + e.getMessage()); } log.logFinestExiting(methodName); } }
- Implement all the methods described in the table in the API Implementation section
- For any failure connecting to the system or if any issues with the data, then you can throw exception. For example throw new ApiException("Invalid credentials.", "");
Groovy Utilities
There are some utility variables provided by FlexDeploy that can used in your custom Groovy code.
- log is a FlexDeploy logger variable which should be used to log any information from the groovy class.
- fdrestutils is a utility object available to use FlexDeploy API to invoke any REST API.
- testConnection(String pHostName, String pUrl, String pUserName, String pPassword)
- getRequest(String pHostName, String pResourcePath, String pUserName, String pPassword) - Returns javax.json.JsonObject
- postRequest(String pHostName, String pUserName, String pPassword, String pResourcePath, String pResourceName, String pPayload) - Returns boolean
putRequest(String pHostName, String pUserName, String pPassword, String pResourcePath, String pPayload) - Returns boolean
def builder = new groovy.json.JsonBuilder() def root = builder.issue { notes "${pComment}" } String payload = builder.toString(); String ticketNumber = ticket.getNumber(); String resourcePath = REDMINE_TICKET_REST_PATTERN.replaceAll("\\{REDMINE_ISSUE\\}", ticketNumber) fdrestutils.putRequest(REDMINE_URL, REDMINE_USER_NMAE, REDMINE_PASSWORD, resourcePath, payload);
- style