Skip to content
April 27, 2012 / ahriman hpc mode

Доступ к хранилищу Windows Azure из Java-приложения. Таблицы.

Storage Client For Java является библиотекой, позволяющей использовать из Java-приложения сервисы хранения блобов, очередей и таблиц. В данный момент релиз находится на стадии Community Technology Preview (CTP).

Основные классы, которые содержит библиотека:

com.microsoft.windowsazure.services.core.storage – основные примитивы и объекты, общие для всех сервисов хранилища: CloudStorageAccount,StorageCredentials, etc.

com.microsoft.windowsazure.services.blob.client – функциональность, необходимая для управления блобами: CloudBlobClient, CloudBlob, etc.

com.microsoft.windowsazure.services.queue.client – функциональность, необходимая для управления очередями: CloudQueueClient, CloudQueue, etc.

com.microsoft.windowsazure.services.table.client – функциональность, необходимая для управления таблицами: CloudTableClient, TableServiceEntity, etc.

Библиотека взаимодействия с хранилищем Windows Azure использует локальную объектную модель для взаимодействия с соответствующей моделью на сервере. К основным объектам, использующимся для взаимодействия с хранилищем, относятся:

* StorageAccount

* ServiceClients

* Cloud Objects

* Queues

* Tables

Немного информации по каждому из объектов.

StorageAccount

CloudStorageAccount является объектом, содержащим точку входа и учетные данные для аккаунта хранилища, а также позволяющим конфигурировать приложение на использование облачного хранилища или локального эмулятора. После создания этого объекта и получения ссылки на соответствующий аккаунт далее можно создавать облачные клиенты для сервисов хранилища: CloudBlobClient, CloudQueueClient, CloudTableClient. При создании CloudStorageAccount можно указать точки входа для сервисов хранилищ.

ServiceClients

Объектная модель сервисов хранилища опирается на клиент сервиса, с которым также ассоциируется специфичные для сервиса сведения, такие как таймауты, retry-политики, etc.

Например, для возвращения списка очередей необходимо вызвать соответствующий метод клиента облачного сервиса очередей: CloudQueueClient.listQueues()

Cloud Objects

Клиент облачного сервиса является “начальником”, управляющим операциями над определенным сервисом хранилища. Его “подчиненными” являются облачные объекты, используемые для отображения уже конкретных сущностей на объектную модель. К этим объектам относятся: CloudBlockBlob, CloudPageBlob, CloudBlobContainer, CloudQueue. Каждый из них содержит соответствующую необходимому сервису функциональность в виде методов и свойств. Исключением является лишь отображение сущности Таблиц.

AccessCondition

Основной задачей AccessCondition (только в случае блобов!) является предоставление набора методов, генерирующих экземпляры AccessCondition для большинства сценариев (IfMatch, IfNoneMatch, IfModifiedSince, IfNotModifiedSince, Lease) или их комбинации. Сценарии AccessCondition определяют условие, при котором должно совершиться действие.

Например:

AccessCondition.generateIfNoneMatchCondition(eTag) – операция выполнится, если ресурс не является ресурсом с определенной версией.

AccessCondition.generateIfModifiedSinceCondition(lastModifiedDate) – операция выполнится, если ресурс был модифицирован с такого-то времени (lastModifiedDate).

Retry-политики

Retry-политики были спроектированы для реализации механизма повторения при определенных кодах статусов HTTP. По умолчанию политики не применяются при коде возврата 400, однако пользователь может создать собственную политику, обрабатывающую операцию повторения при этом коде возврата. Кроме этого, механизм RetryPolicies является сохраняющим состояние, что позволяет добиться высокой гибкости в обработке определенных ситуаций.

Библиотека Java для сервисов хранилищ Windows Azure содержит три основных политики повторения, которые пользователь может переопределить при необходимости. Политика повторения по умолчанию использует для всех операций политику экспоненциального отката с 3 дополнительными попытками:

new RetryExponentialRetry(

3000,

30000,

90000,

3 // максимальное количество попыток

);

