From 84c47af642961294216b11e7b74de8903a83e5c9 Mon Sep 17 00:00:00 2001 From: "Jason Cooke (MSFT)" Date: Wed, 23 Jan 2013 09:27:36 -0800 Subject: [PATCH 01/16] Fix JavaDoc build warnings --- .../services/blob/client/BlobContainerProperties.java | 4 ++-- .../windowsazure/services/blob/client/BlobProperties.java | 4 ++-- .../windowsazure/services/blob/client/CloudBlob.java | 6 +----- .../blob/core/storage/SharedAccessSignatureHelper.java | 8 ++------ .../services/blob/models/CreateBlobOptions.java | 2 +- .../services/blob/models/CreateBlobResult.java | 2 +- .../services/media/entityoperations/EntityOperation.java | 1 - .../windowsazure/services/media/models/ContentKey.java | 4 ++-- .../services/queue/client/SharedAccessQueuePolicy.java | 2 +- .../services/table/client/SharedAccessTablePolicy.java | 2 +- 10 files changed, 13 insertions(+), 22 deletions(-) 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/media/entityoperations/EntityOperation.java b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/media/entityoperations/EntityOperation.java index 6ac4b38c6f08..1670581609e7 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,7 +25,6 @@ public interface EntityOperation { * Supplies the current proxy information to the action. * * @param proxyData - * @return */ public void setProxyData(EntityProxyData proxyData); 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/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/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) { From f4d3d605dc3b6930226222516b2a10277485b445 Mon Sep 17 00:00:00 2001 From: "Jason Cooke (MSFT)" Date: Wed, 23 Jan 2013 12:09:09 -0800 Subject: [PATCH 02/16] Fixing checkstyle errors for Media Services, issue #204. --- microsoft-azure-api/src/config/checkstyle.xml | 6 ++++- .../services/media/MediaConfiguration.java | 3 +++ .../entityoperations/EntityContract.java | 14 +++++------ .../entityoperations/EntityOperation.java | 10 ++++---- .../EntityOperationSingleResult.java | 2 +- .../implementation/MediaBatchOperations.java | 15 ++++++++---- .../implementation/MediaContentProvider.java | 7 ++---- .../media/implementation/OAuthContract.java | 2 +- .../media/implementation/OAuthFilter.java | 2 +- .../media/implementation/OAuthRestProxy.java | 4 ++-- .../implementation/OAuthTokenResponse.java | 24 +++++++++---------- .../implementation/ODataDateAdapter.java | 14 +++++------ .../media/implementation/ODataEntity.java | 8 +++---- .../ODataEntityCollectionProvider.java | 5 ++-- .../implementation/ODataEntityProvider.java | 5 ++-- .../media/implementation/RedirectFilter.java | 2 +- .../media/implementation/SASTokenFilter.java | 6 +---- .../media/implementation/StatusLine.java | 6 +++-- .../implementation/VersionHeadersFilter.java | 3 +-- .../implementation/content/Constants.java | 6 ++++- .../services/media/models/ProtectionKey.java | 3 +++ 21 files changed, 79 insertions(+), 68 deletions(-) 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/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..afa0ea09462e 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 @@ -27,14 +27,14 @@ public interface EntityOperation { * @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 +42,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 +58,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/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. * From 3a63e0ef2436d33a87f3f695100656b938547788 Mon Sep 17 00:00:00 2001 From: "Jason Cooke (MSFT)" Date: Wed, 23 Jan 2013 14:56:31 -0800 Subject: [PATCH 03/16] Update `settingTimeoutPrefixedFromConfigWorks` to test state of the created service directly, instead of relying on getting a timeout. Also adds some randomness to the table names, so tests can be rerun more rapidly than every 5 minutes. --- .../table/TableServiceIntegrationTest.java | 33 ++++++++++++------- 1 file changed, 22 insertions(+), 11 deletions(-) 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..ff3d463985fa 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]; @@ -1201,16 +1204,24 @@ 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 { + if (fieldNames.length == 0) { + return target; } + + java.lang.reflect.Field field = target.getClass().getDeclaredField(fieldNames[0]); + field.setAccessible(true); + Object value = field.get(target); + return readField(value, java.util.Arrays.copyOfRange(fieldNames, 1, fieldNames.length)); } @Test From baaf7944d4d48e50d9c8a198511d2dec757190cb Mon Sep 17 00:00:00 2001 From: "Jason Cooke (MSFT)" Date: Wed, 23 Jan 2013 14:58:35 -0800 Subject: [PATCH 04/16] Removing code to pre-clean tables, because the table names are now unique each time. --- .../services/table/TableServiceIntegrationTest.java | 13 ------------- 1 file changed, 13 deletions(-) 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 ff3d463985fa..754b0932f203 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 @@ -103,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); } @@ -138,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)); From 84dc3952ab35eb8c3e869d0690bdf0eb6dfeb24d Mon Sep 17 00:00:00 2001 From: "Jason Cooke (MSFT)" Date: Wed, 23 Jan 2013 15:37:14 -0800 Subject: [PATCH 05/16] Convert readField from recursive to iterative. --- .../services/table/TableServiceIntegrationTest.java | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) 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 754b0932f203..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 @@ -1201,14 +1201,13 @@ public void settingTimeoutPrefixedFromConfigWorks() throws Exception { } private Object readField(Object target, String... fieldNames) throws NoSuchFieldException, IllegalAccessException { - if (fieldNames.length == 0) { - return target; + Object value = target; + for (String fieldName : fieldNames) { + java.lang.reflect.Field field = value.getClass().getDeclaredField(fieldName); + field.setAccessible(true); + value = field.get(value); } - - java.lang.reflect.Field field = target.getClass().getDeclaredField(fieldNames[0]); - field.setAccessible(true); - Object value = field.get(target); - return readField(value, java.util.Arrays.copyOfRange(fieldNames, 1, fieldNames.length)); + return value; } @Test From 4e7c7d4157ba9d72cb650c81ffdd0fb166b874f0 Mon Sep 17 00:00:00 2001 From: Chris Tavares Date: Wed, 30 Jan 2013 10:52:44 -0800 Subject: [PATCH 06/16] Updated ignore --- .gitignore | 2 ++ .../.settings/org.eclipse.core.resources.prefs | 6 ++++++ 2 files changed, 8 insertions(+) create mode 100644 microsoft-azure-api/.settings/org.eclipse.core.resources.prefs 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/.settings/org.eclipse.core.resources.prefs b/microsoft-azure-api/.settings/org.eclipse.core.resources.prefs new file mode 100644 index 000000000000..29abf9995641 --- /dev/null +++ b/microsoft-azure-api/.settings/org.eclipse.core.resources.prefs @@ -0,0 +1,6 @@ +eclipse.preferences.version=1 +encoding//src/main/java=UTF-8 +encoding//src/main/resources=UTF-8 +encoding//src/test/java=UTF-8 +encoding//src/test/resources=UTF-8 +encoding/=UTF-8 From 5679d73cdede8c0c174a9bb4173bff397d5567a1 Mon Sep 17 00:00:00 2001 From: Chris Tavares Date: Wed, 30 Jan 2013 16:31:50 -0800 Subject: [PATCH 07/16] First cut at base class for connection string parsing. --- .../ConnectionStringSyntaxException.java | 27 +++ .../core/utils/ParsedConnectionString.java | 161 ++++++++++++++++++ .../utils/ParsedConnectionStringTest.java | 110 ++++++++++++ 3 files changed, 298 insertions(+) create mode 100644 microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/core/utils/ConnectionStringSyntaxException.java create mode 100644 microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/core/utils/ParsedConnectionString.java create mode 100644 microsoft-azure-api/src/test/java/com/microsoft/windowsazure/services/core/utils/ParsedConnectionStringTest.java 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/ParsedConnectionString.java b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/core/utils/ParsedConnectionString.java new file mode 100644 index 000000000000..bca48f5ed9a8 --- /dev/null +++ b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/core/utils/ParsedConnectionString.java @@ -0,0 +1,161 @@ +/** + * 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.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +public class ParsedConnectionString { + private String connectionString; + private int currentIndex; + + public ParsedConnectionString(String connectionString) throws ConnectionStringSyntaxException { + this.connectionString = connectionString; + this.currentIndex = 0; + + matchConnectionString(); + } + + private void matchConnectionString() throws ConnectionStringSyntaxException { + matchPair(); + while (charsLeft() && currentChar() == ';') { + consumeChars(1); + if (charsLeft()) { + matchPair(); + } + } + } + + private char currentChar() { + return connectionString.charAt(currentIndex); + } + + private void consumeChars(int numChars) { + currentIndex += numChars; + } + + private boolean charsLeft() { + return currentIndex < connectionString.length(); + } + + private void matchPair() throws ConnectionStringSyntaxException { + String key = matchKey(); + matchEquals(); + String value = matchValue(); + saveValue(key, value); + } + + private String matchKey() throws ConnectionStringSyntaxException { + String key; + if (isQuote(currentChar())) { + key = matchQuoted(); + } else { + key = matchUnquotedKey(); + } + return key; + } + + private String matchQuoted() throws ConnectionStringSyntaxException { + char quote = currentChar(); + consumeChars(1); + + String value = ""; + while (charsLeft() && currentChar() != quote) { + value = value + currentChar(); + consumeChars(1); + } + + if (!charsLeft()) { + throw new ConnectionStringSyntaxException(String.format("Unterminated quoted string '%1$s", value)); + } + consumeChars(1); + return value; + } + + private String matchUnquotedKey() throws ConnectionStringSyntaxException { + String key = ""; + + while (charsLeft() && currentChar() != '=') { + key += currentChar(); + consumeChars(1); + } + + if (!charsLeft()) { + throw new ConnectionStringSyntaxException(String.format("No value given for key %1$s", key)); + } + return key; + } + + private void matchEquals() throws ConnectionStringSyntaxException { + if (charsLeft()) { + if (currentChar() == '=') { + consumeChars(1); + } else { + throw new ConnectionStringSyntaxException(String.format( + "Expected '=' character at position %1$d, but instead was '%2$c'", + this.currentIndex, connectionString.charAt(this.currentIndex))); + } + } else { + throw new ConnectionStringSyntaxException(String.format( + "Expected '=' character at position %1$d but it was not found", currentIndex)); + } + } + + private String matchValue() throws ConnectionStringSyntaxException { + if (!charsLeft()) { + throw new ConnectionStringSyntaxException("Expected value for key, not given"); + } + String value; + if (isQuote(currentChar())) { + value = matchQuoted(); + } else { + value = matchUnquotedValue(); + } + return value; + } + + private String matchUnquotedValue() { + String value = ""; + + while (charsLeft() && currentChar() != ';') { + value += currentChar(); + consumeChars(1); + } + return value; + } + + private boolean isQuote(char c) { + return c == '"' || c == '\''; + } + + private void saveValue(String key, String value) throws ConnectionStringSyntaxException { + Class thisClass = getClass(); + Method setter; + try { + setter = thisClass.getDeclaredMethod("set" + key, String.class); + 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, thisClass.getName()), e); + } + } +} 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..79a87d6064e7 --- /dev/null +++ b/microsoft-azure-api/src/test/java/com/microsoft/windowsazure/services/core/utils/ParsedConnectionStringTest.java @@ -0,0 +1,110 @@ +/** + * 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 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; + } + + protected void setFieldThree(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"); + } +} From 88a1f7a76a7e4b7ffc46ee272d4ae600152d0831 Mon Sep 17 00:00:00 2001 From: Chris Tavares Date: Thu, 31 Jan 2013 17:28:27 -0800 Subject: [PATCH 08/16] Updated based on code review, rewrite parser based on grammar from Jason --- .../core/utils/ParsedConnectionString.java | 314 ++++++++++++++---- .../utils/pipeline/ConnectionStringField.java | 33 ++ .../utils/ParsedConnectionStringTest.java | 19 +- 3 files changed, 292 insertions(+), 74 deletions(-) create mode 100644 microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/core/utils/pipeline/ConnectionStringField.java 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 index bca48f5ed9a8..8be49de1b538 100644 --- 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 @@ -15,137 +15,282 @@ 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; -public class ParsedConnectionString { +/** + * 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 { - this.connectionString = connectionString; + // 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 void matchConnectionString() throws ConnectionStringSyntaxException { - matchPair(); - while (charsLeft() && currentChar() == ';') { - consumeChars(1); - if (charsLeft()) { - matchPair(); - } - } - } - private char currentChar() { return connectionString.charAt(currentIndex); } - private void consumeChars(int numChars) { - currentIndex += numChars; + private void consumeChar() { + currentIndex++; } private boolean charsLeft() { return currentIndex < connectionString.length(); } - private void matchPair() throws ConnectionStringSyntaxException { - String key = matchKey(); - matchEquals(); - String value = matchValue(); - saveValue(key, value); - } + // + // 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 String matchKey() throws ConnectionStringSyntaxException { - String key; - if (isQuote(currentChar())) { - key = matchQuoted(); - } else { - key = matchUnquotedKey(); + private boolean matchConnectionString() throws ConnectionStringSyntaxException { + if (!matchAttribute()) { + throw new ConnectionStringSyntaxException(String.format( + "Could not parse connection string '%1$s'", connectionString)); } - return key; - } - private String matchQuoted() throws ConnectionStringSyntaxException { - char quote = currentChar(); - consumeChars(1); + boolean moreAttributes = true; + int bookmark; - String value = ""; - while (charsLeft() && currentChar() != quote) { - value = value + currentChar(); - consumeChars(1); + while (moreAttributes) { + bookmark = currentIndex; + boolean separators = false; + while (matchSeparator()) { + separators = true; + } + moreAttributes = separators && matchAttribute(); + if (!moreAttributes) { + currentIndex = bookmark; + } } - if (!charsLeft()) { - throw new ConnectionStringSyntaxException(String.format("Unterminated quoted string '%1$s", value)); + while (matchSeparator()) { } - consumeChars(1); - return value; - } - private String matchUnquotedKey() throws ConnectionStringSyntaxException { - String key = ""; + if (!matchEND()) { + throw new ConnectionStringSyntaxException(String.format( + "Expected end of connection string '%1$s', did not get it", connectionString)); + } + + return true; + } - while (charsLeft() && currentChar() != '=') { - key += currentChar(); - consumeChars(1); + 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()) { - throw new ConnectionStringSyntaxException(String.format("No value given for key %1$s", key)); + 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)); } - return key; + 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 void matchEquals() throws ConnectionStringSyntaxException { - if (charsLeft()) { - if (currentChar() == '=') { - consumeChars(1); - } else { + 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( - "Expected '=' character at position %1$d, but instead was '%2$c'", - this.currentIndex, connectionString.charAt(this.currentIndex))); + "Unterminated quoted value in string '%1$s', starting at character %2$d", connectionString, bookmark)); } + consumeChar(); + currentKey = value; + return true; } else { - throw new ConnectionStringSyntaxException(String.format( - "Expected '=' character at position %1$d but it was not found", currentIndex)); + return false; } } - private String matchValue() throws ConnectionStringSyntaxException { + 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("Expected value for key, not given"); + throw new ConnectionStringSyntaxException(String.format( + "Expected '=' in connection string '%1$s', key started at index %2$d", connectionString, bookmark + )); } - String value; - if (isQuote(currentChar())) { - value = matchQuoted(); + + 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 { - value = matchUnquotedValue(); + return false; } - return value; } - private String matchUnquotedValue() { + private boolean matchRawValue() { String value = ""; + int bookmark = currentIndex; - while (charsLeft() && currentChar() != ';') { + while (charsLeft() && !matchSeparator()) { value += currentChar(); - consumeChars(1); + consumeChar(); + bookmark = currentIndex; } - return value; + currentIndex = bookmark; + currentValue = value; + return true; } - private boolean isQuote(char c) { - return c == '"' || c == '\''; + private boolean matchSeparator() { + int bookmark = currentIndex; + matchSpacing(); + if (charsLeft() && currentChar() == ';') { + consumeChar(); + return true; + } + currentIndex = bookmark; + return false; } - private void saveValue(String key, String value) throws ConnectionStringSyntaxException { - Class thisClass = getClass(); + 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 = thisClass.getDeclaredMethod("set" + key, String.class); + setter = findSetter(key); setter.invoke(this, value); } catch (NoSuchMethodException e) { throw new ConnectionStringSyntaxException(String.format( @@ -155,7 +300,30 @@ private void saveValue(String key, String value) throws ConnectionStringSyntaxEx "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, thisClass.getName()), e); + "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/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 index 79a87d6064e7..049204ef66ea 100644 --- 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 @@ -15,6 +15,7 @@ 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; @@ -76,7 +77,8 @@ public int getFieldThree() { return fieldThree; } - protected void setFieldThree(String fieldThree) { + @ConnectionStringField(name = "fieldthree") + protected void setNumericField(String fieldThree) { this.fieldThree = Integer.parseInt(fieldThree); } } @@ -107,4 +109,19 @@ public void shouldThrowForFieldThatDoesntExist() throws Exception { exception.expect(ConnectionStringSyntaxException.class); new OneField("nosuchfield=nothing"); } + + public void shouldNotThrowIfValueMissing() throws Exception { + exception.expect(ConnectionStringSyntaxException.class); + ThreeFields cs = new ThreeFields(" FieldOne= hello; FieldTwo =;FieldThree=19 "); + assertNull(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()); + } } From 702c26adcbd961b88546a91042c8dcab3e59e6b0 Mon Sep 17 00:00:00 2001 From: Chris Tavares Date: Thu, 31 Jan 2013 17:53:06 -0800 Subject: [PATCH 09/16] Added back in test that was accidentally removed --- .../services/core/utils/ParsedConnectionStringTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 index 049204ef66ea..6da2023a2ef9 100644 --- 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 @@ -110,10 +110,10 @@ public void shouldThrowForFieldThatDoesntExist() throws Exception { new OneField("nosuchfield=nothing"); } + @Test public void shouldNotThrowIfValueMissing() throws Exception { - exception.expect(ConnectionStringSyntaxException.class); ThreeFields cs = new ThreeFields(" FieldOne= hello; FieldTwo =;FieldThree=19 "); - assertNull(cs.getFieldTwo()); + assertEquals("", cs.getFieldTwo()); } @Test From a98c88273d036816cb0f3fb6ed1e21591a0cef25 Mon Sep 17 00:00:00 2001 From: Chris Tavares Date: Fri, 1 Feb 2013 13:14:17 -0800 Subject: [PATCH 10/16] Working towards connection string support in service bus --- .../services/core/utils/ExportUtils.java | 56 +++++++++ .../services/core/utils/pipeline/Exports.java | 23 +--- .../serviceBus/ServiceBusConfiguration.java | 7 ++ .../serviceBus/implementation/Exports.java | 19 +++- .../ServiceBusConnectionSettings.java | 90 +++++++++++++++ .../ServiceBusConnectionString.java | 107 ++++++++++++++++++ .../implementation/ServiceBusRestProxy.java | 4 +- .../implementation/WrapTokenManager.java | 10 +- .../implementation/WrapTokenManagerTest.java | 3 +- 9 files changed, 289 insertions(+), 30 deletions(-) create mode 100644 microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/core/utils/ExportUtils.java create mode 100644 microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/serviceBus/implementation/ServiceBusConnectionSettings.java create mode 100644 microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/serviceBus/implementation/ServiceBusConnectionString.java 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/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/serviceBus/ServiceBusConfiguration.java b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/serviceBus/ServiceBusConfiguration.java index 87202a8b2254..38c0b96facaa 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.connectionstring"; + /** * Defines the configuration URI constant. * 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..dfbe1b096bb4 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 @@ -15,6 +15,11 @@ package com.microsoft.windowsazure.services.serviceBus.implementation; import com.microsoft.windowsazure.services.core.Builder; +import com.microsoft.windowsazure.services.serviceBus.ServiceBusConfiguration; + +import java.util.Map; + +import static com.microsoft.windowsazure.services.core.utils.ExportUtils.getPropertyIfExists; public class Exports implements Builder.Exports { @@ -22,6 +27,18 @@ 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) { + 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)); + } + }); + } } 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..50e08e22d55d --- /dev/null +++ b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/serviceBus/implementation/ServiceBusConnectionSettings.java @@ -0,0 +1,90 @@ +/** + * 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. + */ +public 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) { + if (!parseConnectionString(connectionString)) { + 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) { + try { + ServiceBusConnectionString cs = new ServiceBusConnectionString(connectionString); + setUri(cs); + setWrapUri(cs); + wrapName = cs.getSharedSecretIssuer(); + wrapPassword = cs.getSharedSecretValue(); + return true; + } catch (ConnectionStringSyntaxException e) { + return false; + } catch (URISyntaxException e) { + return false; + } + } + + private void setUri(ServiceBusConnectionString connectionString) { + uri = connectionString.getEndpoint().replace("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:443/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..90467ad2df2b --- /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 + */ + protected 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 + */ + protected 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 + */ + protected 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 + */ + protected 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..6b6d640d43ac 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 @@ -74,11 +74,11 @@ public class ServiceBusRestProxy implements ServiceBusContract { @Inject public ServiceBusRestProxy(Client channel, @Named("serviceBus") WrapFilter authFilter, - @Named("serviceBus.uri") String uri, BrokerPropertiesMapper mapper) { + 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/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..4b1d96be3374 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 @@ -43,7 +43,8 @@ public void init() { 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 From 50929a6505e417f455c10da8ab4445a99dc583c5 Mon Sep 17 00:00:00 2001 From: Chris Tavares Date: Fri, 1 Feb 2013 13:56:01 -0800 Subject: [PATCH 11/16] Connection settings class fully plumbed through config --- .../serviceBus/ServiceBusConfiguration.java | 2 +- .../implementation/ServiceBusRestProxy.java | 2 +- .../serviceBus/ServiceBusCreationTest.java | 17 +++++++++++++++++ .../WrapTokenManagerIntegrationTest.java | 2 +- .../implementation/WrapTokenManagerTest.java | 2 +- 5 files changed, 21 insertions(+), 4 deletions(-) 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 38c0b96facaa..f2b03fc7e7b1 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 @@ -27,7 +27,7 @@ public class ServiceBusConfiguration { * Defines the configuration connection string constant. * */ - public final static String CONNECTION_STRING = "serviceBus.connectionstring"; + public final static String CONNECTION_STRING = "serviceBus.connection.string"; /** * Defines the configuration URI constant. 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 6b6d640d43ac..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,7 +73,7 @@ public class ServiceBusRestProxy implements ServiceBusContract { ServiceFilter[] filters; @Inject - public ServiceBusRestProxy(Client channel, @Named("serviceBus") WrapFilter authFilter, + public ServiceBusRestProxy(Client channel, WrapFilter authFilter, ServiceBusConnectionSettings connectionSettings, BrokerPropertiesMapper mapper) { this.channel = channel; 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..37c2b3ec2c3e 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,14 @@ 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; + } + @Test public void theServiceClassMayBeCreatedDirectlyWithConfig() throws Exception { Configuration config = newConfiguration(); @@ -64,4 +72,13 @@ 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()); + } } 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 4b1d96be3374..c8601221fe48 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 @@ -43,7 +43,7 @@ public void init() { dateFactory = mock(DateFactory.class); contract = mock(WrapContract.class); - ServiceBusConnectionSettings settings = new ServiceBusConnectionSettings(null, null, "testurl", "testName","testpassword"); + ServiceBusConnectionSettings settings = new ServiceBusConnectionSettings(null, null, "testurl", "testname", "testpassword"); client = new WrapTokenManager(contract, dateFactory, settings); when(dateFactory.getDate()).thenAnswer(new Answer() { From d0108413481c2841d7bdc8c0a55bfc8bccb42d98 Mon Sep 17 00:00:00 2001 From: Chris Tavares Date: Fri, 1 Feb 2013 14:18:27 -0800 Subject: [PATCH 12/16] Switched tests to running off connection string instead of individual env. variables --- .../META-INF/com.microsoft.windowsazure.properties | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) 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..e72a01c1d5c6 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 @@ -1,7 +1,8 @@ -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.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 From e001391803d89ca2dba362fae40e067edd87885a Mon Sep 17 00:00:00 2001 From: Chris Tavares Date: Fri, 1 Feb 2013 16:17:36 -0800 Subject: [PATCH 13/16] Fixed up exception reporting, fixed so tests actually use connection strings. --- .../serviceBus/ServiceBusConfiguration.java | 17 ++++++++ .../serviceBus/implementation/Exports.java | 24 +++++++---- .../ServiceBusConnectionSettings.java | 30 ++++++-------- .../ServiceBusConnectionString.java | 8 ++-- .../serviceBus/IntegrationTestBase.java | 5 +-- .../ServiceBusConnectionSettingsTest.java | 41 +++++++++++++++++++ .../implementation/WrapTokenManagerTest.java | 2 +- .../com.microsoft.windowsazure.properties | 8 ++-- 8 files changed, 97 insertions(+), 38 deletions(-) create mode 100644 microsoft-azure-api/src/test/java/com/microsoft/windowsazure/services/serviceBus/implementation/ServiceBusConnectionSettingsTest.java 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 f2b03fc7e7b1..60c69d581fbc 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 @@ -136,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); @@ -145,4 +147,19 @@ else if (profile.length() != 0 && !profile.endsWith(".")) { return configuration; } + + public static Configuration configureWithWrapAuthentication(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 dfbe1b096bb4..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,8 +15,10 @@ 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; @@ -32,12 +34,18 @@ public void register(Builder.Registry registry) { @Override public ServiceBusConnectionSettings create(String profile, Builder builder, Map properties) { - 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)); + 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 index 50e08e22d55d..fe5e6f8e91a5 100644 --- 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 @@ -34,8 +34,10 @@ public class ServiceBusConnectionSettings { private String wrapName; private String wrapPassword; - public ServiceBusConnectionSettings(String connectionString, String uri, String wrapUri, String wrapName, String wrapPassword) { - if (!parseConnectionString(connectionString)) { + 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; @@ -59,19 +61,13 @@ public String getWrapPassword() { return wrapPassword; } - private boolean parseConnectionString(String connectionString) { - try { - ServiceBusConnectionString cs = new ServiceBusConnectionString(connectionString); - setUri(cs); - setWrapUri(cs); - wrapName = cs.getSharedSecretIssuer(); - wrapPassword = cs.getSharedSecretValue(); - return true; - } catch (ConnectionStringSyntaxException e) { - return false; - } catch (URISyntaxException e) { - return false; - } + 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) { @@ -81,8 +77,8 @@ private void setUri(ServiceBusConnectionString connectionString) { 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:443/WRAPv0.9"; + 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 index 90467ad2df2b..ee63db4ccaf8 100644 --- 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 @@ -53,7 +53,7 @@ public String getEndpoint() { * Sets the endpoint value * @param endpoint */ - protected void setEndpoint(String endpoint) { + public void setEndpoint(String endpoint) { this.endpoint = endpoint; } @@ -69,7 +69,7 @@ public String getStsEndpoint() { * Sets the StsEndpoint value * @param stsEndpoint */ - protected void setStsEndpoint(String stsEndpoint) { + public void setStsEndpoint(String stsEndpoint) { this.stsEndpoint = stsEndpoint; } @@ -85,7 +85,7 @@ public String getSharedSecretIssuer() { * Set the shared secret issuer * @param sharedSecretIssuer */ - protected void setSharedSecretIssuer(String sharedSecretIssuer) { + public void setSharedSecretIssuer(String sharedSecretIssuer) { this.sharedSecretIssuer = sharedSecretIssuer; } @@ -101,7 +101,7 @@ public String getSharedSecretValue() { * Set the shared secret value * @param sharedSecretValue */ - protected void setSharedSecretValue(String sharedSecretValue) { + public void setSharedSecretValue(String sharedSecretValue) { this.sharedSecretValue = sharedSecretValue; } } 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/implementation/ServiceBusConnectionSettingsTest.java b/microsoft-azure-api/src/test/java/com/microsoft/windowsazure/services/serviceBus/implementation/ServiceBusConnectionSettingsTest.java new file mode 100644 index 000000000000..447ab6cdc3f5 --- /dev/null +++ b/microsoft-azure-api/src/test/java/com/microsoft/windowsazure/services/serviceBus/implementation/ServiceBusConnectionSettingsTest.java @@ -0,0 +1,41 @@ +/** + * 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 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 = String.format( + "Endpoint=sb://%1$s.servicebus.windows.net/;SharedSecretIssuer=%2$s;SharedSecretValue=%3$s", + 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()); + } +} 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 c8601221fe48..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,7 +38,7 @@ 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); 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 e72a01c1d5c6..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 @@ -1,7 +1,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.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% From 87d5ba95cea26dff95dd9324283bab63955b4819 Mon Sep 17 00:00:00 2001 From: Chris Tavares Date: Mon, 4 Feb 2013 12:08:36 -0800 Subject: [PATCH 14/16] Adding testing for various configuration permutations. --- .../serviceBus/ServiceBusConfiguration.java | 15 ++++- .../serviceBus/ServiceBusCreationTest.java | 16 +++++ .../ServiceBusConnectionSettingsTest.java | 60 ++++++++++++++++++- 3 files changed, 87 insertions(+), 4 deletions(-) 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 60c69d581fbc..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 @@ -148,7 +148,20 @@ else if (profile.length() != 0 && !profile.endsWith(".")) { return configuration; } - public static Configuration configureWithWrapAuthentication(String profile, Configuration 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) { 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 37c2b3ec2c3e..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 @@ -47,6 +47,14 @@ private Configuration newConfigurationWithProfile() { 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(); @@ -81,4 +89,12 @@ public void theServiceClassCanBeCreatedThroughAProfile() throws Exception { 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 index 447ab6cdc3f5..77dc9463911b 100644 --- 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 @@ -15,6 +15,8 @@ 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.*; @@ -27,9 +29,7 @@ public void settingsAreParsedFromConnectionString() throws Exception { String issuer = "myissuer"; String secret = "mysecret"; - String connectionString = String.format( - "Endpoint=sb://%1$s.servicebus.windows.net/;SharedSecretIssuer=%2$s;SharedSecretValue=%3$s", - ns, issuer, secret); + String connectionString = getConnectionString(ns, issuer, secret); ServiceBusConnectionSettings settings = new ServiceBusConnectionSettings(connectionString, null, null, null, null); @@ -38,4 +38,58 @@ public void settingsAreParsedFromConnectionString() throws Exception { 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); + } + + @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()); + } } From 959a3c9b648489c9a4411189453398e55fb5650d Mon Sep 17 00:00:00 2001 From: Chris Tavares Date: Mon, 4 Feb 2013 14:56:48 -0800 Subject: [PATCH 15/16] Made connection settings package visible rather than public. Added test of settings wrap uri via connection string. --- .../ServiceBusConnectionSettings.java | 2 +- .../ServiceBusConnectionSettingsTest.java | 17 +++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) 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 index fe5e6f8e91a5..20890227cc52 100644 --- 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 @@ -28,7 +28,7 @@ * The connection string is looked for first, falling back * to separate config values if not found. */ -public class ServiceBusConnectionSettings { +class ServiceBusConnectionSettings { private String uri; private String wrapUri; private String wrapName; 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 index 77dc9463911b..ec64e7d76eff 100644 --- 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 @@ -45,6 +45,11 @@ private String getConnectionString(String ns, String issuer, String secret) { 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(); @@ -92,4 +97,16 @@ public void settingsPreferConnectionStringIfBothPresentInConfiguration() throws 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()); + } } From ba3e0f3f327700460d2cb5948f82c72081ef7229 Mon Sep 17 00:00:00 2001 From: Chris Tavares Date: Mon, 4 Feb 2013 15:15:45 -0800 Subject: [PATCH 16/16] Only replace sb:// at start of connection string value --- .../serviceBus/implementation/ServiceBusConnectionSettings.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 index 20890227cc52..dc0d3da353c8 100644 --- 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 @@ -71,7 +71,7 @@ private boolean parseConnectionString(String connectionString) throws URISyntaxE } private void setUri(ServiceBusConnectionString connectionString) { - uri = connectionString.getEndpoint().replace("sb://", "https://"); + uri = connectionString.getEndpoint().replaceFirst("^sb://", "https://"); } private void setWrapUri(ServiceBusConnectionString connectionString) throws URISyntaxException {