Megosztás:


Az alkalmazás migrálása az Azure Cosmos DB Java SDK v4 használatára

Fontos

Az SDK-val kapcsolatos további információkért tekintse meg az Azure Cosmos DB Java SDK v4 kibocsátási megjegyzéseit, a Maven-adattárat, az Azure Cosmos DB Java SDK v4 teljesítménytippeket és az Azure Cosmos DB Java SDK v4 hibaelhárítási útmutatóját.

Fontos

Mivel az Azure Cosmos DB Java SDK 4-ben legfeljebb 20% továbbfejlesztett átviteli sebesség, TCP-alapú közvetlen mód és a legújabb háttérszolgáltatás-funkciók támogatása érhető el, javasoljuk, hogy a következő lehetőségnél frissítsen a v4-re. További információért olvassa el az alábbi szakaszt.

Frissítsen a legújabb Azure Cosmos DB Java SDK-ra, hogy a lehető legjobban ki tudja használni az Azure Cosmos DB által kínált lehetőségeket – egy felügyelt, nem kapcsolódó adatbázis-szolgáltatást versenyképes teljesítménnyel, öt-kilences rendelkezésre állással, egy-egy típusú erőforrás-szabályozással és egyebekkel. Ez a cikk bemutatja, hogyan frissítheti meglévő Java-alkalmazását, amely egy régebbi Azure Cosmos DB Java SDK-t használ az újabb Azure Cosmos DB Java SDK 4.0 for API for NoSQL-re. Az Azure Cosmos DB Java SDK v4 a com.azure.cosmos csomagnak felel meg. A dokumentum utasításait akkor használhatja, ha az alkalmazást az alábbi Azure Cosmos DB Java SDK-k bármelyikéből migrálja:

  • Java SDK szinkronizálása 2.x.x
  • Async Java SDK 2.x.x
  • Java SDK 3.x.x

Azure Cosmos DB Java SDK-k és csomagleképezések

Az alábbi táblázat felsorolja a különböző Azure Cosmos DB Java SDK-kat, a csomag nevét és a kiadási információkat:

Java SDK Kiadás dátuma Csomagolt API-k Maven Jar Java-csomag neve API-referencia Kibocsátási megjegyzések Kivonás dátuma
Async 2.x.x 2018. június Async(RxJava) com.microsoft.azure::azure-cosmosdb com.microsoft.azure.cosmosdb.rx API Kibocsátási megjegyzések 2024. augusztus 31., szombat
Szinkronizálás 2.x.x 2018. szeptember Szinkronizálás com.microsoft.azure::azure-documentdb com.microsoft.azure.cosmosdb API 2024. február 29.
3.x.x 2019. július Async(Reactor)/Sync com.microsoft.azure::azure-cosmos com.azure.data.cosmos API - 2024. augusztus 31., szombat
4,0 2020. június Aszinkron(Reaktor)/Szinkron com.azure::azure-cosmos com.azure.cosmos API - -

SDK-szintű implementáció változásai

A különböző SDK-k közötti főbb megvalósítási különbségek a következők:

Az RxJava-t a reactor váltja fel az Azure Cosmos DB Java SDK 3.x.x és 4.0-s verzióiban.

Ha nem ismeri az aszinkron programozást vagy a reaktív programozást, tekintse meg a Reactor mintaútmutatóját az aszinkron programozás és a Project Reactor bemutatásához. Ez az útmutató akkor lehet hasznos, ha korábban az Azure Cosmos DB Sync Java SDK 2.x.x vagy az Azure Cosmos DB Java SDK 3.x.x Sync API-t használta.

Ha az Azure Cosmos DB Async Java SDK 2.x.x-et használja, és a 4.0 SDK-ra való migrálást tervezi, tekintse meg a Reactor vs RxJava útmutatót az RxJava-kód Reactor használatára való konvertálásával kapcsolatban.

Az Azure Cosmos DB Java SDK v4 közvetlen kapcsolati móddal rendelkezik mind az Async, mind a Sync API-kban

Ha az Azure Cosmos DB Sync Java SDK 2.x.x-et használja, vegye figyelembe, hogy a TCP-n alapuló közvetlen kapcsolati mód (a HTTP helyett) az Azure Cosmos DB Java SDK 4.0-s verziójában van implementálva az Async és a Sync API-k esetében is.

API-szintű változások

