blob: eacbce0ae01ee2073b95a476a50cb536edf2eae3 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2008, 2011 VMware Inc.
* 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:
* VMware Inc. - initial contribution
*******************************************************************************/
package org.eclipse.virgo.management.console;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.lang.management.ManagementFactory;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import javax.management.MBeanServer;
import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;
import javax.management.openmbean.CompositeDataSupport;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.osgi.framework.BundleContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
*
*
*/
public class UploadServlet extends HttpServlet {
private static final String[] DEPLOYMENT_IDENTITY_FIELDS = new String[]{"type", "symbolicName", "version"};
private static final int HTTP_RESPONSE_INTERNAL_SERVER_ERROR = 500;
private static final String ORG_ECLIPSE_VIRGO_KERNEL_HOME = "org.eclipse.virgo.kernel.home";
private static final String DEPLOYER_MBEAN_NAME = "org.eclipse.virgo.kernel:category=Control,type=Deployer";
private static final long serialVersionUID = 1L;
private static final String STAGING_DIR = "/work/org.eclipse.virgo.apps.admin.web.UploadServlet";
private static final Logger log = LoggerFactory.getLogger(UploadServlet.class);
private MBeanServer mBeanServer = ManagementFactory.getPlatformMBeanServer();
private String serverHome = null;
private BundleContext bundleContext = null;
public UploadServlet() {
}
public UploadServlet(BundleContext bundleContext) {
this.bundleContext = bundleContext;
}
/**
* Do not use this method with the HTTPService unless the BundleContext has already been set.
*/
public void init(ServletConfig config) throws ServletException {
super.init(config);
if(bundleContext == null){
this.bundleContext = (BundleContext) config.getServletContext().getAttribute("osgi-bundlecontext");
}
this.serverHome = this.bundleContext.getProperty(ORG_ECLIPSE_VIRGO_KERNEL_HOME);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {
try {
File stagingDir = createStagingDirectory();
FileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload upload = new ServletFileUpload(factory);
response.setContentType("text/html");
List<FileItem> items = (List<FileItem>) upload.parseRequest(request);
List<File> uploadedFiles = new ArrayList<File>();
for (FileItem fileItem : items) {
File uploadedFile = this.doUpload(fileItem, stagingDir);
if(uploadedFile != null){
uploadedFiles.add(uploadedFile);
}
}
doDeployment(uploadedFiles, response);
} catch (IllegalArgumentException ea){
PrintWriter writer = response.getWriter();
writer.append("<ol id=\"uploadResults\"><li>File name contains '/' or '\\', this is not allowed.</ol>");
writer.close();
} catch (Exception e) {
log.error(e.toString());
response.sendError(HTTP_RESPONSE_INTERNAL_SERVER_ERROR, e.toString());
}
}
File doUpload(FileItem fileItem, File stagingDir) throws Exception{
if (!fileItem.isFormField()) {
String name = fileItem.getName();
if(name != null && name.length() > 0){
if(name.contains("\\") || name.contains("/")){
throw new IllegalArgumentException("Security violation, file name contains '/' or '\\'");
}
File uploadedFile = new File(stagingDir, name);
fileItem.write(uploadedFile);
log.info(String.format("Uploaded artifact of size (%db) to %s", fileItem.getSize(), uploadedFile.getPath()));
return uploadedFile;
}
}
return null;
}
private void doDeployment(List<File> uploadedFiles, HttpServletResponse response) throws MalformedObjectNameException, NullPointerException, IOException{
ObjectName objectName = new ObjectName(DEPLOYER_MBEAN_NAME);
PrintWriter writer = response.getWriter();
writer.append("<ol id=\"uploadResults\">");
for (File file : uploadedFiles) {
URI uri = file.toURI();
try {
Object invoke = this.mBeanServer.invoke(objectName, "deploy", new Object[]{uri.toString()}, new String[]{String.class.getName()});
writer.append("<li>" + file.getName() + " deployed as " + getDeploymentIdentity(invoke) + "</li>");
} catch (Exception e) {
writer.append("<li>" + file.getName() + " failed to deploy '" + e.getMessage() + "'</li>");
}
writer.append("<li />");
}
writer.append("</ol>");
writer.close();
}
private String getDeploymentIdentity(Object deploymentIdentity) {
StringBuilder builder = new StringBuilder();
if(deploymentIdentity instanceof CompositeDataSupport){
CompositeDataSupport deploymentIdentityInstance = (CompositeDataSupport) deploymentIdentity;
Object[] all = deploymentIdentityInstance.getAll(DEPLOYMENT_IDENTITY_FIELDS);
builder.append(all[0]);
builder.append(" - ").append(all[1]);
builder.append(": ").append(all[2]);
}
return builder.toString();
}
private File createStagingDirectory() throws IOException {
File pathReference = new File(String.format("%s%s", this.serverHome, STAGING_DIR));
if (!pathReference.exists()) {
if (!pathReference.mkdirs()) {
throw new IOException("Unable to create directory " + pathReference.getAbsolutePath());
}
}
return pathReference.getAbsoluteFile();
}
}