@Override
  public NextAction processRequest(Packet request) {
    try {
      LOGGER.entering();

      assert request.getMessage() != null
          : "Unexpected [null] message in the server-side Tube.processRequest()";

      String clientUID = getClientUID(request);
      if (isMakeConnectionRequest(request)) {
        return handleMakeConnectionRequest(request, clientUID);
      }

      if (clientUID == null) {
        // don't bother - this is not a WS-MC enabled request
        return super.processRequest(request);
      } else {
        // TODO replace with proper code that replaces only address

        // removing replyTo header and faultTo header to prevent addressing server tube from
        // treating this request as non-anonymous
        request.getMessage().getHeaders().remove(configuration.getAddressingVersion().replyToTag);
        request.getMessage().getHeaders().remove(configuration.getAddressingVersion().faultToTag);
      }

      Packet requestCopy = request.copy(true);
      fiberExecutor.start(
          request, new AppRequestProcessingCallback(responseStorage, clientUID, configuration));
      return super.doReturnWith(createEmptyResponse(requestCopy));
    } finally {
      LOGGER.exiting();
    }
  }
 @Override
 public AbstractTubeImpl copy(TubeCloner cloner) {
   LOGGER.entering();
   try {
     return new McServerTube(this, cloner);
   } finally {
     LOGGER.exiting();
   }
 }
  @Override
  public NextAction processException(Throwable t) {
    try {
      LOGGER.entering();

      return super.processException(t);
    } finally {
      LOGGER.exiting();
    }
  }
  public void putToDeliveryQueue(ApplicationMessage message) throws RxRuntimeException {
    assert sequenceManager != null;

    if (LOGGER.isLoggable(Level.FINER)) {
      LOGGER.finer(
          String.format(
              "Putting a message with number [ %d ] to the delivery queue of a sequence [ %s ]",
              message.getMessageNumber(), message.getSequenceId()));
    }
    sequenceManager.getSequence(message.getSequenceId()).getDeliveryQueue().put(message);
  }
  @Override
  public NextAction processResponse(Packet response) {
    try {
      LOGGER.entering();

      // with WS-MC enabled messages, this method gets never invoked
      return super.processResponse(response);
    } finally {
      LOGGER.exiting();
    }
  }
class ClientDestinationDeliveryCallback implements Postman.Callback {

  private static final Logger LOGGER = Logger.getLogger(ClientDestinationDeliveryCallback.class);
  private final RuntimeContext rc;

  public ClientDestinationDeliveryCallback(RuntimeContext rc) {
    this.rc = rc;
  }

  public void deliver(ApplicationMessage message) {
    if (message instanceof JaxwsApplicationMessage) {
      deliver(JaxwsApplicationMessage.class.cast(message));
    } else {
      throw LOGGER.logSevereException(
          new RxRuntimeException(
              LocalizationMessages.WSRM_1141_UNEXPECTED_MESSAGE_CLASS(
                  message.getClass().getName(), JaxwsApplicationMessage.class.getName())));
    }
  }

