public MavenVersion getLatest() { RepoResponse repoResponse = repositoryConnector.makeAllVersionsRequest(lookupParams); LOGGER.debug(repoResponse.responseBody); List<MavenVersion> allVersions = getAllVersions(repoResponse); MavenVersion latest = getLatest(allVersions); if (latest != null) { latest.setArtifactId(lookupParams.getArtifactId()); latest.setGroupId(lookupParams.getGroupId()); LOGGER.info("Latest is " + latest.getRevisionLabel()); setLocationAndTrackBack(latest); } else { LOGGER.warn("getLatest returning null"); } return latest; }
public ProcessOutput execute( JobConsoleLogger console, boolean showConsoleOutput, String workingDir, List<String> command, Map<String, String> envMap) { ProcessBuilder processBuilder = new ProcessBuilder(command); Process process = null; ProcessOutput processOutput = null; long startTime = System.currentTimeMillis(); try { logger.info(String.format("External process '%s' started", command.get(0))); if (workingDir != null) { processBuilder.directory(new File(workingDir)); } processBuilder.redirectErrorStream(true).environment().putAll(envMap); process = processBuilder.start(); if (showConsoleOutput) { LinesInputStream output = new LinesInputStream(process.getInputStream()); console.readOutputOf(output); int returnCode = process.waitFor(); waitUntilEmpty(2000, output, null); processOutput = new ProcessOutput(returnCode, output.getLines(), new ArrayList<String>()); } else { List output = IOUtils.readLines(process.getInputStream()); int returnCode = process.waitFor(); List pendingOutput = IOUtils.readLines(process.getInputStream()); output.addAll(pendingOutput); processOutput = new ProcessOutput(returnCode, output, new ArrayList<String>()); } } catch (Exception e) { throw new RuntimeException(e.getMessage()); } finally { if (process != null) { closeQuietly(process.getInputStream()); closeQuietly(process.getErrorStream()); closeQuietly(process.getOutputStream()); process.destroy(); long estimatedTime = System.currentTimeMillis() - startTime; logger.info( String.format( "External process '%s' returned %d after %dms.", command.get(0), processOutput.getReturnCode(), estimatedTime)); } } return processOutput; }
public void waitUntilEmpty(int timeout, LinesInputStream output, LinesInputStream error) throws InterruptedException { int numOutLines = output.getLines().size(); int numErrLines = error != null ? error.getLines().size() : 0; while (true) { logger.info(String.format("Waiting %dms for stdour/stderr to settle ...", timeout)); Thread.sleep(timeout, 0); int newNumOutLines = output.getLines().size(); int newNumErrLines = error != null ? error.getLines().size() : 0; if (numOutLines == newNumOutLines && newNumErrLines == numErrLines) { logger.info("stdour/stderr no longer changing"); break; } numOutLines = newNumOutLines; numErrLines = newNumErrLines; } }
public class DockerRun2Command extends DockerCommand { private final Logger logger = Logger.getLoggerFor(DockerRun2Command.class); ConfigVars configVars; public DockerRun2Command(JobConsoleLogger console, ConfigVars configVars) throws Exception { super(console, configVars); this.configVars = configVars; } @Override public void run() throws Exception { DockerCreateCommand cmd = new DockerCreateCommand(console, configVars); cmd.run(); if (cmd.isSuccessful()) { // String id = cmd.getProcessOutput().getStdOut().get(0); String id = cmd.getContainerName(); // tmp<.....> logger.info(String.format("We think the container's name is %s", id)); if (!configVars.isEmpty(DockerTask.RUN_PRE_COPY_TO)) { String hostDir = makeHostDir(getAbsoluteWorkingDir(), configVars.getValue(DockerTask.RUN_PRE_COPY_FROM)); logger.info(String.format("Copying FROM %s", hostDir)); new DockerCpCommand( console, configVars, hostDir, id + ":" + configVars.getValue(DockerTask.RUN_PRE_COPY_TO)) .run(); } new DockerStartCommand(console, configVars, id).run(); if (!configVars.isEmpty(DockerTask.RUN_POST_COPY_FROM)) { String hostDir = makeHostDir(getAbsoluteWorkingDir(), configVars.getValue(DockerTask.RUN_POST_COPY_TO)); logger.info(String.format("Copying TO %s", hostDir)); new DockerCpCommand( console, configVars, id + ":" + configVars.getValue(DockerTask.RUN_POST_COPY_FROM), hostDir) .run(); } new DockerRmCommand(console, configVars, id).run(); } } String makeHostDir(String workingDir, String relative) throws Exception { String relativePath = Paths.get(workingDir, relative).normalize().toAbsolutePath().toString(); if (!relativePath.startsWith(workingDir)) { throw new Exception("Trying to escape working directory"); } return relativePath; } }
private List<MavenVersion> getAllVersions(RepoResponse repoResponse) { List<MavenVersion> versions; NexusResponseHandler nexusReponseHandler = new NexusResponseHandler(repoResponse); if (nexusReponseHandler.canHandle()) { versions = nexusReponseHandler.getAllVersions(); } else { LOGGER.warn("Returning empty version list - no XML nor HTML Nexus answer found"); versions = Collections.emptyList(); } return versions; }
private void setLocationAndTrackBack(MavenVersion version) { try { Files files = getFiles(version); version.setLocation(files.getArtifactLocation()); version.setTrackBackUrl(files.getTrackBackUrl()); } catch (Exception ex) { LOGGER.error("Error getting location for " + version.getRevisionLabel(), ex); version.setErrorMessage( "Plugin could not determine location/trackback. Please see plugin log for details."); } }
MavenVersion getLatest(List<MavenVersion> allVersions) { if (allVersions == null || allVersions.isEmpty()) return null; MavenVersion latest = maxSubjectToUpperBound(allVersions); if (latest == null) { LOGGER.info("maxSubjectToUpperBound is null"); return null; } if (lookupParams.isLastVersionKnown()) { LOGGER.info("lastKnownVersion is " + lookupParams.getLastKnownVersion()); MavenVersion lastKnownVersion = new MavenVersion(lookupParams.getLastKnownVersion()); if (noNewerVersion(latest, lastKnownVersion)) { LOGGER.info("no newer version"); return null; } } if (!lookupParams.lowerBoundGiven() || latest.greaterOrEqual(lookupParams.lowerBound())) { return latest; } else { LOGGER.info("latestSubjectToLowerBound is null"); return null; } }
@Override public void run() throws Exception { DockerCreateCommand cmd = new DockerCreateCommand(console, configVars); cmd.run(); if (cmd.isSuccessful()) { // String id = cmd.getProcessOutput().getStdOut().get(0); String id = cmd.getContainerName(); // tmp<.....> logger.info(String.format("We think the container's name is %s", id)); if (!configVars.isEmpty(DockerTask.RUN_PRE_COPY_TO)) { String hostDir = makeHostDir(getAbsoluteWorkingDir(), configVars.getValue(DockerTask.RUN_PRE_COPY_FROM)); logger.info(String.format("Copying FROM %s", hostDir)); new DockerCpCommand( console, configVars, hostDir, id + ":" + configVars.getValue(DockerTask.RUN_PRE_COPY_TO)) .run(); } new DockerStartCommand(console, configVars, id).run(); if (!configVars.isEmpty(DockerTask.RUN_POST_COPY_FROM)) { String hostDir = makeHostDir(getAbsoluteWorkingDir(), configVars.getValue(DockerTask.RUN_POST_COPY_TO)); logger.info(String.format("Copying TO %s", hostDir)); new DockerCpCommand( console, configVars, id + ":" + configVars.getValue(DockerTask.RUN_POST_COPY_FROM), hostDir) .run(); } new DockerRmCommand(console, configVars, id).run(); } }
Files getFiles(MavenVersion version) { RepoResponse repoResponse = repositoryConnector.makeFilesRequest(lookupParams, version.getV_Q()); LOGGER.debug(repoResponse.responseBody); NexusResponseHandler nexusReponseHandler = new NexusResponseHandler(repoResponse); List<String> files; String pomFile = null; if (nexusReponseHandler.canHandle()) { files = nexusReponseHandler.getFilesMatching(lookupParams.getArtifactSelectionPattern()); pomFile = nexusReponseHandler.getPOMurl(); LOGGER.info("pomFile is " + pomFile); } else { LOGGER.warn("Returning empty version list - no XML nor HTML Nexus answer found"); files = Collections.emptyList(); } LOGGER.info("Files: " + files); return files.size() > 0 ? new Files( repositoryConnector.getFilesUrlWithBasicAuth(lookupParams, version.getV_Q()), files.get(0), repositoryConnector.getFilesUrl(lookupParams, version.getV_Q()) + pomFile, lookupParams) : null; }
private GoPluginApiResponse handleTaskView() { int responseCode = DefaultGoApiResponse.SUCCESS_RESPONSE_CODE; HashMap view = new HashMap(); view.put("displayValue", "Curl"); try { view.put( "template", IOUtils.toString(getClass().getResourceAsStream("/views/task.template.html"), "UTF-8")); } catch (Exception e) { responseCode = DefaultGoApiResponse.INTERNAL_ERROR; String errorMessage = "Failed to find template: " + e.getMessage(); view.put("exception", errorMessage); logger.error(errorMessage, e); } return createResponse(responseCode, view); }
@Extension public class CurlTask implements GoPlugin { public static final String URL_PROPERTY = "Url"; public static final String ADDITIONAL_OPTIONS = "AdditionalOptions"; public static final String SECURE_CONNECTION = "yes"; public static final String SECURE_CONNECTION_PROPERTY = "SecureConnection"; public static final String REQUEST_TYPE = "-G"; public static final String REQUEST_PROPERTY = "RequestType"; private Logger logger = Logger.getLoggerFor(CurlTask.class); @Override public void initializeGoApplicationAccessor(GoApplicationAccessor goApplicationAccessor) {} @Override public GoPluginApiResponse handle(GoPluginApiRequest request) throws UnhandledRequestTypeException { if ("configuration".equals(request.requestName())) { return handleGetConfigRequest(); } else if ("validate".equals(request.requestName())) { return handleValidation(request); } else if ("execute".equals(request.requestName())) { return handleTaskExecution(request); } else if ("view".equals(request.requestName())) { return handleTaskView(); } throw new UnhandledRequestTypeException(request.requestName()); } private GoPluginApiResponse handleTaskView() { int responseCode = DefaultGoApiResponse.SUCCESS_RESPONSE_CODE; HashMap view = new HashMap(); view.put("displayValue", "Curl"); try { view.put( "template", IOUtils.toString(getClass().getResourceAsStream("/views/task.template.html"), "UTF-8")); } catch (Exception e) { responseCode = DefaultGoApiResponse.INTERNAL_ERROR; String errorMessage = "Failed to find template: " + e.getMessage(); view.put("exception", errorMessage); logger.error(errorMessage, e); } return createResponse(responseCode, view); } private GoPluginApiResponse handleTaskExecution(GoPluginApiRequest request) { CurlTaskExecutor executor = new CurlTaskExecutor(); Map executionRequest = (Map) new GsonBuilder().create().fromJson(request.requestBody(), Object.class); Map config = (Map) executionRequest.get("config"); Map context = (Map) executionRequest.get("context"); Result result = executor.execute( new Config(config), new Context(context), JobConsoleLogger.getConsoleLogger()); return createResponse(result.responseCode(), result.toMap()); } private GoPluginApiResponse handleValidation(GoPluginApiRequest request) { HashMap validationResult = new HashMap(); int responseCode = DefaultGoPluginApiResponse.SUCCESS_RESPONSE_CODE; Map configMap = (Map) new GsonBuilder().create().fromJson(request.requestBody(), Object.class); HashMap errorMap = new HashMap(); if (!configMap.containsKey(URL_PROPERTY) || ((Map) configMap.get(URL_PROPERTY)).get("value") == null || ((String) ((Map) configMap.get(URL_PROPERTY)).get("value")).trim().isEmpty()) { errorMap.put(URL_PROPERTY, "URL cannot be empty"); } validationResult.put("errors", errorMap); return createResponse(responseCode, validationResult); } private GoPluginApiResponse handleGetConfigRequest() { HashMap config = new HashMap(); HashMap url = new HashMap(); url.put("display-order", "0"); url.put("display-name", "Url"); url.put("required", true); config.put(URL_PROPERTY, url); HashMap secure = new HashMap(); secure.put("default-value", SECURE_CONNECTION); secure.put("display-order", "1"); secure.put("display-name", "Secure Connection"); secure.put("required", false); config.put(SECURE_CONNECTION_PROPERTY, secure); HashMap requestType = new HashMap(); requestType.put("default-value", REQUEST_TYPE); requestType.put("display-order", "2"); requestType.put("display-name", "Request Type"); requestType.put("required", false); config.put(REQUEST_PROPERTY, requestType); HashMap additionalOptions = new HashMap(); additionalOptions.put("display-order", "3"); additionalOptions.put("display-name", "Additional Options"); additionalOptions.put("required", false); config.put(ADDITIONAL_OPTIONS, additionalOptions); return createResponse(DefaultGoPluginApiResponse.SUCCESS_RESPONSE_CODE, config); } private GoPluginApiResponse createResponse(int responseCode, Map body) { final DefaultGoPluginApiResponse response = new DefaultGoPluginApiResponse(responseCode); response.setResponseBody(new GsonBuilder().serializeNulls().create().toJson(body)); return response; } @Override public GoPluginIdentifier pluginIdentifier() { return new GoPluginIdentifier("task", Arrays.asList("1.0")); } }
/** Copied from https://github.com/gocd/go-plugins.git */ public class ProcessRunner { private static final Logger logger = Logger.getLoggerFor(ProcessRunner.class); public ProcessOutput execute( JobConsoleLogger console, boolean showConsoleOutput, String workingDir, List<String> command, Map<String, String> envMap) { ProcessBuilder processBuilder = new ProcessBuilder(command); Process process = null; ProcessOutput processOutput = null; long startTime = System.currentTimeMillis(); try { logger.info(String.format("External process '%s' started", command.get(0))); if (workingDir != null) { processBuilder.directory(new File(workingDir)); } processBuilder.redirectErrorStream(true).environment().putAll(envMap); process = processBuilder.start(); if (showConsoleOutput) { LinesInputStream output = new LinesInputStream(process.getInputStream()); console.readOutputOf(output); int returnCode = process.waitFor(); waitUntilEmpty(2000, output, null); processOutput = new ProcessOutput(returnCode, output.getLines(), new ArrayList<String>()); } else { List output = IOUtils.readLines(process.getInputStream()); int returnCode = process.waitFor(); List pendingOutput = IOUtils.readLines(process.getInputStream()); output.addAll(pendingOutput); processOutput = new ProcessOutput(returnCode, output, new ArrayList<String>()); } } catch (Exception e) { throw new RuntimeException(e.getMessage()); } finally { if (process != null) { closeQuietly(process.getInputStream()); closeQuietly(process.getErrorStream()); closeQuietly(process.getOutputStream()); process.destroy(); long estimatedTime = System.currentTimeMillis() - startTime; logger.info( String.format( "External process '%s' returned %d after %dms.", command.get(0), processOutput.getReturnCode(), estimatedTime)); } } return processOutput; } public void waitUntilEmpty(int timeout, LinesInputStream output, LinesInputStream error) throws InterruptedException { int numOutLines = output.getLines().size(); int numErrLines = error != null ? error.getLines().size() : 0; while (true) { logger.info(String.format("Waiting %dms for stdour/stderr to settle ...", timeout)); Thread.sleep(timeout, 0); int newNumOutLines = output.getLines().size(); int newNumErrLines = error != null ? error.getLines().size() : 0; if (numOutLines == newNumOutLines && newNumErrLines == numErrLines) { logger.info("stdour/stderr no longer changing"); break; } numOutLines = newNumOutLines; numErrLines = newNumErrLines; } } }
public class RepositoryClient { private static final Logger LOGGER = Logger.getLoggerFor(RepositoryClient.class); private RepositoryConnector repositoryConnector = new RepositoryConnector(); private LookupParams lookupParams; public RepositoryClient(LookupParams lookupParams) { this.lookupParams = lookupParams; } public MavenVersion getLatest() { RepoResponse repoResponse = repositoryConnector.makeAllVersionsRequest(lookupParams); LOGGER.debug(repoResponse.responseBody); List<MavenVersion> allVersions = getAllVersions(repoResponse); MavenVersion latest = getLatest(allVersions); if (latest != null) { latest.setArtifactId(lookupParams.getArtifactId()); latest.setGroupId(lookupParams.getGroupId()); LOGGER.info("Latest is " + latest.getRevisionLabel()); setLocationAndTrackBack(latest); } else { LOGGER.warn("getLatest returning null"); } return latest; } private void setLocationAndTrackBack(MavenVersion version) { try { Files files = getFiles(version); version.setLocation(files.getArtifactLocation()); version.setTrackBackUrl(files.getTrackBackUrl()); } catch (Exception ex) { LOGGER.error("Error getting location for " + version.getRevisionLabel(), ex); version.setErrorMessage( "Plugin could not determine location/trackback. Please see plugin log for details."); } } MavenVersion getLatest(List<MavenVersion> allVersions) { if (allVersions == null || allVersions.isEmpty()) return null; MavenVersion latest = maxSubjectToUpperBound(allVersions); if (latest == null) { LOGGER.info("maxSubjectToUpperBound is null"); return null; } if (lookupParams.isLastVersionKnown()) { LOGGER.info("lastKnownVersion is " + lookupParams.getLastKnownVersion()); MavenVersion lastKnownVersion = new MavenVersion(lookupParams.getLastKnownVersion()); if (noNewerVersion(latest, lastKnownVersion)) { LOGGER.info("no newer version"); return null; } } if (!lookupParams.lowerBoundGiven() || latest.greaterOrEqual(lookupParams.lowerBound())) { return latest; } else { LOGGER.info("latestSubjectToLowerBound is null"); return null; } } private MavenVersion maxSubjectToUpperBound(List<MavenVersion> allVersions) { MavenVersion absoluteMax = Collections.max(allVersions); if (!lookupParams.upperBoundGiven()) return absoluteMax; Collections.sort(allVersions); for (int i = 0; i < allVersions.size(); i++) { if (allVersions.get(i).lessThan(lookupParams.getUpperBound()) && i + 1 <= allVersions.size() - 1 && allVersions.get(i + 1).greaterOrEqual(lookupParams.getUpperBound())) return allVersions.get(i); if (allVersions.get(i).lessThan(lookupParams.getUpperBound()) && i + 1 == allVersions.size()) return allVersions.get(i); } return null; } private boolean noNewerVersion(MavenVersion latest, MavenVersion lastKnownVersion) { return latest.notNewerThan(lastKnownVersion); } private List<MavenVersion> getAllVersions(RepoResponse repoResponse) { List<MavenVersion> versions; NexusResponseHandler nexusReponseHandler = new NexusResponseHandler(repoResponse); if (nexusReponseHandler.canHandle()) { versions = nexusReponseHandler.getAllVersions(); } else { LOGGER.warn("Returning empty version list - no XML nor HTML Nexus answer found"); versions = Collections.emptyList(); } return versions; } Files getFiles(MavenVersion version) { RepoResponse repoResponse = repositoryConnector.makeFilesRequest(lookupParams, version.getV_Q()); LOGGER.debug(repoResponse.responseBody); NexusResponseHandler nexusReponseHandler = new NexusResponseHandler(repoResponse); List<String> files; String pomFile = null; if (nexusReponseHandler.canHandle()) { files = nexusReponseHandler.getFilesMatching(lookupParams.getArtifactSelectionPattern()); pomFile = nexusReponseHandler.getPOMurl(); LOGGER.info("pomFile is " + pomFile); } else { LOGGER.warn("Returning empty version list - no XML nor HTML Nexus answer found"); files = Collections.emptyList(); } LOGGER.info("Files: " + files); return files.size() > 0 ? new Files( repositoryConnector.getFilesUrlWithBasicAuth(lookupParams, version.getV_Q()), files.get(0), repositoryConnector.getFilesUrl(lookupParams, version.getV_Q()) + pomFile, lookupParams) : null; } void setRepositoryConnector(RepositoryConnector repositoryConnector) { this.repositoryConnector = repositoryConnector; } }