/*
* Copyright 2013, The Sporting Exchange Limited
* Copyright 2014, Simon Matić Langford
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.betfair.testing.utils.cougar.manager;
import com.betfair.cougar.util.configuration.PropertyConfigurer;
import com.betfair.testing.utils.JSONHelpers;
import com.betfair.testing.utils.cougar.beans.HttpCallBean;
import com.betfair.testing.utils.cougar.callmaker.AbstractCallMaker;
import com.betfair.testing.utils.cougar.callmaker.CallMakerFactory;
import com.betfair.testing.utils.cougar.enums.CougarMessageContentTypeEnum;
import com.betfair.testing.utils.cougar.enums.CougarMessageProtocolRequestTypeEnum;
import com.betfair.testing.utils.cougar.enums.CougarMessageProtocolResponseTypeEnum;
import com.betfair.testing.utils.cougar.helpers.CougarHelpers;
import com.betfair.testing.utils.cougar.misc.XMLHelpers;
import org.json.JSONObject;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import java.io.File;
import java.io.IOException;
import java.sql.Timestamp;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
public class CougarManager {
private CougarHelpers cougarHelpers;
private JSONHelpers jHelpers = new JSONHelpers();
private static final Map<String, String> OPERATION_PATHS = new HashMap<String, String>(){
{
put("simple","testSimpleGet");
put("noparams","testNoParams");
put("styles","TestParameterStyles");
put("large","testLargePost");
put("complex","testComplexMutator");
put("largeGet","testLargeGet");
put("secure","testSecureService");
put("simple/async","testSimpleAsyncGet");
put("simple/async,timeout","testAsyncGetTimeout");
}
};
private String baseLogDirectory;
private String accessLogFileName;
private AccessLogTailer accessLogTailer;
private RequestLogTailer requestLogTailer;
private ServiceLogTailer serviceLogTailer;
private TraceLogTailer traceLogTailer;
private long logTimeoutMs = 5000L;
private String requestLogFileName;
private String serviceLogFileName;
private String traceLogFileName;
private static CougarManager instance = new CougarManager();
public static CougarManager getInstance() {
return instance;
}
private CougarManager() {
ClassPathXmlApplicationContext springContext = new ClassPathXmlApplicationContext("/conf/com.betfair.jett.utils.cougar.xml");
cougarHelpers = (CougarHelpers)springContext.getBean("cougarHelpers");
HashMap<CougarMessageProtocolRequestTypeEnum, AbstractCallMaker> requestBuilderMap = (HashMap<CougarMessageProtocolRequestTypeEnum, AbstractCallMaker>)springContext.getBean("requestBuilderMap");
CallMakerFactory.setRequestBuilderMap(requestBuilderMap);
}
/**
*
* Get a new CougarHttpCallBean
*
* @return
*/
public HttpCallBean getNewHttpCallBean() {
return new HttpCallBean();
}
/**
* Get a new CougarHttpCallBean setting the ipAddress as passed
*
* @param ipAddress
* @return
*/
public HttpCallBean getNewHttpCallBean(String ipAddress) {
HttpCallBean callBean = new HttpCallBean();
callBean.setIpAddress(ipAddress);
return callBean;
}
/**
* Method will make REST JSON and XML calls to the baseline-app service specified in
* the HttpCallBean, running locally, and returns the responses in the HTTPCallBean.
*
* @param httpCallBean
* @return
*/
public void makeRestCougarHTTPCalls(HttpCallBean httpCallBean) {
AbstractCallMaker callMaker;
callMaker = CallMakerFactory.resolveRequestBuilderForCougarService(CougarMessageProtocolRequestTypeEnum.RESTJSON);
httpCallBean.setResponseByEnum(CougarMessageProtocolResponseTypeEnum.RESTJSONJSON, callMaker.makeCall(httpCallBean, CougarMessageContentTypeEnum.JSON));
httpCallBean.setResponseByEnum(CougarMessageProtocolResponseTypeEnum.RESTJSONXML, callMaker.makeCall(httpCallBean, CougarMessageContentTypeEnum.XML));
callMaker = CallMakerFactory.resolveRequestBuilderForCougarService(CougarMessageProtocolRequestTypeEnum.RESTXML);
httpCallBean.setResponseByEnum(CougarMessageProtocolResponseTypeEnum.RESTXMLXML, callMaker.makeCall(httpCallBean, CougarMessageContentTypeEnum.XML));
httpCallBean.setResponseByEnum(CougarMessageProtocolResponseTypeEnum.RESTXMLJSON, callMaker.makeCall(httpCallBean, CougarMessageContentTypeEnum.JSON));
}
/**
* Method will make SOAP call to the baseline-app service specified in
* the HttpCallBean, running locally, and returns the responses in the HTTPCallBean.
*
* @return
*/
public void makeSoapCougarHTTPCalls(HttpCallBean httpCallBean) {
AbstractCallMaker callMaker;
callMaker = CallMakerFactory.resolveRequestBuilderForCougarService(CougarMessageProtocolRequestTypeEnum.SOAP);
httpCallBean.setResponseByEnum(CougarMessageProtocolResponseTypeEnum.SOAP, callMaker.makeCall(httpCallBean, CougarMessageContentTypeEnum.XML));
}
public CougarHelpers getCougarHelpers() {
return cougarHelpers;
}
public void setCougarHelpers(CougarHelpers cougarHelpers) {
this.cougarHelpers = cougarHelpers;
}
/**
* Method returns a Map holding the response converted to each of the Rest message/content types
* supported by the cougar baseline app
*
* @param document
* @param httpCallBean
* @return
*/
public Map<CougarMessageProtocolRequestTypeEnum, Object> convertResponseToRestTypes(Document document, HttpCallBean httpCallBean) {
HashMap<CougarMessageProtocolRequestTypeEnum, Object> returnMap = new HashMap<CougarMessageProtocolRequestTypeEnum, Object>();
JSONObject jObject = jHelpers.convertXMLDocumentToJSONObjectRemoveRootElement(document);
jHelpers.removeJSONObjectHoldingSameTypeList(jObject);
returnMap.put(CougarMessageProtocolRequestTypeEnum.RESTJSON, jObject);
Document newDocument = null;
if ((document != null) && (!document.getDocumentElement().getNodeName().equalsIgnoreCase("fault"))){
try {
DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
newDocument = builder.newDocument();
/* Operation name may not equal the pathname. Have to use the operation name
* to create a REST wrapper.
*/
String operationName = OPERATION_PATHS.get(httpCallBean.getOperationName());
if(operationName == null){
operationName = httpCallBean.getOperationName();
}
String serviceName = operationName.substring(0,1).toUpperCase(Locale.ENGLISH) + operationName.substring(1) + "Response";
Element root = (Element)newDocument.createElement(serviceName);
newDocument.appendChild(root);
root.appendChild( newDocument.importNode(document.getDocumentElement(), true) );
}catch (ParserConfigurationException e) {
throw new RuntimeException("Error occured while wrapping existing REST request with a new root element ResponseOperationResponse.", e);
}
newDocument.getDocumentElement().setAttribute("xmlns", httpCallBean.getNameSpace());
XMLHelpers helper = new XMLHelpers();
// LogHelper.log(helper.getXMLAsString(newDocument));
}
if(newDocument == null){ // Return original document (for null messages & faults)
returnMap.put(CougarMessageProtocolRequestTypeEnum.RESTXML, document);
}
else{ // Return new Document with correct root
returnMap.put(CougarMessageProtocolRequestTypeEnum.RESTXML, newDocument);
}
return returnMap;
}
/**
* Method will make REST JSON and XML calls to the baseline-app service specified in
* the HttpCallBean, running locally, and returns the responses in the HTTPCallBean.
*
* @return
*/
public void makeRestCougarHTTPCall(HttpCallBean httpCallBean, CougarMessageProtocolRequestTypeEnum requestProtocolType) {
AbstractCallMaker callMaker;
callMaker = CallMakerFactory.resolveRequestBuilderForCougarService(requestProtocolType);
httpCallBean.setResponseByEnum(CougarMessageProtocolResponseTypeEnum.REST, callMaker.makeCall(httpCallBean, null));
}
/**
*
* Sorts the passed array of maps by the ServiceVersion field
*
* @param inputMap
* @return
* */
public Map<String, Object>[] sortRequestLogEntriesByServiceVersion(Map<String,Object>[] inputMap) {
boolean swapped;
Map<String,Object> temp;
do{
swapped = false;
for(int i = 1; i < inputMap.length; i++){
if(((Double) inputMap[i-1].get("ServiceVersion")) > ((Double) inputMap[i].get("ServiceVersion"))){
temp = inputMap[i];
inputMap[i] = inputMap[i-1];
inputMap[i-1] = temp;
swapped = true;
}
}
}while(swapped);
return inputMap;
}
/**
* Sets the value of the specified attribute for the Fault Controller JMX
* MBean.
*
* @param attributeName
* @param value
*/
public void setCougarFaultControllerJMXMBeanAttrbiute(String attributeName, String value) {
cougarHelpers.setJMXFaultControllerAttribute(attributeName, value);
}
/**
*
* Gets the value of the passed attribute from Cougar JMX Logging Manager
*
* @param attributeName
* @return
*/
public String getCougarLogManagerJMXAttributeValue(String attributeName) {
return cougarHelpers.getJMXLoggingManagerAttributeValue(attributeName);
}
public Integer getCougarUpTimeInMins(String attributeName){
String value = cougarHelpers.getRuntimeAttributeValue(attributeName);
Integer timeInMS = Integer.valueOf(value);
Integer timeInMins = (timeInMS / 60000);
return timeInMins;
}
/**
*
* Method will make REST JSON and XML calls to the baseline-app service specified in
* the HttpCallBean, running locally, and returns the responses in the HTTPCallBean.
*
* @param httpCallBean
* @param requestProtocolType
* @param responseContentType
*/
public void makeRestCougarHTTPCall(HttpCallBean httpCallBean, CougarMessageProtocolRequestTypeEnum requestProtocolType, CougarMessageContentTypeEnum responseContentType) {
AbstractCallMaker callMaker;
callMaker = CallMakerFactory.resolveRequestBuilderForCougarService(requestProtocolType);
CougarMessageProtocolResponseTypeEnum messageProtocolResponseTypeEnum = CougarMessageProtocolResponseTypeEnum.valueOf(requestProtocolType.toString()+responseContentType.toString());
httpCallBean.setResponseByEnum(messageProtocolResponseTypeEnum, callMaker.makeCall(httpCallBean, responseContentType));
}
public String getBaseLogDirectory() {
if (baseLogDirectory == null) {
baseLogDirectory = System.getProperty("cougar.base.log.dir");
if (baseLogDirectory == null) {
String logDir = cougarHelpers.getJMXApplicationPropertyValue("cougar.log.dir");
String workingDir = cougarHelpers.getJMXSystemPropertyValue("user.dir");
baseLogDirectory = workingDir + "/" + logDir;
}
}
return baseLogDirectory;
}
public String getAccessLogFileName() {
if (accessLogFileName == null) {
String machineName = PropertyConfigurer.HOSTNAME;
String logName = machineName + "-cougar-baseline-access.log";
accessLogFileName = "dw/"+logName;
}
return accessLogFileName;
}
public String getRequestLogFileName() {
if (requestLogFileName == null) {
String machineName = PropertyConfigurer.HOSTNAME;
String logName = machineName + "-cougar-baseline-request-Baseline.log";
requestLogFileName = "dw/"+logName;
}
return requestLogFileName;
}
public String getServiceLogFileName() {
if (serviceLogFileName == null) {
String machineName = PropertyConfigurer.HOSTNAME;
String logName = machineName + "-cougar-baseline-server.log";
serviceLogFileName = logName;
}
return serviceLogFileName;
}
public String getTraceLogFileName() {
if (traceLogFileName == null) {
String machineName = PropertyConfigurer.HOSTNAME;
String logName = machineName + "-cougar-baseline-trace.log";
traceLogFileName = logName;
}
return traceLogFileName;
}
public void verifyTraceLogEntriesAfterDate(Timestamp fromDate, TraceLogRequirement... requirements) throws IOException, InterruptedException {
verifyTraceLogEntriesAfterDate(fromDate, getLogTimeoutMs(), requirements);
}
public void verifyTraceLogEntriesAfterDate(Timestamp fromDate, long timeoutMs, TraceLogRequirement... requirements) throws IOException, InterruptedException {
if (traceLogTailer == null) {
traceLogTailer = new TraceLogTailer(new File(getBaseLogDirectory(), getTraceLogFileName()));
traceLogTailer.awaitStart();
}
traceLogTailer.lookForLogLines(fromDate, timeoutMs, requirements);
}
public void verifyServiceLogEntriesAfterDate(Timestamp fromDate, ServiceLogRequirement... requirements) throws IOException, InterruptedException {
verifyServiceLogEntriesAfterDate(fromDate, getLogTimeoutMs(), requirements);
}
public void verifyServiceLogEntriesAfterDate(Timestamp fromDate, long timeoutMs, ServiceLogRequirement... requirements) throws IOException, InterruptedException {
if (serviceLogTailer == null) {
serviceLogTailer = new ServiceLogTailer(new File(getBaseLogDirectory(), getServiceLogFileName()));
serviceLogTailer.awaitStart();
}
serviceLogTailer.lookForLogLines(fromDate, timeoutMs, requirements);
}
public void verifyNoServiceLogEntriesAfterDate(Timestamp fromDate, long timeoutMs, ServiceLogRequirement... requirements) throws IOException, InterruptedException {
if (serviceLogTailer == null) {
serviceLogTailer = new ServiceLogTailer(new File(getBaseLogDirectory(), getServiceLogFileName()));
serviceLogTailer.awaitStart();
}
serviceLogTailer.lookForNoLogLines(fromDate, timeoutMs, requirements);
}
public void verifyAccessLogEntriesAfterDate(Timestamp fromDate, AccessLogRequirement... requirements) throws IOException, InterruptedException {
verifyAccessLogEntriesAfterDate(fromDate, getLogTimeoutMs(), requirements);
}
public void verifyAccessLogEntriesAfterDate(Timestamp fromDate, long timeoutMs, AccessLogRequirement... requirements) throws IOException, InterruptedException {
if (accessLogTailer == null) {
accessLogTailer = new AccessLogTailer(new File(getBaseLogDirectory(), getAccessLogFileName()));
accessLogTailer.awaitStart();
}
accessLogTailer.lookForLogLines(fromDate, timeoutMs, requirements);
}
public LogTailer.LogLine[] verifyRequestLogEntriesAfterDate(Timestamp fromDate, RequestLogRequirement... requirements) throws IOException, InterruptedException {
return verifyRequestLogEntriesAfterDate(fromDate, getLogTimeoutMs(), requirements);
}
public LogTailer.LogLine[] verifyRequestLogEntriesAfterDate(Timestamp fromDate, long timeoutMs, RequestLogRequirement... requirements) throws IOException, InterruptedException {
if (requestLogTailer == null) {
requestLogTailer = new RequestLogTailer(new File(getBaseLogDirectory(), getRequestLogFileName()));
requestLogTailer.awaitStart();
}
return requestLogTailer.lookForLogLines(fromDate, timeoutMs, requirements);
}
public long getLogTimeoutMs() {
return logTimeoutMs;
}
public void setLogTimeoutMs(long logTimeoutMs) {
this.logTimeoutMs = logTimeoutMs;
}
}