private static final Logger LOG = LoggerFactory.getLogger(RpcRouterCodegenInstance.class);
- private T defaultService;
-
private final Class<T> serviceType;
private final T invocationProxy;
private final Map<Class<? extends BaseIdentity>, RpcRoutingTableImpl<? extends BaseIdentity, T>> routingTables;
- private final String name;
-
@SuppressWarnings("unchecked")
public RpcRouterCodegenInstance(final String name,final Class<T> type, final T routerImpl, final Iterable<Class<? extends BaseIdentity>> contexts) {
- this.name = name;
this.listeners = ListenerRegistry.create();
this.serviceType = type;
this.invocationProxy = routerImpl;
@Override
public T getDefaultService() {
- return defaultService;
+ return RuntimeCodeHelper.getDelegate(invocationProxy);
}
@Override
return new RoutedRpcRegistrationImpl(service);
}
+ public void removeDefaultImplementation(final T instance) {
+ RpcService current = RuntimeCodeHelper.getDelegate(invocationProxy);
+ if(instance == current) {
+ RuntimeCodeHelper.setDelegate(invocationProxy, null);
+ }
+ }
+
@Override
public RpcRegistration<T> registerDefaultService(final T service) {
- // TODO Auto-generated method stub
RuntimeCodeHelper.setDelegate(invocationProxy, service);
- return null;
+ return new DefaultRpcImplementationRegistration(service);
}
private class RoutedRpcRegistrationImpl extends AbstractObjectRegistration<T> implements RoutedRpcRegistration<T> {
}
}
+
+ private class DefaultRpcImplementationRegistration extends AbstractObjectRegistration<T> implements RpcRegistration<T> {
+
+
+ protected DefaultRpcImplementationRegistration(final T instance) {
+ super(instance);
+ }
+
+ @Override
+ protected void removeRegistration() {
+ removeDefaultImplementation(this.getInstance());
+ }
+
+ @Override
+ public Class<T> getServiceType() {
+ return serviceType;
+ }
+ }
+
+
}
*/
package org.opendaylight.controller.sal.binding.impl;
+import static com.google.common.base.Preconditions.checkState;
+
+import java.util.EventListener;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.WeakHashMap;
+
import org.opendaylight.controller.md.sal.common.api.routing.RouteChange;
import org.opendaylight.controller.md.sal.common.api.routing.RouteChangeListener;
import org.opendaylight.controller.md.sal.common.api.routing.RouteChangePublisher;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.util.EventListener;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.WeakHashMap;
-
-import static com.google.common.base.Preconditions.checkState;
-
public class RpcProviderRegistryImpl implements //
RpcProviderRegistry, //
RouteChangePublisher<RpcContextIdentifier, InstanceIdentifier<?>> {
return name;
}
- public RpcProviderRegistryImpl(String name) {
+ public RpcProviderRegistryImpl(final String name) {
super();
this.name = name;
}
@Override
- public final <T extends RpcService> RoutedRpcRegistration<T> addRoutedRpcImplementation(Class<T> type,
- T implementation) throws IllegalStateException {
+ public final <T extends RpcService> RoutedRpcRegistration<T> addRoutedRpcImplementation(final Class<T> type,
+ final T implementation) throws IllegalStateException {
return getRpcRouter(type).addRoutedRpcImplementation(implementation);
}
@Override
- public final <T extends RpcService> RpcRegistration<T> addRpcImplementation(Class<T> type, T implementation)
+ public final <T extends RpcService> RpcRegistration<T> addRpcImplementation(final Class<T> type, final T implementation)
throws IllegalStateException {
@SuppressWarnings("unchecked")
RpcRouter<T> potentialRouter = (RpcRouter<T>) rpcRouters.get(type);
@SuppressWarnings("unchecked")
@Override
- public final <T extends RpcService> T getRpcService(Class<T> type) {
+ public final <T extends RpcService> T getRpcService(final Class<T> type) {
T potentialProxy = (T) publicProxies.get(type);
if (potentialProxy != null) {
}
}
- @SuppressWarnings("unchecked")
- public <T extends RpcService> RpcRouter<T> getRpcRouter(Class<T> type) {
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ public <T extends RpcService> RpcRouter<T> getRpcRouter(final Class<T> type) {
RpcRouter<?> potentialRouter = rpcRouters.get(type);
if (potentialRouter != null) {
return (RpcRouter<T>) potentialRouter;
}
}
- private void notifyGlobalRpcAdded(Class<? extends RpcService> type) {
+ private void notifyGlobalRpcAdded(final Class<? extends RpcService> type) {
for(ListenerRegistration<GlobalRpcRegistrationListener> listener : globalRpcListeners) {
try {
listener.getInstance().onGlobalRpcRegistered(type);
}
- private void notifyListenersRoutedCreated(RpcRouter<?> router) {
+ private void notifyListenersRoutedCreated(final RpcRouter<?> router) {
for (ListenerRegistration<RouterInstantiationListener> listener : routerInstantiationListener) {
try {
}
public ListenerRegistration<RouterInstantiationListener> registerRouterInstantiationListener(
- RouterInstantiationListener listener) {
+ final RouterInstantiationListener listener) {
ListenerRegistration<RouterInstantiationListener> reg = routerInstantiationListener.register(listener);
try {
for (RpcRouter<?> router : rpcRouters.values()) {
return reg;
}
+ @SuppressWarnings("unchecked")
@Override
public <L extends RouteChangeListener<RpcContextIdentifier, InstanceIdentifier<?>>> ListenerRegistration<L> registerRouteChangeListener(
- L listener) {
+ final L listener) {
return (ListenerRegistration<L>) routeChangeListeners.register(listener);
}
return rpcFactory;
}
- public void setRpcFactory(RuntimeCodeGenerator rpcFactory) {
+ public void setRpcFactory(final RuntimeCodeGenerator rpcFactory) {
this.rpcFactory = rpcFactory;
}
void onRpcRouterCreated(RpcRouter<?> router);
}
- public ListenerRegistration<GlobalRpcRegistrationListener> registerGlobalRpcRegistrationListener(GlobalRpcRegistrationListener listener) {
+ public ListenerRegistration<GlobalRpcRegistrationListener> registerGlobalRpcRegistrationListener(final GlobalRpcRegistrationListener listener) {
return globalRpcListeners.register(listener);
}
private final Class<T> type;
- public RouteChangeForwarder(Class<T> type) {
+ public RouteChangeForwarder(final Class<T> type) {
this.type = type;
}
@Override
- public void onRouteChange(RouteChange<Class<? extends BaseIdentity>, InstanceIdentifier<?>> change) {
+ public void onRouteChange(final RouteChange<Class<? extends BaseIdentity>, InstanceIdentifier<?>> change) {
Map<RpcContextIdentifier, Set<InstanceIdentifier<?>>> announcements = new HashMap<>();
for (Entry<Class<? extends BaseIdentity>, Set<InstanceIdentifier<?>>> entry : change.getAnnouncements()
.entrySet()) {
private final Class<T> serviceType;
private RpcProviderRegistryImpl registry;
- public RpcProxyRegistration(Class<T> type, T service, RpcProviderRegistryImpl registry) {
+ public RpcProxyRegistration(final Class<T> type, final T service, final RpcProviderRegistryImpl registry) {
super(service);
this.serviceType = type;
this.registry = registry;
+++ /dev/null
-/*
- * Copyright (c) 2014 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.controller.sal.binding.impl.util;
-
-import com.google.common.collect.Multimap;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.Map.Entry;
-import org.opendaylight.yangtools.concepts.Path;
-
-@SuppressWarnings("all")
-public class MapUtils {
- public static <P extends Path<P>, V extends Object> Collection<Entry<? extends P,? extends V>> getAllChildren(final Multimap<? extends P,? extends V> map, final P path) {
- HashSet<Entry<? extends P,? extends V>> _hashSet = new HashSet<Entry<? extends P, ? extends V>>();
- final HashSet<Entry<? extends P,? extends V>> ret = _hashSet;
- final Collection<? extends Entry<? extends P,? extends V>> entries = map.entries();
- for (final Entry<? extends P,? extends V> entry : entries) {
- {
- final P currentPath = entry.getKey();
- if (path.contains(currentPath)) {
- ret.add(entry);
- } else if (currentPath.contains(path)){
- ret.add(entry);
- }
- }
- }
- return ret;
- }
-}
-
--- /dev/null
+package org.opendaylight.controller.md.sal.binding.impl.test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.fail;
+import static org.opendaylight.controller.md.sal.test.model.util.ListsBindingUtils.TOP_BAR_KEY;
+import static org.opendaylight.controller.md.sal.test.model.util.ListsBindingUtils.TOP_FOO_KEY;
+import static org.opendaylight.controller.md.sal.test.model.util.ListsBindingUtils.path;
+
+import java.util.Set;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.opendaylight.controller.md.sal.binding.test.AssertCollections;
+import org.opendaylight.controller.md.sal.common.api.routing.RouteChange;
+import org.opendaylight.controller.md.sal.common.api.routing.RouteChangeListener;
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.RoutedRpcRegistration;
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.RpcRegistration;
+import org.opendaylight.controller.sal.binding.api.rpc.RpcContextIdentifier;
+import org.opendaylight.controller.sal.binding.api.rpc.RpcRouter;
+import org.opendaylight.controller.sal.binding.impl.RpcProviderRegistryImpl;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.test.bi.ba.rpcservice.rev140701.OpendaylightTestRpcServiceService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.test.list.rev140701.two.level.list.TopLevelList;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.test.rpc.routing.rev140701.OpendaylightTestRoutedRpcService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.test.rpc.routing.rev140701.TestContext;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+import com.google.common.util.concurrent.SettableFuture;
+
+
+public class RpcProviderRegistryTest {
+
+ private static InstanceIdentifier<TopLevelList> FOO_PATH = path(TOP_FOO_KEY);
+ private static InstanceIdentifier<TopLevelList> BAR_PATH = path(TOP_BAR_KEY);
+ private static RpcContextIdentifier ROUTING_CONTEXT = RpcContextIdentifier.contextFor(OpendaylightTestRoutedRpcService.class, TestContext.class);
+
+ private RpcProviderRegistryImpl rpcRegistry;
+
+ @Before
+ public void setup() {
+ rpcRegistry = new RpcProviderRegistryImpl("test");
+ }
+
+ private static class TestListener implements RouteChangeListener<RpcContextIdentifier, InstanceIdentifier<?>> {
+
+ final SettableFuture<RouteChange<RpcContextIdentifier, InstanceIdentifier<?>>> event = SettableFuture.create();
+ @Override
+ public void onRouteChange(
+ final RouteChange<RpcContextIdentifier, InstanceIdentifier<?>> change) {
+ event.set(change);
+ }
+ }
+
+ @Test
+ public void testGlobalRpcRegistrations() throws Exception {
+ OpendaylightTestRpcServiceService one = Mockito.mock(OpendaylightTestRpcServiceService.class);
+ OpendaylightTestRpcServiceService two = Mockito.mock(OpendaylightTestRpcServiceService.class);
+
+ RpcRegistration<OpendaylightTestRpcServiceService> regOne = rpcRegistry.addRpcImplementation(OpendaylightTestRpcServiceService.class, one);
+ assertNotNull(regOne);
+
+ try {
+ rpcRegistry.addRpcImplementation(OpendaylightTestRpcServiceService.class, two);
+ fail("Second call for registration of same RPC must throw IllegalStateException");
+ } catch (IllegalStateException e) {
+ assertNotNull(e.getMessage());
+ }
+
+ regOne.close();
+
+ RpcRegistration<OpendaylightTestRpcServiceService> regTwo = rpcRegistry.addRpcImplementation(OpendaylightTestRpcServiceService.class, two);
+ assertNotNull(regTwo);
+ }
+
+ @Test
+ public void testRpcRouterInstance() throws Exception {
+ OpendaylightTestRoutedRpcService def = Mockito.mock(OpendaylightTestRoutedRpcService.class);
+
+ RpcRouter<OpendaylightTestRoutedRpcService> router = rpcRegistry.getRpcRouter(OpendaylightTestRoutedRpcService.class);
+
+ assertEquals(OpendaylightTestRoutedRpcService.class, router.getServiceType());
+ assertNotNull(router.getInvocationProxy());
+ assertNull(router.getDefaultService());
+
+ AssertCollections.assertContains(router.getContexts(), TestContext.class);
+
+ RpcRegistration<OpendaylightTestRoutedRpcService> regDef = router.registerDefaultService(def);
+ assertNotNull(regDef);
+ assertEquals(OpendaylightTestRoutedRpcService.class,regDef.getServiceType());
+ assertEquals(def,regDef.getInstance());
+ assertEquals(def, router.getDefaultService());
+
+ regDef.close();
+ assertNull("Default instance should be null after closing registration", router.getDefaultService());
+ }
+
+ @Test
+ public void testRoutedRpcPathChangeEvents() throws InterruptedException, TimeoutException, ExecutionException {
+ OpendaylightTestRoutedRpcService one = Mockito.mock(OpendaylightTestRoutedRpcService.class);
+ OpendaylightTestRoutedRpcService two = Mockito.mock(OpendaylightTestRoutedRpcService.class);
+ RoutedRpcRegistration<OpendaylightTestRoutedRpcService> regOne = rpcRegistry.addRoutedRpcImplementation(OpendaylightTestRoutedRpcService.class, one);
+ RoutedRpcRegistration<OpendaylightTestRoutedRpcService> regTwo = rpcRegistry.addRoutedRpcImplementation(OpendaylightTestRoutedRpcService.class, two);
+ assertNotNull(regOne);
+ assertNotNull(regTwo);
+
+ final TestListener addListener = new TestListener();
+ rpcRegistry.registerRouteChangeListener(addListener);
+ regOne.registerPath(TestContext.class, FOO_PATH);
+
+ RouteChange<RpcContextIdentifier, InstanceIdentifier<?>> fooAddEvent = addListener.event.get(500, TimeUnit.MILLISECONDS);
+ Set<InstanceIdentifier<?>> announce = fooAddEvent.getAnnouncements().get(ROUTING_CONTEXT);
+ assertNotNull(announce);
+ AssertCollections.assertContains(announce, FOO_PATH);
+ AssertCollections.assertNotContains(announce, BAR_PATH);
+
+
+
+ final TestListener removeListener = new TestListener();
+ rpcRegistry.registerRouteChangeListener(removeListener);
+
+ regOne.unregisterPath(TestContext.class, FOO_PATH);
+
+ RouteChange<RpcContextIdentifier, InstanceIdentifier<?>> fooRemoveEvent = removeListener.event.get(500, TimeUnit.MILLISECONDS);
+ Set<InstanceIdentifier<?>> removal = fooRemoveEvent.getRemovals().get(ROUTING_CONTEXT);
+ assertNotNull(removal);
+ AssertCollections.assertContains(removal, FOO_PATH);
+ AssertCollections.assertNotContains(removal, BAR_PATH);
+
+
+ }
+
+}
--- /dev/null
+module opendaylight-test-routed-rpc {
+ yang-version 1;
+ namespace "urn:opendaylight:params:xml:ns:yang:controller:md:sal:test:rpc:routing";
+ prefix "rpc";
+ import yang-ext { prefix ext; }
+
+ description
+ "Test model for testing of registering rpc service on binding independent mount point
+ and retrieving rpc service via binding aware mount point.";
+
+ revision "2014-07-01" {
+ description
+ "Initial revision";
+ }
+
+ identity test-context {
+ description "Test Context";
+ }
+
+ typedef encapsulated-route {
+ type instance-identifier;
+ }
+
+ grouping route-in-grouping {
+ leaf route {
+ type instance-identifier;
+ ext:context-reference test-context;
+ }
+ }
+
+ grouping encapsulated-route-in-grouping {
+ leaf route {
+ type encapsulated-route;
+ ext:context-reference test-context;
+ }
+ }
+
+ rpc routed-simple-route {
+ input {
+ leaf route {
+ type instance-identifier;
+ ext:context-reference test-context;
+ }
+ }
+ }
+}