Beispiel #1
0
 def stop_service_logic(self, params, s_space, s_node, s_launcher):
     from rcmp_robotics_data import execute_int_robotics_data_query
     # TODO this operation must be atomic: in case of failure all has to come back as before
     ss_name = execute_int_robotics_data_query(self.get_ss_name_from_conn, params,
                                               "Unable to get ss_name from the connection '%s' - '%s'" %
                                               (params[self.PI_R_NAME_KEY], params[self.PI_S_NAME_KEY]))
     self._logger.debug("-- TMP -- Stopping service logic using params: %s and ss_name: %s" % (params, ss_name))
     if ss_name:
         sl_items = execute_int_robotics_data_query(self.get_sl_sli, params,
                                                    "Unable to get the service logic items from "
                                                    "service logic of '%s'" % params[self.PI_R_NAME_KEY])
         from rcmp_command import DELETE_SERVICE_SPACE, KILL_SERVICE_NODE, KILL_SERVICE_LAUNCHER, RCMPCommandHandler
         from rcmp_service_command import ServiceSpace, ServiceNode, ServiceLauncher
         if sl_items:
             for sli in sl_items:
                 if sli[3]:
                     # sli[0] is the name of the package for that item, sli[1] is the tag of the item
                     # representing the node type in case of node or the launcher name in case of launcher
                     # sli[2] is service_item type (node or launcher) and is used to know what type of
                     # service we have to kill
                     # sli[3] is service_logic_item si_pi_type_target (meaning where the item was launched
                     # and can be S or R)
                     cmd = {ServiceSpace.I_NAME_KEY: params[self.PI_S_NAME_KEY] if sli[3] == RCMPlatformNode.S_TYPE
                            else params[self.PI_R_NAME_KEY], ServiceSpace.SS_NAME_KEY: ss_name}
                     if sli[2] == ServiceSpace.SLI_N_TYPE:
                         # node
                         cmd[RCMPCommandHandler.COMMAND_KEY] = KILL_SERVICE_NODE
                         # sli[4] is a name for the service item
                         if sli[4]:
                             cmd[ServiceNode.SN_NAME_KEY] = sli[4]
                         else:
                             cmd[ServiceNode.SN_PACKAGE_KEY] = sli[0]
                             cmd[ServiceNode.SN_TYPE_KEY] = sli[1]
                         s_node.stop(cmd)
                     elif sli[2] == ServiceSpace.SLI_L_TYPE:
                         # launcher
                         cmd[RCMPCommandHandler.COMMAND_KEY] = KILL_SERVICE_LAUNCHER
                         # sli[4] is a name for the service item
                         if sli[4]:
                             cmd[ServiceLauncher.SL_NAME_KEY] = sli[4]
                         else:
                             cmd[ServiceLauncher.SL_PACKAGE_KEY] = sli[0]
                             cmd[ServiceLauncher.SL_F_LAUNCHER_KEY] = sli[1]
                         s_launcher.stop(cmd)
                     self._logger.debug("-- TMP -- %s stopped" % cmd)
         # once stopped the service logic items (nodes and launchers) we have to delete the service space
         ss_pi_type_target = execute_int_robotics_data_query(self.get_sl_ss_pi_type_target, params,
                                                             "Unable to get the service space target from "
                                                             "service logic of '%s'" % params[self.PI_R_NAME_KEY])
         if ss_pi_type_target:
             self._logger.debug("Rollback update has to delete the service space on %s" % ss_pi_type_target)
             result = self.delete_all_of_ss(ss_name, s_space)
             if not result.is_ok():
                 self._logger.debug("-- TMP -- Forcing service space deletion")
                 # if the cleaning in the right way failed we force the robotics data cleaning
                 # and aspect that the unreachable platform node would clean himself
                 execute_int_robotics_data_query(self.delete_ss, ss_name,
                                                 "Unable to delete the service space '%s'" % ss_name)
Beispiel #2
0
 def execute_update(self, params):
     from rcmp_robotics_data import execute_int_robotics_data_query
     if self.start_service_logic(params):
         # if the service logic launch went well we have to save this binding
         execute_int_robotics_data_query(self.create_conn, params,
                                         "Unable to update the connection between %s and %s" %
                                         (params[self.PI_S_NAME_KEY], params[self.PI_R_NAME_KEY]))
         # now the master know about the connection between the two ends of the pair and has to throw
         # a paired event to both
         self.throw_paired_event(params)
Beispiel #3
0
 def rollback_update_conn(self, params, s_space, s_node, s_launcher):
     from rcmp_robotics_data import execute_int_robotics_data_query
     self.stop_service_logic(params, s_space, s_node, s_launcher)
     self._logger.debug("-- TMP -- Service logic stopped")
     # in every case we have to cancel the connection and the peer that results unreachable
     execute_int_robotics_data_query(self.delete_conn, params,
                                     "Unable to delete the connection between %s and %s" %
                                     (params[self.PI_S_NAME_KEY], params[self.PI_R_NAME_KEY]))
     self._logger.debug("-- TMP -- Connection deleted")
     # the following must be done to clean up all there is relative to the platform node instance
     # that results disconnected (and is not strictly related with the service logic)
     self.clean_up(params, s_space)
     self._logger.debug("-- TMP -- After clean_up")
 def get_service_spaces(self, params):
     # Take PI_NAME_KEY from params and get all the service spaces running on that RCM
     # platform node instance. Add I_ADDRESS_KEY in params with the ip address of this
     # instance
     from rcmp_robotics_data import execute_int_robotics_data_query
     if self.PI_NAME_KEY not in params or (self.PI_NAME_KEY in params and not params[self.PI_NAME_KEY]):
         raise SyntaxError("%s is missing in the request" % self.PI_NAME_KEY)
     return execute_int_robotics_data_query(self.get_ss, params,
                                            "Unable to provide the list of service spaces "
                                            "for the %s named '%s'" % (self._who, params[self.PI_NAME_KEY]))
Beispiel #5
0
 def clean_up_all(self, params, s_space):
     # this is to clean up all there is on the master that is not in the connection context
     from rcmp_robotics_data import execute_int_robotics_data_query
     self._logger.debug("-- TMP -- Clean_up_all with params: %s" % params)
     # we take all the service spaces
     rows = execute_int_robotics_data_query(self.get_ss_list_all,
                                            err_reason="Unable to get the remaining service spaces")
     if rows:
         for row in rows:
             if row:
                 self.delete_all_of_ss(row[0], s_space)
     # at the end we do the rollback provisioning for all the platform node instances except the master
     rows = execute_int_robotics_data_query(self.get_pi_list_all,
                                            err_reason="Unable to get the remaining platform instances")
     if rows:
         for row in rows:
             if row:
                 # self.roll_pi_back(row[0], row[1])
                 # for robots we roll back half while for servers we roll back fully
                 self.roll_pi_back(row[0])
Beispiel #6
0
 def delete_all_of_ss(self, ss_name, s_space):
     from rcmp_robotics_data import execute_int_robotics_data_query
     ss_info = execute_int_robotics_data_query(self.get_ss_info, ss_name,
                                               "Unable to get the service spaces info of %s" % ss_name)
     if ss_info:
         from rcmp_command import DELETE_L_SERVICE_SPACE, DELETE_SERVICE_SPACE, RCMPCommandHandler
         from rcmp_service_command import ServiceSpace
         cmd = {RCMPCommandHandler.COMMAND_KEY: DELETE_L_SERVICE_SPACE,
                PNodeInstance.I_ADDRESS_KEY: self.pni[RCMPlatformNode.PNI_ADDRESS],
                ServiceSpace.SS_ADDRESS_KEY: ss_info[0],
                ServiceSpace.SS_PORT_KEY: str(ss_info[1])}
         result = s_space.delete_local(cmd)
     else:
         result = RCMPMessage()
         result.create_error_response("Not enough info to delete services of '%s'" % ss_name)
     return result
Beispiel #7
0
 def clean_up(self, params, s_space):
     # we cannot reach params[self.PI_NAME_KEY] because is the platform node that results
     # unreachable so we cannot do the right delete and we have to locally delete the remaining
     # services associated with that node
     from rcmp_robotics_data import execute_int_robotics_data_query
     self._logger.debug("-- TMP -- Clean_up with params: %s" % params)
     rows = execute_int_robotics_data_query(self.get_ss_list, params,
                                            "Unable to get the service spaces of %s" %
                                            params[self.PI_S_NAME_KEY]
                                            if params[self.PI_REACHABLE_KEY] == RCMPlatformNode.R_TYPE
                                            else params[self.PI_R_NAME_KEY])
     if rows:
         self._logger.debug("-- TMP -- Service space missed in the rollback service logic")
         for row in rows:
             if row:
                 self.delete_all_of_ss(row[0], s_space)
     # at the end we do the rollback provisioning for the disconnected platform node instance
     self.roll_pi_back(params[self.PI_S_NAME_KEY]
                       if params[self.PI_REACHABLE_KEY] == RCMPlatformNode.R_TYPE
                       else params[self.PI_R_NAME_KEY])
