Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tables Client commit #11

Closed
wants to merge 30 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
b4a8ff9
Fixing several test-related issues
jcookems Feb 13, 2012
a5e94e3
Avoiding a warning on build. Fixes #177
lodejard Feb 13, 2012
6a25ef7
Initial implementation of table service
Dec 7, 2011
cfb7c93
Integration tests
Dec 8, 2011
bbcee3e
Cosmetic changes
Jan 9, 2012
9432fac
Implement table creation/deletion/querying
Jan 10, 2012
f481f38
Add support for "insertEntity"
Jan 11, 2012
28a3cec
Whitespaces
Jan 11, 2012
b3fc550
Add support for "updateEntity"
Jan 11, 2012
6696e2c
Add support for "DeleteEntity"
Jan 11, 2012
9cede50
Add support for "mergeEntity"
Jan 11, 2012
b9a00d4
Add support for "insertOrReplaceEntity"
Jan 11, 2012
a4f49b0
Add support for "insertOrMergeEntity"
Jan 11, 2012
bf53b9c
Add support for "getEntity" and "queryEntities"
Jan 11, 2012
a72bc2a
Rename a few classes, fix support for query continuation
Jan 12, 2012
711e23d
Fix bug with server sometimes sending back shorter ISO 8601 dates
Jan 12, 2012
06146b7
Adding test for query entities continuation
Jan 12, 2012
8fdbcf7
Adding a couple more unit test for query entities
Jan 12, 2012
3f5f5d7
Initial (not quite working yet) support for batch operations
Jan 13, 2012
802e9b0
Add full support for "batch" operation on tables
Jan 14, 2012
34de8fe
Additional test for "batch" operation
Jan 14, 2012
18c8255
Simple code refactorings
Jan 14, 2012
04cc644
Support for all batch operations
Jan 14, 2012
3ed65cc
Fixed string-comparison bug in service runtime.
Dec 9, 2011
87ebda2
Commenting out an optional diagnostic line
lodejard Feb 13, 2012
eaf313b
Merge pull request #6 from loudej/string-comparison
loudej Feb 14, 2012
73c80b3
Merge pull request #5 from loudej/pom-warning
loudej Feb 14, 2012
8d2258b
Fixing a simple typo: blob to queue
jeffwilcox Feb 15, 2012
2c2ca7e
Merge pull request #7 from loudej/tables
joostdenijs Feb 21, 2012
3a7d97c
Table Client commit
Feb 22, 2012
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions microsoft-azure-api/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,16 @@
<artifactId>commons-logging</artifactId>
<version>1.1.1</version>
</dependency>
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
<version>1.4</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.1</version>
</dependency>
</dependencies>

