private void process(NsaMessage provisionMessage) {

    String correlationId = provisionMessage.getCorrelationId();
    String replyTo = provisionMessage.getReplyTo();
    String requesterNSA = provisionMessage.getRequesterNSA();
    String providerNSA = provisionMessage.getProviderNSA();
    String connectionId = provisionMessage.getConnectionId();
    String globalReservationId = provisionMessage.getGlobalReservationId();

    // Get handles to the data managers.
    DataManager dataManager = DataManager.getInstance();
    StateMachineManager stateMachineManager = dataManager.getStateMachineManager();
    CastingDirector castingDirector = dataManager.getCastingDirector();
    PendingOperationManager pendingOperations = dataManager.getPendingOperationManager();

    // Update the time we sent out the operation.
    PendingOperation pendingOperation = pendingOperations.get(correlationId);
    if (pendingOperation == null) {
      logger.error(
          "ProvisionRequesterLocalActor.process: could not find pendingOperation for "
              + correlationId);
      return;
    }
    pendingOperation.setTimeSentNow();
    PathSegment pathSegment = pendingOperation.getSegment();
    String parentConnectionId = pathSegment.getParentConnectionId();
    String scheduleId = pathSegment.getData();

    // Get the state machine using the parent connectionId.
    StateMachine stateMachine = stateMachineManager.getStateMachine(parentConnectionId);
    if (stateMachine == null) {
      logger.error(
          "ProvisionRequesterLocalActor.process: could not find stateMachine for "
              + parentConnectionId);
      return;
    }

    /*
     * These are the valid states to receive a provision message.  We would
     * have already rejected the message in the ProvisionProviderActor for
     * invalid states on the parent state machine, however, we need to
     * handle our segment individually since some segments may already be
     * provisioned (ESnet requested the protocol leave already provisioned
     * segements in the PROVISIONED state if other segments fail).
     *
     * If we are in the PROVISIONED state then we can send a
     * provisionConfirmed back immediately.
     */
    ConnectionStateType segmentState = pathSegment.getCurrentState();
    if (segmentState == ConnectionStateType.PROVISIONED) {
      // Send back a provisionConfirmed.
      logger.info(
          "ProvisionRequesterLocalActor.process: already provisioned - sending provisionConfirm back for scheduleId="
              + scheduleId);

      NsaMessage childMessage = new NsaMessage();
      childMessage.setCorrelationId(correlationId);
      childMessage.setConnectionId(connectionId);
      childMessage.setConnectionState(pathSegment.getCurrentState());
      childMessage.setGlobalReservationId(globalReservationId);
      childMessage.setMessageType(NsaMessage.MessageType.provisionConfirmedRequester);
      childMessage.setProviderNSA(providerNSA);
      childMessage.setRequesterNSA(requesterNSA);

      // Route this message to the appropriate ReservationFailedRequesterActor for processing.
      castingDirector.send(childMessage);
      logger.info(
          "ProvisionRequesterLocalActor.process: provisionConfirmed message issued to actor so returning");
      return;
    } else if (segmentState != ConnectionStateType.RESERVED
        && segmentState != ConnectionStateType.SCHEDULED) {
      /*
       * We need to feed this back to the reserveFailedRequesterActor
       * to process with other responses.
       */
      ServiceException exception =
          ExceptionCodes.buildProviderException(
              ExceptionCodes.INVALID_STATE, "nrmSegmentState", segmentState.value());

      NsaMessage failedMessage = new NsaMessage();
      failedMessage.setMessageType(NsaMessage.MessageType.provisionFailedRequester);
      failedMessage.setCorrelationId(correlationId);
      failedMessage.setRequesterNSA(requesterNSA);
      failedMessage.setProviderNSA(providerNSA);
      failedMessage.setConnectionId(connectionId);
      failedMessage.setGlobalReservationId(globalReservationId);
      failedMessage.setPayload(exception.getFaultInfo());

      // Route this message to the appropriate ReservationFailedRequesterActor for processing.
      castingDirector.send(failedMessage);
      logger.error(
          "ProvisionRequesterLocalActor.process: segment state invalid for connectionId="
              + parentConnectionId
              + ", state="
              + segmentState.name());
      return;
    }

    /*
     * We transition into the AUTO_PROVISION state to kick off this schedule
     * at startTime. If after startTime we should go into PROVISIONING but
     * we simplify this for the local NRM and just set to AUTO_PROVISION.
     */
    logger.info(
        "ProvisionRequesterLocalActor.process: connectionId="
            + parentConnectionId
            + " transitioning to state="
            + ConnectionStateType.AUTO_PROVISION.name());
    pathSegment.setCurrentState(ConnectionStateType.AUTO_PROVISION);

    /*
     * Now we need to kick the startTime scheduler to look at this new
     * state machine state.  When it is time for provisioning to start on
     * the local NRM this will manage the transition.
     */
    logger.info("ProvisionRequesterLocalActor.process: kicking StartTimeScheduler.");
    StartTimeScheduler.getInstance().timerAudit(stateMachine.getStartTime());

    logger.info("ProvisionRequesterLocalActor.process: completed");
  }
