/* * ############################################################ * 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); } }
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(""); } } }