Migrowanie aplikacji do korzystania z zestawu Java SDK usługi Azure Cosmos DB w wersji 4

DOTYCZY: NoSQL

Ważne

Aby uzyskać więcej informacji na temat tego zestawu SDK, zapoznaj się z informacjami o wersji zestawu Java SDK usługi Azure Cosmos DB w wersji 4, repozytorium Maven, wskazówkami dotyczącymi wydajności zestawu Java SDK w wersji 4 usługi Azure Cosmos DB i przewodnikiem rozwiązywania problemów z zestawem Java SDK usługi Azure Cosmos DB w wersji 4.

Ważne

Ponieważ zestaw Java SDK usługi Azure Cosmos DB w wersji 4 ma do 20% zwiększoną przepływność, tryb bezpośredni oparty na protokole TCP i obsługę najnowszych funkcji usługi zaplecza, zalecamy uaktualnienie do wersji 4 przy następnej okazji. Kontynuuj czytanie poniżej, aby dowiedzieć się więcej.

Przeprowadź aktualizację do najnowszego zestawu JAVA SDK usługi Azure Cosmos DB, aby uzyskać najlepsze informacje o tym, co usługa Azure Cosmos DB ma do zaoferowania — zarządzana usługa nierelacyjnej bazy danych o konkurencyjnej wydajności, dostępność pięciu dziewiątek, ład zasób jednego typu i nie tylko. W tym artykule wyjaśniono, jak uaktualnić istniejącą aplikację Java korzystającą ze starszego zestawu JAVA SDK usługi Azure Cosmos DB do nowszego zestawu Java SDK usługi Azure Cosmos DB 4.0 dla interfejsu API for NoSQL. Zestaw Java SDK usługi Azure Cosmos DB w wersji 4 odpowiada pakietowi com.azure.cosmos . Instrukcje podane w tym dokumencie można wykonać, jeśli migrujesz aplikację z dowolnego z następujących zestawów SDK Języka Java usługi Azure Cosmos DB:

  • Synchronizowanie zestawu Java SDK 2.x.x
  • Async Java SDK 2.x.x
  • Zestaw Java SDK 3.x.x

Mapowania pakietów i zestawu JAVA SDK usługi Azure Cosmos DB

W poniższej tabeli wymieniono różne zestawy SDK java usługi Azure Cosmos DB, nazwę pakietu i informacje o wersji:

Zestaw SDK Java Data wydania Powiązane interfejsy API Maven Jar Nazwa pakietu Java Dokumentacja interfejsu API Informacje o wersji Data wycofania
Async 2.x.x.x 2018 czerwca Async(RxJava) com.microsoft.azure::azure-cosmosdb com.microsoft.azure.cosmosdb.rx API Informacje o wersji sobota, 31 sierpnia 2024 r.
Synchronizacja 2.x.x Wrzesień 2018 r. Synchronizuj com.microsoft.azure::azure-documentdb com.microsoft.azure.cosmosdb API czwartek, 29 lutego 2024 r.
3.x.x Lipiec 2019 Async(Reactor)/Sync com.microsoft.azure::azure-cosmos com.azure.data.cosmos API - sobota, 31 sierpnia 2024 r.
4.0 Czerwiec 2020 Async(Reactor)/Sync com.azure::azure-cosmos com.azure.cosmos API - -

Zmiany implementacji na poziomie zestawu SDK

Poniżej przedstawiono kluczowe różnice implementacji między różnymi zestawami SDK:

Język RxJava jest zastępowany reaktorem w zestawie Java SDK usługi Azure Cosmos DB w wersji 3.x.x i 4.0

Jeśli nie znasz programowania asynchronicznego lub programowania reaktywnego, zapoznaj się z przewodnikiem po wzorcu Reactor, aby zapoznać się z wprowadzeniem do programowania asynchronicznego i projektu Reactor. Ten przewodnik może być przydatny, jeśli w przeszłości używasz zestawu Java SDK 2.x.x synchronizacji usługi Azure Cosmos DB lub zestawu Java SDK 3.x.x synchronizacji usługi Azure Cosmos DB.

Jeśli używasz zestawu Azure Cosmos DB Async Java SDK 2.x.x i planujesz migrację do zestawu SDK w wersji 4.0, zapoznaj się z przewodnikiem Reactor vs RxJava, aby uzyskać wskazówki dotyczące konwertowania kodu RxJava na korzystanie z biblioteki Reactor.

