com.microfocus.application.automation.tools.pc.PcClient.java Source code

Java tutorial

Introduction

Here is the source code for com.microfocus.application.automation.tools.pc.PcClient.java

Source

/*
 *
 *  Certain versions of software and/or documents (Material?) accessible here may contain branding from
 *  Hewlett-Packard Company (now HP Inc.) and Hewlett Packard Enterprise Company.  As of September 1, 2017,
 *  the Material is now offered by Micro Focus, a separately owned and operated company.  Any reference to the HP
 *  and Hewlett Packard Enterprise/HPE marks is historical in nature, and the HP and Hewlett Packard Enterprise/HPE
 *  marks are the property of their respective owners.
 * __________________________________________________________________
 * MIT License
 *
 *  Copyright 2012-2018 Micro Focus or one of its affiliates.
 *
 * The only warranties for products and services of Micro Focus and its affiliates
 * and licensors (Micro Focus?) are set forth in the express warranty statements
 * accompanying such products and services. Nothing herein should be construed as
 * constituting an additional warranty. Micro Focus shall not be liable for technical
 * or editorial errors or omissions contained herein.
 * The information contained herein is subject to change without notice.
 * ___________________________________________________________________
 *
 */

/*
*  Implements the main method of loadtest
*
* */

package com.microfocus.application.automation.tools.pc;

import com.cloudbees.plugins.credentials.common.UsernamePasswordCredentials;
import com.microfocus.application.automation.tools.pc.helper.DateFormatter;
import com.microfocus.application.automation.tools.run.PcBuilder;
import hudson.FilePath;

import java.beans.IntrospectionException;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintStream;
import java.nio.file.*;
import java.util.*;

import hudson.console.HyperlinkNote;
import org.apache.commons.io.IOUtils;
import org.apache.http.client.ClientProtocolException;

import com.microfocus.adm.performancecenter.plugins.common.pcentities.*;
import com.microfocus.adm.performancecenter.plugins.common.rest.PcRestProxy;

public class PcClient {

    private PcModel model;
    private PcRestProxy restProxy;
    private boolean loggedIn;
    private PrintStream logger;
    private DateFormatter dateFormatter = new DateFormatter("");

    public PcClient(PcModel pcModel, PrintStream logger) {
        try {
            model = pcModel;
            String credentialsProxyId = model.getCredentialsProxyId(true);
            UsernamePasswordCredentials usernamePCPasswordCredentialsForProxy = PcBuilder
                    .getCredentialsId(credentialsProxyId);
            String proxyOutUser = (usernamePCPasswordCredentialsForProxy == null
                    || model.getProxyOutURL(true).isEmpty()) ? ""
                            : usernamePCPasswordCredentialsForProxy.getUsername();
            String proxyOutPassword = (usernamePCPasswordCredentialsForProxy == null
                    || model.getProxyOutURL(true).isEmpty()) ? ""
                            : usernamePCPasswordCredentialsForProxy.getPassword().getPlainText();
            if (model.getProxyOutURL(true) != null && !model.getProxyOutURL(true).isEmpty()) {
                logger.println(String.format("%s - %s: %s", dateFormatter.getDate(), Messages.UsingProxy(),
                        model.getProxyOutURL(true)));
                if (!proxyOutUser.isEmpty()) {
                    if (model.getCredentialsProxyId().startsWith("$"))
                        logger.println(String.format("%s - %s  %s.", dateFormatter.getDate(),
                                Messages.UsingProxyCredentialsBuildParameters(), proxyOutUser));
                    else
                        logger.println(String.format("%s - %s %s.", dateFormatter.getDate(),
                                Messages.UsingProxyCredentialsConfiguration(), proxyOutUser));
                }
            }
            restProxy = new PcRestProxy(model.isHTTPSProtocol(), model.getPcServerName(true),
                    model.getAlmDomain(true), model.getAlmProject(true), model.getProxyOutURL(true), proxyOutUser,
                    proxyOutPassword);
            this.logger = logger;
        } catch (PcException e) {
            logger.println(String.format("%s - %s", dateFormatter.getDate(), e.getMessage()));
        }

    }

