private void runProxies(
      BookStore proxy, int numberOfClients, boolean threadSafe, boolean stateCanBeChanged)
      throws Exception {
    ThreadPoolExecutor executor =
        new ThreadPoolExecutor(5, 5, 0, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(10));
    CountDownLatch startSignal = new CountDownLatch(1);
    CountDownLatch doneSignal = new CountDownLatch(numberOfClients);

    for (int i = 1; i <= numberOfClients; i++) {
      // here we do a double copy : from proxy to web client and back to proxy
      BookStore bs =
          !threadSafe
              ? JAXRSClientFactory.fromClient(
                  WebClient.fromClient(WebClient.client(proxy)), BookStore.class)
              : proxy;
      String bookName = stateCanBeChanged ? Integer.toString(i) : "TheBook";
      String bookHeader = stateCanBeChanged ? "value" + i : "CustomValue";

      executor.execute(
          new RootProxyWorker(
              bs, bookName, bookHeader, startSignal, doneSignal, stateCanBeChanged));
    }
    startSignal.countDown();
    doneSignal.await(60, TimeUnit.SECONDS);
    executor.shutdownNow();
    assertEquals("Not all invocations have completed", 0, doneSignal.getCount());
  }
  /**
   *
   *
   * <ul>
   *   <li><code>"OnewayRequest"="true"</code> client header
   *   <li>Calling {@link ITestService#addTestPojo(TestPojo)} which returns <code>void</code> and is
   *       annotated with {@link Oneway}.
   * </ul>
   */
  @Test
  public void witHeaderOnewayVoidMethod() {
    final ITestService client = createJmsClient(true);
    final TestPojo testPojo = createTestPojo(123);

    client.addTestPojoOneWayReturnsVoid(testPojo);
    assertThat(WebClient.client(client).getResponse().getStatus(), is(202));
  }
  /**
   *
   *
   * <ul>
   *   <li>No <code>"OnewayRequest"</code> client header
   *   <li>Calling {@link ITestService#addTestPojo(TestPojo)} which returns <code>void</code> and is
   *       <b>not</b> annotated with {@link Oneway}.
   * </ul>
   *
   * Note: i guess receiving 204 is fine here. Still, the client has to wait until the server
   * implementation returned in order to receive this response.
   */
  @Test
  public void withoutHeaderTwowayVoidMethod() {
    final ITestService client = createJmsClient(false);
    final TestPojo testPojo = createTestPojo(123);

    client.addTestPojoReturnsVoid(testPojo);
    assertThat(WebClient.client(client).getResponse().getStatus(), is(204));
  }
  public <T> T getService(final String etag, final Class<T> serviceClass) {
    T serviceInstance = getCachedService(serviceClass);
    WebClient.client(serviceInstance)
        .match(new EntityTag(etag), false)
        .type(MediaType.APPLICATION_JSON)
        .accept(MediaType.APPLICATION_JSON);

    return serviceInstance;
  }
  /**
   * I would call this the "normal" scenario. Works nicely, but is not what i think we need.
   *
   * <ul>
   *   <li>No <code>"OnewayRequest"</code> client header
   *   <li>Calling {@link ITestService#addTestPojoOneWay(TestPojo)} which returns a {@link Response}
   *       and is annotated with {@link Oneway}.
   * </ul>
   */
  @Test
  public void withoutHeaderOnewayResponseMethod() {
    final ITestService client = createJmsClient(false);
    final TestPojo testPojo = createTestPojo(123);

    final Response response = client.addTestPojoOneWay(testPojo);
    assertThat(response.getStatus(), is(202));
    assertThat(WebClient.client(client).getResponse(), is(response));
  }
  /**
   *
   *
   * <ul>
   *   <li><code>"OnewayRequest"="true"</code> client header
   *   <li>Calling {@link ITestService#addTestPojo(TestPojo)} which returns a {@link Response} and
   *       is <b>not</b> annotated with {@link Oneway}.
   *   <li>I think it's ok that this doesn't work, because the client header is inconsistent with
   *       the annotation.
   * </ul>
   *
   * Note: one has to wait 60 seconds before this one fails with a timeout. I tried setting the
   * timeout in the JMS-config but probably I set the wrong property.
   */
  @Test
  @Ignore
  public void withHeaderTwowayResponseMethod() {
    final ITestService client = createJmsClient(true);
    final TestPojo testPojo = createTestPojo(123);

    final Response response = client.addTestPojo(testPojo);
    assertThat(response.getStatus(), is(202));
    assertThat(WebClient.client(client).getResponse(), is(response));
  }
    private void invoke(int ind) throws Exception {

      String actualHeaderName = bookHeader + ind;
      String actualBookName = bookName + ind;

      if (stateCanBeChanged) {
        Client c = WebClient.client(proxy);
        MultivaluedMap<String, String> map = c.getHeaders();
        map.putSingle("CustomHeader", actualHeaderName);
        c.headers(map);
        proxy.echoBookNameAndHeader2(actualBookName);
        verifyResponse(c.getResponse(), actualBookName, actualHeaderName);
      } else {
        verifyResponse(
            proxy.echoBookNameAndHeader(actualHeaderName, actualBookName),
            actualBookName,
            actualHeaderName);
      }
    }
  /**
   * Creates two clients for {@link ITestService} and {@link ITestService2} and invokes them.<br>
   * The first client has some non-default settings, the second client is default.
   *
   * <p>See http://cxf.apache.org/docs/jax-rs-advanced-features.html#JAX-RSAdvancedFeatures-Client
   */
  private ITestService createJmsClient(boolean withOneWayRequestHeader) {
    final JacksonJaxbJsonProvider jacksonJaxbJsonProvider = new JacksonJaxbJsonProvider();

    //
    // setting up the client
    final ITestService client =
        JAXRSClientFactory.create(
            CLIENT_ADDRESS_URL_ENCODED,
            ITestService.class,
            Collections.singletonList(jacksonJaxbJsonProvider));
    assertThat(client, notNullValue());

    // we don't expect a response. Instead we expect the return code 202.
    // this doesn't work yet. If we set this header, the service won't respond, but this stupid
    // client will still wait and eventually timeout
    if (withOneWayRequestHeader) {
      WebClient.client(client).header("OnewayRequest", "true");
    }

    return client;
  }
 public <T> void resetClient(final Class<T> service) {
   T serviceInstance = getCachedService(service);
   WebClient.client(serviceInstance).reset();
 }
  private String allocateServices(AgreementOffer offer) throws AgreementFactoryException {

    String ac_url =
        ComponentConfigurationProvider.getString("VMServiceInstantiation.url.ac"); // $NON-NLS-1$
    String co_url =
        ComponentConfigurationProvider.getString("VMServiceInstantiation.url.co"); // $NON-NLS-1$

    ServiceManifestDocument manifest = Tools.offerToServiceManifest(offer.getXMLObject());

    log.debug(
        "allocate service for manifest:\n"
            + manifest.xmlText(new XmlOptions().setSavePrettyPrint()));

    String allocationOffer = "";

    boolean skipACtest =
        ComponentConfigurationProvider.getBoolean(
            "VMServiceInstantiation.skipACtest", false); // $NON-NLS-1$

    if (!skipACtest) {
      try {
        log.info(MessageFormat.format("calling admission control at {0}", new Object[] {ac_url}));

        ACModelApi ac = JAXRSClientFactory.create(ac_url, ACModelApi.class);
        allocationOffer = ac.performACTest(manifest.xmlText());

        // allocationOffer = ac.admissionControl("allocate", manifest.xmlText());
        log.info("calling admission control done...");

        log.info(MessageFormat.format("processing admission control response", new Object[] {}));
        log.debug("admission control plain response: \n" + allocationOffer);

        XmlOptions opt = new XmlOptions();
        opt.setLoadReplaceDocumentElement(AllocationOfferDocument.type.getDocumentElementName());
        AllocationOfferDocument ao = AllocationOfferDocument.Factory.parse(allocationOffer, opt);

        log.debug("admission control parsed response:");
        log.debug(ao.xmlText(new XmlOptions().setSavePrettyPrint()));

        if (ao.getAllocationOffer().getAdmissionControlDecision() == 0) {
          throw new AgreementFactoryException("service it is not admidded by admission control.");
        }

      } catch (Exception e) {
        if (e instanceof AgreementFactoryException) {
          throw (AgreementFactoryException) e;
        }

        throw new AgreementFactoryException("Error calling admission control.", e);
      }
    } else {
      log.info("admission control test is skipped");
    }

    try {
      log.info(MessageFormat.format("calling cloud optimizer at {0}", new Object[] {co_url}));

      CloudOptimizerREST co = JAXRSClientFactory.create(co_url, CloudOptimizerREST.class);
      WebClient.client(co).type(MediaType.APPLICATION_XML);

      String response = co.deploy(manifest.xmlText());

      log.info("calling cloud optimizer done...");
      log.debug("cloud optimizer response: '" + response + "'");

      if ((response == null) || ("".equals(response))) {
        throw new AgreementFactoryException("Service could not be deployed by cloud optimizer.");
      }

    } catch (Exception e) {
      if (e instanceof AgreementFactoryException) {
        throw (AgreementFactoryException) e;
      }

      throw new AgreementFactoryException("Error calling cloud optimizer.", e);
    }

    return manifest.getServiceManifest().getServiceDescriptionSection().getServiceId();
  }