Migración de la aplicación para usar el SDK de Azure Cosmos DB para Java v4
SE APLICA A: NoSQL
Importante
Para más información acerca de este SKD, consulte las notas de la versión del SDK de Azure Cosmos DB para Java v4, el repositorio de Maven, las sugerencias de rendimiento del SDK de Azure Cosmos DB para Java v4 y la guía de solución de problemas del SDK de Azure Cosmos DB para Java v4.
Importante
Como la versión 4 del SDK de Java de Azure Cosmos DB tiene un rendimiento mejorado de hasta un 20 %, el modo directo basado en TCP, así como compatibilidad con las características más recientes del servicio back-end, se recomienda actualizar a la versión 4 en la siguiente oportunidad. Siga leyendo a continuación para obtener más información.
Actualice al SDK de Java de Azure Cosmos DB más reciente para obtener lo mejor que ofrece Azure Cosmos DB: un servicio de base de datos no relacional administrado con rendimiento competitivo, disponibilidad de "cinco 9", gobernanza de recursos únicos, etc. Este artículo explica cómo actualizar la aplicación de Java existente mediante el uso del SDK de Java más antiguo de Azure Cosmos DB a la versión más reciente del SDK de Java 4.0 de Azure Cosmos DB para la API para NoSQL. SDK de Azure Cosmos DB para Java v4 se corresponde con el paquete com.azure.cosmos
. Puede usar las instrucciones de este documento si va a migrar la aplicación desde cualquiera de los siguientes SDK de Azure Cosmos DB para Java:
- SDK de Java 2.x.x sincrónico
- SDK de Java 2.x.x asincrónico
- SDK de Java 3.x.x
SDK de Azure Cosmos DB para Java y de las asignaciones de paquetes
En la tabla siguiente se enumeran diferentes SDK de Azure Cosmos DB para Java, el nombre del paquete y la información de la versión:
SDK de Java | Fecha de la versión | API agrupadas | Jar de Maven | Nombre del paquete de Java | Referencia de API | Notas de la versión | Fecha de retirada |
---|---|---|---|---|---|---|---|
Asincrónico 2.x.x | Junio de 2018 | Asincrónico (RxJava) | com.microsoft.azure::azure-cosmosdb |
com.microsoft.azure.cosmosdb.rx |
API | Notas de la versión | 31 de agosto de 2024 |
Sincrónico 2.x.x | Septiembre de 2018 | Sync | com.microsoft.azure::azure-documentdb |
com.microsoft.azure.cosmosdb |
API | 29 de febrero de 2024 | |
3.x.x | Julio de 2019 | Asincrónico (reactor)/Sincrónico | com.microsoft.azure::azure-cosmos |
com.azure.data.cosmos |
API | - | 31 de agosto de 2024 |
4.0 | Junio de 2020 | Asincrónico (reactor)/Sincrónico | com.azure::azure-cosmos |
com.azure.cosmos |
API | - | - |
Cambios de implementación de nivel de SDK
A continuación se enumeran las diferencias de implementación clave entre los distintos SDK:
RxJava se reemplaza por reactor en el SDK de Azure Cosmos DB para Java versiones 3.x. x y 4.0
Si no está familiarizado con la programación asincrónica o la programación reactiva, consulte la Guía de patrones reactores para ver una introducción a la programación asincrónica y el reactor del proyecto. Esta guía puede ser útil si ha estado usando el SDK de Azure Cosmos DB para Java sincrónico 2.x.x o la API del SDK de Azure Cosmos DB para Java sincrónico 3.x.x en el pasado.
Si ha usado el SDK de Azure Cosmos DB para Java asincrónico 2.x.x y tiene previsto migrar al SDK de 4.0, consulte la guía Reactor vs RxJava para obtener instrucciones sobre cómo convertir el código RxJava para usar el reactor.
El SDK de Azure Cosmos DB para Java v4 tiene el modo de conectividad directa en las API asincrónica y de sincronización
Si ha usado el SDK de Azure Cosmos DB para Java sincrónico 2.x.x, tenga en cuenta que el modo de conexión directa basado en TCP (en lugar de HTTP) se implementa en el SDK de Azure Cosmos DB para Java 4.0 para las API asincrónica y de sincronización.
Cambios en el nivel de API
A continuación se muestran los cambios de nivel de API en el SDK de Azure Cosmos DB para Java 4.x.x en comparación con los SDK anteriores (SDK de Java 3.x.x, SDK de Java asincrónico 2.x.x y SDK de Java sincrónico 2.x.x):
El SDK de Azure Cosmos DB para Java 3.x.x y 4.0 hacen referencia a los recursos de cliente como
Cosmos<resourceName>
. Por ejemplo:CosmosClient
,CosmosDatabase
yCosmosContainer
. Mientras que en la versión 2.x.x, los SDK de Azure Cosmos DB para Java no tienen un esquema de nomenclatura uniforme.El SDK de Azure Cosmos DB para Java 3.x.x y 4.0 ofrecen API de sincronización y asincrónica.
SDK de Java 4.0: Todas las clases pertenecen a la API de sincronización a menos que el nombre de clase se anexe con
Async
después deCosmos
.SDK de Java 3.x.x: Todas las clases pertenecen a la API asincrónica a menos que el nombre de clase se anexe con
Async
después deCosmos
.SDK de Java 2.x.x asincrónico: Los nombres de clase son similares a SDK de Java 2.x.x sincrónico, aunque el nombre comienza con Asincrónico.
Estructura jerárquica de la API
El SDK de Azure Cosmos DB para Java 4,.0 y 3.x.x introducen una estructura jerárquica de API que organiza los clientes, las bases de datos y los contenedores de manera anidada, tal y como se muestra en el siguiente fragmento de código del SDK de 4.0:
CosmosContainer container = client.getDatabase("MyDatabaseName").getContainer("MyContainerName");
En la versión 2.x.x de Java del SDK de Azure Cosmos DB, todas las operaciones en recursos y documentos se realizan a través de la instancia de cliente.
Representar documentos
En el SDK de Azure Cosmos DB para Java 4.0, los POJO y JsonNodes
personalizados son las dos opciones para leer y escribir los documentos desde Azure Cosmos DB.
En el SDK de Azure Cosmos DB para Java 3.x.x, el objeto CosmosItemProperties
se expone mediante la API pública y se sirve como una representación del documento. Esta clase ya no se expone públicamente en la versión 4.0.
Importaciones
Los paquetes de SDK de Azure Cosmos DB para Java 4.0 comienzan por
com.azure.cosmos
Los paquetes de SDK de Azure Cosmos DB para Java 3.x.x comienzan por
com.azure.data.cosmos
Los paquetes de API sincrónica del SDK de Azure Cosmos DB para Java 2.x.x comienzan por
com.microsoft.azure.documentdb
SDK de Azure Cosmos DB para Java 4.0 coloca varias clases en un
com.azure.cosmos.models
de paquetes anidados. Algunos de estos paquetes incluyen:CosmosContainerResponse
CosmosDatabaseResponse
CosmosItemResponse
- Los análogos de la API asincrónica para todos los paquetes anteriores
CosmosContainerProperties
FeedOptions
PartitionKey
IndexingPolicy
IndexingMode
... etc.
Descriptores de acceso
El SDK de Azure Cosmos DB para Java 4.0 expone los métodos get
y set
para tener acceso a los miembros de instancia. Por ejemplo, la instancia CosmosContainer
tiene métodos container.getId()
y container.setId()
.
Esto es diferente del SDK de Azure Cosmos DB para Java 3.x.x, que expone una interfaz fluida. Por ejemplo, una instancia CosmosSyncContainer
tiene container.id()
que está sobrecargada para obtener o establecer el valor id
.
Administración de conflictos de dependencias
La actualización del SDK de Java V2 a V4 de Azure Cosmos DB puede introducir conflictos de dependencia debido a cambios en las bibliotecas usadas por el SDK. La resolución de estos conflictos requiere una administración cuidadosa de las dependencias.
Comprender las nuevas dependencias: El SDK de Azure Cosmos DB V4 tiene su propio conjunto de dependencias que podrían ser diferentes de las de versiones anteriores. Asegúrese de que conoce estas dependencias:
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
Quitar dependencias en conflicto: Empiece por quitar las dependencias relacionadas con versiones anteriores del SDK del archivo
pom.xml
. Estos incluyenazure-cosmosdb
y las dependencias transitivas que podría haber tenido el SDK anterior.Agregar dependencias del SDK V4: Agregue el SDK V4 y sus dependencias a la
pom.xml
. Este es un ejemplo:<dependency> <groupId>com.azure</groupId> <artifactId>azure-cosmos</artifactId> <version>4.x.x</version> <!-- Use the latest version available --> </dependency>
Buscar conflictos de dependencia: Use el comando Maven
dependency:tree
para generar un árbol de dependencias e identificar los conflictos. Ejecute:mvn dependency:tree
Busque las versiones en conflicto de las dependencias. Estos conflictos a menudo se producen con bibliotecas como
reactor-core
,netty-handler
,guava
, yjackson
.Use Dependency Management: Si se producen conflictos de versiones, es posible que tenga que invalidar las versiones problemáticas mediante la
<dependencyManagement>
sección de lapom.xml
. Este es un ejemplo para aplicar una versión específica dereactor-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>
Excluir dependencias transitivas: A veces, es posible que tenga que excluir las dependencias transitivas que han traído otras dependencias. Por ejemplo, si otra biblioteca incluye una versión anterior de una dependencia que entra en conflicto, puede excluirla de la siguiente manera:
<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>
Recompilar y probar: Después de realizar estos cambios, recompile el proyecto y pruébelo exhaustivamente para asegurarse de que las nuevas dependencias funcionan correctamente y que no se producen conflictos en tiempo de ejecución.
Comparaciones de fragmentos de código
Crear recursos
En el fragmento de código siguiente se muestran las diferencias en el modo de crear los recursos entre las API 4.0, 3.x.x (asincrónica), 2.x.x (sincrónica) y 2.x.x (asincrónica):
- API asincrónica del SDK de Java 4.0
- API asincrónica del SDK de Java 3.x.x
- API sincrónica del SDK de Java 2.x.x
- API asincrónica del SDK de Java 2.x.x
// 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();
Operaciones de elemento
En el fragmento de código siguiente se muestran las diferencias en el modo de realizar las operaciones de elementos entre las API 4.0, 3.x.x (asincrónica), 2.x.x (sincrónica) y 2.x.x (asincrónica):
- API asincrónica del SDK de Java 4.0
- API asincrónica del SDK de Java 3.x.x
- API sincrónica del SDK de Java 2.x.x
- API asincrónica del SDK de Java 2.x.x
// 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.
Indización
En el fragmento de código siguiente se muestran las diferencias en el modo de crear la indexación entre las API 4.0, 3.x.x (asincrónica), 2.x.x (sincrónica) y 2.x.x (asincrónica):
- API asincrónica del SDK de Java 4.0
- API asincrónica del SDK de Java 3.x.x
- API sincrónica del SDK de Java 2.x.x
- API asincrónica del SDK de Java 2.x.x
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);
Procedimientos almacenados
En el fragmento de código siguiente se muestran las diferencias en el modo de crear procedimientos almacenados entre las API 4.0, 3.x.x (asincrónica), 2.x.x (sincrónica) y 2.x.x (asincrónica):
- API asincrónica del SDK de Java 4.0
- API asincrónica del SDK de Java 3.x.x
- API sincrónica del SDK de Java 2.x.x
- API asincrónica del SDK de Java 2.x.x
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();
Fuente de cambios
En el fragmento de código siguiente se muestran las diferencias en el modo en que se ejecutan las operaciones de fuente de cambios entre las API asincrónicas 4.0 y 3.x.x:
- API asincrónica del SDK de Java 4.0
- API asincrónica del SDK de Java 3.x.x
- API sincrónica del SDK de Java 2.x.x
- API asincrónica del SDK de Java 2.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();
Período de vida (TTL) de nivel de contenedor
En el siguiente fragmento de código se muestran las diferencias en la forma de crear el período de vida de los datos en el contenedor entre las API 4.0, 3.x.x (asincrónica), 2.x.x (sincrónica) y 2.x.x (asincrónica):
- API asincrónica del SDK de Java 4.0
- API asincrónica del SDK de Java 3.x.x
- API sincrónica del SDK de Java 2.x.x
- API asincrónica del SDK de Java 2.x.x
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");
Período de vida (TTL) de nivel de elemento
En el siguiente fragmento de código se muestran las diferencias en la forma de crear el período de vida para un elemento entre las API 4.0, 3.x.x (asincrónica), 2.x.x (sincrónica) y 2.x.x (asincrónica):
- API asincrónica del SDK de Java 4.0
- API asincrónica del SDK de Java 3.x.x
- API sincrónica del SDK de Java 2.x.x
- API asincrónica del SDK de Java 2.x.x
// 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
);
Pasos siguientes
- Creación de una aplicación Java para administrar los datos de Azure Cosmos DB for NoSQL mediante el SDK V4
- Más información sobre los SDK de Java basados en reactores
- Más información sobre la conversión de código asincrónico de RxJava en código asincrónico de reactor con la Guía de reactor vs RxJava
- ¿Intenta planear la capacidad de una migración a Azure Cosmos DB?
- Si lo único que sabe es el número de núcleos virtuales y servidores del clúster de bases de datos existente, lea sobre el cálculo de unidades de solicitud mediante núcleos o CPU virtuales.
- Si conoce las tasas de solicitudes típicas de la carga de trabajo de la base de datos actual, obtenga información sobre el cálculo de unidades de solicitud mediante la herramienta de planeamiento de capacidad de Azure Cosmos DB.