/* * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html */ package org.opendaylight.protocol.integration.pcep; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotSame; import static org.junit.Assert.assertSame; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyZeroInteractions; import static org.mockito.Mockito.when; import static org.ops4j.pax.exam.CoreOptions.frameworkProperty; import static org.ops4j.pax.exam.CoreOptions.junitBundles; import static org.ops4j.pax.exam.CoreOptions.mavenBundle; import static org.ops4j.pax.exam.CoreOptions.options; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; import java.lang.reflect.Method; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mockito; import org.opendaylight.controller.sal.binding.api.BindingAwareBroker; import org.opendaylight.controller.sal.binding.api.BindingAwareConsumer; import org.opendaylight.controller.sal.binding.api.BindingAwareProvider; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.network.topology.rev140113.NetworkTopologyContext; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.network.topology.rev140113.NetworkTopologyRef; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.programming.rev131106.NetworkTopologyPcepProgrammingService; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.programming.rev131106.SubmitAddLspInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.programming.rev131106.SubmitAddLspInputBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.programming.rev131106.SubmitTriggerSyncInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.programming.rev131106.SubmitTriggerSyncInputBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.programming.rev131106.SubmitUpdateLspInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.programming.rev131106.SubmitUpdateLspInputBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.AddLspInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.AddLspInputBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.AddLspOutput; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.EnsureLspOperationalInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.EnsureLspOperationalInputBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.NetworkTopologyPcepService; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.TriggerSyncInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.TriggerSyncInputBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.TriggerSyncOutput; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.tunnel.pcep.programming.rev131030.PcepCreateP2pTunnelInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.tunnel.pcep.programming.rev131030.PcepCreateP2pTunnelInputBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.tunnel.pcep.programming.rev131030.PcepDestroyTunnelInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.tunnel.pcep.programming.rev131030.PcepDestroyTunnelInputBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.tunnel.pcep.programming.rev131030.TopologyTunnelPcepProgrammingService; import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology; import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology; import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.opendaylight.yangtools.yang.common.RpcResultBuilder; import org.ops4j.pax.exam.Option; import org.ops4j.pax.exam.junit.PaxExam; import org.ops4j.pax.exam.options.DefaultCompositeOption; import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy; import org.ops4j.pax.exam.spi.reactors.PerClass; @RunWith(PaxExam.class) @ExamReactorStrategy(PerClass.class) public class PcepRpcServicesRoutingTest extends AbstractPcepOsgiTest { @Override protected Option[] getAdditionalOptions() { // register option to provide Mockito as a bundle dependency return options( new DefaultCompositeOption( // Repository required to load harmcrest (OSGi-fied version). // Mockito mavenBundle("org.mockito", "mockito-core", "1.10.19"), mavenBundle("org.objenesis", "objenesis", "2.2"), junitBundles(), /* * Felix has implicit boot delegation enabled by default. It * conflicts with Mockito: java.lang.LinkageError: loader * constraint violation in interface itable initialization: when * resolving method * "org.osgi.service.useradmin.User$$EnhancerByMockitoWithCGLIB$$dd2f81dc * . * newInstance(Lorg/mockito/cglib/proxy/Callback;)Ljava/lang/Object * ;" the class loader (instance of * org/mockito/internal/creation/jmock/SearchingClassLoader) of * the current class, org/osgi/service/useradmin/ * User$$EnhancerByMockitoWithCGLIB$$dd2f81dc, and the class * loader (instance of org/apache/felix/framework/ * BundleWiringImpl$BundleClassLoaderJava5) for interface * org/mockito/cglib/proxy/Factory have different Class objects * for the type org/mockito/cglib/ proxy/Callback used in the * signature * * So we disable the bootdelegation. this property has no effect * on the other OSGi implementation. */ frameworkProperty("felix.bootdelegation.implicit").value("false")) ); } private static <T> T getInputForRpc(final InstanceIdentifier<Topology> topology, final Class<?> builderClass, final Class<T> builtObjectClass) { try { final Object builderInstance = builderClass.newInstance(); final Method method = builderClass.getMethod("setNetworkTopologyRef", NetworkTopologyRef.class); method.invoke(builderInstance, new NetworkTopologyRef(topology)); return builtObjectClass.cast(builderClass.getMethod("build").invoke(builderInstance)); } catch (final Exception e) { throw new RuntimeException("Unable to create instance from " + builderClass, e); } } @Test public void testRoutedRpcNetworkTopologyPcepService() throws Exception { final NetworkTopologyPcepService pcepService1 = mock(NetworkTopologyPcepService.class, "First pcep Service"); final NetworkTopologyPcepService pcepService2 = mock(NetworkTopologyPcepService.class, "Second pcep Service"); initMock(pcepService1); initMock(pcepService2); assertNotNull(getBroker()); final InstanceIdentifier<Topology> topology = InstanceIdentifier.builder(NetworkTopology.class).child(Topology.class, new TopologyKey(getTopologyId("Topo1"))).build(); final BindingAwareProvider provider1 = new AbstractTestProvider() { @Override public void onSessionInitiated(final BindingAwareBroker.ProviderContext session) { assertNotNull(session); final BindingAwareBroker.RoutedRpcRegistration<NetworkTopologyPcepService> firstReg = session.addRoutedRpcImplementation( NetworkTopologyPcepService.class, pcepService1); assertNotNull("Registration should not be null", firstReg); assertSame(pcepService1, firstReg.getInstance()); firstReg.registerPath(NetworkTopologyContext.class, topology); } }; this.broker.registerProvider(provider1); final InstanceIdentifier<Topology> topology2 = InstanceIdentifier.builder(NetworkTopology.class).child(Topology.class, new TopologyKey(getTopologyId("Topo2"))).build(); final BindingAwareProvider provider2 = new AbstractTestProvider() { @Override public void onSessionInitiated(final BindingAwareBroker.ProviderContext session) { assertNotNull(session); final BindingAwareBroker.RoutedRpcRegistration<NetworkTopologyPcepService> secondReg = session.addRoutedRpcImplementation( NetworkTopologyPcepService.class, pcepService2); secondReg.registerPath(NetworkTopologyContext.class, topology2); } }; this.broker.registerProvider(provider2); final BindingAwareConsumer consumer = new BindingAwareConsumer() { @Override public void onSessionInitialized(final BindingAwareBroker.ConsumerContext session) { final NetworkTopologyPcepService consumerPcepService = session.getRpcService(NetworkTopologyPcepService.class); assertNotNull(consumerPcepService); assertNotSame(pcepService1, consumerPcepService); assertNotSame(pcepService2, consumerPcepService); testAddLspRpce(consumerPcepService); testEnsureLspRpce(consumerPcepService); testTriggerSyncRpce(consumerPcepService); } private void testAddLspRpce(final NetworkTopologyPcepService consumerPcepService) { AddLspInput addLspInput = getInputForRpc(topology, AddLspInputBuilder.class, AddLspInput.class); consumerPcepService.addLsp(addLspInput); verify(pcepService1).addLsp(addLspInput); verifyZeroInteractions(pcepService2); addLspInput = getInputForRpc(topology2, AddLspInputBuilder.class, AddLspInput.class); consumerPcepService.addLsp(addLspInput); verifyZeroInteractions(pcepService1); verify(pcepService2).addLsp(addLspInput); } private void testTriggerSyncRpce(final NetworkTopologyPcepService consumerPcepService) { TriggerSyncInput triggerInput = getInputForRpc(topology, TriggerSyncInputBuilder.class, TriggerSyncInput.class); consumerPcepService.triggerSync(triggerInput); verify(pcepService1).triggerSync(triggerInput); verifyZeroInteractions(pcepService2); triggerInput = getInputForRpc(topology2, TriggerSyncInputBuilder.class, TriggerSyncInput.class); consumerPcepService.triggerSync(triggerInput); verifyZeroInteractions(pcepService1); verify(pcepService2).triggerSync(triggerInput); } private void testEnsureLspRpce(final NetworkTopologyPcepService consumerPcepService) { EnsureLspOperationalInput ensureInput = getInputForRpc(topology, EnsureLspOperationalInputBuilder.class, EnsureLspOperationalInput.class); consumerPcepService.ensureLspOperational(ensureInput); verify(pcepService1).ensureLspOperational(ensureInput); verifyZeroInteractions(pcepService2); ensureInput = getInputForRpc(topology2, EnsureLspOperationalInputBuilder.class, EnsureLspOperationalInput.class); consumerPcepService.ensureLspOperational(ensureInput); verifyZeroInteractions(pcepService1); verify(pcepService2).ensureLspOperational(ensureInput); } }; this.broker.registerConsumer(consumer); } @SuppressWarnings("unchecked") private void initMock(final NetworkTopologyPcepService pcepService) { @SuppressWarnings("rawtypes") final ListenableFuture future = Futures.immediateFuture(RpcResultBuilder.<AddLspOutput>success().build()); final ListenableFuture futureSyncTrigger = Futures.immediateFuture(RpcResultBuilder.<TriggerSyncOutput>success().build()); when(pcepService.addLsp(Mockito.any())).thenReturn(future); when(pcepService.removeLsp(Mockito.any())).thenReturn(future); when(pcepService.triggerSync(Mockito.any())).thenReturn(futureSyncTrigger); when(pcepService.ensureLspOperational(Mockito.any())).thenReturn(future); when(pcepService.updateLsp(Mockito.any())).thenReturn(future); } @Test public void testRoutedRpcNetworkTopologyPcepProgrammingService() throws Exception { final NetworkTopologyPcepProgrammingService pcepService1 = mock(NetworkTopologyPcepProgrammingService.class, "First pcep program Service"); final NetworkTopologyPcepProgrammingService pcepService2 = mock(NetworkTopologyPcepProgrammingService.class, "Second pcep program Service"); initMock(pcepService1); initMock(pcepService2); assertNotNull(getBroker()); final InstanceIdentifier<Topology> topology = InstanceIdentifier.builder(NetworkTopology.class).child(Topology.class, new TopologyKey(getTopologyId("Topo1"))).build(); final BindingAwareProvider provider1 = new AbstractTestProvider() { @Override public void onSessionInitiated(final BindingAwareBroker.ProviderContext session) { assertNotNull(session); final BindingAwareBroker.RoutedRpcRegistration<NetworkTopologyPcepProgrammingService> firstReg = session.addRoutedRpcImplementation( NetworkTopologyPcepProgrammingService.class, pcepService1); assertNotNull("Registration should not be null", firstReg); assertSame(pcepService1, firstReg.getInstance()); firstReg.registerPath(NetworkTopologyContext.class, topology); } }; this.broker.registerProvider(provider1); final InstanceIdentifier<Topology> topology2 = InstanceIdentifier.builder(NetworkTopology.class).child(Topology.class, new TopologyKey(getTopologyId("Topo2"))).build(); final BindingAwareProvider provider2 = new AbstractTestProvider() { @Override public void onSessionInitiated(final BindingAwareBroker.ProviderContext session) { assertNotNull(session); final BindingAwareBroker.RoutedRpcRegistration<NetworkTopologyPcepProgrammingService> secondReg = session.addRoutedRpcImplementation( NetworkTopologyPcepProgrammingService.class, pcepService2); secondReg.registerPath(NetworkTopologyContext.class, topology2); } }; this.broker.registerProvider(provider2); final BindingAwareConsumer consumer = new BindingAwareConsumer() { @Override public void onSessionInitialized(final BindingAwareBroker.ConsumerContext session) { final NetworkTopologyPcepProgrammingService consumerPcepService = session.getRpcService(NetworkTopologyPcepProgrammingService.class); assertNotNull(consumerPcepService); assertNotSame(pcepService1, consumerPcepService); assertNotSame(pcepService2, consumerPcepService); testSubmitAddLspRpc(consumerPcepService); testSubmitUpdateLspRpc(consumerPcepService); testTriggerSyncRpc(consumerPcepService); } private void testSubmitAddLspRpc(final NetworkTopologyPcepProgrammingService consumerPcepService) { SubmitAddLspInput addLspInput = getInputForRpc(topology, SubmitAddLspInputBuilder.class, SubmitAddLspInput.class); consumerPcepService.submitAddLsp(addLspInput); verify(pcepService1).submitAddLsp(addLspInput); verifyZeroInteractions(pcepService2); addLspInput = getInputForRpc(topology2, SubmitAddLspInputBuilder.class, SubmitAddLspInput.class); consumerPcepService.submitAddLsp(addLspInput); verifyZeroInteractions(pcepService1); verify(pcepService2).submitAddLsp(addLspInput); } private void testSubmitUpdateLspRpc(final NetworkTopologyPcepProgrammingService consumerPcepService) { SubmitUpdateLspInput submitLspInput = getInputForRpc(topology, SubmitUpdateLspInputBuilder.class, SubmitUpdateLspInput.class); consumerPcepService.submitUpdateLsp(submitLspInput); verify(pcepService1).submitUpdateLsp(submitLspInput); verifyZeroInteractions(pcepService2); submitLspInput = getInputForRpc(topology2, SubmitUpdateLspInputBuilder.class, SubmitUpdateLspInput.class); consumerPcepService.submitUpdateLsp(submitLspInput); verifyZeroInteractions(pcepService1); verify(pcepService2).submitUpdateLsp(submitLspInput); } private void testTriggerSyncRpc(final NetworkTopologyPcepProgrammingService consumerPcepService) { SubmitTriggerSyncInput submitTriggerSyncInput = getInputForRpc(topology, SubmitTriggerSyncInputBuilder.class, SubmitTriggerSyncInput.class); consumerPcepService.submitTriggerSync(submitTriggerSyncInput); verify(pcepService1).submitTriggerSync(submitTriggerSyncInput); verifyZeroInteractions(pcepService2); submitTriggerSyncInput = getInputForRpc(topology2, SubmitTriggerSyncInputBuilder.class, SubmitTriggerSyncInput.class); consumerPcepService.submitTriggerSync(submitTriggerSyncInput); verifyZeroInteractions(pcepService1); verify(pcepService2).submitTriggerSync(submitTriggerSyncInput); } }; this.broker.registerConsumer(consumer); } @SuppressWarnings("unchecked") private void initMock(final NetworkTopologyPcepProgrammingService pcepService) { @SuppressWarnings("rawtypes") final ListenableFuture future = Futures.immediateFuture(RpcResultBuilder.<AddLspOutput>success().build()); final ListenableFuture futureTriggerSync = Futures.immediateFuture(RpcResultBuilder.<TriggerSyncOutput>success().build()); when(pcepService.submitAddLsp(Mockito.any())).thenReturn(future); when(pcepService.submitRemoveLsp(Mockito.any())).thenReturn(future); when(pcepService.submitTriggerSync(Mockito.any())).thenReturn(futureTriggerSync); when(pcepService.submitEnsureLspOperational(Mockito.any())).thenReturn(future); when(pcepService.submitUpdateLsp(Mockito.any())).thenReturn(future); } @Test public void testRoutedRpcTopologyTunnelPcepProgrammingService() throws Exception { final TopologyTunnelPcepProgrammingService pcepService1 = mock(TopologyTunnelPcepProgrammingService.class, "First pcep program Service"); final TopologyTunnelPcepProgrammingService pcepService2 = mock(TopologyTunnelPcepProgrammingService.class, "Second pcep program Service"); initMock(pcepService1); initMock(pcepService2); assertNotNull(getBroker()); final InstanceIdentifier<Topology> topology = InstanceIdentifier.builder(NetworkTopology.class).child(Topology.class, new TopologyKey(getTopologyId("Topo1"))).build(); final BindingAwareProvider provider1 = new AbstractTestProvider() { @Override public void onSessionInitiated(final BindingAwareBroker.ProviderContext session) { assertNotNull(session); final BindingAwareBroker.RoutedRpcRegistration<TopologyTunnelPcepProgrammingService> firstReg = session.addRoutedRpcImplementation( TopologyTunnelPcepProgrammingService.class, pcepService1); assertNotNull("Registration should not be null", firstReg); assertSame(pcepService1, firstReg.getInstance()); firstReg.registerPath(NetworkTopologyContext.class, topology); } }; this.broker.registerProvider(provider1); final InstanceIdentifier<Topology> topology2 = InstanceIdentifier.builder(NetworkTopology.class).child(Topology.class, new TopologyKey(getTopologyId("Topo2"))).build(); final BindingAwareProvider provider2 = new AbstractTestProvider() { @Override public void onSessionInitiated(final BindingAwareBroker.ProviderContext session) { assertNotNull(session); final BindingAwareBroker.RoutedRpcRegistration<TopologyTunnelPcepProgrammingService> secondReg = session.addRoutedRpcImplementation( TopologyTunnelPcepProgrammingService.class, pcepService2); secondReg.registerPath(NetworkTopologyContext.class, topology2); } }; this.broker.registerProvider(provider2); final BindingAwareConsumer consumer = new BindingAwareConsumer() { @Override public void onSessionInitialized(final BindingAwareBroker.ConsumerContext session) { final TopologyTunnelPcepProgrammingService consumerPcepService = session.getRpcService(TopologyTunnelPcepProgrammingService.class); assertNotNull(consumerPcepService); assertNotSame(pcepService1, consumerPcepService); assertNotSame(pcepService2, consumerPcepService); testCreateP2pTunnel(consumerPcepService); testDestroyP2pTunnel(consumerPcepService); } private void testCreateP2pTunnel(final TopologyTunnelPcepProgrammingService consumerPcepService) { PcepCreateP2pTunnelInput addLspInput = getInputForRpc(topology, PcepCreateP2pTunnelInputBuilder.class, PcepCreateP2pTunnelInput.class); consumerPcepService.pcepCreateP2pTunnel(addLspInput); verify(pcepService1).pcepCreateP2pTunnel(addLspInput); verifyZeroInteractions(pcepService2); addLspInput = getInputForRpc(topology2, PcepCreateP2pTunnelInputBuilder.class, PcepCreateP2pTunnelInput.class); consumerPcepService.pcepCreateP2pTunnel(addLspInput); verifyZeroInteractions(pcepService1); verify(pcepService2).pcepCreateP2pTunnel(addLspInput); } private void testDestroyP2pTunnel(final TopologyTunnelPcepProgrammingService consumerPcepService) { PcepDestroyTunnelInput addLspInput = getInputForRpc(topology, PcepDestroyTunnelInputBuilder.class, PcepDestroyTunnelInput.class); consumerPcepService.pcepDestroyTunnel(addLspInput); verify(pcepService1).pcepDestroyTunnel(addLspInput); verifyZeroInteractions(pcepService2); addLspInput = getInputForRpc(topology2, PcepDestroyTunnelInputBuilder.class, PcepDestroyTunnelInput.class); consumerPcepService.pcepDestroyTunnel(addLspInput); verifyZeroInteractions(pcepService1); verify(pcepService2).pcepDestroyTunnel(addLspInput); } }; this.broker.registerConsumer(consumer); } private void initMock(final TopologyTunnelPcepProgrammingService pcepService) { @SuppressWarnings("rawtypes") final ListenableFuture future = Futures.immediateFuture(RpcResultBuilder.<AddLspOutput>success().build()); when(pcepService.pcepCreateP2pTunnel(Mockito.any())).thenReturn(future); when(pcepService.pcepDestroyTunnel(Mockito.any())).thenReturn(future); when(pcepService.pcepUpdateTunnel(Mockito.any())).thenReturn(future); } }