Zestaw Java SDK usługi Azure Cosmos DB w wersji 4 ma bezpośredni tryb łączności zarówno w interfejsach API asynchronicznych, jak i synchronizacji

Jeśli używasz zestawu Java SDK 2.x.x usługi Azure Cosmos DB, należy pamiętać, że tryb bezpośredniego połączenia na podstawie protokołu TCP (w przeciwieństwie do protokołu HTTP) jest implementowany w zestawie Java SDK 4.0 usługi Azure Cosmos DB dla interfejsów API asynchronicznych i synchronizacji.

Zmiany na poziomie interfejsu API

Poniżej przedstawiono zmiany na poziomie interfejsu API w zestawie Java SDK 4.x.x usługi Azure Cosmos DB w porównaniu z poprzednimi zestawami SDK (zestaw Java SDK 3.x.x, zestaw Async Java SDK 2.x.x i zestaw Java SDK synchronizacji 2.x.x):

Azure Cosmos DB Java SDK naming conventions

  • Zestaw Java SDK usługi Azure Cosmos DB w wersji 3.x.x i 4.0 odwołuje się do zasobów klienta jako Cosmos<resourceName>. Na przykład , CosmosClient, CosmosDatabase, CosmosContainer. Podczas gdy w wersji 2.x.x zestawy SDK języka Java usługi Azure Cosmos DB nie mają jednolitego schematu nazewnictwa.

  • Zestaw Java SDK 3.x.x i 4.0 usługi Azure Cosmos DB oferują zarówno interfejsy API synchronizacji, jak i asynchroniczne.

    • Zestaw Java SDK 4.0 : wszystkie klasy należą do interfejsu API synchronizacji, chyba że nazwa klasy zostanie dołączona Async po Cosmos.

    • Zestaw Java SDK 3.x.x: wszystkie klasy należą do interfejsu API asynchronicznego, chyba że nazwa klasy zostanie dołączona Async po Cosmos.

    • Async Java SDK 2.x.x: Nazwy klas są podobne do synchronizowania zestawu Java SDK 2.x.x, jednak nazwa zaczyna się od Async.

Hierarchiczna struktura interfejsu API

Zestaw Java SDK usługi Azure Cosmos DB w wersji 4.0 i 3.x.x wprowadza hierarchiczną strukturę interfejsu API, która organizuje klientów, bazy danych i kontenery w sposób zagnieżdżony, jak pokazano w poniższym fragmencie kodu zestawu SDK w wersji 4.0:

CosmosContainer container = client.getDatabase("MyDatabaseName").getContainer("MyContainerName");

W wersji 2.x zestawu Java SDK usługi Azure Cosmos DB wszystkie operacje na zasobach i dokumentach są wykonywane za pośrednictwem wystąpienia klienta.

Reprezentowanie dokumentów

W zestawie Java SDK 4.0 usługi Azure Cosmos DB niestandardowe operacje POJO i JsonNodes są dwiema opcjami odczytywania i zapisywania dokumentów z usługi Azure Cosmos DB.

W zestawie Java SDK usługi Azure Cosmos DB w wersji 3.x.x CosmosItemProperties obiekt jest udostępniany przez publiczny interfejs API i służył jako reprezentacja dokumentu. Ta klasa nie jest już uwidoczniona publicznie w wersji 4.0.

Operacje importu

  • Pakiety zestawu Java SDK 4.0 usługi Azure Cosmos DB zaczynają się od com.azure.cosmos

  • Pakiety zestawu Java SDK 3.x.x usługi Azure Cosmos DB zaczynają się od com.azure.data.cosmos

  • Pakiety interfejsu API synchronizacji zestawu Java SDK 2.x.x usługi Azure Cosmos DB zaczynają się od com.microsoft.azure.documentdb

  • Zestaw Java SDK usługi Azure Cosmos DB 4.0 umieszcza kilka klas w zagnieżdżonym pakiecie com.azure.cosmos.models. Niektóre z tych pakietów to:

    • CosmosContainerResponse
    • CosmosDatabaseResponse
    • CosmosItemResponse
    • Analogia interfejsu API asynchronicznego dla wszystkich powyższych pakietów
    • CosmosContainerProperties
    • FeedOptions
    • PartitionKey
    • IndexingPolicy
    • IndexingMode ... Itp.

Akcesorów

