MasterChecker.java
Go to the documentation of this file.
00001 /*
00002  * Software License Agreement (BSD License)
00003  *
00004  * Copyright (c) 2011, Willow Garage, Inc.
00005  * Copyright (c) 2013, OSRF.
00006  * All rights reserved.
00007  * Redistribution and use in source and binary forms, with or without
00008  * modification, are permitted provided that the following conditions
00009  * are met:
00010  *
00011  *  * Redistributions of source code must retain the above copyright
00012  *    notice, this list of conditions and the following disclaimer.
00013  *  * Redistributions in binary form must reproduce the above
00014  *    copyright notice, this list of conditions and the following
00015  *    disclaimer in the documentation and/or other materials provided
00016  *    with the distribution.
00017  *  * Neither the name of Willow Garage, Inc. nor the names of its
00018  *    contributors may be used to endorse or promote products derived
00019  *    from this software without specific prior written permission.
00020  *
00021  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00022  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00023  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00024  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00025  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00026  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00027  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00028  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00029  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00030  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00031  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00032  * POSSIBILITY OF SUCH DAMAGE.
00033  */
00034 
00035 package com.github.rosjava.android_apps.application_management;
00036 
00037 import android.util.Log;
00038 
00039 import com.github.rosjava.android_apps.application_management.rapp_manager.GatewayInfoSubscriber;
00040 import com.github.rosjava.android_apps.application_management.rapp_manager.PlatformInfoServiceClient;
00041 import com.github.rosjava.android_apps.application_management.rapp_manager.StatusServiceClient;
00042 
00043 import java.net.URI;
00044 import java.net.URISyntaxException;
00045 import java.util.Date;
00046 
00047 import org.ros.exception.RosRuntimeException;
00048 import org.ros.internal.node.client.ParameterClient;
00049 import org.ros.internal.node.server.NodeIdentifier;
00050 import org.ros.address.InetAddressFactory;
00051 import org.ros.exception.ServiceNotFoundException;
00052 import org.ros.namespace.GraphName;
00053 import org.ros.node.NodeConfiguration;
00054 import org.ros.android.NodeMainExecutorService;
00055 
00056 import rocon_app_manager_msgs.Icon;
00057 
00066 public class MasterChecker {
00067     public interface RobotDescriptionReceiver {
00071         void receive(RobotDescription robotDescription);
00072     }
00073 
00074     public interface FailureHandler {
00079         void handleFailure(String reason);
00080     }
00081 
00082     private CheckerThread checkerThread;
00083     private RobotDescriptionReceiver foundMasterCallback;
00084     private FailureHandler failureCallback;
00085 
00089     public MasterChecker(RobotDescriptionReceiver foundMasterCallback, FailureHandler failureCallback) {
00090         this.foundMasterCallback = foundMasterCallback;
00091         this.failureCallback = failureCallback;
00092     }
00093 
00098     public void beginChecking(RobotId robotId) {
00099         stopChecking();
00100         if (robotId.getMasterUri() == null) {
00101             failureCallback.handleFailure("empty master URI");
00102             return;
00103         }
00104         URI uri;
00105         try {
00106             uri = new URI(robotId.getMasterUri());
00107         } catch (URISyntaxException e) {
00108             failureCallback.handleFailure("invalid master URI");
00109             return;
00110         }
00111         checkerThread = new CheckerThread(robotId, uri);
00112         checkerThread.start();
00113     }
00114 
00118     public void stopChecking() {
00119         if (checkerThread != null && checkerThread.isAlive()) {
00120             checkerThread.interrupt();
00121         }
00122     }
00123 
00124     private class CheckerThread extends Thread {
00125         private URI masterUri;
00126         private RobotId robotId;
00127 
00128         public CheckerThread(RobotId robotId, URI masterUri) {
00129             this.masterUri = masterUri;
00130             this.robotId = robotId;
00131             setDaemon(true);
00132             // don't require callers to explicitly kill all the old checker threads.
00133             setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
00134                 @Override
00135                 public void uncaughtException(Thread thread, Throwable ex) {
00136                     failureCallback.handleFailure("exception: " + ex.getMessage());
00137                 }
00138             });
00139         }
00140 
00141         @Override
00142         public void run() {
00143             try {
00144                 // Check if the master exists - no really good way in rosjava except by checking a standard parameter.
00145                 ParameterClient paramClient = new ParameterClient(
00146                         NodeIdentifier.forNameAndUri("/master_checker", masterUri.toString()), masterUri);
00147                 // getParam throws when it can't find the parameter.
00148                 String unused_rosversion = (String) paramClient.getParam(GraphName.of("rosversion")).getResult();
00149 
00150                 // Check for the platform information - be sure to check that master exists first otherwise you'll
00151                 // start a thread which perpetually crashes and triest to re-register in .execute()
00152                 NodeMainExecutorService nodeMainExecutorService = new NodeMainExecutorService();
00153                 NodeConfiguration nodeConfiguration = NodeConfiguration.newPublic(
00154                         InetAddressFactory.newNonLoopback().getHostAddress(),
00155                         masterUri);
00156                 GatewayInfoSubscriber gatewayInfoClient = new GatewayInfoSubscriber();
00157                 nodeMainExecutorService.execute(gatewayInfoClient, nodeConfiguration.setNodeName("gateway_info_client_node"));
00158                 gatewayInfoClient.waitForResponse();
00159                 String gatewayName = gatewayInfoClient.getGatewayName();
00160                 PlatformInfoServiceClient client = new PlatformInfoServiceClient();
00161                 nodeMainExecutorService.execute(client, nodeConfiguration.setNodeName("platform_info_client_node"));
00162                 client.waitForResponse();
00163                 String robotName = client.getRobotUniqueName();
00164                 String robotType = client.getRobotType();
00165                 Icon robotIcon = client.getRobotIcon();
00166                 StatusServiceClient statusClient = new StatusServiceClient(client.getRobotAppManagerNamespace(), gatewayName);
00167                 nodeMainExecutorService.execute(statusClient, nodeConfiguration.setNodeName("status_client_node"));
00168                 statusClient.waitForResponse();
00169                 nodeMainExecutorService.shutdownNodeMain(client);
00170                 nodeMainExecutorService.shutdownNodeMain(gatewayInfoClient);
00171                 nodeMainExecutorService.shutdownNodeMain(statusClient);
00172 
00173                 // configure robot description
00174                 Date timeLastSeen = new Date();
00175                 RobotDescription robotDescription = new RobotDescription(robotId, robotName, robotType, robotIcon, gatewayName,
00176                         timeLastSeen);
00177                 if (statusClient.isAvailable()) {
00178                     Log.i("ApplicationManagement", "rapp manager is available");
00179                     robotDescription.setConnectionStatus(RobotDescription.OK);
00180                 } else {
00181                     Log.i("ApplicationManagement", "rapp manager is unavailable");
00182                     robotDescription.setConnectionStatus(RobotDescription.UNAVAILABLE);
00183                 }
00184                 foundMasterCallback.receive(robotDescription);
00185                 return;
00186             } catch ( java.lang.RuntimeException e) {
00187                 // thrown if master could not be found in the getParam call (from java.net.ConnectException)
00188                 Log.w("ApplicationManagement", "could not find the master [" + masterUri + "][" + e.toString() + "]");
00189                 failureCallback.handleFailure(e.toString());
00190             } catch (ServiceNotFoundException e) {
00191                 // thrown by client.waitForResponse() if it times out
00192                 Log.w("ApplicationManagement", e.getMessage()); // e.getMessage() is a little less verbose (no org.ros.exception.ServiceNotFoundException prefix)
00193                 failureCallback.handleFailure(e.getMessage());  // don't need the master uri, it's already shown above in the robot description from input method.
00194             } catch (Throwable e) {
00195                 Log.w("ApplicationManagement", "exception while creating node in masterchecker for master URI "
00196                         + masterUri, e);
00197                 failureCallback.handleFailure(e.toString());
00198             }
00199         }
00200     }
00201 }


android_apps
Author(s): Daniel Stonier , Kazuto Murase
autogenerated on Fri Aug 28 2015 10:04:40