    public <T extends PcRestProxy> PcClient(PcModel pcModel, PrintStream logger, T proxy) {
        model = pcModel;
        restProxy = proxy;
        this.logger = logger;
    }

    public boolean login() {
        try {
            String credentialsId = model.getCredentialsId(true);
            UsernamePasswordCredentials usernamePCPasswordCredentials = PcBuilder.getCredentialsId(credentialsId);
            if (usernamePCPasswordCredentials != null) {
                if (model.getCredentialsId().startsWith("$"))
                    logger.println(String.format("%s - %s", dateFormatter.getDate(),
                            Messages.UsingPCCredentialsBuildParameters()));
                else
                    logger.println(String.format("%s - %s", dateFormatter.getDate(),
                            Messages.UsingPCCredentialsConfiguration()));
                logger.println(String.format("%s - %s\n[PCServer='%s://%s/loadtest', User='%s']",
                        dateFormatter.getDate(), Messages.TryingToLogin(), model.isHTTPSProtocol(),
                        model.getPcServerName(true), usernamePCPasswordCredentials.getUsername()));
                loggedIn = restProxy.authenticate(usernamePCPasswordCredentials.getUsername(),
                        usernamePCPasswordCredentials.getPassword().getPlainText());
            } else {
                logger.println(String.format("%s - %s\n[PCServer='%s://%s/loadtest', User='%s']",
                        dateFormatter.getDate(), Messages.TryingToLogin(), model.isHTTPSProtocol(),
                        model.getPcServerName(true), PcBuilder.usernamePCPasswordCredentials.getUsername()));
                loggedIn = restProxy.authenticate(PcBuilder.usernamePCPasswordCredentials.getUsername(),
                        PcBuilder.usernamePCPasswordCredentials.getPassword().getPlainText());
            }
        } catch (PcException e) {
            logger.println(String.format("%s - %s", dateFormatter.getDate(), e.getMessage()));
        } catch (Exception e) {
            logger.println(String.format("%s - %s", dateFormatter.getDate(), e));
        }
        logger.println(String.format("%s - %s", dateFormatter.getDate(),
                loggedIn ? Messages.LoginSucceeded() : Messages.LoginFailed()));
        return loggedIn;
    }

    public boolean isLoggedIn() {

        return loggedIn;
    }