Таким образом, операция будет повторяться спустя 3 милисекунды, 35,600 милисекунд и 90 милисекунд. Пользователь может увеличить максимальное количество попыток.

Библиотека Java. Таблицы.

Давайте рассмотрим, что же предлагает разработчику библиотека Java в отношении использования таблиц.

clip_image002

CloudTableClient

Главная цель CloudTableClientпредоставление набора операций и их выполнение над облачным сервисом таблиц: получение списка таблиц в аккаунте, выполнение операций над таблицей, обновление записей и т.д.

TableRequestOptions

Класс TableRequestOptions предоставляет дополнительные параметры, определяющие контекст выполнения операции, обычно это таймаут и политики повторения, применяющиеся к каждому запросу. По умолчанию используются стандартные значения таймаута и политик повторения, для их переопределения необходимо использовать TableRequestOptions.

TableResult

Класс TableResult инкапсулирует результат одной операции над таблицей (TableOperation) и включает в себя код возрата HTTP, ETag и слаботипизированную ссылку на соответствующую сущность.

Actions

TableOperation

Класс TableOperation является отображением одной операции над таблицей: вставки, удаления, объединения, получения, insertOrReplace, insertOrMerge и других операций.

Пример вставки записи в таблицу:

//создание клиента для облачного сервиса

CloudTableClient tableClient = storageAccount.createCloudTableClient();

//создание таблицы в том случае, если ее не существует

tableClient.createTableIfNotExists("myTable");

// создание новой сущности.

MyEntity ent = new MyEntity ("1", "2");

ent.setFirst("1");

ent.setSecond("2");

// создание объекта TableOperation для выполнения операции вставки.

TableOperation insertMyEntity = TableOperation.insert(ent);

// подтверждение операции.

tableClient.execute("myTable", insertMyEntity);

TableBatchOperation

С помощьюTableBatchOperation можно объединять несколько объектов TableOperation и выполнять их в одно действие. Ограничения:

  • Можно batch-ить update, delete, insert, merge, replace.
  • Batch-операция может иметь операцию retrieve только если это единственная операция в batch.
  • Одна batch-операция может включать до 100 операций.
  • Все сущности в одной batch-операции должны иметь одинаковый partition key.
  • Batch-операция ограничена до 4Мб нагрузки данных.

Пример: вставка двух сущностей в одной batch-операции.

//создание клиента для облачного сервиса

CloudTableClient tableClient = storageAccount.createCloudTableClient();

// создание объекта TableBatchOperation для выполнения операций вставки.

TableBatchOperation batchOperation = new TableBatchOperation();

// создание новой сущности.

MyEntity ent = new MyEntity ("1", "2");

ent.setFirst("1");

ent.setSecond("2");

batchOperation.insert(ent);

MyEntity ent2 = new MyEntity ("3", "4");

ent.setFirst("3");

