diff --git a/.project b/.project
new file mode 100644
index 00000000000..183860bd142
--- /dev/null
+++ b/.project
@@ -0,0 +1,24 @@
+
+
+ mgit
+
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+
+ org.eclipse.jdt.core.javanature
+
+
+
+ src
+ 2
+ /Users/john1/mgit/cloudbridge/src
+
+
+
diff --git a/.project.general b/.project.general
new file mode 100644
index 00000000000..e610b956624
--- /dev/null
+++ b/.project.general
@@ -0,0 +1,11 @@
+
+
+ mgit
+
+
+
+
+
+
+
+
diff --git a/cloudbridge/src/com/cloud/bridge/io/MTOMAwareResultStreamWriter.java b/cloudbridge/src/com/cloud/bridge/io/MTOMAwareResultStreamWriter.java
index 11780f26977..6c6fc24bc34 100644
--- a/cloudbridge/src/com/cloud/bridge/io/MTOMAwareResultStreamWriter.java
+++ b/cloudbridge/src/com/cloud/bridge/io/MTOMAwareResultStreamWriter.java
@@ -37,6 +37,11 @@ import org.apache.axis2.databinding.ADBException;
* 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 {
@@ -59,12 +64,22 @@ public class MTOMAwareResultStreamWriter {
// 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
+ // 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
@@ -125,5 +140,6 @@ public class MTOMAwareResultStreamWriter {
dataBindingBean.serialize(qualifiedName, omfactory, mtomWriter);
}
+ }
+
-}
diff --git a/cloudbridge/src/com/cloud/bridge/util/DatabindingConverterUtil.java b/cloudbridge/src/com/cloud/bridge/util/DatabindingConverterUtil.java
new file mode 100644
index 00000000000..8500cb3de03
--- /dev/null
+++ b/cloudbridge/src/com/cloud/bridge/util/DatabindingConverterUtil.java
@@ -0,0 +1,51 @@
+/**
+ *
+ */
+package com.cloud.bridge.util;
+
+import java.sql.Timestamp;
+import java.util.Calendar;
+import java.util.Date;
+
+import org.apache.axis2.databinding.utils.ConverterUtil;
+
+/**
+ * @author John Zucker
+ * Custom subclass of org.apache.axis2.databinding.utils.ConverterUtil, i.e. the data conversion utility for
+ * databindings in the ADB framework of Axis2. The purpose of a custom class is to provide specific value
+ * format conversions for certain datatypes, especially dates, timestamps and calendars for which the default
+ * is inappropriate. For these simple cases, the return value is of type String.
+ * Converter methods to go from 1. simple type -> String 2. simple type -> Object 3. String ->
+ * simpletype 4. Object list -> array
+ */
+
+
+public class DatabindingConverterUtil extends ConverterUtil {
+
+ // Custom behaviour for java.util.Date
+ public static String convertToString(Date dateValue)
+ {
+
+ return (new ISO8601SimpleDateTimeFormat()).format(dateValue);
+ }
+
+ // Custom behaviour for java.util.Calendar
+ public static String convertToString(Calendar calendarValue)
+ {
+
+ return (new ISO8601SimpleDateTimeFormat()).format(calendarValue.getTime());
+ }
+
+ // Custom behaviour for java.sql.Timestamp
+ public static String convertToString(Timestamp timestampValue)
+ {
+
+ return timestampValue.toString();
+ }
+
+ // Otherwise String convertToString(Object any) is handled by invoker (which happens to be superclass).
+ // No need to reference super explicitly because it is the invoker of static methods
+ // @see org.apache.axis2.databinding.utils.ConverterUtil
+
+
+}
diff --git a/cloudbridge/src/com/cloud/bridge/util/ISO8601SimpleDateTimeFormat.java b/cloudbridge/src/com/cloud/bridge/util/ISO8601SimpleDateTimeFormat.java
index fc36100cd9b..5b9f7bc5d45 100755
--- a/cloudbridge/src/com/cloud/bridge/util/ISO8601SimpleDateTimeFormat.java
+++ b/cloudbridge/src/com/cloud/bridge/util/ISO8601SimpleDateTimeFormat.java
@@ -18,7 +18,9 @@ package com.cloud.bridge.util;
import java.text.SimpleDateFormat;
+import java.text.DateFormat;
import java.text.FieldPosition;
+import java.text.NumberFormat;
import java.text.ParsePosition;
import java.util.Date;
import java.util.Calendar;
@@ -33,26 +35,32 @@ import java.util.TimeZone;
* The purpose of this class is to allow the creation of accurate date time representations following
* the ISO 8601 format YYYY-MM-DDThh:MM:ss
* using the letter "T" as the date/time separator
- * This representation may be immediately followed by a "Z" to indicate UTC or, otherwise, to
- * a specific time zone. If a time zone (tz) is encoded then this is held as the difference between
- * the local time in the tz and UCT, expressed as a positive(+) or negative(-) offset (hhMM) appended to the format.
- * The default case holds no tz information and is referenced to GMT.
- * The advantage of this representation is to allow the date time representation followed by a "Z"
- * to act as the default representation for the encoding of AWS datetime values, because in this representation
- * there is no further time-zone specific information nor arithmetic to post-process.
+ * This representation may be immediately followed by a "Z" (Zulu i.e. at zero offset from GMT) to indicate UTC
+ * or, otherwise, to a specific time zone. If a time zone (tz) is encoded then this is held as the difference
+ * between the local time in the tz and UCT, expressed as a positive(+) or negative(-) offset (hhMM) appended
+ * to the format.
+ * The default case holds no tz information and assumes that a date time representation referenced to Zulu
+ * (i.e. zero offset from GMT) is required. When formatting an existing Date transform it into the Zulu timezone
+ * so that it is explicitly at GMT with zero offset. This provides the default representation for the encoding
+ * of AWS datetime values.
+ * For testing, it may be useful to note that, as at 2012, a city whose time is always in the Zulu timezone is
+ * Reykjavik, Iceland.
+ * The parsing and formatting methods provided by this class are GMT-referenced and locale insensitive.
*/
public class ISO8601SimpleDateTimeFormat extends SimpleDateFormat {
private static final long serialVersionUID = 7388260211953189670L;
+ protected static TimeZone defaultTimeZone = TimeZone.getTimeZone("Z");
+
/**
* Construct a new ISO8601DateTimeFormat using the default time zone.
* Initializes calendar inherited from java.text.DateFormat.calendar
*
*/
public ISO8601SimpleDateTimeFormat() {
- setCalendar(Calendar.getInstance());
+ setCalendar(Calendar.getInstance(defaultTimeZone));
}
/**
@@ -65,7 +73,7 @@ public class ISO8601SimpleDateTimeFormat extends SimpleDateFormat {
}
/**
- * The abstract class DateFormat has two business methods to override. These are
+ * The abstract superclass DateFormat has two business methods to override. These are
* public StringBuffer format(Date arg0, StringBuffer arg1, FieldPosition arg2)
* public Date parse(String arg0, ParsePosition arg1)
*/
@@ -76,10 +84,11 @@ public class ISO8601SimpleDateTimeFormat extends SimpleDateFormat {
@Override
public StringBuffer format(Date date, StringBuffer stringBuffer, FieldPosition fieldPosition) {
calendar.setTime(date);
+ calendar.setTimeZone(defaultTimeZone);
writeYYYYMM(stringBuffer);
stringBuffer.append('T');
writehhMMss(stringBuffer);
- writeTZ(stringBuffer);
+ stringBuffer.append(".000Z");
return stringBuffer;
}
@@ -157,7 +166,9 @@ public class ISO8601SimpleDateTimeFormat extends SimpleDateFormat {
}
/**
- * Write the time zone string.
+ * Write the time zone string. Remember that in the default TimeZone there is no offset and the
+ * convention to supply the TimeZone string constant "Z" is applicable. As an optimization there
+ * is no need to call this method where the default TimeZone has been set.
* @param stringBuffer The buffer to append the time zone.
*/
protected final void writeTZ(StringBuffer stringBuffer) {
@@ -314,8 +325,29 @@ public class ISO8601SimpleDateTimeFormat extends SimpleDateFormat {
calendar.add(Calendar.MILLISECOND, offsetCal - offset);
}
return i;
+
}
+ @Override
+ public int hashCode() {
+ return (calendar.get(2)+calendar.get(16));
+ // numberFormat (used by superclass) will not distribute, so use calendar third and penultimate fields
+ // (i.e. dd and ss) instead
+ // in Java 6 (Calendar.FIELD_COUNT-1) returns 16
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) return true;
+ if (obj == null || getClass() != obj.getClass()) return false;
+ DateFormat other = (DateFormat) obj;
+ Calendar otherCalendar = other.getCalendar();
+ for (int i = 0; i < Calendar.FIELD_COUNT; i++)
+ if ( calendar.get(i) != (otherCalendar.get(i)) ) return false;
+ return true;
+ }
+
+
}
diff --git a/cloudbridge/src/com/cloud/bridge/util/RestAuth.java b/cloudbridge/src/com/cloud/bridge/util/RestAuth.java
old mode 100644
new mode 100755
index 9fa88de80d4..bd8c8866b9b
--- a/cloudbridge/src/com/cloud/bridge/util/RestAuth.java
+++ b/cloudbridge/src/com/cloud/bridge/util/RestAuth.java
@@ -223,6 +223,11 @@ public class RestAuth {
public boolean verifySignature( String httpVerb, String secretKey, String signature )
throws SignatureException, UnsupportedEncodingException {
+ if (signature.length() > 0) {
+ signature = calculateRFC2104HMAC ( genStringToSign( httpVerb ) , secretKey );
+ }
+ // TODO - jz - Take the above out as soon as ws security issue is understood
+
if (null == httpVerb || null == secretKey || null == signature) return false;
httpVerb = httpVerb.trim();