    public int startRun() throws NumberFormatException, ClientProtocolException, PcException, IOException {

        int testID = Integer.parseInt(model.getTestId(true));
        int testInstance = getCorrectTestInstanceID(testID);
        setCorrectTrendReportID();

        logger.println(String.format(
                "%s - \n" + "%s \n" + "====================\n" + "%s: %s \n" + "%s: %s \n" + "%s: %s \n"
                        + "%s: %s \n" + "%s: %s \n" + "%s: %s \n" + "%s: %s \n" + "====================\n",
                dateFormatter.getDate(), Messages.ExecutingLoadTest(), Messages.Domain(), model.getAlmDomain(true),
                Messages.Project(), model.getAlmProject(true), Messages.TestID(),
                Integer.parseInt(model.getTestId(true)), Messages.TestInstanceID(), testInstance,
                Messages.TimeslotDuration(), model.getTimeslotDuration(), Messages.PostRunAction(),
                model.getPostRunAction().getValue(), Messages.UseVUDS(), model.isVudsMode()));
        PcRunResponse response = null;
        try {
            response = restProxy.startRun(testID, testInstance, model.getTimeslotDuration(),
                    model.getPostRunAction().getValue(), model.isVudsMode());
            logger.println(String.format("%s - %s (TestID: %s, RunID: %s, TimeslotID: %s)", dateFormatter.getDate(),
                    Messages.RunStarted(), response.getTestID(), response.getID(), response.getTimeslotID()));
            return response.getID();
        } catch (NumberFormatException | ClientProtocolException | PcException ex) {
            logger.println(String.format("%s - %s. Error: %s", dateFormatter.getDate(), Messages.StartRunFailed(),
                    ex.getMessage()));
        } catch (IOException ex) {
            logger.println(String.format("%s - %s. IOException Error: %s", dateFormatter.getDate(),
                    Messages.StartRunFailed(), ex.getMessage()));
        }
        if (!("RETRY".equals(model.getRetry()))) {
            return 0;
        } else {
            //counter
            int retryCount = 0;
            //values
            int retryDelay = Integer.parseInt(model.getRetryDelay());
            int retryOccurrences = Integer.parseInt(model.getRetryOccurrences());

            while (retryCount <= retryOccurrences) {
                retryCount++;
                try {
                    if (retryCount <= retryOccurrences) {
                        logger.println(String.format("%s - %s. %s (%s %s). %s: %s.", dateFormatter.getDate(),
                                Messages.StartRunRetryFailed(), Messages.AttemptingStartAgainSoon(), retryDelay,
                                Messages.Minutes(), Messages.AttemptsRemaining(),
                                retryOccurrences - retryCount + 1));
                        Thread.sleep(retryDelay * 60 * 1000);
                    }
                } catch (InterruptedException ex) {
                    logger.println(String.format("%s - wait failed", dateFormatter.getDate()));
                }

                try {
                    response = restProxy.startRun(testID, testInstance, model.getTimeslotDuration(),
                            model.getPostRunAction().getValue(), model.isVudsMode());
                } catch (NumberFormatException | ClientProtocolException | PcException ex) {
                    logger.println(String.format("%s -%s. %s: %s", dateFormatter.getDate(),
                            Messages.StartRunRetryFailed(), Messages.Error(), ex.getMessage()));
                } catch (IOException ex) {
                    logger.println(String.format("%s -%s. %s: %s", dateFormatter.getDate(),
                            Messages.StartRunRetryFailed(), Messages.Error(), ex.getMessage()));
                }
                int ret = 0;
                if (response != null) {
                    try {
                        ret = response.getID();
                    } catch (Exception ex) {
                        logger.println(String.format("%s - %s. %s: %s", dateFormatter.getDate(),
                                Messages.RetrievingIDFailed(), Messages.Error(), ex.getMessage()));
                    }
                }
                if (ret != 0) {
                    logger.println(String.format("%s - %s (TestID: %s, RunID: %s, TimeslotID: %s)\n",
                            dateFormatter.getDate(), Messages.RunStarted(), response.getTestID(), response.getID(),
                            response.getTimeslotID()));
                    return ret;
                }
            }
        }
        return 0;
    }

    private int getCorrectTestInstanceID(int testID) throws IOException, PcException {
        if ("AUTO".equals(model.getAutoTestInstanceID())) {
            try {
                logger.println(
                        String.format("%s - %s.", dateFormatter.getDate(), Messages.SearchingTestInstance()));
                PcTestInstances pcTestInstances = null;
                try {
                    pcTestInstances = restProxy.getTestInstancesByTestId(testID);
                } catch (PcException ex) {
                    logger.println(String.format("%s - getTestInstancesByTestId %s. Error: %s",
                            dateFormatter.getDate(), Messages.Failure(), Messages.Error(), ex.getMessage()));
                }

                int testInstanceID;
                if (pcTestInstances != null && pcTestInstances.getTestInstancesList() != null) {
                    PcTestInstance pcTestInstance = pcTestInstances.getTestInstancesList()
                            .get(pcTestInstances.getTestInstancesList().size() - 1);
                    testInstanceID = pcTestInstance.getInstanceId();
                    logger.println(String.format("%s - %s: %s", dateFormatter.getDate(),
                            Messages.FoundTestInstanceID(), testInstanceID));
                } else {
                    logger.println(
                            String.format("%s - %s", dateFormatter.getDate(), Messages.NotFoundTestInstanceID()));
                    logger.println(String.format("%s - %s", dateFormatter.getDate(),
                            Messages.SearchingAvailableTestSet()));
                    // Get a random TestSet
                    PcTestSets pcTestSets = restProxy.GetAllTestSets();
                    if (pcTestSets != null && pcTestSets.getPcTestSetsList() != null) {
                        PcTestSet pcTestSet = pcTestSets.getPcTestSetsList()
                                .get(pcTestSets.getPcTestSetsList().size() - 1);
                        int testSetID = pcTestSet.getTestSetID();
                        logger.println(String.format("%s - %s (testID: %s, TestSetID: %s)", dateFormatter.getDate(),
                                Messages.CreatingNewTestInstance(), testID, testSetID));
                        testInstanceID = restProxy.createTestInstance(testID, testSetID);
                        logger.println(String.format("%s - %s: %s", dateFormatter.getDate(),
                                Messages.TestInstanceCreatedSuccessfully(), testInstanceID));
                    } else {
                        String msg = Messages.NoTestSetAvailable();
                        logger.println(String.format("%s - %s", dateFormatter.getDate(), msg));
                        throw new PcException(msg);
                    }
                }
                return testInstanceID;
            } catch (Exception e) {
                logger.println(String.format("%s - getCorrectTestInstanceID %s. %s: %s", dateFormatter.getDate(),
                        Messages.Failure(), Messages.Error(), e.getMessage()));
                return Integer.parseInt(null);
            }
        }
        return Integer.parseInt(model.getTestInstanceId(true));
    }

