View Javadoc

1   /*
2    * EL4J, the Extension Library for the J2EE, adds incremental enhancements to
3    * the spring framework, http://el4j.sf.net
4    * Copyright (C) 2006 by ELCA Informatique SA, Av. de la Harpe 22-24,
5    * 1000 Lausanne, Switzerland, http://www.elca.ch
6    *
7    * EL4J is published under the GNU Lesser General Public License (LGPL)
8    * Version 2.1. See http://www.gnu.org/licenses/
9    *
10   * This program is distributed in the hope that it will be useful,
11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13   * GNU Lesser General Public License for more details.
14   *
15   * For alternative licensing, please contact info@elca.ch
16   */
17  package ch.elca.el4j.tests.tcpforwarder;
18  
19  import static org.junit.Assert.fail;
20  
21  import java.util.List;
22  
23  import org.slf4j.Logger;
24  import org.slf4j.LoggerFactory;
25  import org.junit.After;
26  import org.junit.Before;
27  import org.junit.Test;
28  import org.springframework.context.ApplicationContext;
29  import org.springframework.context.ConfigurableApplicationContext;
30  import org.springframework.dao.DataIntegrityViolationException;
31  
32  import ch.elca.el4j.core.context.ModuleApplicationContext;
33  import ch.elca.el4j.services.persistence.hibernate.dao.ConvenienceGenericHibernateDao;
34  import ch.elca.el4j.services.tcpforwarder.TcpForwarder;
35  import ch.elca.el4j.tests.tcpforwarder.dom.Name;
36  import ch.elca.el4j.util.env.EnvPropertiesUtils;
37  
38  /**
39   *
40   * This class is a TestSuite for the TCP Forwarder Module.
41   * It tests
42   * 1) Wheter a store call to a database (using hibernate) is forwarded
43   * to the right port.
44   * 2) The Application Context can be created and the Dao retrieved with the
45   * connection to the database cut.
46   *
47   * @svnLink $Revision: 3884 $;$Date: 2009-08-04 15:48:31 +0200 (Di, 04. Aug 2009) $;$Author: swismer $;$URL: https://el4j.svn.sourceforge.net/svnroot/el4j/branches/el4j_3_1/el4j/framework/tests/tcp_forwarder/src/test/java/ch/elca/el4j/tests/tcpforwarder/TcpForwarderTest.java $
48   *
49   * @author David Stefan (DST)
50   */
51  public class TcpForwarderTest {
52  
53  	/**
54  	 * Delay between the single test steps (in milliseconds).
55  	 */
56  	static final int DELAY = 2000;
57  	
58  	/**
59  	 * New input port -> Forwarder between INPUT_PORT and target port resp.
60  	 * target server.
61  	 */
62  	static final int INPUT_PORT = 6786;
63  	
64  	/**
65  	 * Port of the Derby database.
66  	 */
67  	static final int DERBY_DEST_PORT = 1527;
68  	
69  	/**
70  	 * Port of the Oracle database.
71  	 */
72  	static final int ORACLE_DEST_PORT = 1521;
73  
74  	/**
75  	 * Original domain name of the Oracle database server.
76  	 */
77  	static final String ORACLE_SERVER_NAME = "tulipe.elca.ch";
78  	
79  	/**
80  	 * Config locations.
81  	 */
82  	private static final String[] CONFIG_LOCATIONS = {
83  		"classpath*:mandatory/*.xml",
84  		"classpath*:scenarios/db/raw/*.xml",
85  		"classpath*:scenarios/dataaccess/hibernate/*.xml",
86  		"classpath*:scenarios/dataaccess/hibernate/name/*.xml",
87  		"classpath*:optional/interception/transactionJava5Annotations.xml"};
88  	
89  	/**
90  	 * Private logger.
91  	 */
92  	private static Logger s_logger = LoggerFactory.getLogger(TcpForwarderTest.class);
93  	
94  	/**
95  	 * Application context to load beans.
96  	 */
97  	private ConfigurableApplicationContext m_appContext;
98  	
99  	/**
100 	 * Are we executing the tests on a DB2 database?
101 	 */
102 	private boolean m_isDB2;
103 	
104 	/**
105 	 * The TCP Forwarder.
106 	 */
107 	private TcpForwarder m_forwarder;
108 	
109 	/**
110 	 * Data Access Object.
111 	 */
112 	private ConvenienceGenericHibernateDao<Name, Integer> m_dao;
113 	
114 	/**
115 	 * {@inheritDoc}
116 	 */
117 	@Before
118 	public void setUp() {
119 		String dbName
120 			= EnvPropertiesUtils.getEnvProperties().getProperty("db.name");
121 		m_isDB2 = dbName.equals("db2");
122 		if (m_isDB2) {
123 			m_forwarder = new TcpForwarder(INPUT_PORT, DERBY_DEST_PORT);
124 		} else {
125 			s_logger.info("TCP forwarder doesn't work using Oracle "
126 				+ "due to load balancing");
127 			//InetSocketAddress target = new InetSocketAddress(Inet4Address
128 			//    .getByName(ORACLE_SERVER_NAME), ORACLE_DEST_PORT);
129 			//m_forwarder = new TcpForwarder(INPUT_PORT, target);
130 			m_forwarder = null;
131 		}
132 	}
133 	
134 	
135 	/**
136 	 * {@inheritDoc}
137 	 */
138 	@After
139 	public void tearDown() {
140 		if (m_forwarder != null) {
141 			m_forwarder.unplug();
142 		}
143 		if (m_appContext != null) {
144 			m_appContext.close();
145 		}
146 	}
147 	
148 	/**
149 	 * This test uses a tcp forwarder to connect to a databse and verifies that
150 	 * this connection has been established, then cuts the connection to the
151 	 * database and verifies that there is no connectivity to the database any
152 	 * more, then reconnects to the database again and tests whether the
153 	 * connection has been re-established.
154 	 *
155 	 * @throws Exception
156 	 */
157 	@Test
158 	public void testForwarder() throws Exception {
159 		if (!m_isDB2) {
160 			return;
161 		}
162 		// Try if connection works
163 		executeFirstInsert();
164 		// Unplug and check, if database connection is down
165 		m_forwarder.unplug();
166 		Thread.sleep(DELAY);
167 		executeSecondInsert();
168 		Thread.sleep(DELAY);
169 		// Plug again and check if connection works again
170 		s_logger.debug("Restoring Link");
171 		m_forwarder.plug();
172 		Thread.sleep(DELAY);
173 		executeThirdInsert();
174 		Thread.sleep(DELAY);
175 		s_logger.debug("TEST OK");
176 	}
177 	
178 	/**
179 	 * This test tries to start Spring when there is no connection to a
180 	 * database.
181 	 */
182 	@Test
183 	public void testSpringWithoutDBConnection() throws Exception {
184 		if (!m_isDB2) {
185 			return;
186 		}
187 		// Cutting the connection to the database
188 		m_forwarder.unplug();
189 
190 		try {
191 			getApplicationContext().getBean("nameDao");
192 			s_logger.debug("Spring context started up successfully.");
193 		} catch (Exception e) {
194 			fail("Spring failed to start up...");
195 		}
196 
197 		// Establishing the connection to the database
198 		m_forwarder.plug();
199 
200 		List<Name> nameList = getDao().getAll();
201 		for (Name k : nameList) {
202 			getDao().delete(k.getKey());
203 		}
204 		Name newName = new Name();
205 		newName.setName("NewName");
206 
207 		getDao().saveOrUpdate(newName);
208 
209 		Name newName2 = new Name();
210 		newName2.setName("NewName");
211 
212 		try {
213 			getDao().saveOrUpdate(newName2);
214 		} catch (DataIntegrityViolationException e) {
215 			s_logger.debug("Expected exception catched.");
216 		} catch (Exception e) {
217 			fail("Exception translation has not been performed correctly.");
218 		}
219 		s_logger.debug("TEST OK");
220 	}
221 	
222 	/**
223 	 * @return Returns the applicationContext.
224 	 */
225 	private ApplicationContext getApplicationContext() {
226 		if (m_appContext == null) {
227 			m_appContext
228 				= new ModuleApplicationContext(CONFIG_LOCATIONS, false);
229 		}
230 		return m_appContext;
231 	}
232 	
233 	/**
234 	 * @return The DAO for the inserts
235 	 */
236 	@SuppressWarnings("unchecked")
237 	private ConvenienceGenericHibernateDao<Name, Integer> getDao() {
238 		if (m_dao == null) {
239 			m_dao = (ConvenienceGenericHibernateDao<Name, Integer>)
240 				getApplicationContext().getBean("nameDao");
241 		}
242 		return m_dao;
243 	}
244 	
245 	/**
246 	 * Execute store of data object to test database.
247 	 *
248 	 * @throws InterruptedException
249 	 */
250 	private void executeFirstInsert() throws InterruptedException {
251 		if (m_isDB2) {
252 			s_logger.debug("testing if port '" + DERBY_DEST_PORT
253 				+ "' is up...");
254 		} else {
255 			s_logger.debug("testing if server '" + ORACLE_SERVER_NAME
256 				+ "' is up...");
257 		}
258 		Thread.sleep(DELAY);
259 		try {
260 			Name name = new Name();
261 			name.setName("First");
262 			name = (Name) getDao().saveOrUpdate(name);
263 		} catch (Exception e) {
264 			e.printStackTrace();
265 			fail("Database not reachable -> Test FAILED");
266 		}
267 		s_logger.debug("TEST OK");
268 		Thread.sleep(DELAY);
269 		if (m_isDB2) {
270 			s_logger.debug("Cutting Link to port '" + DERBY_DEST_PORT + "'");
271 		} else {
272 			s_logger.debug("Cutting Link to server '" + ORACLE_SERVER_NAME
273 				+ "'");
274 		}
275 	}
276 	/**
277 	 * Execute the second store, which is supposed to fail, because
278 	 * the TCP fowarder is unplugged.
279 	 */
280 	private void executeSecondInsert() {
281 		try {
282 			Name name = new Name();
283 			name.setName("Second");
284 			name = (Name) getDao().saveOrUpdate(name);
285 			fail("Connection is still up");
286 		} catch (Exception e) {
287 			s_logger.debug("TEST OK");
288 		}
289 	}
290 
291 	/**
292 	 * Execute third store to check if database connection works after we
293 	 * have plugged it again.
294 	 */
295 	private void executeThirdInsert() {
296 		if (m_isDB2) {
297 			s_logger.debug("testing if port '" + DERBY_DEST_PORT
298 				+ "' is up again");
299 		} else {
300 			s_logger.debug("testing if server '" + ORACLE_SERVER_NAME
301 				+ "' is up again");
302 		}
303 		try {
304 			Name name = new Name();
305 			name.setName("Third");
306 			name = (Name) getDao().saveOrUpdate(name);
307 		} catch (Exception e) {
308 			fail("Database not reachable -> Test FAILED");
309 		}
310 	}
311 }