/******************************************************************************* * Copyright (c) 2016 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ package com.ibm.team.build.internal.hjplugin; import hudson.AbortException; import hudson.model.TaskListener; import hudson.remoting.RemoteOutputStream; import hudson.remoting.VirtualChannel; import hudson.util.Secret; import java.io.File; import java.io.IOException; import java.io.OutputStream; import java.io.PrintWriter; import java.lang.reflect.InvocationTargetException; import java.util.Locale; import java.util.Map; import java.util.logging.Logger; import com.ibm.team.build.internal.hjplugin.RTCFacadeFactory.RTCFacadeWrapper; /** * Class responsible for Accepting incoming changes * */ public class RTCAcceptTask extends RTCTask<Map<String, Object>> { private static final Logger LOGGER = Logger.getLogger(RTCAcceptTask.class.getName()); private String buildToolkit; private String serverURI; private String userId; private Secret password; private int timeout; private String processArea; private String buildWorkspace; private String buildResultUUID; private Map<String, String> buildSnapshotContextMap; private String buildSnapshot; private String buildStream; private TaskListener listener; private boolean isCustomSnapshotName; private String snapshotName; private String previousSnapshotUUID; private RemoteOutputStream changeLog; private boolean isRemote; private String contextStr; private boolean debug; private Locale clientLocale; private String callConnectorTimeout; private boolean acceptBeforeLoad; // The relative url of the previous build from which the previous snapshot uuid was obtained private String previousBuildUrl; private String temporaryWorkspaceComment; /** * Back links to Hudson/Jenkins that are to be set on the build result */ private String root; private String projectUrl; private String buildUrl; private static final long serialVersionUID = 1L; /** * Task that performs accept work on the master or the slave * * @param contextStr Context for logging * @param buildToolkit The build toolkit to use when working with the facade * @param serverURI The address of the repository server * @param userId The user id to use when logging into the server * @param password The password to use when logging into the server. * @param timeout The timeout period for requests made to the server * @param processArea The name of the project or team area * @param buildDefinition The name (id) of the build definition to use. May be <code>null</code> if buildWorkspace * is supplied instead. * @param buildWorkspace The name of the RTC build workspace. May be <code>null</code> if buildDefinition is * supplied instead. * @param buildSnapshotContextMap Name-Value pair representing the snapshot owner details. May be <code>null</code> * @param buildStream The name of the RTC build stream. May be <code>null</code> if buildWorkspace or * buildDefinition is supplied instead. * @param buildResultUUID The build result to relate build results with. * @param isCustomSnapshotName Indicates if a custom snapshot name is configured in the Job * @param snapshotName The name to set on the snapshot created during accept * @param previousSnapshotUUID The uuid of the previous snapshot. Used for generating changelog in build stream * case. May be <code>null</code> if a buildResultUUID or buildWorkspace is supplied. * @param listener A listener that will be notified of the progress and errors encountered. * @param changeLog Output stream to hold the Change log results. May be <code>null</code>. * @param isRemote Whether this will be executed on the Master or a slave * @param debug Whether to report debugging messages to the listener * @param clientLocale The locale of the requesting client * @param acceptBeforeLoad Accept latest changes before loading, if true * @param previousBuildUrl * @param temporaryWorkspaceComment */ public RTCAcceptTask(String contextStr, String buildToolkit, String serverURI, String userId, String password, int timeout, String processArea, String buildResultUUID, String buildWorkspace, Map<String, String> buildSnapshotContextMap, String buildSnapshot, String buildStream, boolean isCustomSnapshotName, String snapshotName, String previousSnapshotUUID, TaskListener listener, RemoteOutputStream changeLog, boolean isRemote, boolean debug, Locale clientLocale, String strCallConnectorTimeout, boolean acceptBeforeLoad, String previousBuildUrl, String temporaryWorkspaceComment) { super(debug, listener); this.contextStr = contextStr; this.buildToolkit = buildToolkit; this.serverURI = serverURI; this.userId = userId; this.password = Secret.fromString(password); this.timeout = timeout; this.processArea = processArea; this.buildWorkspace = buildWorkspace; this.buildResultUUID = buildResultUUID; this.buildSnapshotContextMap = buildSnapshotContextMap; this.buildSnapshot = buildSnapshot; this.buildStream = buildStream; this.isCustomSnapshotName = isCustomSnapshotName; this.snapshotName = snapshotName; this.previousSnapshotUUID = previousSnapshotUUID; this.listener = listener; this.changeLog = changeLog; this.isRemote = isRemote; this.debug = debug; this.clientLocale = clientLocale; this.callConnectorTimeout = strCallConnectorTimeout; this.acceptBeforeLoad = acceptBeforeLoad; this.previousBuildUrl = previousBuildUrl; this.temporaryWorkspaceComment = temporaryWorkspaceComment; } /** * Provides the Urls to be set as links on the build result * @param rootUrl The root url of the H/J server * @param projectUrl The relative link to the H/J project * @param buildUrl The relative link to the H/J build */ public void setLinkURLs(String rootUrl, String projectUrl, String buildUrl) { this.root = rootUrl; this.projectUrl = projectUrl; this.buildUrl = buildUrl; } public Map<String, Object> invoke(File workspace, VirtualChannel channel) throws IOException, InterruptedException { if (debug) { debug("Running " + contextStr); //$NON-NLS-1$ debug("serverURI " + serverURI); //$NON-NLS-1$ debug("userId " + userId); //$NON-NLS-1$ debug("timeout " + timeout); //$NON-NLS-1$ debug("processArea " + processArea); //$//$NON-NLS-1$ debug("buildWorkspace " + (buildWorkspace == null ? "n/a" : buildWorkspace)); //$NON-NLS-1$ //$NON-NLS-2$ debug("buildResult " + (buildResultUUID == null ? "n/a" : "defined")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ debug("buildStream " + (buildStream == null ? "n/a" : buildStream)); //$NON-NLS-1$ //$NON-NLS-2$ debug("buildSnapshot " + (buildSnapshot == null ? "n/a" : buildSnapshot)); //$NON-NLS-1$ //$NON-NLS-2$ debug("previousSnapshotUUID" + (previousSnapshotUUID == null ? "n/a" : previousSnapshotUUID)); //$NON-NLS-1$ //$NON-NLS-2$ debug("listener is " + (listener == null ? "null" : "not null")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ debug("Running remote " + isRemote); //$NON-NLS-1$ debug("buildToolkit property " + buildToolkit); //$NON-NLS-1$ debug("prevBuildUrl" + ((previousBuildUrl != null)? previousBuildUrl :"No Url Provided")); //$NON-NLS-1$ //$NON-NLS-2$ debug("temporaryWorkspacComment"+ temporaryWorkspaceComment); //$NON-NLS-1$ } try { RTCFacadeWrapper facade = RTCFacadeFactory.getFacade(buildToolkit, debug ? listener.getLogger() : null); if (debug) { debug("hjplugin-rtc.jar " + RTCFacadeFactory.getFacadeJarURL(listener.getLogger()).toString()); //$NON-NLS-1$ } if (buildResultUUID != null) { try { facade.invoke( "createBuildLinks", new Class[] { //$NON-NLS-1$ String.class, // serverURI, String.class, // userId, String.class, // password, int.class, // timeout, String.class, // buildResultUUID String.class, // rootUrl String.class, // projectUrl String.class, // buildUrl Object.class, // listener) }, serverURI, userId, Secret.toString(password), timeout, buildResultUUID, root, projectUrl, buildUrl, listener); } catch (Exception e) { // failure to create links is not a reason to abort the build unless cancelled Throwable eToReport = e; if (e instanceof InvocationTargetException) { eToReport = e.getCause(); } if (eToReport instanceof InterruptedException) { if (debug) { debug("build link creation interrupted " + eToReport.getMessage(), eToReport); //$NON-NLS-1$ } throw (InterruptedException) eToReport; } listener.getLogger().println(Messages.RTCScm_link_creation_failure(e.getMessage())); if (debug) { debug("Failed to create build links", eToReport); //$NON-NLS-1$ } } } return (Map<String, Object>) facade.invoke("accept", new Class[] { //$NON-NLS-1$ String.class, // serverURI, String.class, // userId, String.class, // password, int.class, // timeout, String.class, //processArea, String.class, // buildResultUUID, String.class, // buildWorkspace, Map.class, // buildSnapshotContext String.class, // buildSnapshot, String.class, // buildStream, String.class, // hjWorkspacePath, OutputStream.class, // changeLog, boolean.class, // isCustomSnapshotName String.class, // snapshotName, String.class, // previousSnapshotUUID Object.class, // listener Locale.class, // clientLocale String.class, // callConnectorTimeout boolean.class, // acceptBeforeLoad String.class, // previousBuildUrl String.class // temporaryWorkspaceComment }, serverURI, userId, Secret.toString(password), timeout, processArea, buildResultUUID, buildWorkspace, buildSnapshotContextMap, buildSnapshot, buildStream, workspace.getAbsolutePath(), changeLog, isCustomSnapshotName, snapshotName, previousSnapshotUUID, listener, clientLocale, callConnectorTimeout, acceptBeforeLoad, previousBuildUrl, temporaryWorkspaceComment); } catch (Exception e) { Throwable eToReport = e; if (eToReport instanceof InvocationTargetException && e.getCause() != null) { eToReport = e.getCause(); } if (eToReport instanceof InterruptedException) { listener.getLogger().println(Messages.RTCScm_checkout_failure3(eToReport.getMessage())); throw (InterruptedException) eToReport; } PrintWriter writer = listener.fatalError(Messages.RTCScm_checkout_failure(eToReport.getMessage())); if (RTCScm.unexpectedFailure(eToReport)) { eToReport.printStackTrace(writer); } // if we can't check out then we can't build it throw new AbortException(Messages.RTCScm_checkout_failure2(eToReport.getMessage())); } } @Override protected Logger getLogger() { return LOGGER; } }