  private void deliver(JaxwsApplicationMessage message) {
    rc.suspendedFiberStorage.resumeFiber(message.getCorrelationId(), message.getPacket());
    rc.destinationMessageHandler.acknowledgeApplicationLayerDelivery(message);
  }
}
  public List<Device> getDevices() {
    try {

      Builder obj =
          service
              .path(pathString)
              .path(labBookPath + "/device")
              .accept(MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON);
      IndexBean indexBean =
          FacesContext.getCurrentInstance()
              .getApplication()
              .evaluateExpressionGet(
                  FacesContext.getCurrentInstance(), "#{indexBean}", IndexBean.class);
      Object username = indexBean.getLoginUserName();
      obj.header("username", username);
      DeviceListServiceBean result = obj.get(new GenericType<DeviceListServiceBean>() {});
      List<Device> itemList = result.getDeviceList();
      for (Item it : itemList) {
        string = it.getName();
        System.out.println(string);
      }
      return itemList;
    } catch (Exception e) {
      Logger.getLogger(this.getClass())
          .log(Level.SEVERE, "LabBookToolClient.getDevices() exception occured", e);
    }
    return null;
  }
 public void deliver(ApplicationMessage message) {
   if (message instanceof JaxwsApplicationMessage) {
     deliver(JaxwsApplicationMessage.class.cast(message));
   } else {
     throw LOGGER.logSevereException(
         new RxRuntimeException(
             LocalizationMessages.WSRM_1141_UNEXPECTED_MESSAGE_CLASS(
                 message.getClass().getName(), JaxwsApplicationMessage.class.getName())));
   }
 }
    public void onCompletion(Packet response) {
      LOGGER.finer(LocalizationMessages.WSMC_0105_STORING_RESPONSE(clientUID));

      if (response.getMessage() != null) {
        final HeaderList headers = response.getMessage().getHeaders();
        headers.remove(configuration.getAddressingVersion().toTag);
        headers.add(
            Headers.create(
                configuration.getAddressingVersion().toTag,
                configuration.getMcVersion().getWsmcAnonymousAddress(clientUID)));
      }

      responseStorage.store(response, clientUID);
    }
  private String getClientUID(Packet request) {
    Header replyToHeader =
        request
            .getMessage()
            .getHeaders()
            .get(configuration.getAddressingVersion().replyToTag, false);
    if (replyToHeader != null) {
      try {
        String replyToAddress =
            replyToHeader.readAsEPR(configuration.getAddressingVersion()).getAddress();
        return configuration.getMcVersion().getClientId(replyToAddress);
      } catch (XMLStreamException ex) {
        throw LOGGER.logSevereException(
            new RxRuntimeException(
                LocalizationMessages.WSMC_0103_ERROR_RETRIEVING_WSA_REPLYTO_CONTENT(), ex));
      }
    }

    return null;
  }
  public List<Laptop> getLaptops() {
    try {

      Builder obj =
          service
              .path(pathString)
              .path(labBookPath + "/laptop")
              .accept(MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON);
      LaptopListServiceBean result = obj.get(new GenericType<LaptopListServiceBean>() {});

      List<Laptop> laptopList = result.getLaptopList();
      for (Item it : laptopList) {
        string = it.getName();
        System.out.println(string);
      }
      return laptopList;
    } catch (Exception e) {
      Logger.getLogger(this.getClass())
          .log(Level.SEVERE, "LabBookToolClient.getDevices() exception occured", e);
    }
    return new ArrayList<Laptop>();
  }
  private static final class AppRequestProcessingCallback implements Fiber.CompletionCallback {

    private static final Logger LOGGER = Logger.getLogger(AppRequestProcessingCallback.class);
    private final ResponseStorage responseStorage;
    private final String clientUID;
    private final McConfiguration configuration;

    public AppRequestProcessingCallback(
        @NotNull ResponseStorage responseStorage,
        @NotNull String clientUID,
        @NotNull McConfiguration configuration) {
      this.responseStorage = responseStorage;
      this.clientUID = clientUID;
      this.configuration = configuration;
    }

    public void onCompletion(Packet response) {
      LOGGER.finer(LocalizationMessages.WSMC_0105_STORING_RESPONSE(clientUID));

      if (response.getMessage() != null) {
        final HeaderList headers = response.getMessage().getHeaders();
        headers.remove(configuration.getAddressingVersion().toTag);
        headers.add(
            Headers.create(
                configuration.getAddressingVersion().toTag,
                configuration.getMcVersion().getWsmcAnonymousAddress(clientUID)));
      }

      responseStorage.store(response, clientUID);
    }

    public void onCompletion(Throwable error) {
      LOGGER.severe(
          LocalizationMessages.WSMC_0106_EXCEPTION_IN_REQUEST_PROCESSING(clientUID), error);
    }
  }
/**
 * Handles outgoing application messages. This class encapsulates RM Source logic that is
 * independent on of the actual delivery mechanism or framework (such as JAX-WS fibers).
 *
 * @author Marek Potociar <marek.potociar at sun.com>
 */
class SourceMessageHandler implements MessageHandler {
  private static final Logger LOGGER = Logger.getLogger(SourceMessageHandler.class);

  private volatile SequenceManager sequenceManager;

  SourceMessageHandler(@Nullable SequenceManager sequenceManager) {
    this.sequenceManager = sequenceManager;
  }

