blob: a2a03e3b8619efa727670b13b40bb71650b3f520 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 catalina.deployer;
import org.apache.catalina.Container;
import org.apache.catalina.Engine;
import org.apache.catalina.Service;
import org.apache.catalina.core.StandardHost;
import org.apache.catalina.core.StandardServer;
import org.apache.catalina.util.ContextName;
import org.apache.openejb.NoSuchApplicationException;
import org.apache.openejb.OpenEJBException;
import org.apache.openejb.UndeployException;
import org.apache.openejb.assembler.Deployer;
import org.apache.openejb.assembler.classic.AppInfo;
import org.apache.openejb.assembler.classic.Assembler;
import org.apache.openejb.assembler.classic.DeploymentExceptionManager;
import org.apache.openejb.assembler.classic.WebAppBuilder;
import org.apache.openejb.loader.IO;
import org.apache.openejb.loader.SystemInstance;
import org.apache.tomcat.util.modeler.Registry;
import org.apache.tomee.catalina.TomEERuntimeException;
import org.apache.tomee.catalina.TomcatWebAppBuilder;
import org.apache.tomee.loader.TomcatHelper;
import javax.ejb.Lock;
import javax.ejb.LockType;
import javax.ejb.Remote;
import javax.ejb.Singleton;
import javax.ejb.TransactionManagement;
import javax.management.MBeanServer;
import javax.management.ObjectName;
import java.io.File;
import java.util.Collection;
import java.util.Properties;
import static javax.ejb.TransactionManagementType.BEAN;
@Lock(LockType.READ)
@Singleton(name = "openejb/WebappDeployer")
@Remote(Deployer.class)
@TransactionManagement(BEAN)
public class WebappDeployer implements Deployer {
private static final String WEBAPPS = "webapps";
private static final String OPENEJB_HOME = "openejb.home";
private final TomcatWebAppBuilder webappBuilder;
private final Assembler assembler;
private final MBeanServer mBeanServer;
public WebappDeployer() {
assembler = (Assembler) SystemInstance.get().getComponent(org.apache.openejb.spi.Assembler.class);
webappBuilder = (TomcatWebAppBuilder) SystemInstance.get().getComponent(WebAppBuilder.class);
mBeanServer = Registry.getRegistry(null, null).getMBeanServer();
}
@Override
public String getUniqueFile() {
throw new TomEERuntimeException("This method is not used");
}
@Override
public Collection<AppInfo> getDeployedApps() {
return assembler.getDeployedApplications();
}
@Override
public AppInfo deploy(final String location) throws OpenEJBException {
return deploy(location, null);
}
@Override
public AppInfo deploy(final Properties properties) throws OpenEJBException {
return deploy(null, properties);
}
@Override
public AppInfo deploy(String location, Properties properties) throws OpenEJBException {
try {
if (location == null && properties == null) {
throw new NullPointerException("location and properties are null");
}
if (location == null) {
location = properties.getProperty(FILENAME);
}
final File source = new File(location);
final File destination = new File(
System.getProperty(OPENEJB_HOME) + File.separator + WEBAPPS + File.separator + source.getName());
IO.copy(source, destination);
String destinationWithoutExtension = destination.getAbsolutePath();
String destinationFilenameWithoutExtension = destination.getName();
if (destination.getName().contains(".")) {
destinationWithoutExtension = destinationWithoutExtension.substring(0, destinationWithoutExtension.lastIndexOf('.'));
destinationFilenameWithoutExtension = destinationFilenameWithoutExtension.substring(0, destinationFilenameWithoutExtension.lastIndexOf('.'));
}
if (destination.getName().toLowerCase().endsWith(".war")) {
checkWebapp(destinationFilenameWithoutExtension);
} else {
check();
}
final AppInfo info = findAppInfo(destination.getAbsolutePath(), destinationWithoutExtension);
if (info == null) {
throw new NullPointerException("appinfo not found");
}
final DeploymentExceptionManager dem = SystemInstance.get().getComponent(DeploymentExceptionManager.class);
if (dem.hasDeploymentFailed()) {
final Exception tre = dem.getLastException();
// we don't need this exception anymore
dem.clearLastException(info);
throw tre;
}
return info;
} catch (Exception e) {
throw new OpenEJBException(e);
}
}
private AppInfo findAppInfo(final String... paths) {
final Collection<AppInfo> deployedApps = getDeployedApps();
for (final AppInfo appInfo : deployedApps) {
for (final String path : paths) {
if (appInfo.path.equals(path)) {
return appInfo;
}
}
}
return null;
}
private void check() {
final StandardServer server = TomcatHelper.getServer();
for (final Service service : server.findServices()) {
if (service.getContainer() instanceof Engine) {
final Engine engine = (Engine) service.getContainer();
for (final Container engineChild : engine.findChildren()) {
if (engineChild instanceof StandardHost) {
final StandardHost host = (StandardHost) engineChild;
webappBuilder.checkHost(host);
}
}
}
}
}
private void checkWebapp(final String webappName) {
try {
final ContextName cn = new ContextName(webappName, true);
final String name = "Catalina:type=Deployer,host=localhost";
final ObjectName oname = new ObjectName(name);
final String[] params = {cn.getName() };
final String[] signature = {"java.lang.String" };
mBeanServer.invoke(oname, "check", params, signature);
} catch (Exception e) {
//Ignore
}
}
@Override
public void undeploy(final String moduleId) throws UndeployException, NoSuchApplicationException {
try {
final AppInfo appInfo = findAppInfo(moduleId);
if (appInfo != null) {
webappBuilder.undeployWebApps(appInfo);
}
assembler.destroyApplication(moduleId);
final File moduleFile = new File(moduleId);
if (moduleFile.getName().contains(".")) {
// delete matching directory
final File dir = new File(moduleFile.getAbsolutePath().substring(0, moduleFile.getAbsolutePath().lastIndexOf('.')));
if (dir.exists() && dir.isDirectory()) {
delete(dir);
}
} else {
delete(new File(moduleFile + ".war"));
delete(new File(moduleFile + ".ear"));
delete(new File(moduleFile + ".rar"));
}
delete(moduleFile);
} catch (Exception e) {
throw new UndeployException(e);
}
}
@Override
public void reload(final String s) {
throw new UnsupportedOperationException();
}
private void delete(final File f) {
if (f == null || (!f.exists())) {
return;
}
if (f.isFile()) {
if(!f.delete()){
f.deleteOnExit();
}
return;
}
if (f.isDirectory()) {
final File[] listFiles = f.listFiles();
if (listFiles != null) {
for (final File file : listFiles) {
if (file.getName().equals(".") || file.getName().equals("..")) continue;
delete(file);
}
}
if(!f.delete()){
f.deleteOnExit();
}
}
}
}