Java tutorial
/* * RHQ Management Platform * Copyright 2013-2014, Red Hat Middleware LLC, and individual contributors * as indicated by the @author tags. See the copyright.txt file in the * distribution for a full listing of individual contributors. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.rhq.maven.plugins; import java.io.File; import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; import org.apache.http.auth.AuthScope; import org.apache.http.auth.UsernamePasswordCredentials; import org.apache.http.client.methods.AbortableHttpRequest; 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.utils.URIBuilder; import org.apache.http.conn.ClientConnectionManager; import org.apache.http.entity.FileEntity; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.impl.conn.BasicClientConnectionManager; import org.apache.http.params.HttpConnectionParams; import org.apache.http.params.HttpParams; import org.apache.http.util.EntityUtils; import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; import org.apache.maven.plugins.annotations.Mojo; import org.apache.maven.plugins.annotations.Parameter; import org.json.JSONException; import org.json.JSONObject; import static java.lang.Boolean.TRUE; import static java.util.concurrent.TimeUnit.SECONDS; import static org.apache.http.HttpHeaders.ACCEPT; import static org.apache.http.entity.ContentType.APPLICATION_JSON; import static org.apache.http.entity.ContentType.APPLICATION_OCTET_STREAM; import static org.apache.maven.plugins.annotations.LifecyclePhase.PACKAGE; import static org.rhq.maven.plugins.Utils.getAgentPluginArchiveFile; /** * Upload a freshly built RHQ Agent Plugin to an RHQ container. * * @author Thomas Segismont */ @Mojo(name = "upload", defaultPhase = PACKAGE, threadSafe = true) public class UploadMojo extends AbstractMojo { private static final String REST_CONTEXT_PATH = "/rest"; private static final String REST_CONTENT_URI = REST_CONTEXT_PATH + "/content"; private static final String REST_CONTENT_UPLOAD_URI = REST_CONTENT_URI + "/fresh"; private static final String REST_PLUGINS_URI = REST_CONTEXT_PATH + "/plugins"; private static final String REST_PLUGINS_DEPLOY_URI = REST_PLUGINS_URI + "/deploy"; /** * The build directory (root of build works). */ @Parameter(defaultValue = "${project.build.directory}", required = true, readonly = true) private File buildDirectory; /** * The name of the generated RHQ agent plugin archive. */ @Parameter(defaultValue = "${project.build.finalName}", required = true, readonly = true) private String finalName; /** * The scheme to use to communicate with the remote RHQ server. */ @Parameter(defaultValue = "http") private String scheme; /** * Remote RHQ server host. */ @Parameter(required = true) private String host; /** * Remote RHQ server port. */ @Parameter(defaultValue = "7080") private int port; /** * Authentication user name. The user must have appropriate permissions (MANAGE_SETTINGS). */ @Parameter(required = true) private String username; /** * Authentication password. */ @Parameter(required = true) private String password; /** * Whether a plugin scan should be triggered on the server after upload. */ @Parameter(defaultValue = "true") private boolean startScan; /** * Whether all agents should update their plugins. <strong>This will make your agents' plugin containers restart * .</strong> */ @Parameter(defaultValue = "false") private boolean updatePluginsOnAllAgents; /** * Whether to wait for the plugins update requests to complete. */ @Parameter(defaultValue = "false") private boolean waitForPluginsUpdateOnAllAgents; /** * How long should we wait for the plugins update requests to complete. In seconds. */ @Parameter(defaultValue = "300") private long maxWaitForPluginsUpdateOnAllAgents; /** * Whether to fail the build if an error occurs while uploading. */ @Parameter(defaultValue = "true") private boolean failOnError; /** * Whether to skip the execution of this mojo. */ @Parameter(defaultValue = "false") private boolean skipUpload; /** * In milliseconds. */ @Parameter(defaultValue = "60000") private int socketConnectionTimeout; /** * In milliseconds. */ @Parameter(defaultValue = "300000") private int socketReadTimeout; @Override public void execute() throws MojoExecutionException, MojoFailureException { if (skipUpload) { getLog().info("Skipped execution"); return; } File agentPluginArchive = getAgentPluginArchiveFile(buildDirectory, finalName); if (!agentPluginArchive.exists() && agentPluginArchive.isFile()) { throw new MojoExecutionException("Agent plugin archive does not exist: " + agentPluginArchive); } // Prepare HttpClient ClientConnectionManager httpConnectionManager = new BasicClientConnectionManager(); DefaultHttpClient httpClient = new DefaultHttpClient(httpConnectionManager); HttpParams httpParams = httpClient.getParams(); HttpConnectionParams.setConnectionTimeout(httpParams, socketConnectionTimeout); HttpConnectionParams.setSoTimeout(httpParams, socketReadTimeout); httpClient.getCredentialsProvider().setCredentials(new AuthScope(host, port), new UsernamePasswordCredentials(username, password)); HttpPost uploadContentRequest = null; HttpPut moveContentToPluginsDirRequest = null; HttpPost pluginScanRequest = null; HttpPost pluginDeployRequest = null; HttpGet pluginDeployCheckCompleteRequest = null; try { // Upload plugin content URI uploadContentUri = buildUploadContentUri(); uploadContentRequest = new HttpPost(uploadContentUri); uploadContentRequest.setEntity(new FileEntity(agentPluginArchive, APPLICATION_OCTET_STREAM)); uploadContentRequest.setHeader(ACCEPT, APPLICATION_JSON.getMimeType()); HttpResponse uploadContentResponse = httpClient.execute(uploadContentRequest); if (uploadContentResponse.getStatusLine().getStatusCode() != HttpStatus.SC_CREATED) { handleProblem(uploadContentResponse.getStatusLine().toString()); return; } getLog().info("Uploaded " + agentPluginArchive); // Read the content handle value in JSON response JSONObject uploadContentResponseJsonObject = new JSONObject( EntityUtils.toString(uploadContentResponse.getEntity())); String contentHandle = (String) uploadContentResponseJsonObject.get("value"); uploadContentRequest.abort(); if (!startScan && !updatePluginsOnAllAgents) { // Request uploaded content to be moved to the plugins directory but do not trigger a plugin scan URI moveContentToPluginsDirUri = buildMoveContentToPluginsDirUri(contentHandle); moveContentToPluginsDirRequest = new HttpPut(moveContentToPluginsDirUri); moveContentToPluginsDirRequest.setHeader(ACCEPT, APPLICATION_JSON.getMimeType()); HttpResponse moveContentToPluginsDirResponse = httpClient.execute(moveContentToPluginsDirRequest); if (moveContentToPluginsDirResponse.getStatusLine().getStatusCode() != HttpStatus.SC_OK) { handleProblem(moveContentToPluginsDirResponse.getStatusLine().toString()); return; } moveContentToPluginsDirRequest.abort(); getLog().info("Moved uploaded content to plugins directory"); return; } // Request uploaded content to be moved to the plugins directory and trigger a plugin scan URI pluginScanUri = buildPluginScanUri(contentHandle); pluginScanRequest = new HttpPost(pluginScanUri); pluginScanRequest.setHeader(ACCEPT, APPLICATION_JSON.getMimeType()); getLog().info("Moving uploaded content to plugins directory and requesting a plugin scan"); HttpResponse pluginScanResponse = httpClient.execute(pluginScanRequest); if (pluginScanResponse.getStatusLine().getStatusCode() != HttpStatus.SC_CREATED // && pluginScanResponse.getStatusLine().getStatusCode() != HttpStatus.SC_OK) { handleProblem(pluginScanResponse.getStatusLine().toString()); return; } pluginScanRequest.abort(); getLog().info("Plugin scan complete"); if (updatePluginsOnAllAgents) { URI pluginDeployUri = buildPluginDeployUri(); pluginDeployRequest = new HttpPost(pluginDeployUri); pluginDeployRequest.setHeader(ACCEPT, APPLICATION_JSON.getMimeType()); getLog().info("Requesting agents to update their plugins"); HttpResponse pluginDeployResponse = httpClient.execute(pluginDeployRequest); if (pluginDeployResponse.getStatusLine().getStatusCode() != HttpStatus.SC_OK) { handleProblem(pluginDeployResponse.getStatusLine().toString()); return; } getLog().info("Plugins update requests sent"); // Read the agent plugins update handle value in JSON response JSONObject pluginDeployResponseJsonObject = new JSONObject( EntityUtils.toString(pluginDeployResponse.getEntity())); String pluginsUpdateHandle = (String) pluginDeployResponseJsonObject.get("value"); pluginDeployRequest.abort(); if (waitForPluginsUpdateOnAllAgents) { getLog().info("Waiting for plugins update requests to complete"); long start = System.currentTimeMillis(); for (;;) { URI pluginDeployCheckCompleteUri = buildPluginDeployCheckCompleteUri(pluginsUpdateHandle); pluginDeployCheckCompleteRequest = new HttpGet(pluginDeployCheckCompleteUri); pluginDeployCheckCompleteRequest.setHeader(ACCEPT, APPLICATION_JSON.getMimeType()); HttpResponse pluginDeployCheckCompleteResponse = httpClient .execute(pluginDeployCheckCompleteRequest); if (pluginDeployCheckCompleteResponse.getStatusLine().getStatusCode() != HttpStatus.SC_OK) { handleProblem(pluginDeployCheckCompleteResponse.getStatusLine().toString()); return; } // Read the agent plugins update handle value in JSON response JSONObject pluginDeployCheckCompleteResponseJsonObject = new JSONObject( EntityUtils.toString(pluginDeployCheckCompleteResponse.getEntity())); Boolean pluginDeployCheckCompleteHandle = (Boolean) pluginDeployCheckCompleteResponseJsonObject .get("value"); pluginDeployCheckCompleteRequest.abort(); if (pluginDeployCheckCompleteHandle == TRUE) { getLog().info("All agents updated their plugins"); return; } if (SECONDS.toMillis( maxWaitForPluginsUpdateOnAllAgents) < (System.currentTimeMillis() - start)) { handleProblem("Not all agents updated their plugins but wait limit has been reached (" + maxWaitForPluginsUpdateOnAllAgents + " ms)"); return; } Thread.sleep(SECONDS.toMillis(5)); getLog().info("Checking plugins update requests status again"); } } } } catch (IOException e) { handleException(e); } catch (JSONException e) { handleException(e); } catch (URISyntaxException e) { handleException(e); } catch (InterruptedException e) { handleException(e); } finally { abortQuietly(uploadContentRequest); abortQuietly(moveContentToPluginsDirRequest); abortQuietly(pluginScanRequest); abortQuietly(pluginDeployRequest); abortQuietly(pluginDeployCheckCompleteRequest); httpConnectionManager.shutdown(); } } private void abortQuietly(AbortableHttpRequest httpRequest) { if (httpRequest != null) { httpRequest.abort(); } } private void handleProblem(String message) throws MojoExecutionException { if (failOnError) { throw new MojoExecutionException(message); } getLog().error(message); } private void handleException(Exception e) throws MojoExecutionException { if (failOnError) { throw new MojoExecutionException(e.getMessage(), e); } getLog().error(e.getMessage(), e); } private URI buildUploadContentUri() throws URISyntaxException { return new URIBuilder() // .setScheme(scheme) // .setHost(host) // .setPort(port) // .setPath(REST_CONTENT_UPLOAD_URI) // .build(); } private URI buildMoveContentToPluginsDirUri(String contentHandle) throws URISyntaxException { return new URIBuilder() // .setScheme(scheme) // .setHost(host) // .setPort(port) // .setPath(REST_CONTENT_URI + "/" + contentHandle + "/plugins") // .setParameter("name", getAgentPluginArchiveFile(buildDirectory, finalName).getName()) // .setParameter("startScan", String.valueOf(false)) // .build(); } private URI buildPluginScanUri(String contentHandle) throws URISyntaxException { return new URIBuilder() // .setScheme(scheme) // .setHost(host) // .setPort(port) // .setPath(REST_PLUGINS_URI) // .setParameter("handle", contentHandle) // .setParameter("name", getAgentPluginArchiveFile(buildDirectory, finalName).getName()) // .build(); } private URI buildPluginDeployUri() throws URISyntaxException { return new URIBuilder() // .setScheme(scheme) // .setHost(host) // .setPort(port) // .setPath(REST_PLUGINS_DEPLOY_URI) // .build(); } private URI buildPluginDeployCheckCompleteUri(String pluginsUpdateHandle) throws URISyntaxException { return new URIBuilder() // .setScheme(scheme) // .setHost(host) // .setPort(port) // .setPath(REST_PLUGINS_DEPLOY_URI + "/" + pluginsUpdateHandle) // .build(); } }