  void setSequenceManager(SequenceManager sequenceManager) {
    this.sequenceManager = sequenceManager;
  }
  /**
   * Registers outgoing message with the provided outbound sequence and sets sequenceId and
   * messageNumber properties on the outgoing message.
   *
   * <p>Once the message is registered and properties are set, the message is placed into a delivery
   * queue and delivery callback is invoked.
   *
   * @throws UnknownSequenceException if no such sequence exits for a given sequence identifier
   */
  public void registerMessage(
      @NotNull ApplicationMessage outMessage, @NotNull String outboundSequenceId)
      throws DuplicateMessageRegistrationException, UnknownSequenceException {
    assert sequenceManager != null;
    assert outMessage != null;
    assert outboundSequenceId != null;

    final Sequence outboundSequence = sequenceManager.getSequence(outboundSequenceId);
    outboundSequence.registerMessage(
        outMessage, true); // TODO it may not be needed to store message if AtMostOnce delivery
  }

  /**
   * Attaches RM acknowledgement information such as inbound sequence acknowledgements (if there is
   * an inbound sequence bound to the specified outbound sequence) or outbound sequence
   * acknowledgement requested flag to the outgoing message.
   *
   * @throws UnknownSequenceException if no such sequence exits for a given sequence identifier
   */
  public void attachAcknowledgementInfo(@NotNull ApplicationMessage outMessage)
      throws UnknownSequenceException {
    assert sequenceManager != null;
    assert outMessage != null;
    assert outMessage.getSequenceId() != null;

    // inbound sequence acknowledgements
    outMessage.setAcknowledgementData(getAcknowledgementData(outMessage.getSequenceId()));
  }

  /**
   * Retrieves acknowledgement information for a given outbound (and inbound) sequence
   *
   * @param outboundSequenceId outbound sequence identifier
   * @return acknowledgement information for a given outbound sequence
   * @throws UnknownSequenceException if no such sequence exits for a given sequence identifier
   */
  public AcknowledgementData getAcknowledgementData(String outboundSequenceId)
      throws UnknownSequenceException {
    assert sequenceManager != null;

    AcknowledgementData.Builder ackDataBuilder = AcknowledgementData.getBuilder();
    Sequence inboundSequence = sequenceManager.getBoundSequence(outboundSequenceId);
    if (inboundSequence != null) {
      /**
       * If inbound sequence exists, we are not checking if inboundSequence.isAckRequested() is
       * true. Instead, we are allways attaching inbound sequence acknowledegements (even if not
       * requested by the other side) This is to avoid potential locks in InOrder
       * delivery/redelivery scenarios.
       *
       * <p>For example, following could happen on the client side with InOrder enabled if we
       * strictly checked for inboundSequence.isAckRequested() to be true:
       *
       * <p>0. response to a previous client request arrives, endpoint is waiting for an
       * acknowledgement 1. client request is put to delivery queue 2. acknowledgements are attached
       * to the client request and ackRequested flag is cleared on inbound sequence 3. client
       * request gets lost. 4. client request is scheduled for a resend 5. client request is put to
       * delivery queue 6. this time, ackRequested flag is clear, so we will not append any
       * acknowledgements 7. client request is processed on the endpoint and response is put to the
       * endpoint's source delivery queue 8. since there was no acknowledgement of the previous
       * response, the new response is blocekd in the delivery queue forever
       *
       * <p>After step 8., communication between client and endpoint might freeze in a deadlock
       * unless another means of communicating the sequence acknowledgements from client to the
       * endpoint are established.
       */
      ackDataBuilder.acknowledgements(
          inboundSequence.getId(),
          inboundSequence.getAcknowledgedMessageNumbers(),
          inboundSequence.isClosed());
      inboundSequence.clearAckRequestedFlag();
    }
    // outbound sequence ack requested flag
    final Sequence outboundSequence = sequenceManager.getSequence(outboundSequenceId);
    if (outboundSequence.hasUnacknowledgedMessages()) {
      ackDataBuilder.ackReqestedSequenceId(outboundSequenceId);
      outboundSequence.updateLastAcknowledgementRequestTime();
    }
    final AcknowledgementData acknowledgementData = ackDataBuilder.build();
    return acknowledgementData;
  }