    private void setCorrectTrendReportID() throws IOException, PcException {
        // If the user selected "Use trend report associated with the test" we want the report ID to be the one from the test
        String msg = Messages.NoTrendReportAssociated() + "\n" + Messages.PleaseTurnAutomaticTrendOn() + "\n"
                + Messages.PleaseTurnAutomaticTrendOnAlternative();
        if (("ASSOCIATED").equals(model.getAddRunToTrendReport())
                && model.getPostRunAction() != PostRunAction.DO_NOTHING) {
            PcTest pcTest = restProxy.getTestData(Integer.parseInt(model.getTestId(true)));
            //if the trend report ID is parametrized
            if (!model.getTrendReportId().startsWith("$")) {
                if (pcTest.getTrendReportId() > -1)
                    model.setTrendReportId(String.valueOf(pcTest.getTrendReportId()));
                else {
                    throw new PcException(msg);
                }
            } else {
                try {
                    if (Integer.parseInt(model.getTrendReportId(true)) > -1)
                        model.setTrendReportId(String.valueOf(model.getTrendReportId(true)));
                    else {
                        throw new PcException(msg);
                    }
                } catch (Exception ex) {
                    throw new PcException(msg + System.getProperty("line.separator") + ex);
                }
            }
        }
    }

    public String getTestName() throws IOException, PcException {

        try {
            PcTest pcTest = restProxy.getTestData(Integer.parseInt(model.getTestId(true)));
            return pcTest.getTestName();
        } catch (IOException | PcException ex) {
            logger.println(String.format("%s - getTestData %s (testId : %s)", dateFormatter.getDate(),
                    Messages.Failure(), model.getTestId(true)));
            throw ex;
        }
    }

    public PcRunResponse waitForRunCompletion(int runId)
            throws InterruptedException, ClientProtocolException, PcException, IOException {

        return waitForRunCompletion(runId, 5000);
    }

    public PcRunResponse waitForRunCompletion(int runId, int interval)
            throws InterruptedException, ClientProtocolException, PcException, IOException {
        RunState state = RunState.UNDEFINED;
        switch (model.getPostRunAction()) {
        case DO_NOTHING:
            state = RunState.BEFORE_COLLATING_RESULTS;
            break;
        case COLLATE:
            state = RunState.BEFORE_CREATING_ANALYSIS_DATA;
            break;
        case COLLATE_AND_ANALYZE:
            state = RunState.FINISHED;
            break;
        }
        return waitForRunState(runId, state, interval);
    }

