| /* |
| * Copyright (c) 2005, 2021 Oracle and/or its affiliates. All rights reserved. |
| * Copyright (c) 2005, 2015 SAP. All rights reserved. |
| * |
| * This program and the accompanying materials are made available under the |
| * terms of the Eclipse Public License v. 2.0 which is available at |
| * http://www.eclipse.org/legal/epl-2.0, |
| * or the Eclipse Distribution License v. 1.0 which is available at |
| * http://www.eclipse.org/org/documents/edl-v10.php. |
| * |
| * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause |
| */ |
| |
| // Contributors: |
| // SAP - initial API and implementation |
| |
| package org.eclipse.persistence.testing.framework.wdf; |
| |
| import java.io.ByteArrayInputStream; |
| import java.io.ByteArrayOutputStream; |
| import java.io.IOException; |
| import java.io.ObjectInputStream; |
| import java.io.ObjectOutputStream; |
| import java.io.Serializable; |
| import java.lang.reflect.InvocationTargetException; |
| import java.lang.reflect.Method; |
| import java.sql.Connection; |
| import java.sql.DatabaseMetaData; |
| import java.sql.ResultSet; |
| import java.sql.SQLException; |
| import java.sql.Statement; |
| import java.util.HashMap; |
| import java.util.HashSet; |
| import java.util.Hashtable; |
| import java.util.Locale; |
| import java.util.Map; |
| import java.util.Properties; |
| import java.util.Set; |
| |
| import javax.naming.Context; |
| import javax.naming.InitialContext; |
| import javax.naming.NamingException; |
| import jakarta.persistence.EntityManager; |
| import jakarta.persistence.EntityManagerFactory; |
| import jakarta.persistence.LockModeType; |
| import jakarta.persistence.Persistence; |
| import javax.sql.DataSource; |
| |
| import org.eclipse.persistence.config.PersistenceUnitProperties; |
| import org.eclipse.persistence.testing.framework.junit.JUnitTestCaseHelper; |
| import org.eclipse.persistence.testing.framework.server.JEEPlatform; |
| import org.eclipse.persistence.testing.framework.server.ServerPlatform; |
| import org.eclipse.persistence.testing.tests.feature.TestDataSource; |
| import org.junit.Assert; |
| import org.junit.Before; |
| import org.junit.runner.RunWith; |
| import org.junit.runners.Parameterized.Parameters; |
| |
| @SuppressWarnings("unchecked") |
| @RunWith(SkipBugzillaTestRunner.class) |
| public abstract class AbstractBaseTest { |
| |
| // /** System variable to set the tests to run on the server. */ |
| // public static final String RUN_ON_SERVER = "server.run"; |
| // |
| private static Map<String, EntityManagerFactory> emfNamedPersistenceUnits = new Hashtable<String, EntityManagerFactory>(); |
| |
| /** Determine if the test is running on a JEE server, or in JSE. */ |
| |
| private static ServerPlatform serverPlatform; |
| |
| private final JPAEnvironment environment; |
| private final String puName; |
| private final static DataSource dataSource; |
| protected final static Map EMF_PROPERTIES; |
| |
| private static boolean seesJPA2 = (LockModeType.values().length > 2); |
| |
| static { |
| final DataSource aDataSource; |
| |
| if (!ServerInfoHolder.isOnServer()) { |
| Map<String, String> properties = JUnitTestCaseHelper.getDatabaseProperties(); |
| String driver = properties.get(PersistenceUnitProperties.JDBC_DRIVER); |
| String url = properties.get(PersistenceUnitProperties.JDBC_URL); |
| String user = properties.get(PersistenceUnitProperties.JDBC_USER); |
| String password = properties.get(PersistenceUnitProperties.JDBC_PASSWORD); |
| |
| Properties userPasswd = new Properties(); |
| userPasswd.put("user", user); |
| userPasswd.put("password", password); |
| |
| DataSource ds = new TestDataSource(driver, url, userPasswd); |
| aDataSource = new PooledDataSource(ds); |
| |
| } else { |
| Context context; |
| try { |
| context = new InitialContext(); |
| aDataSource = (DataSource) context.lookup(ServerInfoHolder.getDataSourceName()); |
| } catch (NamingException e) { |
| throw new RuntimeException(e); |
| } |
| } |
| dataSource = aDataSource; |
| EMF_PROPERTIES = new HashMap(); |
| EMF_PROPERTIES.put("delimited-identifiers", "true"); |
| EMF_PROPERTIES.put(PersistenceUnitProperties.NON_JTA_DATASOURCE, dataSource); |
| } |
| |
| public AbstractBaseTest(String name) { |
| environment = new ResourceLocalEnvironment(); |
| puName = name; |
| } |
| |
| protected final JPAEnvironment getEnvironment() { |
| return environment; |
| } |
| |
| @Parameters |
| public static void parameters() { |
| |
| } |
| |
| final class ResourceLocalEnvironment implements JPAEnvironment { |
| |
| @Override |
| public void beginTransaction(EntityManager em) { |
| em.getTransaction().begin(); |
| } |
| |
| @Override |
| public void commitTransaction(EntityManager em) { |
| em.getTransaction().commit(); |
| } |
| |
| @Override |
| public void commitTransactionAndClear(EntityManager em) { |
| try { |
| commitTransaction(em); |
| } finally { |
| em.clear(); |
| } |
| } |
| |
| @Override |
| public EntityManagerFactory createNewEntityManagerFactory() throws NamingException { |
| AbstractBaseTest.closeEntityManagerFactory(puName); |
| return Persistence.createEntityManagerFactory(puName, EMF_PROPERTIES); |
| } |
| |
| @Override |
| public EntityManager getEntityManager() { |
| return getEntityManagerFactory().createEntityManager(); |
| // return AbstractBaseTest.createEntityManager(puName, |
| // EMF_PROPERTIES); |
| } |
| |
| @Override |
| public EntityManagerFactory getEntityManagerFactory() { |
| return AbstractBaseTest.getEntityManagerFactory(puName, EMF_PROPERTIES); |
| } |
| |
| @Override |
| public boolean isTransactionActive(EntityManager em) { |
| return em.getTransaction().isActive(); |
| } |
| |
| @Override |
| public boolean isTransactionMarkedForRollback(EntityManager em) { |
| return em.getTransaction().getRollbackOnly(); |
| } |
| |
| @Override |
| public void markTransactionForRollback(EntityManager em) { |
| em.getTransaction().setRollbackOnly(); |
| } |
| |
| @Override |
| public void rollbackTransaction(EntityManager em) { |
| em.getTransaction().rollback(); |
| } |
| |
| @Override |
| public void rollbackTransactionAndClear(EntityManager em) { |
| try { |
| rollbackTransaction(em); |
| } finally { |
| em.clear(); |
| } |
| } |
| |
| @Override |
| public boolean usesExtendedPC() { |
| return true; |
| } |
| |
| @Override |
| public DataSource getDataSource() { |
| return AbstractBaseTest.this.getDataSource(); |
| } |
| |
| @Override |
| public EntityManagerFactory createNewEntityManagerFactory(Map properties) throws NamingException { |
| Map mergedProperties = new HashMap(); |
| mergedProperties.putAll(EMF_PROPERTIES); |
| mergedProperties.putAll(properties); |
| |
| AbstractBaseTest.closeEntityManagerFactory(puName); |
| return Persistence.createEntityManagerFactory(puName, mergedProperties); |
| } |
| |
| @Override |
| public Object getPropertyValue(EntityManager em, String key) { |
| Object delegate = em.getDelegate(); |
| Method getEntityManagerFactoryMethod; |
| try { |
| getEntityManagerFactoryMethod = delegate.getClass().getMethod("getEntityManagerFactory"); |
| Object emf = getEntityManagerFactoryMethod.invoke(delegate); |
| |
| Method getPropertiesMethod = emf.getClass().getMethod("getProperties"); |
| @SuppressWarnings("rawtypes") |
| Map map = (Map) getPropertiesMethod.invoke(emf); |
| |
| return map.get(key); |
| } catch (NoSuchMethodException e) { |
| throw new RuntimeException(e); |
| } catch (IllegalArgumentException e) { |
| throw new RuntimeException(e); |
| } catch (IllegalAccessException e) { |
| throw new RuntimeException(e); |
| } catch (InvocationTargetException e) { |
| throw new RuntimeException(e); |
| } |
| |
| } |
| |
| @Override |
| public void evict(EntityManager em, Class<?> clazz) { |
| Object delegate = em.getDelegate(); |
| Method getEntityManagerFactoryMethod; |
| try { |
| getEntityManagerFactoryMethod = delegate.getClass().getMethod("getEntityManagerFactory"); |
| Object emf = getEntityManagerFactoryMethod.invoke(delegate); |
| |
| Method getCacheMethod = emf.getClass().getMethod("getCache"); |
| Object cache = getCacheMethod.invoke(emf); |
| |
| Method evictClassMethod = cache.getClass().getMethod("evict", Class.class); |
| |
| evictClassMethod.invoke(cache, clazz); |
| } catch (NoSuchMethodException e) { |
| throw new RuntimeException(e); |
| } catch (IllegalArgumentException e) { |
| throw new RuntimeException(e); |
| } catch (IllegalAccessException e) { |
| throw new RuntimeException(e); |
| } catch (InvocationTargetException e) { |
| throw new RuntimeException(e); |
| } |
| } |
| |
| @Override |
| public void evictAll(EntityManager em) { |
| Object delegate = em.getDelegate(); |
| Method getEntityManagerFactoryMethod; |
| try { |
| getEntityManagerFactoryMethod = delegate.getClass().getMethod("getEntityManagerFactory"); |
| Object emf = getEntityManagerFactoryMethod.invoke(delegate); |
| |
| Method getCacheMethod = emf.getClass().getMethod("getCache"); |
| Object cache = getCacheMethod.invoke(emf); |
| |
| Method evictClassMethod = cache.getClass().getMethod("evictAll", new Class[]{}); |
| |
| evictClassMethod.invoke(cache, new Object[]{}); |
| } catch (NoSuchMethodException e) { |
| throw new RuntimeException(e); |
| } catch (IllegalArgumentException e) { |
| throw new RuntimeException(e); |
| } catch (IllegalAccessException e) { |
| throw new RuntimeException(e); |
| } catch (InvocationTargetException e) { |
| throw new RuntimeException(e); |
| } |
| } |
| |
| } |
| |
| final class JTATxScopedEnvironment implements JPAEnvironment { |
| |
| @Override |
| public void beginTransaction(EntityManager em) { |
| AbstractBaseTest.this.beginTransaction(em); |
| } |
| |
| @Override |
| public void commitTransaction(EntityManager em) { |
| AbstractBaseTest.this.commitTransaction(em); |
| } |
| |
| @Override |
| public void commitTransactionAndClear(EntityManager em) { |
| try { |
| commitTransaction(em); |
| } finally { |
| em.clear(); |
| } |
| } |
| |
| @Override |
| public EntityManagerFactory createNewEntityManagerFactory() throws NamingException { |
| AbstractBaseTest.closeEntityManagerFactory(puName); |
| return Persistence.createEntityManagerFactory(puName, EMF_PROPERTIES); |
| } |
| |
| @Override |
| public EntityManager getEntityManager() { |
| return AbstractBaseTest.createEntityManager(puName, EMF_PROPERTIES); |
| } |
| |
| @Override |
| public EntityManagerFactory getEntityManagerFactory() { |
| return AbstractBaseTest.getEntityManagerFactory(puName, EMF_PROPERTIES); |
| } |
| |
| @Override |
| public boolean isTransactionActive(EntityManager em) { |
| return AbstractBaseTest.this.isTransactionActive(em); |
| } |
| |
| @Override |
| public boolean isTransactionMarkedForRollback(EntityManager em) { |
| return AbstractBaseTest.this.getRollbackOnly(em); |
| } |
| |
| @Override |
| public void markTransactionForRollback(EntityManager em) { |
| throw new UnsupportedOperationException(); |
| } |
| |
| @Override |
| public void rollbackTransaction(EntityManager em) { |
| AbstractBaseTest.this.rollbackTransaction(em); |
| } |
| |
| @Override |
| public void rollbackTransactionAndClear(EntityManager em) { |
| try { |
| rollbackTransaction(em); |
| } finally { |
| em.clear(); |
| } |
| } |
| |
| @Override |
| public boolean usesExtendedPC() { |
| return true; |
| } |
| |
| @Override |
| public DataSource getDataSource() { |
| return AbstractBaseTest.this.getDataSource(); |
| } |
| |
| @Override |
| public EntityManagerFactory createNewEntityManagerFactory(Map<String, Object> properties) throws NamingException { |
| throw new UnsupportedOperationException(); |
| } |
| |
| @Override |
| public Object getPropertyValue(EntityManager em, String key) { |
| throw new UnsupportedOperationException(); |
| } |
| |
| @Override |
| public void evict(EntityManager em, Class<?> clazz) { |
| throw new UnsupportedOperationException(); |
| } |
| |
| @Override |
| public void evictAll(EntityManager em) { |
| throw new UnsupportedOperationException(); |
| } |
| |
| } |
| |
| public DataSource getDataSource() { |
| return dataSource; |
| } |
| |
| final public void closeEntityManager(EntityManager em) { |
| if (!em.isOpen()) { |
| return; |
| } |
| if (environment.isTransactionActive(em)/* |
| * ||environment. |
| * isTransactionMarkedForRollback |
| * (em) |
| */) { // FIXME discuss if tx is |
| // active if marked for |
| // rollback |
| environment.rollbackTransaction(em); |
| } |
| // // close application-managed entity manager |
| // if (!(getEnvironment() instanceof JTASharedPCEnvironment)) { |
| // em.close(); FIXME |
| // } |
| } |
| |
| protected static void verify(boolean condition, String string) { |
| Assert.assertTrue(string, condition); |
| } |
| |
| protected final void flop(final String msg) { |
| Assert.fail(msg); |
| } |
| |
| abstract protected String[] getClearableTableNames(); |
| |
| @Before |
| public void clearAllTablesAndSetup() throws SQLException { |
| clearAllTables(); |
| |
| setup(); |
| } |
| |
| protected void clearAllTables() throws SQLException { |
| Connection conn = getDataSource().getConnection(); |
| try { |
| conn.setAutoCommit(false); |
| |
| Set<String> existingTables = new HashSet<String>(); |
| DatabaseMetaData metaData = conn.getMetaData(); |
| String schemaPattern = null; |
| if (metaData.getDriverName().toLowerCase().contains("oracle")) { |
| schemaPattern = metaData.getUserName().toUpperCase(); |
| } |
| ResultSet rs = metaData.getTables(null, schemaPattern, "TMP_%", null); |
| try { |
| while (rs.next()) { |
| existingTables.add(rs.getString("TABLE_NAME").toUpperCase(Locale.ENGLISH)); |
| } |
| } finally { |
| rs.close(); |
| } |
| |
| Statement statement = conn.createStatement(); |
| try { |
| if (existingTables.contains("TMP_CASC_NODE")) { |
| statement.executeUpdate("update TMP_CASC_NODE set PARENT = null"); |
| } |
| if (existingTables.contains("TMP_NODE")) { |
| statement.executeUpdate("update TMP_NODE set PARENT = null"); |
| } |
| if (existingTables.contains("TMP_COP")) { |
| statement.executeUpdate("update TMP_COP set PARTNER_ID = null"); |
| } |
| if (existingTables.contains("TMP_UCOFFICE_CUBICLE")) { |
| statement.executeUpdate("delete from TMP_UCOFFICE_CUBICLE"); |
| existingTables.remove("TMP_UCOFFICE_CUBICLE"); |
| } |
| for (String name : getClearableTableNames()) { |
| if (existingTables.contains(name.toUpperCase(Locale.ENGLISH))) { |
| statement.executeUpdate("delete from " + name); |
| } |
| } |
| } catch (SQLException ex) { |
| System.err.println(ex.getMessage()); |
| throw ex; |
| } finally { |
| statement.close(); |
| } |
| conn.commit(); |
| } finally { |
| conn.close(); |
| } |
| |
| // TODO evictAll |
| |
| } |
| |
| /** |
| * intended to be overwritten by subclasses |
| */ |
| protected void setup() throws SQLException { |
| |
| } |
| |
| public static final <T extends Serializable> T serializeDeserialize(T serializable) throws IOException, ClassNotFoundException { |
| ByteArrayOutputStream out = new ByteArrayOutputStream(); |
| ObjectOutputStream objectOutputStream = new ObjectOutputStream(out); |
| try { |
| objectOutputStream.writeObject(serializable); |
| } finally { |
| objectOutputStream.close(); |
| } |
| ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); |
| return (T) new ObjectInputStream(in).readObject(); |
| } |
| |
| public static boolean isInsideEngine() { |
| return false; |
| } |
| |
| /** |
| * Checks whether the given throwable is of type |
| * java.lang.IllegalStateException, or otherwise if the throwable contains a |
| * java.lang.IllegalStateException somewhere in the cause stack. |
| * |
| * @param e |
| * The throwable to check |
| * @return <code>true</code> if the throwable is instance of or caused by |
| * java.lang.IllegalStateException |
| */ |
| protected final boolean checkForIllegalStateException(Throwable e) { |
| boolean contained = false; |
| while (e != null) { |
| if (e instanceof IllegalStateException) { |
| contained = true; |
| break; |
| } |
| e = e.getCause(); |
| } |
| return contained; |
| } |
| |
| /** |
| * Checks whether the given throwable is of type java.sql.SQLException, or |
| * otherwise if the throwable contains a java.sql.SQLException somewhere in |
| * the cause stack. |
| * |
| * @param e |
| * The throwable to check |
| * @return <code>true</code> if the throwable is instance of or caused by |
| * java.sql.SQLException |
| */ |
| protected final boolean checkForSQLException(Throwable e) { |
| boolean contained = false; |
| while (e != null) { |
| if (e instanceof SQLException) { |
| contained = true; |
| break; |
| } |
| e = e.getCause(); |
| } |
| return contained; |
| } |
| |
| /** |
| * Return if the transaction is active. This allows the same code to be used |
| * on the server where JTA is used. |
| */ |
| public boolean isTransactionActive(EntityManager entityManager) { |
| if (ServerInfoHolder.isOnServer()) { |
| return getServerPlatform().isTransactionActive(); |
| } else { |
| return entityManager.getTransaction().isActive(); |
| } |
| } |
| |
| /** |
| * Return if the transaction is roll back only. This allows the same code to |
| * be used on the server where JTA is used. |
| */ |
| public boolean getRollbackOnly(EntityManager entityManager) { |
| if (ServerInfoHolder.isOnServer()) { |
| return getServerPlatform().getRollbackOnly(); |
| } else { |
| return entityManager.getTransaction().getRollbackOnly(); |
| } |
| } |
| |
| /** |
| * Begin a transaction on the entity manager. This allows the same code to |
| * be used on the server where JTA is used. |
| */ |
| public void beginTransaction(EntityManager entityManager) { |
| if (ServerInfoHolder.isOnServer()) { |
| getServerPlatform().beginTransaction(); |
| } else { |
| entityManager.getTransaction().begin(); |
| } |
| } |
| |
| /** |
| * Commit a transaction on the entity manager. This allows the same code to |
| * be used on the server where JTA is used. |
| */ |
| public void commitTransaction(EntityManager entityManager) { |
| if (ServerInfoHolder.isOnServer()) { |
| getServerPlatform().commitTransaction(); |
| } else { |
| entityManager.getTransaction().commit(); |
| } |
| } |
| |
| /** |
| * Rollback a transaction on the entity manager. This allows the same code |
| * to be used on the server where JTA is used. |
| */ |
| public void rollbackTransaction(EntityManager entityManager) { |
| if (ServerInfoHolder.isOnServer()) { |
| getServerPlatform().rollbackTransaction(); |
| } else { |
| entityManager.getTransaction().rollback(); |
| } |
| } |
| |
| /** |
| * Return the server platform if running in JEE. |
| */ |
| public static ServerPlatform getServerPlatform() { |
| if (serverPlatform == null) { |
| serverPlatform = new JEEPlatform(); |
| } |
| return serverPlatform; |
| } |
| |
| /** |
| * Create a new entity manager for the "default" persistence unit. If in JEE |
| * this will create or return the active managed entity manager. |
| */ |
| public static EntityManager createEntityManager() { |
| if (ServerInfoHolder.isOnServer()) { |
| return getServerPlatform().getEntityManager("default"); |
| } else { |
| return getEntityManagerFactory().createEntityManager(); |
| } |
| } |
| |
| /** |
| * Create a new entity manager for the persistence unit using the |
| * properties. The properties will only be used the first time this entity |
| * manager is accessed. If in JEE this will create or return the active |
| * managed entity manager. |
| */ |
| public static EntityManager createEntityManager(String persistenceUnitName, Map<String, String> properties) { |
| if (ServerInfoHolder.isOnServer()) { |
| return getServerPlatform().getEntityManager(persistenceUnitName); |
| } else { |
| return getEntityManagerFactory(persistenceUnitName, properties).createEntityManager(); |
| } |
| } |
| |
| public static EntityManagerFactory getEntityManagerFactory(String persistenceUnitName) { |
| return getEntityManagerFactory(persistenceUnitName, JUnitTestCaseHelper.getDatabaseProperties()); |
| } |
| |
| public static EntityManagerFactory getEntityManagerFactory(String persistenceUnitName, Map<String, String> properties) { |
| if (ServerInfoHolder.isOnServer()) { |
| return getServerPlatform().getEntityManagerFactory(persistenceUnitName); |
| } else { |
| EntityManagerFactory emfNamedPersistenceUnit = emfNamedPersistenceUnits.get(persistenceUnitName); |
| if (emfNamedPersistenceUnit == null) { |
| emfNamedPersistenceUnit = Persistence.createEntityManagerFactory(persistenceUnitName, properties); |
| emfNamedPersistenceUnits.put(persistenceUnitName, emfNamedPersistenceUnit); |
| } |
| return emfNamedPersistenceUnit; |
| } |
| } |
| |
| public static EntityManagerFactory getEntityManagerFactory() { |
| return getEntityManagerFactory("default"); |
| } |
| |
| public static void closeEntityManagerFactory() { |
| closeEntityManagerFactory("default"); |
| } |
| |
| public static void closeEntityManagerFactory(String persistenceUnitName) { |
| EntityManagerFactory emfNamedPersistenceUnit = emfNamedPersistenceUnits.get(persistenceUnitName); |
| if (emfNamedPersistenceUnit != null) { |
| if (emfNamedPersistenceUnit.isOpen()) { |
| emfNamedPersistenceUnit.close(); |
| } |
| emfNamedPersistenceUnits.remove(persistenceUnitName); |
| } |
| } |
| |
| public static boolean seesJPA2() { |
| return seesJPA2; |
| } |
| |
| public static Map<String, String> getTestProperties() { |
| if (ServerInfoHolder.isOnServer()) { |
| return ServerInfoHolder.getTestProperties(); |
| } else { |
| return JUnitTestCaseHelper.getDatabaseProperties(); |
| } |
| |
| } |
| } |