  public void putToDeliveryQueue(ApplicationMessage message) throws RxRuntimeException {
    assert sequenceManager != null;

    if (LOGGER.isLoggable(Level.FINER)) {
      LOGGER.finer(
          String.format(
              "Putting a message with number [ %d ] to the delivery queue of a sequence [ %s ]",
              message.getMessageNumber(), message.getSequenceId()));
    }
    sequenceManager.getSequence(message.getSequenceId()).getDeliveryQueue().put(message);
  }
}
/** @author Marek Potociar <marek.potociar at sun.com> */
public class McServerTube extends AbstractFilterTubeImpl {

  private static final class ResponseStorage {

    final Map<String, Queue<Packet>> storage = new HashMap<String, Queue<Packet>>();
    final ReentrantReadWriteLock storageLock = new ReentrantReadWriteLock();

    void store(@NotNull Packet response, @NotNull String clientUID) {
      if (!getClientQueue(clientUID).offer(response)) {
        LOGGER.severe(LocalizationMessages.WSMC_0104_ERROR_STORING_RESPONSE(clientUID));
      }
    }

    private Packet getPendingResponsePacket(@NotNull String clientUID) {
      try {
        storageLock.readLock().lock();

        final Queue<Packet> clientQueue = storage.get(clientUID);
        return (clientQueue == null) ? null : clientQueue.poll();
      } finally {
        storageLock.readLock().unlock();
      }
    }

    private boolean hasPendingResponse(@NotNull String clientUID) {
      try {
        storageLock.readLock().lock();

        final Queue<Packet> clientQueue = storage.get(clientUID);
        return clientQueue != null && !clientQueue.isEmpty();
      } finally {
        storageLock.readLock().unlock();
      }
    }

    private Queue<Packet> getClientQueue(@NotNull String clientUID) {
      try {
        storageLock.readLock().lock();
        Queue<Packet> clientQueue = storage.get(clientUID);
        if (clientQueue == null) {
          storageLock.readLock().unlock();

          try {
            storageLock.writeLock().lock();
            clientQueue = storage.get(clientUID);
            if (clientQueue == null) { // recheck
              clientQueue = new ConcurrentLinkedQueue<Packet>();
              storage.put(clientUID, clientQueue);
            }
            storageLock.readLock().lock();
          } finally {
            storageLock.writeLock().unlock();
          }
        }

        return clientQueue;
      } finally {
        storageLock.readLock().unlock();
      }
    }
  }

  private static final class AppRequestProcessingCallback implements Fiber.CompletionCallback {

    private static final Logger LOGGER = Logger.getLogger(AppRequestProcessingCallback.class);
    private final ResponseStorage responseStorage;
    private final String clientUID;
    private final McConfiguration configuration;

    public AppRequestProcessingCallback(
        @NotNull ResponseStorage responseStorage,
        @NotNull String clientUID,
        @NotNull McConfiguration configuration) {
      this.responseStorage = responseStorage;
      this.clientUID = clientUID;
      this.configuration = configuration;
    }

    public void onCompletion(Packet response) {
      LOGGER.finer(LocalizationMessages.WSMC_0105_STORING_RESPONSE(clientUID));

      if (response.getMessage() != null) {
        final HeaderList headers = response.getMessage().getHeaders();
        headers.remove(configuration.getAddressingVersion().toTag);
        headers.add(
            Headers.create(
                configuration.getAddressingVersion().toTag,
                configuration.getMcVersion().getWsmcAnonymousAddress(clientUID)));
      }

      responseStorage.store(response, clientUID);
    }

    public void onCompletion(Throwable error) {
      LOGGER.severe(
          LocalizationMessages.WSMC_0106_EXCEPTION_IN_REQUEST_PROCESSING(clientUID), error);
    }
  }
  //
  private static final Logger LOGGER = Logger.getLogger(McServerTube.class);
  //
  private final McConfiguration configuration;
  private final FiberExecutor fiberExecutor;
  private final ResponseStorage responseStorage;

