br.gov.frameworkdemoiselle.behave.integration.alm.ALMIntegration Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of demoiselle-behave-integration-alm Show documentation
Show all versions of demoiselle-behave-integration-alm Show documentation
Demoiselle Behave Integration - ALM
/*
* Demoiselle Framework
* Copyright (C) 2013 SERPRO
* ----------------------------------------------------------------------------
* This file is part of Demoiselle Framework.
*
* Demoiselle Framework is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License version 3
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License version 3
* along with this program; if not, see
* or write to the Free Software Foundation, Inc., 51 Franklin Street,
* Fifth Floor, Boston, MA 02110-1301, USA.
* ----------------------------------------------------------------------------
* Este arquivo é parte do Framework Demoiselle.
*
* O Framework Demoiselle é um software livre; você pode redistribuí-lo e/ou
* modificá-lo dentro dos termos da GNU LGPL versão 3 como publicada pela Fundação
* do Software Livre (FSF).
*
* Este programa é distribuído na esperança que possa ser útil, mas SEM NENHUMA
* GARANTIA; sem uma garantia implícita de ADEQUAÇÃO a qualquer MERCADO ou
* APLICAÇÃO EM PARTICULAR. Veja a Licença Pública Geral GNU/LGPL em português
* para maiores detalhes.
*
* Você deve ter recebido uma cópia da GNU LGPL versão 3, sob o título
* "LICENCA.txt", junto com esse programa. Se não, acesse
* ou escreva para a Fundação do Software Livre (FSF) Inc.,
* 51 Franklin St, Fifth Floor, Boston, MA 02111-1301, USA.
*/
package br.gov.frameworkdemoiselle.behave.integration.alm;
import java.io.IOException;
import java.net.ConnectException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.text.DecimalFormat;
import java.text.Normalizer;
import java.util.ArrayList;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Hashtable;
import java.util.List;
import org.apache.http.Header;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.client.params.ClientPNames;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.params.HttpParams;
import org.apache.log4j.Logger;
import br.gov.frameworkdemoiselle.behave.config.BehaveConfig;
import br.gov.frameworkdemoiselle.behave.exception.BehaveException;
import br.gov.frameworkdemoiselle.behave.integration.Integration;
import br.gov.frameworkdemoiselle.behave.integration.alm.autenticator.AutenticatorClient;
import br.gov.frameworkdemoiselle.behave.integration.alm.httpsclient.HttpsClient;
import br.gov.frameworkdemoiselle.behave.integration.alm.objects.util.GenerateXMLString;
import br.gov.frameworkdemoiselle.behave.internal.integration.ScenarioState;
import br.gov.frameworkdemoiselle.behave.message.BehaveMessage;
import com.ibm.rqm.xml.bind.Testcase;
import com.ibm.rqm.xml.bind.Testplan;
@SuppressWarnings("deprecation")
public class ALMIntegration implements Integration {
private static Logger log = Logger.getLogger(ALMIntegration.class);
public static String MESSAGEBUNDLE = "demoiselle-integration-alm-bundle";
private BehaveMessage message = new BehaveMessage(MESSAGEBUNDLE);
public String urlServer;
public String urlServerAuth;
public String projectAreaAlias;
private Integer testCaseId;
private String username;
private String password;
public final String ENCODING = "UTF-8";
/**
* A integração presupõe que cada Cenário de cada história é um Caso de
* Teste na ALM
*/
public void sendScenario(Hashtable result) {
try {
// Tenta obter dados de autenticacao vindo do Hashtable
if (result.containsKey("user") && result.containsKey("password")) {
username = (String) result.get("user");
password = (String) result.get("password");
} else {
// Pega os dados de autenticação
log.debug(message.getString("message-get-authenticator"));
AutenticatorClient autenticator = new AutenticatorClient(BehaveConfig.getIntegration_AuthenticatorPort(), BehaveConfig.getIntegration_AuthenticatorHost());
autenticator.open();
username = autenticator.getUser();
password = autenticator.getPassword();
autenticator.close();
}
// Tenta obter dados de conexao com o ALM via hash
urlServer = getHash(result, "urlServer", BehaveConfig.getIntegration_UrlServices()).trim();
urlServerAuth = getHash(result, "urlServerAuth", BehaveConfig.getIntegration_UrlSecurity()).trim();
projectAreaAlias = getHash(result, "projectAreaAlias", BehaveConfig.getIntegration_ProjectArea()).trim();
// Para evitar problemas com encodings em projetos nós sempre
// fazemos o decoding e depois encoding
projectAreaAlias = URLDecoder.decode(projectAreaAlias, ENCODING);
// Encode do Alias do Projeto
projectAreaAlias = URLEncoder.encode(projectAreaAlias, ENCODING);
// ID fixo de caso de teste
boolean testCaseIdMeta = false;
if (result.containsKey("testCaseId")) {
testCaseId = Integer.parseInt((String) result.get("testCaseId"));
testCaseIdMeta = true;
} else {
testCaseId = null;
}
log.debug(message.getString("message-integration-alm-started"));
long t0 = GregorianCalendar.getInstance().getTimeInMillis();
HttpClient client;
String testCaseName;
// Somente cria e associa o caso de teste quando ele não é informado
if (testCaseId == null) {
String testCaseIdentification = convertToIdentificationString(result.get("name").toString());
testCaseName = "testcase" + testCaseIdentification;
// --------------------------- TestCase (GET)
// Conexão HTTPS
client = HttpsClient.getNewHttpClient(ENCODING);
// Login
login(client);
// Cria um novo caso de teste
Testcase testCase = new Testcase();
HttpResponse responseTestCaseGet = getRequest(client, "testcase", testCaseName);
if (responseTestCaseGet.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
testCase = GenerateXMLString.getTestcaseObject(responseTestCaseGet);
}
// --------------------------- TestCase (PUT)
// Conexão HTTPS
client = HttpsClient.getNewHttpClient(ENCODING);
// Login
login(client);
// TestCase
log.debug(message.getString("message-send-test-case"));
HttpResponse responseTestCase = sendRequest(client, "testcase", testCaseName, GenerateXMLString.getTestcaseString(urlServer, projectAreaAlias, ENCODING, result.get("name").toString(), result.get("steps").toString(), testCase));
if (responseTestCase.getStatusLine().getStatusCode() != HttpStatus.SC_CREATED && responseTestCase.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
throw new BehaveException(message.getString("exception-create-test-case", responseTestCase.getStatusLine().toString()));
}
} else {
testCaseName = "urn:com.ibm.rqm:testcase:" + testCaseId;
}
// Verifica se a auto associação esta habilitada
if (BehaveConfig.getIntegration_AutoAssociateTestCaseInPlan()) {
// --------------------------- Test Plan (GET)
// Conexão HTTPS
client = HttpsClient.getNewHttpClient(ENCODING);
// Login
login(client);
Testplan plan;
String testPlanNameId = "urn:com.ibm.rqm:testplan:" + result.get("testPlanId").toString();
HttpResponse responseTestPlanGet = getRequest(client, "testplan", testPlanNameId);
if (responseTestPlanGet.getStatusLine().getStatusCode() != HttpStatus.SC_CREATED && responseTestPlanGet.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
throw new BehaveException(message.getString("exception-test-plan-not-found", result.get("testPlanId").toString(), projectAreaAlias) + ". --> communication failure, status code [" + responseTestPlanGet.getStatusLine().getStatusCode() +"]");
} else {
plan = GenerateXMLString.getTestPlanObject(responseTestPlanGet);
}
// --------------------------- Test Plan (PUT)
// Conexão HTTPS
client = HttpsClient.getNewHttpClient(ENCODING);
// Login
login(client);
// TestPlan
log.debug(message.getString("message-send-test-plan"));
HttpResponse responseTestPlan = sendRequest(client, "testplan", testPlanNameId, GenerateXMLString.getTestplanString(urlServer, projectAreaAlias, ENCODING, testCaseName, plan));
if (responseTestPlan.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
throw new BehaveException(message.getString("exception-send-test-plan", responseTestPlan.getStatusLine().toString()));
}
}
// --------------------------- Work Item (PUT)
// Conexão HTTPS
client = HttpsClient.getNewHttpClient(ENCODING);
// Login
login(client);
// WorkItem
log.debug(message.getString("message-send-execution"));
String workItemName = "workitemExecucaoAutomatizada-" + convertToIdentificationString(testCaseName) + "-" + result.get("testPlanId").toString();
boolean redirect = false;
HttpResponse responseWorkItem = sendRequest(client, "executionworkitem", workItemName, GenerateXMLString.getExecutionworkitemString(urlServer, projectAreaAlias, ENCODING, testCaseName, result.get("testPlanId").toString()));
if (responseWorkItem.getStatusLine().getStatusCode() != HttpStatus.SC_CREATED && responseWorkItem.getStatusLine().getStatusCode() != HttpStatus.SC_OK && responseWorkItem.getStatusLine().getStatusCode() != HttpStatus.SC_SEE_OTHER) {
String ms = message.getString("exception-create-execution", responseWorkItem.getStatusLine().toString());
if (testCaseIdMeta) {
ms = message.getString("exception-verity-execution", testCaseId.toString(), message);
}
throw new BehaveException(ms);
} else {
Header locationHeader = responseWorkItem.getFirstHeader("Content-Location");
if (locationHeader != null) {
redirect = true;
workItemName = locationHeader.getValue();
}
}
// --------------------------- Result (PUT)
// Conexão HTTPS
client = HttpsClient.getNewHttpClient(ENCODING);
// Login
login(client);
// WorkItem
log.debug(message.getString("message-send-result"));
String resultName = "result" + System.nanoTime();
// Tratamento da identificação do workitem
String executionWorkItemUrl = urlServer + "resources/" + projectAreaAlias + "/executionworkitem/" + workItemName;
if (redirect) {
executionWorkItemUrl = workItemName;
}
HttpResponse responseResult = sendRequest(client, "executionresult", resultName, GenerateXMLString.getExecutionresultString(urlServer, projectAreaAlias, ENCODING, executionWorkItemUrl, ((ScenarioState) result.get("state")), (Date) result.get("startDate"), (Date) result.get("endDate"), (String) result.get("details")));
if (responseResult.getStatusLine().getStatusCode() != HttpStatus.SC_CREATED) {
throw new BehaveException(message.getString("exception-send-result", responseResult.getStatusLine().toString()));
}
long t1 = GregorianCalendar.getInstance().getTimeInMillis();
DecimalFormat df = new DecimalFormat("0.0");
log.debug(message.getString("message-integration-alm-end", df.format((t1 - t0) / 1000.00)));
} catch (RuntimeException e) {
if (e.getCause() instanceof ConnectException) {
throw new BehaveException(message.getString("exception-authenticator-inaccessible"), e);
} else {
throw new BehaveException(e);
}
} catch (Exception e) {
throw new BehaveException(e);
}
}
/**
* Obteem o valor do hash ou retorna um valor padrão
*
* @param result
* @param key
* @param defaultValue
* @return
*/
private String getHash(Hashtable result, String key, String defaultValue) {
if (result.containsKey(key)) {
return (String) result.get(key);
} else {
return defaultValue;
}
}
public void login(HttpClient client) throws Exception {
log.debug(message.getString("message-user-authentication", username));
HttpResponse responseLogin = login(client, username, password);
if (responseLogin.getStatusLine().getStatusCode() != 302 || !responseLogin.toString().contains("LtpaToken2")) {
throw new BehaveException(message.getString("exception-user-authentication"));
}
}
public String convertToIdentificationString(String str) {
String ret = Normalizer.normalize(str, Normalizer.Form.NFD).replace(" ", "").replaceAll("\\p{InCombiningDiacriticalMarks}+", "");
ret = ret.replaceAll("[-]", "").replaceAll("[:]", "").replaceAll("[.]", "").replaceAll("[#]", "");
return ret;
}
public HttpResponse login(HttpClient client, String username, String password) throws ClientProtocolException, IOException {
// Inicia o login
HttpPost requestAuth = new HttpPost(urlServerAuth);
List formparams = new ArrayList();
formparams.add(new BasicNameValuePair("j_username", username));
formparams.add(new BasicNameValuePair("j_password", password));
UrlEncodedFormEntity entity = new UrlEncodedFormEntity(formparams, ENCODING);
requestAuth.setEntity(entity);
// Faz o post e pega os cookies
HttpResponse response = client.execute(requestAuth);
return response;
}
public HttpResponse sendRequest(HttpClient client, String resource, String id, String xmlRequest) throws ClientProtocolException, IOException {
String url = urlServer + "resources/" + projectAreaAlias + "/" + resource + "/" + id;
log.debug(url);
HttpPut request = new HttpPut(url);
request.addHeader("Content-Type", "application/xml; charset=" + ENCODING);
request.addHeader("Encoding", ENCODING);
HttpParams params = request.getParams();
params.setParameter(ClientPNames.HANDLE_REDIRECTS, Boolean.FALSE);
// Seta o encoding da mensagem XML
ContentType ct = ContentType.create("text/xml", ENCODING);
StringEntity se = new StringEntity(xmlRequest, ct);
se.setContentType("text/xml");
se.setContentEncoding(ENCODING);
request.setEntity(se);
log.debug(xmlRequest);
return client.execute(request);
}
public HttpResponse getRequest(HttpClient client, String resource, String id) throws ClientProtocolException, IOException {
String url = urlServer + "resources/" + projectAreaAlias + "/" + resource + "/" + id;
log.debug(url);
HttpGet request = new HttpGet(url);
request.addHeader("Content-Type", "application/xml; charset=" + ENCODING);
request.addHeader("Encoding", ENCODING);
return client.execute(request);
}
}