ent.setSecond("4”);

batchOperation.insert(ent2);

// подтверждение операции

tableClient.execute("myTable", batchOperation);

TableQuery

Класс TableQuery является отображением легковесного запроса.

Entities

TableEntity

Интерфейс TableEntity определяет объект, который может быть сериализован и десериализован с помощью клиента. Интерфейс содержит в себе аксессорные и мутаторные методы для PartitionKey, RowKey, Timestamp, Etag, а также методы чтения и записи сущности. Переопределив методы readEntity и writeEntity, пользователь может реализовать собственную логику сериализации.

TableServiceEntity

Класс TableServiceEntity реализует интерфейс TableEntity и содержит свойства RowKey, PartitionKey, Timestamp.

Пример: POCO, расширяющий TableServiceEntity

public class MyEntity extends TableServiceEntity {

private String MyProperty;

public String getMyProperty() {

return this.MyProperty;

}

public String setMyProperty (String MyProperty) {

this.MyProperty= MyProperty;

}

}

EntityProperty

EntityProperty инкапсулирует свойство сущности для дальнейшей сериализации или десериализации.

Пример: обновление свойства сущности

//получение свойства

TableResult tr = tableClient.execute("mytable", TableOperation.retrieve("Watson", "Dr", DynamicTableEntity.class));

DynamicTableEntity detective = tr.getResultAsType();

// получение нужного свойства

EntityProperty prop = tr.getProperties().get("pos");

prop.setValue(“Mr”);

// сохранение

tableClient.execute("mytable", TableOperation.merge(tr));

EntityResolver

Интерфейс EntityResolver определяет метод resolve и позволяет осуществлять обработку каждой сущности в течение сериализации или десериализации и спроектирован для дальнейшей реализации анонимным внутренним классом для реализации собственных проекций на клиентской стороне, фильтрации. Это позволяет реализовывать ключевые сценарии типа десериализации коллекции различных сущностей из одного запроса.

Пример: проекция на стороне клиента

// Определение запроса на возвращение свойства сущностей Email

TableQuery<MyEntity> query = TableQuery.from(tableName, Customer.class).select(new String[] { "Email" });

// Определение резольвера для внесения изменений в данные сущности

во время возвращения. В данном случае мы просто возвращаем строку E-Mail.

EntityResolver<String> emailResolver = new EntityResolver<String>() {

@Override

public String resolve(String PartitionKey, String RowKey, Date timeStamp, HashMap<String, EntityProperty> props, String etag) {

return props.get("Email").getValueAsString();

}

};

// Отображение результатов запроса.

При этом запрос возвращает строки вместо типов сущностей, так как String – тип нашего резольвера.

for (String projectedString : tableClient.execute(query, emailResolver)) {

System.out.println(projectedString);

}

Annotations

Аннотации необходимы для указания определенных правил для свойств.

@StoreAs

Аннотация @StoreAs указывает имя сериализованного свойства для необходимого свойства, если оно не указано – используется имя самого свойства. Эту аннотацию нельзя использовать с системными свойствами – оно будет просто проигнорировано. Данную аннотацию можно использовать для сокращения длины имени свойства для производительности либо для переназначения имени свойства.

Пример: изменение имени свойства

public class StoreAsEntity extends TableServiceEntity {

private String superLongNameOfEntityProperty;

@StoreAs(name = "slnoep")

public String getSuperLongNameOfEntityProperty() {

return this.superLongNameOfEntityProperty;

}

@StoreAs(name = "slnoep")

public void setSuperLongNameOfEntityProperty (String superLongNameOfEntityProperty) {

this.superLongNameOfEntityProperty= superLongNameOfEntityProperty;

}

}

@Ignore

@Ignore указывает сериализатору на то, что данное свойство не должно быть использовано для сериализации или десериализации.

Примеры запросов к таблицам

Возвращение одной сущности:

CloudTableClient tableClient = storageAccount.createCloudTableClient();

TableOperation retrieveSmithJeff = TableOperation.retrieve("Smith", "Jeff", CustomerEntity.class);

CustomerEntity specificEntity = tableClient.execute("people", retrieveSmithJeff).getResultAsType();

Запрос первых 10 сущностей со значением RowKey более 10

TableQuery<TableServiceEntity> query =

TableQuery.from(“myTable”, TableServiceEntity.class).

where(TableQuery.generateFilterCondition("RowKey", QueryComparisons.GREATER_THAN_OR_EQUAL, "10")).take(10);

Запрос всех сущностей со значением PartitionKey=”SamplePK” и значением RowKey более или равным “5”

String pkFilter = TableQuery.generateFilterCondition(TableConstants.PARTITION_KEY, QueryComparisons.EQUAL,"samplePK");

String rkFilter = TableQuery.generateFilterCondition(TableConstants.ROW_KEY, QueryComparisons.GREATER_THAN_OR_EQUAL, "5");

String combinedFilter = TableQuery.combineFilters(pkFilter, Operators.AND, rkFilter);

TableQuery<SampleEntity> query = TableQuery.from(tableName, SampleEntity.class).where(combinedFilter);

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: