Skip to content

Commit 1ffd6e1

Browse files
committed
Handle connection faults more gracefully. Internal docs maint.
1 parent 1a5266b commit 1ffd6e1

File tree

8 files changed

+104
-76
lines changed

8 files changed

+104
-76
lines changed

src/main/java/org/ros/exception/ServiceNotFoundException.java

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,17 @@
2121
*/
2222
public class ServiceNotFoundException extends RosException {
2323

24-
public ServiceNotFoundException(final Throwable throwable) {
25-
super(throwable);
26-
}
24+
private static final long serialVersionUID = -706891733230399864L;
2725

28-
public ServiceNotFoundException(final String message, final Throwable throwable) {
29-
super(message, throwable);
30-
}
26+
public ServiceNotFoundException(final Throwable throwable) {
27+
super(throwable);
28+
}
3129

32-
public ServiceNotFoundException(final String message) {
33-
super(message);
34-
}
30+
public ServiceNotFoundException(final String message, final Throwable throwable) {
31+
super(message, throwable);
32+
}
33+
34+
public ServiceNotFoundException(final String message) {
35+
super(message);
36+
}
3537
}

src/main/java/org/ros/internal/node/client/RemoteClient.java

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@
1818

1919

2020
/**
21-
* This class functions as client to the remote node.
21+
* This class functions as client to the remote node. MasterRpcEndpoint has one of these each for master and parameter server
22+
* SlaveRpcEndpoint has but one for contacting the remote master and issuing commands via the remote invokable methods.
23+
* The transport is accomplished via the RemoteRequestinterface implementors.
2224
* @author jg
2325
* Copyright (C) NeoCoreTechs 2014,2015
2426
*/
@@ -63,8 +65,7 @@ public RemoteClient(String bootNode, int bootPort) throws IOException {
6365

6466

6567
/**
66-
* Look for messages coming back from the workers. Extract the UUID of the returned packet
67-
* and get the real request from the ConcurrentHashTable buffer
68+
* Look for messages coming back from the workers.
6869
*/
6970
@Override
7071
public void run() {
@@ -83,10 +84,17 @@ public void run() {
8384
responses.put(ret);
8485
} catch (SocketException e) {
8586
log.error("RemoteClient: receive socket error "+e+" Address:"+IPAddress+" port:"+remotePort);
86-
break;
87+
try {
88+
if( workerSocket != null ) workerSocket.close();
89+
} catch (IOException e2) {}
90+
workerSocket = null;
8791
} catch (IOException e) {
8892
// we lost the remote, try to close worker and wait for reconnect
8993
log.debug("RemoteClient: receive IO error "+e+" Address:"+IPAddress+" port:"+remotePort);
94+
try {
95+
if( workerSocket != null ) workerSocket.close();
96+
} catch (IOException e2) {}
97+
workerSocket = null;
9098
} catch (ClassNotFoundException e1) {
9199
log.error("Class not found for deserialization "+e1+" Address:"+IPAddress+" port:"+remotePort);
92100
break;

src/main/java/org/ros/internal/node/client/SlaveClient.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package org.ros.internal.node.client;
22

3+
import org.ros.exception.RemoteException;
4+
import org.ros.exception.RemoteNotFoundException;
35
import org.ros.internal.node.response.IntegerResultFactory;
46
import org.ros.internal.node.response.ProtocolDescriptionResultFactory;
57
import org.ros.internal.node.response.Response;
@@ -15,7 +17,6 @@
1517
import java.io.IOException;
1618
import java.net.InetSocketAddress;
1719
import java.net.URI;
18-
1920
import java.util.Collection;
2021
import java.util.List;
2122

@@ -78,8 +79,8 @@ public Response<Void> publisherUpdate(GraphName topic, List<InetSocketAddress> p
7879
}
7980

8081
public Response<ProtocolDescription> requestTopic(GraphName topic,
81-
Collection<String> requestedProtocols) {
82-
return Response.fromListChecked(rpcEndpoint.requestTopic(nodeName.toString(), topic.toString(),
82+
Collection<String> requestedProtocols) throws RemoteException, RemoteNotFoundException {
83+
return Response.fromListCheckedNotFound(rpcEndpoint.requestTopic(nodeName.toString(), topic.toString(),
8384
new Object[][] { requestedProtocols.toArray() }), new ProtocolDescriptionResultFactory());
8485
}
8586
}

src/main/java/org/ros/internal/node/response/Response.java

Lines changed: 52 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,16 @@
1-
/*
2-
* Copyright (C) 2011 Google Inc.
3-
*
4-
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
5-
* use this file except in compliance with the License. You may obtain a copy of
6-
* the License at
7-
*
8-
* http://www.apache.org/licenses/LICENSE-2.0
9-
*
10-
* Unless required by applicable law or agreed to in writing, software
11-
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12-
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13-
* License for the specific language governing permissions and limitations under
14-
* the License.
15-
*/
16-
171
package org.ros.internal.node.response;
182

193
import org.ros.exception.RemoteException;
4+
import org.ros.exception.RemoteNotFoundException;
205
import org.ros.exception.RosRuntimeException;
216

22-
import java.net.InetAddress;
23-
import java.net.InetSocketAddress;
247
import java.util.ArrayList;
25-
import java.util.Collection;
268
import java.util.List;
279

2810
/**
29-
* The response from an XML-RPC call.
30-
*
31-
* @author damonkohler@google.com (Damon Kohler)
11+
* The response from a remote call.
3212
*
33-
* @param <T>
13+
* @author jg Copyright (C) NeoCoreTechs 2018
3414
*/
3515
public class Response<T> {
3616

@@ -50,14 +30,18 @@ public static <T> Response<T> newSuccess(String message, T value) {
5030
return new Response<T>(StatusCode.SUCCESS, message, value);
5131
}
5232

33+
public static <T> Response<T> newNotfound(String message, T value) {
34+
return new Response<T>(StatusCode.NOTFOUND, message, value);
35+
}
36+
5337
/**
5438
* Creates a {@link Response} from the {@link List} of {@link Object}s
55-
* returned from an XML-RPC call. Throws {@link RemoteException} if the
39+
* returned from a remote call. Throws {@link RemoteException} if the
5640
* {@link StatusCode} is StatusCode.FAILURE.
5741
*
5842
* @param <T>
5943
* @param response
60-
* the {@link List} of {@link Object}s returned from the XML-RPC call
44+
* the {@link List} of {@link Object}s returned from the remote call
6145
* @param resultFactory
6246
* a {@link ResultFactory} that creates a result from the third
6347
* {@link Object} in the {@link Response}
@@ -96,7 +80,7 @@ public static <T> Response<T> fromListCheckedFailure(List<Object> response,
9680
*
9781
* @param <T>
9882
* @param response
99-
* the {@link List} of {@link Object}s returned from the XML-RPC call
83+
* the {@link List} of {@link Object}s returned from the remote call
10084
* @param resultFactory
10185
* a {@link ResultFactory} that creates a result from the third
10286
* {@link Object} in the {@link Response}
@@ -114,11 +98,51 @@ public static <T> Response<T> fromListChecked(List<Object> response,
11498
statusCode = StatusCode.fromInt((Integer) response.get(0));
11599
message = (String) response.get(1);
116100
if (statusCode != StatusCode.SUCCESS) {
101+
117102
throw new RemoteException(statusCode, message);
118103
}
119104
} catch (ClassCastException e) {
120-
throw new RosRuntimeException(
121-
"Remote side did not return correct type (status code/message).", e);
105+
throw new RosRuntimeException("Remote side did not return correct type (status code/message).", e);
106+
}
107+
try {
108+
return new Response<T>(statusCode, message, resultFactory.newFromValue(response.get(2)));
109+
} catch (ClassCastException e) {
110+
throw new RosRuntimeException("Remote side did not return correct value type.", e);
111+
}
112+
}
113+
114+
/**
115+
* Creates a {@link Response} from the {@link List} of {@link Object}s
116+
* returned from an RPC call. Throws {@link RemoteNotfoundException} if the
117+
* {@link StatusCode} is not found, and {@link RemoteException) if it is not a success.
118+
*
119+
* @param <T>
120+
* @param response
121+
* the {@link List} of {@link Object}s returned from the remote call
122+
* @param resultFactory
123+
* a {@link ResultFactory} that creates a result from the third
124+
* {@link Object} in the {@link Response}
125+
* @return a {@link Response} using the specified {@link ResultFactory} to
126+
* generate the result
127+
* @throws RemoteException
128+
* if the {@link Response}'s {@link StatusCode} does not indicate
129+
* success
130+
* @throws RemoteNotfoundException if the remote call tried to locate a resource not there
131+
*/
132+
public static <T> Response<T> fromListCheckedNotFound(List<Object> response,
133+
ResultFactory<T> resultFactory) throws RemoteException, RemoteNotFoundException {
134+
StatusCode statusCode;
135+
String message;
136+
try {
137+
statusCode = StatusCode.fromInt((Integer) response.get(0));
138+
message = (String) response.get(1);
139+
if (statusCode != StatusCode.SUCCESS) {
140+
if( statusCode == StatusCode.NOTFOUND )
141+
throw new RemoteNotFoundException(statusCode, message);
142+
throw new RemoteException(statusCode, message);
143+
}
144+
} catch (ClassCastException e) {
145+
throw new RosRuntimeException("Remote side did not return correct type (status code/message).", e);
122146
}
123147
try {
124148
return new Response<T>(statusCode, message, resultFactory.newFromValue(response.get(2)));

src/main/java/org/ros/internal/node/response/StatusCode.java

Lines changed: 9 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,11 @@
1-
/*
2-
* Copyright (C) 2011 Google Inc.
3-
*
4-
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
5-
* use this file except in compliance with the License. You may obtain a copy of
6-
* the License at
7-
*
8-
* http://www.apache.org/licenses/LICENSE-2.0
1+
package org.ros.internal.node.response;
2+
/**
3+
* Status codes from remote calls.
4+
* @author jg
95
*
10-
* Unless required by applicable law or agreed to in writing, software
11-
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12-
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13-
* License for the specific language governing permissions and limitations under
14-
* the License.
156
*/
16-
17-
package org.ros.internal.node.response;
18-
197
public enum StatusCode {
20-
ERROR(-1), FAILURE(0), SUCCESS(1);
8+
ERROR(-1), FAILURE(0), SUCCESS(1), NOTFOUND(2);
219

2210
private final int intValue;
2311

@@ -35,6 +23,8 @@ public static StatusCode fromInt(int intValue) {
3523
return ERROR;
3624
case 1:
3725
return SUCCESS;
26+
case 2:
27+
return NOTFOUND;
3828
case 0:
3929
default:
4030
return FAILURE;
@@ -48,6 +38,8 @@ public String toString() {
4838
return "Error";
4939
case SUCCESS:
5040
return "Success";
41+
case NOTFOUND:
42+
return "Not Found";
5143
case FAILURE:
5244
default:
5345
return "Failure";

src/main/java/org/ros/internal/node/rpc/SlaveRpcEndpointImpl.java

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -43,15 +43,15 @@ public SlaveRpcEndpointImpl(String remoteHost, int remotePort) throws IOExceptio
4343

4444
@Override
4545
public List<Object> getBusStats(String callerId) {
46-
RemoteRequestInterface rri = new RemoteRequest("org.ros.internal.node.server.master.SlaverServer",
46+
RemoteRequestInterface rri = new RemoteRequest("org.ros.internal.node.server.SlaveServer",
4747
"getBusStats",
4848
callerId);
4949
return (List<Object>) remoteSlave.queue(rri);//slave.getBusStats(callerId);
5050
}
5151

5252
@Override
5353
public List<Object> getBusInfo(String callerId) {
54-
RemoteRequestInterface rri = new RemoteRequest("org.ros.internal.node.server.master.SlaverServer",
54+
RemoteRequestInterface rri = new RemoteRequest("org.ros.internal.node.server.SlaveServer",
5555
"getBusInfo",
5656
callerId);
5757
List<Object> busInfo = (List<Object>) remoteSlave.queue(rri);//slave.getBusInfo(callerId);
@@ -60,7 +60,7 @@ public List<Object> getBusInfo(String callerId) {
6060

6161
@Override
6262
public List<Object> getMasterUri(String callerId) {
63-
RemoteRequestInterface rri = new RemoteRequest("org.ros.internal.node.server.master.SlaverServer",
63+
RemoteRequestInterface rri = new RemoteRequest("org.ros.internal.node.server.SlaveServer",
6464
"getMasterUri"
6565
);
6666
InetSocketAddress uri = (InetSocketAddress) remoteSlave.queue(rri);//slave.getMasterUri();
@@ -70,7 +70,7 @@ public List<Object> getMasterUri(String callerId) {
7070
@Override
7171
public List<Object> shutdown(String callerId, String message) {
7272
log.info("Shutdown requested by " + callerId + " with message \"" + message + "\"");
73-
RemoteRequestInterface rri = new RemoteRequest("org.ros.internal.node.server.master.SlaverServer",
73+
RemoteRequestInterface rri = new RemoteRequest("org.ros.internal.node.server.SlaveServer",
7474
"shutdown"
7575
);
7676
//slave.shutdown();
@@ -80,7 +80,7 @@ public List<Object> shutdown(String callerId, String message) {
8080
@Override
8181
public List<Object> getPid(String callerId) {
8282
try {
83-
RemoteRequestInterface rri = new RemoteRequest("org.ros.internal.node.server.master.SlaverServer",
83+
RemoteRequestInterface rri = new RemoteRequest("org.ros.internal.node.server.SlaveServer",
8484
"getPid"
8585
);
8686
int pid = (int) remoteSlave.queue(rri);//slave.getPid();
@@ -92,7 +92,7 @@ public List<Object> getPid(String callerId) {
9292

9393
@Override
9494
public List<Object> getSubscriptions(String callerId) {
95-
RemoteRequestInterface rri = new RemoteRequest("org.ros.internal.node.server.master.SlaverServer",
95+
RemoteRequestInterface rri = new RemoteRequest("org.ros.internal.node.server.SlaveServer",
9696
"getSubscriptions"
9797
);
9898
Collection<DefaultSubscriber<?>> subscribers = (Collection<DefaultSubscriber<?>>) remoteSlave.queue(rri);//slave.getSubscriptions();
@@ -105,7 +105,7 @@ public List<Object> getSubscriptions(String callerId) {
105105

106106
@Override
107107
public List<Object> getPublications(String callerId) {
108-
RemoteRequestInterface rri = new RemoteRequest("org.ros.internal.node.server.master.SlaverServer",
108+
RemoteRequestInterface rri = new RemoteRequest("org.ros.internal.node.server.SlaveServer",
109109
"getPublications"
110110
);
111111
Collection<DefaultPublisher<?>> publishers = (Collection<DefaultPublisher<?>>) remoteSlave.queue(rri);//slave.getPublications();
@@ -117,7 +117,7 @@ public List<Object> getPublications(String callerId) {
117117
}
118118

119119
private List<Object> parameterUpdate(String parameterName, Object parameterValue) {
120-
RemoteRequestInterface rri = new RemoteRequest("org.ros.internal.node.server.master.SlaverServer",
120+
RemoteRequestInterface rri = new RemoteRequest("org.ros.internal.node.server.SlaveServer",
121121
"paramUpdate",
122122
GraphName.of(parameterName), parameterValue);
123123
if ((int)remoteSlave.queue(rri) > 0) {
@@ -140,7 +140,7 @@ public List<Object> publisherUpdate(String callerId, String topicName, Object[]
140140
InetSocketAddress uri = (InetSocketAddress)publisher;
141141
publisherUris.add(uri);
142142
}
143-
RemoteRequestInterface rri = new RemoteRequest("org.ros.internal.node.server.master.SlaverServer",
143+
RemoteRequestInterface rri = new RemoteRequest("org.ros.internal.node.server.SlaveServer",
144144
"publisherUpdate",
145145
callerId, topicName, publisherUris);
146146
//slave.publisherUpdate(callerId, topicName, publisherUris);
@@ -155,11 +155,11 @@ public List<Object> requestTopic(String callerId, String topic, Object[] protoco
155155
requestedProtocols.add((String) ((Object[]) protocols[i])[0]);
156156
}
157157
ProtocolDescription protocol = null;
158-
RemoteRequestInterface rri = new RemoteRequest("org.ros.internal.node.server.master.SlaverServer",
158+
RemoteRequestInterface rri = new RemoteRequest("org.ros.internal.node.server.SlaveServer",
159159
"requestTopic",
160160
topic, requestedProtocols);
161161
// The remote request may reference a topic with no publishers
162-
// in that case the call on the remote side return null, which is translated to
162+
// in that case the call on the remote side returns null, which is translated to
163163
// an empty object instance by the time it gets here, so check for proper
164164
// type returned before cast fail
165165
Object res = remoteSlave.queue(rri);//slave.requestTopic(topic, requestedProtocols);
@@ -171,7 +171,7 @@ public List<Object> requestTopic(String callerId, String topic, Object[] protoco
171171
log.info("Requested topic " + topic + " with proto:" + requestedProtocols + ". response: "+ response.toString());
172172
}
173173
} else {
174-
response = Response.newFailure("Requested topic "+topic+" failed to return a valid protcol response, may not exist", 1).toList();
174+
response = Response.newNotfound("Requested topic:"+topic+" failed to return a valid protocol response from requested protocol:"+requestedProtocols+". Publisher may not exist.", 1).toList();
175175
}
176176
return response;
177177
}

src/main/java/org/ros/internal/node/server/SlaveServer.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ public void publisherUpdate(String callerId, String topicName, Collection<InetSo
171171
}
172172
}
173173
/**
174-
* Request a topic conforming to the specified set of protocols, fir instance
174+
* Request a topic conforming to the specified set of protocols, for instance
175175
* if a ProtocolNames.TCPROS is included, a new TcpRosProtocolDescription from tcpRosServer.getAdvertiseAddress
176176
* using tcpRosServer class field will be returned
177177
* @param topicName

0 commit comments

Comments
 (0)