/* * Copyright (c) MuleSoft, Inc. All rights reserved. http://www.mulesoft.com * The software in this package is published under the terms of the CPAL v1.0 * license, a copy of which has been included with this distribution in the * LICENSE.txt file. */ package org.mule.runtime.config.spring; import static java.util.concurrent.Executors.newCachedThreadPool; import static org.hamcrest.core.Is.is; import static org.hamcrest.core.IsInstanceOf.instanceOf; import static org.junit.Assert.assertThat; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.withSettings; import org.mule.runtime.api.exception.MuleException; import org.mule.runtime.api.exception.MuleRuntimeException; import org.mule.runtime.api.lifecycle.Disposable; import org.mule.runtime.api.lifecycle.Startable; import org.mule.runtime.core.api.MuleContext; import org.mule.runtime.core.api.registry.RegistrationException; import org.mule.runtime.core.api.registry.Registry; import org.mule.runtime.core.util.concurrent.Latch; import org.mule.tck.core.registry.AbstractRegistryTestCase; import org.mule.tck.probe.JUnitLambdaProbe; import org.mule.tck.probe.PollingProber; import java.util.Collection; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Future; import org.hamcrest.core.Is; import org.junit.Test; import org.springframework.context.support.StaticApplicationContext; public class SpringRegistryTestCase extends AbstractRegistryTestCase { public static final String BEAN_KEY = "someBean"; public static final String ANOTHER_BEAN_KEY = "someOtherBean"; public static final String REGISTERY_ID = "someId"; private StaticApplicationContext applicationContext; private StaticApplicationContext parentApplicationContext; private SpringRegistry springRegistry; @Override public Registry getRegistry() { return new SpringRegistry(new StaticApplicationContext(), null); } @Test public void lookupByTypeSearchInParentAlso() { createSpringRegistryWithParentContext(); applicationContext.registerSingleton(BEAN_KEY, String.class); parentApplicationContext.registerSingleton(ANOTHER_BEAN_KEY, String.class); Collection<String> values = springRegistry.lookupObjects(String.class); assertThat(values.size(), is(2)); } @Test public void lookupByIdReturnsApplicationContextBean() { createSpringRegistryWithParentContext(); applicationContext.registerSingleton(BEAN_KEY, String.class); parentApplicationContext.registerSingleton(BEAN_KEY, Integer.class); assertThat(springRegistry.get(BEAN_KEY), is(instanceOf(String.class))); } @Test public void lookupByIdReturnsParentApplicationContextBean() { createSpringRegistryWithParentContext(); parentApplicationContext.registerSingleton(BEAN_KEY, Object.class); assertThat(springRegistry.get(BEAN_KEY), Is.is(Object.class)); } @Test public void lookupByLifecycleReturnsApplicationContextBeanOnly() { createSpringRegistryWithParentContext(); applicationContext.registerSingleton(BEAN_KEY, String.class); parentApplicationContext.registerSingleton(ANOTHER_BEAN_KEY, String.class); assertThat(springRegistry.lookupObjectsForLifecycle(String.class).size(), is(1)); } private void createSpringRegistryWithParentContext() { applicationContext = new StaticApplicationContext(); parentApplicationContext = new StaticApplicationContext(); springRegistry = new SpringRegistry(REGISTERY_ID, applicationContext, parentApplicationContext, null); } @Test public void registerObjectAsynchronously() throws MuleException, InterruptedException, ExecutionException { final MuleContext muleContext = mock(MuleContext.class); springRegistry = new SpringRegistry(new StaticApplicationContext(), muleContext); springRegistry.initialise(); springRegistry.getLifecycleManager().fireLifecycle(Startable.PHASE_NAME); final Startable asyncStartableBean = mock(Startable.class, withSettings().extraInterfaces(Disposable.class)); final Latch startingLatch = new Latch(); final Latch disposingLatch = new Latch(); doAnswer(invocation -> { startingLatch.countDown(); synchronized (muleContext) { disposingLatch.await(); } verify((Disposable) asyncStartableBean, never()).dispose(); return null; }).when(asyncStartableBean).start(); ((Disposable) doAnswer(invocation -> { return null; }).when(asyncStartableBean)).dispose(); final ExecutorService threadPool = newCachedThreadPool(); try { final Future<?> submittedStop = threadPool.submit(() -> { try { springRegistry.registerObject(BEAN_KEY, asyncStartableBean); } catch (RegistrationException e) { throw new MuleRuntimeException(e); } }); final Future<?> submittedRegistryDispose = threadPool.submit(() -> { try { startingLatch.await(); } catch (InterruptedException e) { throw new MuleRuntimeException(e); } disposingLatch.countDown(); synchronized (muleContext) { springRegistry.dispose(); } }); submittedRegistryDispose.get(); submittedStop.get(); } finally { threadPool.shutdownNow(); } new PollingProber().check(new JUnitLambdaProbe(() -> { try { verify(asyncStartableBean).start(); verify((Disposable) asyncStartableBean).dispose(); return true; } catch (MuleException e) { throw new MuleRuntimeException(e); } })); } }