+/*
+ * 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.controller.sal.binding.impl;
+import java.util.EventListener;
import java.util.Map;
import java.util.Map.Entry;
import java.util.HashMap;
import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
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.RpcRouter;
import org.opendaylight.controller.sal.binding.codegen.RuntimeCodeGenerator;
import org.opendaylight.controller.sal.binding.codegen.RuntimeCodeHelper;
import org.opendaylight.controller.sal.binding.codegen.impl.SingletonHolder;
-import org.opendaylight.controller.sal.binding.spi.RpcContextIdentifier;
-import org.opendaylight.controller.sal.binding.spi.RpcRouter;
+import org.opendaylight.controller.sal.binding.api.rpc.RpcContextIdentifier;
import org.opendaylight.yangtools.concepts.AbstractObjectRegistration;
import org.opendaylight.yangtools.concepts.Identifiable;
import org.opendaylight.yangtools.concepts.ListenerRegistration;
private final Map<Class<? extends RpcService>, RpcRouter<?>> rpcRouters = new WeakHashMap<>();
private final ListenerRegistry<RouteChangeListener<RpcContextIdentifier, InstanceIdentifier<?>>> routeChangeListeners = ListenerRegistry
.create();
+ private final ListenerRegistry<RouterInstantiationListener> routerInstantiationListener = ListenerRegistry.create();
private final static Logger LOG = LoggerFactory.getLogger(RpcProviderRegistryImpl.class);
-
+
private final String name;
+ private ListenerRegistry<GlobalRpcRegistrationListener> globalRpcListeners = ListenerRegistry.create();
+
public String getName() {
return name;
}
T publicProxy = getRpcService(type);
RpcService currentDelegate = RuntimeCodeHelper.getDelegate(publicProxy);
checkState(currentDelegate == null, "Rpc service is already registered");
- LOG.debug("Registering {} as global implementation of {} in {}",implementation,type.getSimpleName(),this);
+ LOG.debug("Registering {} as global implementation of {} in {}", implementation, type.getSimpleName(), this);
RuntimeCodeHelper.setDelegate(publicProxy, implementation);
+ notifyGlobalRpcAdded(type);
return new RpcProxyRegistration<T>(type, implementation, this);
}
if (potentialProxy != null) {
return potentialProxy;
}
- synchronized(this) {
+ synchronized (this) {
/**
- * Potential proxy could be instantiated by other thread while we were
- * waiting for the lock.
+ * Potential proxy could be instantiated by other thread while we
+ * were waiting for the lock.
*/
-
+
potentialProxy = (T) publicProxies.get(type);
if (potentialProxy != null) {
return (T) potentialProxy;
}
T proxy = rpcFactory.getDirectProxyFor(type);
- LOG.debug("Created {} as public proxy for {} in {}",proxy,type.getSimpleName(),this);
+ LOG.debug("Created {} as public proxy for {} in {}", proxy, type.getSimpleName(), this);
publicProxies.put(type, proxy);
return proxy;
}
}
- private <T extends RpcService> RpcRouter<T> getRpcRouter(Class<T> type) {
+ @SuppressWarnings("unchecked")
+ public <T extends RpcService> RpcRouter<T> getRpcRouter(Class<T> type) {
RpcRouter<?> potentialRouter = rpcRouters.get(type);
if (potentialRouter != null) {
return (RpcRouter<T>) potentialRouter;
}
- synchronized(this) {
+ synchronized (this) {
/**
- * Potential Router could be instantiated by other thread while we were
- * waiting for the lock.
+ * Potential Router could be instantiated by other thread while we
+ * were waiting for the lock.
*/
- potentialRouter = rpcRouters.get(type);
+ potentialRouter = rpcRouters.get(type);
if (potentialRouter != null) {
return (RpcRouter<T>) potentialRouter;
}
- RpcRouter<T> router = rpcFactory.getRouterFor(type,name);
+ RpcRouter<T> router = rpcFactory.getRouterFor(type, name);
router.registerRouteChangeListener(new RouteChangeForwarder(type));
- LOG.debug("Registering router {} as global implementation of {} in {}",router,type.getSimpleName(),this);
+ LOG.debug("Registering router {} as global implementation of {} in {}", router, type.getSimpleName(), this);
RuntimeCodeHelper.setDelegate(getRpcService(type), router.getInvocationProxy());
rpcRouters.put(type, router);
+ notifyListenersRoutedCreated(router);
return router;
}
}
+ private void notifyGlobalRpcAdded(Class<? extends RpcService> type) {
+ for(ListenerRegistration<GlobalRpcRegistrationListener> listener : globalRpcListeners) {
+ try {
+ listener.getInstance().onGlobalRpcRegistered(type);
+ } catch (Exception e) {
+ LOG.error("Unhandled exception during invoking listener {}", e);
+ }
+ }
+
+ }
+
+ private void notifyListenersRoutedCreated(RpcRouter router) {
+
+ for (ListenerRegistration<RouterInstantiationListener> listener : routerInstantiationListener) {
+ try {
+ listener.getInstance().onRpcRouterCreated(router);
+ } catch (Exception e) {
+ LOG.error("Unhandled exception during invoking listener {}", e);
+ }
+ }
+
+ }
+
+ public ListenerRegistration<RouterInstantiationListener> registerRouterInstantiationListener(
+ RouterInstantiationListener listener) {
+ ListenerRegistration<RouterInstantiationListener> reg = routerInstantiationListener.register(listener);
+ try {
+ for (RpcRouter<?> router : rpcRouters.values()) {
+ listener.onRpcRouterCreated(router);
+ }
+ } catch (Exception e) {
+ LOG.error("Unhandled exception during invoking listener {}", e);
+ }
+ return reg;
+ }
+
@Override
public <L extends RouteChangeListener<RpcContextIdentifier, InstanceIdentifier<?>>> ListenerRegistration<L> registerRouteChangeListener(
L listener) {
this.rpcFactory = rpcFactory;
}
+ public interface RouterInstantiationListener extends EventListener {
+ void onRpcRouterCreated(RpcRouter<?> router);
+ }
+
+ public ListenerRegistration<GlobalRpcRegistrationListener> registerGlobalRpcRegistrationListener(GlobalRpcRegistrationListener listener) {
+ return globalRpcListeners.register(listener);
+ }
+
+ public interface GlobalRpcRegistrationListener extends EventListener {
+ void onGlobalRpcRegistered(Class<? extends RpcService> cls);
+ void onGlobalRpcUnregistered(Class<? extends RpcService> cls);
+
+ }
+
private class RouteChangeForwarder<T extends RpcService> implements
RouteChangeListener<Class<? extends BaseIdentity>, InstanceIdentifier<?>> {