001: /*
002: * JBoss, Home of Professional Open Source.
003: * Copyright 2006, Red Hat Middleware LLC, and individual contributors
004: * as indicated by the @author tags. See the copyright.txt file in the
005: * distribution for a full listing of individual contributors.
006: *
007: * This is free software; you can redistribute it and/or modify it
008: * under the terms of the GNU Lesser General Public License as
009: * published by the Free Software Foundation; either version 2.1 of
010: * the License, or (at your option) any later version.
011: *
012: * This software is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * Lesser General Public License for more details.
016: *
017: * You should have received a copy of the GNU Lesser General Public
018: * License along with this software; if not, write to the Free
019: * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
021: */
022: package org.jboss.test.jca.ejb;
023:
024: import org.jboss.logging.Logger;
025: import org.jboss.mx.util.MBeanServerLocator;
026: import org.jboss.test.jca.interfaces.HAConnectionSession;
027: import org.jboss.test.jca.adapter.MockedXADataSource;
028: import org.jboss.system.ServiceMBean;
029:
030: import javax.ejb.SessionBean;
031: import javax.ejb.SessionContext;
032: import javax.ejb.EJBException;
033: import javax.ejb.CreateException;
034: import javax.sql.DataSource;
035: import javax.naming.InitialContext;
036: import javax.management.MBeanServer;
037: import javax.management.ObjectName;
038: import javax.management.InstanceNotFoundException;
039: import javax.management.MBeanException;
040: import javax.management.ReflectionException;
041: import javax.management.AttributeNotFoundException;
042: import java.rmi.RemoteException;
043: import java.sql.Connection;
044:
045: /**
046: * @ejb.bean
047: * name="HAConnectionSession"
048: * view-type="remote"
049: * type="Stateless"
050: *
051: * @author <a href="mailto:alex@jboss.org">Alexey Loubyansky</a>
052: * @version <tt>$Revision: 57211 $</tt>
053: */
054: public class HAConnectionSessionBean implements SessionBean {
055: /** The serialVersionUID */
056: private static final long serialVersionUID = 1L;
057:
058: private static final Logger log = Logger
059: .getLogger(HAConnectionSessionBean.class);
060:
061: private SessionContext ctx;
062:
063: /**
064: * @ejb.interface-method
065: * @ejb.transaction type="NotSupported"
066: */
067: public void testHaLocalConnection() throws Exception {
068: //String url1 = "jdbc:hsqldb:hsql://localhost:1702";
069: //String url2 = "jdbc:hsqldb:hsql://localhost:1703";
070: String port1 = "1702";
071: String port2 = "1703";
072: ObjectName db1 = new ObjectName(
073: "jboss:service=Hypersonic,database=haLocalDB1");
074: ObjectName db2 = new ObjectName(
075: "jboss:service=Hypersonic,database=haLocalDB2");
076:
077: MBeanServer server = MBeanServerLocator.locateJBoss();
078:
079: waitForState(server, db1, ServiceMBean.STARTED);
080: waitForState(server, db2, ServiceMBean.STARTED);
081:
082: DataSource ds = (DataSource) new InitialContext()
083: .lookup("java:/TestHADefaultDS");
084:
085: stopDb(server, db2);
086: String expectedPort = port1;
087:
088: for (int i = 0; i < 10; ++i) {
089: HAConnectionSession me = (HAConnectionSession) ctx
090: .getEJBObject();
091: String conUrl = me.getHAConnectionURL(ds);
092: log.debug("got connection to: " + conUrl);
093:
094: if (!conUrl.endsWith(expectedPort)) {
095: throw new Exception("Expected " + expectedPort
096: + " but got " + conUrl);
097: }
098:
099: if (conUrl.endsWith(port1)) {
100: stopDb(server, db1);
101: startDb(server, db2);
102: expectedPort = port2;
103: } else if (conUrl.endsWith(port2)) {
104: stopDb(server, db2);
105: startDb(server, db1);
106: expectedPort = port1;
107: } else {
108: throw new Exception("Unexpected connection url: "
109: + conUrl);
110: }
111: }
112: }
113:
114: /**
115: * @ejb.interface-method
116: * @ejb.transaction type="NotSupported"
117: */
118: public void testHaXaConnection() throws Exception {
119: String[] urls = MockedXADataSource.getUrls();
120: for (int i = 1; i < urls.length; ++i) {
121: MockedXADataSource.stop(urls[i]);
122: }
123:
124: DataSource ds = (DataSource) new InitialContext()
125: .lookup("java:/MockedHaXaDS");
126: HAConnectionSession facade = (HAConnectionSession) ctx
127: .getEJBObject();
128:
129: for (int i = 0; i < 3 * urls.length; ++i) {
130: String url = facade.getHAConnectionURL(ds);
131: int urlIndex = i % urls.length;
132:
133: if (!url.equals(urls[urlIndex])) {
134: throw new IllegalStateException(
135: "Connected to a wrong database: " + url
136: + ", expected " + urls[urlIndex]);
137: }
138:
139: MockedXADataSource.stop(url);
140:
141: urlIndex = (i + 1) % urls.length;
142: MockedXADataSource.start(urls[urlIndex]);
143: }
144: }
145:
146: /**
147: * @ejb.interface-method
148: * @ejb.transaction type="RequiresNew"
149: */
150: public String getHAConnectionURL(DataSource ds) throws Exception {
151: Connection con = null;
152: try {
153: con = ds.getConnection();
154: return con.getMetaData().getURL();
155: } finally {
156: if (con != null) {
157: con.close();
158: }
159: }
160: }
161:
162: private void startDb(MBeanServer server, ObjectName db2)
163: throws InstanceNotFoundException, MBeanException,
164: ReflectionException, AttributeNotFoundException {
165: server.invoke(db2, "start", null, null);
166: waitForState(server, db2, ServiceMBean.STARTED);
167: }
168:
169: private void stopDb(MBeanServer server, ObjectName db2)
170: throws InstanceNotFoundException, MBeanException,
171: ReflectionException, AttributeNotFoundException {
172: server.invoke(db2, "stop", null, null);
173: waitForState(server, db2, ServiceMBean.STOPPED);
174: }
175:
176: private void waitForState(MBeanServer server, ObjectName db2,
177: int state) throws MBeanException,
178: AttributeNotFoundException, InstanceNotFoundException,
179: ReflectionException {
180: Integer stateValue = (Integer) server
181: .getAttribute(db2, "State");
182: while (stateValue.intValue() != state) {
183: try {
184: Thread.sleep(500);
185: } catch (InterruptedException e) {
186: }
187: stateValue = (Integer) server.getAttribute(db2, "State");
188: }
189: // The hypersonic MBean is not implementated properly
190: // It goes into state STARTED when in reality there is
191: // a background thread still recovering the server
192: if (stateValue.intValue() == ServiceMBean.STARTED) {
193: try {
194: Thread.sleep(5000);
195: } catch (InterruptedException e) {
196: }
197: }
198: }
199:
200: /**
201: * @throws javax.ejb.CreateException Description of Exception
202: * @ejb.create-method
203: */
204: public void ejbCreate() throws CreateException {
205: }
206:
207: public void setSessionContext(SessionContext ctx)
208: throws EJBException, RemoteException {
209: this .ctx = ctx;
210: }
211:
212: public void ejbRemove() throws EJBException, RemoteException {
213: }
214:
215: public void ejbActivate() throws EJBException, RemoteException {
216: }
217:
218: public void ejbPassivate() throws EJBException, RemoteException {
219: }
220: }
|