org.apache.tomee.RemoteTomEEEJBContainer Maven / Gradle / Ivy
/**
*
* 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 org.apache.tomee;
import org.apache.geronimo.osgi.locator.ProviderLocator;
import org.apache.openejb.OpenEJBException;
import org.apache.openejb.assembler.Deployer;
import org.apache.openejb.assembler.DeployerEjb;
import org.apache.openejb.client.EjbObjectInputStream;
import org.apache.openejb.client.RemoteInitialContextFactory;
import org.apache.openejb.config.RemoteServer;
import org.apache.openejb.loader.IO;
import org.apache.tomee.util.QuickServerXmlParser;
import javax.ejb.EJBException;
import javax.ejb.embeddable.EJBContainer;
import javax.ejb.spi.EJBContainerProvider;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.validation.ValidationException;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import static java.lang.Thread.sleep;
public class RemoteTomEEEJBContainer extends EJBContainer {
private static RemoteTomEEEJBContainer instance;
private RemoteServer container;
private InitialContext context;
@Override
public void close() {
instance.container.destroy();
instance.container = null;
}
@Override
public Context getContext() {
return context;
}
public static class Provider implements EJBContainerProvider {
private static final List CONTAINER_NAMES = Arrays.asList(RemoteTomEEEJBContainer.class.getName(), "tomee-remote", "remote-tomee");
@Override
public EJBContainer createEJBContainer(final Map, ?> rawProperties) {
final Map, ?> properties = rawProperties == null ? new HashMap<>() : rawProperties;
final Object provider = properties.get(EJBContainer.PROVIDER);
int ejbContainerProviders = 1;
try {
ejbContainerProviders = ProviderLocator.getServices(EJBContainerProvider.class.getName(), EJBContainer.class, Thread.currentThread().getContextClassLoader()).size();
} catch (final Exception e) {
// no-op
}
if ((provider == null && ejbContainerProviders > 1)
|| (!RemoteTomEEEJBContainer.class.equals(provider)
&& !CONTAINER_NAMES.contains(String.valueOf(provider)))) {
return null;
}
if (instance != null) {
return instance;
}
final Object modules = properties.get(EJBContainer.MODULES);
System.getProperties().putAll(properties);
final File home = new File(System.getProperty("openejb.home", "doesn't exist"));
if (!home.exists()) {
throw new IllegalArgumentException("You need to set openejb.home");
}
final QuickServerXmlParser parser = QuickServerXmlParser.parse(new File(home, "conf/server.xml"));
final String remoteEjb = System.getProperty(Context.PROVIDER_URL, "http://" + parser.host() + ":" + parser.http() + "/tomee/ejb");
System.setProperty(RemoteServer.SERVER_SHUTDOWN_PORT, parser.stop());
final String blacklist = System.getProperty("tomee.serialization.class.blacklist");
if (blacklist == null) {
System.setProperty("tomee.serialization.class.blacklist", "-");
EjbObjectInputStream.reloadResolverConfig();
}
try {
instance = new RemoteTomEEEJBContainer();
instance.container = new RemoteServer();
instance.container.setDebug("true".equalsIgnoreCase(String.valueOf(properties.get("debug"))));
instance.container.setPortStartup(Integer.parseInt(parser.http()));
try {
instance.container.start(Arrays.asList(
"-Dtomee.serialization.class.blacklist=" + System.getProperty("tomee.serialization.class.blacklist"),
"-Dopenejb.system.apps=true", "-Dtomee.remote.support=true"),
"start", true);
} catch (final Exception e) {
instance.container.destroy();
throw e;
}
instance.context = new InitialContext(new Properties() {{
setProperty(Context.INITIAL_CONTEXT_FACTORY, RemoteInitialContextFactory.class.getName());
setProperty(Context.PROVIDER_URL, String.valueOf(properties.containsKey(Context.PROVIDER_URL) ? properties.get(Context.PROVIDER_URL) : remoteEjb));
}});
Deployer deployer = null;
for (int i = 0; i < (properties.containsKey("retries") ? Integer.parseInt(String.class.cast(properties.get("retries"))) : 4); i++) {
try {
deployer = Deployer.class.cast(instance.context.lookup("openejb/DeployerBusinessRemote"));
if (deployer != null) {
break;
}
} catch (final NamingException ne) {
try {
sleep(250);
} catch (final InterruptedException ie) {
Thread.interrupted();
break;
}
}
}
if (deployer == null) {
throw new TomEERemoteEJBContainerException("Can't lookup deployer, eother increse retries or setup it correctly", new IllegalStateException());
}
if (modules instanceof File) {
final File file = File.class.cast(modules);
deployFile(deployer, file);
} else if (modules instanceof String) {
final String path = String.class.cast(modules);
final File file = new File(path);
deployFile(deployer, file);
} else if (modules instanceof String[]) {
for (final String path : (String[]) modules) {
deployFile(deployer, new File(path));
}
} else if (modules instanceof File[]) {
for (final File file : (File[]) modules) {
deployFile(deployer, file);
}
} // else suppose already deployed
return instance;
} catch (final OpenEJBException | MalformedURLException e) {
throw new EJBException(e);
} catch (final ValidationException ve) {
throw ve;
} catch (final Exception e) {
if (e instanceof EJBException) {
throw (EJBException) e;
}
throw new TomEERemoteEJBContainerException("initialization exception", e);
} finally {
if (blacklist == null) {
System.clearProperty("tomee.serialization.class.blacklist");
EjbObjectInputStream.reloadResolverConfig();
}
}
}
}
private static void deployFile(final Deployer deployer, final File file) throws IOException, OpenEJBException {
if ("true".equalsIgnoreCase(System.getProperty(DeployerEjb.OPENEJB_USE_BINARIES, "false"))) {
final Properties props = new Properties();
final byte[] slurpBinaries = IO.slurp(file).getBytes();
props.put(DeployerEjb.OPENEJB_VALUE_BINARIES, slurpBinaries);
props.put(DeployerEjb.OPENEJB_PATH_BINARIES, file.getName());
deployer.deploy(file.getAbsolutePath(), props);
} else {
deployer.deploy(file.getAbsolutePath());
}
}
protected static class TomEERemoteEJBContainerException extends RuntimeException {
protected TomEERemoteEJBContainerException(final String s, final Exception e) {
super(s, e);
}
}
}