org.alfresco.maven.plugin.AbstractRefreshWebappMojo Maven / Gradle / Ivy
/**
* Copyright (C) 2017 Alfresco Software Limited.
*
* This file is part of the Alfresco SDK.
*
* 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 org.alfresco.maven.plugin;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.net.telnet.TelnetClient;
import org.apache.http.HttpHost;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.AuthCache;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.impl.auth.BasicScheme;
import org.apache.http.impl.client.BasicAuthCache;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugins.annotations.Component;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.project.MavenProject;
import java.io.Closeable;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
/**
* Abstract Maven Mojo with generic functionality common to
* both the Refresh Repo and Refresh Share Mojos.
*
* @author [email protected]
* @since 2.1.0
*/
public abstract class AbstractRefreshWebappMojo extends AbstractMojo {
@Component
protected MavenProject project;
/**
* The mode for the refresh goal, current supported values are:
* auto - Checks packaging and app.amp.client.war.artifactId to determine if it should refresh for repo or share
* both - Forces it to refresh both for Repo and Share
* share - Forces only to refresh share
* repo - Forces only to refresh repo
* none - Disables refreshing web scripts
*/
@Parameter(property = "maven.alfresco.refresh.mode", defaultValue = "auto")
protected String refreshMode;
/**
* The hostname for where the Alfresco Tomcat server is running.
*/
@Parameter(property = "maven.alfresco.refresh.host", defaultValue = "localhost")
protected String refreshHost;
/**
* The port number for where the Alfresco Tomcat server is running.
*/
@Parameter(property = "maven.alfresco.refresh.port", defaultValue = "${maven.tomcat.port}")
private String refreshPort;
/**
* The username for authenticating against Alfresco Repo.
*/
@Parameter(property = "maven.alfresco.refresh.username", defaultValue = "admin")
private String refreshUsername;
/**
* The password for authenticating against Alfresco Repo.
*/
@Parameter(property = "maven.alfresco.refresh.password", defaultValue = "admin")
protected String refreshPassword;
/**
* The URL to send the POST to when you want to refresh Alfresco Repo Web Scripts container.
*/
@Parameter(property = "maven.alfresco.refresh.repoUrl", defaultValue = "/alfresco/service/index")
protected String refreshRepoUrl;
/**
* The URL to send the POST to when you want to refresh Alfresco Share Spring Surf Web Scripts container.
*/
@Parameter(property = "maven.alfresco.refresh.shareUrl", defaultValue = "/share/page/index")
protected String refreshShareUrl;
/**
* The URL to send the POST to when you want to clear dependency caches for the Alfresco Share webapp.
*/
@Parameter(property = "maven.alfresco.refresh.clearCacheShareUrl", defaultValue = "/share/page/caches/dependency/clear")
protected String clearCacheShareUrl;
/**
* The name of the web application we are refreshing, just for logging purpose
*/
protected String refreshWebappName;
@Parameter(defaultValue = "${app.amp.client.war.artifactId}")
protected String alfrescoClientWar;
/**
* Mojo interface implementation
*/
@Override
public void execute() throws MojoExecutionException {
if (StringUtils.isBlank(this.refreshPort)) {
this.refreshPort = "8080";
}
// Do a ping to see if the server is up, if not, log and just exit
if (!ping()) {
getLog().warn("Connection failed to " + this.refreshHost + ":" + this.refreshPort + ", " + getAbortedMsg());
return;
}
executeRefresh();
}
/**
* To be implemented by webapp "refresh" Mojos
*/
protected abstract void executeRefresh();
protected void _refreshRepo() {
refreshWebappName = "Alfresco Repository";
refreshWebScripts(refreshRepoUrl);
}
protected void _refreshShare() {
refreshWebappName = "Alfresco Share";
refreshWebScripts(refreshShareUrl);
clearDependencyCaches(clearCacheShareUrl);
}
/**
* Perform a Refresh of Web Scripts container in webapp.
* Called by specific refresh mojo implementation.
*
* @param url the relative path to refresh webscripts
*/
protected void refreshWebScripts(String url) {
// Create the Refresh URL for the Alfresco Tomcat server
URL alfrescoTomcatUrl = buildFinalUrl(url);
if (alfrescoTomcatUrl == null) {
getLog().error("Could not build refresh URL for " + refreshWebappName + ", " + getAbortedMsg());
}
// Set up the data we need to POST to the server for the refresh to work
List postData = new ArrayList();
postData.add(new BasicNameValuePair("reset", "on"));
postData.add(new BasicNameValuePair("submit", "Refresh Web Scripts"));
// Do the refresh
makePostCall(alfrescoTomcatUrl, postData, "Refresh Web Scripts");
}
/**
* Perform a Clear Dependency Caches call on Share webapp.
* Called by specific refresh mojo implementation, currently only applicable to Share webapp.
*
* @param url the relative path to clear cache
*/
protected void clearDependencyCaches(String url) {
// Create the Clear Cache URL for the Alfresco Tomcat server
URL alfrescoTomcatUrl = buildFinalUrl(url);
if (alfrescoTomcatUrl == null) {
getLog().error("Could not build clear dependency caches URL for " +
refreshWebappName + ", " + getAbortedMsg());
}
// Do the refresh
makePostCall(alfrescoTomcatUrl, null, "Clear Dependency Caches");
}
/**
* Helper method to make a POST request to the Alfresco Webapp
*
* @param alfrescoTomcatUrl the URL for the webapp we want to post to
* @param postData the POST data that should be sent
* @param operation information about the operation we are performing
*/
private void makePostCall(URL alfrescoTomcatUrl, List postData, String operation) {
CloseableHttpClient client = null;
CloseableHttpResponse response = null;
try {
// Set up a HTTP POST request to the Alfresco Webapp we are targeting
HttpHost targetHost = new HttpHost(
alfrescoTomcatUrl.getHost(), alfrescoTomcatUrl.getPort(), alfrescoTomcatUrl.getProtocol());
// Set up authentication parameters
CredentialsProvider credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials(new AuthScope(targetHost.getHostName(), targetHost.getPort()),
new UsernamePasswordCredentials(refreshUsername, refreshPassword));
// Create the HTTP Client we will use to make the call
client = HttpClients.custom().setDefaultCredentialsProvider(credsProvider).build();
// Create AuthCache instance
AuthCache authCache = new BasicAuthCache();
// Generate BASIC scheme object and add it to the local auth cache
BasicScheme basicAuth = new BasicScheme();
authCache.put(targetHost, basicAuth);
// Add AuthCache to the execution context
HttpClientContext localContext = HttpClientContext.create();
localContext.setAuthCache(authCache);
// Make the call to Refresh the Alfresco Webapp
HttpPost httpPost = new HttpPost(alfrescoTomcatUrl.toURI());
response = client.execute(httpPost);
if (postData != null) {
UrlEncodedFormEntity entity = new UrlEncodedFormEntity(postData, "UTF-8");
httpPost.setEntity(entity);
}
httpPost.setHeader("Accept-Charset", "iso-8859-1,utf-8");
httpPost.setHeader("Accept-Language", "en-us");
response = client.execute(httpPost);
// If no response, no method has been passed
if (response == null) {
getLog().error("POST request failed to " + alfrescoTomcatUrl.toString() + ", " + getAbortedMsg());
return;
}
// Check if we got a successful response or not
int statusCode = response.getStatusLine().getStatusCode();
if (statusCode == HttpStatus.SC_OK) {
getLog().info("Successfull " + operation + " for " + refreshWebappName);
} else {
String reasonPhrase = response.getStatusLine().getReasonPhrase();
getLog().warn("Failed to " + operation + " for " + refreshWebappName + ". Response status: " +
statusCode + ", message: " + reasonPhrase);
}
} catch (Exception ex) {
getLog().error("POST request failed to " + alfrescoTomcatUrl.toString() + ", " + getAbortedMsg());
getLog().error("Exception Msg: " + ex.getMessage());
} finally {
closeQuietly(response);
closeQuietly(client);
}
}
private URL buildFinalUrl(String specificRefreshUrlPath) {
try {
return new URL("http://" + this.refreshHost + ":" + this.refreshPort + specificRefreshUrlPath);
} catch (MalformedURLException e) {
e.printStackTrace();
return null;
}
}
/**
* Utility method to ping/call the Alfresco Tomcat server and see if it is up (running)
*
* @return true if the Alfresco Tomcat server was reachable and up
*/
private boolean ping() {
try {
URL alfrescoTomcatUrl = buildFinalUrl("");
TelnetClient telnetClient = new TelnetClient();
telnetClient.setDefaultTimeout(500);
telnetClient.connect(alfrescoTomcatUrl.getHost(), alfrescoTomcatUrl.getPort());
return true;
} catch (Exception ex) {
return false;
}
}
/**
* Close down communication objects without any messages
*
* @param closeable
*/
private void closeQuietly(Closeable closeable) {
try {
closeable.close();
} catch (Exception ex) {
// swallow any exceptions
}
}
/**
* Helper to get consistent aborted message
* @return
*/
private String getAbortedMsg() {
return refreshWebappName + " webapp refresh aborted";
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy