/** * Starts an instance (prerequisite: DEPLOYED_STOPPED). * * @param instance the instance * @param plugin the associated plug-in * @throws IOException if something went wrong */ void start(Instance instance, PluginInterface plugin) throws IOException { String instancePath = InstanceHelpers.computeInstancePath(instance); if (instance.getStatus() != InstanceStatus.DEPLOYED_STOPPED && instance.getStatus() != InstanceStatus.WAITING_FOR_ANCESTOR) { this.logger.fine( instancePath + " cannot be started. Prerequisite status: DEPLOYED_STOPPED or WAITING_FOR_ANCESTOR (but was " + instance.getStatus() + ")."); } else if (instance.getParent() != null && instance.getParent().getStatus() != InstanceStatus.DEPLOYED_STARTED) { // An element cannot start if its parent is not started. // However, if the parent is unresolved (or waiting for its parent to start), // then we can mark this instance as ready to start with its parent. this.logger.fine( instancePath + " cannot be started because its parent is not started. Parent status: " + instance.getParent().getStatus() + "."); if (instance.getParent().getStatus() == InstanceStatus.UNRESOLVED || instance.getParent().getStatus() == InstanceStatus.WAITING_FOR_ANCESTOR) { instance.setStatus(InstanceStatus.WAITING_FOR_ANCESTOR); this.logger.fine(instancePath + " will start as soon as its parent starts."); } } else { // Otherwise, start it try { if (ImportHelpers.hasAllRequiredImports(instance, this.logger)) { instance.data.put(FORCE, "whatever"); updateStateFromImports(instance, plugin, null, null); } else { this.logger.fine( "Instance " + InstanceHelpers.computeInstancePath(instance) + " cannot be started, dependencies are missing. Requesting exports from other agents."); instance.setStatus(InstanceStatus.UNRESOLVED); this.messagingClient.sendMessageToTheDm( new MsgNotifInstanceChanged(this.appName, instance)); this.messagingClient.requestExportsFromOtherAgents(instance); } } catch (PluginException e) { this.logger.severe( "An error occured while starting " + InstanceHelpers.computeInstancePath(instance)); Utils.logException(this.logger, e); instance.setStatus(InstanceStatus.DEPLOYED_STOPPED); this.messagingClient.sendMessageToTheDm( new MsgNotifInstanceChanged(this.appName, instance)); } } }
/** * Updates the status of an instance based on the imports. * * @param impactedInstance the instance whose imports may have changed * @param plugin the plug-in to use to apply a concrete modification * @param statusChanged The changed status of the instance that changed (e.g. that provided new * imports) * @param importChanged The individual imports that changed */ public void updateStateFromImports( Instance impactedInstance, PluginInterface plugin, Import importChanged, InstanceStatus statusChanged) throws IOException, PluginException { // Do we have all the imports we need? boolean haveAllImports = ImportHelpers.hasAllRequiredImports(impactedInstance, this.logger); // Update the life cycle of this instance if necessary // Maybe we have something to start if (haveAllImports) { if (impactedInstance.getStatus() == InstanceStatus.UNRESOLVED || impactedInstance.data.remove(FORCE) != null) { InstanceStatus oldState = impactedInstance.getStatus(); impactedInstance.setStatus(InstanceStatus.STARTING); try { this.messagingClient.sendMessageToTheDm( new MsgNotifInstanceChanged(this.appName, impactedInstance)); plugin.start(impactedInstance); impactedInstance.setStatus(InstanceStatus.DEPLOYED_STARTED); this.messagingClient.sendMessageToTheDm( new MsgNotifInstanceChanged(this.appName, impactedInstance)); this.messagingClient.publishExports(impactedInstance); this.messagingClient.listenToRequestsFromOtherAgents( ListenerCommand.START, impactedInstance); } catch (Exception e) { this.logger.severe( "An error occured while starting " + InstanceHelpers.computeInstancePath(impactedInstance)); Utils.logException(this.logger, e); impactedInstance.setStatus(oldState); this.messagingClient.sendMessageToTheDm( new MsgNotifInstanceChanged(this.appName, impactedInstance)); } } else if (impactedInstance.getStatus() == InstanceStatus.DEPLOYED_STARTED) { plugin.update(impactedInstance, importChanged, statusChanged); } else { this.logger.fine( InstanceHelpers.computeInstancePath(impactedInstance) + " checked import changes but has nothing to update (1)."); } } // Or maybe we have something to stop else { if (impactedInstance.getStatus() == InstanceStatus.DEPLOYED_STARTED) { stopInstance(impactedInstance, plugin, true); } else { this.logger.fine( InstanceHelpers.computeInstancePath(impactedInstance) + " checked import changes but has nothing to update (2)."); } } }