| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| package org.apache.openjpa.ee; |
| |
| import java.io.File; |
| import java.io.InputStream; |
| import java.util.ArrayList; |
| import java.util.Dictionary; |
| import java.util.List; |
| |
| import javax.transaction.HeuristicMixedException; |
| import javax.transaction.HeuristicRollbackException; |
| import javax.transaction.InvalidTransactionException; |
| import javax.transaction.NotSupportedException; |
| import javax.transaction.RollbackException; |
| import javax.transaction.SystemException; |
| import javax.transaction.Transaction; |
| import javax.transaction.TransactionManager; |
| |
| import junit.framework.AssertionFailedError; |
| import junit.framework.TestCase; |
| |
| import org.apache.openjpa.util.InternalException; |
| import org.osgi.framework.Bundle; |
| import org.osgi.framework.BundleContext; |
| import org.osgi.framework.BundleException; |
| import org.osgi.framework.BundleListener; |
| import org.osgi.framework.Filter; |
| import org.osgi.framework.FrameworkListener; |
| import org.osgi.framework.InvalidSyntaxException; |
| import org.osgi.framework.ServiceEvent; |
| import org.osgi.framework.ServiceListener; |
| import org.osgi.framework.ServiceReference; |
| import org.osgi.framework.ServiceRegistration; |
| |
| /** |
| * Test javax.transaction.TransactionManager OSGi service discovery. |
| */ |
| public class TestOSGiManagedRuntime extends TestCase { |
| |
| private static final String TXN_MANAGER_CLASS_NAME = "javax.transaction.TransactionManager"; |
| |
| /** |
| * A transaction manager instance an nothing more. |
| */ |
| private static final TransactionManager TXN_MANAGER = new TransactionManager() { |
| |
| public void begin() throws NotSupportedException, SystemException { |
| } |
| |
| public void commit() throws HeuristicMixedException, |
| HeuristicRollbackException, IllegalStateException, |
| RollbackException, SecurityException, SystemException { |
| } |
| |
| public int getStatus() throws SystemException { |
| return 0; |
| } |
| |
| public Transaction getTransaction() throws SystemException { |
| return null; |
| } |
| |
| public void resume(Transaction tobj) throws IllegalStateException, |
| InvalidTransactionException, SystemException { |
| } |
| |
| public void rollback() throws IllegalStateException, SecurityException, |
| SystemException { |
| } |
| |
| public void setRollbackOnly() throws IllegalStateException, |
| SystemException { |
| } |
| |
| public void setTransactionTimeout(int seconds) throws SystemException { |
| } |
| |
| public Transaction suspend() throws SystemException { |
| return null; |
| } |
| |
| public String toString() { |
| return TestOSGiManagedRuntime.class.getName()+"::TXN_MANAGER"; |
| } |
| }; |
| |
| /** |
| * A service reference instance an nothing more. |
| */ |
| private static final ServiceReference TXN_SVC_REFERENCE = new ServiceReference() { |
| |
| @Override |
| public boolean isAssignableTo(Bundle bundle, String className) { |
| return false; |
| } |
| |
| @Override |
| public Bundle[] getUsingBundles() { |
| return null; |
| } |
| |
| @Override |
| public String[] getPropertyKeys() { |
| return null; |
| } |
| |
| @Override |
| public Object getProperty(String key) { |
| return null; |
| } |
| |
| @Override |
| public Bundle getBundle() { |
| return null; |
| } |
| |
| @Override |
| public int compareTo(Object reference) { |
| return reference == TXN_SVC_REFERENCE ? 0 : 1; |
| } |
| |
| public String toString() { |
| return TestOSGiManagedRuntime.class.getName()+"::TXN_SVC_REFERENCE"; |
| } |
| }; |
| |
| /** |
| * A fake bundle context with a reference counter for a javax.transaction.TRansactionManager |
| */ |
| private static final class TestBundleContext implements BundleContext { |
| |
| private List<ServiceListener> serviceListeners; |
| private TransactionManager transactionManager; |
| private int txnRefCount; |
| |
| public void setTransactionManager(TransactionManager transactionManager) { |
| |
| if (transactionManager == null) { |
| |
| if (this.serviceListeners != null) { |
| for (ServiceListener listener :this.serviceListeners) { |
| listener.serviceChanged(new ServiceEvent(ServiceEvent.UNREGISTERING,TXN_SVC_REFERENCE)); |
| } |
| } |
| } |
| |
| // test for properly calling ungetReference(). |
| assertEquals(0,this.txnRefCount); |
| this.transactionManager = transactionManager; |
| |
| if (transactionManager != null) { |
| |
| if (this.serviceListeners != null) { |
| for (ServiceListener listener :this.serviceListeners) { |
| listener.serviceChanged(new ServiceEvent(ServiceEvent.REGISTERED,TXN_SVC_REFERENCE)); |
| } |
| } |
| } |
| } |
| |
| public int getServiceListenerCount() { |
| |
| if (this.serviceListeners == null) { |
| return 0; |
| } |
| else { |
| return this.serviceListeners.size(); |
| } |
| } |
| |
| public int getTxnRefCount() { |
| return this.txnRefCount; |
| } |
| |
| public String getProperty(String key) { |
| throw new UnsupportedOperationException(); |
| } |
| |
| public Bundle getBundle() { |
| throw new UnsupportedOperationException(); |
| } |
| |
| public Bundle installBundle(String location, InputStream input) |
| throws BundleException { |
| throw new UnsupportedOperationException(); |
| } |
| |
| public Bundle installBundle(String location) throws BundleException { |
| throw new UnsupportedOperationException(); |
| } |
| |
| public Bundle getBundle(long id) { |
| throw new UnsupportedOperationException(); |
| } |
| |
| public Bundle[] getBundles() { |
| throw new UnsupportedOperationException(); |
| } |
| |
| public void addServiceListener(ServiceListener listener, String filter) |
| throws InvalidSyntaxException { |
| |
| assertEquals("(objectClass="+TXN_MANAGER_CLASS_NAME+")",filter); |
| |
| if (this.serviceListeners == null) |
| this.serviceListeners = new ArrayList<ServiceListener>(); |
| |
| this.serviceListeners.add(listener); |
| } |
| |
| public void addServiceListener(ServiceListener listener) { |
| |
| throw new AssertionFailedError("service listener must be added using an objectClass filter."); |
| } |
| |
| public void removeServiceListener(ServiceListener listener) { |
| |
| if (this.serviceListeners == null || ! this.serviceListeners.remove(listener)) { |
| throw new AssertionFailedError("Try to remove service listener, which has not been added before."); |
| } |
| |
| assertEquals(0,this.txnRefCount); |
| } |
| |
| public void addBundleListener(BundleListener listener) { |
| throw new UnsupportedOperationException(); |
| } |
| |
| public void removeBundleListener(BundleListener listener) { |
| throw new UnsupportedOperationException(); |
| } |
| |
| public void addFrameworkListener(FrameworkListener listener) { |
| throw new UnsupportedOperationException(); |
| } |
| |
| public void removeFrameworkListener(FrameworkListener listener) { |
| throw new UnsupportedOperationException(); |
| } |
| |
| @SuppressWarnings("rawtypes") |
| public ServiceRegistration registerService(String[] clazzes, |
| Object service, Dictionary properties) { |
| throw new UnsupportedOperationException(); |
| } |
| |
| @SuppressWarnings("rawtypes") |
| public ServiceRegistration registerService(String clazz, |
| Object service, Dictionary properties) { |
| throw new UnsupportedOperationException(); |
| } |
| |
| public ServiceReference[] getServiceReferences(String clazz, |
| String filter) throws InvalidSyntaxException { |
| throw new UnsupportedOperationException(); |
| } |
| |
| public ServiceReference[] getAllServiceReferences(String clazz, |
| String filter) throws InvalidSyntaxException { |
| throw new UnsupportedOperationException(); |
| } |
| |
| public ServiceReference getServiceReference(String clazz) { |
| |
| assertEquals(TXN_MANAGER_CLASS_NAME,clazz); |
| |
| if (this.transactionManager == null) { |
| return null; |
| } |
| |
| assertEquals(TXN_MANAGER_CLASS_NAME,clazz); |
| return TXN_SVC_REFERENCE; |
| } |
| |
| @Override |
| public Object getService(ServiceReference reference) { |
| |
| assertSame(TXN_SVC_REFERENCE,reference); |
| ++this.txnRefCount; |
| return this.transactionManager; |
| } |
| |
| @Override |
| public boolean ungetService(ServiceReference reference) { |
| |
| assertSame(TXN_SVC_REFERENCE,reference); |
| --this.txnRefCount; |
| return true; |
| } |
| |
| public File getDataFile(String filename) { |
| throw new UnsupportedOperationException(); |
| } |
| |
| public Filter createFilter(String filter) throws InvalidSyntaxException { |
| throw new UnsupportedOperationException(); |
| } |
| |
| } |
| |
| private static void assertTxnManagerAvailable(TestBundleContext context, ManagedRuntime mr) throws Exception { |
| |
| assertSame(TXN_MANAGER,mr.getTransactionManager()); |
| assertEquals(1,context.getTxnRefCount()); |
| } |
| |
| private static void assertTxnManagerUnavailable(TestBundleContext context, ManagedRuntime mr) throws Exception { |
| |
| InternalException ie = null; |
| |
| try { |
| mr.getTransactionManager(); |
| } catch (InternalException e) { |
| ie = e; |
| } |
| assertNotNull(ie); |
| assertEquals(0,context.getTxnRefCount()); |
| } |
| |
| /** |
| * Test the discovery, when transaction manager is available before starting |
| * OSGiManagedRuntime and disappears after stopping the managed runtime. |
| * |
| * @throws Throwable |
| */ |
| public void testTxnServiceDiscoveryPreStartPostStop() throws Throwable { |
| |
| TestBundleContext context = new TestBundleContext(); |
| context.setTransactionManager(TXN_MANAGER); |
| |
| OSGiManagedRuntime.registerServiceListener(context); |
| |
| ManagedRuntime mr = new OSGiManagedRuntime(); |
| |
| try { |
| |
| assertEquals(1,context.getServiceListenerCount()); |
| |
| assertTxnManagerAvailable(context, mr); |
| |
| context.setTransactionManager(null); |
| |
| assertTxnManagerUnavailable(context, mr); |
| |
| OSGiManagedRuntime.deregisterServiceListener(context); |
| } |
| catch(Throwable e) { |
| // this is her in order to make test repeatable in one JVM, because |
| // OSGiManagerRuntime has static properties. |
| OSGiManagedRuntime.deregisterServiceListener(context); |
| throw e; |
| } |
| assertEquals(0,context.getServiceListenerCount()); |
| |
| assertTxnManagerUnavailable(context, mr); |
| } |
| |
| /** |
| * Test the discovery, when transaction manager is available before starting |
| * OSGiManagedRuntime and disappears before stopping the managed runtime. |
| * |
| * @throws Throwable |
| */ |
| public void testTxnServiceDiscoveryPreStartPreStop() throws Throwable { |
| |
| TestBundleContext context = new TestBundleContext(); |
| context.setTransactionManager(TXN_MANAGER); |
| |
| OSGiManagedRuntime.registerServiceListener(context); |
| |
| ManagedRuntime mr = new OSGiManagedRuntime(); |
| |
| try { |
| |
| assertEquals(1,context.getServiceListenerCount()); |
| |
| assertTxnManagerAvailable(context, mr); |
| |
| OSGiManagedRuntime.deregisterServiceListener(context); |
| } |
| catch(Throwable e) { |
| // this is her in order to make test repeatable in one JVM, because |
| // OSGiManagerRuntime has static properties. |
| OSGiManagedRuntime.deregisterServiceListener(context); |
| throw e; |
| } |
| assertEquals(0,context.getServiceListenerCount()); |
| |
| assertTxnManagerUnavailable(context, mr); |
| } |
| |
| /** |
| * Test the discovery, when transaction manager becomes available after starting |
| * OSGiManagedRuntime and disappears after stopping the managed runtime. |
| * |
| * @throws Throwable |
| */ |
| public void testTxnServiceDiscoveryPostStartPostStop() throws Throwable { |
| |
| TestBundleContext context = new TestBundleContext(); |
| |
| OSGiManagedRuntime.registerServiceListener(context); |
| ManagedRuntime mr = new OSGiManagedRuntime(); |
| |
| try{ |
| assertEquals(1,context.getServiceListenerCount()); |
| |
| assertTxnManagerUnavailable(context, mr); |
| |
| context.setTransactionManager(TXN_MANAGER); |
| |
| assertTxnManagerAvailable(context, mr); |
| |
| OSGiManagedRuntime.deregisterServiceListener(context); |
| } |
| catch(Throwable e) { |
| // this is her in order to make test repeatable in one JVM, because |
| // OSGiManagerRuntime has static proeprties. |
| OSGiManagedRuntime.deregisterServiceListener(context); |
| throw e; |
| } |
| assertEquals(0,context.getServiceListenerCount()); |
| |
| assertTxnManagerUnavailable(context, mr); |
| } |
| |
| /** |
| * Test the discovery, when transaction manager becomes available after starting |
| * OSGiManagedRuntime and disappears before stopping the managed runtime. |
| * |
| * @throws Throwable |
| */ |
| public void testTxnServiceDiscoveryPostStartPreStop() throws Throwable { |
| |
| TestBundleContext context = new TestBundleContext(); |
| |
| OSGiManagedRuntime.registerServiceListener(context); |
| ManagedRuntime mr = new OSGiManagedRuntime(); |
| |
| try { |
| assertEquals(1,context.getServiceListenerCount()); |
| |
| assertTxnManagerUnavailable(context, mr); |
| |
| context.setTransactionManager(TXN_MANAGER); |
| |
| assertTxnManagerAvailable(context, mr); |
| |
| context.setTransactionManager(null); |
| |
| assertTxnManagerUnavailable(context, mr); |
| |
| OSGiManagedRuntime.deregisterServiceListener(context); |
| } |
| catch(Throwable e) { |
| // this is her in order to make test repeatable in one JVM, because |
| // OSGiManagerRuntime has static proeprties. |
| OSGiManagedRuntime.deregisterServiceListener(context); |
| throw e; |
| } |
| assertEquals(0,context.getServiceListenerCount()); |
| |
| assertTxnManagerUnavailable(context, mr); |
| } |
| } |