public HttpResponse call() throws Exception {

      HttpResponse response = null;
      for (; ; ) {
        HttpRequest request = command.getCurrentRequest();
        Q nativeRequest = null;
        try {
          for (HttpRequestFilter filter : request.getFilters()) {
            request = filter.filter(request);
          }
          checkRequestHasContentLengthOrChunkedEncoding(
              request,
              "After filtering, the request has neither chunked encoding nor content length: "
                  + request);
          logger.debug("Sending request %s: %s", request.hashCode(), request.getRequestLine());
          wirePayloadIfEnabled(wire, request);
          utils.logRequest(headerLog, request, ">>");
          nativeRequest = convert(request);
          response = invoke(nativeRequest);

          logger.debug("Receiving response %s: %s", request.hashCode(), response.getStatusLine());
          utils.logResponse(headerLog, response, "<<");
          if (response.getPayload() != null && wire.enabled()) wire.input(response);
          int statusCode = response.getStatusCode();
          if (statusCode >= 300) {
            if (shouldContinue(response)) continue;
            else break;
          } else {
            break;
          }
        } catch (Exception e) {
          IOException ioe = Throwables2.getFirstThrowableOfType(e, IOException.class);
          if (ioe != null) {
            if (ioe instanceof SSLException) {
              command.setException(
                  new AuthorizationException(
                      e.getMessage()
                          + " connecting to "
                          + command.getCurrentRequest().getRequestLine(),
                      e));
              break;
            } else if (ioRetryHandler.shouldRetryRequest(command, ioe)) {
              continue;
            }
          }
          command.setException(
              new HttpResponseException(
                  e.getMessage() + " connecting to " + command.getCurrentRequest().getRequestLine(),
                  command,
                  null,
                  e));
          break;
        } finally {
          cleanup(nativeRequest);
        }
      }
      if (command.getException() != null) throw command.getException();
      return response;
    }
示例#2
0
 /**
  * Exit if klass has the same type or sub-type as throwable or one of its causes. If exiting, emit
  * message.
  */
 private static void exitIfThrowableMatches(
     Throwable throwable, Class klass, Errno errno, String message) {
   Throwable cause = Throwables2.getFirstThrowableOfType(throwable, klass);
   if (cause == null) {
     return;
   }
   System.err.format("%s: %s\n", message, cause.getMessage());
   System.exit(errno.getErrno());
 }
 @Override
 public T get() {
   TimeoutException ex = null;
   for (int i = 0; i < 3; i++) {
     try {
       ex = null;
       return delegate.get();
     } catch (Exception e) {
       if ((ex = Throwables2.getFirstThrowableOfType(e, TimeoutException.class)) != null) continue;
       propagate(e);
       assert false;
       return null;
     }
   }
   if (ex != null) propagate(ex);
   assert false;
   return null;
 }
