00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 package org.ros.internal.node.server.master;
00018
00019 import java.net.URI;
00020 import java.util.Collection;
00021 import java.util.Collections;
00022 import java.util.Map;
00023
00024 import org.apache.commons.logging.Log;
00025 import org.apache.commons.logging.LogFactory;
00026 import org.ros.internal.node.service.ServiceIdentifier;
00027 import org.ros.master.client.TopicSystemState;
00028 import org.ros.namespace.GraphName;
00029 import org.ros.node.service.ServiceServer;
00030
00031 import com.google.common.collect.Maps;
00032
00041 public class MasterRegistrationManagerImpl {
00042
00043 private static final Log log = LogFactory.getLog(MasterRegistrationManagerImpl.class);
00044
00048 private final Map<GraphName, NodeRegistrationInfo> nodes;
00049
00054 private final Map<GraphName, ServiceRegistrationInfo> services;
00055
00060 private final Map<GraphName, TopicRegistrationInfo> topics;
00061
00065 private final MasterRegistrationListener listener;
00066
00067 public MasterRegistrationManagerImpl(MasterRegistrationListener listener) {
00068 this.listener = listener;
00069 nodes = Maps.newHashMap();
00070 services = Maps.newConcurrentMap();
00071 topics = Maps.newHashMap();
00072 }
00073
00088 public TopicRegistrationInfo registerPublisher(GraphName nodeName, URI nodeSlaveUri,
00089 GraphName topicName, String topicMessageType) {
00090 if (log.isDebugEnabled()) {
00091 log.debug(String.format(
00092 "Registering publisher topic %s with message type %s on node %s with slave URI %s",
00093 topicName, topicMessageType, nodeName, nodeSlaveUri));
00094 }
00095
00096 TopicRegistrationInfo topic = obtainTopicRegistrationInfo(topicName, true);
00097 NodeRegistrationInfo node = obtainNodeRegistrationInfo(nodeName, nodeSlaveUri);
00098 topic.addPublisher(node, topicMessageType);
00099 node.addPublisher(topic);
00100
00101 return topic;
00102 }
00103
00115 public boolean unregisterPublisher(GraphName nodeName, GraphName topicName) {
00116 if (log.isDebugEnabled()) {
00117 log.debug(String.format("Unregistering publisher of topic %s from node %s",
00118 topicName, nodeName));
00119 }
00120
00121 TopicRegistrationInfo topic = obtainTopicRegistrationInfo(topicName, false);
00122 if (topic != null) {
00123 NodeRegistrationInfo node = nodes.get(nodeName);
00124 if (node != null) {
00125 node.removePublisher(topic);
00126 topic.removePublisher(node);
00127
00128 potentiallyDeleteNode(node);
00129
00130 return true;
00131 } else {
00132
00133 if (log.isWarnEnabled()) {
00134 log.warn(String.format("Received unregister publisher for topic %s on unknown node %s",
00135 topicName, nodeName));
00136 }
00137
00138 return false;
00139 }
00140 } else {
00141
00142 if (log.isWarnEnabled()) {
00143 log.warn(String.format("Received unregister publisher for unknown topic %s on node %s",
00144 topicName, nodeName));
00145 }
00146
00147 return false;
00148 }
00149 }
00150
00165 public TopicRegistrationInfo registerSubscriber(GraphName nodeName, URI nodeSlaveUri,
00166 GraphName topicName, String topicMessageType) {
00167 if (log.isDebugEnabled()) {
00168 log.debug(String.format(
00169 "Registering subscriber topic %s with message type %s on node %s with slave URI %s",
00170 topicName, topicMessageType, nodeName, nodeSlaveUri));
00171 }
00172
00173 TopicRegistrationInfo topic = obtainTopicRegistrationInfo(topicName, true);
00174 NodeRegistrationInfo node = obtainNodeRegistrationInfo(nodeName, nodeSlaveUri);
00175 topic.addSubscriber(node, topicMessageType);
00176 node.addSubscriber(topic);
00177
00178 return topic;
00179 }
00180
00192 public boolean unregisterSubscriber(GraphName nodeName, GraphName topicName) {
00193 if (log.isDebugEnabled()) {
00194 log.debug(String.format("Unregistering subscriber of topic %s from node %s",
00195 topicName, nodeName));
00196 }
00197
00198 TopicRegistrationInfo topic = obtainTopicRegistrationInfo(topicName, false);
00199 if (topic != null) {
00200 NodeRegistrationInfo node = nodes.get(nodeName);
00201 if (node != null) {
00202 node.removeSubscriber(topic);
00203 topic.removeSubscriber(node);
00204 potentiallyDeleteNode(node);
00205 return true;
00206 } else {
00207
00208 if (log.isWarnEnabled()) {
00209 log.warn(String.format("Received unregister subscriber for topic %s on unknown node %s",
00210 topicName, nodeName));
00211 }
00212 return false;
00213 }
00214 } else {
00215
00216 if (log.isWarnEnabled()) {
00217 log.warn(String.format("Received unregister subscriber for unknown topic %s on node %s",
00218 topicName, nodeName));
00219 }
00220 return false;
00221 }
00222 }
00223
00238 public ServiceRegistrationInfo registerService(GraphName nodeName, URI nodeSlaveUri,
00239 GraphName serviceName, URI serviceUri) {
00240 if (log.isDebugEnabled()) {
00241 log.debug(String.format(
00242 "Registering service %s with server URI %s on node %s with slave URI %s", serviceName,
00243 serviceUri, nodeName, nodeSlaveUri));
00244 }
00245
00246 NodeRegistrationInfo node = obtainNodeRegistrationInfo(nodeName, nodeSlaveUri);
00247
00248 ServiceRegistrationInfo service = services.get(serviceName);
00249 if (service != null) {
00250 NodeRegistrationInfo previousServiceNode = service.getNode();
00251 if (previousServiceNode == node) {
00252
00253 if (log.isWarnEnabled()) {
00254 log.warn(String
00255 .format(
00256 "Registering already known service %s with server URI %s on node %s with slave URI %s",
00257 serviceName, serviceUri, nodeName, nodeSlaveUri));
00258 }
00259 return service;
00260 } else {
00261
00262 previousServiceNode.removeService(service);
00263 potentiallyDeleteNode(previousServiceNode);
00264 }
00265 }
00266
00267
00268 service = new ServiceRegistrationInfo(serviceName, serviceUri, node);
00269 node.addService(service);
00270
00271 services.put(serviceName, service);
00272
00273 return service;
00274 }
00275
00289 public boolean unregisterService(GraphName nodeName, GraphName serviceName, URI serviceUri) {
00290 if (log.isDebugEnabled()) {
00291 log.debug(String.format("Unregistering service %s from node %s", serviceName, nodeName));
00292 }
00293
00294 ServiceRegistrationInfo service = services.get(serviceName);
00295 if (service != null) {
00296 NodeRegistrationInfo node = nodes.get(nodeName);
00297 if (node != null) {
00298
00299 services.remove(serviceName);
00300
00301 node.removeService(service);
00302 potentiallyDeleteNode(node);
00303
00304 return true;
00305 } else {
00306
00307 if (log.isWarnEnabled()) {
00308 log.warn(String.format("Received unregister for service %s on unknown node %s",
00309 serviceName, nodeName));
00310 }
00311
00312
00313
00314
00315 return false;
00316 }
00317 } else {
00318
00319 if (log.isWarnEnabled()) {
00320 log.warn(String.format("Received unregister for unknown service %s on node %s",
00321 serviceName, nodeName));
00322 }
00323
00324 return false;
00325 }
00326 }
00327
00333 public Collection<TopicRegistrationInfo> getAllTopics() {
00334 return Collections.unmodifiableCollection(topics.values());
00335 }
00336
00346 public TopicRegistrationInfo getTopicRegistrationInfo(GraphName topicName) {
00347 return topics.get(topicName);
00348 }
00349
00359 public NodeRegistrationInfo getNodeRegistrationInfo(GraphName nodeName) {
00360 return nodes.get(nodeName);
00361 }
00362
00368 public Collection<ServiceRegistrationInfo> getAllServices() {
00369 return Collections.unmodifiableCollection(services.values());
00370 }
00371
00381 public ServiceRegistrationInfo getServiceRegistrationInfo(GraphName serviceName) {
00382 return services.get(serviceName);
00383 }
00384
00396 private TopicRegistrationInfo obtainTopicRegistrationInfo(GraphName topicName,
00397 boolean shouldCreate) {
00398 TopicRegistrationInfo info = topics.get(topicName);
00399 if (info == null && shouldCreate) {
00400 info = new TopicRegistrationInfo(topicName);
00401 topics.put(topicName, info);
00402 }
00403
00404 return info;
00405 }
00406
00418 private NodeRegistrationInfo obtainNodeRegistrationInfo(GraphName nodeName, URI nodeSlaveUri) {
00419 NodeRegistrationInfo node = nodes.get(nodeName);
00420 if (node != null) {
00421
00422 if (node.getNodeSlaveUri().equals(nodeSlaveUri)) {
00423
00424 return node;
00425 }
00426
00427
00428 potentiallyDeleteNode(node);
00429 cleanupNode(node);
00430 try {
00431 listener.onNodeReplacement(node);
00432 } catch (Exception e) {
00433
00434 log.error("Error during onNodeReplacement call", e);
00435 }
00436 }
00437
00438
00439 node = new NodeRegistrationInfo(nodeName, nodeSlaveUri);
00440 nodes.put(nodeName, node);
00441
00442 return node;
00443 }
00444
00452 private void cleanupNode(NodeRegistrationInfo node) {
00453 for (TopicRegistrationInfo topic : node.getPublishers()) {
00454 topic.removePublisher(node);
00455 }
00456
00457 for (TopicRegistrationInfo topic : node.getSubscribers()) {
00458 topic.removeSubscriber(node);
00459 }
00460
00461 for (ServiceRegistrationInfo service : node.getServices()) {
00462 services.remove(service.getServiceName());
00463 }
00464 }
00465
00472 private void potentiallyDeleteNode(NodeRegistrationInfo node) {
00473 if (!node.hasRegistrations()) {
00474 nodes.remove(node.getNodeName());
00475 }
00476 }
00477 }