diff --git a/.gitignore b/.gitignore index 11a721777fdd..1760b790d851 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,5 @@ .project target node_modules +.idea +*.iml diff --git a/microsoft-azure-api/src/config/checkstyle.xml b/microsoft-azure-api/src/config/checkstyle.xml index 287b61490dd3..58a40f4ac43a 100644 --- a/microsoft-azure-api/src/config/checkstyle.xml +++ b/microsoft-azure-api/src/config/checkstyle.xml @@ -195,7 +195,11 @@ - + + + + + diff --git a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/blob/client/BlobContainerProperties.java b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/blob/client/BlobContainerProperties.java index 2b781912d584..516183818f69 100644 --- a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/blob/client/BlobContainerProperties.java +++ b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/blob/client/BlobContainerProperties.java @@ -131,7 +131,7 @@ public void setLeaseStatus(final LeaseStatus leaseStatus) { /** * Sets the lease status on the container. Reserved for internal use. * - * @param LeaseState + * @param leaseState * The lease state to set, as a LeaseState object. */ public void setLeaseState(final LeaseState leaseState) { @@ -141,7 +141,7 @@ public void setLeaseState(final LeaseState leaseState) { /** * Sets the lease duration on the container. Reserved for internal use. * - * @param LeaseDuration + * @param leaseDuration * The lease duration to set, as a LeaseDuration object. */ public void setLeaseDuration(final LeaseDuration leaseDuration) { diff --git a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/blob/client/BlobProperties.java b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/blob/client/BlobProperties.java index 9fc4475b052d..0eaff8e5789a 100644 --- a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/blob/client/BlobProperties.java +++ b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/blob/client/BlobProperties.java @@ -334,7 +334,7 @@ public void setLeaseStatus(final LeaseStatus leaseStatus) { /** * Sets the lease state for the blob. Reserved for internal use. * - * @param LeaseState + * @param leaseState * The lease state to set, represented by a LeaseState object. */ public void setLeaseState(final LeaseState leaseState) { @@ -344,7 +344,7 @@ public void setLeaseState(final LeaseState leaseState) { /** * Sets the lease duration for the blob. Reserved for internal use. * - * @param LeaseDuration + * @param leaseDuration * The lease duration value to set, represented by a LeaseDuration object. */ public void setLeaseDuration(final LeaseDuration leaseDuration) { diff --git a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/blob/client/CloudBlob.java b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/blob/client/CloudBlob.java index 49ae8c7366fa..585c5cb8da14 100644 --- a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/blob/client/CloudBlob.java +++ b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/blob/client/CloudBlob.java @@ -1247,7 +1247,7 @@ public final void downloadRange(final long offset, final int length, final byte[ * the number of bytes to read * @param buffer * the byte buffer to write to. - * @param bufferOffet + * @param bufferOffset * the offset in the byte buffer to begin writing. * @param accessCondition * An {@link AccessCondition} object that represents the access conditions for the blob. @@ -1468,10 +1468,6 @@ else if (this.getResult().getStatusCode() == HttpURLConnection.HTTP_NOT_FOUND) { * signature. * @param groupPolicyIdentifier * A String that represents the container-level access policy. - * @param opContext - * An {@link OperationContext} object that represents the context for the current operation. This object - * is used to track requests to the storage service, and to provide additional runtime information about - * the operation. * * @return A String that represents the shared access signature. * diff --git a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/blob/core/storage/SharedAccessSignatureHelper.java b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/blob/core/storage/SharedAccessSignatureHelper.java index 9be65bdcb88f..f798b4838232 100644 --- a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/blob/core/storage/SharedAccessSignatureHelper.java +++ b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/blob/core/storage/SharedAccessSignatureHelper.java @@ -149,10 +149,6 @@ public static UriQueryBuilder generateSharedAccessSignature(final SharedAccessQu /** * Get the complete query builder for creating the Shared Access Signature query. * - * @param policy - * The shared access policy to hash. - * @param groupPolicyIdentifier - * An optional identifier for the policy. * @param signature * The signature to use. * @return The finished query builder @@ -285,7 +281,7 @@ public static String generateSharedAccessSignatureHash(final SharedAccessBlobPol * * @param policy * The shared access policy to hash. - * @param groupPolicyIdentifier + * @param accessPolicyIdentifier * An optional identifier for the policy. * @param resourceName * the resource name. @@ -356,7 +352,7 @@ public static String generateSharedAccessSignatureHash(final String permissions, * * @param policy * The shared access policy to hash. - * @param groupPolicyIdentifier + * @param accessPolicyIdentifier * An optional identifier for the policy. * @param resourceName * the resource name. diff --git a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/blob/models/CreateBlobOptions.java b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/blob/models/CreateBlobOptions.java index 644f5e7b4718..44e3e63090b4 100644 --- a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/blob/models/CreateBlobOptions.java +++ b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/blob/models/CreateBlobOptions.java @@ -20,7 +20,7 @@ /** * Represents the options that may be set on a - * {@link BlobContract#createPageBlob(String, String, int, CreateBlobOptions) createPageBlob} or + * {@link BlobContract#createPageBlob(String, String, long, CreateBlobOptions) createPageBlob} or * {@link BlobContract#createBlockBlob(String, String, java.io.InputStream, CreateBlobOptions) createBlockBlob} request. * These options include an optional server timeout for the operation, the MIME content type and content encoding for * the blob, the content language, the MD5 hash, a cache control value, blob metadata, a blob lease ID, a sequence diff --git a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/blob/models/CreateBlobResult.java b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/blob/models/CreateBlobResult.java index 6181e7c7278f..57a4c0faebce 100644 --- a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/blob/models/CreateBlobResult.java +++ b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/blob/models/CreateBlobResult.java @@ -21,7 +21,7 @@ /** * A wrapper class for the response returned from a Blob Service REST API Create Blob operation. This is returned by * calls to implementations of {@link BlobContract#createPageBlob(String, String, long, CreateBlobOptions)} and - * {@link BlobContract#createBlockBlob(String, String, long, CreateBlobOptions)}. + * {@link BlobContract#createBlockBlob(String, String, java.io.InputStream, CreateBlobOptions)}. *

* See the Put Blob documentation on * MSDN for details of the underlying Blob Service REST API operation. diff --git a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/core/utils/ConnectionStringSyntaxException.java b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/core/utils/ConnectionStringSyntaxException.java new file mode 100644 index 000000000000..5f6a24c8f0ce --- /dev/null +++ b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/core/utils/ConnectionStringSyntaxException.java @@ -0,0 +1,27 @@ +/** + * Copyright Microsoft Corporation + * + * 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.microsoft.windowsazure.services.core.utils; + +public class ConnectionStringSyntaxException extends Exception { + + public ConnectionStringSyntaxException(String message) { + super(message); + } + + public ConnectionStringSyntaxException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/core/utils/ExportUtils.java b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/core/utils/ExportUtils.java new file mode 100644 index 000000000000..d07a57c02941 --- /dev/null +++ b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/core/utils/ExportUtils.java @@ -0,0 +1,56 @@ +/** + * Copyright Microsoft Corporation + * + * 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.microsoft.windowsazure.services.core.utils; + +import java.util.Map; + +/** + * Helper functions useful when creating Exports classses. + * + */ +public abstract class ExportUtils { + + private static String normalizeProfile(String profile) { + if (profile == null || profile.equals("")) { + return ""; + } + + if (profile.endsWith(".")) { + return profile; + } + + return profile + "."; + } + + /** + * Check if the given property exists under the given profile. If + * so, return the value, otherwise return null. + * + * @param profile profile to search + * @param properties the set of property values + * @param propertyName name of desired property + * @return the property value, or null if it is not set. + */ + public static Object getPropertyIfExists(String profile, Map properties, String propertyName) { + String fullPropertyName = normalizeProfile(profile) + propertyName; + + if (properties.containsKey(fullPropertyName)) { + return properties.get(fullPropertyName); + } + return null; + } + +} diff --git a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/core/utils/ParsedConnectionString.java b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/core/utils/ParsedConnectionString.java new file mode 100644 index 000000000000..8be49de1b538 --- /dev/null +++ b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/core/utils/ParsedConnectionString.java @@ -0,0 +1,329 @@ +/** + * Copyright Microsoft Corporation + * + * 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.microsoft.windowsazure.services.core.utils; + +import com.microsoft.windowsazure.services.core.utils.pipeline.ConnectionStringField; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +/** + * Base class representing an Azure connection string. This + * provides parsing logic to split the string up into + * the various fields. + */ +public abstract class ParsedConnectionString { + private String connectionString; + private int currentIndex; + private String currentKey; + private String currentValue; + + public ParsedConnectionString(String connectionString) throws ConnectionStringSyntaxException { + // Forcing a separator at the end makes implementation below + // easier - don't have to check for end of string everywhere + this.connectionString = connectionString + ';'; + this.currentIndex = 0; + + matchConnectionString(); + } + + private char currentChar() { + return connectionString.charAt(currentIndex); + } + + private void consumeChar() { + currentIndex++; + } + + private boolean charsLeft() { + return currentIndex < connectionString.length(); + } + + // + // PEG Grammar for a connection string: + // + // ConnectionString <- Attribute (Separator+ Attribute)* Separator* END + // Attribute <- Spacing (KeyValuePair / &Separator) + // KeyValuePair <- Key Equals Spacing Value + // Key <- QuotedKey / RawKey + // QuotedKey <- DoubleQuote (!DoubleQuote .)* DoubleQuote / SingleQuote (!SingleQuote .)* SingleQuote + // RawKey <- (!Equals .)+ + // Equals <- Spacing '=' + // Value <- QuotedValue / RawValue + // QuotedValue <- DoubleQuote (!DoubleQuote .)* DoubleQuote / SingleQuote (!SingleQuote .*) SingleQuote + // RawValue <- (!Separator .)* + // Separator <- Spacing ';' + // Spacing <- WS* + // WS <- ' ' / '\t' + // END <- !. + // + + private boolean matchConnectionString() throws ConnectionStringSyntaxException { + if (!matchAttribute()) { + throw new ConnectionStringSyntaxException(String.format( + "Could not parse connection string '%1$s'", connectionString)); + } + + boolean moreAttributes = true; + int bookmark; + + while (moreAttributes) { + bookmark = currentIndex; + boolean separators = false; + while (matchSeparator()) { + separators = true; + } + moreAttributes = separators && matchAttribute(); + if (!moreAttributes) { + currentIndex = bookmark; + } + } + + while (matchSeparator()) { + } + + if (!matchEND()) { + throw new ConnectionStringSyntaxException(String.format( + "Expected end of connection string '%1$s', did not get it", connectionString)); + } + + return true; + } + + private boolean matchAttribute() throws ConnectionStringSyntaxException { + matchSpacing(); + if (matchKeyValuePair()) { + return true; + } + int bookmark = currentIndex; + boolean matchedSeparator = matchSeparator(); + currentIndex = bookmark; + return matchedSeparator; + } + + private boolean matchKeyValuePair() throws ConnectionStringSyntaxException { + if (!charsLeft()) { + return false; + } + if (!matchKey()) { + throw new ConnectionStringSyntaxException(String.format( + "Expected key in connection string '%1$s' at position %2$d but did not find one", + connectionString, currentIndex)); + } + if (!matchEquals()) { + throw new ConnectionStringSyntaxException(String.format( + "Expected '=' character in connection string '%1$s' after key near position %2$d", + connectionString, currentIndex)); + } + if (!matchValue()) { + throw new ConnectionStringSyntaxException(String.format( + "Expected value in connection string '%1$s' for key '%3$s' at position %2$d but did not find one", + connectionString, currentIndex, currentKey)); + } + + saveValue(currentKey, currentValue); + return true; + } + + private boolean matchKey() throws ConnectionStringSyntaxException { + return matchQuotedKey() || matchRawKey(); + } + + private boolean matchQuotedKey() throws ConnectionStringSyntaxException { + if (!charsLeft()) { + return false; + } + String value = ""; + char quote = currentChar(); + int bookmark = currentIndex; + + if (quote == '"' || quote == '\'') { + consumeChar(); + while (charsLeft() && currentChar() != quote) { + value += currentChar(); + consumeChar(); + } + if (!charsLeft()) { + throw new ConnectionStringSyntaxException(String.format( + "Unterminated quoted value in string '%1$s', starting at character %2$d", connectionString, bookmark)); + } + consumeChar(); + currentKey = value; + return true; + } else { + return false; + } + } + + private boolean matchRawKey() throws ConnectionStringSyntaxException { + if (!charsLeft()) { + return false; + } + + String value = ""; + int bookmark = currentIndex; + + while (charsLeft() && !matchEquals()) { + value += currentChar(); + consumeChar(); + bookmark = currentIndex; + } + + if (!charsLeft()) { + throw new ConnectionStringSyntaxException(String.format( + "Expected '=' in connection string '%1$s', key started at index %2$d", connectionString, bookmark + )); + } + + currentIndex = bookmark; + currentKey = value; + return true; + } + + private boolean matchEquals() { + int bookmark = currentIndex; + matchSpacing(); + if (charsLeft() && currentChar() == '=') { + consumeChar(); + return true; + } + currentIndex = bookmark; + return false; + } + + private boolean matchValue() throws ConnectionStringSyntaxException { + return matchQuotedValue() || matchRawValue(); + } + + private boolean matchQuotedValue() throws ConnectionStringSyntaxException { + String value = ""; + char quote = currentChar(); + int bookmark = currentIndex; + + if (quote == '"' || quote == '\'') { + consumeChar(); + while (charsLeft() && currentChar() != quote) { + value += currentChar(); + consumeChar(); + } + if (!charsLeft()) { + throw new ConnectionStringSyntaxException(String.format( + "Unterminated quoted value in string '%1$s', starting at character %2$d", connectionString, bookmark)); + } + consumeChar(); + currentValue = value; + return true; + } else { + return false; + } + } + + private boolean matchRawValue() { + String value = ""; + int bookmark = currentIndex; + + while (charsLeft() && !matchSeparator()) { + value += currentChar(); + consumeChar(); + bookmark = currentIndex; + } + currentIndex = bookmark; + currentValue = value; + return true; + } + + private boolean matchSeparator() { + int bookmark = currentIndex; + matchSpacing(); + if (charsLeft() && currentChar() == ';') { + consumeChar(); + return true; + } + currentIndex = bookmark; + return false; + } + + private boolean matchSpacing() { + while (matchWS()) { + } + return true; + } + + private boolean matchWS() { + if (charsLeft() && (currentChar() == ' ' || currentChar() == '\t')) { + consumeChar(); + return true; + } + return false; + } + + private boolean matchEND() { + return !(currentIndex < connectionString.length()); + } + + /** + * Store the value for the given key. + * + * Default implementation looks for a property setter with the + * matching name or the @ConnectionStringField annotation on the + * setter method to set the field. You can override this method + * for other behavior. + * + * @param key Key to store value under. If keys repeat, older values are overwritten. + * @param value value to associate with the key. + * + * @throws ConnectionStringSyntaxException + */ + protected void saveValue(String key, String value) throws ConnectionStringSyntaxException { + Method setter; + try { + setter = findSetter(key); + setter.invoke(this, value); + } catch (NoSuchMethodException e) { + throw new ConnectionStringSyntaxException(String.format( + "The key '%1$s' is not valid for this connection string", key), e); + } catch (InvocationTargetException e) { + throw new ConnectionStringSyntaxException(String.format( + "Could not invoke setter for key '%1$s'", key), e); + } catch (IllegalAccessException e) { + throw new ConnectionStringSyntaxException(String.format( + "Setter for key '%1$s' is not accessible in class %2$s", key, getClass().getName()), e); + } + } + + private Method findSetter(String key) throws NoSuchMethodException { + Class thisClass = getClass(); + for (Method m : thisClass.getDeclaredMethods()) { + if (methodMatches(m, key)) { + return m; + } + } + throw new NoSuchMethodException(); + } + + private boolean methodMatches(Method method, String key) { + return matchesViaAnnotation(method, key) || matchesByName(method, key); + } + + private boolean matchesViaAnnotation(Method method, String key) { + ConnectionStringField annotation = method.getAnnotation(ConnectionStringField.class); + return annotation != null && annotation.name().toLowerCase().equals(key.toLowerCase()); + } + + private boolean matchesByName(Method method, String key) { + return method.getName().toLowerCase().equals("set" + key.toLowerCase()); + } +} diff --git a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/core/utils/pipeline/ConnectionStringField.java b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/core/utils/pipeline/ConnectionStringField.java new file mode 100644 index 000000000000..ef773b705465 --- /dev/null +++ b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/core/utils/pipeline/ConnectionStringField.java @@ -0,0 +1,33 @@ +/** + * Copyright Microsoft Corporation + * + * 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.microsoft.windowsazure.services.core.utils.pipeline; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + + +/** + * Annotation used to mark method setters to be used + * when the field name in the connection string isn't + * a valid Java method name. + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.METHOD) +public @interface ConnectionStringField { + public String name(); +} diff --git a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/core/utils/pipeline/Exports.java b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/core/utils/pipeline/Exports.java index 23b7ae821526..4acda86f735b 100644 --- a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/core/utils/pipeline/Exports.java +++ b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/core/utils/pipeline/Exports.java @@ -23,6 +23,8 @@ import com.sun.jersey.api.client.config.ClientConfig; import com.sun.jersey.api.client.config.DefaultClientConfig; +import static com.microsoft.windowsazure.services.core.utils.ExportUtils.getPropertyIfExists; + public class Exports implements Builder.Exports { @Override @@ -71,25 +73,4 @@ public HttpURLConnectionClient create(String profile, Builder builder, Map properties, String propertyName) { - String fullPropertyName = normalizeProfile(profile) + propertyName; - - if (properties.containsKey(fullPropertyName)) { - return properties.get(fullPropertyName); - } - return null; - } } diff --git a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/media/MediaConfiguration.java b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/media/MediaConfiguration.java index f25537df87f4..e85fd9803b60 100644 --- a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/media/MediaConfiguration.java +++ b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/media/MediaConfiguration.java @@ -22,6 +22,9 @@ */ public class MediaConfiguration { + private MediaConfiguration() { + } + /** * Defines the media service configuration URI constant. * diff --git a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/media/entityoperations/EntityContract.java b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/media/entityoperations/EntityContract.java index d42fcdc14d30..67c539bfe63e 100644 --- a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/media/entityoperations/EntityContract.java +++ b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/media/entityoperations/EntityContract.java @@ -38,7 +38,7 @@ public interface EntityContract { * the service exception * The created entity */ - public abstract T create(EntityCreateOperation creator) throws ServiceException; + T create(EntityCreateOperation creator) throws ServiceException; /** * Retrieve an existing entity by id. @@ -51,7 +51,7 @@ public interface EntityContract { * @throws ServiceException * the service exception */ - public abstract T get(EntityGetOperation getter) throws ServiceException; + T get(EntityGetOperation getter) throws ServiceException; /** * Retrieve a list of entities. @@ -64,7 +64,7 @@ public interface EntityContract { * @throws ServiceException * the service exception */ - public abstract ListResult list(EntityListOperation lister) throws ServiceException; + ListResult list(EntityListOperation lister) throws ServiceException; /** * Update an existing entity. @@ -74,7 +74,7 @@ public interface EntityContract { * @throws ServiceException * the service exception */ - public abstract void update(EntityUpdateOperation updater) throws ServiceException; + void update(EntityUpdateOperation updater) throws ServiceException; /** * Delete an entity. @@ -84,7 +84,7 @@ public interface EntityContract { * @throws ServiceException * the service exception */ - public abstract void delete(EntityDeleteOperation deleter) throws ServiceException; + void delete(EntityDeleteOperation deleter) throws ServiceException; /** * Perform an action on an entity. @@ -94,7 +94,7 @@ public interface EntityContract { * @throws ServiceException * the service exception */ - public abstract void action(EntityActionOperation action) throws ServiceException; + void action(EntityActionOperation action) throws ServiceException; /** * Action. @@ -107,6 +107,6 @@ public interface EntityContract { * @throws ServiceException * the service exception */ - public abstract T action(EntityTypeActionOperation entityActionOperation) throws ServiceException; + T action(EntityTypeActionOperation entityActionOperation) throws ServiceException; } diff --git a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/media/entityoperations/EntityOperation.java b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/media/entityoperations/EntityOperation.java index 6ac4b38c6f08..4317bd39f08d 100644 --- a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/media/entityoperations/EntityOperation.java +++ b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/media/entityoperations/EntityOperation.java @@ -25,16 +25,15 @@ public interface EntityOperation { * Supplies the current proxy information to the action. * * @param proxyData - * @return */ - public void setProxyData(EntityProxyData proxyData); + void setProxyData(EntityProxyData proxyData); /** * Get the URI the creation request should be sent to. * * @return The uri */ - public abstract String getUri(); + String getUri(); /** * Get the MIME type for the content that's being sent to the server. @@ -42,12 +41,12 @@ public interface EntityOperation { * @return The MIME type * @throws ServiceException */ - public abstract MediaType getContentType(); + MediaType getContentType(); /** * Get the MIME type that we're expecting the server to send back. */ - public abstract MediaType getAcceptType(); + MediaType getAcceptType(); /** * Process response process. @@ -58,5 +57,5 @@ public interface EntityOperation { * @throws ServiceException * the service exception */ - public abstract Object processResponse(Object rawResponse) throws ServiceException; + Object processResponse(Object rawResponse) throws ServiceException; } diff --git a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/media/entityoperations/EntityOperationSingleResult.java b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/media/entityoperations/EntityOperationSingleResult.java index f3eeb0141d63..67586641b5f8 100644 --- a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/media/entityoperations/EntityOperationSingleResult.java +++ b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/media/entityoperations/EntityOperationSingleResult.java @@ -22,5 +22,5 @@ public interface EntityOperationSingleResult extends EntityOperation { * * @return Class object for response. */ - public abstract Class getResponseClass(); + Class getResponseClass(); } diff --git a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/media/implementation/MediaBatchOperations.java b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/media/implementation/MediaBatchOperations.java index 85a9dce36971..f3798aed41e2 100644 --- a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/media/implementation/MediaBatchOperations.java +++ b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/media/implementation/MediaBatchOperations.java @@ -61,6 +61,10 @@ */ public class MediaBatchOperations { + private static final int BUFFER_SIZE = 1024; + + private static final int HTTP_ERROR = 400; + /** The operations. */ private final List entityBatchOperations; @@ -138,7 +142,7 @@ private List createRequestBody() throws JAXBException { */ private int addJobPart(List bodyPartContents, URI jobURI, int contentId) throws JAXBException { int jobContentId = contentId; - ValidateJobOperation(); + validateJobOperation(); for (EntityBatchOperation entityBatchOperation : entityBatchOperations) { DataSource bodyPartContent = null; @@ -157,7 +161,7 @@ private int addJobPart(List bodyPartContents, URI jobURI, int conten return jobContentId; } - private void ValidateJobOperation() { + private void validateJobOperation() { int jobCount = 0; for (EntityBatchOperation entityBatchOperation : entityBatchOperations) { if (entityBatchOperation instanceof Job.CreateBatchOperation) { @@ -324,7 +328,7 @@ public void parseBatchResult(ClientResponse response) throws IOException, Servic InternetHeaders headers = parseHeaders(ds); InputStream content = parseEntity(ds); - if (status.getStatus() >= 400) { + if (status.getStatus() >= HTTP_ERROR) { InBoundHeaders inBoundHeaders = new InBoundHeaders(); @SuppressWarnings("unchecked") @@ -520,11 +524,12 @@ private void appendHeaders(OutputStream outputStream, InternetHeaders internetHe */ private void appendEntity(OutputStream outputStream, ByteArrayInputStream byteArrayInputStream) { try { - byte[] buffer = new byte[1024]; + byte[] buffer = new byte[BUFFER_SIZE]; while (true) { int bytesRead = byteArrayInputStream.read(buffer); - if (bytesRead <= 0) + if (bytesRead <= 0) { break; + } outputStream.write(buffer, 0, bytesRead); } } diff --git a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/media/implementation/MediaContentProvider.java b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/media/implementation/MediaContentProvider.java index 9e04edf56d03..eae063529e67 100644 --- a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/media/implementation/MediaContentProvider.java +++ b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/media/implementation/MediaContentProvider.java @@ -21,7 +21,6 @@ import java.lang.annotation.Annotation; import java.lang.reflect.Type; -import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MultivaluedMap; import javax.xml.bind.JAXBException; @@ -56,8 +55,7 @@ public boolean isReadable(Class type, Type genericType, Annotation[] annotati @Override public T readFrom(Class type, Type genericType, Annotation[] annotations, MediaType mediaType, - MultivaluedMap httpHeaders, InputStream entityStream) throws IOException, - WebApplicationException { + MultivaluedMap httpHeaders, InputStream entityStream) throws IOException { throw new UnsupportedOperationException(); } @@ -68,8 +66,7 @@ public boolean isWriteable(Class type, Type genericType, Annotation[] annotat @Override public void writeTo(T t, Class type, Type genericType, Annotation[] annotations, MediaType mediaType, - MultivaluedMap httpHeaders, OutputStream entityStream) throws IOException, - WebApplicationException { + MultivaluedMap httpHeaders, OutputStream entityStream) throws IOException { try { marshaller.marshalEntry(t, entityStream); } diff --git a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/media/implementation/OAuthContract.java b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/media/implementation/OAuthContract.java index ef2982aa2c17..603e9b0caeb1 100644 --- a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/media/implementation/OAuthContract.java +++ b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/media/implementation/OAuthContract.java @@ -38,7 +38,7 @@ public interface OAuthContract { * @return OAuthTokenResponse * @throws ServiceException */ - public OAuthTokenResponse getAccessToken(URI oAuthUri, String clientId, String clientSecret, String scope) + OAuthTokenResponse getAccessToken(URI oAuthUri, String clientId, String clientSecret, String scope) throws ServiceException; } diff --git a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/media/implementation/OAuthFilter.java b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/media/implementation/OAuthFilter.java index 81d50e6a6bfc..dff2e042c771 100644 --- a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/media/implementation/OAuthFilter.java +++ b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/media/implementation/OAuthFilter.java @@ -41,7 +41,7 @@ public OAuthFilter(OAuthTokenManager oAuthTokenManager) { /* (non-Javadoc) * @see com.microsoft.windowsazure.services.core.IdempotentClientFilter#doHandle(com.sun.jersey.api.client.ClientRequest) */@Override - public ClientResponse doHandle(ClientRequest clientRequest) throws ClientHandlerException { + public ClientResponse doHandle(ClientRequest clientRequest) { String accessToken; try { accessToken = oAuthTokenManager.getAccessToken(); diff --git a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/media/implementation/OAuthRestProxy.java b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/media/implementation/OAuthRestProxy.java index ecf179072bc5..be98df7af380 100644 --- a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/media/implementation/OAuthRestProxy.java +++ b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/media/implementation/OAuthRestProxy.java @@ -41,7 +41,7 @@ public class OAuthRestProxy implements OAuthContract { Client channel; - private final String _grantType = "client_credentials"; + private final String grantType = "client_credentials"; static Log log = LogFactory.getLog(OAuthContract.class); @@ -76,7 +76,7 @@ public OAuthTokenResponse getAccessToken(URI oAuthUri, String clientId, String c ClientResponse clientResponse; String responseJson; - requestForm.add("grant_type", _grantType); + requestForm.add("grant_type", grantType); requestForm.add("client_id", clientId); requestForm.add("client_secret", clientSecret); requestForm.add("scope", scope); diff --git a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/media/implementation/OAuthTokenResponse.java b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/media/implementation/OAuthTokenResponse.java index bc8d3622e068..1a124d4dd662 100644 --- a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/media/implementation/OAuthTokenResponse.java +++ b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/media/implementation/OAuthTokenResponse.java @@ -23,10 +23,10 @@ */ public class OAuthTokenResponse { - private String _accessToken; - private String _scope; - private String _tokenType; - private long _expiresIn; + private String accessToken; + private String scope; + private String tokenType; + private long expiresIn; /** * Sets the token type. @@ -35,41 +35,41 @@ public class OAuthTokenResponse { */ @JsonProperty("token_type") public void setTokenType(String tokenType) { - _tokenType = tokenType; + this.tokenType = tokenType; } @JsonProperty("token_type") public String getTokenType() { - return _tokenType; + return tokenType; } @JsonProperty("expires_in") public long getExpiresIn() { - return _expiresIn; + return expiresIn; } @JsonProperty("expires_in") public void setExpiresIn(long expiresIn) { - _expiresIn = expiresIn; + this.expiresIn = expiresIn; } @JsonProperty("access_token") public String getAccessToken() { - return _accessToken; + return accessToken; } @JsonProperty("access_token") public void setAccessToken(String accessToken) { - _accessToken = accessToken; + this.accessToken = accessToken; } @JsonProperty("scope") public String getScope() { - return _scope; + return scope; } @JsonProperty("scope") public void setScope(String scope) { - _scope = scope; + this.scope = scope; } } diff --git a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/media/implementation/ODataDateAdapter.java b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/media/implementation/ODataDateAdapter.java index c09aa98d873d..a23d7a712dda 100644 --- a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/media/implementation/ODataDateAdapter.java +++ b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/media/implementation/ODataDateAdapter.java @@ -30,14 +30,14 @@ */ public class ODataDateAdapter extends XmlAdapter { - private final static Pattern hasTimezoneRegex; - private final static TimeZone utc; + private static final Pattern HAS_TIMEZONE_REGEX; + private static final TimeZone UTC; static { - hasTimezoneRegex = Pattern.compile("^.*(\\+|-)\\d\\d:\\d\\d$"); + HAS_TIMEZONE_REGEX = Pattern.compile("^.*(\\+|-)\\d\\d:\\d\\d$"); - utc = TimeZone.getDefault(); - utc.setRawOffset(0); + UTC = TimeZone.getDefault(); + UTC.setRawOffset(0); } @Override @@ -53,11 +53,11 @@ public Date unmarshal(String dateString) throws Exception { public String marshal(Date date) throws Exception { Calendar dateToMarshal = Calendar.getInstance(); dateToMarshal.setTime(date); - dateToMarshal.setTimeZone(utc); + dateToMarshal.setTimeZone(UTC); return DatatypeConverter.printDateTime(dateToMarshal); } private boolean hasTimezone(String dateString) { - return dateString.endsWith("Z") || hasTimezoneRegex.matcher(dateString).matches(); + return dateString.endsWith("Z") || HAS_TIMEZONE_REGEX.matcher(dateString).matches(); } } diff --git a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/media/implementation/ODataEntity.java b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/media/implementation/ODataEntity.java index c89f3453c89d..65765129905b 100644 --- a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/media/implementation/ODataEntity.java +++ b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/media/implementation/ODataEntity.java @@ -89,7 +89,7 @@ public boolean hasLink(String rel) { public > LinkInfo getLink(String rel) { for (Object child : entry.getEntryChildren()) { - LinkType link = LinkFromChild(child); + LinkType link = linkFromChild(child); if (link != null && link.getRel().equals(rel)) { return new LinkInfo(link); } @@ -109,14 +109,14 @@ public > LinkInfo getRelationLink(String relationNam } @SuppressWarnings("rawtypes") - private static LinkType LinkFromChild(Object child) { + private static LinkType linkFromChild(Object child) { if (child instanceof JAXBElement) { - return LinkFromElement((JAXBElement) child); + return linkFromElement((JAXBElement) child); } return null; } - private static LinkType LinkFromElement(@SuppressWarnings("rawtypes") JAXBElement element) { + private static LinkType linkFromElement(@SuppressWarnings("rawtypes") JAXBElement element) { if (element.getDeclaredType() == LinkType.class) { return (LinkType) element.getValue(); } diff --git a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/media/implementation/ODataEntityCollectionProvider.java b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/media/implementation/ODataEntityCollectionProvider.java index 5b04e13ce4e7..1a63e2f3c99e 100644 --- a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/media/implementation/ODataEntityCollectionProvider.java +++ b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/media/implementation/ODataEntityCollectionProvider.java @@ -21,7 +21,6 @@ import java.lang.annotation.Annotation; import java.lang.reflect.Type; -import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MultivaluedMap; import javax.xml.bind.JAXBException; @@ -50,7 +49,7 @@ public boolean isReadable(Class type, Type genericType, Annotation[] annotati @Override public ListResult> readFrom(Class>> type, Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap httpHeaders, - InputStream entityStream) throws IOException, WebApplicationException { + InputStream entityStream) throws IOException { String responseType = mediaType.getParameters().get("type"); try { @@ -89,7 +88,7 @@ public boolean isWriteable(Class type, Type genericType, Annotation[] annotat @Override public void writeTo(ListResult> t, Class type, Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap httpHeaders, OutputStream entityStream) - throws IOException, WebApplicationException { + throws IOException { throw new UnsupportedOperationException(); } diff --git a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/media/implementation/ODataEntityProvider.java b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/media/implementation/ODataEntityProvider.java index 0a2150608560..c879f1e5ee94 100644 --- a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/media/implementation/ODataEntityProvider.java +++ b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/media/implementation/ODataEntityProvider.java @@ -22,7 +22,6 @@ import java.lang.reflect.Type; import java.util.List; -import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MultivaluedMap; import javax.xml.bind.JAXBException; @@ -57,7 +56,7 @@ public boolean isReadable(Class type, Type genericType, Annotation[] annotati @Override public ODataEntity readFrom(Class> type, Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap httpHeaders, InputStream entityStream) - throws IOException, WebApplicationException { + throws IOException { ODataEntity result = null; String responseType = mediaType.getParameters().get("type"); @@ -97,7 +96,7 @@ public boolean isWriteable(Class type, Type genericType, Annotation[] annotat @Override public void writeTo(ODataEntity t, Class type, Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap httpHeaders, OutputStream entityStream) - throws IOException, WebApplicationException { + throws IOException { throw new UnsupportedOperationException(); } } diff --git a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/media/implementation/RedirectFilter.java b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/media/implementation/RedirectFilter.java index 433e5ec7e6e8..6efebe7453d9 100644 --- a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/media/implementation/RedirectFilter.java +++ b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/media/implementation/RedirectFilter.java @@ -34,7 +34,7 @@ public RedirectFilter(ResourceLocationManager locationManager) { * @see com.microsoft.windowsazure.services.core.IdempotentClientFilter#doHandle(com.sun.jersey.api.client.ClientRequest) */ @Override - public ClientResponse doHandle(ClientRequest request) throws ClientHandlerException { + public ClientResponse doHandle(ClientRequest request) { if (request == null) { throw new IllegalArgumentException("Request should not be null"); } diff --git a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/media/implementation/SASTokenFilter.java b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/media/implementation/SASTokenFilter.java index f5c3ef493a68..400b304a07d6 100644 --- a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/media/implementation/SASTokenFilter.java +++ b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/media/implementation/SASTokenFilter.java @@ -15,12 +15,9 @@ package com.microsoft.windowsazure.services.media.implementation; -import java.net.URISyntaxException; - import javax.ws.rs.core.UriBuilder; import com.microsoft.windowsazure.services.core.IdempotentClientFilter; -import com.sun.jersey.api.client.ClientHandlerException; import com.sun.jersey.api.client.ClientRequest; import com.sun.jersey.api.client.ClientResponse; @@ -37,7 +34,6 @@ public class SASTokenFilter extends IdempotentClientFilter { * * @param sasUrl * URL containing authentication information - * @throws URISyntaxException */ public SASTokenFilter(String sasToken) { this.sasToken = sasToken; @@ -47,7 +43,7 @@ public SASTokenFilter(String sasToken) { * @see com.microsoft.windowsazure.services.core.IdempotentClientFilter#doHandle(com.sun.jersey.api.client.ClientRequest) */ @Override - public ClientResponse doHandle(ClientRequest cr) throws ClientHandlerException { + public ClientResponse doHandle(ClientRequest cr) { UriBuilder newUri = UriBuilder.fromUri(cr.getURI()); String currentQuery = cr.getURI().getRawQuery(); if (currentQuery == null) { diff --git a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/media/implementation/StatusLine.java b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/media/implementation/StatusLine.java index d3fabaa0c460..70be929297ed 100644 --- a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/media/implementation/StatusLine.java +++ b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/media/implementation/StatusLine.java @@ -24,6 +24,7 @@ import com.sun.mail.util.LineInputStream; public class StatusLine { + private static final int DELIMITER = -1; private int status; private String reason; @@ -37,7 +38,7 @@ public static StatusLine create(DataSource dataSource) { expect(lineReader, "HTTP/1.1"); expect(lineReader, " "); String statusString = extractInput(lineReader, ' '); - String reason = extractInput(lineReader, -1); + String reason = extractInput(lineReader, DELIMITER); return new StatusLine().setStatus(Integer.parseInt(statusString)).setReason(reason); } @@ -72,8 +73,9 @@ private static String extractInput(Reader reader, int delimiter) { StringBuilder sb = new StringBuilder(); while (true) { int ch = reader.read(); - if (ch == -1 || ch == delimiter) + if (ch == DELIMITER || ch == delimiter) { break; + } sb.append((char) ch); } diff --git a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/media/implementation/VersionHeadersFilter.java b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/media/implementation/VersionHeadersFilter.java index d21e3852162c..84b1a670a763 100644 --- a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/media/implementation/VersionHeadersFilter.java +++ b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/media/implementation/VersionHeadersFilter.java @@ -18,7 +18,6 @@ import javax.ws.rs.core.MultivaluedMap; import com.microsoft.windowsazure.services.core.IdempotentClientFilter; -import com.sun.jersey.api.client.ClientHandlerException; import com.sun.jersey.api.client.ClientRequest; import com.sun.jersey.api.client.ClientResponse; @@ -33,7 +32,7 @@ public class VersionHeadersFilter extends IdempotentClientFilter { * @see com.microsoft.windowsazure.services.core.IdempotentClientFilter#doHandle(com.sun.jersey.api.client.ClientRequest) */ @Override - public ClientResponse doHandle(ClientRequest cr) throws ClientHandlerException { + public ClientResponse doHandle(ClientRequest cr) { MultivaluedMap headers = cr.getHeaders(); headers.add("DataServiceVersion", "3.0"); headers.add("MaxDataServiceVersion", "3.0"); diff --git a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/media/implementation/content/Constants.java b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/media/implementation/content/Constants.java index b713aedf0961..a6e75b29512a 100644 --- a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/media/implementation/content/Constants.java +++ b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/media/implementation/content/Constants.java @@ -23,7 +23,11 @@ * media services entities. */ -public class Constants { +public final class Constants { + + private Constants() { + } + /** * XML Namespace for Atom syndication format, as defined by IETF RFC 4287 */ diff --git a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/media/models/ContentKey.java b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/media/models/ContentKey.java index 4d93a5e77356..fea8d2ba62e2 100644 --- a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/media/models/ContentKey.java +++ b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/media/models/ContentKey.java @@ -172,7 +172,7 @@ public Creator setProtectionKeyType(ProtectionKeyType protectionKeyType) { /** * Create an operation that will retrieve the given content key. * - * @param ContentKeyId + * @param contentKeyId * id of content key to retrieve * @return the operation */ @@ -205,7 +205,7 @@ public static DefaultListOperation list(LinkInfo /** * Create an operation to delete the given content key. * - * @param ContentKeyId + * @param contentKeyId * id of content key to delete * @return the delete operation */ diff --git a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/media/models/ProtectionKey.java b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/media/models/ProtectionKey.java index 7b9a6bb15d1c..5ec69e13bf6a 100644 --- a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/media/models/ProtectionKey.java +++ b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/media/models/ProtectionKey.java @@ -37,6 +37,9 @@ */ public class ProtectionKey { + private ProtectionKey() { + } + /** * Gets the protection key id. * diff --git a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/queue/client/SharedAccessQueuePolicy.java b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/queue/client/SharedAccessQueuePolicy.java index cd6b9085b4de..77ffca21efd7 100644 --- a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/queue/client/SharedAccessQueuePolicy.java +++ b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/queue/client/SharedAccessQueuePolicy.java @@ -75,7 +75,7 @@ public static EnumSet permissionsFromString(final * A {@link SharedAccessQueuePermissions} object that represents the shared access permissions. * * @return A String that represents the shared access permissions in the "rwdl" format, which is - * described at {@link SharedAccessQueuePermissions#permissionsFromString}. + * described at {@link SharedAccessQueuePolicy#permissionsFromString(String)}. */ public static String permissionsToString(final EnumSet permissions) { if (permissions == null) { diff --git a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/serviceBus/ServiceBusConfiguration.java b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/serviceBus/ServiceBusConfiguration.java index 87202a8b2254..5ad1631e8ebb 100644 --- a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/serviceBus/ServiceBusConfiguration.java +++ b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/serviceBus/ServiceBusConfiguration.java @@ -22,6 +22,13 @@ */ public class ServiceBusConfiguration { + + /** + * Defines the configuration connection string constant. + * + */ + public final static String CONNECTION_STRING = "serviceBus.connection.string"; + /** * Defines the configuration URI constant. * @@ -129,6 +136,8 @@ else if (profile.length() != 0 && !profile.endsWith(".")) { profile = profile + "."; } + configuration.setProperty(profile + CONNECTION_STRING, null); + configuration.setProperty(profile + URI, "https://" + namespace + serviceBusRootUri); configuration.setProperty(profile + WRAP_URI, "https://" + namespace + wrapRootUri); @@ -138,4 +147,32 @@ else if (profile.length() != 0 && !profile.endsWith(".")) { return configuration; } + + /** + * Creates a service bus configuration using the specified connection string. + * @param profile + * A String object that represents the profile. + * @param configuration + * A previously instantiated Configuration object. + * @param connectionString + * A String object the contains the connection string for the + * service bus connection information. + * @return + * A Configuration object that can be used when creating an instance of the + * ServiceBusService class. + */ + public static Configuration configureWithConnectionString(String profile, Configuration configuration, + String connectionString) { + + if (profile == null) { + profile = ""; + } + else if (profile.length() != 0 && !profile.endsWith(".")) { + profile = profile + "."; + } + + configuration.setProperty(profile + CONNECTION_STRING, connectionString); + + return configuration; + } } diff --git a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/serviceBus/implementation/Exports.java b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/serviceBus/implementation/Exports.java index d0f454a25517..40a04ba676de 100644 --- a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/serviceBus/implementation/Exports.java +++ b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/serviceBus/implementation/Exports.java @@ -1,11 +1,11 @@ /** * Copyright Microsoft Corporation - * + * * 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. @@ -15,6 +15,13 @@ package com.microsoft.windowsazure.services.serviceBus.implementation; import com.microsoft.windowsazure.services.core.Builder; +import com.microsoft.windowsazure.services.core.utils.ConnectionStringSyntaxException; +import com.microsoft.windowsazure.services.serviceBus.ServiceBusConfiguration; + +import java.net.URISyntaxException; +import java.util.Map; + +import static com.microsoft.windowsazure.services.core.utils.ExportUtils.getPropertyIfExists; public class Exports implements Builder.Exports { @@ -22,6 +29,24 @@ public void register(Builder.Registry registry) { registry.add(WrapContract.class, WrapRestProxy.class); registry.add(WrapTokenManager.class); registry.add(WrapFilter.class); - } + registry.add(new Builder.Factory() { + + @Override + public ServiceBusConnectionSettings create(String profile, Builder builder, Map properties) { + try { + return new ServiceBusConnectionSettings( + (String) getPropertyIfExists(profile, properties, ServiceBusConfiguration.CONNECTION_STRING), + (String) getPropertyIfExists(profile, properties, ServiceBusConfiguration.URI), + (String) getPropertyIfExists(profile, properties, ServiceBusConfiguration.WRAP_URI), + (String) getPropertyIfExists(profile, properties, ServiceBusConfiguration.WRAP_NAME), + (String) getPropertyIfExists(profile, properties, ServiceBusConfiguration.WRAP_PASSWORD)); + } catch (ConnectionStringSyntaxException e) { + throw new RuntimeException(e.getMessage(), e); + } catch (URISyntaxException e) { + throw new RuntimeException(e.getMessage(), e); + } + } + }); + } } diff --git a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/serviceBus/implementation/ServiceBusConnectionSettings.java b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/serviceBus/implementation/ServiceBusConnectionSettings.java new file mode 100644 index 000000000000..dc0d3da353c8 --- /dev/null +++ b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/serviceBus/implementation/ServiceBusConnectionSettings.java @@ -0,0 +1,86 @@ +/** + * Copyright Microsoft Corporation + * + * 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.microsoft.windowsazure.services.serviceBus.implementation; + +import com.microsoft.windowsazure.services.core.utils.ConnectionStringSyntaxException; + +import java.net.URI; +import java.net.URISyntaxException; + +/** + * Class that encapsulates all the various settings needed + * to connect to Service Bus, provided via either a + * connection string or via separate configuration variables. + *

+ * The connection string is looked for first, falling back + * to separate config values if not found. + */ +class ServiceBusConnectionSettings { + private String uri; + private String wrapUri; + private String wrapName; + private String wrapPassword; + + public ServiceBusConnectionSettings(String connectionString, String uri, String wrapUri, String wrapName, String wrapPassword) throws ConnectionStringSyntaxException, URISyntaxException { + if (connectionString != null) { + parseConnectionString(connectionString); + } else { + this.uri = uri; + this.wrapUri = wrapUri; + this.wrapName = wrapName; + this.wrapPassword = wrapPassword; + } + } + + public String getUri() { + return uri; + } + + public String getWrapUri() { + return wrapUri; + } + + public String getWrapName() { + return wrapName; + } + + public String getWrapPassword() { + return wrapPassword; + } + + private boolean parseConnectionString(String connectionString) throws URISyntaxException, ConnectionStringSyntaxException { + ServiceBusConnectionString cs = new ServiceBusConnectionString(connectionString); + setUri(cs); + setWrapUri(cs); + wrapName = cs.getSharedSecretIssuer(); + wrapPassword = cs.getSharedSecretValue(); + return true; + } + + private void setUri(ServiceBusConnectionString connectionString) { + uri = connectionString.getEndpoint().replaceFirst("^sb://", "https://"); + } + + private void setWrapUri(ServiceBusConnectionString connectionString) throws URISyntaxException { + if (connectionString.getStsEndpoint() == null || connectionString.getStsEndpoint().isEmpty()) { + URI hostUri = new URI(uri); + String namespace = hostUri.getHost().split("\\.")[0]; + wrapUri = "https://" + namespace + "-sb.accesscontrol.windows.net/WRAPv0.9"; + } else { + wrapUri = connectionString.getStsEndpoint(); + } + } +} diff --git a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/serviceBus/implementation/ServiceBusConnectionString.java b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/serviceBus/implementation/ServiceBusConnectionString.java new file mode 100644 index 000000000000..ee63db4ccaf8 --- /dev/null +++ b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/serviceBus/implementation/ServiceBusConnectionString.java @@ -0,0 +1,107 @@ +/** + * Copyright Microsoft Corporation + * + * 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.microsoft.windowsazure.services.serviceBus.implementation; + +import com.microsoft.windowsazure.services.core.utils.ConnectionStringSyntaxException; +import com.microsoft.windowsazure.services.core.utils.ParsedConnectionString; + +/** + * Class that parses the fields present in a service bus connection string. + * + */ +public class ServiceBusConnectionString extends ParsedConnectionString { + + /** + * Construct the {@link ServiceBusConnectionString} instance with the + * data from the given connection string + * + * @param connectionString The connection string + * + * @throws ConnectionStringSyntaxException + */ + public ServiceBusConnectionString(String connectionString) throws ConnectionStringSyntaxException { + super(connectionString); + } + + private String endpoint; + private String stsEndpoint; + private String sharedSecretIssuer; + private String sharedSecretValue; + + /** + * Get the endpoint from the connection string + * @return the endpoint + */ + public String getEndpoint() { + return endpoint; + } + + /** + * Sets the endpoint value + * @param endpoint + */ + public void setEndpoint(String endpoint) { + this.endpoint = endpoint; + } + + /** + * Get the StsEndpoint from the connection string + * @return the sts endpoint + */ + public String getStsEndpoint() { + return stsEndpoint; + } + + /** + * Sets the StsEndpoint value + * @param stsEndpoint + */ + public void setStsEndpoint(String stsEndpoint) { + this.stsEndpoint = stsEndpoint; + } + + /** + * Get the shared secret issuer + * @return the issuer + */ + public String getSharedSecretIssuer() { + return sharedSecretIssuer; + } + + /** + * Set the shared secret issuer + * @param sharedSecretIssuer + */ + public void setSharedSecretIssuer(String sharedSecretIssuer) { + this.sharedSecretIssuer = sharedSecretIssuer; + } + + /** + * Get the shared secret value + * @return the shared secret value + */ + public String getSharedSecretValue() { + return sharedSecretValue; + } + + /** + * Set the shared secret value + * @param sharedSecretValue + */ + public void setSharedSecretValue(String sharedSecretValue) { + this.sharedSecretValue = sharedSecretValue; + } +} diff --git a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/serviceBus/implementation/ServiceBusRestProxy.java b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/serviceBus/implementation/ServiceBusRestProxy.java index b2007513afb2..77220bb360e9 100644 --- a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/serviceBus/implementation/ServiceBusRestProxy.java +++ b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/serviceBus/implementation/ServiceBusRestProxy.java @@ -73,12 +73,12 @@ public class ServiceBusRestProxy implements ServiceBusContract { ServiceFilter[] filters; @Inject - public ServiceBusRestProxy(Client channel, @Named("serviceBus") WrapFilter authFilter, - @Named("serviceBus.uri") String uri, BrokerPropertiesMapper mapper) { + public ServiceBusRestProxy(Client channel, WrapFilter authFilter, + ServiceBusConnectionSettings connectionSettings, BrokerPropertiesMapper mapper) { this.channel = channel; this.filters = new ServiceFilter[0]; - this.uri = uri; + this.uri = connectionSettings.getUri(); this.mapper = mapper; this.customPropertiesMapper = new CustomPropertiesMapper(); channel.addFilter(authFilter); diff --git a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/serviceBus/implementation/WrapTokenManager.java b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/serviceBus/implementation/WrapTokenManager.java index 407b839ddbb8..df43072ce8cc 100644 --- a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/serviceBus/implementation/WrapTokenManager.java +++ b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/serviceBus/implementation/WrapTokenManager.java @@ -40,13 +40,13 @@ public class WrapTokenManager { private final Map activeTokens; @Inject - public WrapTokenManager(WrapContract contract, DateFactory dateFactory, @Named("wrap.uri") String uri, - @Named("wrap.name") String name, @Named("wrap.password") String password) { + public WrapTokenManager(WrapContract contract, DateFactory dateFactory, + ServiceBusConnectionSettings connectionSettings) { this.contract = contract; this.dateFactory = dateFactory; - this.uri = uri; - this.name = name; - this.password = password; + this.uri = connectionSettings.getWrapUri(); + this.name = connectionSettings.getWrapName(); + this.password = connectionSettings.getWrapPassword(); activeTokens = new ConcurrentHashMap(); } diff --git a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/table/client/SharedAccessTablePolicy.java b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/table/client/SharedAccessTablePolicy.java index fbeb55dae5be..4bca919332ca 100644 --- a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/table/client/SharedAccessTablePolicy.java +++ b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/table/client/SharedAccessTablePolicy.java @@ -75,7 +75,7 @@ public static EnumSet permissionsFromString(final * A set of {@link SharedAccessTablePermissions} objects that represent the shared access permissions. * * @return A String that represents the shared access permissions in the "rwdl" format, which is - * described at {@link SharedAccessTablePermissions#permissionsFromString}. + * described at {@link SharedAccessTablePolicy#permissionsFromString(String)}. */ public static String permissionsToString(final EnumSet permissions) { if (permissions == null) { diff --git a/microsoft-azure-api/src/test/java/com/microsoft/windowsazure/services/core/utils/ParsedConnectionStringTest.java b/microsoft-azure-api/src/test/java/com/microsoft/windowsazure/services/core/utils/ParsedConnectionStringTest.java new file mode 100644 index 000000000000..6da2023a2ef9 --- /dev/null +++ b/microsoft-azure-api/src/test/java/com/microsoft/windowsazure/services/core/utils/ParsedConnectionStringTest.java @@ -0,0 +1,127 @@ +/** + * Copyright Microsoft Corporation + * + * 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.microsoft.windowsazure.services.core.utils; + +import com.microsoft.windowsazure.services.core.utils.pipeline.ConnectionStringField; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; + +import static org.junit.Assert.*; + +public class ParsedConnectionStringTest { + + private static class OneField extends ParsedConnectionString { + private String aField; + + public OneField(String connectionString) throws ConnectionStringSyntaxException { + super(connectionString); + } + + public String getAField() { + return aField; + } + + protected void setAField(String aField) { + this.aField = aField; + } + } + + @Test + public void shouldSuccessfullyParseValidStringWithOneField() throws Exception { + OneField cs = new OneField("AField=avalue"); + + assertEquals("avalue", cs.getAField()); + } + + private static class ThreeFields extends ParsedConnectionString { + private String fieldOne; + private String fieldTwo; + private int fieldThree; + + + public ThreeFields(String connectionString) throws ConnectionStringSyntaxException { + super(connectionString); + } + + public String getFieldOne() { + return fieldOne; + } + + protected void setFieldOne(String fieldOne) { + this.fieldOne = fieldOne; + } + + public String getFieldTwo() { + return fieldTwo; + } + + protected void setFieldTwo(String fieldTwo) { + this.fieldTwo = fieldTwo; + } + + public int getFieldThree() { + return fieldThree; + } + + @ConnectionStringField(name = "fieldthree") + protected void setNumericField(String fieldThree) { + this.fieldThree = Integer.parseInt(fieldThree); + } + } + + @Test + public void shouldSuccessfullyParseValidStringWithMultipleFields() throws Exception { + ThreeFields cs = new ThreeFields("FieldOne=hello;FieldTwo=world;FieldThree=27"); + + assertEquals("hello", cs.getFieldOne()); + assertEquals("world", cs.getFieldTwo()); + assertEquals(27, cs.getFieldThree()); + } + + @Test + public void shouldSuccessFullyParseValisStringWithQuotedKeysAndValues() throws Exception { + ThreeFields cs = new ThreeFields("FieldOne=hello;'FieldTwo'=world;FieldThree='27'"); + + assertEquals("hello", cs.getFieldOne()); + assertEquals("world", cs.getFieldTwo()); + assertEquals(27, cs.getFieldThree()); + } + + @Rule + public ExpectedException exception = ExpectedException.none(); + + @Test + public void shouldThrowForFieldThatDoesntExist() throws Exception { + exception.expect(ConnectionStringSyntaxException.class); + new OneField("nosuchfield=nothing"); + } + + @Test + public void shouldNotThrowIfValueMissing() throws Exception { + ThreeFields cs = new ThreeFields(" FieldOne= hello; FieldTwo =;FieldThree=19 "); + assertEquals("", cs.getFieldTwo()); + } + + @Test + public void shouldIgnoreEmptyPairsAndExtraSemicolons() throws Exception { + ThreeFields cs = new ThreeFields("FieldOne=hello;; ; 'FieldTwo'=world;FieldThree='27';"); + + assertEquals("hello", cs.getFieldOne()); + assertEquals("world", cs.getFieldTwo()); + assertEquals(27, cs.getFieldThree()); + } +} diff --git a/microsoft-azure-api/src/test/java/com/microsoft/windowsazure/services/serviceBus/IntegrationTestBase.java b/microsoft-azure-api/src/test/java/com/microsoft/windowsazure/services/serviceBus/IntegrationTestBase.java index 1d57ed6fbb81..ddff90ded344 100644 --- a/microsoft-azure-api/src/test/java/com/microsoft/windowsazure/services/serviceBus/IntegrationTestBase.java +++ b/microsoft-azure-api/src/test/java/com/microsoft/windowsazure/services/serviceBus/IntegrationTestBase.java @@ -64,10 +64,7 @@ public void initialize() throws Exception { protected static Configuration createConfiguration() throws Exception { Configuration config = Configuration.load(); - overrideWithEnv(config, ServiceBusConfiguration.URI); - overrideWithEnv(config, ServiceBusConfiguration.WRAP_URI); - overrideWithEnv(config, ServiceBusConfiguration.WRAP_NAME); - overrideWithEnv(config, ServiceBusConfiguration.WRAP_PASSWORD); + overrideWithEnv(config, ServiceBusConfiguration.CONNECTION_STRING); return config; } diff --git a/microsoft-azure-api/src/test/java/com/microsoft/windowsazure/services/serviceBus/ServiceBusCreationTest.java b/microsoft-azure-api/src/test/java/com/microsoft/windowsazure/services/serviceBus/ServiceBusCreationTest.java index 9cc4d707c900..d86163d79946 100644 --- a/microsoft-azure-api/src/test/java/com/microsoft/windowsazure/services/serviceBus/ServiceBusCreationTest.java +++ b/microsoft-azure-api/src/test/java/com/microsoft/windowsazure/services/serviceBus/ServiceBusCreationTest.java @@ -39,6 +39,22 @@ public Configuration newConfiguration() { return config; } + private Configuration newConfigurationWithProfile() { + Configuration config = newConfiguration(); + ServiceBusConfiguration.configureWithWrapAuthentication("other", config, + "my-other-namespace", "my-other-identity", + "my-shared-secret", ".servicebus.windows.net", "-sb.accesscontrol.windows.net/WRAPv0.9"); + return config; + } + + private Configuration newConfigurationWithConnectionString() { + Configuration config = newConfiguration(); + ServiceBusConfiguration.configureWithConnectionString(null, config, + "Endpoint=https://my-other-namespace.servicebus.windows.net/;" + + "SharedSecretIssuer=owner;" + + "SharedSecretValue=my-shared-secret"); + return config; + } @Test public void theServiceClassMayBeCreatedDirectlyWithConfig() throws Exception { Configuration config = newConfiguration(); @@ -64,4 +80,21 @@ public void testDefaultBuilderCreatesServiceImpl() throws Exception { assertNotNull(service); } + + @Test + public void theServiceClassCanBeCreatedThroughAProfile() throws Exception { + Configuration config = newConfigurationWithProfile(); + ServiceBusContract service = config.create("other", ServiceBusContract.class); + + assertNotNull(service); + assertEquals(ServiceBusExceptionProcessor.class, service.getClass()); + } + + @Test + public void theServiceClassCanBeCreatedThroughConnectionString() throws Exception { + Configuration config = newConfigurationWithConnectionString(); + + ServiceBusContract service = config.create(ServiceBusContract.class); + assertNotNull(service); + } } diff --git a/microsoft-azure-api/src/test/java/com/microsoft/windowsazure/services/serviceBus/implementation/ServiceBusConnectionSettingsTest.java b/microsoft-azure-api/src/test/java/com/microsoft/windowsazure/services/serviceBus/implementation/ServiceBusConnectionSettingsTest.java new file mode 100644 index 000000000000..ec64e7d76eff --- /dev/null +++ b/microsoft-azure-api/src/test/java/com/microsoft/windowsazure/services/serviceBus/implementation/ServiceBusConnectionSettingsTest.java @@ -0,0 +1,112 @@ +/** + * Copyright Microsoft Corporation + * + * 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.microsoft.windowsazure.services.serviceBus.implementation; + +import com.microsoft.windowsazure.services.core.Configuration; +import com.microsoft.windowsazure.services.serviceBus.ServiceBusConfiguration; +import org.junit.Test; + +import static junit.framework.Assert.*; + +public class ServiceBusConnectionSettingsTest { + + @Test + public void settingsAreParsedFromConnectionString() throws Exception { + String ns = "myNamespace"; + String issuer = "myissuer"; + String secret = "mysecret"; + + String connectionString = getConnectionString(ns, issuer, secret); + + ServiceBusConnectionSettings settings = new ServiceBusConnectionSettings(connectionString, null, null, null, null); + + assertEquals(String.format("https://%1$s.servicebus.windows.net/", ns), settings.getUri()); + assertEquals(String.format("https://%1$s-sb.accesscontrol.windows.net/WRAPv0.9", ns), settings.getWrapUri()); + assertEquals(issuer, settings.getWrapName()); + assertEquals(secret, settings.getWrapPassword()); + } + + private String getConnectionString(String ns, String issuer, String secret) { + return String.format( + "Endpoint=sb://%1$s.servicebus.windows.net/;SharedSecretIssuer=%2$s;SharedSecretValue=%3$s", + ns, issuer, secret); + } + + private String getConnectionString(String ns, String stsEndpoint, String issuer, String secret) { + return String.format( + "Endpoint=sb://%1$s.servicebus.windows.net/;StsEndpoint=https://%1$s%4$s;SharedSecretIssuer=%2$s;SharedSecretValue=%3$s", + ns, issuer, secret, stsEndpoint); + } + @Test + public void settingsAreUsedFromConnectionStringInConfig() throws Exception { + Configuration config = Configuration.load(); + ServiceBusConfiguration.configureWithConnectionString(null, config, + getConnectionString("myNamespace", "owner", "secret")); + + ServiceBusConnectionSettings settings = config.create(ServiceBusConnectionSettings.class); + + assertEquals("https://myNamespace.servicebus.windows.net/", settings.getUri()); + assertEquals("https://myNamespace-sb.accesscontrol.windows.net/WRAPv0.9", settings.getWrapUri()); + assertEquals("owner", settings.getWrapName()); + assertEquals("secret", settings.getWrapPassword()); + } + + @Test + public void settingsAreUsedFromIndividualSettingsInConfiguration() throws Exception { + Configuration config = Configuration.load(); + + ServiceBusConfiguration.configureWithWrapAuthentication(config, + "myNamespace", "owner", "secret", ".servicebus.windows.net/", "-sb.accesscontrol.windows.net/WRAPv0.9"); + + ServiceBusConnectionSettings settings = config.create(ServiceBusConnectionSettings.class); + + assertEquals("https://myNamespace.servicebus.windows.net/", settings.getUri()); + assertEquals("https://myNamespace-sb.accesscontrol.windows.net/WRAPv0.9", settings.getWrapUri()); + assertEquals("owner", settings.getWrapName()); + assertEquals("secret", settings.getWrapPassword()); + } + + @Test + public void settingsPreferConnectionStringIfBothPresentInConfiguration() throws Exception { + Configuration config = Configuration.load(); + + ServiceBusConfiguration.configureWithWrapAuthentication(config, + "myIndividualNamespace", "individualowner", "individualsecret", + ".servicebus.windows.net/", "-sb.accesscontrol.windows.net/WRAPv0.9"); + + ServiceBusConfiguration.configureWithConnectionString(null, config, + getConnectionString("myNamespaceCS", "ownerCS", "secretCS")); + + ServiceBusConnectionSettings settings = config.create(ServiceBusConnectionSettings.class); + + assertEquals("https://myNamespaceCS.servicebus.windows.net/", settings.getUri()); + assertEquals("https://myNamespaceCS-sb.accesscontrol.windows.net/WRAPv0.9", settings.getWrapUri()); + assertEquals("ownerCS", settings.getWrapName()); + assertEquals("secretCS", settings.getWrapPassword()); + } + + @Test + public void canSetStSEndPointInConnectionString() throws Exception { + ServiceBusConnectionSettings settings = new ServiceBusConnectionSettings( + getConnectionString("myNs", "-some.accesscontrol.net", "owner", "secret"), + null, null, null, null); + + assertEquals("https://myNs.servicebus.windows.net/", settings.getUri()); + assertEquals("https://myNs-some.accesscontrol.net", settings.getWrapUri()); + assertEquals("owner", settings.getWrapName()); + assertEquals("secret", settings.getWrapPassword()); + } +} diff --git a/microsoft-azure-api/src/test/java/com/microsoft/windowsazure/services/serviceBus/implementation/WrapTokenManagerIntegrationTest.java b/microsoft-azure-api/src/test/java/com/microsoft/windowsazure/services/serviceBus/implementation/WrapTokenManagerIntegrationTest.java index 3eb2fd952a7a..a10e4e118e64 100644 --- a/microsoft-azure-api/src/test/java/com/microsoft/windowsazure/services/serviceBus/implementation/WrapTokenManagerIntegrationTest.java +++ b/microsoft-azure-api/src/test/java/com/microsoft/windowsazure/services/serviceBus/implementation/WrapTokenManagerIntegrationTest.java @@ -32,7 +32,7 @@ public void wrapClientWillAcquireAccessToken() throws Exception { overrideWithEnv(config, ServiceBusConfiguration.WRAP_URI); overrideWithEnv(config, ServiceBusConfiguration.WRAP_NAME); overrideWithEnv(config, ServiceBusConfiguration.WRAP_PASSWORD); - WrapTokenManager client = config.create("serviceBus", WrapTokenManager.class); + WrapTokenManager client = config.create(WrapTokenManager.class); // Act URI serviceBusURI = new URI((String) config.getProperty(ServiceBusConfiguration.URI)); diff --git a/microsoft-azure-api/src/test/java/com/microsoft/windowsazure/services/serviceBus/implementation/WrapTokenManagerTest.java b/microsoft-azure-api/src/test/java/com/microsoft/windowsazure/services/serviceBus/implementation/WrapTokenManagerTest.java index 11d2abfbd9bd..5fb85b33358e 100644 --- a/microsoft-azure-api/src/test/java/com/microsoft/windowsazure/services/serviceBus/implementation/WrapTokenManagerTest.java +++ b/microsoft-azure-api/src/test/java/com/microsoft/windowsazure/services/serviceBus/implementation/WrapTokenManagerTest.java @@ -38,12 +38,13 @@ public class WrapTokenManagerTest { private Calendar calendar; @Before - public void init() { + public void init() throws Exception { calendar = Calendar.getInstance(TimeZone.getTimeZone("GMT")); dateFactory = mock(DateFactory.class); contract = mock(WrapContract.class); - client = new WrapTokenManager(contract, dateFactory, "testurl", "testname", "testpassword"); + ServiceBusConnectionSettings settings = new ServiceBusConnectionSettings(null, null, "testurl", "testname", "testpassword"); + client = new WrapTokenManager(contract, dateFactory, settings); when(dateFactory.getDate()).thenAnswer(new Answer() { @Override diff --git a/microsoft-azure-api/src/test/java/com/microsoft/windowsazure/services/table/TableServiceIntegrationTest.java b/microsoft-azure-api/src/test/java/com/microsoft/windowsazure/services/table/TableServiceIntegrationTest.java index 485c239890a3..bef37b00a273 100644 --- a/microsoft-azure-api/src/test/java/com/microsoft/windowsazure/services/table/TableServiceIntegrationTest.java +++ b/microsoft-azure-api/src/test/java/com/microsoft/windowsazure/services/table/TableServiceIntegrationTest.java @@ -48,6 +48,8 @@ import com.microsoft.windowsazure.services.table.models.QueryTablesResult; import com.microsoft.windowsazure.services.table.models.ServiceProperties; import com.microsoft.windowsazure.services.table.models.TableEntry; +import com.sun.jersey.api.client.Client; +import com.sun.jersey.api.client.config.ClientConfig; public class TableServiceIntegrationTest extends IntegrationTestBase { private static final String testTablesPrefix = "sdktest"; @@ -74,13 +76,14 @@ public static void setup() throws Exception { // Setup container names array (list of container names used by // integration tests) testTables = new String[10]; + int uniqueId = (new java.util.Random()).nextInt(100000); for (int i = 0; i < testTables.length; i++) { - testTables[i] = String.format("%s%d", testTablesPrefix, i + 1); + testTables[i] = String.format("%s%d%d", testTablesPrefix, uniqueId, i + 1); } creatableTables = new String[10]; for (int i = 0; i < creatableTables.length; i++) { - creatableTables[i] = String.format("%s%d", createableTablesPrefix, i + 1); + creatableTables[i] = String.format("%s%d%d", createableTablesPrefix, uniqueId, i + 1); } TEST_TABLE_1 = testTables[0]; @@ -100,8 +103,6 @@ public static void setup() throws Exception { Configuration config = createConfiguration(); TableContract service = TableService.create(config); - deleteAllTables(service, testTables); - deleteAllTables(service, creatableTables); createTables(service, testTablesPrefix, testTables); } @@ -135,17 +136,6 @@ private static void deleteTables(TableContract service, String prefix, String[] } } - private static void deleteAllTables(TableContract service, String[] list) throws Exception { - for (String item : list) { - try { - service.deleteTable(item); - } - catch (ServiceException e) { - // Ignore - } - } - } - private static Set queryTables(TableContract service, String prefix) throws Exception { HashSet result = new HashSet(); QueryTablesResult list = service.queryTables(new QueryTablesOptions().setPrefix(prefix)); @@ -1201,16 +1191,23 @@ public void settingTimeoutPrefixedFromConfigWorks() throws Exception { TableContract service = TableService.create("testprefix", config); - try { - service.queryTables(); - fail("Exception should have been thrown"); - } - catch (ServiceTimeoutException ex) { - // No need to assert, test is if correct assertion type is thrown. - } - catch (Exception ex) { - fail("unexpected exception was thrown"); + // Use reflection to pull the state out of the service. + Client channel = (Client) readField(service, "service", "channel"); + Integer connTimeout = (Integer) channel.getProperties().get(ClientConfig.PROPERTY_CONNECT_TIMEOUT); + Integer readTimeout = (Integer) channel.getProperties().get(ClientConfig.PROPERTY_READ_TIMEOUT); + + assertEquals(3, connTimeout.intValue()); + assertEquals(7, readTimeout.intValue()); + } + + private Object readField(Object target, String... fieldNames) throws NoSuchFieldException, IllegalAccessException { + Object value = target; + for (String fieldName : fieldNames) { + java.lang.reflect.Field field = value.getClass().getDeclaredField(fieldName); + field.setAccessible(true); + value = field.get(value); } + return value; } @Test diff --git a/microsoft-azure-api/src/test/resources/META-INF/com.microsoft.windowsazure.properties b/microsoft-azure-api/src/test/resources/META-INF/com.microsoft.windowsazure.properties index 1abb40b2238c..27b1e2813951 100644 --- a/microsoft-azure-api/src/test/resources/META-INF/com.microsoft.windowsazure.properties +++ b/microsoft-azure-api/src/test/resources/META-INF/com.microsoft.windowsazure.properties @@ -2,6 +2,7 @@ serviceBus.uri=https://%SERVICEBUS_NAMESPACE%.servicebus.windows.net/ serviceBus.wrap.uri=https://%SERVICEBUS_NAMESPACE%-sb.accesscontrol.windows.net/WRAPv0.9 serviceBus.wrap.name=%SERVICEBUS_SERVICEIDENTITY% serviceBus.wrap.password=%SERVICEBUS_SHAREDSECRET% +serviceBus.connection.string=EndPoint=sb://%SERVICEBUS_NAMESPACE%.servicebus.windows.net/;SharedSecretIssuer=%SERVICEBUS_SERVICEIDENTITY%;SharedSecretValue=%SERVICEBUS_SHAREDSECRET% blob.accountName=%BLOB_ACCOUNTNAME% blob.accountKey=%BLOB_ACCOUNTKEY% blob.uri=http://%BLOB_ACCOUNTNAME%.blob.core.windows.net