Az azure Cosmos DB Java SDK 4.x.x api-szintű változásai a korábbi SDK-khoz képest (Java SDK 3.x.x, Async Java SDK 2.x.x és Sync Java SDK 2.x.x):

Azure Cosmos DB Java SDK elnevezési konvenciók

  • Az Azure Cosmos DB Java SDK 3.x.x és 4.0 az ügyfélerőforrásokat a következőképpen tekinti Cosmos<resourceName>. Például, CosmosClient, CosmosDatabase. CosmosContainer Míg a 2.x.x verzióban az Azure Cosmos DB Java SDK-k nem rendelkeznek egységes elnevezési sémával.

  • Az Azure Cosmos DB Java SDK 3.x.x és 4.0 szinkronizálási és Async API-kat is kínál.

    • Java SDK 4.0 : Az összes osztály a Sync API-hoz tartozik, kivéve, ha az osztály neve hozzá van fűzve Async utána Cosmos.

    • Java SDK 3.x.x: Az összes osztály az Async API-hoz tartozik, kivéve, ha az osztály neve hozzá van fűzve Async utána Cosmos.

    • Aszinkron Java SDK 2.x.x: Az osztálynevek hasonlóak a Sync Java SDK 2.x.x-hez, de a név az Asynctel kezdődik.

Hierarchikus API-struktúra

Az Azure Cosmos DB Java SDK 4.0-s és 3.x.x-es verziójában hierarchikus API-struktúra jelenik meg, amely beágyazott módon rendszerezi az ügyfeleket, az adatbázisokat és a tárolókat, ahogyan az a következő 4.0 SDK-kódrészletben látható:

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

Az Azure Cosmos DB Java SDK 2.x.x verziójában az erőforrásokon és dokumentumokon végzett összes művelet az ügyfélpéldányon keresztül történik.

Dokumentumok reprezentálása

Az Azure Cosmos DB Java SDK 4.0 esetében az egyéni POJO-k és a JsonNodes két lehetőséget jelentenek a dokumentumok Azure Cosmos DB-ben való olvasására és írására.

Az Azure Cosmos DB Java SDK 3.x.x.x verziójában az CosmosItemProperties objektumot a nyilvános API teszi elérhetővé, és dokumentumábrázolásként szolgál. Ez az osztály már nem érhető el nyilvánosan a 4.0-s verzióban.

Importálások

  • Az Azure Cosmos DB Java SDK 4.0-s csomagjai a következővel kezdődnek: com.azure.cosmos

  • Az Azure Cosmos DB Java SDK 3.x.x csomagjai a következővel kezdődnek: com.azure.data.cosmos

  • Az Azure Cosmos DB Java SDK 2.x.x Sync API-csomagok a következővel kezdődnek: com.microsoft.azure.documentdb

  • Az Azure Cosmos DB Java SDK 4.0 több osztályt helyez el egy beágyazott csomagban com.azure.cosmos.models. A csomagok némelyike a következőket tartalmazza:

    • CosmosContainerResponse
    • CosmosDatabaseResponse
    • CosmosItemResponse
    • Az Async API analógjai az összes fenti csomaghoz
    • CosmosContainerProperties
    • FeedOptions
    • PartitionKey
    • IndexingPolicy
    • IndexingMode ... stb.

Accessors

Az Azure Cosmos DB Java SDK 4.0 a példánytagok elérésére szolgáló get és set metódusokat teszi elérhetővé. Például a CosmosContainer példány rendelkezik container.getId() és container.setId() metódusokkal.

Ez eltér az Azure Cosmos DB Java SDK 3.x.x-től, amely egy folyékony felületet tesz elérhetővé. Például egy CosmosSyncContainer példány esetén a container.id() túl van terhelve, hogy lekérje vagy beállítsa a id értékét.

Függőségi ütközések kezelése