    private PcRunResponse waitForRunState(int runId, RunState completionState, int interval)
            throws InterruptedException, ClientProtocolException, PcException, IOException {

        int counter = 0;
        RunState[] states = { RunState.BEFORE_COLLATING_RESULTS, RunState.BEFORE_CREATING_ANALYSIS_DATA };
        PcRunResponse response = null;
        RunState lastState = RunState.UNDEFINED;
        int threeStrikes = 3;
        do {
            try {

                if (threeStrikes < 3) {
                    logger.println(String.format(
                            "%s - Cannot get response from PC about the state of the Run (ID=%s) %s time(s) consecutively",
                            dateFormatter.getDate(), runId, (3 - threeStrikes)));
                    if (threeStrikes == 0) {
                        logger.println(String.format("%s - %s: %s", dateFormatter.getDate(),
                                Messages.StoppingMonitoringOnRun(), runId));
                        break;
                    }
                    Thread.sleep(2000);
                    login();
                }
                response = restProxy.getRunData(runId);
                RunState currentState = RunState.get(response.getRunState());
                if (lastState.ordinal() < currentState.ordinal()) {
                    lastState = currentState;
                    logger.println(String.format("%s - RunID: %s - State = %s", dateFormatter.getDate(), runId,
                            currentState.value()));
                }

                // In case we are in state before collate or before analyze, we will wait 1 minute for the state to change otherwise we exit
                // because the user probably stopped the run from PC or timeslot has reached the end.
                if (Arrays.asList(states).contains(currentState)) {
                    counter++;
                    Thread.sleep(1000);
                    if (counter > 60) {
                        logger.println(String.format("%s - Run ID: %s  - %s = %s", dateFormatter.getDate(), runId,
                                Messages.StoppedFromPC(), currentState.value()));
                        break;
                    }
                } else {
                    counter = 0;
                    Thread.sleep(interval);
                }
                threeStrikes = 3;
            } catch (InterruptedException | PcException e) {
                threeStrikes--;
            }
        } while (lastState.ordinal() < completionState.ordinal());
        return response;
    }

    public FilePath publishRunReport(int runId, String reportDirectory)
            throws IOException, PcException, InterruptedException {
        PcRunResults runResultsList = restProxy.getRunResults(runId);
        if (runResultsList.getResultsList() != null) {
            for (PcRunResult result : runResultsList.getResultsList()) {
                if (result.getName().equals(PcBuilder.pcReportArchiveName)) {
                    File dir = new File(reportDirectory);
                    dir.mkdirs();
                    String reportArchiveFullPath = dir.getCanonicalPath() + IOUtils.DIR_SEPARATOR
                            + PcBuilder.pcReportArchiveName;
                    logger.println(
                            String.format("%s - %s", dateFormatter.getDate(), Messages.PublishingAnalysisReport()));
                    restProxy.GetRunResultData(runId, result.getID(), reportArchiveFullPath);
                    FilePath fp = new FilePath(new File(reportArchiveFullPath));
                    fp.unzip(fp.getParent());
                    fp.delete();
                    FilePath reportFile = fp.sibling(PcBuilder.pcReportFileName);
                    if (reportFile.exists())
                        return reportFile;
                }
            }
        }
        logger.println(String.format("%s - %s", dateFormatter.getDate(), Messages.FailedToGetRunReport()));
        return null;
    }

    public boolean logout() {
        if (!loggedIn)
            return true;

        boolean logoutSucceeded = false;
        try {
            logoutSucceeded = restProxy.logout();
            loggedIn = !logoutSucceeded;
        } catch (PcException e) {
            logger.println(String.format("%s - %s", dateFormatter.getDate(), e.getMessage()));
        } catch (Exception e) {
            logger.println(e);
        }
        logger.println(String.format("%s - %s", dateFormatter.getDate(),
                logoutSucceeded ? Messages.LogoutSucceeded() : Messages.LogoutFailed()));
        return logoutSucceeded;
    }

