Fix intermittent RemoteRpcRegistryMXBeanImplTest failures
[controller.git] / opendaylight / md-sal / sal-remoterpc-connector / src / main / java / org / opendaylight / controller / remote / rpc / registry / mbeans / RemoteRpcRegistryMXBeanImpl.java
1 /*
2  * Copyright (c) 2015 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
9 package org.opendaylight.controller.remote.rpc.registry.mbeans;
10
11 import akka.actor.Address;
12 import akka.util.Timeout;
13 import java.util.HashMap;
14 import java.util.HashSet;
15 import java.util.Map;
16 import java.util.Map.Entry;
17 import java.util.Set;
18 import org.opendaylight.controller.md.sal.common.util.jmx.AbstractMXBean;
19 import org.opendaylight.controller.md.sal.dom.api.DOMRpcIdentifier;
20 import org.opendaylight.controller.remote.rpc.registry.RoutingTable;
21 import org.opendaylight.controller.remote.rpc.registry.gossip.Bucket;
22 import org.opendaylight.controller.remote.rpc.registry.gossip.BucketStoreAccess;
23 import org.slf4j.Logger;
24 import org.slf4j.LoggerFactory;
25 import scala.concurrent.Await;
26 import scala.concurrent.Future;
27
28
29 public class RemoteRpcRegistryMXBeanImpl extends AbstractMXBean implements RemoteRpcRegistryMXBean {
30
31     protected final Logger log = LoggerFactory.getLogger(getClass());
32
33     private static final String LOCAL_CONSTANT = "local";
34
35     private static final String ROUTE_CONSTANT = "route:";
36
37     private static final String NAME_CONSTANT = " | name:";
38
39     private final BucketStoreAccess rpcRegistryAccess;
40     private final Timeout timeout;
41
42     public RemoteRpcRegistryMXBeanImpl(final BucketStoreAccess rpcRegistryAccess, Timeout timeout) {
43         super("RemoteRpcRegistry", "RemoteRpcBroker", null);
44         this.rpcRegistryAccess = rpcRegistryAccess;
45         this.timeout = timeout;
46         registerMBean();
47     }
48
49     @SuppressWarnings({"unchecked", "checkstyle:IllegalCatch", "rawtypes"})
50     private RoutingTable getLocalData() {
51         try {
52             return (RoutingTable) Await.result((Future) rpcRegistryAccess.getLocalData(), timeout.duration());
53         } catch (Exception e) {
54             throw new RuntimeException("getLocalData failed", e);
55         }
56     }
57
58     @SuppressWarnings({"unchecked", "checkstyle:IllegalCatch", "rawtypes"})
59     private Map<Address, Bucket<RoutingTable>> getRemoteBuckets() {
60         try {
61             return (Map<Address, Bucket<RoutingTable>>) Await.result((Future)rpcRegistryAccess.getRemoteBuckets(),
62                     timeout.duration());
63         } catch (Exception e) {
64             throw new RuntimeException("getRemoteBuckets failed", e);
65         }
66     }
67
68     @Override
69     public Set<String> getGlobalRpc() {
70         RoutingTable table = getLocalData();
71         Set<String> globalRpc = new HashSet<>(table.getRoutes().size());
72         for (DOMRpcIdentifier route : table.getRoutes()) {
73             if (route.getContextReference().isEmpty()) {
74                 globalRpc.add(route.getType().toString());
75             }
76         }
77
78         log.debug("Locally registered global RPCs {}", globalRpc);
79         return globalRpc;
80     }
81
82     @Override
83     public Set<String> getLocalRegisteredRoutedRpc() {
84         RoutingTable table = getLocalData();
85         Set<String> routedRpc = new HashSet<>(table.getRoutes().size());
86         for (DOMRpcIdentifier route : table.getRoutes()) {
87             if (!route.getContextReference().isEmpty()) {
88                 StringBuilder builder = new StringBuilder(ROUTE_CONSTANT);
89                 builder.append(route.getContextReference().toString()).append(NAME_CONSTANT).append(route.getType());
90                 routedRpc.add(builder.toString());
91             }
92         }
93
94         log.debug("Locally registered routed RPCs {}", routedRpc);
95         return routedRpc;
96     }
97
98     @Override
99     public Map<String, String> findRpcByName(final String name) {
100         RoutingTable localTable = getLocalData();
101         // Get all RPCs from local bucket
102         Map<String, String> rpcMap = new HashMap<>(getRpcMemberMapByName(localTable, name, LOCAL_CONSTANT));
103
104         // Get all RPCs from remote bucket
105         Map<Address, Bucket<RoutingTable>> buckets = getRemoteBuckets();
106         for (Entry<Address, Bucket<RoutingTable>> entry : buckets.entrySet()) {
107             RoutingTable table = entry.getValue().getData();
108             rpcMap.putAll(getRpcMemberMapByName(table, name, entry.getKey().toString()));
109         }
110
111         log.debug("list of RPCs {} searched by name {}", rpcMap, name);
112         return rpcMap;
113     }
114
115     @Override
116     public Map<String, String> findRpcByRoute(final String routeId) {
117         RoutingTable localTable = getLocalData();
118         Map<String, String> rpcMap = new HashMap<>(getRpcMemberMapByRoute(localTable, routeId, LOCAL_CONSTANT));
119
120         Map<Address, Bucket<RoutingTable>> buckets = getRemoteBuckets();
121         for (Entry<Address, Bucket<RoutingTable>> entry : buckets.entrySet()) {
122             RoutingTable table = entry.getValue().getData();
123             rpcMap.putAll(getRpcMemberMapByRoute(table, routeId, entry.getKey().toString()));
124         }
125
126         log.debug("list of RPCs {} searched by route {}", rpcMap, routeId);
127         return rpcMap;
128     }
129
130     /**
131      * Search if the routing table route String contains routeName.
132      */
133     private static Map<String,String> getRpcMemberMapByRoute(final RoutingTable table, final String routeName,
134                                                       final String address) {
135         Set<DOMRpcIdentifier> routes = table.getRoutes();
136         Map<String, String> rpcMap = new HashMap<>(routes.size());
137         for (DOMRpcIdentifier route : routes) {
138             if (!route.getContextReference().isEmpty()) {
139                 String routeString = route.getContextReference().toString();
140                 if (routeString.contains(routeName)) {
141                     StringBuilder builder = new StringBuilder(ROUTE_CONSTANT);
142                     builder.append(routeString).append(NAME_CONSTANT).append(route.getType());
143                     rpcMap.put(builder.toString(), address);
144                 }
145             }
146         }
147         return rpcMap;
148     }
149
150     /**
151      * Search if the routing table route type contains name.
152      */
153     private static Map<String, String>  getRpcMemberMapByName(final RoutingTable table, final String name,
154                                                        final String address) {
155         Set<DOMRpcIdentifier> routes = table.getRoutes();
156         Map<String, String> rpcMap = new HashMap<>(routes.size());
157         for (DOMRpcIdentifier route : routes) {
158             if (!route.getContextReference().isEmpty()) {
159                 String type = route.getType().toString();
160                 if (type.contains(name)) {
161                     StringBuilder builder = new StringBuilder(ROUTE_CONSTANT);
162                     builder.append(route.getContextReference()).append(NAME_CONSTANT).append(type);
163                     rpcMap.put(builder.toString(), address);
164                 }
165             }
166         }
167         return rpcMap;
168     }
169
170     @Override
171     @SuppressWarnings({"unchecked", "checkstyle:IllegalCatch", "rawtypes"})
172     public String getBucketVersions() {
173         try {
174             return Await.result((Future)rpcRegistryAccess.getBucketVersions(), timeout.duration()).toString();
175         } catch (Exception e) {
176             throw new RuntimeException("getVersions failed", e);
177         }
178     }
179 }