Zestaw Java SDK usługi Azure Cosmos DB w wersji 4.0 uwidacznia get i set metody uzyskiwania dostępu do elementów członkowskich wystąpienia. Na przykład CosmosContainer wystąpienie ma container.getId() metody i container.setId() .

Różni się to od zestawu Java SDK usługi Azure Cosmos DB 3.x.x, który uwidacznia płynny interfejs. Na przykład CosmosSyncContainer wystąpienie ma container.id() przeciążone, aby pobrać lub ustawić id wartość.

Porównania fragmentów kodu

Tworzenie zasobów

Poniższy fragment kodu przedstawia różnice w sposobie tworzenia zasobów między interfejsami API 4.0, 3.x.x.x, 2.x.x Sync i 2.x.x Async:


// Create Async client.
// Building an async client is still a sync operation.
CosmosAsyncClient client = new CosmosClientBuilder()
        .endpoint("your.hostname")
        .key("yourmasterkey")
        .consistencyLevel(ConsistencyLevel.EVENTUAL)
        .buildAsyncClient();

// Create database with specified name
client.createDatabaseIfNotExists("YourDatabaseName")
        .flatMap(databaseResponse -> {
            testDatabaseAsync = client.getDatabase("YourDatabaseName");
            // Container properties - name and partition key
            CosmosContainerProperties containerProperties =
                    new CosmosContainerProperties("YourContainerName", "/id");

            // Provision manual throughput
            ThroughputProperties throughputProperties = ThroughputProperties.createManualThroughput(400);

            // Create container
            return database.createContainerIfNotExists(containerProperties, throughputProperties);
        }).flatMap(containerResponse -> {
    testContainerAsync = database.getContainer("YourContainerName");
    return Mono.empty();
}).subscribe();

Operacje na elementach

Poniższy fragment kodu pokazuje różnice w sposobie wykonywania operacji elementów między interfejsami API 4.0, 3.x.x.x, 2.x.x Sync i 2.x.x Async:


// Container is created. Generate many docs to insert.
int number_of_docs = 50000;
ArrayList<JsonNode> docs = generateManyDocs(number_of_docs);

// Insert many docs into container...
Flux.fromIterable(docs)
        .flatMap(doc -> testContainerAsync.createItem(doc))
        .subscribe(); // ...Subscribing triggers stream execution.

Indeksowanie

Poniższy fragment kodu przedstawia różnice w tworzeniu indeksowania między interfejsami API 4.0, 3.x.x.x, 2.x.x Sync i 2.x.x Async:


CosmosContainerProperties containerProperties = new CosmosContainerProperties(containerName, "/lastName");

// Custom indexing policy
IndexingPolicy indexingPolicy = new IndexingPolicy();
indexingPolicy.setIndexingMode(IndexingMode.CONSISTENT);

// Included paths
List<IncludedPath> includedPaths = new ArrayList<>();
includedPaths.add(new IncludedPath("/*"));
indexingPolicy.setIncludedPaths(includedPaths);

// Excluded paths
List<ExcludedPath> excludedPaths = new ArrayList<>();
excludedPaths.add(new ExcludedPath("/name/*"));
indexingPolicy.setExcludedPaths(excludedPaths);

containerProperties.setIndexingPolicy(indexingPolicy);

ThroughputProperties throughputProperties = ThroughputProperties.createManualThroughput(400);

database.createContainerIfNotExists(containerProperties, throughputProperties);
CosmosAsyncContainer containerIfNotExists = database.getContainer(containerName);

Procedury składowane

Poniższy fragment kodu pokazuje różnice w tworzeniu procedur składowanych między interfejsami API 4.0, 3.x.x.x, 2.x.x Sync i 2.x.x Async:


logger.info("Creating stored procedure...\n");

String sprocId = "createMyDocument";

String sprocBody = "function createMyDocument() {\n" +
        "var documentToCreate = {\"id\":\"test_doc\"}\n" +
        "var context = getContext();\n" +
        "var collection = context.getCollection();\n" +
        "var accepted = collection.createDocument(collection.getSelfLink(), documentToCreate,\n" +
        "    function (err, documentCreated) {\n" +
        "if (err) throw new Error('Error' + err.message);\n" +
        "context.getResponse().setBody(documentCreated.id)\n" +
        "});\n" +
        "if (!accepted) return;\n" +
        "}";

