001: /*******************************************************************************
002: * Licensed to the Apache Software Foundation (ASF) under one
003: * or more contributor license agreements. See the NOTICE file
004: * distributed with this work for additional information
005: * regarding copyright ownership. The ASF licenses this file
006: * to you under the Apache License, Version 2.0 (the
007: * "License"); you may not use this file except in compliance
008: * with the License. You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing,
013: * software distributed under the License is distributed on an
014: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015: * KIND, either express or implied. See the License for the
016: * specific language governing permissions and limitations
017: * under the License.
018: *******************************************************************************/package org.ofbiz.service.rmi;
019:
020: import java.rmi.Naming;
021: import java.rmi.RemoteException;
022: import java.rmi.server.RMIClientSocketFactory;
023: import java.rmi.server.RMIServerSocketFactory;
024:
025: import javax.naming.InitialContext;
026: import javax.naming.NamingException;
027:
028: import org.ofbiz.base.container.Container;
029: import org.ofbiz.base.container.ContainerConfig;
030: import org.ofbiz.base.container.ContainerException;
031: import org.ofbiz.entity.GenericDelegator;
032: import org.ofbiz.service.GenericDispatcher;
033: import org.ofbiz.service.LocalDispatcher;
034:
035: /**
036: * RMI Service Engine Container / Dispatcher
037: */
038: public class RmiServiceContainer implements Container {
039:
040: public static final String module = RmiServiceContainer.class
041: .getName();
042:
043: protected RemoteDispatcherImpl remote = null;
044: protected String configFile = null;
045: protected String name = null;
046:
047: // Container methods
048:
049: /**
050: * @see org.ofbiz.base.container.Container#init(java.lang.String[], java.lang.String)
051: */
052: public void init(String[] args, String configFile) {
053: this .configFile = configFile;
054: }
055:
056: public boolean start() throws ContainerException {
057: // get the container config
058: ContainerConfig.Container cfg = ContainerConfig.getContainer(
059: "rmi-dispatcher", configFile);
060: ContainerConfig.Container.Property initialCtxProp = cfg
061: .getProperty("use-initial-context");
062: ContainerConfig.Container.Property lookupHostProp = cfg
063: .getProperty("bound-host");
064: ContainerConfig.Container.Property lookupPortProp = cfg
065: .getProperty("bound-port");
066: ContainerConfig.Container.Property lookupNameProp = cfg
067: .getProperty("bound-name");
068: ContainerConfig.Container.Property delegatorProp = cfg
069: .getProperty("delegator-name");
070: ContainerConfig.Container.Property clientProp = cfg
071: .getProperty("client-factory");
072: ContainerConfig.Container.Property serverProp = cfg
073: .getProperty("server-factory");
074:
075: // check the required lookup-name property
076: if (lookupNameProp == null || lookupNameProp.value == null
077: || lookupNameProp.value.length() == 0) {
078: throw new ContainerException(
079: "Invalid lookup-name defined in container configuration");
080: } else {
081: this .name = lookupNameProp.value;
082: }
083:
084: // check the required delegator-name property
085: if (delegatorProp == null || delegatorProp.value == null
086: || delegatorProp.value.length() == 0) {
087: throw new ContainerException(
088: "Invalid delegator-name defined in container configuration");
089: }
090:
091: String useCtx = initialCtxProp == null
092: || initialCtxProp.value == null ? "false"
093: : initialCtxProp.value;
094: String host = lookupHostProp == null
095: || lookupHostProp.value == null ? "localhost"
096: : lookupHostProp.value;
097: String port = lookupPortProp == null
098: || lookupPortProp.value == null ? "1099"
099: : lookupPortProp.value;
100: String keystore = ContainerConfig.getPropertyValue(cfg,
101: "ssl-keystore", null);
102: String ksType = ContainerConfig.getPropertyValue(cfg,
103: "ssl-keystore-type", "JKS");
104: String ksPass = ContainerConfig.getPropertyValue(cfg,
105: "ssl-keystore-pass", null);
106: String ksAlias = ContainerConfig.getPropertyValue(cfg,
107: "ssl-keystore-alias", null);
108: boolean clientAuth = ContainerConfig.getPropertyValue(cfg,
109: "ssl-client-auth", false);
110:
111: // setup the factories
112: RMIClientSocketFactory csf = null;
113: RMIServerSocketFactory ssf = null;
114:
115: // get the classloader
116: ClassLoader loader = Thread.currentThread()
117: .getContextClassLoader();
118:
119: // load the factories
120: if (clientProp != null && clientProp.value != null
121: && clientProp.value.length() > 0) {
122: try {
123: Class c = loader.loadClass(clientProp.value);
124: csf = (RMIClientSocketFactory) c.newInstance();
125: } catch (Exception e) {
126: throw new ContainerException(e);
127: }
128: }
129: if (serverProp != null && serverProp.value != null
130: && serverProp.value.length() > 0) {
131: try {
132: Class c = loader.loadClass(serverProp.value);
133: ssf = (RMIServerSocketFactory) c.newInstance();
134: } catch (Exception e) {
135: throw new ContainerException(e);
136: }
137: }
138:
139: // set the client auth flag on our custom SSL socket factory
140: if (ssf != null
141: && ssf instanceof org.ofbiz.service.rmi.socket.ssl.SSLServerSocketFactory) {
142: ((org.ofbiz.service.rmi.socket.ssl.SSLServerSocketFactory) ssf)
143: .setNeedClientAuth(clientAuth);
144: ((org.ofbiz.service.rmi.socket.ssl.SSLServerSocketFactory) ssf)
145: .setKeyStoreAlias(ksAlias);
146: if (keystore != null) {
147: ((org.ofbiz.service.rmi.socket.ssl.SSLServerSocketFactory) ssf)
148: .setKeyStore(keystore, ksType, ksPass);
149: }
150: }
151:
152: // get the delegator for this container
153: GenericDelegator delegator = GenericDelegator
154: .getGenericDelegator(delegatorProp.value);
155:
156: // create the LocalDispatcher
157: LocalDispatcher dispatcher = GenericDispatcher
158: .getLocalDispatcher(name, delegator);
159:
160: // create the RemoteDispatcher
161: try {
162: remote = new RemoteDispatcherImpl(dispatcher, csf, ssf);
163: } catch (RemoteException e) {
164: throw new ContainerException(
165: "Unable to start the RMI dispatcher", e);
166: }
167:
168: if (!useCtx.equalsIgnoreCase("true")) {
169: // bind RMIDispatcher to RMI Naming (Must be JRMP protocol)
170: try {
171: Naming.rebind("//" + host + ":" + port + "/" + name,
172: remote);
173: } catch (RemoteException e) {
174: throw new ContainerException(
175: "Unable to bind RMIDispatcher to RMI on "
176: + "//host[" + host + "]:port[" + port
177: + "]/name[" + name + "] - with remote="
178: + remote, e);
179: } catch (java.net.MalformedURLException e) {
180: throw new ContainerException("Invalid URL for binding",
181: e);
182: }
183: } else {
184: // bind RMIDispatcher to InitialContext (must be RMI protocol not IIOP)
185: try {
186: InitialContext ic = new InitialContext();
187: ic.rebind(name, remote);
188: } catch (NamingException e) {
189: throw new ContainerException(
190: "Unable to bind RMIDispatcher to JNDI", e);
191: }
192:
193: // check JNDI
194: try {
195: InitialContext ic = new InitialContext();
196: Object o = ic.lookup(name);
197: if (o == null) {
198: throw new NamingException("Object came back null");
199: }
200: } catch (NamingException e) {
201: throw new ContainerException(
202: "Unable to lookup bound objects", e);
203: }
204: }
205:
206: return true;
207: }
208:
209: public void stop() throws ContainerException {
210: remote.deregister();
211: }
212: }
|