com.seleniumtests.connectors.tms.hpalm.HpAlmConnector.java Source code

Java tutorial

Introduction

Here is the source code for com.seleniumtests.connectors.tms.hpalm.HpAlmConnector.java

Source

/**
 * Orignal work: Copyright 2015 www.seleniumtests.com
 * Modified work: Copyright 2016 www.infotel.com
 *             Copyright 2017-2019 B.Hecquet
 *
 * 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.seleniumtests.connectors.tms.hpalm;

import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.commons.io.FileUtils;
import org.json.JSONException;
import org.json.JSONObject;
import org.zeroturnaround.zip.ZipUtil;

import com.google.common.primitives.Bytes;
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;
import com.mashape.unirest.http.exceptions.UnirestException;
import com.seleniumtests.connectors.tms.TestManager;
import com.seleniumtests.core.SeleniumTestsContextManager;
import com.seleniumtests.customexception.ConfigurationException;

/**
 * Class to connect to HP ALM using  API
 * @author 
 *
 */
public class HpAlmConnector extends TestManager {

    public static final String HP_ALM_SERVER_URL = "hpAlmServerUrl";
    public static final String HP_ALM_PASSWORD = "hpAlmPassword";
    public static final String HP_ALM_USER = "hpAlmUser";
    public static final String HP_ALM_DOMAIN = "hpAlmDomain";
    public static final String HP_ALM_PROJECT = "hpAlmProject";
    private static final String DOMAIN_NAME = "domain";
    private static final String PROJECT_NAME = "project";
    private static final String ENTITY_ID = "entityId";
    private static final String ENTITY_TYPE = "entityType";

    private String serverUrl;
    private String project;
    private String domain;
    private String user;
    private String password;
    private String currentRunId;
    private Boolean loggedIn;

    /**
     * Constructeur
     * Configure connection to server (>=11) from following variables searched in configuration (env.ini)
     * hpAlmServerUrl, hpAlmProject, hpAlmDomain, hpAlmUser, hpAlmPassword
     * @param configString   JSON conf for HP ALM. must contain the key 'run' (currently runnning test)
     */
    public HpAlmConnector(JSONObject configString) {
        super();

        // check configuration
        try {
            currentRunId = Integer.toString(configString.getInt("run"));
        } catch (JSONException e) {
            throw new ConfigurationException("Test manager configuration does not contain 'run' parameter");
        }

    }

    @Override
    public void init(JSONObject connectParams) {

        String serverUrlVar = connectParams.optString(HP_ALM_SERVER_URL, null);
        String projectVar = connectParams.optString(HP_ALM_PROJECT, null);
        String domainVar = connectParams.optString(HP_ALM_DOMAIN, null);
        String userVar = connectParams.optString(HP_ALM_USER, null);
        String passwordVar = connectParams.optString(HP_ALM_PASSWORD, null);

        if (serverUrlVar == null || projectVar == null || domainVar == null || userVar == null
                || passwordVar == null) {
            throw new ConfigurationException(String.format(
                    "HP ALM access not correctly configured. Environment configuration must contain variables"
                            + "%s, %s, %s, %s, %s",
                    HP_ALM_SERVER_URL, HP_ALM_PASSWORD, HP_ALM_USER, HP_ALM_DOMAIN, HP_ALM_PROJECT));
        }

        serverUrl = serverUrlVar;
        project = projectVar;
        domain = domainVar;
        user = userVar;
        password = passwordVar;

        serverUrl += "/qcbin";
        initialized = true;
    }

    /**
     * connect to server
     */
    @Override
    public void login() {
        if (!initialized) {
            throw new ConfigurationException("test manager has not been previously initialized");
        }

        try {
            HttpResponse<String> response = Unirest.get(serverUrl + "/authentication-point/authenticate")
                    .basicAuth(user, password).asString();
            if (response.getStatus() != 200) {
                throw new ConfigurationException("Cannot connect to HP server: " + response.getStatusText());
            }
        } catch (UnirestException e) {
            throw new ConfigurationException("Cannot connect to HP server", e);
        }
        loggedIn = true;
    }

    /**
     * disconnect from server
     */
    @Override
    public void logout() {
        if (loggedIn) {
            try {
                Unirest.get(serverUrl + "/authentication-point/logout").asString();
            } catch (UnirestException e) {
                logger.warn("Error while logout", e);
            }
        }
    }

    public void updateRunStatus() throws Exception {

        // cration du XML de modification
        HashMap<String, String> fields = new HashMap<>();
        fields.put("status", "Failed");
        Entity entity = buildTestRunResultEntity(fields, "run");
        String xml = EntityMarshallingUtils.unmarshal(Entity.class, entity);

        try {
            lockEntity("run", currentRunId);
            try {
                checkoutEntity("run", currentRunId);

                HttpResponse<String> response = Unirest
                        .put(serverUrl + "/rest/domains/{domain}/projects/{project}/runs/{runId}")
                        .routeParam("runId", currentRunId).routeParam(PROJECT_NAME, project)
                        .routeParam(DOMAIN_NAME, domain).header("Content-Type", "application/xml").body(xml)
                        .asString();

                if (response.getStatus() != 200) {
                    logger.error("Mise  jour du statut impossible: " + response.getStatusText());
                }

            } finally {
                checkinEntity("run", currentRunId);
            }
        } finally {
            unlockEntity("run", currentRunId);
        }
    }

