package mycompany.extension.flexdeploy.zendesk;
import flexagon.fd.model.integration.cms.api.CMSObject;
import flexagon.fd.model.integration.cms.api.ChangeManagementSystem;
import flexagon.fd.model.integration.util.ApiException;
import java.io.Serializable;
import java.io.StringReader;
import java.util.Date;
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.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Entity;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import org.glassfish.jersey.client.ClientConfig;
import org.glassfish.jersey.client.ClientProperties;
import org.glassfish.jersey.filter.LoggingFilter;
public class ZendeskServiceIntegration
extends ChangeManagementSystem
{
private static final String CLZ_NAM = ZendeskServiceIntegration.class.getName();
private Logger mLogger;
private Client mRestClient;
private String mAccessToken;
public ZendeskServiceIntegration()
{
super();
this.mLogger = Logger.getLogger(CLZ_NAM);
}
private void getOAuthAccessToken(String pScope)
throws ApiException
{
String methodName = "getOAuthAccessToken";
mLogger.logp(Level.INFO, mLogger.getName(), methodName, "ENTRY");
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();
Response clientResponse =
getRestClient().target(getZendeskDomain()).path(getOAuthURI()).request(MediaType.APPLICATION_JSON_TYPE).accept(MediaType.APPLICATION_JSON_TYPE).post(Entity.json(payLoad));
checkResponse(clientResponse);
JsonObject jsonResponseObject = readJsonObject(clientResponse.readEntity(String.class));
mLogger.logp(Level.INFO, mLogger.getName(), methodName, "OAuth Response " + jsonResponseObject);
mAccessToken = jsonResponseObject.getString("access_token");
mLogger.logp(Level.INFO, mLogger.getName(), methodName, "EXIT");
}
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 CMSObject createTicket(Map<String, Serializable> pTicketFields)
throws ApiException
{
String methodName = "createRequest";
mLogger.logp(Level.INFO, mLogger.getName(), methodName, "ENTRY");
mLogger.logp(Level.INFO, mLogger.getName(), methodName, " Creating new Request using " + pTicketFields);
CMSObject request = postTicket("request", "ZD_REQUEST_CREATE_PATTERN", "requests:write read", pTicketFields);
mLogger.logp(Level.INFO, mLogger.getName(), methodName, "EXIT");
return request;
}
private CMSObject postTicket(String pObjectType, String pURLKey, String pScope, Map<String, Serializable> pTicketFields)
throws ApiException
{
String methodName = "postTicket";
mLogger.logp(Level.INFO, mLogger.getName(), methodName, "ENTRY");
JsonObjectBuilder zenInputJson = Json.createObjectBuilder();
Serializable requestor = pTicketFields.remove("requester_id");
JsonObjectBuilder reqParamJsonBuider = null;
if (requestor != null)
{
reqParamJsonBuider = Json.createObjectBuilder();
reqParamJsonBuider.add("name", requestor.toString());
}
Serializable description = pTicketFields.remove("description");
JsonObjectBuilder desParamJsonBuider = null;
if (description != null)
{
desParamJsonBuider = Json.createObjectBuilder();
desParamJsonBuider.add("body", description.toString());
}
JsonObjectBuilder inputJsonObject = buildJsonRequest(pTicketFields);
if (requestor != null)
{
inputJsonObject.add("requester", reqParamJsonBuider.build());
}
if (description != null)
{
inputJsonObject.add("comment", desParamJsonBuider.build());
}
zenInputJson.add(pObjectType, inputJsonObject);
WebTarget postRequest = getWebResource(getPropertyAsString(pURLKey));
String payLoad = zenInputJson.build().toString();
mLogger.logp(Level.INFO, mLogger.getName(), methodName, String.format(" Creating new %s %s", pObjectType, payLoad));
Response clientResponse = postRequest.request(MediaType.APPLICATION_JSON_TYPE).accept(MediaType.APPLICATION_JSON_TYPE).header("Authorization", getAccessToken(pScope)).post(Entity.json(payLoad));
checkResponse(clientResponse);
JsonObject jsonResponseObject = readJsonObject(clientResponse.readEntity(String.class));
JsonObject requestResponseJson = jsonResponseObject.getJsonObject(pObjectType);
CMSObject request = createTicketFromJson(requestResponseJson, ChangeManagementSystem.CMSObjectType.TICKET);
mLogger.logp(Level.INFO, mLogger.getName(), methodName, String.format(" Successfully created ticket %s", request.getNumber()));
mLogger.logp(Level.INFO, mLogger.getName(), methodName, "EXIT");
return request;
}
private CMSObject createTicketFromJson(JsonObject jsonObject, CMSObjectType pType)
{
String methodName = "createTicketFromJson";
mLogger.logp(Level.INFO, mLogger.getName(), methodName, "ENTRY");
CMSObject ticket = CMSObjectImpl.getInstance(String.valueOf(jsonObject.getInt("id")), pType, jsonObject, jsonObject.getString("description"));
mLogger.logp(Level.INFO, mLogger.getName(), methodName, "EXIT");
return ticket;
}
private JsonObject readJsonObject(String source)
{
String methodName = "readJsonObject";
mLogger.logp(Level.INFO, mLogger.getName(), methodName, "ENTRY");
JsonReader jsonReader = Json.createReader(new StringReader(source));
JsonObject object = null;
try
{
object = jsonReader.readObject();
mLogger.logp(Level.INFO, mLogger.getName(), 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));
}
finally
{
if (jsonReader != null)
{
jsonReader.close();
}
}
mLogger.logp(Level.INFO, mLogger.getName(), methodName, "EXIT");
return object;
}
@Override
public CMSObject createIncident(Map<String, Serializable> pIncidentFields)
{
String methodName = "createIncident";
mLogger.logp(Level.INFO, mLogger.getName(), methodName, "ENTRY");
CMSObject request = null;
try
{
request = postTicket("ticket", "ZD_TICKET_CREATE_PATTERN", "tickets:write read", pIncidentFields);
}
catch (ApiException e)
{
mLogger.logp(Level.INFO, mLogger.getName(), methodName, String.format(" Exception while creating incident, error %s", e.getMessage()));
}
mLogger.logp(Level.INFO, mLogger.getName(), methodName, "EXIT");
return request;
}
@Override
public CMSObject findCMSObjectByType(String pRequestNumber, ChangeManagementSystem.CMSObjectType pRequestType)
throws ApiException
{
String methodName = "findCMSObjectByType";
mLogger.logp(Level.INFO, mLogger.getName(), methodName, "ENTRY");
CMSObject changeRequest = getChangeRequest(pRequestNumber);
if (changeRequest != null && changeRequest.getTypeName().equalsIgnoreCase("QUESTION") && pRequestType.equals(ChangeManagementSystem.CMSObjectType.TICKET))
{
mLogger.logp(Level.INFO, mLogger.getName(), methodName, pRequestNumber + " is of type QUESTION, setting it as REQUEST for FD");
}
mLogger.logp(Level.INFO, mLogger.getName(), methodName, "EXIT");
return getChangeRequest(pRequestNumber);
}
private CMSObject getChangeRequest(String pRequestNumber)
throws ApiException
{
return getTicket("request", "ZD_REQUEST_GET_PATTERN", pRequestNumber, "{ZENDESK_REQUEST}");
}
private CMSObject getTicket(String pObjectType, String pURLKey, String pRequestNumber, String pSearchPattern)
throws ApiException
{
String methodName = "getTicket";
mLogger.logp(Level.INFO, mLogger.getName(), methodName, "ENTRY");
mLogger.logp(Level.INFO, mLogger.getName(), 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);
Response clientResponse = getWebResource(urlString).request(MediaType.APPLICATION_JSON_TYPE).header("Authorization", getAccessToken("tickets:write read")).get(Response.class);
checkResponse(clientResponse);
JsonObject jsonResponseObject = readJsonObject(clientResponse.readEntity(String.class));
JsonObject ticketResponseJson = jsonResponseObject.getJsonObject(pObjectType);
CMSObject request = createTicketFromJson(ticketResponseJson, ChangeManagementSystem.CMSObjectType.TICKET);
mLogger.logp(Level.INFO, mLogger.getName(), methodName, String.format(" Successfully found ticket %s", request.getNumber()));
mLogger.logp(Level.INFO, mLogger.getName(), methodName, "EXIT");
return request;
}
@Override
public Boolean isTicketApproved(CMSObject requestNumber, String environmentCode)
{
String methodName = "isTicketApproved";
mLogger.logp(Level.INFO, mLogger.getName(), methodName, "ENTRY");
CMSObject findRequest = requestNumber;
Boolean approved = false;
try
{
if (findRequest != null)
{
String status = findRequest.getJson().getString("status");
mLogger.logp(Level.INFO, mLogger.getName(), methodName, String.format("#[%s] status [%s]", requestNumber, status));
if ("solved".equalsIgnoreCase(status))
{
approved = true;
}
}
}
catch (Exception e)
{
// TODO: Add catch code
}
mLogger.logp(Level.INFO, mLogger.getName(), methodName, "EXIT");
return approved;
}
@Override
public Boolean isTicketRejected(CMSObject requestNumber, String environmentCode)
{
String methodName = "isTicketRejected";
mLogger.logp(Level.INFO, mLogger.getName(), methodName, "ENTRY");
CMSObject findRequest = requestNumber;
Boolean rejected = false;
try
{
if (findRequest != null)
{
String status = findRequest.getJson().getString("status");
mLogger.logp(Level.INFO, mLogger.getName(), methodName, String.format("#[%s] status [%s]", requestNumber, status));
if ((!"New".equalsIgnoreCase(status)) && ("on-hold".equalsIgnoreCase(status) || "Closed".equalsIgnoreCase(status)))
{
rejected = true;
}
}
}
catch (Exception e)
{
// TODO: Add catch code
}
mLogger.logp(Level.INFO, mLogger.getName(), methodName, "EXIT");
return rejected;
}
@Override
public Boolean isDoPolling()
{
return false;
}
@Override
public void checkConnection()
throws ApiException
{
String methodName = "checkConnection";
mLogger.logp(Level.INFO, mLogger.getName(), methodName, "ENTRY");
mLogger.logp(Level.INFO, mLogger.getName(), methodName, " getting user details to check connection");
// ClientResponse clientResponse = getWebResource("/api/v2/users/me.json").header("Authorization", "Basic " + getAuthString()).get(ClientResponse.class);
Response clientResponse = getWebResource("/api/v2/users/me.json").request(MediaType.APPLICATION_JSON_TYPE).header("Authorization", getAccessToken("organizations:write read")).get(Response.class);
checkResponse(clientResponse);
String responseString = clientResponse.readEntity(String.class);
mLogger.logp(Level.INFO, mLogger.getName(), methodName, "responseString=" + responseString + ", Validated that JSON data was received from test connction URL invocation.");
mLogger.logp(Level.INFO, mLogger.getName(), methodName, "EXIT");
}
private StringBuilder getZendeskURLBuilder()
{
StringBuilder urlBuilder = new StringBuilder(getPropertyAsString("ZD_DOMAIN_NAME"));
return urlBuilder;
}
private void checkResponse(Response clientResponse)
throws ApiException
{
String methodName = "checkResponse";
mLogger.logp(Level.INFO, mLogger.getName(), methodName, "EXIT");
mLogger.logp(Level.INFO, mLogger.getName(), methodName, String.format(" Response %s", clientResponse));
int statusCode = clientResponse.getStatusInfo().getStatusCode();
if (statusCode == 401)
{
throw new ApiException("Invalid credentials.", "");
}
if (statusCode == 500)
{
//record not found or other scenarious don't want to fail.
return;
}
if (!(clientResponse.getStatusInfo().getFamily() == Response.Status.Family.SUCCESSFUL))
{
throw new ApiException(clientResponse.toString(), clientResponse.getStatusInfo().getReasonPhrase());
}
mLogger.logp(Level.INFO, mLogger.getName(), methodName, "EXIT");
}
private String getZendeskDomain()
{
return getZendeskURLBuilder().toString();
}
private String getUserName()
{
String userName = getPropertyAsString("ZD_USER_NAME");
return userName;
}
private String getPassword()
{
String pwd = getPropertyAsString("ZD_PASSWORD");
return pwd;
}
private String getPropertyAsString(String pKey)
{
return (String) getProperties().get(pKey);
}
private Client getRestClient()
throws ApiException
{
if (mRestClient == null)
{
mRestClient = ClientBuilder.newClient(new ClientConfig().register(LoggingFilter.class));
mRestClient.property(ClientProperties.CONNECT_TIMEOUT, 10000);
mRestClient.property(ClientProperties.READ_TIMEOUT, 20000);
}
return mRestClient;
}
public WebTarget getWebResource(String resource)
throws ApiException
{
if (resource != null && !resource.isEmpty() && !resource.startsWith("/"))
{
resource += "/" + resource;
}
WebTarget webResource = null;
try
{
webResource = getRestClient().target(getZendeskDomain()).path(resource);
}
catch (Exception e)
{
throw new ApiException(e.getMessage(), e.getMessage());
}
return webResource;
}
protected JsonObjectBuilder buildJsonRequest(Map<String, Serializable> pFields)
{
JsonObjectBuilder jsonBuider = Json.createObjectBuilder();
for (String fieldKey: pFields.keySet())
{
Serializable fieldValue = pFields.get(fieldKey);
if (fieldValue != null)
{
if (fieldValue instanceof String)
{
jsonBuider.add(fieldKey, (String) fieldValue);
}
else if (fieldValue instanceof Boolean)
{
jsonBuider.add(fieldKey, (Boolean) fieldValue);
}
else if (fieldValue instanceof Integer)
{
jsonBuider.add(fieldKey, (Integer) fieldValue);
}
else if (fieldValue instanceof Float)
{
jsonBuider.add(fieldKey, (Float) fieldValue);
}
else if (fieldValue instanceof Double)
{
jsonBuider.add(fieldKey, (Double) fieldValue);
}
else if (fieldValue instanceof Long)
{
jsonBuider.add(fieldKey, (Long) fieldValue);
}
else
{
// convert to String if type unknown
jsonBuider.add(fieldKey, fieldValue.toString());
}
}
}
return jsonBuider;
}
public String getTicketURL(CMSObject pCMSObject)
{
String methodName = "getTicketURL()";
log.logFinestEntering(methodName, pCMSObject);
StringBuilder //tickerUrlBuilder convert= to String if type unknown
jsonBuider.add(fieldKey, fieldValue.toString());
new StringBuilder();
if(pCMSObject != null)
{
tickerUrlBuilder.append(getZendeskDomain());
String urlString = getPropertyAsString("ZD_REQUEST_GET_PATTERN");
String changeRequestURI = urlString.replace("{ZENDESK_REQUEST}"), pCMSObject.getNumber());
tickerUrlBuilder.append(changeRequestURI);
}
}String url = tickerUrlBuilder.toString();
} log.logFinestExiting(methodName, url);
return jsonBuiderurl;
}
}
|