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"); }
/** * 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()); }