Ejemplo n.º 2
0
  /**
   * Process the NSI terminate message and dispatch to individual NSA/NRM involved in the path
   * segments.
   *
   * @param terminateMessage Our generic message holding the NSI reservation message.
   */
  private void process(NsaMessage terminateMessage) {

    // We have already verified this field is present and not null.
    NsaSecurityContext nsaSecurityContext = terminateMessage.getNsaSecurityContext();
    GenericRequestType terminate = (GenericRequestType) terminateMessage.getPayload();
    String correlationId = terminateMessage.getCorrelationId();
    String replyTo = terminateMessage.getReplyTo();
    String requesterNSA = terminateMessage.getRequesterNSA();
    String providerNSA = terminateMessage.getProviderNSA();
    String connectionId = terminateMessage.getConnectionId();

    // Log the incoming message information.
    logger.info(
        "TerminateProviderActor.process: Incoming message ["
            + nsaSecurityContext.getUserName()
            + " @ "
            + nsaSecurityContext.getRemoteAddr()
            + ", requesterNSA="
            + requesterNSA
            + ", correlationId="
            + correlationId
            + "]");
    logger.info(MessageDump.dump(GenericRequestType.class, terminate));

    /*
     * TODO: In the next iteration we can apply any needed access control
     * based on the NSA request the resource.  In general, we will only
     * want to give them access to the endpoints within their associated
     * groups.  Whether we trust an NSA 100% and only enforce user level
     * access control will need to be determined.
     */

    // Get a reference to the related data managers.
    DataManager dataManager = DataManager.getInstance();
    StateMachineManager stateMachineManager = dataManager.getStateMachineManager();
    CastingDirector castingDirector = dataManager.getCastingDirector();
    NsaConfigurationManager nsaConfiguration = dataManager.getNsaConfigurationManager();
    PendingOperationManager pendingOperations = dataManager.getPendingOperationManager();
    TopologyFactory topology = dataManager.getTopologyFactory();

    /*
     * If we find any error messages from this point forward we need to
     * send a terminateFailed message back to the requesterNSA.
     */
    StateMachine machine = null;
    try {
      /*
       * Verify we have an existing reservation with the same
       * connectionId.
       */
      machine = stateMachineManager.failOnNoStateMachine(connectionId);

      /*
       * We are always in the correct state to get a terminate request.
       */

      // Parse the session security and assign to state machine.
      SessionSecurity sessionSecurity = new SessionSecurity();
      sessionSecurity.parseSessionSecurityAttr(terminate.getSessionSecurityAttr());

      /*
       * TODO: compare security to determine if sending NSA/User can
       * manipulate this state machine.  We will use the user's NSI role
       * to do this in the future.
       */
    } catch (ServiceException nsi) {
      /*
       * Send this to a web services actor for delivery of a
       * ReservationFailed message.
       */
      logger.info(
          "TerminateProviderActor.process: Sending terminateFailed message " + nsi.toString());

      // Leave the state where it is for now.

      NsaMessage failedMessage = new NsaMessage();
      failedMessage.setCorrelationId(correlationId);
      failedMessage.setReplyTo(replyTo);
      failedMessage.setRequesterNSA(requesterNSA);
      failedMessage.setProviderNSA(providerNSA);
      failedMessage.setConnectionId(connectionId);
      if (machine != null) {
        failedMessage.setConnectionState(machine.getCurrentState());
        failedMessage.setGlobalReservationId(machine.getGlobalReservationId());
      }

      failedMessage.setMessageType(NsaMessage.MessageType.terminateFailedProvider);
      failedMessage.setPayload(nsi.getFaultInfo());

      // Route this message to the appropriate actor for processing.
      castingDirector.send(failedMessage);
      logger.info(
          "TerminateProviderActor.process: terminateFailed message issued to actor so returning");
      return;
    }

    /*
     * If we were already in the TERMINATING or TERMINATED state then we
     * can send back a terminateConfirmed message immediately and leave the
     * state machine in the current state.
     *
     * TODO: should we consider sending this terminate request down the
     * tree if in the TERMINATING state already?  Will this help with error
     * recovery?
     */
    if (machine.getCurrentState() == ConnectionStateType.TERMINATING
        || machine.getCurrentState() == ConnectionStateType.TERMINATED
        || machine.getCurrentState() == ConnectionStateType.CLEANING) {
      NsaMessage childMessage = new NsaMessage();
      childMessage.setCorrelationId(correlationId);
      childMessage.setConnectionId(connectionId);
      childMessage.setConnectionState(machine.getCurrentState());
      childMessage.setGlobalReservationId(machine.getGlobalReservationId());
      childMessage.setMessageType(NsaMessage.MessageType.terminateConfirmedProvider);
      childMessage.setProviderNSA(providerNSA);
      childMessage.setRequesterNSA(requesterNSA);
      childMessage.setReplyTo(replyTo);

      castingDirector.send(childMessage);
      logger.info(
          "TerminateProviderActor.process: terminateConfirmed message issued to actor for processing");
    }

    /*
     * Transition state machine to Terminating state before issuing
     * individual termnate messages to NSA.
     */
    machine.setCurrentState(ConnectionStateType.TERMINATING);

    /*
     * For all path segments in the list that are managed by the local
     * NSA we will send a terminateRequest to local NSA actors, while path
     * segments on remote NSA will be sent to remote NSA actors via the
     * NSI protocol.
     */
    List<PathSegment> pathList = machine.getRoutePathList();

    for (PathSegment segment : pathList) {
      logger.info(
          "TerminateProviderActor.process: Routing terminate requests to NSA = "
              + segment.getManagingNsaURN()
              + ", NsaType = "
              + segment.getNsaType().name()
              + ", childConnectionId = "
              + segment.getChildConnectionId()
              + ", sourceSTP = "
              + segment.getSourceStpURN()
              + ", destSTP = "
              + segment.getDestStpURN());

      TerminateMessage termMessage = new TerminateMessage();

      NsaMessage childMessage =
          termMessage.getRequestMessage(
              correlationId, machine.getGlobalReservationId(), replyTo, providerNSA, segment);

      // Give this to the casting director to find us an actor.
      castingDirector.send(childMessage);
      logger.info(
          "TerminateProviderActor.process: terminateRequest message issued to actor for processing");
    }

    // We are done - all other processing is handled by other actors.
    logger.info(
        "TerminateProviderActor.process: terminateRequests issued to children NSA so returning with state="
            + machine.getCurrentState());
  }