示例#4
0
 protected <T, C extends Connection<T>> T acquire(C connection) {
   String errorMessage = String.format("(%s) error acquiring %s", toString(), connection);
   for (int i = 0; i < sshRetries; i++) {
     try {
       connection.clear();
       logger.debug(">> (%s) acquiring %s", toString(), connection);
       T returnVal = connection.create();
       logger.debug("<< (%s) acquired %s", toString(), returnVal);
       return returnVal;
     } catch (Exception from) {
       try {
         connection.clear();
       } catch (Exception e1) {
         logger.warn(from, "<< (%s) error closing connection", toString());
       }
       if (i + 1 == sshRetries) {
         logger.error(from, "<< " + errorMessage + ": out of retries %d", sshRetries);
         throw propagate(from, errorMessage);
       } else if (Throwables2.getFirstThrowableOfType(from, IllegalStateException.class) != null) {
         logger.warn(from, "<< " + errorMessage + ": " + from.getMessage());
         disconnect();
         backoffForAttempt(i + 1, errorMessage + ": " + from.getMessage());
         connect();
         continue;
       } else if (shouldRetry(from)) {
         logger.warn(from, "<< " + errorMessage + ": " + from.getMessage());
         backoffForAttempt(i + 1, errorMessage + ": " + from.getMessage());
         continue;
       } else {
         logger.error(from, "<< " + errorMessage + ": exception not retryable");
         throw propagate(from, errorMessage);
       }
     }
   }
   assert false : "should not reach here";
   return null;
 }
  @Override
  public NodeMetadata apply(VirtualMachine from) {
    // convert the result object to a jclouds NodeMetadata
    NodeMetadataBuilder builder = new NodeMetadataBuilder();
    builder.ids(from.getId() + "");
    builder.name(from.getName());
    // TODO: in cloudstack 2.2.12, when "name" was set fine on the backend,
    // but wrong API response was returned to the user
    // http://bugs.cloud.com/show_bug.cgi?id=11664
    //
    // we set displayName to the same value as name, but this could be wrong
    // on hosts not started with jclouds
    builder.hostname(from.getDisplayName());
    builder.location(findLocationForVirtualMachine.apply(from));
    builder.group(parseGroupFromName(from.getDisplayName()));
    Image image = findImageForVirtualMachine.apply(from);
    if (image != null) {
      builder.imageId(image.getId());
      builder.operatingSystem(image.getOperatingSystem());
    }

    builder.hardware(
        new HardwareBuilder()
            .ids(from.getServiceOfferingId() + "")
            .name(from.getServiceOfferingName() + "")
            // .tags() TODO
            .processors(ImmutableList.of(new Processor(from.getCpuCount(), from.getCpuSpeed())))
            .ram((int) from.getMemory()) //
            .hypervisor(from.getHypervisor()) //
            .build());

    builder.state(vmStateToNodeState.get(from.getState()));

    Set<String> publicAddresses = newHashSet(), privateAddresses = newHashSet();
    if (from.getIPAddress() != null) {
      boolean isPrivate = isPrivateIPAddress(from.getIPAddress());
      if (isPrivate) {
        privateAddresses.add(from.getIPAddress());
      } else {
        publicAddresses.add(from.getIPAddress());
      }
    }
    for (NIC nic : from.getNICs()) {
      if (nic.getIPAddress() != null) {
        if (isPrivateIPAddress(nic.getIPAddress())) {
          privateAddresses.add(nic.getIPAddress());
        } else {
          publicAddresses.add(nic.getIPAddress());
        }
      }
    }
    try {
      /* Also add to the list of public IPs any public IP address that has a
      forwarding rule that links to this machine */
      Iterables.addAll(
          publicAddresses,
          transform(
              filter(
                  getIPForwardingRulesByVirtualMachine.getUnchecked(from.getId()),
                  new Predicate<IPForwardingRule>() {
                    @Override
                    public boolean apply(@Nullable IPForwardingRule rule) {
                      return !"Deleting".equals(rule.getState());
                    }
                  }),
              new Function<IPForwardingRule, String>() {
                @Override
                public String apply(@Nullable IPForwardingRule rule) {
                  return rule.getIPAddress();
                }
              }));
    } catch (UncheckedExecutionException e) {
      if (Throwables2.getFirstThrowableOfType(e, ResourceNotFoundException.class) == null) {
        Throwables.propagateIfPossible(e.getCause());
        throw e;
      }
    }
    return builder.privateAddresses(privateAddresses).publicAddresses(publicAddresses).build();
  }
  @Test(
      timeOut = 5 * 60 * 1000,
      dependsOnMethods = {"testCreateContainer", "testCreatePublicContainer"})
  public void testObjectOperations() throws Exception {
    String data = "Here is my data";

    // Test PUT with string data, ETag hash, and a piece of metadata
    AzureBlob object = getApi().newBlob();
    object.getProperties().setName("object");
    object.setPayload(data);
    Payloads.calculateMD5(object);
    object.getProperties().getContentMetadata().setContentType("text/plain");
    object.getProperties().getMetadata().put("mykey", "metadata-value");
    byte[] md5 = object.getProperties().getContentMetadata().getContentMD5();
    String newEtag = getApi().putBlob(privateContainer, object);
    assertEquals(
        CryptoStreams.hex(md5),
        CryptoStreams.hex(object.getProperties().getContentMetadata().getContentMD5()));

    // Test HEAD of missing object
    assert getApi().getBlobProperties(privateContainer, "non-existent-object") == null;

    // Test HEAD of object
    BlobProperties metadata =
        getApi().getBlobProperties(privateContainer, object.getProperties().getName());
    // TODO assertEquals(metadata.getName(),
    // object.getProperties().getName());
    // we can't check this while hacking around lack of content-md5, as GET of
    // the first byte will
    // show incorrect length 1, the returned size, as opposed to the real
    // length. This is an ok
    // tradeoff, as a container list will contain the correct size of the
    // objects in an
    // inexpensive fashion
    // http://code.google.com/p/jclouds/issues/detail?id=92
    // assertEquals(metadata.getSize(), data.length());
    assertEquals(metadata.getContentMetadata().getContentType(), "text/plain");
    // Azure doesn't return the Content-MD5 on head request..
    assertEquals(
        CryptoStreams.hex(md5),
        CryptoStreams.hex(object.getProperties().getContentMetadata().getContentMD5()));
    assertEquals(metadata.getETag(), newEtag);
    assertEquals(metadata.getMetadata().entrySet().size(), 1);
    assertEquals(metadata.getMetadata().get("mykey"), "metadata-value");

    // // Test POST to update object's metadata
    // Multimap<String, String> userMetadata = LinkedHashMultimap.create();
    // userMetadata.put("New-Metadata-1", "value-1");
    // userMetadata.put("New-Metadata-2", "value-2");
    // assertTrue(getApi().setBlobProperties(privateContainer,
    // object.getProperties().getName(),
    // userMetadata));

    // Test GET of missing object
    assert getApi().getBlob(privateContainer, "non-existent-object") == null;

    // Test GET of object (including updated metadata)
    AzureBlob getBlob = getApi().getBlob(privateContainer, object.getProperties().getName());
    assertEquals(Strings2.toString(getBlob.getPayload()), data);
    // TODO assertEquals(getBlob.getName(), object.getProperties().getName());
    assertEquals(
        getBlob.getPayload().getContentMetadata().getContentLength(), Long.valueOf(data.length()));
    assertEquals(getBlob.getProperties().getContentMetadata().getContentType(), "text/plain");
    assertEquals(
        CryptoStreams.hex(md5),
        CryptoStreams.hex(getBlob.getProperties().getContentMetadata().getContentMD5()));
    assertEquals(newEtag, getBlob.getProperties().getETag());
    // wait until we can update metadata
    // assertEquals(getBlob.getProperties().getMetadata().entries().size(),
    // 2);
    // assertEquals(
    // Iterables.getLast(getBlob.getProperties().getMetadata().get("New-Metadata-1")),
    // "value-1");
    // assertEquals(
    // Iterables.getLast(getBlob.getProperties().getMetadata().get("New-Metadata-2")),
    // "value-2");
    assertEquals(metadata.getMetadata().entrySet().size(), 1);
    assertEquals(metadata.getMetadata().get("mykey"), "metadata-value");

    // test listing
    ListBlobsResponse response =
        getApi()
            .listBlobs(
                privateContainer,
                ListBlobsOptions.Builder.prefix(
                        object
                            .getProperties()
                            .getName()
                            .substring(0, object.getProperties().getName().length() - 1))
                    .maxResults(1)
                    .includeMetadata());
    assertEquals(response.size(), 1);
    assertEquals(Iterables.getOnlyElement(response).getName(), object.getProperties().getName());
    assertEquals(
        Iterables.getOnlyElement(response).getMetadata(),
        ImmutableMap.of("mykey", "metadata-value"));

    // Test PUT with invalid ETag (as if object's data was corrupted in
    // transit)
    String correctEtag = newEtag;
    String incorrectEtag = "0" + correctEtag.substring(1);
    object.getProperties().setETag(incorrectEtag);
    try {
      getApi().putBlob(privateContainer, object);
    } catch (Throwable e) {
      assertEquals(e.getCause().getClass(), HttpResponseException.class);
      assertEquals(((HttpResponseException) e.getCause()).getResponse().getStatusCode(), 422);
    }

    ByteArrayInputStream bais = new ByteArrayInputStream(data.getBytes(Charsets.UTF_8));
    object = getApi().newBlob();
    object.getProperties().setName("chunked-object");
    object.setPayload(bais);
    object.getPayload().getContentMetadata().setContentLength(Long.valueOf(data.getBytes().length));
    newEtag = getApi().putBlob(privateContainer, object);
    assertEquals(
        CryptoStreams.hex(md5),
        CryptoStreams.hex(getBlob.getProperties().getContentMetadata().getContentMD5()));

    // Test GET with options
    // Non-matching ETag
    try {
      getApi()
          .getBlob(
              privateContainer,
              object.getProperties().getName(),
              GetOptions.Builder.ifETagDoesntMatch(newEtag));
    } catch (Exception e) {
      HttpResponseException httpEx =
          Throwables2.getFirstThrowableOfType(e, HttpResponseException.class);
      assert (httpEx != null) : "expected http exception, not " + e;
      assertEquals(httpEx.getResponse().getStatusCode(), 304);
    }

    // Matching ETag TODO this shouldn't fail!!!
    try {
      getBlob =
          getApi()
              .getBlob(
                  privateContainer,
                  object.getProperties().getName(),
                  GetOptions.Builder.ifETagMatches(newEtag));
      assertEquals(getBlob.getProperties().getETag(), newEtag);
    } catch (HttpResponseException e) {
      assertEquals(e.getResponse().getStatusCode(), 412);
    }

    // Range
    // doesn't work per
    // http://social.msdn.microsoft.com/Forums/en-US/windowsazure/thread/479fa63f-51df-4b66-96b5-33ae362747b6
    // getBlob = getApi()
    // .getBlob(privateContainer, object.getProperties().getName(),
    // GetOptions.Builder.startAt(8)).get(120,
    // TimeUnit.SECONDS);
    // assertEquals(Utils.toStringAndClose((InputStream) getBlob.getData()),
    // data.substring(8));

    getApi().deleteBlob(privateContainer, "object");
    getApi().deleteBlob(privateContainer, "chunked-object");
  }