<build>
Expand All @@ -104,6 +114,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ private Map<String, Role> translateRoles(RoleEnvironmentInfo environmentInfo, Ro
for (RoleInfo roleInfo : environmentInfo.getRoles().getRole()) {
Map<String, RoleInstance> instances = translateRoleInstances(roleInfo.getInstances());

if (roleInfo.getName() == currentRole) {
if (roleInfo.getName().equals(currentRole)) {
instances.put(currentInstance.getId(), currentInstance);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,21 @@
* Copyright 2011 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
* 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.
* 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.blob;

import com.microsoft.windowsazure.services.blob.implementation.BlobExceptionProcessor;
import com.microsoft.windowsazure.services.blob.implementation.BlobRestProxy;
import com.microsoft.windowsazure.services.blob.implementation.ISO8601DateConverter;
import com.microsoft.windowsazure.services.blob.implementation.SharedKeyFilter;
import com.microsoft.windowsazure.services.blob.implementation.SharedKeyLiteFilter;
import com.microsoft.windowsazure.services.core.Builder;
Expand All @@ -28,5 +29,6 @@ public void register(Builder.Registry registry) {
registry.add(BlobRestProxy.class);
registry.add(SharedKeyLiteFilter.class);
registry.add(SharedKeyFilter.class);
registry.add(ISO8601DateConverter.class);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,10 @@
import com.microsoft.windowsazure.services.blob.models.SetContainerMetadataOptions;
import com.microsoft.windowsazure.services.core.ServiceException;
import com.microsoft.windowsazure.services.core.ServiceFilter;
import com.microsoft.windowsazure.services.core.utils.CommaStringBuilder;
import com.microsoft.windowsazure.services.core.utils.pipeline.ClientFilterAdapter;
import com.microsoft.windowsazure.services.core.utils.pipeline.HttpURLConnectionClient;
import com.microsoft.windowsazure.services.core.utils.pipeline.PipelineHelpers;
import com.microsoft.windowsazure.services.core.utils.pipeline.PipelineHelpers.EnumCommaStringBuilder;
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.WebResource;
import com.sun.jersey.api.client.WebResource.Builder;
Expand Down Expand Up @@ -155,18 +155,18 @@ private HashMap<String, String> getMetadataFromHeaders(ClientResponse response)
}

private WebResource addOptionalBlobListingIncludeQueryParam(ListBlobsOptions options, WebResource webResource) {
EnumCommaStringBuilder sb = new EnumCommaStringBuilder();
CommaStringBuilder sb = new CommaStringBuilder();
sb.addValue(options.isIncludeSnapshots(), "snapshots");
sb.addValue(options.isIncludeUncommittedBlobs(), "uncommittedblobs");
sb.addValue(options.isIncludeMetadata(), "metadata");
webResource = addOptionalQueryParam(webResource, "include", sb.getValue());
webResource = addOptionalQueryParam(webResource, "include", sb.toString());
return webResource;
}

private WebResource addOptionalContainerIncludeQueryParam(ListContainersOptions options, WebResource webResource) {
EnumCommaStringBuilder sb = new EnumCommaStringBuilder();
CommaStringBuilder sb = new CommaStringBuilder();
sb.addValue(options.isIncludeMetadata(), "metadata");
webResource = addOptionalQueryParam(webResource, "include", sb.getValue());
webResource = addOptionalQueryParam(webResource, "include", sb.toString());
return webResource;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,11 @@ public class ContainerACLDateAdapter extends XmlAdapter<String, Date> {

@Override
public Date unmarshal(String arg0) throws Exception {
return new ContainerACLDateConverter().parse(arg0);
return new ISO8601DateConverter().parse(arg0);
}

@Override
public String marshal(Date arg0) throws Exception {
return new ContainerACLDateConverter().format(arg0);
return new ISO8601DateConverter().format(arg0);
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/**
* Copyright 2011 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.blob.implementation;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;

/*
* "not quite" ISO 8601 date time conversion routines
*/
public class ISO8601DateConverter {
// Note: because of the trailing "0000000", this is not quite ISO 8601 compatible
private static final String DATETIME_PATTERN = "yyyy-MM-dd'T'HH:mm:ss.SSSSSSS'Z'";
private static final String SHORT_DATETIME_PATTERN = "yyyy-MM-dd'T'HH:mm:ss'Z'";

public String format(Date date) {
return getFormat().format(date);
}

public Date parse(String date) throws ParseException {
if (date == null)
return null;

// Sometimes, the date comes back without the ".SSSSSSS" part (presumably when the decimal value
// of the date is "0". Use the short format in that case.
if (date.indexOf('.') < 0)
return getShortFormat().parse(date);
else
return getFormat().parse(date);
}

private DateFormat getFormat() {
DateFormat iso8601Format = new SimpleDateFormat(DATETIME_PATTERN, Locale.US);
iso8601Format.setTimeZone(TimeZone.getTimeZone("GMT"));
return iso8601Format;
}

private DateFormat getShortFormat() {
DateFormat iso8601Format = new SimpleDateFormat(SHORT_DATETIME_PATTERN, Locale.US);
iso8601Format.setTimeZone(TimeZone.getTimeZone("GMT"));
return iso8601Format;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@
* Copyright 2011 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
* 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.
* 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.blob.implementation;

Expand Down Expand Up @@ -44,6 +44,18 @@ public SharedKeyFilter(@Named(BlobConfiguration.ACCOUNT_NAME) String accountName
this.signer = new HmacSHA256Sign(accountKey);
}

protected String getHeader(ClientRequest cr, String headerKey) {
return SharedKeyUtils.getHeader(cr, headerKey);
}

protected HmacSHA256Sign getSigner() {
return signer;
}

protected String getAccountName() {
return accountName;
}

@Override
public ClientResponse handle(ClientRequest cr) throws ClientHandlerException {
// Only sign if no other filter is handling authorization
Expand All @@ -60,6 +72,7 @@ public ClientResponse handle(ClientRequest cr) throws ClientHandlerException {
return this.getNext().handle(cr);
}

@Override
public void onBeforeStreamingEntity(ClientRequest clientRequest) {
// All headers should be known at this point, time to sign!
sign(clientRequest);
Expand Down Expand Up @@ -105,11 +118,11 @@ public void sign(ClientRequest cr) {
cr.getHeaders().putSingle("Authorization", "SharedKey " + this.accountName + ":" + signature);
}

private void addOptionalDateHeader(ClientRequest cr) {
protected void addOptionalDateHeader(ClientRequest cr) {
String date = getHeader(cr, "Date");
if (date == "") {
date = new RFC1123DateConverter().format(new Date());
cr.getHeaders().add("Date", date);
cr.getHeaders().putSingle("Date", date);
}
}

Expand Down Expand Up @@ -209,8 +222,4 @@ private String getCanonicalizedResource(ClientRequest cr) {

return result;
}

private String getHeader(ClientRequest cr, String headerKey) {
return SharedKeyUtils.getHeader(cr, headerKey);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@
* Copyright 2011 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
* 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.
* 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.blob.implementation;

Expand Down Expand Up @@ -59,6 +59,7 @@ public ClientResponse handle(ClientRequest cr) throws ClientHandlerException {
return this.getNext().handle(cr);
}

@Override
public void onBeforeStreamingEntity(ClientRequest clientRequest) {
// All headers should be known at this point, time to sign!
sign(clientRequest);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,8 @@ public static AccessCondition generateEmptyCondition() {
* Returns an access condition such that an operation will be performed only if the resource's ETag value matches
* the specified ETag value.
* <p>
* Setting this access condition modifies the request to include the HTTP <i>If-Match</i> conditional header. If
* this access condition is set, the operation is performed only if the ETag of the resource matches the specified
* ETag.
* Setting this access condition modifies the request to include the HTTP <i>If-Match</i> conditional header. If this
* access condition is set, the operation is performed only if the ETag of the resource matches the specified ETag.
* <p>
* For more information, see <a href= 'http://go.microsoft.com/fwlink/?LinkID=224642&clcid=0x409'>Specifying
* Conditional Headers for Blob Service Operations</a>.
Expand Down Expand Up @@ -84,8 +83,8 @@ public static AccessCondition generateIfModifiedSinceCondition(final Date lastMo
* Returns an access condition such that an operation will be performed only if the resource's ETag value does not
* match the specified ETag value.
* <p>
* Setting this access condition modifies the request to include the HTTP <i>If-None-Match</i> conditional header.
* If this access condition is set, the operation is performed only if the ETag of the resource does not match the
* Setting this access condition modifies the request to include the HTTP <i>If-None-Match</i> conditional header. If
* this access condition is set, the operation is performed only if the ETag of the resource does not match the
* specified ETag.
* <p>
* For more information, see <a href= 'http://go.microsoft.com/fwlink/?LinkID=224642&clcid=0x409'>Specifying
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import com.microsoft.windowsazure.services.blob.client.CloudBlobClient;
import com.microsoft.windowsazure.services.core.storage.utils.Utility;
import com.microsoft.windowsazure.services.queue.client.CloudQueueClient;
import com.microsoft.windowsazure.services.table.client.CloudTableClient;

/**
* Represents a Windows Azure storage account.
Expand Down Expand Up @@ -538,6 +539,26 @@ public CloudQueueClient createCloudQueueClient() {
return new CloudQueueClient(this.getQueueEndpoint(), this.getCredentials());
}

/**
* Creates a new table service client.
*
* @return A client object that uses the Table service endpoint.
*/
public CloudTableClient createCloudTableClient() {
if (this.getTableEndpoint() == null) {
throw new IllegalArgumentException("No table endpoint configured.");
}

if (this.credentials == null) {
throw new IllegalArgumentException("No credentials provided.");
}

if (!this.credentials.canCredentialsSignRequest()) {
throw new IllegalArgumentException("CloudTableClient requires a credential that can sign request");
}
return new CloudTableClient(this.getTableEndpoint(), this.getCredentials());
}

/**
* Returns the endpoint for the Blob service, as configured for the storage account. This method is not supported
* when using shared access signature credentials.
Expand Down
Loading