  McServerTube(McConfiguration configuration, Tube tubelineHead) {
    super(tubelineHead);

    this.configuration = configuration;
    this.fiberExecutor = new FiberExecutor("McServerTubeCommunicator", tubelineHead);
    this.responseStorage = new ResponseStorage();
  }

  McServerTube(McServerTube original, TubeCloner cloner) {
    super(original, cloner);

    this.configuration = original.configuration;
    this.fiberExecutor = original.fiberExecutor;
    this.responseStorage = original.responseStorage;
  }

  @Override
  public AbstractTubeImpl copy(TubeCloner cloner) {
    LOGGER.entering();
    try {
      return new McServerTube(this, cloner);
    } finally {
      LOGGER.exiting();
    }
  }

  @Override
  public NextAction processRequest(Packet request) {
    try {
      LOGGER.entering();

      assert request.getMessage() != null
          : "Unexpected [null] message in the server-side Tube.processRequest()";

      String clientUID = getClientUID(request);
      if (isMakeConnectionRequest(request)) {
        return handleMakeConnectionRequest(request, clientUID);
      }

      if (clientUID == null) {
        // don't bother - this is not a WS-MC enabled request
        return super.processRequest(request);
      } else {
        // TODO replace with proper code that replaces only address

        // removing replyTo header and faultTo header to prevent addressing server tube from
        // treating this request as non-anonymous
        request.getMessage().getHeaders().remove(configuration.getAddressingVersion().replyToTag);
        request.getMessage().getHeaders().remove(configuration.getAddressingVersion().faultToTag);
      }

      Packet requestCopy = request.copy(true);
      fiberExecutor.start(
          request, new AppRequestProcessingCallback(responseStorage, clientUID, configuration));
      return super.doReturnWith(createEmptyResponse(requestCopy));
    } finally {
      LOGGER.exiting();
    }
  }

  @Override
  public NextAction processResponse(Packet response) {
    try {
      LOGGER.entering();

      // with WS-MC enabled messages, this method gets never invoked
      return super.processResponse(response);
    } finally {
      LOGGER.exiting();
    }
  }

  private NextAction handleMakeConnectionRequest(Packet request, String clientUID) {
    try {
      LOGGER.entering();

      String selectionUID;
      try {
        MakeConnectionElement mcElement =
            request
                .getMessage()
                .readPayloadAsJAXB(
                    configuration
                        .getMcVersion()
                        .getUnmarshaller(configuration.getAddressingVersion()));
        selectionUID = configuration.getMcVersion().getClientId(mcElement.getAddress().getValue());
      } catch (JAXBException ex) {
        throw LOGGER.logSevereException(
            new RxRuntimeException(
                LocalizationMessages.WSMC_0107_ERROR_UNMARSHALLING_PROTOCOL_MESSAGE(), ex));
      }

      if (selectionUID == null) {
        // TODO return a MissingSelection SOAP fault
        throw LOGGER.logSevereException(
            new RxRuntimeException(LocalizationMessages.WSMC_0108_NULL_SELECTION_ADDRESS()));
      }

      if (!selectionUID.equals(clientUID)) {
        // TODO return a SOAP fault?
        throw LOGGER.logSevereException(
            new RxRuntimeException(
                LocalizationMessages.WSMC_0109_SELECTION_ADDRESS_NOT_MATCHING_WSA_REPLYTO()));
      }

      Packet response = null;
      if (selectionUID != null && responseStorage.hasPendingResponse(selectionUID)) {
        LOGGER.finer(
            LocalizationMessages.WSMC_0110_PENDING_MESSAGE_FOUND_FOR_SELECTION_UUID(selectionUID));
        response = responseStorage.getPendingResponsePacket(selectionUID);
      }

      if (response == null) {
        LOGGER.finer(
            LocalizationMessages.WSMC_0111_NO_PENDING_MESSAGE_FOUND_FOR_SELECTION_UUID(
                selectionUID));
        response = createEmptyResponse(request);
      } else {
        Message message = response.getMessage();
        if (message != null) {
          HeaderList headers = message.getHeaders();
          headers.add(
              Headers.create(
                  configuration.getMcVersion().getJaxbContext(configuration.getAddressingVersion()),
                  new MessagePendingElement(
                      Boolean.valueOf(
                          selectionUID != null
                              && responseStorage.hasPendingResponse(selectionUID)))));
        }
      }

      return super.doReturnWith(response);
    } finally {
      LOGGER.exiting();
    }
  }

