com.microsoft.windowsazure.services.table.client.TableRequest Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of microsoft-windowsazure-api Show documentation
Show all versions of microsoft-windowsazure-api Show documentation
API for Microsoft Windows Azure Clients
/** * 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.table.client; import java.io.IOException; import java.io.StringWriter; import java.net.HttpURLConnection; import java.net.URI; import java.net.URISyntaxException; import java.util.HashMap; import java.util.Map.Entry; import javax.xml.stream.XMLOutputFactory; import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamWriter; import com.microsoft.windowsazure.services.core.storage.Constants; import com.microsoft.windowsazure.services.core.storage.OperationContext; import com.microsoft.windowsazure.services.core.storage.ResultContinuation; import com.microsoft.windowsazure.services.core.storage.StorageException; import com.microsoft.windowsazure.services.core.storage.utils.PathUtility; import com.microsoft.windowsazure.services.core.storage.utils.UriQueryBuilder; import com.microsoft.windowsazure.services.core.storage.utils.Utility; import com.microsoft.windowsazure.services.core.storage.utils.implementation.BaseRequest; /** * Reserved for internal use. A class used to generate requests for Table objects. */ final class TableRequest { /** * Reserved for internal use. Adds continuation token values to the specified query builder, if set. * * @param builder * The {@link UriQueryBuilder} object to apply the continuation token properties to. * @param continuationToken * The {@link ResultContinuation} object containing the continuation token values to apply to the query * builder. Specify
or empty. * @param eTag * The etag of the entity. * @param timeoutInMs * The server timeout interval in milliseconds. * @param queryBuilder * The {@link UriQueryBuilder} for the operation. * @param options * A {@link TableRequestOptions} object that specifies execution options such as retry policy and timeout * settings for the operation. Specifynull
if no continuation token values are set. * * @throws StorageException * if an error occurs in accessing the query builder or continuation token. */ protected static void applyContinuationToQueryBuilder(final UriQueryBuilder builder, final ResultContinuation continuationToken) throws StorageException { if (continuationToken != null) { if (continuationToken.getNextPartitionKey() != null) { builder.add(TableConstants.TABLE_SERVICE_NEXT_PARTITION_KEY, continuationToken.getNextPartitionKey()); } if (continuationToken.getNextRowKey() != null) { builder.add(TableConstants.TABLE_SERVICE_NEXT_ROW_KEY, continuationToken.getNextRowKey()); } if (continuationToken.getNextTableName() != null) { builder.add(TableConstants.TABLE_SERVICE_NEXT_TABLE_NAME, continuationToken.getNextTableName()); } } } /** * Reserved for internal use. Constructs anHttpURLConnection
to perform a table batch operation. * * @param rootUri * Ajava.net.URI
containing an absolute URI to the resource. * @param timeoutInMs * The server timeout interval in milliseconds. * @param batchID * TheString
containing the batch identifier. * @param queryBuilder * The {@link UriQueryBuilder} for the operation. * @param tableOptions * A {@link TableRequestOptions} object that specifies execution options such as retry policy and timeout * settings for the operation. This parameter is unused. * @param opContext * An {@link OperationContext} object for tracking the current operation. Specifynull
to * safely ignore operation context. * * @return * AnHttpURLConnection
to use to perform the operation. * * @throws IOException * if there is an error opening the connection. * @throws URISyntaxException * if the resource URI is invalid. * @throws StorageException * if a storage service error occurred during the operation. */ protected static HttpURLConnection batch(final URI rootUri, final int timeoutInMs, final String batchID, final UriQueryBuilder queryBuilder, final TableRequestOptions tableOptions, final OperationContext opContext) throws IOException, URISyntaxException, StorageException { final URI queryUri = PathUtility.appendPathToUri(rootUri, "$batch"); final HttpURLConnection retConnection = BaseRequest.createURLConnection(queryUri, timeoutInMs, queryBuilder, opContext); // Note : accept behavior, java by default sends Accept behavior // as text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2 retConnection.setRequestProperty(Constants.HeaderConstants.ACCEPT, TableConstants.HeaderConstants.ACCEPT_TYPE); retConnection.setRequestProperty(Constants.HeaderConstants.ACCEPT_CHARSET, "UTF8"); retConnection.setRequestProperty(TableConstants.HeaderConstants.MAX_DATA_SERVICE_VERSION, TableConstants.HeaderConstants.MAX_DATA_SERVICE_VERSION_VALUE); retConnection.setRequestProperty(Constants.HeaderConstants.CONTENT_TYPE, String.format(TableConstants.HeaderConstants.MULTIPART_MIXED_FORMAT, batchID)); retConnection.setRequestMethod("POST"); retConnection.setDoOutput(true); return retConnection; } /** * Reserved for internal use. Constructs the coreHttpURLConnection
to perform an operation. * * @param rootUri * Ajava.net.URI
containing an absolute URI to the resource. * @param tableName * The name of the table. * @param identity * The identity of the entity, to pass in the Service Managment REST operation URI as *tableName(identity)
. Ifnull
, only the tableName * value will be passed. * @param timeoutInMs * The server timeout interval in milliseconds. * @param queryBuilder * TheUriQueryBuilder
for the request. * @param requestMethod * The HTTP request method to set. * @param options * A {@link TableRequestOptions} object that specifies execution options such as retry policy and timeout * settings for the operation. This parameter is unused. * @param opContext * An {@link OperationContext} object for tracking the current operation. * * @return * AnHttpURLConnection
to use to perform the operation. * * @throws IOException * if there is an error opening the connection. * @throws URISyntaxException * if the resource URI is invalid. * @throws StorageException * if a storage service error occurred during the operation. */ protected static HttpURLConnection coreCreate(final URI rootUri, final String tableName, final String eTag, final String identity, final int timeoutInMs, final UriQueryBuilder queryBuilder, final String requestMethod, final TableRequestOptions tableOptions, final OperationContext opContext) throws IOException, URISyntaxException, StorageException { URI queryUri = null; // Do point query / delete etc. if (!Utility.isNullOrEmpty(identity)) { queryUri = PathUtility.appendPathToUri(rootUri, tableName.concat(String.format("(%s)", identity))); } else { queryUri = PathUtility.appendPathToUri(rootUri, tableName); } final HttpURLConnection retConnection = BaseRequest.createURLConnection(queryUri, timeoutInMs, queryBuilder, opContext); // Note : accept behavior, java by default sends Accept behavior // as text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2 retConnection.setRequestProperty(Constants.HeaderConstants.ACCEPT, TableConstants.HeaderConstants.ACCEPT_TYPE); retConnection.setRequestProperty(Constants.HeaderConstants.ACCEPT_CHARSET, "UTF-8"); retConnection.setRequestProperty(TableConstants.HeaderConstants.MAX_DATA_SERVICE_VERSION, TableConstants.HeaderConstants.MAX_DATA_SERVICE_VERSION_VALUE); retConnection.setRequestProperty(Constants.HeaderConstants.CONTENT_TYPE, TableConstants.HeaderConstants.ATOMPUB_TYPE); if (!Utility.isNullOrEmpty(eTag)) { retConnection.setRequestProperty(Constants.HeaderConstants.IF_MATCH, eTag); } retConnection.setRequestMethod(requestMethod); return retConnection; } /** * Reserved for internal use. Constructs anHttpURLConnection
to perform a delete operation. * * @param rootUri * Ajava.net.URI
containing an absolute URI to the resource. * @param tableName * The name of the table. * @param identity * The identity of the entity. The resulting request will be formatted as /tableName(identity) if not * null or empty. * @param eTag * The etag of the entity. * @param timeoutInMs * The server timeout interval in milliseconds. * @param queryBuilder * The {@link UriQueryBuilder} for the operation. * @param options * A {@link TableRequestOptions} object that specifies execution options such as retry policy and timeout * settings for the operation. Specifynull
to use the request options specified on the * {@link CloudTableClient}. * @param opContext * An {@link OperationContext} object for tracking the current operation. Specifynull
to * safely ignore operation context. * * @return * AnHttpURLConnection
to use to perform the operation. * * @throws IOException * if there is an error opening the connection. * @throws URISyntaxException * if the resource URI is invalid. * @throws StorageException * if a storage service error occurred during the operation. */ protected static HttpURLConnection delete(final URI rootUri, final String tableName, final String identity, final String eTag, final int timeoutInMs, final UriQueryBuilder queryBuilder, final TableRequestOptions tableOptions, final OperationContext opContext) throws IOException, URISyntaxException, StorageException { return coreCreate(rootUri, tableName, eTag, identity, timeoutInMs, queryBuilder, "DELETE", tableOptions, opContext); } /** * Reserved for internal use. Constructs anHttpURLConnection
to perform an insert operation. * * @param rootUri * Ajava.net.URI
containing an absolute URI to the resource. * @param tableName * The name of the table. * @param identity * The identity of the entity. The resulting request will be formatted as /tableName(identity) if not * null or empty. * @param eTag * The etag of the entity, can be null for straight inserts. * @param updateType * The {@link TableUpdateType} type of update to be performed. Specifynull
for straight * inserts. * @param timeoutInMs * The server timeout interval in milliseconds. * @param queryBuilder * The {@link UriQueryBuilder} for the operation. * @param options * A {@link TableRequestOptions} object that specifies execution options such as retry policy and timeout * settings for the operation. Specifynull
to use the request options specified on the * {@link CloudTableClient}. * @param opContext * An {@link OperationContext} object for tracking the current operation. Specifynull
to * safely ignore operation context. * * @return * AnHttpURLConnection
to use to perform the operation. * * @throws IOException * if there is an error opening the connection. * @throws URISyntaxException * if the resource URI is invalid. * @throws StorageException * if a storage service error occurred during the operation. */ protected static HttpURLConnection insert(final URI rootUri, final String tableName, final String identity, final String eTag, final TableUpdateType updateType, final int timeoutInMs, final UriQueryBuilder queryBuilder, final TableRequestOptions tableOptions, final OperationContext opContext) throws IOException, URISyntaxException, StorageException { HttpURLConnection retConnection = null; if (updateType == null) { retConnection = coreCreate(rootUri, tableName, eTag, null/* identity */, timeoutInMs, queryBuilder, "POST", tableOptions, opContext); } else if (updateType == TableUpdateType.MERGE) { retConnection = coreCreate(rootUri, tableName, null/* ETAG */, identity, timeoutInMs, queryBuilder, "POST", tableOptions, opContext); retConnection.setRequestProperty("X-HTTP-Method", "MERGE"); } else if (updateType == TableUpdateType.REPLACE) { retConnection = coreCreate(rootUri, tableName, null/* ETAG */, identity, timeoutInMs, queryBuilder, "PUT", tableOptions, opContext); } retConnection.setDoOutput(true); return retConnection; } /** * Reserved for internal use. Constructs an HttpURLConnection to perform a merge operation. * * @param rootUri * Ajava.net.URI
containing an absolute URI to the resource. * @param tableName * The name of the table. * @param identity * The identity of the entity. The resulting request will be formatted as /tableName(identity) if not * null or empty. * @param eTag * The etag of the entity. * @param timeoutInMs * The server timeout interval in milliseconds. * @param queryBuilder * The {@link UriQueryBuilder} for the operation. * @param options * A {@link TableRequestOptions} object that specifies execution options such as retry policy and timeout * settings for the operation. Specifynull
to use the request options specified on the * {@link CloudTableClient}. * @param opContext * An {@link OperationContext} object for tracking the current operation. Specifynull
to * safely ignore operation context. * * @return * AnHttpURLConnection
to use to perform the operation. * * @throws IOException * if there is an error opening the connection. * @throws URISyntaxException * if the resource URI is invalid. * @throws StorageException * if a storage service error occurred during the operation. */ protected static HttpURLConnection merge(final URI rootUri, final String tableName, final String identity, final String eTag, final int timeoutInMs, final UriQueryBuilder queryBuilder, final TableRequestOptions tableOptions, final OperationContext opContext) throws IOException, URISyntaxException, StorageException { final HttpURLConnection retConnection = coreCreate(rootUri, tableName, eTag, identity, timeoutInMs, queryBuilder, "POST", tableOptions, opContext); retConnection.setRequestProperty("X-HTTP-Method", "MERGE"); retConnection.setDoOutput(true); return retConnection; } /** * Reserved for internal use. Constructs an HttpURLConnection to perform a single entity query operation. * * @param rootUri * Ajava.net.URI
containing an absolute URI to the resource. * @param tableName * The name of the table. * @param identity * The identity of the entity. The resulting request will be formatted as /tableName(identity) if not * null or empty. * @param timeoutInMs * The server timeout interval in milliseconds. * @param queryBuilder * The {@link UriQueryBuilder} for the operation. * @param options * A {@link TableRequestOptions} object that specifies execution options such as retry policy and timeout * settings for the operation. Specifynull
to use the request options specified on the * {@link CloudTableClient}. * @param opContext * An {@link OperationContext} object for tracking the current operation. Specifynull
to * safely ignore operation context. * * @return * AnHttpURLConnection
to use to perform the operation. * * @throws IOException * if there is an error opening the connection. * @throws URISyntaxException * if the resource URI is invalid. * @throws StorageException * if a storage service error occurred during the operation. */ protected static HttpURLConnection query(final URI rootUri, final String tableName, final String identity, final int timeoutInMs, UriQueryBuilder queryBuilder, final ResultContinuation continuationToken, final TableRequestOptions tableOptions, final OperationContext opContext) throws IOException, URISyntaxException, StorageException { if (queryBuilder == null) { queryBuilder = new UriQueryBuilder(); } applyContinuationToQueryBuilder(queryBuilder, continuationToken); final HttpURLConnection retConnection = coreCreate(rootUri, tableName, null, identity, timeoutInMs, queryBuilder, "GET", tableOptions, opContext); return retConnection; } /** * Reserved for internal use. Constructs an HttpURLConnection to perform an update operation. * * @param rootUri * Ajava.net.URI
containing an absolute URI to the resource. * @param tableName * The name of the table. * @param identity * AString
representing the identity of the entity. The resulting request will be formatted * using /tableName(identity) if identity is not >code>nullnull
to use the request options specified on the * {@link CloudTableClient}. * @param opContext * An {@link OperationContext} object for tracking the current operation. Specifynull
to * safely ignore operation context. * * @return * AnHttpURLConnection
to use to perform the operation. * * @throws IOException * if there is an error opening the connection. * @throws URISyntaxException * if the resource URI is invalid. * @throws StorageException * if a storage service error occurred during the operation. */ protected static HttpURLConnection update(final URI rootUri, final String tableName, final String identity, final String eTag, final int timeoutInMs, final UriQueryBuilder queryBuilder, final TableRequestOptions tableOptions, final OperationContext opContext) throws IOException, URISyntaxException, StorageException { final HttpURLConnection retConnection = coreCreate(rootUri, tableName, eTag, identity, timeoutInMs, queryBuilder, "PUT", tableOptions, opContext); retConnection.setDoOutput(true); return retConnection; } /** * Sets the ACL for the table. , Sign with length of aclBytes. * * @param rootUri * Ajava.net.URI
containing an absolute URI to the resource. * @param tableName * The name of the table. * @param timeoutInMs * The server timeout interval in milliseconds. * @param options * A {@link TableRequestOptions} object that specifies execution options such as retry policy and timeout * settings for the operation. Specifynull
to use the request options specified on the * {@link CloudTableClient}. * @param opContext * An {@link OperationContext} object for tracking the current operation. Specifynull
to * safely ignore operation context. * * @return a HttpURLConnection configured for the operation. * @throws StorageException * */ public static HttpURLConnection setAcl(final URI rootUri, final int timeoutInMs, final OperationContext opContext) throws IOException, URISyntaxException, StorageException { UriQueryBuilder queryBuilder = new UriQueryBuilder(); queryBuilder.add("comp", "acl"); final HttpURLConnection retConnection = BaseRequest.createURLConnection(rootUri, timeoutInMs, queryBuilder, opContext); retConnection.setRequestMethod("PUT"); retConnection.setDoOutput(true); retConnection.setRequestProperty(Constants.HeaderConstants.CONTENT_TYPE, TableConstants.HeaderConstants.ATOMPUB_TYPE); return retConnection; } /** * Writes a collection of shared access policies to the specified stream in XML format. * * @param sharedAccessPolicies * A collection of shared access policies * @param outWriter * an sink to write the output to. * @throws XMLStreamException */ public static void writeSharedAccessIdentifiersToStream( final HashMapsharedAccessPolicies, final StringWriter outWriter) throws XMLStreamException { Utility.assertNotNull("sharedAccessPolicies", sharedAccessPolicies); Utility.assertNotNull("outWriter", outWriter); final XMLOutputFactory xmlOutFactoryInst = XMLOutputFactory.newInstance(); final XMLStreamWriter xmlw = xmlOutFactoryInst.createXMLStreamWriter(outWriter); if (sharedAccessPolicies.keySet().size() > Constants.MAX_SHARED_ACCESS_POLICY_IDENTIFIERS) { final String errorMessage = String .format("Too many %d shared access policy identifiers provided. Server does not support setting more than %d on a single container.", sharedAccessPolicies.keySet().size(), Constants.MAX_SHARED_ACCESS_POLICY_IDENTIFIERS); throw new IllegalArgumentException(errorMessage); } // default is UTF8 xmlw.writeStartDocument(); xmlw.writeStartElement(Constants.SIGNED_IDENTIFIERS_ELEMENT); for (final Entry entry : sharedAccessPolicies.entrySet()) { final SharedAccessTablePolicy policy = entry.getValue(); xmlw.writeStartElement(Constants.SIGNED_IDENTIFIER_ELEMENT); // Set the identifier xmlw.writeStartElement(Constants.ID); xmlw.writeCharacters(entry.getKey()); xmlw.writeEndElement(); xmlw.writeStartElement(Constants.ACCESS_POLICY); // Set the Start Time xmlw.writeStartElement(Constants.START); xmlw.writeCharacters(Utility.getUTCTimeOrEmpty(policy.getSharedAccessStartTime())); // end Start xmlw.writeEndElement(); // Set the Expiry Time xmlw.writeStartElement(Constants.EXPIRY); xmlw.writeCharacters(Utility.getUTCTimeOrEmpty(policy.getSharedAccessExpiryTime())); // end Expiry xmlw.writeEndElement(); // Set the Permissions xmlw.writeStartElement(Constants.PERMISSION); xmlw.writeCharacters(SharedAccessTablePolicy.permissionsToString(policy.getPermissions())); // end Permission xmlw.writeEndElement(); // end AccessPolicy xmlw.writeEndElement(); // end SignedIdentifier xmlw.writeEndElement(); } // end SignedIdentifiers xmlw.writeEndElement(); // end doc xmlw.writeEndDocument(); } /** * Constructs a web request to return the ACL for this table. Sign with no length specified. * * @param rootUri * A java.net.URI
containing an absolute URI to the resource. * @param tableName * The name of the table. * @param timeoutInMs * The server timeout interval in milliseconds. * @param options * A {@link TableRequestOptions} object that specifies execution options such as retry policy and timeout * settings for the operation. Specifynull
to use the request options specified on the * {@link CloudTableClient}. * @param opContext * An {@link OperationContext} object for tracking the current operation. Specifynull
to * safely ignore operation context. * * @return a HttpURLConnection configured for the operation. * @throws StorageException */ public static HttpURLConnection getAcl(final URI rootUri, final String tableName, final int timeoutInMs, final OperationContext opContext) throws IOException, URISyntaxException, StorageException { UriQueryBuilder queryBuilder = new UriQueryBuilder(); queryBuilder.add("comp", "acl"); final HttpURLConnection retConnection = BaseRequest.createURLConnection(rootUri, timeoutInMs, queryBuilder, opContext); retConnection.setRequestMethod("GET"); retConnection.setRequestProperty(Constants.HeaderConstants.ACCEPT, TableConstants.HeaderConstants.ACCEPT_TYPE); retConnection.setRequestProperty(Constants.HeaderConstants.ACCEPT_CHARSET, "UTF8"); retConnection.setRequestProperty(TableConstants.HeaderConstants.MAX_DATA_SERVICE_VERSION, TableConstants.HeaderConstants.MAX_DATA_SERVICE_VERSION_VALUE); retConnection.setRequestProperty(Constants.HeaderConstants.CONTENT_TYPE, TableConstants.HeaderConstants.ATOMPUB_TYPE); return retConnection; } /** * Private Default Constructor. */ private TableRequest() { // No op } }