CosmosStoredProcedureProperties storedProcedureDef = new CosmosStoredProcedureProperties(sprocId, sprocBody);
container.getScripts()
        .createStoredProcedure(storedProcedureDef,
                new CosmosStoredProcedureRequestOptions()).block();

// ...

logger.info(String.format("Executing stored procedure %s...\n\n", sprocId));

CosmosStoredProcedureRequestOptions options = new CosmosStoredProcedureRequestOptions();
options.setPartitionKey(new PartitionKey("test_doc"));

container.getScripts()
        .getStoredProcedure(sprocId)
        .execute(null, options)
        .flatMap(executeResponse -> {
            logger.info(String.format("Stored procedure %s returned %s (HTTP %d), at cost %.3f RU.\n",
                    sprocId,
                    executeResponse.getResponseAsString(),
                    executeResponse.getStatusCode(),
                    executeResponse.getRequestCharge()));
            return Mono.empty();
        }).block();

Źródło zmian

Poniższy fragment kodu pokazuje różnice w sposobie wykonywania operacji zestawienia zmian między interfejsami API 4.0 i 3.x.x.x:


ChangeFeedProcessor changeFeedProcessorInstance =
        new ChangeFeedProcessorBuilder()
                .hostName(hostName)
                .feedContainer(feedContainer)
                .leaseContainer(leaseContainer)
                .handleChanges((List<JsonNode> docs) -> {
                    logger.info("--->setHandleChanges() START");

                    for (JsonNode document : docs) {
                        try {
                            //Change Feed hands the document to you in the form of a JsonNode
                            //As a developer you have two options for handling the JsonNode document provided to you by Change Feed
                            //One option is to operate on the document in the form of a JsonNode, as shown below. This is great
                            //especially if you do not have a single uniform data model for all documents.
                            logger.info("---->DOCUMENT RECEIVED: " + OBJECT_MAPPER.writerWithDefaultPrettyPrinter()
                                    .writeValueAsString(document));

                            //You can also transform the JsonNode to a POJO having the same structure as the JsonNode,
                            //as shown below. Then you can operate on the POJO.
                            CustomPOJO pojo_doc = OBJECT_MAPPER.treeToValue(document, CustomPOJO.class);
                            logger.info("----=>id: " + pojo_doc.getId());

                        } catch (JsonProcessingException e) {
                            e.printStackTrace();
                        }
                    }
                    logger.info("--->handleChanges() END");

                })
                .buildChangeFeedProcessor();

// ...

changeFeedProcessorInstance.start()
        .subscribeOn(Schedulers.elastic())
        .subscribe();

Czas wygaśnięcia na poziomie kontenera (TTL)

Poniższy fragment kodu pokazuje różnice w sposobie tworzenia czasu wygaśnięcia danych w kontenerze między 4.0, 3.x.x Async, 2.x.x Sync i 2.x.x Async API:


CosmosAsyncContainer container;

// Create a new container with TTL enabled with default expiration value
CosmosContainerProperties containerProperties = new CosmosContainerProperties("myContainer", "/myPartitionKey");
containerProperties.setDefaultTimeToLiveInSeconds(90 * 60 * 60 * 24);
ThroughputProperties throughputProperties = ThroughputProperties.createManualThroughput(400);
database.createContainerIfNotExists(containerProperties, throughputProperties).block();
container = database.getContainer("myContainer");

Czas wygaśnięcia na poziomie elementu (TTL)

Poniższy fragment kodu pokazuje różnice w sposobie tworzenia czasu wygaśnięcia dla elementu między 4.0, 3.x.x Async, 2.x.x Sync i 2.x.x Async api:


// Include a property that serializes to "ttl" in JSON
class SalesOrder
{
    private String id;
    private String customerId;
    private Integer ttl;

    public SalesOrder(String id, String customerId, Integer ttl) {
        this.id = id;
        this.customerId = customerId;
        this.ttl = ttl;
    }

    public String getId() {return this.id;}
    public void setId(String new_id) {this.id = new_id;}
    public String getCustomerId() {return this.customerId;}
    public void setCustomerId(String new_cid) {this.customerId = new_cid;}
    public Integer getTtl() {return this.ttl;}
    public void setTtl(Integer new_ttl) {this.ttl = new_ttl;}

    //...
}


// Set the value to the expiration in seconds
SalesOrder salesOrder = new SalesOrder(
        "SO05",
        "CO18009186470",
        60 * 60 * 24 * 30  // Expire sales orders in 30 days
);

Następne kroki