package org.opennaas.extensions.bod.autobahn.commands; import static com.google.common.base.Preconditions.checkState; import static com.google.common.collect.Iterables.getOnlyElement; import static net.geant.autobahn.useraccesspoint.State.ACTIVE; import static net.geant.autobahn.useraccesspoint.State.SCHEDULED; import net.geant.autobahn.useraccesspoint.ReservationResponse; import net.geant.autobahn.useraccesspoint.ServiceRequest; import net.geant.autobahn.useraccesspoint.ServiceResponse; import net.geant.autobahn.useraccesspoint.State; import net.geant.autobahn.useraccesspoint.UserAccessPoint; import net.geant.autobahn.useraccesspoint.UserAccessPointException_Exception; import org.opennaas.core.resources.action.ActionException; import org.opennaas.core.resources.command.Response; public class SubmitServiceCommand extends AutobahnCommand { private final UserAccessPoint userAccessPoint; private final ServiceRequest serviceRequest; private String serviceId; public SubmitServiceCommand(UserAccessPoint userAccessPoint, ServiceRequest serviceRequest) { this.userAccessPoint = userAccessPoint; this.serviceRequest = serviceRequest; setCommandId("submit"); } @Override public Response execute() { checkState(serviceId == null); try { serviceId = userAccessPoint.submitService(serviceRequest); if (getOnlyElement(serviceRequest.getReservations()).isProcessNow()) { waitUntilOrFailure(ACTIVE); } else { waitUntilOrFailure(SCHEDULED); } return okResponse("submitService", "Service " + serviceId + " submitted"); } catch (ActionException e) { return errorResponse("submit", e.getMessage()); } catch (UserAccessPointException_Exception e) { return errorResponse("submit", e.getMessage()); } } @Override public Response undo() { if (serviceId == null) { return okResponse("", "Nothing to undo"); } try { userAccessPoint.cancelService(serviceId); return okResponse("cancelService", "Service " + serviceId + " cancelled"); } catch (UserAccessPointException_Exception e) { return errorResponse("submit", e.getMessage()); } } private void waitUntilOrFailure(State state) throws ActionException, UserAccessPointException_Exception { log.debug("Waiting for Service " + serviceId + " to be " + state); State lastState = State.ACCEPTED; while (true) { ReservationResponse reservation = getReservation(); if (!(reservation.getState().equals(lastState))) { lastState = reservation.getState(); log.debug("Service " + serviceId + " state updated to " + lastState); } switch (reservation.getState()) { case CANCELLED: throw new ActionException("Reservation cancelled: " + reservation.getMessage()); case FAILED: throw new ActionException("Reservation failed: " + reservation.getMessage()); default: break; } if (reservation.getState().ordinal() >= state.ordinal()) { return; } try { Thread.currentThread().sleep(500); } catch (InterruptedException e) { throw new ActionException("Reservation was interrupted", e); } } } private ReservationResponse getReservation() throws UserAccessPointException_Exception { ServiceResponse service = userAccessPoint.queryService(serviceId); return getOnlyElement(service.getReservations()); } }