Reuse PEM provider in netconf-testtool.
[controller.git] / opendaylight / md-sal / sal-binding-broker / src / main / java / org / opendaylight / controller / sal / binding / codegen / impl / RpcRouterCodegenInstance.java
1 /*
2  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.controller.sal.binding.codegen.impl;
9
10 import static org.opendaylight.controller.sal.binding.codegen.RuntimeCodeHelper.setRoutingTable;
11
12 import java.util.HashMap;
13 import java.util.Map;
14 import java.util.Set;
15
16 import org.opendaylight.controller.md.sal.common.api.routing.RouteChange;
17 import org.opendaylight.controller.md.sal.common.api.routing.RouteChangeListener;
18 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.RoutedRpcRegistration;
19 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.RpcRegistration;
20 import org.opendaylight.controller.sal.binding.api.rpc.RpcRouter;
21 import org.opendaylight.controller.sal.binding.api.rpc.RpcRoutingTable;
22 import org.opendaylight.controller.sal.binding.codegen.RuntimeCodeHelper;
23 import org.opendaylight.yangtools.concepts.AbstractObjectRegistration;
24 import org.opendaylight.yangtools.concepts.ListenerRegistration;
25 import org.opendaylight.yangtools.util.ListenerRegistry;
26 import org.opendaylight.yangtools.yang.binding.BaseIdentity;
27 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
28 import org.opendaylight.yangtools.yang.binding.RpcService;
29 import org.slf4j.Logger;
30 import org.slf4j.LoggerFactory;
31
32 import com.google.common.collect.ImmutableMap;
33 import com.google.common.collect.ImmutableSet;
34
35 public class RpcRouterCodegenInstance<T extends RpcService> implements //
36 RpcRouter<T>, RouteChangeListener<Class<? extends BaseIdentity>, InstanceIdentifier<?>> {
37
38     private static final Logger LOG = LoggerFactory.getLogger(RpcRouterCodegenInstance.class);
39
40     private final Class<T> serviceType;
41
42     private final T invocationProxy;
43
44     private final Set<Class<? extends BaseIdentity>> contexts;
45
46     private final ListenerRegistry<RouteChangeListener<Class<? extends BaseIdentity>, InstanceIdentifier<?>>> listeners;
47
48     private final Map<Class<? extends BaseIdentity>, RpcRoutingTableImpl<? extends BaseIdentity, T>> routingTables;
49
50     @SuppressWarnings("unchecked")
51     public RpcRouterCodegenInstance(final String name,final Class<T> type, final T routerImpl, final Iterable<Class<? extends BaseIdentity>> contexts) {
52         this.listeners = ListenerRegistry.create();
53         this.serviceType = type;
54         this.invocationProxy = routerImpl;
55         this.contexts = ImmutableSet.copyOf(contexts);
56         Map<Class<? extends BaseIdentity>, RpcRoutingTableImpl<? extends BaseIdentity, T>> mutableRoutingTables = new HashMap<>();
57         for (Class<? extends BaseIdentity> ctx : contexts) {
58             RpcRoutingTableImpl<? extends BaseIdentity, T> table = new RpcRoutingTableImpl<>(name,ctx,type);
59
60             @SuppressWarnings("rawtypes")
61             Map invokerView = table.getRoutes();
62
63             setRoutingTable(invocationProxy, ctx, invokerView);
64             mutableRoutingTables.put(ctx, table);
65             table.registerRouteChangeListener(this);
66         }
67         this.routingTables = ImmutableMap.copyOf(mutableRoutingTables);
68     }
69
70     @Override
71     public Class<T> getServiceType() {
72         return serviceType;
73     }
74
75     @Override
76     public T getInvocationProxy() {
77         return invocationProxy;
78     }
79
80     @Override
81     @SuppressWarnings("unchecked")
82     public <C extends BaseIdentity> RpcRoutingTable<C, T> getRoutingTable(final Class<C> routeContext) {
83         return (RpcRoutingTable<C, T>) routingTables.get(routeContext);
84     }
85
86     @Override
87     public T getDefaultService() {
88         return RuntimeCodeHelper.getDelegate(invocationProxy);
89     }
90
91     @Override
92     public Set<Class<? extends BaseIdentity>> getContexts() {
93         return contexts;
94     }
95
96     @Override
97     public <L extends RouteChangeListener<Class<? extends BaseIdentity>, InstanceIdentifier<?>>> ListenerRegistration<L> registerRouteChangeListener(
98             final L listener) {
99         return listeners.registerWithType(listener);
100     }
101
102     @Override
103     public void onRouteChange(final RouteChange<Class<? extends BaseIdentity>, InstanceIdentifier<?>> change) {
104         for (ListenerRegistration<RouteChangeListener<Class<? extends BaseIdentity>, InstanceIdentifier<?>>> listener : listeners) {
105             try {
106                 listener.getInstance().onRouteChange(change);
107             } catch (Exception e) {
108                 LOG.error("Error occured during invoker listener {}", listener.getInstance(), e);
109             }
110         }
111     }
112
113     @Override
114     public T getService(final Class<? extends BaseIdentity> context, final InstanceIdentifier<?> path) {
115         return routingTables.get(context).getRoute(path);
116     }
117
118     @Override
119     public RoutedRpcRegistration<T> addRoutedRpcImplementation(final T service) {
120         return new RoutedRpcRegistrationImpl(service);
121     }
122
123     public void removeDefaultImplementation(final T instance) {
124         RpcService current = RuntimeCodeHelper.getDelegate(invocationProxy);
125         if(instance == current) {
126             RuntimeCodeHelper.setDelegate(invocationProxy, null);
127         }
128     }
129
130     @Override
131     public RpcRegistration<T> registerDefaultService(final T service) {
132         RuntimeCodeHelper.setDelegate(invocationProxy, service);
133         return new DefaultRpcImplementationRegistration(service);
134     }
135
136     private class RoutedRpcRegistrationImpl extends AbstractObjectRegistration<T> implements RoutedRpcRegistration<T> {
137
138         public RoutedRpcRegistrationImpl(final T instance) {
139             super(instance);
140         }
141
142         @Override
143         public Class<T> getServiceType() {
144             return serviceType;
145         }
146
147         @Override
148         public void registerPath(final Class<? extends BaseIdentity> context, final InstanceIdentifier<?> path) {
149             routingTables.get(context).updateRoute(path, getInstance());
150         }
151
152         @Override
153         public void unregisterPath(final Class<? extends BaseIdentity> context, final InstanceIdentifier<?> path) {
154             routingTables.get(context).removeRoute(path, getInstance());
155         }
156
157         @Override
158         public void registerInstance(final Class<? extends BaseIdentity> context, final InstanceIdentifier<?> instance) {
159             registerPath(context, instance);
160         }
161
162         @Override
163         public void unregisterInstance(final Class<? extends BaseIdentity> context, final InstanceIdentifier<?> instance) {
164             unregisterPath(context, instance);
165         }
166
167         @Override
168         protected void removeRegistration() {
169
170         }
171     }
172
173     private class DefaultRpcImplementationRegistration extends AbstractObjectRegistration<T> implements RpcRegistration<T> {
174
175
176         protected DefaultRpcImplementationRegistration(final T instance) {
177             super(instance);
178         }
179
180         @Override
181         protected void removeRegistration() {
182             removeDefaultImplementation(this.getInstance());
183         }
184
185         @Override
186         public Class<T> getServiceType() {
187             return serviceType;
188         }
189     }
190
191
192 }