Az Azure Cosmos DB Java SDK V2-ről v4-re való frissítés függőségi ütközéseket okozhat az SDK által használt kódtárak változásai miatt. Ezeknek az ütközéseknek a feloldása a függőségek gondos kezelését igényli.

  1. Az új függőségek ismertetése: Az Azure Cosmos DB V4 SDK saját függőségekkel rendelkezik, amelyek eltérhetnek a korábbi verziókban használt függőségektől. Győződjön meg arról, hogy tisztában van a következő függőségekkel:

    • azure-cosmos
    • reactor-core
    • reactor-netty
    • netty-handler
    • guava
    • slf4j-api
    • jackson-databind
    • jackson-annotations
    • jackson-core
    • commons-lang3
    • commons-collections4
    • azure-core
    • azure-core-http-netty
  2. Ütköző függőségek eltávolítása: Először távolítsa el az SDK korábbi verzióihoz kapcsolódó függőségeket a pom.xml fájlból. Ezek közé tartozik a azure-cosmosdb komponens, valamint a régi SDK valószínű transzitív függőségei.

  3. V4 SDK-függőségek hozzáadása: Adja hozzá a V4 SDK-t és annak függőségeit a sajátjához pom.xml. Íme egy példa:

    <dependency>
        <groupId>com.azure</groupId>
        <artifactId>azure-cosmos</artifactId>
        <version>4.x.x</version> <!-- Use the latest version available -->
    </dependency>
    
  4. Függőségi ütközések keresése: A Maven dependency:tree paranccsal hozzon létre egy függőségi fát, és azonosítsa az ütközéseket. Indítás:

    mvn dependency:tree
    

    Keresse meg a függőségek ütköző verzióit. Ezek az ütközések gyakran fordulnak elő olyan kódtárakkal, mint a reactor-core, netty-handler, guavaés jackson.

  5. Függőségkezelés használata: Ha verzióütközéseket tapasztal, előfordulhat, hogy felül kell írnia a problémás verziókat a <dependencyManagement> szakaszban pom.xml. Íme egy példa egy adott verziójának kényszerítésére reactor-core:

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>io.projectreactor</groupId>
                <artifactId>reactor-core</artifactId>
                <version>3.x.x</version> <!-- Use a compatible version -->
            </dependency>
            <!-- Repeat for any other conflicting dependencies -->
        </dependencies>
    </dependencyManagement>
    
  6. Tranzitív függőségek kizárása: Előfordulhat, hogy ki kell zárnia a más függőségek által létrehozott tranzitív függőségeket. Ha például egy másik kódtár egy ütközést okozó függőség régebbi verzióját hozza létre, a következő módon zárhatja ki:

    <dependency>
        <groupId>some.group</groupId>
        <artifactId>some-artifact</artifactId>
        <version>x.x.x</version>
        <exclusions>
            <exclusion>
                <groupId>conflicting.group</groupId>
                <artifactId>conflicting-artifact</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    
  7. Újraépítés és tesztelés: A módosítások elvégzése után újraépítse a projektet, és alaposan tesztelje, hogy az új függőségek megfelelően működjenek, és hogy ne forduljanak elő futásidejű ütközések.

Kódrészletek összehasonlítása

Erőforrások létrehozása

Az alábbi kódrészlet a 4.0, 3.x.x Async, 2.x.x Szinkronizálás és 2.x.x Async API-k közötti erőforrások létrehozásának különbségeit mutatja be:


// 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();

Elemműveletek

A következő kódrészlet a 4.0, 3.x.x Async, 2.x.x Szinkronizálás és 2.x.x Async API-k közötti elemműveletek végrehajtásának különbségeit mutatja be:


// 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.

Indexelés

Az alábbi kódrészlet a 4.0, 3.x.x Async, 2.x.x Szinkronizálás és 2.x.x Async API-k közötti indexelés létrehozásának különbségeit mutatja be:


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);

Tárolt eljárások

Az alábbi kódrészlet a tárolt eljárások létrehozásának különbségeit mutatja be a 4.0, a 3.x.x Async, a 2.x.x Sync és a 2.x.x Async API-k között:


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();

Változásértesítés

Az alábbi kódrészlet a változáscsatorna-műveletek 4.0 és 3.x.x Async API-k közötti végrehajtásának különbségeit mutatja be:


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.boundedElastic())
        .subscribe();

Tárolószintű élettartam (TTL)

Az alábbi kódrészlet bemutatja a tárolóban lévő adatok élettartamának létrehozására vonatkozó különbségeket a 4.0, 3.x.x Async, 2.x.x Sync és 2.x.x Async API-k között.


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");

Elemszintű élettartam(TTL)

Az alábbi kódrészlet bemutatja az eltéréseket abban, hogyan lehet élettartamot létrehozni egy elemhez a 4.0, 3.x.x aszinkron, valamint a 2.x.x szinkron és aszinkron API-k esetében.


// 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
);

Következő lépések