    /**
     * Do nothing as result is directly get from .bat execution
     */
    @Override
    public void recordResult() {
        // nothing to do
    }

    /**
     * compress and record results in ALM
     */
    @Override
    public void recordResultFiles() {

        try {
            File resultFile = File.createTempFile("result-", ".zip");
            ZipUtil.pack(new File(SeleniumTestsContextManager.getThreadContext().getOutputDirectory()), resultFile);

            // Unirest does not allow sending result to ALM
            String boundary = "azertyuiop";
            String body = "--" + boundary + "\r\n";
            body += "Content-Disposition: form-data; name=\"filename\"\r\n";
            body += "Content-type: application/octet-stream\r\n\r\n";
            body += String.format("%s\r\n", resultFile.getName());
            body += "--" + boundary + "\r\n";
            body += String.format("Content-Disposition: form-data; name=\"file\"; filename=\"%s\"\r\n\r\n",
                    resultFile.getName());

            byte[] bodyBytes = Bytes.concat(body.getBytes(), FileUtils.readFileToByteArray(resultFile),
                    String.format("\r\n--%s--\r\n", boundary).getBytes());

            Unirest.post(
                    serverUrl + "/rest/domains/{domain}/projects/{project}/{entityType}s/{entityId}/attachments")
                    .routeParam(ENTITY_TYPE, "run").routeParam(ENTITY_ID, currentRunId)
                    .routeParam(PROJECT_NAME, project).routeParam(DOMAIN_NAME, domain)
                    .header("Content-Type", "multipart/form-data; boundary=" + boundary).body(bodyBytes).asString();

        } catch (UnirestException | IOException e) {
            logger.error("Result record failed", e);
        }
    }

    /**
     * lock entity object so that it can be found during test
     * @param entityType
     * @param entityId
     * @throws UnirestException
     */
    private void lockEntity(String entityType, String entityId) throws UnirestException {
        Unirest.get(serverUrl + "/rest/domains/{domain}/projects/{project}/{entityType}s/{entityId}/lock")
                .routeParam(ENTITY_TYPE, entityType).routeParam(ENTITY_ID, entityId)
                .routeParam(PROJECT_NAME, project).routeParam(DOMAIN_NAME, domain).asString();
    }

    /**
     * lock entity object so that it can be found during test
     * @param entityType
     * @param entityId
     * @throws UnirestException
     */
    private void unlockEntity(String entityType, String entityId) throws UnirestException {
        Unirest.delete(serverUrl + "/rest/domains/{domain}/projects/{project}/{entityType}s/{entityId}/lock")
                .routeParam(ENTITY_TYPE, entityType).routeParam(ENTITY_ID, entityId)
                .routeParam(PROJECT_NAME, project).routeParam(DOMAIN_NAME, domain).asString();
    }

    /**
     * checkout entity object so that it can be found during test
     * used when versionning is enabled
     * @param entityType
     * @param entityId
     * @throws UnirestException
     */
    private void checkoutEntity(String entityType, String entityId) throws UnirestException {
        Unirest.post(
                serverUrl + "/rest/domains/{domain}/projects/{project}/{entityType}s/{entityId}/versions/check-out")
                .routeParam(ENTITY_TYPE, entityType).routeParam(ENTITY_ID, entityId)
                .routeParam(PROJECT_NAME, project).routeParam(DOMAIN_NAME, domain).asString();
    }

    /**
     * checkin entity object so that it can be found during test
     * used when versionning is enabled
     * @param entityType
     * @param entityId
     * @throws UnirestException
     */
    private void checkinEntity(String entityType, String entityId) throws UnirestException {
        Unirest.post(
                serverUrl + "/rest/domains/{domain}/projects/{project}/{entityType}s/{entityId}/versions/check-in")
                .routeParam(ENTITY_TYPE, entityType).routeParam(ENTITY_ID, entityId)
                .routeParam(PROJECT_NAME, project).routeParam(DOMAIN_NAME, domain).asString();
    }

    /**
     * @param fieldMap
     *            Map consisting of values to be sent to the web service (key,
     *            value)
     * @return Entity object based on the given input values
     */
    private Entity buildTestRunResultEntity(Map<String, String> fieldMap, String entityType) {
        Entity entity = new Entity();
        Entity.Fields fields = new Entity.Fields();

        Iterator<Entry<String, String>> headersIterator = fieldMap.entrySet().iterator();
        while (headersIterator.hasNext()) {
            Entry<String, String> header = headersIterator.next();
            Entity.Fields.Field field = new Entity.Fields.Field();
            field.setName(header.getKey());
            field.addValue(header.getValue());
            fields.addField(field);
        }

        entity.setFields(fields);
        entity.setType(entityType);
        return entity;
    }

    public String getCurrentRunId() {
        return currentRunId;
    }

}