/* * 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.codegen.impl; import static org.opendaylight.controller.sal.binding.codegen.RuntimeCodeHelper.setRoutingTable; import java.util.HashMap; import java.util.Map; import java.util.Set; 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.RpcRouter; import org.opendaylight.controller.sal.binding.api.rpc.RpcRoutingTable; import org.opendaylight.controller.sal.binding.codegen.RuntimeCodeHelper; import org.opendaylight.yangtools.concepts.AbstractObjectRegistration; import org.opendaylight.yangtools.concepts.ListenerRegistration; import org.opendaylight.yangtools.util.ListenerRegistry; import org.opendaylight.yangtools.yang.binding.BaseIdentity; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.opendaylight.yangtools.yang.binding.RpcService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; public class RpcRouterCodegenInstance implements // RpcRouter, RouteChangeListener, InstanceIdentifier> { private static final Logger LOG = LoggerFactory.getLogger(RpcRouterCodegenInstance.class); private final Class serviceType; private final T invocationProxy; private final Set> contexts; private final ListenerRegistry, InstanceIdentifier>> listeners; private final Map, RpcRoutingTableImpl> routingTables; @SuppressWarnings("unchecked") public RpcRouterCodegenInstance(final String name,final Class type, final T routerImpl, final Iterable> contexts) { this.listeners = ListenerRegistry.create(); this.serviceType = type; this.invocationProxy = routerImpl; this.contexts = ImmutableSet.copyOf(contexts); Map, RpcRoutingTableImpl> mutableRoutingTables = new HashMap<>(); for (Class ctx : contexts) { RpcRoutingTableImpl table = new RpcRoutingTableImpl<>(name,ctx,type); @SuppressWarnings("rawtypes") Map invokerView = table.getRoutes(); setRoutingTable(invocationProxy, ctx, invokerView); mutableRoutingTables.put(ctx, table); table.registerRouteChangeListener(this); } this.routingTables = ImmutableMap.copyOf(mutableRoutingTables); } @Override public Class getServiceType() { return serviceType; } @Override public T getInvocationProxy() { return invocationProxy; } @Override @SuppressWarnings("unchecked") public RpcRoutingTable getRoutingTable(final Class routeContext) { return (RpcRoutingTable) routingTables.get(routeContext); } @Override public T getDefaultService() { return RuntimeCodeHelper.getDelegate(invocationProxy); } @Override public Set> getContexts() { return contexts; } @Override public , InstanceIdentifier>> ListenerRegistration registerRouteChangeListener( final L listener) { return listeners.registerWithType(listener); } @Override public void onRouteChange(final RouteChange, InstanceIdentifier> change) { for (ListenerRegistration, InstanceIdentifier>> listener : listeners) { try { listener.getInstance().onRouteChange(change); } catch (Exception e) { LOG.error("Error occured during invoker listener {}", listener.getInstance(), e); } } } @Override public T getService(final Class context, final InstanceIdentifier path) { return routingTables.get(context).getRoute(path); } @Override public RoutedRpcRegistration addRoutedRpcImplementation(final T service) { 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 registerDefaultService(final T service) { RuntimeCodeHelper.setDelegate(invocationProxy, service); return new DefaultRpcImplementationRegistration(service); } private class RoutedRpcRegistrationImpl extends AbstractObjectRegistration implements RoutedRpcRegistration { public RoutedRpcRegistrationImpl(final T instance) { super(instance); } @Override public Class getServiceType() { return serviceType; } @Override public void registerPath(final Class context, final InstanceIdentifier path) { routingTables.get(context).updateRoute(path, getInstance()); } @Override public void unregisterPath(final Class context, final InstanceIdentifier path) { routingTables.get(context).removeRoute(path, getInstance()); } @Override public void registerInstance(final Class context, final InstanceIdentifier instance) { registerPath(context, instance); } @Override public void unregisterInstance(final Class context, final InstanceIdentifier instance) { unregisterPath(context, instance); } @Override protected void removeRegistration() { } } private class DefaultRpcImplementationRegistration extends AbstractObjectRegistration implements RpcRegistration { protected DefaultRpcImplementationRegistration(final T instance) { super(instance); } @Override protected void removeRegistration() { removeDefaultImplementation(this.getInstance()); } @Override public Class getServiceType() { return serviceType; } } }