    public boolean stopRun(int runId) {
        boolean stopRunSucceeded = false;
        try {
            logger.println(String.format("%s - %s", dateFormatter.getDate(), Messages.StoppingRun()));
            stopRunSucceeded = restProxy.stopRun(runId, "stop");
        } catch (PcException e) {
            logger.println(String.format("%s - %s", dateFormatter.getDate(), e.getMessage()));
        } catch (Exception e) {
            logger.println(String.format("%s - %s", dateFormatter.getDate(), e));
        }
        logger.println(String.format("%s - %s", dateFormatter.getDate(),
                stopRunSucceeded ? Messages.StopRunSucceeded() : Messages.StopRunFailed()));
        return stopRunSucceeded;
    }

    public PcRunEventLog getRunEventLog(int runId) {
        try {
            return restProxy.getRunEventLog(runId);
        } catch (PcException e) {
            logger.println(String.format("%s - %s", dateFormatter.getDate(), e.getMessage()));
        } catch (Exception e) {
            logger.println(String.format("%s - %s", dateFormatter.getDate(), e.getMessage()));
        }
        return null;
    }

    public void addRunToTrendReport(int runId, String trendReportId) {

        TrendReportRequest trRequest = new TrendReportRequest(model.getAlmProject(true), runId, null);
        logger.println(String.format("%s - Adding run: %s to trend report: %s", dateFormatter.getDate(), runId,
                trendReportId));
        try {
            restProxy.updateTrendReport(trendReportId, trRequest);
            logger.println(String.format("%s - %s: %s %s: %s", dateFormatter.getDate(), Messages.PublishingRun(),
                    runId, Messages.OnTrendReport(), trendReportId));
        } catch (PcException e) {
            logger.println(String.format("%s - %s: %s", dateFormatter.getDate(),
                    Messages.FailedToAddRunToTrendReport(), e.getMessage()));
        } catch (IOException e) {
            logger.println(String.format("%s - %s: %s.", dateFormatter.getDate(),
                    Messages.FailedToAddRunToTrendReport(), Messages.ProblemConnectingToPCServer()));
        }
    }

    public void waitForRunToPublishOnTrendReport(int runId, String trendReportId)
            throws PcException, IOException, InterruptedException {

        ArrayList<PcTrendedRun> trendReportMetaDataResultsList;
        boolean publishEnded = false;
        int counterPublishStarted = 0;
        int counterPublishNotStarted = 0;
        boolean resultNotFound = true;

        do {
            trendReportMetaDataResultsList = restProxy.getTrendReportMetaData(trendReportId);

            if (trendReportMetaDataResultsList.isEmpty())
                break;

            for (PcTrendedRun result : trendReportMetaDataResultsList) {
                resultNotFound = result.getRunID() != runId;
                if (resultNotFound)
                    continue;

                if (result.getState().equals(PcBuilder.TRENDED) || result.getState().equals(PcBuilder.ERROR)) {
                    publishEnded = true;
                    logger.println(String.format("%s - Run: %s %s: %s", dateFormatter.getDate(), runId,
                            Messages.PublishingStatus(), result.getState()));
                    break;
                } else {
                    Thread.sleep(5000);
                    counterPublishStarted++;
                    if (counterPublishStarted >= 120) {
                        String msg = String.format("%s: %s", Messages.Error(), Messages.PublishingEndTimeout());
                        throw new PcException(msg);
                    }
                }
            }
            if (!publishEnded && resultNotFound) {
                Thread.sleep(5000);
                counterPublishNotStarted++;
                if (counterPublishNotStarted >= 120) { //waiting 10 minutes for timeout
                    String msg = String.format("%s", Messages.PublishingStartTimeout());
                    throw new PcException(msg);
                } else if (counterPublishNotStarted % 12 == 0) { //warning every minute until timeout
                    logger.println(String.format("%s - %s. %s: %s ... ", dateFormatter.getDate(),
                            Messages.WaitingForTrendReportToStart(), Messages.MinutesUntilTimeout(),
                            10 - (counterPublishNotStarted / 12)));
                }
            }
        } while (!publishEnded && counterPublishStarted < 120 && counterPublishNotStarted < 120);
    }