  @Override
  public NextAction processException(Throwable t) {
    try {
      LOGGER.entering();

      return super.processException(t);
    } finally {
      LOGGER.exiting();
    }
  }

  @Override
  public void preDestroy() {
    super.preDestroy();
  }

  private String getClientUID(Packet request) {
    Header replyToHeader =
        request
            .getMessage()
            .getHeaders()
            .get(configuration.getAddressingVersion().replyToTag, false);
    if (replyToHeader != null) {
      try {
        String replyToAddress =
            replyToHeader.readAsEPR(configuration.getAddressingVersion()).getAddress();
        return configuration.getMcVersion().getClientId(replyToAddress);
      } catch (XMLStreamException ex) {
        throw LOGGER.logSevereException(
            new RxRuntimeException(
                LocalizationMessages.WSMC_0103_ERROR_RETRIEVING_WSA_REPLYTO_CONTENT(), ex));
      }
    }

    return null;
  }

  private boolean isMakeConnectionRequest(final Packet request) {
    return configuration
        .getMcVersion()
        .wsmcAction
        .equals(
            request
                .getMessage()
                .getHeaders()
                .getAction(configuration.getAddressingVersion(), configuration.getSoapVersion()));
  }

  private Packet createEmptyResponse(Packet request) {
    return request.createServerResponse(null, null, null, "");
  }
}
  private NextAction handleMakeConnectionRequest(Packet request, String clientUID) {
    try {
      LOGGER.entering();

      String selectionUID;
      try {
        MakeConnectionElement mcElement =
            request
                .getMessage()
                .readPayloadAsJAXB(
                    configuration
                        .getMcVersion()
                        .getUnmarshaller(configuration.getAddressingVersion()));
        selectionUID = configuration.getMcVersion().getClientId(mcElement.getAddress().getValue());
      } catch (JAXBException ex) {
        throw LOGGER.logSevereException(
            new RxRuntimeException(
                LocalizationMessages.WSMC_0107_ERROR_UNMARSHALLING_PROTOCOL_MESSAGE(), ex));
      }

      if (selectionUID == null) {
        // TODO return a MissingSelection SOAP fault
        throw LOGGER.logSevereException(
            new RxRuntimeException(LocalizationMessages.WSMC_0108_NULL_SELECTION_ADDRESS()));
      }

      if (!selectionUID.equals(clientUID)) {
        // TODO return a SOAP fault?
        throw LOGGER.logSevereException(
            new RxRuntimeException(
                LocalizationMessages.WSMC_0109_SELECTION_ADDRESS_NOT_MATCHING_WSA_REPLYTO()));
      }

      Packet response = null;
      if (selectionUID != null && responseStorage.hasPendingResponse(selectionUID)) {
        LOGGER.finer(
            LocalizationMessages.WSMC_0110_PENDING_MESSAGE_FOUND_FOR_SELECTION_UUID(selectionUID));
        response = responseStorage.getPendingResponsePacket(selectionUID);
      }

      if (response == null) {
        LOGGER.finer(
            LocalizationMessages.WSMC_0111_NO_PENDING_MESSAGE_FOUND_FOR_SELECTION_UUID(
                selectionUID));
        response = createEmptyResponse(request);
      } else {
        Message message = response.getMessage();
        if (message != null) {
          HeaderList headers = message.getHeaders();
          headers.add(
              Headers.create(
                  configuration.getMcVersion().getJaxbContext(configuration.getAddressingVersion()),
                  new MessagePendingElement(
                      Boolean.valueOf(
                          selectionUID != null
                              && responseStorage.hasPendingResponse(selectionUID)))));
        }
      }

      return super.doReturnWith(response);
    } finally {
      LOGGER.exiting();
    }
  }
 public void onCompletion(Throwable error) {
   LOGGER.severe(
       LocalizationMessages.WSMC_0106_EXCEPTION_IN_REQUEST_PROCESSING(clientUID), error);
 }