Beispiel #8
0
 def execute_rollback_update(self, params):
     from rcmp_robotics_data import execute_int_robotics_data_query
     self._logger.debug("Executing rollback update with params: %s" % params)
     conns = execute_int_robotics_data_query(self.get_conn, params,
                                             "Unable to get the connections from '%s'" %
                                             params[self.PI_R_NAME_KEY] if self.PI_R_NAME_KEY in params
                                             else params[self.PI_S_NAME_KEY])
     self._logger.debug("-- TMP -- conns: %s" % conns)
     if conns:
         from rcmp_service_command import ServiceSpace, ServiceNode, ServiceLauncher
         s_space = ServiceSpace(self.pni, self.msm)
         s_node = ServiceNode(self.pni, self.msm)
         s_launcher = ServiceLauncher(self.pni, self.msm)
         if isinstance(conns, list):
             # starting from a server we have a list of tuples
             for conn in conns:
                 params[self.PI_R_NAME_KEY] = conn[0]
                 self.rollback_update_conn(params, s_space, s_node, s_launcher)
         else:
             # starting from a robot we have only one tuple
             params[self.PI_S_NAME_KEY] = conns[0]
             self.rollback_update_conn(params, s_space, s_node, s_launcher)
Beispiel #9
0
 def start_service_logic(self, params):
     # TODO this operation must be atomic: check if the solution is ok
     from rcmp_robotics_data import execute_int_robotics_data_query
     result = True
     ss_pi_type_target = execute_int_robotics_data_query(self.get_sl_ss_pi_type_target, params,
                                                         "Unable to get the service space target from "
                                                         "service logic of '%s'" % params[self.PI_R_NAME_KEY])
     if ss_pi_type_target:
         ssl_flow = []
         self._logger.debug("-- TMP -- Update has to create the service space on %s" % ss_pi_type_target)
         from rcmp_command import CREATE_SERVICE_SPACE, DELETE_SERVICE_SPACE, \
             START_SERVICE_NODE, KILL_SERVICE_NODE, START_SERVICE_LAUNCHER, KILL_SERVICE_LAUNCHER, \
             RCMPCommandHandler
         from rcmp_service_command import ServiceSpace, ServiceNode, ServiceLauncher
         s_space = ServiceSpace(self.pni, self.msm)
         s_node = ServiceNode(self.pni, self.msm)
         s_launcher = ServiceLauncher(self.pni, self.msm)
         # the update starts the service logic associated with the platform
         # node instance of type R at manual provisioning time
         cmd = {RCMPCommandHandler.COMMAND_KEY: CREATE_SERVICE_SPACE,
                ServiceSpace.I_NAME_KEY: params[self.PI_S_NAME_KEY] if ss_pi_type_target == RCMPlatformNode.S_TYPE
                else params[self.PI_R_NAME_KEY], ServiceSpace.SS_NAME_KEY: params[self.PI_R_NAME_KEY]}
         res = s_space.create(cmd)
         result = res.is_ok()
         if result:
             # the service space creation went well so we can add it in ssl_flow
             ssl_flow.append(cmd)
             # once started the service space associated with the service logic
             # we have to start all the remaining items of the service logic (nodes
             # and launchers)
             sl_items = execute_int_robotics_data_query(self.get_sl_sli, params,
                                                        "Unable to get the service logic items from "
                                                        "service logic of '%s'" % params[self.PI_R_NAME_KEY])
             if sl_items:
                 for sli in sl_items:
                     if sli[0] and sli[1] and sli[2] and sli[3]:
                         # all this parameters are mandatory
                         # sli[0] is the name of the package for that item, sli[1] is the tag of the item
                         # representing the node type in case of node or the launcher name in case of launcher
                         # sli[2] is service_item type (node or launcher) and is used to know what type of
                         # service we have to launch
                         # sli[3] is service_logic_item si_pi_type_target (meaning where to launch
                         # the item and can be S or R)
                         cmd = {ServiceSpace.I_NAME_KEY: params[self.PI_S_NAME_KEY]
                                if sli[3] == RCMPlatformNode.S_TYPE else params[self.PI_R_NAME_KEY],
                                ServiceSpace.SS_NAME_KEY: params[self.PI_R_NAME_KEY]}
                         if sli[2] == ServiceSpace.SLI_N_TYPE:
                             # node
                             cmd[RCMPCommandHandler.COMMAND_KEY] = START_SERVICE_NODE
                             cmd[ServiceNode.SN_PACKAGE_KEY] = sli[0]
                             cmd[ServiceNode.SN_TYPE_KEY] = sli[1]
                             # the following are optional parameters: sli[4] is a name for the service item
                             # and sli[5] is a list of params to pass to the service
                             if sli[4]:
                                 cmd[ServiceNode.SN_NAME_KEY] = sli[4]
                             if sli[5]:
                                 cmd[ServiceNode.SN_PARAMS_KEY] = sli[5]
                             if sli[0] == ServiceNode.FIROS_PACKAGE and sli[1] == ServiceNode.FIROS_TYPE:
                                 firos_connected_cb = False
                                 try:
                                     while not firos_connected_cb:
                                         ss_ext_port = execute_int_robotics_data_query(self.get_ss_ext_port, cmd,
                                                                                       "Unable to get an inbound "
                                                                                       "free port for '%s' '%s' "
                                                                                       "from service logic of '%s'"
                                                                                       %
                                                                                       (sli[0], sli[1],
                                                                                        params[self.PI_R_NAME_KEY]))
                                         if ss_ext_port:
                                             res = s_node.start(cmd)
                                             if not res.is_ok() and \
                                                     ServiceNode.FIROS_FAILURE in res.get_response_reason():
                                                 # only in case of FIROS_FAILURE we retry to launch firos
                                                 firos_connected_cb = False
                                             else:
                                                 firos_connected_cb = True
                                             # result is needed for appending the result in the rollback trace
                                             result = res.is_ok()
                                         else:
                                             # no port found but not firos error so no more firos retry
                                             firos_connected_cb = True
                                             result = False
                                 except Exception as e:
                                     self._logger.error(e)
                                     result = False
                             else:
                                 # the custom case of rcm rcmdriver.py is different because need to be managed on the
                                 # machine where we launch that node because has to check for a local free port
                                 if sli[0] == "webrtc" and sli[1] == "webRTC_master.py":
                                     cmd[ServiceNode.SN_PARAMS_KEY] = "%s r_name=%s" % \
                                                                      (cmd[ServiceNode.SN_PARAMS_KEY],
                                                                       params[self.PI_R_NAME_KEY]) \
                                         if cmd[ServiceNode.SN_PARAMS_KEY] else "r_name=%s" % \
                                                                                params[self.PI_R_NAME_KEY]
                                 res = s_node.start(cmd)
                                 result = res.is_ok()
                         elif sli[2] == ServiceSpace.SLI_L_TYPE:
                             # launcher
                             cmd[RCMPCommandHandler.COMMAND_KEY] = START_SERVICE_LAUNCHER
                             cmd[ServiceLauncher.SL_PACKAGE_KEY] = sli[0]
                             cmd[ServiceLauncher.SL_F_LAUNCHER_KEY] = sli[1]
                             # the following are optional parameters: sli[4] is a name for the service item
                             # and sli[5] is a list of params to pass to the service
                             if sli[4]:
                                 cmd[ServiceLauncher.SL_NAME_KEY] = sli[4]
                             if sli[5]:
                                 cmd[ServiceLauncher.SL_PARAMS_KEY] = sli[5]
                             res = s_launcher.start(cmd)
                             result = res.is_ok()
                         if result:
                             # the command went well so we add it in ssl_flow
                             ssl_flow.append(cmd)
                         else:
                             # we found and error so we exit from the loop without adding ssl_flow
                             # element
                             break
                     else:
                         # some mandatory parameter missing in the service logic
                         result = False
             if not result:
                 # something went wrong so we have to rollback the service space creation
                 while len(ssl_flow) > 0:
                     # we pop (return the entry and delete from the list) from the last entry
                     # in the list that hold all the cmd went well before the error
                     cmd = ssl_flow.pop(-1)
                     if cmd[RCMPCommandHandler.COMMAND_KEY] == CREATE_SERVICE_SPACE:
                         cmd[RCMPCommandHandler.COMMAND_KEY] = DELETE_SERVICE_SPACE
                         s_space.delete(cmd)
                     elif cmd[RCMPCommandHandler.COMMAND_KEY] == START_SERVICE_NODE:
                         cmd[RCMPCommandHandler.COMMAND_KEY] = KILL_SERVICE_NODE
                         s_node.stop(cmd)
                     elif cmd[RCMPCommandHandler.COMMAND_KEY] == START_SERVICE_LAUNCHER:
                         cmd[RCMPCommandHandler.COMMAND_KEY] = KILL_SERVICE_LAUNCHER
                         s_launcher.stop(cmd)
     self._logger.debug("-- TMP -- result: %s" % result)
     return result