001: /**
002: * JOnAS: Java(TM) Open Application Server
003: * Copyright (C) 2006 Bull S.A.S.
004: * Contact: jonas-team@objectweb.org
005: * Copyright (C) 2006 Distributed Systems Lab.
006: * Universidad Polit??cnica de Madrid (Spain)
007: * Contact: http://lsd.ls.fi.upm.es/lsd
008: *
009: * This library is free software; you can redistribute it and/or
010: * modify it under the terms of the GNU Lesser General Public
011: * License as published by the Free Software Foundation; either
012: * version 2.1 of the License, or any later version.
013: *
014: * This library is distributed in the hope that it will be useful,
015: * but WITHOUT ANY WARRANTY; without even the implied warranty of
016: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
017: * Lesser General Public License for more details.
018: *
019: * You should have received a copy of the GNU Lesser General Public
020: * License along with this library; if not, write to the Free Software
021: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
022: * USA
023: *
024: * --------------------------------------------------------------------------
025: *
026: * --------------------------------------------------------------------------
027: */package org.objectweb.jonas_ejb.container;
028:
029: import java.rmi.NoSuchObjectException;
030: import java.rmi.Remote;
031: import java.rmi.RemoteException;
032:
033: import org.objectweb.carol.cmi.ClusterStub;
034: import org.objectweb.carol.cmi.CmiOutputStream;
035: import org.objectweb.carol.cmi.DistributedEquiv;
036: import org.objectweb.carol.cmi.LowerOrb;
037: import org.objectweb.carol.cmi.ObjectId;
038: import org.objectweb.carol.cmi.ServerConfigException;
039: import org.objectweb.carol.cmi.StubConfig;
040: import org.objectweb.carol.cmi.StubConfigException;
041: import org.objectweb.carol.cmi.StubData;
042: import org.objectweb.carol.cmi.configuration.TraceCmi;
043: import org.objectweb.carol.cmi.ha.EntityBeanReference;
044: import org.objectweb.carol.cmi.ha.StatefulBeanReference;
045: import org.objectweb.carol.cmi.ha.ReplicationManager;
046: import org.objectweb.carol.cmi.ha.RequestId;
047: import org.objectweb.carol.util.configuration.ConfigurationRepository;
048: import org.objectweb.jonas.ha.EntityBeanRefImpl;
049: import org.objectweb.jonas.ha.StatefulBeanRefImpl;
050: import org.objectweb.jonas.ha.HaService;
051: import org.objectweb.jonas.ha.interceptor.HACurrentDelegateImpl;
052: import org.objectweb.jonas.service.ServiceException;
053: import org.objectweb.jonas.service.ServiceManager;
054: import org.objectweb.jonas_ejb.deployment.api.BeanDesc;
055:
056: /**
057: * This class implements common function for SFSB replication.
058: * @author Francisco Perez-Sorrosal (fpsorrosal@no-spam@fi.upm.es)
059: * @author Alberto Paz-Jimenez (apaz@no-spam@fi.upm.es)
060: */
061: class JRepUtil {
062:
063: static boolean hasBackupResponse(RequestId requestId) {
064: boolean result = false;
065:
066: if (TraceCmi.isDebugCmiHA()) {
067: TraceCmi
068: .debugCmiHA("---------------------------------------");
069: TraceCmi.debugCmiHA("In hasBackupResponse for: "
070: + requestId);
071: }
072:
073: try {
074: // Only injects state during failover
075: if (HACurrentDelegateImpl.getCurrent().isOnFailover()) {
076: result = getRepMgr().hasBackupResponse(requestId);
077: }
078: } catch (Exception e) {
079: TraceCmi.error("Unable to obtain the info", e);
080: }
081:
082: if (TraceCmi.isDebugCmiHA()) {
083: TraceCmi
084: .debugCmiHA("---------------------------------------");
085: }
086:
087: return result;
088: }
089:
090: /**
091: * Injects the state of the bean if the cluster object id received in the
092: * request is in the current node.
093: * Only injects the state if we are on failover
094: */
095: static void injectState(ObjectId clusterOId, JStatefulSwitch bs) {
096: if (TraceCmi.isDebugCmiHA()) {
097: TraceCmi
098: .debugCmiHA("---------------------------------------");
099: TraceCmi.debugCmiHA("In injectState for: " + clusterOId);
100: }
101:
102: try {
103: // Only injects state during failover
104: if (HACurrentDelegateImpl.getCurrent().isOnFailover()) {
105: StatefulBeanReference bean = new StatefulBeanRefImpl(bs);
106: getRepMgr().restoreBeanChanges(clusterOId, bean);
107: }
108: } catch (Exception e) {
109: TraceCmi.error("Unable to replicate the state", e);
110: }
111:
112: if (TraceCmi.isDebugCmiHA()) {
113: TraceCmi
114: .debugCmiHA("---------------------------------------");
115: }
116: }
117:
118: /**
119: * Sets the clusterOId in the context, and if the bean does not implement
120: * isModifiedMethod stores the state in the context
121: * @param bs the session switch
122: * @param clusterOId the cluster object Id
123: * @param rctx the request context
124: */
125: static void preInvokeHook(JSessionSwitch bs, ObjectId clusterOId,
126: RequestCtx rctx) {
127: JRepUtil.setClusterOId(bs, clusterOId, rctx);
128: }
129:
130: static void postInvokeHook(RequestCtx rctx, ObjectId clusterOId,
131: JSessionSwitch bs, boolean remove) {
132: if (TraceCmi.isDebugCmiHA()) {
133: TraceCmi
134: .debugCmiHA("---------------------------------------");
135: TraceCmi
136: .debugCmiHA("In PostInvoke hook for: " + clusterOId);
137: }
138:
139: // Create the rootId from the current HACtx/Thread association
140: HACurrentDelegateImpl current = HACurrentDelegateImpl
141: .getCurrent();
142: // Obtain the root request
143: RequestId rootId = null;
144: try {
145: rootId = (RequestId) current.getRequests().get(0);
146:
147: if (remove) {
148: JRepUtil.addRemovedBean(clusterOId, rootId);
149: } else {
150: JRepUtil.addModifiedBean((JStatefulSwitch) bs,
151: clusterOId, rootId);
152: }
153: } catch (ArrayIndexOutOfBoundsException e) {
154: TraceCmi.debugCmiHA("Don't need to be replicate.");
155: }
156:
157: if (TraceCmi.isDebugCmiHA()) {
158: TraceCmi
159: .debugCmiHA("---------------------------------------");
160: }
161: }
162:
163: /**
164: * Adds a bean to the beans associated with rootId
165: * @param bs the bean switch
166: * @param clusterOId the cluster object id
167: * @param rootId the root request id
168: */
169: static void addModifiedBean(JStatefulSwitch bs,
170: ObjectId clusterOId, RequestId rootId) {
171: StatefulBeanReference bean = new StatefulBeanRefImpl(bs);
172:
173: try {
174: getRepMgr().addModifiedBean(rootId, clusterOId, bean);
175: } catch (Exception e) {
176: TraceCmi.error(
177: "Unable to add modified bean: " + clusterOId, e);
178: }
179: }
180:
181: /**
182: * Adds a bean to the beans associated with rootId marked for remove
183: * @param clusterOId the cluster object id
184: * @param rootId the root request id
185: */
186: public static void addRemovedBean(ObjectId clusterOId,
187: RequestId rootId) {
188: try {
189: getRepMgr().addModifiedBean(rootId, clusterOId, null);
190: } catch (Exception e) {
191: TraceCmi.error("Unable to add removed bean: " + clusterOId,
192: e);
193: }
194: }
195:
196: /**
197: * Adds an entity bean to the beans associated with rootId
198: * @param bctx The entity context
199: * @param rootId the root request id
200: */
201: public static void addEntityBean(JEntityContext bctx,
202: RequestId rootId) {
203: EntityBeanReference bean = new EntityBeanRefImpl(bctx);
204:
205: try {
206: getRepMgr().addEntityBean(rootId, bean);
207: } catch (Exception e) {
208: try {
209: TraceCmi.error("Unable to add entity bean: "
210: + bean.getPrimaryKey(), e);
211: } catch (Exception e1) {
212: ;
213: }
214: }
215: }
216:
217: /**
218: * Get the remote object as a stub object for HA remote object LB
219: * @param remote remote object
220: * @param dd the deployment descriptor
221: * @return get remote object
222: * @throws RemoteException
223: * @throws ServerConfigException
224: * @throws NoSuchObjectException if the clustered object is not found in the
225: * CMI registry
226: */
227: public static Remote getHARemoteStub(Remote remote, BeanDesc dd)
228: throws RemoteException {
229: String protocol = ConfigurationRepository
230: .getCurrentConfiguration().getProtocol().getName();
231: if (protocol.equals("cmi")) {
232: StubData sd;
233: ClusterStub cs;
234: try {
235: Remote remObject = LowerOrb.getPRODelegate().toStub(
236: remote);
237: byte[] ser = CmiOutputStream.serialize(
238: dd.getJndiName(), remObject);
239: // Need to obtain an ObjectId from DistributedEquivSystem.
240: sd = new StubData(DistributedEquiv.getOidFactory()
241: .getId(), ser, 100);
242: sd.setKey(dd.getJndiName());
243: cs = StubConfig.instanciateClusterStub(remote
244: .getClass(), sd);
245: } catch (RemoteException e) {
246: e.printStackTrace();
247: throw e;
248: } catch (ServerConfigException e) {
249: e.printStackTrace();
250: throw new StubConfigException(e.getMessage());
251: }
252: return cs;
253: }
254:
255: return remote;
256: }
257:
258: /**
259: * Replication manager
260: */
261: private static ReplicationManager repMgr = null;
262:
263: /**
264: * Get the replication manager
265: * @return replication manager
266: * @throws Exception if the replication manager is not set
267: */
268: static public ReplicationManager getRepMgr() throws Exception {
269: // Get a reference to the replication manager from the HA service
270: if (repMgr == null) {
271: try {
272: HaService svc = null;
273: try {
274: // Access the high-availability service (HA)
275: svc = (HaService) ServiceManager.getInstance()
276: .getService("ha");
277: } catch (ServiceException se) {
278: se.printStackTrace();
279: throw se;
280: } catch (Exception e) {
281: e.printStackTrace();
282: throw e;
283: }
284: // Get the replication manager
285: repMgr = svc.getReplicationManager();
286:
287: if (repMgr == null) {
288: TraceCmi
289: .error("unable to obtain Replication Manager (not set)");
290: throw new Exception(
291: "unable to obtain Replication Manager");
292: }
293: } catch (Exception e) {
294: TraceCmi.error("unable to obtain Replication Manager",
295: e);
296: throw new Exception(
297: "unable to obtain Replication Manager");
298: }
299: }
300: return repMgr;
301: }
302:
303: /**
304: * Sets the clusterOId in the context
305: * @param bs the session switch
306: * @param clusterOId the cluster object Id
307: * @param rctx the request context
308: */
309: static private void setClusterOId(JSessionSwitch bs,
310: ObjectId clusterOId, RequestCtx rctx) {
311: JRepStatefulContext jrsc;
312: try {
313: jrsc = (JRepStatefulContext) bs.getICtx(rctx.currTx);
314: jrsc.setClusterOId(clusterOId);
315: } catch (RemoteException e) {
316: e.printStackTrace();
317: TraceCmi.error("Unable to set clusterOId in context", e);
318: }
319: }
320:
321: }
|