Пример #1
0
 /*
  * ############################################################
  * operations which alter the physical resource and persist changes
  * ############################################################
  */
 @Override
 public boolean delete() throws ResourceException, IOException {
   try {
     S3Response response = S3Object.deleteObject(this.uri);
     if (response.getReturnCode() != HttpURLConnection.HTTP_NO_CONTENT)
       throw new ResourceException(
           "something went wrong when deleting the file: " + response.toString());
     /*
      * At this moment we know the URI of the object and that it is deleted (isFile=FALSE). Therefore the resource
      * has to be reset, to behave like a new constructed one.
      * But under versioning it still exists but with new versionID and delete marker
      */
     this.s3Object = new S3Object(response);
     this.modifiedHeader = null;
     return true;
   } catch (S3Exception e) {
     if (e.getErrorCode() == HttpURLConnection.HTTP_NOT_FOUND) {
       logger.info("file not found" + e.toString());
       return false;
     } else throw new ResourceException("error while deleting", e);
   }
 }
Пример #2
0
  S3Response invoke(
      @Nullable String bucket, @Nullable String object, @Nullable String temporaryEndpoint)
      throws S3Exception, CloudException, InternalException {
    if (wire.isDebugEnabled()) {
      wire.debug("");
      wire.debug(
          "----------------------------------------------------------------------------------");
    }
    try {
      StringBuilder url = new StringBuilder();
      boolean leaveOpen = false;
      HttpRequestBase method;
      HttpClient client;
      int status;

      if (provider.getEC2Provider().isAWS()) {
        url.append("https://");
        if (temporaryEndpoint == null) {
          boolean validDomainName = isValidDomainName(bucket);
          if (bucket != null && validDomainName) {
            url.append(bucket);
            url.append(".");
          }
          url.append("s3.amazonaws.com/");
          if (bucket != null && !validDomainName) {
            url.append(bucket);
            url.append("/");
          }
        } else {
          url.append(temporaryEndpoint);
          url.append("/");
        }
      } else if (provider.getEC2Provider().isStorage()
          && "google".equalsIgnoreCase(provider.getProviderName())) {
        url.append("https://");
        if (temporaryEndpoint == null) {
          if (bucket != null) {
            url.append(bucket);
            url.append(".");
          }
          url.append("commondatastorage.googleapis.com/");
        } else {
          url.append(temporaryEndpoint);
          url.append("/");
        }
      } else {
        int idx = 0;

        if (!provider.getContext().getEndpoint().startsWith("http")) {
          url.append("https://");
        } else {
          idx = provider.getContext().getEndpoint().indexOf("https://");
          if (idx == -1) {
            idx = "http://".length();
            url.append("http://");
          } else {
            idx = "https://".length();
            url.append("https://");
          }
        }
        String service = "";
        if (provider.getEC2Provider().isEucalyptus()) {
          service = "Walrus/";
        }

        if (temporaryEndpoint == null) {
          url.append(provider.getContext().getEndpoint().substring(idx));
          if (!provider.getContext().getEndpoint().endsWith("/")) {
            url.append("/").append(service);
          } else {
            url.append(service);
          }
        } else {
          url.append(temporaryEndpoint);
          url.append("/");
          url.append(service);
        }
        if (bucket != null) {
          url.append(bucket);
          url.append("/");
        }
      }
      if (object != null) {
        url.append(object);
      } else if (parameters != null) {
        boolean first = true;

        if (object != null && object.indexOf('?') != -1) {
          first = false;
        }
        for (Map.Entry<String, String> entry : parameters.entrySet()) {
          String key = entry.getKey();
          String val = entry.getValue();

          if (first) {
            url.append("?");
            first = false;
          } else {
            url.append("&");
          }
          if (val != null) {
            url.append(AWSCloud.encode(key, false));
            url.append("=");
            url.append(AWSCloud.encode(val, false));
          } else {
            url.append(AWSCloud.encode(key, false));
          }
        }
      }

      if (provider.getEC2Provider().isStorage()
          && provider.getProviderName().equalsIgnoreCase("Google")) {
        headers.put(AWSCloud.P_GOOG_DATE, getDate());
      } else {
        headers.put(AWSCloud.P_AWS_DATE, getDate());
      }
      method = action.getMethod(url.toString());
      if (headers != null) {
        for (Map.Entry<String, String> entry : headers.entrySet()) {
          method.addHeader(entry.getKey(), entry.getValue());
        }
      }
      if (contentType == null && body != null) {
        contentType = "application/xml";
        method.addHeader("Content-Type", contentType);
      }
      try {
        String hash = null;
        String signature;

        signature =
            provider.signS3(
                new String(provider.getContext().getAccessPublic(), "utf-8"),
                provider.getContext().getAccessPrivate(),
                method.getMethod(),
                hash,
                contentType,
                headers,
                bucket,
                object);
        method.addHeader(AWSCloud.P_CFAUTH, signature);
      } catch (UnsupportedEncodingException e) {
        logger.error(e);
        e.printStackTrace();
        throw new InternalException(e);
      }
      if (body != null) {
        try {
          ((HttpEntityEnclosingRequestBase) method)
              .setEntity(new StringEntity(body, "application/xml", "utf-8"));
        } catch (UnsupportedEncodingException e) {
          throw new InternalException(e);
        }
      } else if (uploadFile != null) {
        ((HttpEntityEnclosingRequestBase) method)
            .setEntity(new FileEntity(uploadFile, contentType));
      }
      attempts++;
      client = getClient(url.toString(), body == null && uploadFile == null);

      if (wire.isDebugEnabled()) {
        wire.debug("[" + url.toString() + "]");
        wire.debug(method.getRequestLine().toString());
        for (Header header : method.getAllHeaders()) {
          wire.debug(header.getName() + ": " + header.getValue());
        }
        wire.debug("");
        if (body != null) {
          try {
            wire.debug(EntityUtils.toString(((HttpEntityEnclosingRequestBase) method).getEntity()));
          } catch (IOException ignore) {
          }

          wire.debug("");
        } else if (uploadFile != null) {
          wire.debug("-- file upload --");
          wire.debug("");
        }
      }
      S3Response response = new S3Response();
      HttpResponse httpResponse;

      try {
        httpResponse = client.execute(method);
        if (wire.isDebugEnabled()) {
          wire.debug(httpResponse.getStatusLine().toString());
          for (Header header : httpResponse.getAllHeaders()) {
            wire.debug(header.getName() + ": " + header.getValue());
          }
          wire.debug("");
        }
        status = httpResponse.getStatusLine().getStatusCode();
      } catch (IOException e) {
        logger.error(url + ": " + e.getMessage());
        e.printStackTrace();
        throw new InternalException(e);
      }
      response.headers = httpResponse.getAllHeaders();

      HttpEntity entity = httpResponse.getEntity();
      InputStream input = null;

      if (entity != null) {
        try {
          input = entity.getContent();
        } catch (IOException e) {
          throw new CloudException(e);
        }
      }
      try {
        if (status == HttpServletResponse.SC_OK
            || status == HttpServletResponse.SC_CREATED
            || status == HttpServletResponse.SC_ACCEPTED) {
          Header clen = httpResponse.getFirstHeader("Content-Length");
          long len = -1L;

          if (clen != null) {
            len = Long.parseLong(clen.getValue());
          }
          if (len != 0L) {
            try {
              Header ct = httpResponse.getFirstHeader("Content-Type");

              if (ct != null
                  && (ct.getValue().startsWith("application/xml")
                      || ct.getValue().startsWith("text/xml"))) {
                try {
                  response.document = parseResponse(input);
                  return response;
                } finally {
                  input.close();
                }
              } else if (ct != null
                  && ct.getValue().startsWith("application/octet-stream")
                  && len < 1) {
                return null;
              } else {
                response.contentLength = len;
                if (ct != null) {
                  response.contentType = ct.getValue();
                }
                response.input = input;
                response.method = method;
                leaveOpen = true;
                return response;
              }
            } catch (IOException e) {
              logger.error(e);
              e.printStackTrace();
              throw new CloudException(e);
            }
          } else {
            return response;
          }
        } else if (status == HttpServletResponse.SC_NO_CONTENT) {
          return response;
        } else if (status == HttpServletResponse.SC_NOT_FOUND) {
          throw new S3Exception(status, null, null, "Object not found.");
        } else {
          if (status == HttpServletResponse.SC_SERVICE_UNAVAILABLE
              || status == HttpServletResponse.SC_INTERNAL_SERVER_ERROR) {
            if (attempts >= 5) {
              String msg;

              if (status == HttpServletResponse.SC_SERVICE_UNAVAILABLE) {
                msg = "Cloud service is currently unavailable.";
              } else {
                msg = "The cloud service encountered a server error while processing your request.";
              }
              logger.error(msg);
              throw new CloudException(msg);
            } else {
              leaveOpen = true;
              if (input != null) {
                try {
                  input.close();
                } catch (IOException ignore) {
                }
              }
              try {
                Thread.sleep(5000L);
              } catch (InterruptedException ignore) {
              }
              return invoke(bucket, object);
            }
          }
          try {
            Document doc;

            try {
              logger.warn("Received error code: " + status);
              doc = parseResponse(input);
            } finally {
              input.close();
            }
            if (doc != null) {
              String endpoint = null, code = null, message = null, requestId = null;
              NodeList blocks = doc.getElementsByTagName("Error");

              if (blocks.getLength() > 0) {
                Node error = blocks.item(0);
                NodeList attrs;

                attrs = error.getChildNodes();
                for (int i = 0; i < attrs.getLength(); i++) {
                  Node attr = attrs.item(i);

                  if (attr.getNodeName().equals("Code") && attr.hasChildNodes()) {
                    code = attr.getFirstChild().getNodeValue().trim();
                  } else if (attr.getNodeName().equals("Message") && attr.hasChildNodes()) {
                    message = attr.getFirstChild().getNodeValue().trim();
                  } else if (attr.getNodeName().equals("RequestId") && attr.hasChildNodes()) {
                    requestId = attr.getFirstChild().getNodeValue().trim();
                  } else if (attr.getNodeName().equals("Endpoint") && attr.hasChildNodes()) {
                    endpoint = attr.getFirstChild().getNodeValue().trim();
                  }
                }
              }
              if (endpoint != null && code.equals("TemporaryRedirect")) {
                if (temporaryEndpoint != null) {
                  throw new CloudException("Too deep redirect to " + endpoint);
                } else {
                  return invoke(bucket, object, endpoint);
                }
              } else {
                if (message == null) {
                  throw new CloudException(
                      "Unable to identify error condition: "
                          + status
                          + "/"
                          + requestId
                          + "/"
                          + code);
                }
                throw new S3Exception(status, requestId, code, message);
              }
            } else {
              throw new CloudException("Unable to parse error.");
            }
          } catch (IOException e) {
            if (status == HttpServletResponse.SC_FORBIDDEN) {
              throw new S3Exception(
                  status, "", "AccessForbidden", "Access was denied without explanation.");
            }
            throw new CloudException(e);
          } catch (RuntimeException e) {
            throw new CloudException(e);
          } catch (Error e) {
            throw new CloudException(e);
          }
        }
      } finally {
        if (!leaveOpen) {
          if (input != null) {
            try {
              input.close();
            } catch (IOException ignore) {
            }
          }
        }
      }
    } finally {
      if (wire.isDebugEnabled()) {
        wire.debug(
            "----------------------------------------------------------------------------------");
        wire.debug("");
      }
    }
  }