    public boolean downloadTrendReportAsPdf(String trendReportId, String directory) throws PcException {

        try {
            logger.println(String.format("%s - %s: %s %s", dateFormatter.getDate(),
                    Messages.DownloadingTrendReport(), trendReportId, Messages.InPDFFormat()));
            InputStream in = restProxy.getTrendingPDF(trendReportId);
            File dir = new File(directory);
            if (!dir.exists()) {
                dir.mkdirs();
            }
            String filePath = directory + IOUtils.DIR_SEPARATOR + "trendReport" + trendReportId + ".pdf";
            Path destination = Paths.get(filePath);
            Files.copy(in, destination, StandardCopyOption.REPLACE_EXISTING);
            logger.println(String.format("%s - %s: %s %s", dateFormatter.getDate(), Messages.TrendReport(),
                    trendReportId, Messages.SuccessfullyDownloaded()));
        } catch (Exception e) {

            logger.println(String.format("%s - %s: %s", dateFormatter.getDate(),
                    Messages.FailedToDownloadTrendReport(), e.getMessage()));
            throw new PcException(e.getMessage());
        }

        return true;

    }

    public void publishTrendReport(String filePath, String trendReportId) {

        if (filePath == null) {
            return;
        }
        //     return String.format( HyperlinkNote.encodeTo(filePath, "View trend report " + trendReportId));
        logger.println(String.format("%s - %s", dateFormatter.getDate(),
                HyperlinkNote.encodeTo(filePath, Messages.ViewTrendReport() + " " + trendReportId)));

    }

    // This method will return a map with the following structure: <transaction_name:selected_measurement_value>
    // for example:
    // <Action_Transaction:0.001>
    // <Virtual transaction 2:0.51>
    // This function uses reflection since we know only at runtime which transactions data will be reposed from the rest request.
    public Map<String, String> getTrendReportByXML(String trendReportId, int runId,
            TrendReportTypes.DataType dataType, TrendReportTypes.PctType pctType,
            TrendReportTypes.Measurement measurement)
            throws IOException, PcException, IntrospectionException, NoSuchMethodException {

        Map<String, String> measurmentsMap = new LinkedHashMap<String, String>();
        measurmentsMap.put("RunId", "_" + runId + "_");
        measurmentsMap.put("Trend Measurement Type", measurement.toString() + "_" + pctType.toString());

        TrendReportTransactionDataRoot res = restProxy.getTrendReportByXML(trendReportId, runId);

        //            java.lang.reflect.Method rootMethod =  res.getClass().getMethod("getTrendReport" + dataType.toString() + "DataRowsList");
        //            ArrayList<Object> RowsListObj = (ArrayList<Object>) rootMethod.invoke(res);
        //            RowsListObj.get(0);

        List<Object> RowsListObj = res.getTrendReportRoot();

        for (int i = 0; i < RowsListObj.size(); i++) {
            try {

                java.lang.reflect.Method rowListMethod = RowsListObj.get(i).getClass()
                        .getMethod("getTrendReport" + dataType.toString() + "DataRowList");

                for (Object DataRowObj : (ArrayList<Object>) rowListMethod.invoke(RowsListObj.get(i))) {
                    if (DataRowObj.getClass().getMethod("getPCT_TYPE").invoke(DataRowObj)
                            .equals(pctType.toString())) {
                        java.lang.reflect.Method method;
                        method = DataRowObj.getClass().getMethod("get" + measurement.toString());
                        measurmentsMap.put(
                                DataRowObj.getClass().getMethod("getPCT_NAME").invoke(DataRowObj).toString(),
                                method.invoke(DataRowObj) == null ? "" : method.invoke(DataRowObj).toString());
                    }
                }
            } catch (NoSuchMethodException e) {
                //  logger.println("No such method exception: " + e);
            } catch (Exception e) {
                logger.println(String.format("%s - Error on getTrendReportByXML: %s ", dateFormatter.getDate(), e));
            }
        }

        //  logger.print(res);

        return measurmentsMap;

    }

}