com.mysql.jdbc.Driver
+<<<<<<< HEAD
+=======
+ jdbc:mysql://localhost/cloudbridge
+ cloud
+ cloud
+>>>>>>> 6472e7b... Now really adding the renamed files!
20
false
@@ -16,10 +22,17 @@
true
+<<<<<<< HEAD
+=======
+
+>>>>>>> 6472e7b... Now really adding the renamed files!
diff --git a/awsapi/conf/log4j-cloud-bridge.xml b/awsapi/conf/log4j-cloud-bridge.xml
new file mode 100644
index 00000000000..cc5a76f6de2
--- /dev/null
+++ b/awsapi/conf/log4j-cloud-bridge.xml
@@ -0,0 +1,68 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/awsapi/docs/AmazonS3/wsdl2java-command-line.txt b/awsapi/docs/AmazonS3/wsdl2java-command-line.txt
new file mode 100644
index 00000000000..fbd134075b1
--- /dev/null
+++ b/awsapi/docs/AmazonS3/wsdl2java-command-line.txt
@@ -0,0 +1,47 @@
+To generate the Java AXIS2 classes from the Amazon EC2 wsdl use the following command line, assuming source definitions in the local directory:
+$ wsdl2java.sh -ss -sd -ssi -g -p com.amazon.s3 -ns2p "http://s3.amazonaws.com/doc/2006-03-01/"=com.amazon.s3 -uri cloud-AmazonS3.wsdl
+
+This runs the wsdl2java code generation tool to produce stubs with asynchronous invocation methods, such as those useful for REST using the com.amazon.s3 package.
+
+This creates the following java source files in the src/com/amazon/s3 subdirectory …
+
+AccessControlList.java ListAllMyBucketsResponse.java
+AccessControlPolicy.java ListAllMyBucketsResult.java
+AmazonCustomerByEmail.java ListBucket.java
+AmazonS3CallbackHandler.java ListBucketResponse.java
+AmazonS3MessageReceiverInOut.java ListBucketResult.java
+AmazonS3Skeleton.java ListEntry.java
+AmazonS3SkeletonInterface.java ListVersionsResponse.java
+AmazonS3Stub.java ListVersionsResult.java
+BucketLoggingStatus.java ListVersionsResultChoice_type0.java
+CanonicalUser.java LocationConstraint.java
+CopyObject.java LoggingSettings.java
+CopyObjectResponse.java MetadataDirective.java
+CopyObjectResult.java MetadataEntry.java
+CreateBucket.java MfaDeleteStatus.java
+CreateBucketConfiguration.java NotificationConfiguration.java
+CreateBucketResponse.java Payer.java
+CreateBucketResult.java Permission.java
+DeleteBucket.java PostResponse.java
+DeleteBucketResponse.java PrefixEntry.java
+DeleteMarkerEntry.java PutObject.java
+DeleteObject.java PutObjectInline.java
+DeleteObjectResponse.java PutObjectInlineResponse.java
+ExtensionMapper.java PutObjectResponse.java
+GetBucketAccessControlPolicy.java PutObjectResult.java
+GetBucketAccessControlPolicyResponse.java RequestPaymentConfiguration.java
+GetBucketLoggingStatus.java Result.java
+GetBucketLoggingStatusResponse.java SetBucketAccessControlPolicy.java
+GetObject.java SetBucketAccessControlPolicyResponse.java
+GetObjectAccessControlPolicy.java SetBucketLoggingStatus.java
+GetObjectAccessControlPolicyResponse.java SetBucketLoggingStatusResponse.java
+GetObjectExtended.java SetObjectAccessControlPolicy.java
+GetObjectExtendedResponse.java SetObjectAccessControlPolicyResponse.java
+GetObjectResponse.java Status.java
+GetObjectResult.java StorageClass.java
+Grant.java TopicConfiguration.java
+Grantee.java User.java
+Group.java VersionEntry.java
+ListAllMyBuckets.java VersioningConfiguration.java
+ListAllMyBucketsEntry.java VersioningStatus.java
+ListAllMyBucketsList.java
diff --git a/awsapi/modules/axis2-adb-1.6.2.jar b/awsapi/modules/axis2-adb-1.6.2.jar
new file mode 100644
index 00000000000..6234fdbba89
Binary files /dev/null and b/awsapi/modules/axis2-adb-1.6.2.jar differ
diff --git a/awsapi/modules/axis2-adb-codegen-1.6.2.jar b/awsapi/modules/axis2-adb-codegen-1.6.2.jar
new file mode 100644
index 00000000000..7d037d49846
Binary files /dev/null and b/awsapi/modules/axis2-adb-codegen-1.6.2.jar differ
diff --git a/awsapi/modules/axis2-ant-plugin-1.6.2.jar b/awsapi/modules/axis2-ant-plugin-1.6.2.jar
new file mode 100644
index 00000000000..771b2222319
Binary files /dev/null and b/awsapi/modules/axis2-ant-plugin-1.6.2.jar differ
diff --git a/awsapi/modules/axis2-clustering-1.6.2.jar b/awsapi/modules/axis2-clustering-1.6.2.jar
new file mode 100644
index 00000000000..e45be9997e0
Binary files /dev/null and b/awsapi/modules/axis2-clustering-1.6.2.jar differ
diff --git a/awsapi/modules/axis2-codegen-1.6.2.jar b/awsapi/modules/axis2-codegen-1.6.2.jar
new file mode 100644
index 00000000000..f742f19c6b7
Binary files /dev/null and b/awsapi/modules/axis2-codegen-1.6.2.jar differ
diff --git a/awsapi/modules/axis2-corba-1.6.2.jar b/awsapi/modules/axis2-corba-1.6.2.jar
new file mode 100644
index 00000000000..ee3c78e9ddf
Binary files /dev/null and b/awsapi/modules/axis2-corba-1.6.2.jar differ
diff --git a/awsapi/modules/axis2-fastinfoset-1.6.2.jar b/awsapi/modules/axis2-fastinfoset-1.6.2.jar
new file mode 100644
index 00000000000..d10c36a4926
Binary files /dev/null and b/awsapi/modules/axis2-fastinfoset-1.6.2.jar differ
diff --git a/awsapi/modules/axis2-java2wsdl-1.6.2.jar b/awsapi/modules/axis2-java2wsdl-1.6.2.jar
new file mode 100644
index 00000000000..0bb869d71f1
Binary files /dev/null and b/awsapi/modules/axis2-java2wsdl-1.6.2.jar differ
diff --git a/awsapi/modules/axis2-jaxbri-1.6.2.jar b/awsapi/modules/axis2-jaxbri-1.6.2.jar
new file mode 100644
index 00000000000..616eec9ca65
Binary files /dev/null and b/awsapi/modules/axis2-jaxbri-1.6.2.jar differ
diff --git a/awsapi/modules/axis2-jaxws-1.6.2.jar b/awsapi/modules/axis2-jaxws-1.6.2.jar
new file mode 100644
index 00000000000..064351a5b8a
Binary files /dev/null and b/awsapi/modules/axis2-jaxws-1.6.2.jar differ
diff --git a/awsapi/modules/axis2-jibx-1.6.2.jar b/awsapi/modules/axis2-jibx-1.6.2.jar
new file mode 100644
index 00000000000..75f9d1a4c5b
Binary files /dev/null and b/awsapi/modules/axis2-jibx-1.6.2.jar differ
diff --git a/awsapi/modules/axis2-json-1.6.2.jar b/awsapi/modules/axis2-json-1.6.2.jar
new file mode 100644
index 00000000000..edd79368eaa
Binary files /dev/null and b/awsapi/modules/axis2-json-1.6.2.jar differ
diff --git a/awsapi/modules/axis2-kernel-1.6.2.jar b/awsapi/modules/axis2-kernel-1.6.2.jar
new file mode 100644
index 00000000000..3ae5f7a0466
Binary files /dev/null and b/awsapi/modules/axis2-kernel-1.6.2.jar differ
diff --git a/awsapi/modules/axis2-metadata-1.6.2.jar b/awsapi/modules/axis2-metadata-1.6.2.jar
new file mode 100644
index 00000000000..492f1ac4ab7
Binary files /dev/null and b/awsapi/modules/axis2-metadata-1.6.2.jar differ
diff --git a/awsapi/modules/axis2-mtompolicy-1.6.2.jar b/awsapi/modules/axis2-mtompolicy-1.6.2.jar
new file mode 100644
index 00000000000..561e84a9536
Binary files /dev/null and b/awsapi/modules/axis2-mtompolicy-1.6.2.jar differ
diff --git a/awsapi/modules/axis2-saaj-1.6.2.jar b/awsapi/modules/axis2-saaj-1.6.2.jar
new file mode 100644
index 00000000000..c14531dc563
Binary files /dev/null and b/awsapi/modules/axis2-saaj-1.6.2.jar differ
diff --git a/awsapi/modules/axis2-soapmonitor-servlet-1.6.2.jar b/awsapi/modules/axis2-soapmonitor-servlet-1.6.2.jar
new file mode 100644
index 00000000000..276dac7e76c
Binary files /dev/null and b/awsapi/modules/axis2-soapmonitor-servlet-1.6.2.jar differ
diff --git a/awsapi/modules/axis2-spring-1.6.2.jar b/awsapi/modules/axis2-spring-1.6.2.jar
new file mode 100644
index 00000000000..30b9baaffd5
Binary files /dev/null and b/awsapi/modules/axis2-spring-1.6.2.jar differ
diff --git a/awsapi/modules/axis2-transport-http-1.6.2.jar b/awsapi/modules/axis2-transport-http-1.6.2.jar
new file mode 100644
index 00000000000..b1dad789900
Binary files /dev/null and b/awsapi/modules/axis2-transport-http-1.6.2.jar differ
diff --git a/awsapi/modules/axis2-transport-local-1.6.2.jar b/awsapi/modules/axis2-transport-local-1.6.2.jar
new file mode 100644
index 00000000000..34a7073f34f
Binary files /dev/null and b/awsapi/modules/axis2-transport-local-1.6.2.jar differ
diff --git a/awsapi/modules/axis2-xmlbeans-1.6.2.jar b/awsapi/modules/axis2-xmlbeans-1.6.2.jar
new file mode 100644
index 00000000000..58fba9b9bed
Binary files /dev/null and b/awsapi/modules/axis2-xmlbeans-1.6.2.jar differ
diff --git a/awsapi/release-notes.html b/awsapi/release-notes.html
new file mode 100644
index 00000000000..419cb188d32
--- /dev/null
+++ b/awsapi/release-notes.html
@@ -0,0 +1,123 @@
+
+
+
+
+
+ Welcome to Apache Axis2 version 1.6.2
+
+
+
+Welcome to Apache Axis2 version 1.6.2
+
+April 17, 2012
+
+Axis2 1.6.2 is a maintenance release that upgrades Axiom to version 1.2.13 and
+Neethi to version 3.0.2. it contains fixes for several issues discovered
+over the last six months. The complete list can be found here.
+
+
+About Axis2
+
+Downloads are available at:
+ http://axis.apache.org/axis2/java/core/download.cgi
+
+Apache Axis2 is a complete re-design and re-write of the widely used
+Apache Axis engine and is a more efficient, more scalable, more modular
+and more XML-oriented Web services framework. It is carefully designed to
+support the easy addition of plug-in "modules" that extend its
+functionality for features such as security and reliability.
+
+Modules supporting WS-Security/Secure-Conversation (Apache Rampart),
+WS-Trust (Apache Rahas), WS-Reliable Messaging (Apache Sandesha) and
+WS-Eventing (Apache Savan) will be available soon after the Apache Axis2
+@axisVersion@ release. Please see these projects' own sites for further information.
+
+Known Issues and Limitations in 1.6.2 Release:
+- Please see JIRA
+
+We are striving for a simple and happy first time user experience as well as a
+satisfying experienced user experience with this release. We welcome any
+and all feedback at:
+ java-user@axis.apache.org (please include "[axis2]" in the subject)
+ java-dev@axis.apache.org (please include "[axis2]" in the subject)
+ http://issues.apache.org/jira/browse/AXIS2
+
+Thank you for your interest in Apache Axis2!
+
+The Axis2 Development Team
+http://axis.apache.org/axis2/java/core/
+
+------------------------------------------------------------------------------------
+
+Features of Apache Axis2:
+
+Programming Model
+ - Simple XML-centric client API with full WSDL and policy support
+ - Support for POJO and Spring services and clients
+ - Support for any message exchange pattern (MEP)
+ - Synchronous and asynchronous programming model
+ - Archived service deployment model supporting full service
+ encapsulation with versioning support
+ - Archived module deployment model supporting controlled
+ extensibility with versioning support
+ - Hot deployment
+ - WS-Policy driven code generation extensions
+ - Flexible service life cycle model
+ - Automatic support for POX (REST) style invocation of services
+ - Support for querying service's WSDL (with ?wsdl), schema (with
+ ?xsd) and policies (with ?policy)
+
+Supported Specifications
+ - SOAP 1.1 and 1.2
+ - Message Transmission Optimization Mechanism (MTOM)
+ - XML Optimized Packaging (XOP)
+ - SOAP with Attachments
+ - WSDL 1.1, including both SOAP and HTTP bindings , WSDL 2.0
+ - WS-Addressing submission and 1.0
+ - WS-Policy
+ - SAAJ 1.1
+
+Transports
+ - HTTP
+ - SMTP
+ - JMS
+ - TCP
+ - udp
+ - xmpp
+
+For more details refer to the Axis2 Transports project.
+
+Supported Data Bindings
+ - Axis Data Binding (ADB)
+ - XMLBeans
+ - JibX
+ - JAXB
+
+Tools
+ - WSDL2Java: Generate Java stubs and skeletons from a WSDL document.
+ - Java2WSDL: Generate a WSDL document from a Java class.
+ - Eclipse Plugins
+ - IntelliJ Idea Plugins
+ - Maven2 Plugins
+ - Web application for administering Apache Axis2
+
+
+
+
diff --git a/awsapi/release-notes.txt b/awsapi/release-notes.txt
index 04250ec0b42..6b20c73a754 100644
--- a/awsapi/release-notes.txt
+++ b/awsapi/release-notes.txt
@@ -1,3 +1,4 @@
+<<<<<<< HEAD
1.0.2.RC6
=========
@@ -10,6 +11,8 @@
* Fixed ec2-register/registerTemplate calls
+=======
+>>>>>>> 6472e7b... Now really adding the renamed files!
1.0.2.RC4
=========
diff --git a/awsapi/src/com/cloud/bridge/auth/s3/AuthenticationHandler.java b/awsapi/src/com/cloud/bridge/auth/s3/AuthenticationHandler.java
index 3b2ffcb282f..e1eb06347be 100644
--- a/awsapi/src/com/cloud/bridge/auth/s3/AuthenticationHandler.java
+++ b/awsapi/src/com/cloud/bridge/auth/s3/AuthenticationHandler.java
@@ -33,6 +33,12 @@ import com.cloud.bridge.persist.dao.UserCredentialsDao;
import com.cloud.bridge.service.UserContext;
import com.cloud.bridge.util.S3SoapAuth;
+<<<<<<< HEAD
+=======
+/*
+ * For SOAP compatibility.
+ */
+>>>>>>> 6472e7b... Now really adding the renamed files!
public class AuthenticationHandler implements Handler {
protected final static Logger logger = Logger.getLogger(AuthenticationHandler.class);
diff --git a/awsapi/src/com/cloud/bridge/io/DimeDelimitedInputStream.java b/awsapi/src/com/cloud/bridge/io/DimeDelimitedInputStream.java
new file mode 100644
index 00000000000..bad5164127d
--- /dev/null
+++ b/awsapi/src/com/cloud/bridge/io/DimeDelimitedInputStream.java
@@ -0,0 +1,617 @@
+/* Took the basic code from Axis 1.2 and modified to fit into the cloud code base */
+
+/*
+ * Copyright 2001-2004 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.cloud.bridge.io;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.FilterInputStream;
+import org.apache.log4j.Logger;
+
+
+/**
+ * This class takes the input stream and turns it multiple streams.
+ DIME version 0 format
+
+ 0 1 2 3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ---
+ | VERSION |B|E|C| TYPE_T| OPT_T | OPTIONS_LENGTH | A
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | ID_LENGTH | TYPE_LENGTH | Always present 12 bytes
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ even on chunked data.
+ | DATA_LENGTH | V
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ---
+ | /
+ / OPTIONS + PADDING /
+ / (absent for version 0) |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | /
+ / ID + PADDING /
+ / |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | /
+ / TYPE + PADDING /
+ / |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | /
+ / DATA + PADDING /
+ / |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+ * This implementation of input stream does not support marking operations.
+ *
+ * Incoming data is DIME encoded when its MIME type is "application/dime".
+ * Then use this class to pull out 2 streams:
+ * (1) The first stream is the SOAP request,
+ * (2) The second stream is a chunked attachment (e.g., a file to store)
+ *
+ * The DIME format is defined at this reference:
+ * http://msdn.microsoft.com/en-us/library/aa480488.aspx
+ *
+ * @author Rick Rineholt
+ */
+public class DimeDelimitedInputStream extends FilterInputStream
+{
+ protected final static Logger logger = Logger.getLogger(DimeDelimitedInputStream.class);
+
+ InputStream is = null; //The source input stream.
+ boolean closed = true; //The stream has been closed.
+ boolean theEnd = false; //There are no more streams left.
+ boolean moreChunks = false; //More chunks are a coming!
+ boolean MB = false; //Message begin flag
+ boolean ME = false; //Message end flag
+ String type = null; //
+ String id = null; //
+ String tnf = null; //DIME type format
+ long recordLength = 0L; //length of the current record.
+ long bytesRead = 0L; //How many bytes of the current record have been read.
+ int dataPadLength = 0; //How many pad bytes there are.
+
+ protected int streamNo = 0;
+ protected IOException streamInError = null;
+
+ private static byte[] trash = new byte[4];
+ protected static int streamCount = 0; //number of streams produced.
+
+ protected static synchronized int newStreamNo()
+ {
+ logger.debug( "streamNo " + (streamCount + 1));
+ return ++streamCount;
+ }
+
+
+ /**
+ * There can be multiple streams in a DIME encoding. For example, the first
+ * stream can be a SOAP message, and the second stream a binary attachment (e.g.,
+ * a file). During reading after an EOF is returned, this function should be
+ * called to see if there is another stream following the last.
+ *
+ * @return the dime delimited stream, null if there are no more streams
+ * @throws IOException if there was an error loading the data for the next stream
+ */
+ public synchronized DimeDelimitedInputStream getNextStream() throws IOException
+ {
+ if (null != streamInError) throw streamInError;
+ if (theEnd) return null;
+
+ //Each Stream must be read in succession
+ if (bytesRead < recordLength || moreChunks)
+ throw new RuntimeException("attach.dimeReadFullyError");
+
+ dataPadLength -= readPad(dataPadLength);
+
+ //Create an new dime stream that comes after this one.
+ return new DimeDelimitedInputStream( this.is );
+ }
+
+
+ /**
+ * Create a new dime stream.
+ *
+ * @param is the InputStream to wrap
+ * @throws IOException if anything goes wrong
+ */
+ public DimeDelimitedInputStream( InputStream is ) throws IOException
+ {
+ super(null);
+ streamNo = newStreamNo();
+ closed = false;
+ this.is = is;
+ readHeader( false );
+ }
+
+
+ /**
+ * Make sure to skip the pad which appear in several parts of a DIME message.
+ * @param size
+ * @return
+ * @throws IOException
+ */
+ private final int readPad( int size ) throws IOException
+ {
+ if (0 == size) return 0;
+ int read = readFromStream(trash, 0, size);
+
+ if (size != read)
+ {
+ streamInError = new IOException("attach.dimeNotPaddedCorrectly");
+ throw streamInError;
+ }
+ return read;
+ }
+
+
+ private final int readFromStream( byte[] b ) throws IOException
+ {
+ return readFromStream( b, 0, b.length );
+ }
+
+ private final int readFromStream( byte[] b, int start, int length ) throws IOException
+ {
+ int br = 0;
+ int brTotal = 0;
+
+ if (length == 0) return 0;
+
+ do
+ { try
+ {
+ br = is.read( b, brTotal + start, length - brTotal );
+ }
+ catch (IOException e)
+ {
+ streamInError = e;
+ throw e;
+ }
+ if (br > 0) brTotal += br;
+ }
+ while( br > -1 && brTotal < length );
+
+ return br > -1 ? brTotal : br;
+ }
+
+
+ /**
+ * Get the id for this stream part.
+ * @return the id;
+ */
+ public String getContentId()
+ {
+ return id;
+ }
+
+ public String getDimeTypeNameFormat()
+ {
+ return tnf;
+ }
+
+ /**
+ * Get the type, as read from the header.
+ * @return the type of this dime
+ */
+ public String getType()
+ {
+ return type;
+ }
+
+
+ /**
+ * Read from the DIME stream.
+ *
+ * @param b is the array to read into.
+ * @param off is the offset
+ * @return the number of bytes read. -1 if endof stream
+ * @throws IOException if data could not be read from the stream
+ */
+ public synchronized int read( byte[] b, int off, int len ) throws IOException
+ {
+ if (closed)
+ {
+ dataPadLength -= readPad(dataPadLength);
+ throw new IOException( "streamClosed" );
+ }
+ return _read( b, off, len );
+ }
+
+
+ protected int _read( byte[] b, int off, int len ) throws IOException
+ {
+ int totalbytesread = 0;
+ int bytes2read = 0;
+
+ if (len < 0)
+ throw new IllegalArgumentException( "attach.readLengthError" + len );
+
+ if (off < 0)
+ throw new IllegalArgumentException( "attach.readOffsetError" + off );
+
+ if (b == null)
+ throw new IllegalArgumentException( "attach.readArrayNullError" );
+
+ if (b.length < off + len)
+ throw new IllegalArgumentException("attach.readArraySizeError " + b.length + " " + len + " " + off );
+
+ if (null != streamInError) throw streamInError;
+ if (0 == len) return 0; //quick.
+
+ // odd case no data to read -- give back 0 next time -1;
+ if (recordLength == 0 && bytesRead == 0 && !moreChunks)
+ {
+ ++bytesRead;
+ if (ME) finalClose();
+ return 0;
+ }
+ if (bytesRead >= recordLength && !moreChunks)
+ {
+ dataPadLength -= readPad( dataPadLength );
+ if (ME) finalClose();
+ return -1;
+ }
+
+
+ do
+ { if (bytesRead >= recordLength && moreChunks) readHeader( true );
+ bytes2read = (int) Math.min( recordLength - bytesRead, (long)len - totalbytesread );
+
+ try
+ { bytes2read = is.read( b, off + totalbytesread, bytes2read );
+ }
+ catch (IOException e)
+ {
+ streamInError = e;
+ throw e;
+ }
+
+ if (0 < bytes2read)
+ {
+ totalbytesread += bytes2read;
+ bytesRead += bytes2read;
+ }
+ }
+ while( bytes2read > -1 && totalbytesread < len && (bytesRead < recordLength || moreChunks));
+
+ if ( 0 > bytes2read )
+ {
+ if (moreChunks)
+ {
+ streamInError = new IOException("attach.DimeStreamError0");
+ throw streamInError;
+ }
+ if (bytesRead < recordLength)
+ {
+ streamInError = new IOException("attach.DimeStreamError1 " + (recordLength - bytesRead));
+ throw streamInError;
+ }
+ if (!ME)
+ {
+ streamInError = new IOException("attach.DimeStreamError0");
+ throw streamInError;
+ }
+ //in theory the last chunk of data should also have been padded, but lets be tolerant of that.
+ dataPadLength = 0;
+ }
+ else if (bytesRead >= recordLength)
+ {
+ //get rid of pading.
+ try
+ { dataPadLength -= readPad( dataPadLength );
+ }
+ catch (IOException e)
+ {
+ //in theory the last chunk of data should also have been padded, but lets be tolerant of that.
+ if (!ME) throw e;
+ else
+ {
+ dataPadLength = 0;
+ streamInError = null;
+ }
+ }
+ }
+
+ if (bytesRead >= recordLength && ME) finalClose();
+
+ return totalbytesread >= 0 ? totalbytesread : -1;
+ }
+
+
+ /**
+ * The DIME header is read into local class data fields and are not
+ * passed as part of the stream data.
+ *
+ * @param isChunk
+ * @throws IOException
+ */
+ protected void readHeader( boolean isChunk ) throws IOException
+ {
+ bytesRead = 0; //How many bytes of the record have been read.
+
+ if (isChunk)
+ {
+ if (!moreChunks) throw new RuntimeException("attach.DimeStreamError2");
+ dataPadLength -= readPad(dataPadLength); //Just in case it was left over.
+ }
+
+ byte[] header = new byte[12];
+
+ if (header.length != readFromStream( header) )
+ {
+ streamInError = new IOException("attach.DimeStreamError3 " + header.length );
+ throw streamInError;
+ }
+
+ //VERSION
+ byte version = (byte) ((header[0] >>> 3) & 0x1f);
+ if (version > 1)
+ {
+ streamInError = new IOException("attach.DimeStreamError4 " + version );
+ throw streamInError;
+ }
+
+ //B, E, C
+ MB = 0 != (0x4 & header[0]);
+ ME = 0 != (0x2 & header[0]);
+ moreChunks = 0 != (0x1 & header[0]);
+
+ //TYPE_T
+ if (!isChunk)
+ {
+ switch( ((header[1] >>> 4) & (byte)0x0f) ) {
+ case 0x00: tnf = "UNCHANGED"; break;
+ case 0x01: tnf = "MIME"; break;
+ case 0x02: tnf = "URI"; break;
+ default: tnf = "UNKNOWN"; break;
+ }
+ }
+
+ //OPTIONS_LENGTH
+ int optionsLength = ((((int) header[2]) << 8) & 0xff00) | ((int) header[3]);
+
+ //ID_LENGTH
+ int idLength = ((((int) header[4]) << 8) & 0xff00) | ((int) header[5]);
+
+ //TYPE_LENGTH
+ int typeLength = ((((int) header[6]) << 8) & 0xff00) | ((int) header[7]);
+
+ //DATA_LENGTH
+ recordLength = ((((long) header[8] ) << 24) & 0xff000000L) |
+ ((((long) header[9] ) << 16) & 0xff0000L ) |
+ ((((long) header[10]) << 8 ) & 0xff00L ) |
+ ((long) header[11] & 0xffL );
+
+ //OPTIONS + PADDING
+ if (0 != optionsLength)
+ {
+ byte[] optBytes = new byte[optionsLength];
+
+ if (optionsLength != readFromStream( optBytes ))
+ {
+ streamInError = new IOException("attach.DimeStreamError5 " + optionsLength );
+ throw streamInError;
+ }
+ optBytes = null; // throw it away, don't know anything about options.
+
+ int pad = (int) ((4L - (optionsLength & 0x3L)) & 0x03L);
+
+ if (pad != readFromStream( header, 0, pad ))
+ {
+ streamInError = new IOException("attach.DimeStreamError7");
+ throw streamInError;
+ }
+ }
+
+ // ID + PADDING
+ if (0 < idLength)
+ {
+ byte[] idBytes = new byte[ idLength];
+
+ if (idLength != readFromStream( idBytes ))
+ {
+ streamInError = new IOException("attach.DimeStreamError8");
+ throw streamInError;
+ }
+ if (idLength != 0 && !isChunk) id = new String(idBytes);
+
+ int pad = (int) ((4L - (idLength & 0x3L)) & 0x03L);
+
+ if (pad != readFromStream( header, 0, pad ))
+ {
+ streamInError = new IOException("attach.DimeStreamError9");
+ throw streamInError;
+ }
+ }
+
+ //TYPE + PADDING
+ if (0 < typeLength)
+ {
+ byte[] typeBytes = new byte[typeLength];
+
+ if (typeLength != readFromStream( typeBytes ))
+ {
+ streamInError = new IOException("attach.DimeStreamError10");
+ throw streamInError;
+ }
+ if (typeLength != 0 && !isChunk) type = new String(typeBytes);
+
+ int pad = (int) ((4L - (typeLength & 0x3L)) & 0x03L);
+
+ if (pad != readFromStream( header, 0, pad ))
+ {
+ streamInError = new IOException("attach.DimeStreamError11");
+ throw streamInError;
+ }
+ }
+ logger.debug("MB:" + MB + ", ME:" + ME + ", CF:" + moreChunks +
+ "Option length:" + optionsLength +
+ ", ID length:" + idLength +
+ ", typeLength:" + typeLength + ", TYPE_T:" + tnf);
+ logger.debug("id:\"" + id + "\"");
+ logger.debug("type:\"" + type + "\"");
+ logger.debug("recordlength:\"" + recordLength + "\"");
+
+ dataPadLength = (int) ((4L - (recordLength & 0x3L)) & 0x03L);
+ }
+
+
+ /**
+ * Read from the delimited stream.
+ *
+ * @param b is the array to read into. Read as much as possible
+ * into the size of this array.
+ * @return the number of bytes read. -1 if endof stream
+ * @throws IOException if data could not be read from the stream
+ */
+ public int read( byte[] b ) throws IOException
+ {
+ return read( b, 0, b.length );
+ }
+
+
+ // fixme: this seems a bit inefficient
+ /**
+ * Read from the boundary delimited stream.
+ *
+ * @return the byte read, or -1 if endof stream
+ * @throws IOException if there was an error reading the data
+ */
+ public int read() throws IOException
+ {
+ byte[] b = new byte[1];
+ int read = read( b, 0, 1 );
+
+ if (read < 0) return -1; // fixme: should we also check for read != 1?
+ return (b[0] & 0xff); // convert byte value to a positive int
+ }
+
+
+ /**
+ * Closes the stream.
+ * This will take care of flushing any remaining data to the stream.
+ * Multiple calls to this method will result in the stream being closed once
+ * and then all subsequent calls being ignored.
+ *
+ * @throws IOException if the stream could not be closed
+ */
+ public void close() throws IOException
+ {
+ synchronized( this )
+ {
+ if (closed) return;
+ closed = true; //mark it closed.
+ }
+ logger.debug("bStreamClosed " + streamNo);
+
+ if (bytesRead < recordLength || moreChunks)
+ {
+ //We need get this off the stream. Easy way to flush through the stream;
+ byte[] readrest = new byte[1024 * 16];
+ int bread = 0;
+
+ do
+ { bread = _read( readrest, 0, readrest.length ); //should also close the original stream.
+ }
+ while( bread > -1 );
+ }
+ dataPadLength -= readPad( dataPadLength );
+ }
+
+
+ /**
+ * Skip n bytes of data in the DIME stream, while reading and processing
+ * any headers in the current stream.
+ *
+ * @param n - number of data bytes to skip
+ * @return number of bytes actually skipped
+ * @throws IOException
+ */
+ public long skip( long n ) throws IOException
+ {
+ long bytesSkipped = 0;
+ long bytes2Read = 0;
+ byte[] dumpbytes = new byte[1024];
+
+ while( n > 0 )
+ {
+ bytes2Read = (n > 1024 ? 1024 : n);
+ bytes2Read = _read( dumpbytes, 0, (int)bytes2Read );
+
+ n -= bytes2Read;
+ bytesSkipped += bytes2Read;
+ }
+
+ return bytesSkipped;
+ }
+
+
+ /**
+ * Mark the stream. This is not supported.
+ */
+ public void mark( int readlimit )
+ { //do nothing
+ }
+
+ public void reset() throws IOException
+ {
+ streamInError = new IOException("attach.bounday.mns");
+ throw streamInError;
+ }
+
+ public boolean markSupported()
+ {
+ return false;
+ }
+
+
+ public synchronized int available() throws IOException
+ {
+ if (null != streamInError) throw streamInError;
+
+ int chunkAvail = (int) Math.min((long)Integer.MAX_VALUE, recordLength - bytesRead);
+ int streamAvail = 0;
+
+ try
+ { streamAvail = is.available();
+ }
+ catch( IOException e )
+ {
+ streamInError = e;
+ throw e;
+ }
+
+ if (chunkAvail == 0 && moreChunks && (12 + dataPadLength) <= streamAvail)
+ {
+ dataPadLength -= readPad(dataPadLength);
+ readHeader( true );
+ return available();
+ }
+ return Math.min( streamAvail, chunkAvail );
+ }
+
+
+ protected void finalClose() throws IOException
+ {
+ try
+ { theEnd = true;
+ if(null != is) is.close();
+ }
+ finally
+ {
+ is= null;
+ }
+ }
+}
+
diff --git a/awsapi/src/com/cloud/bridge/io/FileRangeDataSource.java b/awsapi/src/com/cloud/bridge/io/FileRangeDataSource.java
new file mode 100644
index 00000000000..d87d5d39926
--- /dev/null
+++ b/awsapi/src/com/cloud/bridge/io/FileRangeDataSource.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2011 Citrix Systems, Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.cloud.bridge.io;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import javax.activation.DataSource;
+
+import org.apache.log4j.Logger;
+
+/**
+ * @author Kelven Yang
+ */
+public class FileRangeDataSource implements DataSource {
+ protected final static Logger logger = Logger.getLogger(FileRangeDataSource.class);
+
+ private FileRangeInputStream is;
+
+ public FileRangeDataSource(File file, long startPos, long endPos) throws IOException {
+ is = new FileRangeInputStream(file, startPos, endPos);
+ }
+
+ @Override
+ public String getContentType() {
+ assert(false);
+ return null;
+ }
+
+ @Override
+ public InputStream getInputStream() throws IOException {
+ return is;
+ }
+
+ @Override
+ public String getName() {
+ assert(false);
+ return null;
+ }
+
+ @Override
+ public OutputStream getOutputStream() throws IOException {
+ assert(false);
+ return null;
+ }
+}
diff --git a/awsapi/src/com/cloud/bridge/io/FileRangeInputStream.java b/awsapi/src/com/cloud/bridge/io/FileRangeInputStream.java
new file mode 100644
index 00000000000..4fb87e2ee42
--- /dev/null
+++ b/awsapi/src/com/cloud/bridge/io/FileRangeInputStream.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2011 Citrix Systems, Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.cloud.bridge.io;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.RandomAccessFile;
+
+/**
+ * @author Kelven Yang
+ */
+public class FileRangeInputStream extends InputStream {
+ private RandomAccessFile randomAccessFile;
+ private long curPos;
+ private long endPos;
+ private long fileLength;
+
+ public FileRangeInputStream(File file, long startPos, long endPos) throws IOException {
+ fileLength = file.length();
+
+ if(startPos > fileLength)
+ startPos = fileLength;
+
+ if(endPos > fileLength)
+ endPos = fileLength;
+
+ if(startPos > endPos)
+ throw new IllegalArgumentException("Invalid file range " + startPos + "-" + endPos);
+
+ this.curPos = startPos;
+ this.endPos = endPos;
+ randomAccessFile = new RandomAccessFile(file, "r");
+ randomAccessFile.seek(startPos);
+ }
+
+ @Override
+ public int available() throws IOException {
+ return (int)(endPos - curPos);
+ }
+
+ @Override
+ public int read() throws IOException {
+ if(available() > 0) {
+ int value = randomAccessFile.read();
+ curPos++;
+ return value;
+ }
+ return -1;
+ }
+
+ @Override
+ public int read(byte[] b) throws IOException {
+ return read(b, 0, b.length);
+ }
+
+ @Override
+ public int read(byte[] b, int off, int len) throws IOException {
+ int bytesToRead = Math.min(len, available());
+ if(bytesToRead == 0)
+ return -1;
+
+ int bytesRead = randomAccessFile.read(b, off, bytesToRead);
+ if(bytesRead < 0)
+ return -1;
+
+ curPos += bytesRead;
+ return bytesRead;
+ }
+
+ @Override
+ public long skip(long n) throws IOException {
+ long skipped = Math.min(n, available());
+ randomAccessFile.skipBytes((int)skipped);
+ curPos += skipped;
+ return skipped;
+ }
+
+ @Override
+ public void close() throws IOException {
+ randomAccessFile.close();
+ }
+}
diff --git a/awsapi/src/com/cloud/bridge/io/MTOMAwareResultStreamWriter.java b/awsapi/src/com/cloud/bridge/io/MTOMAwareResultStreamWriter.java
new file mode 100644
index 00000000000..6c6fc24bc34
--- /dev/null
+++ b/awsapi/src/com/cloud/bridge/io/MTOMAwareResultStreamWriter.java
@@ -0,0 +1,145 @@
+/**
+ *
+ */
+package com.cloud.bridge.io;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+import javax.xml.XMLConstants;
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamWriter;
+import javax.xml.stream.XMLOutputFactory;
+
+import org.apache.axiom.om.OMAbstractFactory;
+import org.apache.axiom.om.OMFactory;
+import org.apache.axis2.databinding.utils.writer.MTOMAwareXMLSerializer;
+import org.apache.axis2.databinding.ADBBean;
+import org.apache.axis2.databinding.ADBException;
+
+/**
+ * @author John Zucker
+ * Provide an MTOM aware serializable output stream writer to be consumed by implementors of the
+ * com.amazon.s3 Response ADB bean classes.
+ * This writer enables participation is StaX based builders and AXIOM om xml stream processing
+ * An instance of a MTOMAwareResultStreamWriter is a convenient argument to a com.amazon.s3 Response bean, as generated
+ * from the Amazon S3 WSDL using
+ * wsdl2java.sh -ss -sd -ssi -g -p com.amazon.s3 -ns2p "http://s3.amazonaws.com/doc/2006-03-01/"=com.amazon.s3 -uri cloud-AmazonS3.wsdl
+ * Such a bean implements a serialize method of the form
+ * public void serialize(qualifiedName,omfactory, xmlWriter)
+ * where
+ * @param qualifiedName is the XML qualified name of the parent
+ * @param omfactory is an implementor of the AXIOM object model interface
+ * @param xmlWriter is an implementor of XMLStxreamWriter for writing plain XML
+ * A convenience constructor of MTOMAwareResultStreamWriter is of the form
+ * MTOMAwareResultStreamWriter(nameOfResult, outputStream)
+ * where
+ * @param nameOfResult is the name used for the root (parent) tag by the serialization bean
+ * @param outputStream is the (servlet) output stream into which the bytes are written
+ * Addtionally, as a side effect, ensure that the org.apache.axis2.databinding classes which serialize the
+ * output of each fields have been initialized to be aware of any custom classes which override the default
+ * output xsd converter methods of Axis2's databinding. Such a custom class is notified to the ADB framework
+ * (via its org.apache.axis2.databinding.utils.ConverterUtil class) by setting a System property,
+ * SYSTEM_PROPERTY_ADB_CONVERTERUTIL to name the custom class.
+ */
+public class MTOMAwareResultStreamWriter {
+
+ // Standard XML prolog to add to the beginning of each XML document.
+ public static final String
+ XMLPROLOG = "";
+ private static final byte[] XMLPROLOGBYTES = XMLPROLOG.getBytes();
+
+ // The XML namespace used in documents transported to and from the service
+ public static final String
+ S3XMLNS = "http://s3.amazonaws.com/doc/2006-03-01/";
+ // Prefix to use to represent the default XML Namespace, defined by the Namespaces in XML 3 spec to be ""
+ public static final String
+ DEFAULT_NS_PREFIX = XMLConstants.DEFAULT_NS_PREFIX;
+
+ private XMLStreamWriter xmlWriter = null;
+
+ private MTOMAwareXMLSerializer mtomWriter = null;
+
+ // A default instance of AXIOM object model factory suitable for constructing plain XML
+ private OMFactory omfactory = OMAbstractFactory.getOMFactory();
+
+ // The qualified name for use in the XML schema as defined by http://www.w3.org/TR/xmlschema-2/#QName
+ private QName qualifiedName = null;
+
+ // Usually bound to a servlet output stream
+ private OutputStream outputStream = null;
+
+
+ // Set the system property to notify the ADB framework of its custom class for system-wide side effect
+ // at time of initialization of this class (executed once in any JVM running this application)
+ static
+ {
+ System.setProperty
+ (org.apache.axis2.databinding.utils.ConverterUtil.SYSTEM_PROPERTY_ADB_CONVERTERUTIL,
+ "com.cloud.bridge.util.DatabindingConverterUtil");
+ }
+
+ /*
+ * @params
+ * @param nameOfResult Used as the tag description of the result written out when the requester serializes
+ * @param outputStream The stream capable of sinking bytes written at the time the requester is ready to serialize,
+ * assumed to be a ServletOutputStream
+ * @param xmlOutputFactory If passing a non-default factory, used to get an implementor of XmlStreamWriter
+ * @throw XMLStreamException
+ */
+ public MTOMAwareResultStreamWriter (String nameOfResult, OutputStream outputStream, XMLOutputFactory xmlOutputFactory)
+ throws XMLStreamException
+ {
+ this.outputStream = outputStream;
+ // Create an implementor of xmlWriter for this instance
+ xmlWriter = xmlOutputFactory.createXMLStreamWriter(outputStream);
+ // Create an MTOM aware XML serializer for this instance
+ // An MTOMAwareXMLSerializer wraps a xmlStreamWriter and implements writeDataHandler
+ mtomWriter = new MTOMAwareXMLSerializer( xmlWriter );
+ // Create a new qualified name passing in namespace URI (default), localpart, prefix (default)
+ qualifiedName = new QName (S3XMLNS, nameOfResult, DEFAULT_NS_PREFIX);
+ }
+
+ /*
+ * @params
+ * @param nameOfResult Used as the tag description of the result written out when the requester serializes
+ * @param outputStream The stream capable of sinking bytes written at the time the requester is ready to serialize,
+ * assumed to be a ServletOutputStream
+ * Uses default implementor of XmlStreamWriter
+ * @throw XMLStreamException
+ */
+
+ public MTOMAwareResultStreamWriter (String nameOfResult, OutputStream outputStream)
+ throws XMLStreamException
+ {
+ this (nameOfResult, outputStream, XMLOutputFactory.newInstance());
+ }
+
+ // Housekeeping before consumption in a serialize call
+ public void startWrite ()
+ throws IOException
+ { outputStream.write(XMLPROLOGBYTES);
+
+ }
+
+ public void stopWrite ()
+ throws IOException, XMLStreamException
+ {
+ xmlWriter.flush();
+ xmlWriter.close();
+ outputStream.close();
+ }
+
+ // Cooperate with an instance of org.apache.axis2.databinding.ADBBean to provide serialization output of XML
+ // An org.apache.axis2.databinding.ADBBean implements a serialize method which takes a QName and a XMLStreamWriter
+ public void writeout
+ (ADBBean dataBindingBean) throws ADBException, XMLStreamException
+ {
+
+ dataBindingBean.serialize(qualifiedName, omfactory, mtomWriter);
+ }
+
+ }
+
+
diff --git a/awsapi/src/com/cloud/bridge/io/MultiPartDimeInputStream.java b/awsapi/src/com/cloud/bridge/io/MultiPartDimeInputStream.java
new file mode 100644
index 00000000000..219f6989db1
--- /dev/null
+++ b/awsapi/src/com/cloud/bridge/io/MultiPartDimeInputStream.java
@@ -0,0 +1,171 @@
+/*
+ * Copyright (C) 2011 Citrix Systems, Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.cloud.bridge.io;
+
+import org.apache.log4j.Logger;
+
+
+import java.io.InputStream;
+import java.io.IOException;
+
+/**
+ * A DIME stream is actually composed of multiple encoded streams.
+ * This class is a wrapper around the DimeDelimitedInputStream inorder
+ * to provide a simple iterator like interface for all the streams in a
+ * DIME encoded message.
+ */
+public class MultiPartDimeInputStream
+{
+ protected final static Logger logger = Logger.getLogger(MultiPartDimeInputStream.class);
+
+ protected InputStream is = null;
+ protected DimeDelimitedInputStream currentStream = null;
+
+ protected int count = 0;
+ protected boolean eos = false;
+ protected String contentId = null;
+ protected String type = null;
+ protected String typeFormat = null;
+
+ /**
+ * The SOAP stream must be first, call nextInputStream to get
+ * access to the first stream and all streams after that.
+ *
+ * @param is the true input stream holding the incoming request.
+ */
+ public MultiPartDimeInputStream( InputStream is ) throws IOException
+ {
+ this.is = is;
+ }
+
+
+ /**
+ * These three methods are DIME specific but provide potentially
+ * useful information about the current stream's data.
+ *
+ * @return URL or MIME type
+ */
+ public String getStreamType()
+ {
+ return type;
+ }
+
+ public String getStreamTypeFormat()
+ {
+ // Is the type a URI or MIME type or just unknown?
+ return typeFormat;
+ }
+
+ public String getStreamId()
+ {
+ // The soap body might have string identifiers to point to other streams in the message
+ return contentId;
+ }
+
+ public InputStream getInputStream()
+ {
+ return currentStream;
+ }
+
+ public int available() throws IOException
+ {
+ if (eos) return -1;
+
+ if (null == currentStream)
+ {
+ throw new IOException( "streamClosed -- call nextInputStream()" );
+ }
+ return currentStream.available();
+ }
+
+
+ /**
+ * Move on to the next stream encoded in the DIME stream.
+ * If the current stream has not been all read, then we skip the remaining bytes of
+ * that stream.
+ *
+ * @return false if no next input stream, true if next input stream ready
+ * @throws IOException
+ */
+ public boolean nextInputStream() throws IOException
+ {
+ if ( null == currentStream )
+ {
+ // on the first call to this function get the first stream
+ if (0 == count) currentStream = new DimeDelimitedInputStream( is );
+ }
+ else
+ { // make sure the bytes of the previous stream are all skipped before we start the next
+ currentStream.close();
+ contentId = null;
+ type = null;
+ typeFormat = null;
+ currentStream = currentStream.getNextStream();
+ }
+
+ if ( null != currentStream )
+ {
+ contentId = currentStream.getContentId();
+ type = currentStream.getType();
+ typeFormat = currentStream.getDimeTypeNameFormat();
+ eos = false;
+ count++;
+ return true;
+ }
+ else return false;
+ }
+
+
+ public long skip( long n ) throws IOException
+ {
+ if (eos || null == currentStream)
+ {
+ throw new IOException( "streamClosed -- call nextInputStream()" );
+ }
+ return currentStream.skip( n );
+ }
+
+
+ public int read( byte[] b, int off, int len ) throws IOException
+ {
+ if (eos || null == currentStream) return -1;
+
+ int read = currentStream.read( b, off, len );
+
+ if (read < 0) eos = true;
+
+ return read;
+ }
+
+
+ public int read( byte[] b ) throws IOException
+ {
+ return read( b, 0, b.length );
+ }
+
+
+ public int read() throws IOException
+ {
+ if (eos || null == currentStream) return -1;
+
+ int ret = currentStream.read();
+
+ if (ret < 0) eos = true;
+
+ return ret;
+ }
+}
+
diff --git a/awsapi/src/com/cloud/bridge/io/S3FileSystemBucketAdapter.java b/awsapi/src/com/cloud/bridge/io/S3FileSystemBucketAdapter.java
new file mode 100644
index 00000000000..7cc45042efc
--- /dev/null
+++ b/awsapi/src/com/cloud/bridge/io/S3FileSystemBucketAdapter.java
@@ -0,0 +1,248 @@
+/*
+ * Copyright (C) 2011 Citrix Systems, Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.cloud.bridge.io;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.MalformedURLException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+
+import javax.activation.DataHandler;
+import javax.activation.DataSource;
+
+import org.apache.log4j.Logger;
+
+import com.cloud.bridge.service.core.s3.S3BucketAdapter;
+import com.cloud.bridge.service.core.s3.S3MultipartPart;
+import com.cloud.bridge.service.exception.FileNotExistException;
+import com.cloud.bridge.service.exception.InternalErrorException;
+import com.cloud.bridge.service.exception.OutOfStorageException;
+import com.cloud.bridge.util.StringHelper;
+import com.cloud.bridge.util.OrderedPair;
+
+/**
+ * @author Kelven Yang, John Zucker
+ */
+public class S3FileSystemBucketAdapter implements S3BucketAdapter {
+ protected final static Logger logger = Logger.getLogger(S3FileSystemBucketAdapter.class);
+
+ public S3FileSystemBucketAdapter() {
+ }
+
+ @Override
+ public void createContainer(String mountedRoot, String bucket) {
+
+ String dir = getBucketFolderDir(mountedRoot, bucket);
+ File container = new File(dir);
+
+ if (!container.exists()) {
+ if (!container.mkdirs())
+ throw new OutOfStorageException("Unable to create " + dir + " for bucket " + bucket);
+ }
+ }
+
+ @Override
+ public void deleteContainer(String mountedRoot, String bucket) {
+ String dir = getBucketFolderDir(mountedRoot, bucket);
+ File path = new File(dir);
+ if(!deleteDirectory(path))
+ throw new OutOfStorageException("Unable to delete " + dir + " for bucket " + bucket);
+ }
+
+ @Override
+ public String getBucketFolderDir(String mountedRoot, String bucket) {
+ String bucketFolder = getBucketFolderName(bucket);
+ String dir;
+ String separator = ""+File.separatorChar;
+ if(!mountedRoot.endsWith(separator))
+ dir = mountedRoot + separator + bucketFolder;
+ else
+ dir = mountedRoot + bucketFolder;
+
+ return dir;
+ }
+
+ @Override
+ public String saveObject(InputStream is, String mountedRoot, String bucket, String fileName)
+ {
+ FileOutputStream fos = null;
+ MessageDigest md5 = null;
+
+ try {
+ md5 = MessageDigest.getInstance("MD5");
+ } catch (NoSuchAlgorithmException e) {
+ logger.error("Unexpected exception " + e.getMessage(), e);
+ throw new InternalErrorException("Unable to get MD5 MessageDigest", e);
+ }
+
+ File file = new File(getBucketFolderDir(mountedRoot, bucket) + File.separatorChar + fileName);
+ try {
+ // -> when versioning is off we need to rewrite the file contents
+ file.delete();
+ file.createNewFile();
+
+ fos = new FileOutputStream(file);
+ byte[] buffer = new byte[4096];
+ int len = 0;
+ while( (len = is.read(buffer)) > 0) {
+ fos.write(buffer, 0, len);
+ md5.update(buffer, 0, len);
+
+ }
+ //Convert MD4 digest to (lowercase) hex String
+ return StringHelper.toHexString(md5.digest());
+
+ }
+ catch(IOException e) {
+ logger.error("Unexpected exception " + e.getMessage(), e);
+ throw new OutOfStorageException(e);
+ }
+ finally {
+ try {
+ if (null != fos) fos.close();
+ }
+ catch( Exception e ) {
+ logger.error("Can't close FileOutputStream " + e.getMessage(), e);
+ }
+ }
+ }
+
+ /**
+ * From a list of files (each being one part of the multipart upload), concatentate all files into a single
+ * object that can be accessed by normal S3 calls. This function could take a long time since a multipart is
+ * allowed to have upto 10,000 parts (each 5 gib long). Amazon defines that while this operation is in progress
+ * whitespace is sent back to the client inorder to keep the HTTP connection alive.
+ *
+ * @param mountedRoot - where both the source and dest buckets are located
+ * @param destBucket - resulting location of the concatenated objects
+ * @param fileName - resulting file name of the concatenated objects
+ * @param sourceBucket - special bucket used to save uploaded file parts
+ * @param parts - an array of file names in the sourceBucket
+ * @param client - if not null, then keep the servlet connection alive while this potentially long concatentation takes place
+ * @return OrderedPair with the first value the MD5 of the final object, and the second value the length of the final object
+ */
+ @Override
+ public OrderedPair concatentateObjects(String mountedRoot, String destBucket, String fileName, String sourceBucket, S3MultipartPart[] parts, OutputStream client)
+ {
+ MessageDigest md5;
+ long totalLength = 0;
+
+ try {
+ md5 = MessageDigest.getInstance("MD5");
+ } catch (NoSuchAlgorithmException e) {
+ logger.error("Unexpected exception " + e.getMessage(), e);
+ throw new InternalErrorException("Unable to get MD5 MessageDigest", e);
+ }
+
+ File file = new File(getBucketFolderDir(mountedRoot, destBucket) + File.separatorChar + fileName);
+ try {
+ // -> when versioning is off we need to rewrite the file contents
+ file.delete();
+ file.createNewFile();
+
+ final FileOutputStream fos = new FileOutputStream(file);
+ byte[] buffer = new byte[4096];
+
+ // -> get the input stream for the next file part
+ for( int i=0; i < parts.length; i++ )
+ {
+ DataHandler nextPart = loadObject( mountedRoot, sourceBucket, parts[i].getPath());
+ InputStream is = nextPart.getInputStream();
+
+ int len = 0;
+ while( (len = is.read(buffer)) > 0) {
+ fos.write(buffer, 0, len);
+ md5.update(buffer, 0, len);
+ totalLength += len;
+ }
+ is.close();
+
+ // -> after each file write tell the client we are still here to keep connection alive
+ if (null != client) {
+ client.write( new String(" ").getBytes());
+ client.flush();
+ }
+ }
+ fos.close();
+ return new OrderedPair(StringHelper.toHexString(md5.digest()), new Long(totalLength));
+ //Create an ordered pair whose first element is the MD4 digest as a (lowercase) hex String
+ }
+ catch(IOException e) {
+ logger.error("concatentateObjects unexpected exception " + e.getMessage(), e);
+ throw new OutOfStorageException(e);
+ }
+ }
+
+ @Override
+ public DataHandler loadObject(String mountedRoot, String bucket, String fileName) {
+ File file = new File(getBucketFolderDir(mountedRoot, bucket) + File.separatorChar + fileName);
+ try {
+ return new DataHandler(file.toURL());
+ } catch (MalformedURLException e) {
+ throw new FileNotExistException("Unable to open underlying object file");
+ }
+ }
+
+ @Override
+ public void deleteObject(String mountedRoot, String bucket, String fileName) {
+ String filePath = new String( getBucketFolderDir(mountedRoot, bucket) + File.separatorChar + fileName );
+ File file = new File( filePath );
+ if (!file.delete()) {
+ logger.error("file: " + filePath + ", f=" + file.isFile() + ", h=" + file.isHidden() + ", e=" + file.exists() + ", w=" + file.canWrite());
+ throw new OutOfStorageException( "Unable to delete " + filePath + " for object deletion" );
+ }
+ }
+
+ @Override
+ public DataHandler loadObjectRange(String mountedRoot, String bucket, String fileName, long startPos, long endPos) {
+ File file = new File(getBucketFolderDir(mountedRoot, bucket) + File.separatorChar + fileName);
+ try {
+ DataSource ds = new FileRangeDataSource(file, startPos, endPos);
+ return new DataHandler(ds);
+ } catch (MalformedURLException e) {
+ throw new FileNotExistException("Unable to open underlying object file");
+ } catch(IOException e) {
+ throw new FileNotExistException("Unable to open underlying object file");
+ }
+ }
+
+ public static boolean deleteDirectory(File path) {
+ if( path.exists() ) {
+ File[] files = path.listFiles();
+ for(int i = 0; i < files.length; i++) {
+ if(files[i].isDirectory()) {
+ deleteDirectory(files[i]);
+ } else {
+ files[i].delete();
+ }
+ }
+ }
+ return path.delete();
+ }
+
+ private String getBucketFolderName(String bucket) {
+ // temporary
+ String name = bucket.replace(' ', '_');
+ name = bucket.replace('\\', '-');
+ name = bucket.replace('/', '-');
+
+ return name;
+ }
+}
diff --git a/awsapi/src/com/cloud/bridge/lifecycle/ServiceEngineLifecycle.java b/awsapi/src/com/cloud/bridge/lifecycle/ServiceEngineLifecycle.java
index e34eb15cfa9..889a3e76c81 100644
--- a/awsapi/src/com/cloud/bridge/lifecycle/ServiceEngineLifecycle.java
+++ b/awsapi/src/com/cloud/bridge/lifecycle/ServiceEngineLifecycle.java
@@ -19,7 +19,11 @@ import org.apache.axis2.context.ConfigurationContext;
import org.apache.axis2.description.AxisService;
import org.apache.axis2.engine.ServiceLifeCycle;
+<<<<<<< HEAD
import com.cloud.bridge.service.ServiceProvider;
+=======
+import com.cloud.bridge.service.controller.s3.ServiceProvider;
+>>>>>>> 6472e7b... Now really adding the renamed files!
/**
* @author Kelven Yang
diff --git a/awsapi/src/com/cloud/bridge/model/SAcl.java b/awsapi/src/com/cloud/bridge/model/SAcl.java
index 119d1a124f3..e94fdcfce16 100644
--- a/awsapi/src/com/cloud/bridge/model/SAcl.java
+++ b/awsapi/src/com/cloud/bridge/model/SAcl.java
@@ -18,8 +18,29 @@ package com.cloud.bridge.model;
import java.io.Serializable;
import java.util.Date;
+<<<<<<< HEAD
/**
* @author Kelven Yang
+=======
+import com.cloud.bridge.service.exception.UnsupportedException;
+import com.cloud.bridge.util.OrderedPair;
+import com.cloud.bridge.util.Triple;
+
+/**
+ * @author John Zucker, Kelven Yang
+ * A model of stored ACLs to remember the ACL permissions per canonicalUserID per grantee
+ * Hold the AWS S3 grantee and permission constants.
+ *
+ * This class implements two forms of getCannedAccessControls mappings, as static methods,
+ *
+ * (a) an OrderedPair which provides a maplet across
+ * < permission, grantee >
+ * when given an aclRequestString and a target (i.e. bucket or object),
+ *
+ * (b) a Triplet
+ * < permission1, permission2, symbol >
+ * when given an aclRequestString, a target (i.e. bucket or object) and the ID of the owner.
+>>>>>>> 6472e7b... Now really adding the renamed files!
*/
public class SAcl implements Serializable {
private static final long serialVersionUID = 7900837117165018850L;
@@ -28,7 +49,11 @@ public class SAcl implements Serializable {
public static final int GRANTEE_ALLUSERS = 1;
public static final int GRANTEE_AUTHENTICATED = 2;
+<<<<<<< HEAD
public static final int PERMISSION_PASS = -1; // -> no ACL test required
+=======
+ public static final int PERMISSION_PASS = -1; // No ACL test required
+>>>>>>> 6472e7b... Now really adding the renamed files!
public static final int PERMISSION_NONE = 0;
public static final int PERMISSION_READ = 1;
public static final int PERMISSION_WRITE = 2;
@@ -124,4 +149,103 @@ public class SAcl implements Serializable {
public void setLastModifiedTime(Date lastModifiedTime) {
this.lastModifiedTime = lastModifiedTime;
}
+<<<<<<< HEAD
+=======
+
+ /** Return an OrderedPair
+ * < permission, grantee >
+ * comprising
+ * a permission - which is one of SAcl.PERMISSION_PASS, SAcl.PERMISSION_NONE, SAcl.PERMISSION_READ,
+ * SAcl.PERMISSION_WRITE, SAcl.PERMISSION_READ_ACL, SAcl.PERMISSION_WRITE_ACL, SAcl.PERMISSION_FULL
+ * a grantee - which is one of GRANTEE_ALLUSERS, GRANTEE_AUTHENTICATED, GRANTEE_USER
+ *
+ * Access controls that are specified via the "x-amz-acl:" headers in REST requests for buckets.
+ * The ACL request string is treated as a request for a known cannedAccessPolicy
+ * @param aclRequestString - The requested ACL from the set of AWS S3 canned ACLs
+ * @param target - Either "SBucket" or otherwise assumed to be for a single object item
+ */
+ public static OrderedPair getCannedAccessControls ( String aclRequestString, String target )
+ throws UnsupportedException
+ {
+ if ( aclRequestString.equalsIgnoreCase( "public-read" ))
+ // All users granted READ access.
+ return new OrderedPair (PERMISSION_READ,GRANTEE_ALLUSERS);
+ else if (aclRequestString.equalsIgnoreCase( "public-read-write" ))
+ // All users granted READ and WRITE access
+ return new OrderedPair ((PERMISSION_READ | PERMISSION_WRITE),GRANTEE_ALLUSERS);
+ else if (aclRequestString.equalsIgnoreCase( "authenticated-read" ))
+ // Authenticated users have READ access
+ return new OrderedPair (PERMISSION_READ,GRANTEE_AUTHENTICATED);
+ else if (aclRequestString.equalsIgnoreCase( "private" ))
+ // Only Owner gets FULL_CONTROL
+ return new OrderedPair (PERMISSION_FULL,GRANTEE_USER);
+ else if (aclRequestString.equalsIgnoreCase( "bucket-owner-read" ))
+ {
+ // Object Owner gets FULL_CONTROL, Bucket Owner gets READ
+ if ( target.equalsIgnoreCase( "SBucket" ))
+ return new OrderedPair (PERMISSION_READ, GRANTEE_USER);
+ else
+ return new OrderedPair (PERMISSION_FULL, GRANTEE_USER);
+ }
+ else if (aclRequestString.equalsIgnoreCase( "bucket-owner-full-control" ))
+ {
+ // Object Owner gets FULL_CONTROL, Bucket Owner gets FULL_CONTROL
+ // This is equivalent to private when used with PUT Bucket
+ return new OrderedPair (PERMISSION_FULL,GRANTEE_USER);
+ }
+ else throw new UnsupportedException( "Unknown Canned Access Policy: " + aclRequestString + " is not supported" );
+ }
+
+ /** Return a Triple
+ * < permission1, permission2, symbol >
+ * comprising
+ * two permissions - which is one of SAcl.PERMISSION_PASS, SAcl.PERMISSION_NONE, SAcl.PERMISSION_READ,
+ * SAcl.PERMISSION_WRITE, SAcl.PERMISSION_READ_ACL, SAcl.PERMISSION_WRITE_ACL, SAcl.PERMISSION_FULL
+ * permission1 applies to objects, permission2 applies to buckets.
+ * a symbol to indicate whether the principal is anonymous (i.e. string "A") or authenticated user (i.e.
+ * string "*") - otherwise null indicates a single ACL for all users.
+ *
+ * Access controls that are specified via the "x-amz-acl:" headers in REST requests for buckets.
+ * The ACL request string is treated as a request for a known cannedAccessPolicy
+ * @param aclRequestString - The requested ACL from the set of AWS S3 canned ACLs
+ * @param target - Either "SBucket" or otherwise assumed to be for a single object item
+ * @param ownerID - An ID for the owner, if used in place of symbols "A" or "*"
+ */
+ public static Triple getCannedAccessControls ( String aclRequestString, String target, String ownerID )
+ throws UnsupportedException
+ {
+ if ( aclRequestString.equalsIgnoreCase( "public-read" ))
+ // Owner gets FULL_CONTROL and the anonymous principal (the 'A' symbol here) is granted READ access.
+ return new Triple (PERMISSION_FULL, PERMISSION_READ,"A");
+ else if (aclRequestString.equalsIgnoreCase( "public-read-write" ))
+ // Owner gets FULL_CONTROL and the anonymous principal (the 'A' symbol here) is granted READ and WRITE access
+ return new Triple (PERMISSION_FULL, (PERMISSION_READ | PERMISSION_WRITE),"A");
+ else if (aclRequestString.equalsIgnoreCase( "authenticated-read" ))
+ // Owner gets FULL_CONTROL and ANY principal authenticated as a registered S3 user (the '*' symbol here) is granted READ access
+ return new Triple (PERMISSION_FULL, PERMISSION_READ,"*");
+ else if (aclRequestString.equalsIgnoreCase( "private" ))
+ // This is termed the "private" or default ACL, "Owner gets FULL_CONTROL"
+ return new Triple (PERMISSION_FULL, PERMISSION_FULL,null);
+ else if (aclRequestString.equalsIgnoreCase( "bucket-owner-read" ))
+ {
+ // Object Owner gets FULL_CONTROL, Bucket Owner gets READ
+ // This is equivalent to private when used with PUT Bucket
+ if ( target.equalsIgnoreCase( "SBucket" ))
+ return new Triple (PERMISSION_FULL,PERMISSION_FULL ,null);
+ else
+ return new Triple (PERMISSION_FULL,PERMISSION_READ,ownerID);
+ }
+ else if (aclRequestString.equalsIgnoreCase( "bucket-owner-full-control" ))
+ {
+ // Object Owner gets FULL_CONTROL, Bucket Owner gets FULL_CONTROL
+ // This is equivalent to private when used with PUT Bucket
+ if ( target.equalsIgnoreCase( "SBucket" ))
+ return new Triple (PERMISSION_FULL, PERMISSION_FULL, null);
+ else
+ return new Triple (PERMISSION_FULL,PERMISSION_FULL, ownerID);
+ }
+ else throw new UnsupportedException( "Unknown Canned Access Policy: " + aclRequestString + " is not supported" );
+ }
+
+>>>>>>> 6472e7b... Now really adding the renamed files!
}
diff --git a/awsapi/src/com/cloud/bridge/model/SBucket.java b/awsapi/src/com/cloud/bridge/model/SBucket.java
index 983fde0d1cb..12e5d73e21f 100644
--- a/awsapi/src/com/cloud/bridge/model/SBucket.java
+++ b/awsapi/src/com/cloud/bridge/model/SBucket.java
@@ -21,12 +21,28 @@ import java.util.HashSet;
import java.util.Set;
/**
+<<<<<<< HEAD
* @author Kelven Yang
+=======
+ * @author Kelven Yang, John Zucker
+ * Holds the relation
+ * Id,
+ * Name,
+ * OwnerCanonicalId,
+ * SHost,
+ * CreateTime,
+ * VersioningStatus
+ * For ORM see "com/cloud/bridge/model/SHost.hbm.xml"
+>>>>>>> 6472e7b... Now really adding the renamed files!
*/
public class SBucket implements Serializable {
private static final long serialVersionUID = 7430267766019671273L;
+<<<<<<< HEAD
public static final int VERSIONING_NULL = 0; // -> initial set, not set to anything yet
+=======
+ public static final int VERSIONING_NULL = 0;
+>>>>>>> 6472e7b... Now really adding the renamed files!
public static final int VERSIONING_ENABLED = 1;
public static final int VERSIONING_SUSPENDED = 2;
diff --git a/awsapi/src/com/cloud/bridge/model/SHost.java b/awsapi/src/com/cloud/bridge/model/SHost.java
index e76cf948844..d055c2d76bb 100644
--- a/awsapi/src/com/cloud/bridge/model/SHost.java
+++ b/awsapi/src/com/cloud/bridge/model/SHost.java
@@ -20,7 +20,11 @@ import java.util.HashSet;
import java.util.Set;
/**
+<<<<<<< HEAD
* @author Kelven Yang
+=======
+ * @author Kelven Yang, John Zucker
+>>>>>>> 6472e7b... Now really adding the renamed files!
*/
public class SHost implements Serializable {
private static final long serialVersionUID = 213346565810468018L;
diff --git a/awsapi/src/com/cloud/bridge/model/SObject.java b/awsapi/src/com/cloud/bridge/model/SObject.java
index 785ebba5397..7ded7582f46 100644
--- a/awsapi/src/com/cloud/bridge/model/SObject.java
+++ b/awsapi/src/com/cloud/bridge/model/SObject.java
@@ -22,7 +22,11 @@ import java.util.Iterator;
import java.util.Set;
/**
+<<<<<<< HEAD
* @author Kelven Yang
+=======
+ * @author Kelven Yang, John Zucker
+>>>>>>> 6472e7b... Now really adding the renamed files!
*/
public class SObject implements Serializable {
private static final long serialVersionUID = 8566744941395660486L;
@@ -33,7 +37,11 @@ public class SObject implements Serializable {
private String ownerCanonicalId;
private int nextSequence;
+<<<<<<< HEAD
private String deletionMark; // -> this must also a unique ID to give to the REST client
+=======
+ private String deletionMark; // This must also a unique ID to give to the REST client
+>>>>>>> 6472e7b... Now really adding the renamed files!
private Date createTime;
@@ -133,7 +141,11 @@ public class SObject implements Serializable {
{
SObjectItem item = it.next();
+<<<<<<< HEAD
// -> If versioning is off then return the item with the null version string (if exists)
+=======
+ // If versioning is off then return the item with the null version string (if exists)
+>>>>>>> 6472e7b... Now really adding the renamed files!
// For example, the bucket could have allowed versioning and then it was suspended
// If an application wants a specific version it will need to explicitly ask for it
try {
diff --git a/awsapi/src/com/cloud/bridge/model/SObjectItem.java b/awsapi/src/com/cloud/bridge/model/SObjectItem.java
index 64c1dd585c8..1f5a82011ca 100644
--- a/awsapi/src/com/cloud/bridge/model/SObjectItem.java
+++ b/awsapi/src/com/cloud/bridge/model/SObjectItem.java
@@ -19,7 +19,11 @@ import java.io.Serializable;
import java.util.Date;
/**
+<<<<<<< HEAD
* @author Kelven Yang
+=======
+ * @author Kelven Yang, John Zucker
+>>>>>>> 6472e7b... Now really adding the renamed files!
*/
public class SObjectItem implements Serializable {
private static final long serialVersionUID = -7351173256185687851L;
@@ -76,7 +80,11 @@ public class SObjectItem implements Serializable {
}
public void setStoredPath(String storedPath) {
+<<<<<<< HEAD
this.storedPath = storedPath;
+=======
+ this.storedPath = storedPath; // TODO - storedpath holds integer, called from S3Engine.allocObjectItem
+>>>>>>> 6472e7b... Now really adding the renamed files!
}
public long getStoredSize() {
diff --git a/awsapi/src/com/cloud/bridge/model/UserCredentials.java b/awsapi/src/com/cloud/bridge/model/UserCredentials.java
index 932c7132c03..1f3ad121221 100644
--- a/awsapi/src/com/cloud/bridge/model/UserCredentials.java
+++ b/awsapi/src/com/cloud/bridge/model/UserCredentials.java
@@ -66,7 +66,11 @@ public class UserCredentials implements Serializable {
if (!(other instanceof UserCredentials)) return false;
+<<<<<<< HEAD
// -> the cert id can be null in both or either, since it is only used for the SOAP API
+=======
+ // The cert id can be null. The cert is unused in the REST API.
+>>>>>>> 6472e7b... Now really adding the renamed files!
if ( getAccessKey().equals(((UserCredentials)other).getAccessKey()) &&
getSecretKey().equals(((UserCredentials)other).getSecretKey()))
{
@@ -85,7 +89,11 @@ public class UserCredentials implements Serializable {
int hashCode = 0;
String thisCertId = getCertUniqueId();
+<<<<<<< HEAD
// -> the cert id can be null, since it is only used for the SOAP API
+=======
+ // The cert id can be null. The cert is unused in the REST API.
+>>>>>>> 6472e7b... Now really adding the renamed files!
hashCode = hashCode*17 + getAccessKey().hashCode();
hashCode = hashCode*17 + getSecretKey().hashCode();
if (null != thisCertId) hashCode = hashCode*17 + thisCertId.hashCode();
diff --git a/awsapi/src/com/cloud/bridge/persist/EntityDao.java b/awsapi/src/com/cloud/bridge/persist/EntityDao.java
index ba19cceb5fd..ac542b5fad7 100644
--- a/awsapi/src/com/cloud/bridge/persist/EntityDao.java
+++ b/awsapi/src/com/cloud/bridge/persist/EntityDao.java
@@ -24,6 +24,7 @@ import org.hibernate.Session;
import com.cloud.bridge.util.QueryHelper;
/**
+<<<<<<< HEAD
* @author Kelven Yang
*/
public class EntityDao {
@@ -40,33 +41,72 @@ public class EntityDao {
this.isCloudStackSession = isCloudStackSession;
// Note : beginTransaction can be called multiple times
PersistContext.beginTransaction(isCloudStackSession);
+=======
+ * @author Kelven Yang, John Zucker
+ * Provide methods for getting, saving, deleting or updating state per session or, in a given session, returnin a List in
+ * response to queryEntities for a particular instantation of the EntityDao generic class, as defined here.
+ * Any instantation of EntityDao passes in the class for which it is instantiating. For example a new instance of SBucketDao
+ * passes in com.cloud.bridge.model.SBucket as its clazz.
+ */
+
+public class EntityDao {
+ private Class> clazz;
+
+ public EntityDao(Class> clazz) {
+ this.clazz = clazz;
+
+ // Note : beginTransaction can be called multiple times
+ // "If a new underlying transaction is required, begin the transaction. Otherwise continue the new work in the
+ // context of the existing underlying transaction." from the Hibernate spec
+ PersistContext.beginTransaction();
+>>>>>>> 6472e7b... Now really adding the renamed files!
}
@SuppressWarnings("unchecked")
public T get(Serializable id) {
+<<<<<<< HEAD
Session session = PersistContext.getSession(isCloudStackSession);
+=======
+ Session session = PersistContext.getSession();
+>>>>>>> 6472e7b... Now really adding the renamed files!
return (T)session.get(clazz, id);
}
public T save(T entity) {
+<<<<<<< HEAD
Session session = PersistContext.getSession(isCloudStackSession);
+=======
+ Session session = PersistContext.getSession();
+>>>>>>> 6472e7b... Now really adding the renamed files!
session.saveOrUpdate(entity);
return entity;
}
public T update(T entity) {
+<<<<<<< HEAD
Session session = PersistContext.getSession(isCloudStackSession);
+=======
+ Session session = PersistContext.getSession();
+>>>>>>> 6472e7b... Now really adding the renamed files!
session.saveOrUpdate(entity);
return entity;
}
public void delete(T entity) {
+<<<<<<< HEAD
Session session = PersistContext.getSession(isCloudStackSession);
+=======
+ Session session = PersistContext.getSession();
+>>>>>>> 6472e7b... Now really adding the renamed files!
session.delete(entity);
}
public T queryEntity(String hql, Object[] params) {
+<<<<<<< HEAD
Session session = PersistContext.getSession(isCloudStackSession);
+=======
+ Session session = PersistContext.getSession();
+>>>>>>> 6472e7b... Now really adding the renamed files!
Query query = session.createQuery(hql);
query.setMaxResults(1);
QueryHelper.bindParameters(query, params);
@@ -74,7 +114,11 @@ public class EntityDao {
}
public List queryEntities(String hql, Object[] params) {
+<<<<<<< HEAD
Session session = PersistContext.getSession(isCloudStackSession);
+=======
+ Session session = PersistContext.getSession();
+>>>>>>> 6472e7b... Now really adding the renamed files!
Query query = session.createQuery(hql);
QueryHelper.bindParameters(query, params);
@@ -82,7 +126,11 @@ public class EntityDao {
}
public List queryEntities(String hql, int offset, int limit, Object[] params) {
+<<<<<<< HEAD
Session session = PersistContext.getSession(isCloudStackSession);
+=======
+ Session session = PersistContext.getSession();
+>>>>>>> 6472e7b... Now really adding the renamed files!
Query query = session.createQuery(hql);
QueryHelper.bindParameters(query, params);
query.setFirstResult(offset);
@@ -91,7 +139,11 @@ public class EntityDao {
}
public int executeUpdate(String hql, Object[] params) {
+<<<<<<< HEAD
Session session = PersistContext.getSession(isCloudStackSession);
+=======
+ Session session = PersistContext.getSession();
+>>>>>>> 6472e7b... Now really adding the renamed files!
Query query = session.createQuery(hql);
QueryHelper.bindParameters(query, params);
diff --git a/awsapi/src/com/cloud/bridge/persist/PersistContext.java b/awsapi/src/com/cloud/bridge/persist/PersistContext.java
index e721a1ddd2f..0674ed388b0 100644
--- a/awsapi/src/com/cloud/bridge/persist/PersistContext.java
+++ b/awsapi/src/com/cloud/bridge/persist/PersistContext.java
@@ -28,8 +28,12 @@ import org.hibernate.Session;
import org.hibernate.Transaction;
import com.cloud.bridge.util.CloudSessionFactory;
+<<<<<<< HEAD
import com.cloud.bridge.util.CloudStackSessionFactory;
import com.cloud.bridge.util.Tuple;
+=======
+import com.cloud.bridge.util.OrderedPair;
+>>>>>>> 6472e7b... Now really adding the renamed files!
/**
* @author Kelven Yang
@@ -49,11 +53,16 @@ public class PersistContext {
protected final static Logger logger = Logger.getLogger(PersistContext.class);
private static final CloudSessionFactory sessionFactory;
+<<<<<<< HEAD
+=======
+
+>>>>>>> 6472e7b... Now really adding the renamed files!
private static final ThreadLocal threadSession = new ThreadLocal();
private static final ThreadLocal threadTransaction = new ThreadLocal();
private static final ThreadLocal