From 6ced6b1a90787d00fcb9edbaee30b5c321a2bafe Mon Sep 17 00:00:00 2001 From: JohnZ Date: Tue, 17 Apr 2012 13:22:25 +0100 Subject: [PATCH] new file: .project new file: .project.general modified: cloudbridge/src/com/cloud/bridge/io/MTOMAwareResultStreamWriter.java new file: cloudbridge/src/com/cloud/bridge/util/DatabindingConverterUtil.java modified: cloudbridge/src/com/cloud/bridge/util/ISO8601SimpleDateTimeFormat.java --- .project | 24 +++++++++ .project.general | 11 ++++ .../io/MTOMAwareResultStreamWriter.java | 20 ++++++- .../bridge/util/DatabindingConverterUtil.java | 51 ++++++++++++++++++ .../util/ISO8601SimpleDateTimeFormat.java | 54 +++++++++++++++---- .../src/com/cloud/bridge/util/RestAuth.java | 5 ++ 6 files changed, 152 insertions(+), 13 deletions(-) create mode 100644 .project create mode 100644 .project.general create mode 100644 cloudbridge/src/com/cloud/bridge/util/DatabindingConverterUtil.java mode change 100644 => 100755 cloudbridge/src/com/cloud/bridge/util/RestAuth.java 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();