Author: rmannibucau
Date: Mon Jul 8 21:48:58 2013
New Revision: 1500981
URL: http://svn.apache.org/r1500981
Log:
TOMEE-1000 openejb-hessian module
Added:
tomee/tomee/trunk/server/openejb-hessian/
tomee/tomee/trunk/server/openejb-hessian/pom.xml
tomee/tomee/trunk/server/openejb-hessian/src/
tomee/tomee/trunk/server/openejb-hessian/src/main/
tomee/tomee/trunk/server/openejb-hessian/src/main/java/
tomee/tomee/trunk/server/openejb-hessian/src/main/java/org/
tomee/tomee/trunk/server/openejb-hessian/src/main/java/org/apache/
tomee/tomee/trunk/server/openejb-hessian/src/main/java/org/apache/openejb/
tomee/tomee/trunk/server/openejb-hessian/src/main/java/org/apache/openejb/server/
tomee/tomee/trunk/server/openejb-hessian/src/main/java/org/apache/openejb/server/hessian/
tomee/tomee/trunk/server/openejb-hessian/src/main/java/org/apache/openejb/server/hessian/HessianRegistry.java
tomee/tomee/trunk/server/openejb-hessian/src/main/java/org/apache/openejb/server/hessian/HessianRegistryImpl.java
tomee/tomee/trunk/server/openejb-hessian/src/main/java/org/apache/openejb/server/hessian/HessianServer.java
tomee/tomee/trunk/server/openejb-hessian/src/main/java/org/apache/openejb/server/hessian/HessianService.java
tomee/tomee/trunk/server/openejb-hessian/src/main/java/org/apache/openejb/server/hessian/OpenEJBHessianServlet.java
tomee/tomee/trunk/server/openejb-hessian/src/main/java/org/apache/openejb/server/hessian/TomcatHessianRegistry.java
tomee/tomee/trunk/server/openejb-hessian/src/main/resources/
tomee/tomee/trunk/server/openejb-hessian/src/main/resources/META-INF/
tomee/tomee/trunk/server/openejb-hessian/src/main/resources/META-INF/org.apache.openejb.server.ServerService/
tomee/tomee/trunk/server/openejb-hessian/src/main/resources/META-INF/org.apache.openejb.server.ServerService/hessian
tomee/tomee/trunk/server/openejb-hessian/src/test/
tomee/tomee/trunk/server/openejb-hessian/src/test/java/
tomee/tomee/trunk/server/openejb-hessian/src/test/java/org/
tomee/tomee/trunk/server/openejb-hessian/src/test/java/org/apache/
tomee/tomee/trunk/server/openejb-hessian/src/test/java/org/apache/openejb/
tomee/tomee/trunk/server/openejb-hessian/src/test/java/org/apache/openejb/server/
tomee/tomee/trunk/server/openejb-hessian/src/test/java/org/apache/openejb/server/hessian/
tomee/tomee/trunk/server/openejb-hessian/src/test/java/org/apache/openejb/server/hessian/HessianServiceTest.java
Modified:
tomee/tomee/trunk/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/HttpListenerRegistry.java
tomee/tomee/trunk/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/OpenEJBHttpRegistry.java
tomee/tomee/trunk/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/util/HttpUtil.java
tomee/tomee/trunk/server/pom.xml
tomee/tomee/trunk/tomee/tomee-webservices/src/main/java/org/apache/tomee/webservices/TomcatWsRegistry.java
Added: tomee/tomee/trunk/server/openejb-hessian/pom.xml
URL:
http://svn.apache.org/viewvc/tomee/tomee/trunk/server/openejb-hessian/pom.xml?rev=1500981&view=auto
==============================================================================
--- tomee/tomee/trunk/server/openejb-hessian/pom.xml (added)
+++ tomee/tomee/trunk/server/openejb-hessian/pom.xml Mon Jul 8 21:48:58 2013
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+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.
+
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <artifactId>server</artifactId>
+ <groupId>org.apache.openejb</groupId>
+ <version>4.6.0-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>openejb-hessian</artifactId>
+ <name>OpenEJB :: Server :: Hessian</name>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.openejb</groupId>
+ <artifactId>openejb-http</artifactId>
+ <version>4.6.0-SNAPSHOT</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.tomcat</groupId>
+ <artifactId>tomcat-catalina</artifactId>
+ <version>${tomcat.version}</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.openejb</groupId>
+ <artifactId>tomee-catalina</artifactId>
+ <version>${tomee.version}</version>
+ <scope>provided</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>com.caucho</groupId>
+ <artifactId>hessian</artifactId>
+ <version>4.0.7</version>
+ </dependency>
+ </dependencies>
+</project>
Added:
tomee/tomee/trunk/server/openejb-hessian/src/main/java/org/apache/openejb/server/hessian/HessianRegistry.java
URL:
http://svn.apache.org/viewvc/tomee/tomee/trunk/server/openejb-hessian/src/main/java/org/apache/openejb/server/hessian/HessianRegistry.java?rev=1500981&view=auto
==============================================================================
---
tomee/tomee/trunk/server/openejb-hessian/src/main/java/org/apache/openejb/server/hessian/HessianRegistry.java
(added)
+++
tomee/tomee/trunk/server/openejb-hessian/src/main/java/org/apache/openejb/server/hessian/HessianRegistry.java
Mon Jul 8 21:48:58 2013
@@ -0,0 +1,32 @@
+/*
+ * 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.openejb.server.hessian;
+
+import org.apache.openejb.loader.SystemInstance;
+
+import java.net.URISyntaxException;
+
+public interface HessianRegistry {
+ static final String HESSIAN =
SystemInstance.get().getProperty("openejb.hessian.subcontext", "/hessian/");
+
+ String deploy(ClassLoader loader, HessianServer server,
+ String host, String app,
+ String authMethod, String transportGuarantee, String
realmName,
+ String name) throws URISyntaxException;
+
+ public void undeploy(String host, String app, String name);
+}
Added:
tomee/tomee/trunk/server/openejb-hessian/src/main/java/org/apache/openejb/server/hessian/HessianRegistryImpl.java
URL:
http://svn.apache.org/viewvc/tomee/tomee/trunk/server/openejb-hessian/src/main/java/org/apache/openejb/server/hessian/HessianRegistryImpl.java?rev=1500981&view=auto
==============================================================================
---
tomee/tomee/trunk/server/openejb-hessian/src/main/java/org/apache/openejb/server/hessian/HessianRegistryImpl.java
(added)
+++
tomee/tomee/trunk/server/openejb-hessian/src/main/java/org/apache/openejb/server/hessian/HessianRegistryImpl.java
Mon Jul 8 21:48:58 2013
@@ -0,0 +1,50 @@
+package org.apache.openejb.server.hessian;
+
+import org.apache.openejb.OpenEJBRuntimeException;
+import org.apache.openejb.loader.SystemInstance;
+import org.apache.openejb.server.httpd.HttpListener;
+import org.apache.openejb.server.httpd.HttpListenerRegistry;
+import org.apache.openejb.server.httpd.HttpRequest;
+import org.apache.openejb.server.httpd.HttpResponse;
+import org.apache.openejb.server.httpd.OpenEJBHttpRegistry;
+import org.apache.openejb.server.httpd.util.HttpUtil;
+
+public class HessianRegistryImpl extends OpenEJBHttpRegistry implements
HessianRegistry {
+ @Override
+ public String deploy(final ClassLoader loader, final HessianServer
listener, final String host,
+ final String app, final String authMethod, final
String transportGuarantee,
+ final String realmName, final String name) {
+ final String path = generateEndpointName(app, name);
+ addWrappedHttpListener(new HessianListener(listener), loader, path);
+ return HttpUtil.selectSingleAddress(getResolvedAddresses(path));
+ }
+
+ @Override
+ public void undeploy(String host, String app, String name) {
+
SystemInstance.get().getComponent(HttpListenerRegistry.class).removeHttpListener(generateEndpointName(app,
name));
+ }
+
+ private static String generateEndpointName(final String app, final String
name) {
+ return "/" + app + HESSIAN + name;
+ }
+
+ protected static class HessianListener implements HttpListener {
+ private final HessianServer delegate;
+
+ protected HessianListener(final HessianServer server) {
+ this.delegate = server;
+ }
+
+ @Override
+ public void onMessage(final HttpRequest request, final HttpResponse
response) throws Exception {
+ try {
+ delegate.invoke(request.getInputStream(),
response.getOutputStream());
+ } catch (final Throwable throwable) {
+ if (Exception.class.isInstance(throwable)) {
+ throw Exception.class.cast(throwable);
+ }
+ throw new OpenEJBRuntimeException(throwable.getMessage(),
throwable);
+ }
+ }
+ }
+}
Added:
tomee/tomee/trunk/server/openejb-hessian/src/main/java/org/apache/openejb/server/hessian/HessianServer.java
URL:
http://svn.apache.org/viewvc/tomee/tomee/trunk/server/openejb-hessian/src/main/java/org/apache/openejb/server/hessian/HessianServer.java?rev=1500981&view=auto
==============================================================================
---
tomee/tomee/trunk/server/openejb-hessian/src/main/java/org/apache/openejb/server/hessian/HessianServer.java
(added)
+++
tomee/tomee/trunk/server/openejb-hessian/src/main/java/org/apache/openejb/server/hessian/HessianServer.java
Mon Jul 8 21:48:58 2013
@@ -0,0 +1,148 @@
+/*
+ * 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.openejb.server.hessian;
+
+import com.caucho.hessian.io.AbstractHessianInput;
+import com.caucho.hessian.io.AbstractHessianOutput;
+import com.caucho.hessian.io.Hessian2Input;
+import com.caucho.hessian.io.Hessian2Output;
+import com.caucho.hessian.io.HessianDebugInputStream;
+import com.caucho.hessian.io.HessianDebugOutputStream;
+import com.caucho.hessian.io.HessianFactory;
+import com.caucho.hessian.io.HessianInput;
+import com.caucho.hessian.io.HessianOutput;
+import com.caucho.hessian.io.SerializerFactory;
+import com.caucho.hessian.server.HessianSkeleton;
+
+import java.io.BufferedInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+public class HessianServer {
+ public static final String CONTENT_TYPE_HESSIAN = "application/x-hessian";
+
+ private final ClassLoader loader;
+
+ private SerializerFactory serializerFactory;
+ private HessianSkeleton skeleton;
+ private Logger debugLogger = null;
+
+ public HessianServer(final ClassLoader classLoader) {
+ this.loader = classLoader;
+
+ serializerFactory = new SerializerFactory(loader);
+ serializerFactory.setAllowNonSerializable(true);
+ }
+
+ public HessianServer serializerFactory(final SerializerFactory
serializerFactory) {
+ this.serializerFactory = (serializerFactory != null ?
serializerFactory : new SerializerFactory(loader));
+ return this;
+ }
+
+ public HessianServer sendCollectionType(final boolean sendCollectionType) {
+ this.serializerFactory.setSendCollectionType(sendCollectionType);
+ return this;
+ }
+
+ public HessianServer debug(boolean debug) {
+ this.debugLogger = (debug ? Logger.getLogger("OpenEJB.hessian.DEBUG")
: null);
+ return this;
+ }
+
+ public HessianServer createSkeleton(final Object instance, final Class<?>
itf) {
+ skeleton = new HessianSkeleton(instance, itf);
+ return this;
+ }
+
+ public void invoke(final InputStream inputStream, final OutputStream
outputStream) throws Throwable {
+ InputStream isToUse = inputStream;
+ OutputStream osToUse = outputStream;
+
+ if (debugLogger != null && debugLogger.isLoggable(Level.FINE)) {
+ final HessianDebugInputStream dis = new
HessianDebugInputStream(inputStream, debugLogger, Level.FINE);
+ dis.startTop2();
+ final HessianDebugOutputStream dos = new
HessianDebugOutputStream(outputStream, debugLogger, Level.FINE);
+ dos.startTop2();
+ isToUse = dis;
+ osToUse = dos;
+ }
+
+ if (!isToUse.markSupported()) {
+ isToUse = new BufferedInputStream(isToUse);
+ isToUse.mark(1);
+ }
+
+ int code = isToUse.read();
+ int major;
+ int minor;
+
+ AbstractHessianInput in;
+ AbstractHessianOutput out;
+
+ if (code == 'H') { // Hessian 2.0 stream
+ major = isToUse.read();
+ minor = isToUse.read();
+ if (major != 0x02) {
+ throw new IOException("Version " + major + "." + minor + " is
not understood");
+ }
+ in = new Hessian2Input(isToUse);
+ out = new Hessian2Output(osToUse);
+ in.readCall();
+ } else if (code == 'C') { // Hessian 2.0 call... for some reason not
handled in HessianServlet!
+ isToUse.reset();
+ in = new Hessian2Input(isToUse);
+ out = new Hessian2Output(osToUse);
+ in.readCall();
+ } else if (code == 'c') { // Hessian 1.0 call
+ major = isToUse.read();
+ minor = isToUse.read();
+ in = new HessianInput(isToUse);
+ if (major >= 2) {
+ out = new Hessian2Output(osToUse);
+ } else {
+ out = new HessianOutput(osToUse);
+ }
+ } else {
+ throw new IOException("Expected 'H'/'C' (Hessian 2.0) or 'c'
(Hessian 1.0) in hessian input at " + code);
+ }
+
+ if (serializerFactory != null) {
+ in.setSerializerFactory(serializerFactory);
+ out.setSerializerFactory(serializerFactory);
+ }
+
+ try {
+ skeleton.invoke(in, out);
+ } finally {
+ try {
+ in.close();
+ isToUse.close();
+ } catch (final IOException ex) {
+ // ignore
+ }
+ try {
+ out.close();
+ osToUse.close();
+ } catch (final IOException ex) {
+ // ignore
+ }
+ }
+ }
+}
Added:
tomee/tomee/trunk/server/openejb-hessian/src/main/java/org/apache/openejb/server/hessian/HessianService.java
URL:
http://svn.apache.org/viewvc/tomee/tomee/trunk/server/openejb-hessian/src/main/java/org/apache/openejb/server/hessian/HessianService.java?rev=1500981&view=auto
==============================================================================
---
tomee/tomee/trunk/server/openejb-hessian/src/main/java/org/apache/openejb/server/hessian/HessianService.java
(added)
+++
tomee/tomee/trunk/server/openejb-hessian/src/main/java/org/apache/openejb/server/hessian/HessianService.java
Mon Jul 8 21:48:58 2013
@@ -0,0 +1,201 @@
+/*
+ * 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.openejb.server.hessian;
+
+import com.caucho.hessian.io.SerializerFactory;
+import org.apache.openejb.BeanContext;
+import org.apache.openejb.OpenEJBRuntimeException;
+import org.apache.openejb.assembler.classic.AppInfo;
+import org.apache.openejb.assembler.classic.Assembler;
+import org.apache.openejb.assembler.classic.EjbJarInfo;
+import org.apache.openejb.assembler.classic.EnterpriseBeanInfo;
+import
org.apache.openejb.assembler.classic.event.AssemblerAfterApplicationCreated;
+import
org.apache.openejb.assembler.classic.event.AssemblerBeforeApplicationDestroyed;
+import
org.apache.openejb.assembler.classic.event.NewEjbAvailableAfterApplicationCreated;
+import org.apache.openejb.loader.SystemInstance;
+import org.apache.openejb.observer.Observes;
+import org.apache.openejb.server.SelfManaging;
+import org.apache.openejb.server.ServerService;
+import org.apache.openejb.server.ServiceException;
+import org.apache.openejb.server.httpd.HttpListenerRegistry;
+import org.apache.openejb.spi.ContainerSystem;
+import org.apache.openejb.util.LogCategory;
+import org.apache.openejb.util.Logger;
+import org.apache.openejb.util.proxy.ProxyEJB;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.Socket;
+import java.net.URISyntaxException;
+import java.util.Collection;
+import java.util.Properties;
+
+public class HessianService implements ServerService, SelfManaging {
+ private static final Logger LOGGER =
Logger.getInstance(LogCategory.OPENEJB_SERVER.createChild("hessian"),
HessianService.class);
+
+ private boolean disabled;
+ private boolean debug;
+ private boolean sendCollectionType;
+ private SerializerFactory serializerFactory;
+ private String realmName;
+ private String virtualHost;
+ private String transportGuarantee;
+ private String authMethod;
+
+ private HessianRegistry registry;
+
+ private void deploy(final AppInfo app, final Collection<BeanContext>
beanContexts) {
+ if (disabled) {
+ return;
+ }
+
+ for (final BeanContext beanContext : beanContexts) {
+ final Class<?> remoteItf =
beanContext.getBusinessRemoteInterface();
+ if (remoteItf == null) {
+ continue;
+ }
+
+ final HessianServer server = new
HessianServer(beanContext.getClassLoader())
+ .debug(debug)
+ .sendCollectionType(sendCollectionType);
+ if (serializerFactory != null) {
+ server.serializerFactory(serializerFactory);
+ }
+ server.createSkeleton(ProxyEJB.simpleProxy(beanContext, new
Class<?>[]{ remoteItf }), remoteItf);
+
+ try {
+ LOGGER.info("Hessian(url=" +
registry.deploy(beanContext.getClassLoader(), server, virtualHost, appName(app,
beanContext), authMethod, transportGuarantee, realmName,
String.class.cast(beanContext.getDeploymentID())) + ", interface=" +
remoteItf.getName() + ")");
+ } catch (final URISyntaxException e) {
+ throw new OpenEJBRuntimeException(e);
+ }
+ }
+ }
+
+ @Override
+ public void start() throws ServiceException {
+ SystemInstance.get().addObserver(this);
+ registry = SystemInstance.get().getComponent(HessianRegistry.class);
+ if (registry == null) {
+ try { // if tomcat
+
HessianService.class.getClassLoader().loadClass("org.apache.catalina.Context");
+ registry = new TomcatHessianRegistry();
+ } catch (final Throwable t) { // else if embedded
+ if
(SystemInstance.get().getComponent(HttpListenerRegistry.class) != null) {
+ registry = new HessianRegistryImpl();
+ } else {
+ throw new IllegalStateException("openejb-http is missing
at classpath");
+ }
+ }
+ SystemInstance.get().setComponent(HessianRegistry.class, registry);
+ }
+
+ final Assembler assembler =
SystemInstance.get().getComponent(Assembler.class);
+ if (assembler != null) {
+ for (final AppInfo appInfo : assembler.getDeployedApplications()) {
+ afterApplicationCreated(new
AssemblerAfterApplicationCreated(appInfo,
SystemInstance.get().getComponent(ContainerSystem.class).getAppContext(appInfo.appId).getBeanContexts()));
+ }
+ }
+ }
+
+ @Override
+ public void stop() throws ServiceException {
+ SystemInstance.get().removeObserver(this);
+ }
+
+ @Override
+ public void service(final InputStream in, final OutputStream out) throws
ServiceException, IOException {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void service(final Socket socket) throws ServiceException,
IOException {
+ throw new UnsupportedOperationException();
+ }
+
+ public void newEjbToDeploy(final @Observes
NewEjbAvailableAfterApplicationCreated event) {
+ deploy(event.getApp(), event.getBeanContexts());
+ }
+
+ public void afterApplicationCreated(final @Observes
AssemblerAfterApplicationCreated event) {
+ final AppInfo appInfo = event.getApp();
+ deploy(appInfo, event.getDeployedEjbs());
+ }
+
+ public void beforeApplicationDestroyed(@Observes final
AssemblerBeforeApplicationDestroyed event) {
+ if (disabled) {
+ return;
+ }
+
+ for (final BeanContext beanContext :
SystemInstance.get().getComponent(ContainerSystem.class).getAppContext(event.getApp().appId).getBeanContexts())
{
+ final Class<?> remoteItf =
beanContext.getBusinessRemoteInterface();
+ if (remoteItf == null) {
+ continue;
+ }
+
+ final String name =
String.class.cast(beanContext.getDeploymentID());
+ registry.undeploy(virtualHost, appName(event.getApp(),
beanContext), name);
+ LOGGER.info("Undeployed hessian service " + name);
+ }
+ }
+
+ private static String appName(final AppInfo app, final BeanContext
beanContext) {
+ if (!app.webApps.isEmpty()) {
+ for (final EjbJarInfo ejbJar : app.ejbJars) {
+ for (final EnterpriseBeanInfo bean : ejbJar.enterpriseBeans) {
+ if (bean.ejbName.equals(beanContext.getEjbName())) {
+ if (ejbJar.webapp) {
+ return ejbJar.moduleName;
+ }
+ }
+ }
+ }
+ }
+ return app.appId;
+ }
+
+ @Override
+ public String getName() {
+ return "hessian";
+ }
+
+ @Override
+ public String getIP() {
+ return "n/a";
+ }
+
+ @Override
+ public int getPort() {
+ return -1;
+ }
+
+ @Override
+ public void init(final Properties props) throws Exception {
+ disabled = Boolean.parseBoolean(props.getProperty("disabled",
"false"));
+ debug = Boolean.parseBoolean(props.getProperty("debug", "false"));
+ sendCollectionType =
Boolean.parseBoolean(props.getProperty("sendCollectionType", "false"));
+ realmName = props.getProperty("realmName");
+ transportGuarantee = props.getProperty("transportGuarantee", "NONE");
+ virtualHost = props.getProperty("virtualHost", "localhost");
+ authMethod = props.getProperty("authMethod", "NONE");
+
+ final String serializerFactoryClass =
props.getProperty("serializerFactory", null);
+ if (serializerFactoryClass != null) {
+ serializerFactory =
SerializerFactory.class.cast(Thread.currentThread().getContextClassLoader().loadClass(serializerFactoryClass).newInstance());
+ }
+ }
+}
Added:
tomee/tomee/trunk/server/openejb-hessian/src/main/java/org/apache/openejb/server/hessian/OpenEJBHessianServlet.java
URL:
http://svn.apache.org/viewvc/tomee/tomee/trunk/server/openejb-hessian/src/main/java/org/apache/openejb/server/hessian/OpenEJBHessianServlet.java?rev=1500981&view=auto
==============================================================================
---
tomee/tomee/trunk/server/openejb-hessian/src/main/java/org/apache/openejb/server/hessian/OpenEJBHessianServlet.java
(added)
+++
tomee/tomee/trunk/server/openejb-hessian/src/main/java/org/apache/openejb/server/hessian/OpenEJBHessianServlet.java
Mon Jul 8 21:48:58 2013
@@ -0,0 +1,41 @@
+/*
+ * 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.openejb.server.hessian;
+
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServlet;
+import java.io.IOException;
+
+public class OpenEJBHessianServlet extends HttpServlet {
+ private final HessianServer delegate;
+
+ public OpenEJBHessianServlet(final HessianServer listener) {
+ this.delegate = listener;
+ }
+
+ @Override
+ public void service(final ServletRequest req, final ServletResponse res)
throws ServletException, IOException {
+ res.setContentType(HessianServer.CONTENT_TYPE_HESSIAN);
+ try {
+ delegate.invoke(req.getInputStream(), res.getOutputStream());
+ } catch (final Throwable throwable) {
+ throw new ServletException(throwable);
+ }
+ }
+}
Added:
tomee/tomee/trunk/server/openejb-hessian/src/main/java/org/apache/openejb/server/hessian/TomcatHessianRegistry.java
URL:
http://svn.apache.org/viewvc/tomee/tomee/trunk/server/openejb-hessian/src/main/java/org/apache/openejb/server/hessian/TomcatHessianRegistry.java?rev=1500981&view=auto
==============================================================================
---
tomee/tomee/trunk/server/openejb-hessian/src/main/java/org/apache/openejb/server/hessian/TomcatHessianRegistry.java
(added)
+++
tomee/tomee/trunk/server/openejb-hessian/src/main/java/org/apache/openejb/server/hessian/TomcatHessianRegistry.java
Mon Jul 8 21:48:58 2013
@@ -0,0 +1,275 @@
+/*
+ * 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.openejb.server.hessian;
+
+import org.apache.catalina.Container;
+import org.apache.catalina.Context;
+import org.apache.catalina.Engine;
+import org.apache.catalina.Service;
+import org.apache.catalina.Valve;
+import org.apache.catalina.Wrapper;
+import org.apache.catalina.authenticator.BasicAuthenticator;
+import org.apache.catalina.authenticator.DigestAuthenticator;
+import org.apache.catalina.authenticator.NonLoginAuthenticator;
+import org.apache.catalina.authenticator.SSLAuthenticator;
+import org.apache.catalina.connector.Connector;
+import org.apache.catalina.connector.Request;
+import org.apache.catalina.connector.Response;
+import org.apache.catalina.core.StandardContext;
+import org.apache.catalina.core.StandardServer;
+import org.apache.catalina.deploy.LoginConfig;
+import org.apache.catalina.deploy.SecurityCollection;
+import org.apache.catalina.deploy.SecurityConstraint;
+import org.apache.commons.lang3.tuple.MutablePair;
+import org.apache.commons.lang3.tuple.Pair;
+import org.apache.openejb.assembler.classic.WebAppBuilder;
+import org.apache.openejb.loader.SystemInstance;
+import org.apache.openejb.server.httpd.util.HttpUtil;
+import org.apache.tomee.catalina.IgnoredStandardContext;
+import org.apache.tomee.catalina.OpenEJBValve;
+import org.apache.tomee.catalina.TomcatWebAppBuilder;
+import org.apache.tomee.loader.TomcatHelper;
+
+import javax.servlet.ServletException;
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class TomcatHessianRegistry implements HessianRegistry {
+ private static final String TOMEE_HESSIAN_SECURITY_ROLE_PREFIX =
"tomee.jaxws.security-role.";
+
+ private final Map<String, Pair<Context, Integer>> fakeContexts = new
HashMap<String, Pair<Context, Integer>>();
+
+ private Engine engine;
+ private List<Connector> connectors;
+
+ public TomcatHessianRegistry() {
+ final StandardServer standardServer = TomcatHelper.getServer();
+ for (final Service service : standardServer.findServices()) {
+ if (Engine.class.isInstance(service.getContainer())) {
+ connectors = Arrays.asList(service.findConnectors());
+ engine = Engine.class.cast(service.getContainer());
+ break;
+ }
+ }
+ }
+
+ @Override
+ public String deploy(final ClassLoader loader, final HessianServer
listener,
+ final String hostname, final String app,
+ final String authMethod, final String
transportGuarantee,
+ final String realmName, final String name) throws
URISyntaxException {
+ Container host = engine.findChild(hostname);
+ if (host == null) {
+ host = engine.findChild(engine.getDefaultHost());
+ if (host == null) {
+ throw new IllegalArgumentException("Invalid virtual host '" +
host + "'. Do you have a matchiing Host entry in the server.xml?");
+ }
+ }
+
+ final String contextRoot = contextName(app);
+ Context context = Context.class.cast(host.findChild(contextRoot));
+ if (context == null) {
+ Pair<Context, Integer> fakeContext = fakeContexts.get(contextRoot);
+ if (fakeContext != null) {
+ context = fakeContext.getLeft();
+ fakeContext.setValue(fakeContext.getValue() + 1);
+ } else {
+ context = Context.class.cast(host.findChild(contextRoot));
+ if (context == null) {
+ fakeContext = fakeContexts.get(contextRoot);
+ if (fakeContext == null) {
+ context = createNewContext(loader, authMethod,
transportGuarantee, realmName, app);
+ fakeContext = new MutablePair<Context,
Integer>(context, 1);
+ fakeContexts.put(contextRoot, fakeContext);
+ } else {
+ context = fakeContext.getLeft();
+ fakeContext.setValue(fakeContext.getValue() + 1);
+ }
+ }
+ }
+ }
+
+ final String servletMapping = generateServletPath(name);
+
+ Wrapper wrapper =
Wrapper.class.cast(context.findChild(servletMapping));
+ if (wrapper != null) {
+ throw new IllegalArgumentException("Servlet " + servletMapping + "
in web application context " + context.getName() + " already exists");
+ }
+
+ wrapper = context.createWrapper();
+ wrapper.setName(HESSIAN.replace("/", "") + "_" + name);
+ wrapper.setServlet(new OpenEJBHessianServlet(listener));
+ context.addChild(wrapper);
+ context.addServletMapping(servletMapping, wrapper.getName());
+
+ if ("BASIC".equals(authMethod) &&
StandardContext.class.isInstance(context)) {
+ final StandardContext standardContext =
StandardContext.class.cast(context);
+
+ boolean found = false;
+ for (final Valve v : standardContext.getPipeline().getValves()) {
+ if (LimitedBasicValve.class.isInstance(v) ||
BasicAuthenticator.class.isInstance(v)) {
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ standardContext.addValve(new LimitedBasicValve(new
LoginConfig(authMethod, realmName, null, null)));
+ }
+ }
+
+ final List<String> addresses = new ArrayList<String>();
+ for (final Connector connector : connectors) {
+ for (final String mapping : wrapper.findMappings()) {
+ final URI address = new URI(connector.getScheme(), null,
host.getName(), connector.getPort(), contextRoot + mapping, null, null);
+ addresses.add(address.toString());
+ }
+ }
+ return HttpUtil.selectSingleAddress(addresses);
+ }
+
+ private static Context createNewContext(final ClassLoader classLoader,
final String rAuthMethod, final String rTransportGuarantee, final String
realmName, final String name) {
+ String path = name;
+ if (path == null) {
+ path = "/";
+ }
+ if (!path.startsWith("/")) {
+ path = "/" + path;
+ }
+
+ final StandardContext context = new IgnoredStandardContext();
+ context.setPath(path);
+ context.setDocBase("");
+ context.setParentClassLoader(classLoader);
+ context.setDelegate(true);
+ context.setName(name);
+
TomcatWebAppBuilder.class.cast(SystemInstance.get().getComponent(WebAppBuilder.class)).initJ2EEInfo(context);
+
+ // Configure security
+ String authMethod = rAuthMethod;
+ if (authMethod != null) {
+ authMethod = authMethod.toUpperCase();
+ }
+ String transportGuarantee = rTransportGuarantee;
+ if (transportGuarantee != null) {
+ transportGuarantee = transportGuarantee.toUpperCase();
+ }
+ if (authMethod != null & !"NONE".equals(authMethod)) {
+ if ("BASIC".equals(authMethod) || "DIGEST".equals(authMethod) ||
"CLIENT-CERT".equals(authMethod)) {
+
+ //Setup a login configuration
+ final LoginConfig loginConfig = new LoginConfig();
+ loginConfig.setAuthMethod(authMethod);
+ loginConfig.setRealmName(realmName);
+ context.setLoginConfig(loginConfig);
+
+ //Setup a default Security Constraint
+ final String securityRole =
SystemInstance.get().getProperty(TOMEE_HESSIAN_SECURITY_ROLE_PREFIX + name,
"default");
+ for (final String role : securityRole.split(",")) {
+ final SecurityCollection collection = new
SecurityCollection();
+ collection.addMethod("GET");
+ collection.addMethod("POST");
+ collection.addPattern("/*");
+ collection.setName(role);
+
+ final SecurityConstraint sc = new SecurityConstraint();
+ sc.addAuthRole("*");
+ sc.addCollection(collection);
+ sc.setAuthConstraint(true);
+ sc.setUserConstraint(transportGuarantee);
+
+ context.addConstraint(sc);
+ context.addSecurityRole(role);
+ }
+ }
+
+ //Set the proper authenticator
+ if ("BASIC".equals(authMethod)) {
+ context.addValve(new BasicAuthenticator());
+ } else if ("DIGEST".equals(authMethod)) {
+ context.addValve(new DigestAuthenticator());
+ } else if ("CLIENT-CERT".equals(authMethod)) {
+ context.addValve(new SSLAuthenticator());
+ } else if ("NONE".equals(authMethod)) {
+ context.addValve(new NonLoginAuthenticator());
+ }
+
+ context.getPipeline().addValve(new OpenEJBValve());
+ } else {
+ throw new IllegalArgumentException("Invalid authMethod: " +
authMethod);
+ }
+
+ return context;
+ }
+
+ private static String generateServletPath(String name) {
+ return HESSIAN + name;
+ }
+
+ private static String contextName(final String app) {
+ if (!app.startsWith("/") && !app.isEmpty()) {
+ return "/" + app;
+ }
+ return app;
+ }
+
+ @Override
+ public void undeploy(final String hostname, final String app, final String
name) {
+ Container host = engine.findChild(hostname);
+ if (host == null) {
+ host = engine.findChild(engine.getDefaultHost());
+ if (host == null) {
+ throw new IllegalArgumentException("Invalid virtual host '" +
host + "'. Do you have a matchiing Host entry in the server.xml?");
+ }
+ }
+
+ final String contextRoot = contextName(app);
+ final Pair<Context, Integer> fakeContext =
fakeContexts.get(contextRoot);
+
+ if (fakeContext != null) {
+ fakeContext.setValue(fakeContext.getValue() - 1);
+ if (fakeContext.getValue() == 0) {
+ fakeContexts.remove(contextRoot);
+ host.removeChild(fakeContext.getKey());
+ }
+ }
+ }
+
+ protected static class LimitedBasicValve extends BasicAuthenticator {
+ private final LoginConfig fakeLoginConfig;
+
+ protected LimitedBasicValve(final LoginConfig fakeLoginConfig) {
+ this.fakeLoginConfig = fakeLoginConfig;
+ }
+
+ @Override
+ public void invoke(final Request request, final Response response)
throws IOException, ServletException {
+ final String requestURI = request.getDecodedRequestURI();
+ if (requestURI.startsWith(HESSIAN)) {
+ if (!authenticate(request, response, fakeLoginConfig)) {
+ return;
+ }
+ }
+ getNext().invoke(request, response);
+ }
+ }
+}
Added:
tomee/tomee/trunk/server/openejb-hessian/src/main/resources/META-INF/org.apache.openejb.server.ServerService/hessian
URL:
http://svn.apache.org/viewvc/tomee/tomee/trunk/server/openejb-hessian/src/main/resources/META-INF/org.apache.openejb.server.ServerService/hessian?rev=1500981&view=auto
==============================================================================
---
tomee/tomee/trunk/server/openejb-hessian/src/main/resources/META-INF/org.apache.openejb.server.ServerService/hessian
(added)
+++
tomee/tomee/trunk/server/openejb-hessian/src/main/resources/META-INF/org.apache.openejb.server.ServerService/hessian
Mon Jul 8 21:48:58 2013
@@ -0,0 +1,10 @@
+server = org.apache.openejb.server.hessian.HessianService
+disabled = ${openejb.profile.custom}
+
+# NONE, INTEGRAL or CONFIDENTIAL
+transportGuarantee = NONE
+
+# NONE, BASIC
+authMethod = NONE
+
+# realmName =
Added:
tomee/tomee/trunk/server/openejb-hessian/src/test/java/org/apache/openejb/server/hessian/HessianServiceTest.java
URL:
http://svn.apache.org/viewvc/tomee/tomee/trunk/server/openejb-hessian/src/test/java/org/apache/openejb/server/hessian/HessianServiceTest.java?rev=1500981&view=auto
==============================================================================
---
tomee/tomee/trunk/server/openejb-hessian/src/test/java/org/apache/openejb/server/hessian/HessianServiceTest.java
(added)
+++
tomee/tomee/trunk/server/openejb-hessian/src/test/java/org/apache/openejb/server/hessian/HessianServiceTest.java
Mon Jul 8 21:48:58 2013
@@ -0,0 +1,69 @@
+package org.apache.openejb.server.hessian;
+
+import com.caucho.hessian.client.HessianProxyFactory;
+import com.caucho.hessian.io.SerializerFactory;
+import org.apache.openejb.junit.ApplicationComposer;
+import org.apache.openejb.testing.EnableServices;
+import org.apache.openejb.testing.Module;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import javax.ejb.Remote;
+import javax.ejb.Singleton;
+import java.net.MalformedURLException;
+
+import static org.hamcrest.CoreMatchers.instanceOf;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThat;
+
+@EnableServices({ "hessian", "httpejbd" })
+@RunWith(ApplicationComposer.class)
+public class HessianServiceTest {
+ @Module
+ public Class<?>[] classes() {
+ return new Class<?>[] { MyHessianWebService.class };
+ }
+
+ @Test
+ public void client() throws MalformedURLException {
+ final ClassLoader loader =
Thread.currentThread().getContextClassLoader();
+ final HessianProxyFactory clientFactory = new
HessianProxyFactory(loader);
+ final SerializerFactory factory = new SerializerFactory(loader);
+ factory.setAllowNonSerializable(true);
+ clientFactory.setSerializerFactory(factory);
+ final HessianWebService client =
HessianWebService.class.cast(clientFactory.create(HessianWebService.class,
"http://127.0.0.1:4204/HessianServiceTest/hessian/" +
MyHessianWebService.class.getSimpleName()));
+
+ final Out out = client.call(new In("test"));
+ assertThat(out, instanceOf(Out.class));
+ assertEquals("test", out.value);
+ }
+
+ @Remote
+ public static interface HessianWebService {
+ Out call(In in);
+ }
+
+ @Singleton
+ public static class MyHessianWebService implements HessianWebService {
+ @Override
+ public Out call(final In in) {
+ return new Out(in.value);
+ }
+ }
+
+ public static class In {
+ private String value;
+
+ public In(String value) {
+ this.value = value;
+ }
+ }
+
+ public static class Out {
+ private String value;
+
+ public Out(String value) {
+ this.value = value;
+ }
+ }
+}
Modified:
tomee/tomee/trunk/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/HttpListenerRegistry.java
URL:
http://svn.apache.org/viewvc/tomee/tomee/trunk/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/HttpListenerRegistry.java?rev=1500981&r1=1500980&r2=1500981&view=diff
==============================================================================
---
tomee/tomee/trunk/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/HttpListenerRegistry.java
(original)
+++
tomee/tomee/trunk/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/HttpListenerRegistry.java
Mon Jul 8 21:48:58 2013
@@ -63,9 +63,9 @@ public class HttpListenerRegistry implem
listeners = new HashMap<String, HttpListener>(registry);
}
- for (Map.Entry<String, HttpListener> entry : listeners.entrySet())
{
- String pattern = entry.getKey();
- if (path.matches(pattern)) {
+ for (final Map.Entry<String, HttpListener> entry :
listeners.entrySet()) {
+ final String pattern = entry.getKey();
+ if (path.matches(pattern) || path.equals(pattern)) {
entry.getValue().onMessage(request, response);
break;
}
Modified:
tomee/tomee/trunk/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/OpenEJBHttpRegistry.java
URL:
http://svn.apache.org/viewvc/tomee/tomee/trunk/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/OpenEJBHttpRegistry.java?rev=1500981&r1=1500980&r2=1500981&view=diff
==============================================================================
---
tomee/tomee/trunk/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/OpenEJBHttpRegistry.java
(original)
+++
tomee/tomee/trunk/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/OpenEJBHttpRegistry.java
Mon Jul 8 21:48:58 2013
@@ -82,7 +82,7 @@ public class OpenEJBHttpRegistry {
private final HttpListener delegate;
private final ClassLoader classLoader;
- private ClassLoaderHttpListener(HttpListener delegate, ClassLoader
classLoader) {
+ protected ClassLoaderHttpListener(HttpListener delegate, ClassLoader
classLoader) {
this.delegate = delegate;
this.classLoader = classLoader;
}
Modified:
tomee/tomee/trunk/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/util/HttpUtil.java
URL:
http://svn.apache.org/viewvc/tomee/tomee/trunk/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/util/HttpUtil.java?rev=1500981&r1=1500980&r2=1500981&view=diff
==============================================================================
---
tomee/tomee/trunk/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/util/HttpUtil.java
(original)
+++
tomee/tomee/trunk/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/util/HttpUtil.java
Mon Jul 8 21:48:58 2013
@@ -37,26 +37,25 @@ public final class HttpUtil {
// no-op
}
- public static String selectSingleAddress(List<String> addresses) {
+ public static String selectSingleAddress(final List<String> addresses) {
if (addresses == null || addresses.isEmpty()) {
return null;
}
// return the first http address
- for (String address : addresses) {
+ for (final String address : addresses) {
if (address.startsWith("http:")) {
return address;
}
}
// return the first https address
- for (String address : addresses) {
+ for (final String address : addresses) {
if (address.startsWith("https:")) {
return address;
}
}
// just return the first address
- String address = addresses.iterator().next();
- return address;
+ return addresses.iterator().next();
}
public static boolean addServlet(final String classname, final WebContext
wc, final String mapping) {
Modified: tomee/tomee/trunk/server/pom.xml
URL:
http://svn.apache.org/viewvc/tomee/tomee/trunk/server/pom.xml?rev=1500981&r1=1500980&r2=1500981&view=diff
==============================================================================
--- tomee/tomee/trunk/server/pom.xml (original)
+++ tomee/tomee/trunk/server/pom.xml Mon Jul 8 21:48:58 2013
@@ -45,6 +45,7 @@
<module>openejb-ssh</module>
<module>openejb-common-cli</module>
<module>openejb-bonecp</module>
+ <module>openejb-hessian</module>
</modules>
</project>
Modified:
tomee/tomee/trunk/tomee/tomee-webservices/src/main/java/org/apache/tomee/webservices/TomcatWsRegistry.java
URL:
http://svn.apache.org/viewvc/tomee/tomee/trunk/tomee/tomee-webservices/src/main/java/org/apache/tomee/webservices/TomcatWsRegistry.java?rev=1500981&r1=1500980&r2=1500981&view=diff
==============================================================================
---
tomee/tomee/trunk/tomee/tomee-webservices/src/main/java/org/apache/tomee/webservices/TomcatWsRegistry.java
(original)
+++
tomee/tomee/trunk/tomee/tomee-webservices/src/main/java/org/apache/tomee/webservices/TomcatWsRegistry.java
Mon Jul 8 21:48:58 2013
@@ -318,7 +318,7 @@ public class TomcatWsRegistry implements
webserviceContexts.put(path, context);
// register wsdl locations for service-ref resolution
- for (Connector connector : connectors) {
+ for (final Connector connector : connectors) {
final StringBuilder fullContextpath;
if (!WEBSERVICE_OLDCONTEXT_ACTIVE && !fakeDeployment) {
String contextPath = context.getName();