Desarrollo local con el emulador de Azure Cosmos DB

Un caso de uso común para el emulador es servir como base de datos de desarrollo mientras compila las aplicaciones. El uso del emulador para el desarrollo puede ayudarle a aprender las características de creación y modelado de datos para una base de datos como Azure Cosmos DB sin incurrir en ningún costo de servicio. Además, el uso del emulador como parte de un flujo de trabajo de automatización puede garantizar la ejecución del mismo conjunto de pruebas de integración. Puede asegurarse de que las mismas pruebas se ejecutan localmente en la máquina de desarrollo y de forma remota en un trabajo de integración continua.

Requisitos previos

Instalación del emulador

Existen múltiples variaciones del emulador y cada una de ellas tiene un proceso de instalación relativamente sencillo.

Para empezar, obtenga la variante de Linux de la imagen de contenedor de Microsoft Container Registry (MCR).

  1. Extraiga la imagen de contenedor de Linux mcr.microsoft.com/cosmosdb/linux/azure-cosmos-emulator del registro de contenedor en el host de Docker local.

    docker pull mcr.microsoft.com/cosmosdb/linux/azure-cosmos-emulator:latest
    
  2. Asegúrese de que la imagen del emulador se haya extraído en el host de Docker local.

    docker images
    

Para empezar, obtenga la variante de Linux de la imagen de contenedor de Microsoft Container Registry (MCR).

  1. Extraiga la imagen de contenedor de Linux mcr.microsoft.com/cosmosdb/linux/azure-cosmos-emulator mediante la etiqueta mongodb del registro de contenedor en el host de Docker local.

    docker pull mcr.microsoft.com/cosmosdb/linux/azure-cosmos-emulator:mongodb
    
  2. Asegúrese de que la imagen del emulador se haya extraído en el host de Docker local.

    docker images
    

La variante de contenedor de Docker (Linux o Windows) del emulador no admite la API para Apache Cassandra, la API para Apache Gremlin ni la API para Table.

Inicio del emulador

Una vez descargado, inicie el emulador con la API especificada habilitada.

La variante de contenedor de Docker del emulador no admite la API para Apache Cassandra.

La variante de contenedor de Docker del emulador no admite la API para Apache Gremlin.

La variante de contenedor de Docker del emulador no admite la API para Table.

  1. Ejecute un nuevo contenedor mediante la imagen de contenedor y la siguiente configuración:

    Descripción
    AZURE_COSMOS_EMULATOR_PARTITION_COUNT(Opcional) Especifique el número de particiones que se van a usar.
    AZURE_COSMOS_EMULATOR_ENABLE_DATA_PERSISTENCE(Opcional) Habilite la persistencia de datos entre ejecuciones del emulador.
    AZURE_COSMOS_EMULATOR_IP_ADDRESS_OVERRIDE(Opcional) Invalide la dirección IP predeterminada del emulador.

    Para los sistemas de Linux, use:

    docker run \
        --publish 8081:8081 \
        --publish 10250-10255:10250-10255 \
        --name linux-emulator \
        --detach \
        mcr.microsoft.com/cosmosdb/linux/azure-cosmos-emulator:latest    
    

    Para los sistemas de Windows, use:

    $parameters = @(
        "--publish", "8081:8081"
        "--publish", "10250-10255:10250-10255"
        "--name", "windows-emulator"
        "--detach"
    )
    docker run @parameters mcr.microsoft.com/cosmosdb/linux/azure-cosmos-emulator:latest 
    
  2. Vaya a https://localhost:8081/_explorer/index.html para acceder al explorador de datos.

  1. Ejecute un nuevo contenedor mediante la imagen de contenedor y la siguiente configuración:

    Descripción
    AZURE_COSMOS_EMULATOR_ENABLE_MONGODB_ENDPOINT Especifique la versión del punto de conexión de MongoDB que se va a usar. Entre los puntos de conexión admitidos se incluyen: 3.2, 3.6 o 4.0.
    AZURE_COSMOS_EMULATOR_PARTITION_COUNT(Opcional) Especifique el número de particiones que se van a usar.
    AZURE_COSMOS_EMULATOR_ENABLE_DATA_PERSISTENCE(Opcional) Habilite la persistencia de datos entre ejecuciones del emulador.
    AZURE_COSMOS_EMULATOR_IP_ADDRESS_OVERRIDE(Opcional) Invalide la dirección IP predeterminada del emulador.

    Para los sistemas de Linux, use:

    docker run \
        --publish 8081:8081 \
        --publish 10250:10250 \
        --env AZURE_COSMOS_EMULATOR_ENABLE_MONGODB_ENDPOINT=4.0 \
        --name linux-emulator \
        --detach \
        mcr.microsoft.com/cosmosdb/linux/azure-cosmos-emulator:mongodb
    

    Para los sistemas de Windows, use:

    $parameters = @(
        "--publish", "8081:8081"
        "--publish", "10250:10250"
        "--env", "AZURE_COSMOS_EMULATOR_ENABLE_MONGODB_ENDPOINT=4.0"
        "--name", "windows-emulator"
        "--detach"
    )
    docker run @parameters mcr.microsoft.com/cosmosdb/linux/azure-cosmos-emulator:mongodb
    
  2. Vaya a https://localhost:8081/_explorer/index.html para acceder al explorador de datos.

Importación del certificado TLS/SSL del emulador

Importe el certificado TLS/SSL del emulador para usar el emulador con su SDK de desarrollador preferido sin deshabilitar TLS/SSL en el cliente.

La variante de contenedor de Docker (Linux o Windows) del emulador no admite la API para Apache Cassandra, la API para Apache Gremlin ni la API para Table.

El certificado del emulador está disponible en la ruta de acceso _explorer/emulator.pem en el contenedor en ejecución. Use curl para descargar el certificado del contenedor en ejecución en la máquina local.

  1. Obtenga el certificado del contenedor en ejecución.

    Para los sistemas de Linux, use:

    curl --insecure https://localhost:8081/_explorer/emulator.pem > ~/emulatorcert.crt
    

    Para los sistemas de Windows, use:

    $parameters = @{
        Uri = 'https://localhost:8081/_explorer/emulator.pem'
        Method = 'GET'
        OutFile = 'emulatorcert.crt'
        SkipCertificateCheck = $True
    }
    Invoke-WebRequest @parameters
    
  2. Vuelva a generar la agrupación de certificados mediante el comando adecuado para el sistema operativo.

    Para sistemas de Linux basados en Debian (por ejemplo, Ubuntu), use:

    sudo update-ca-certificates
    

    Para sistemas Linux basados en Red Hat (por ejemplo, CentOS, Fedora), use:

    sudo update-ca-trust
    

    Para los sistemas de Windows, use:

    certutil -f -addstore "Root" ~/emulatorcert.crt
    

    Para obtener instrucciones más detalladas, consulte la documentación específica del sistema operativo.

El certificado del emulador está disponible en la ruta de acceso /_explorer/emulator.pem en el contenedor en ejecución.

  1. Descargue el certificado del contenedor en ejecución en el equipo local.

    Para los sistemas de Linux, use:

    curl --insecure https://localhost:8081/_explorer/emulator.pem > ~/emulatorcert.crt
    

    Para los sistemas de Windows, use:

    $parameters = @{
        Uri = 'https://localhost:8081/_explorer/emulator.pem'
        Method = 'GET'
        OutFile = 'emulatorcert.crt'
        SkipCertificateCheck = $True
    }
    Invoke-WebRequest @parameters
    

    Nota:

    Es posible que tenga que cambiar el host (o la dirección IP) y el número de puerto si ha modificado previamente esos valores.

  2. Instale el certificado según el proceso que se usa normalmente para el sistema operativo. Por ejemplo, en Linux, copiaría el certificado en la ruta de acceso /usr/local/share/ca-certificates/.

    Para los sistemas de Linux, use:

    cp ~/emulatorcert.crt /usr/local/share/ca-certificates/
    

    Para los sistemas de Windows, use:

    $parameters = @{
        FilePath = 'emulatorcert.crt'
        CertStoreLocation = 'Cert:\CurrentUser\Root'
    }
    Import-Certificate @parameters
    
  3. En el caso de los sistemas de Linux, vuelva a generar la agrupación de certificados mediante el comando adecuado para la distribución de Linux.

    Para sistemas de Linux basados en Debian (por ejemplo, Ubuntu), use:

    sudo update-ca-certificates
    

    Para sistemas Linux basados en Red Hat (por ejemplo, CentOS, Fedora), use:

    sudo update-ca-trust
    

    Para obtener instrucciones más detalladas, consulte la documentación específica del sistema operativo.

Conexión al emulador desde el SDK

Cada SDK incluye una clase de cliente que se usa normalmente para conectar el SDK a la cuenta de Azure Cosmos DB. Mediante el uso de las credenciales del emulador, puede conectar el SDK a la instancia del emulador en su lugar.

Use el SDK de .NET de la API para NoSQL de Azure Cosmos DB para conectarse al emulador desde una aplicación .NET.

  1. Comience en una carpeta vacía.

  2. Creación de una aplicación de consola de .NET

    dotnet new console
    
  3. Agregue el paquete Microsoft.Azure.Cosmos de NuGet.

    dotnet add package Microsoft.Azure.Cosmos
    
  4. Abra el archivo Program.cs.

  5. Elimine cualquier contenido existente dentro del archivo.

  6. Agregue un bloque using para el espacio de nombres Microsoft.Azure.Cosmos.

    using Microsoft.Azure.Cosmos;
    
  7. Cree una nueva instancia de CosmosClient con las credenciales del emulador.

    using CosmosClient client = new(
        accountEndpoint: "https://localhost:8081/",
        authKeyOrResourceToken: "C2y6yDjf5/R+ob0N8A7Cgv30VRDJIWEHLM+4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw/Jw=="
    );
    
  8. Cree una base de datos y un contenedor mediante CreateDatabaseIfNotExistsAsync y CreateContainerIfNotExistsAsync.

    Database database = await client.CreateDatabaseIfNotExistsAsync(
        id: "cosmicworks",
        throughput: 400
    );
    
    Container container = await database.CreateContainerIfNotExistsAsync(
        id: "products",
        partitionKeyPath: "/id"
    );
    
  9. Cree un nuevo elemento en el contenedor mediante UpsertItemAsync.

    var item = new
    {
        id = "68719518371",
        name = "Kiama classic surfboard"
    };
    
    await container.UpsertItemAsync(item);
    
  10. Ejecute la aplicación .NET.

    dotnet run
    

    Advertencia

    Si recibe un error SSL, es posible que tenga que deshabilitar TLS/SSL para la aplicación. Esto suele ocurrir si está desarrollando en el equipo local, mediante el emulador de Azure Cosmos DB en un contenedor, y no ha importado el certificado SSL del contenedor. Para resolverlo, configure las opciones del cliente para deshabilitar la validación TLS/SSL antes de crear el cliente:

    CosmosClientOptions options = new ()
    {
        HttpClientFactory = () => new HttpClient(new HttpClientHandler()
        {
            ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator
        }),
        ConnectionMode = ConnectionMode.Gateway,
    };
    
    using CosmosClient client = new(
      ...,
      ...,
      clientOptions: options
    );
    

Sugerencia

Consulte la guía para desarrolladores de .NET para consultar más operaciones que puede realizar mediante el SDK de .NET.

Use el controlador de .NET de MongoDB para conectarse al emulador desde una aplicación .NET.

  1. Comience en una carpeta vacía.

  2. Creación de una aplicación de consola de .NET

    dotnet new console
    
  3. Agregue el paquete MongoDB.Driver de NuGet.

    dotnet add package MongoDB.Driver
    
  4. Abra el archivo Program.cs.

  5. Elimine cualquier contenido existente dentro del archivo.

  6. Agregue un bloque using para el espacio de nombres MongoDB.Driver.

    using MongoDB.Driver;
    
  7. Cree una nueva instancia de MongoClient con las credenciales del emulador.

    var client = new MongoClient(
        "mongodb://localhost:C2y6yDjf5%2FR%2Bob0N8A7Cgv30VRDJIWEHLM%2B4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw%2FJw%3D%3D@localhost:10255/admin?ssl=true&retrywrites=false"
    );
    
  8. Obtenga la base de datos y el contenedor mediante GetDatabase y GetCollection<>.

    var database = client.GetDatabase("cosmicworks");
    
    var collection = database.GetCollection<dynamic>("products");
    
  9. Cree un nuevo elemento en XXX mediante InsertOneAsync.

    var item = new
    {
        name = "Kiama classic surfboard"
    };
    
    await collection.InsertOneAsync(item);
    
  10. Ejecute la aplicación .NET.

    dotnet run
    

Use el controlador de .NET de Apache Cassandra para conectarse al emulador desde una aplicación .NET.

  1. Comience en una carpeta vacía.

  2. Creación de una aplicación de consola de .NET

    dotnet new console
    
  3. Agregue el paquete CassandraCSharpDriver de NuGet.

    dotnet add package CassandraCSharpDriver
    
  4. Abra el archivo Program.cs.

  5. Elimine cualquier contenido existente dentro del archivo.

  6. Agregue un bloque using para el espacio de nombres Cassandra.

    using Cassandra;
    
  7. Cree una nueva instancia de Cluster con las credenciales del emulador. Cree una nueva sesión mediante Connect.

    var options = new SSLOptions(
        sslProtocol: System.Security.Authentication.SslProtocols.Tls12,
        checkCertificateRevocation: true,
        remoteCertValidationCallback: (_, _, _, policyErrors) => policyErrors == System.Net.Security.SslPolicyErrors.None);
    
    using var cluster = Cluster.Builder()
        .WithCredentials(
            username: "localhost",
            password: "C2y6yDjf5/R+ob0N8A7Cgv30VRDJIWEHLM+4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw/Jw=="
        )
        .WithPort(
            port: 10350
        )
        .AddContactPoint(
            address: "localhost"
        )
        .WithSSL(
            sslOptions: options
        )
        .Build();
    
    using var session = cluster.Connect();
    
  8. Cree una base de datos y un contenedor mediante PrepareAsync y ExecuteAsync.

    var createKeyspace = await session.PrepareAsync("CREATE KEYSPACE IF NOT EXISTS cosmicworks WITH replication = {'class':'basicclass', 'replication_factor': 1};");
    await session.ExecuteAsync(createKeyspace.Bind());
    
    var createTable = await session.PrepareAsync("CREATE TABLE IF NOT EXISTS cosmicworks.products (id text PRIMARY KEY, name text)");
    await session.ExecuteAsync(createTable.Bind());
    
  9. Cree un nuevo elemento en la tabla mediante ExecuteAsync. Asigne propiedades al elemento mediante Bind.

    var item = new
    {
        id = "68719518371",
        name = "Kiama classic surfboard"
    };
    
    var createItem = await session.PrepareAsync("INSERT INTO cosmicworks.products (id, name) VALUES (?, ?)");
    
    var createItemStatement = createItem.Bind(item.id, item.name);
    
    await session.ExecuteAsync(createItemStatement);
    
  10. Ejecute la aplicación .NET.

    dotnet run
    

Importante

Antes de empezar, la API para Apache Gremlin requiere que cree los recursos en el emulador. Cree una base de datos denominada db1 y un contenedor denominado coll1. La configuración del rendimiento es irrelevante para esta guía y se puede establecer tan bajo como se quiera.

Use el controlador de .NET de Apache Gremlin para conectarse al emulador desde una aplicación .NET.

  1. Comience en una carpeta vacía.

  2. Creación de una aplicación de consola de .NET

    dotnet new console
    
  3. Agregue el paquete Gremlin.Net de NuGet.

    dotnet add package Gremlin.Net 
    
  4. Abra el archivo Program.cs.

  5. Elimine cualquier contenido existente dentro del archivo.

  6. Agregue un bloque using para el espacio de nombres Gremlin.Net.Driver.

    using Gremlin.Net.Driver;
    
  7. Cree una nueva instancia de GremlinServer y GremlinClient con las credenciales del emulador.

    var server = new GremlinServer(
        hostname: "localhost",
        port: 8901,
        username: "/dbs/db1/colls/coll1",
        password: "C2y6yDjf5/R+ob0N8A7Cgv30VRDJIWEHLM+4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw/Jw=="
    );
    
    using var client = new GremlinClient(
        gremlinServer: server,
        messageSerializer: new Gremlin.Net.Structure.IO.GraphSON.GraphSON2MessageSerializer()
    );
    
  8. Limpie el gráfico mediante SubmitAsync.

    await client.SubmitAsync(
        requestScript: "g.V().drop()"
    );
    
  9. Use SubmitAsync de nuevo para agregar un nuevo elemento al gráfico con los parámetros especificados.

    await client.SubmitAsync(
        requestScript: "g.addV('product').property('id', prop_id).property('name', prop_name)",
        bindings: new Dictionary<string, object>
        {
            { "prop_id", "68719518371" },
            { "prop_name", "Kiama classic surfboard" }
        }
    );
    
  10. Ejecute la aplicación .NET.

    dotnet run
    

Use el SDK para .NET de Azure Tables para conectarse al emulador desde una aplicación .NET.

  1. Comience en una carpeta vacía.

  2. Creación de una aplicación de consola de .NET

    dotnet new console
    
  3. Agregue el paquete Azure.Data.Tables de NuGet.

    dotnet add package Azure.Data.Tables
    
  4. Abra el archivo Program.cs.

  5. Elimine cualquier contenido existente dentro del archivo.

  6. Agregue un bloque using para el espacio de nombres Azure.Data.Tables.

    using Azure.Data.Tables;
    
  7. Cree una nueva instancia de TableServiceClient con las credenciales del emulador.

    var serviceClient = new TableServiceClient(
        connectionString: "DefaultEndpointsProtocol=http;AccountName=localhost;AccountKey=C2y6yDjf5/R+ob0N8A7Cgv30VRDJIWEHLM+4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw/Jw==;TableEndpoint=http://localhost:8902/;"
    );
    
  8. Use GetTableClient para crear una nueva instancia de TableClient con el nombre de la tabla. A continuación, asegúrese de que la tabla existe mediante CreateIfNotExistsAsync.

    var client = serviceClient.GetTableClient(
        tableName: "cosmicworksproducts"
    );
    
    await client.CreateIfNotExistsAsync();
    
  9. Cree un nuevo tipo record para los elementos.

    public record Product : Azure.Data.Tables.ITableEntity
    {
        public required string RowKey { get; set; }
    
        public required string PartitionKey { get; set; }
    
        public required string Name { get; init; }
    
        public Azure.ETag ETag { get; set; }
    
        public DateTimeOffset? Timestamp { get; set; }
    }
    
  10. Cree un nuevo elemento en la tabla mediante el modo UpsertEntityAsync y Replace.

    var item = new Product
    {
        RowKey = "68719518371",
        PartitionKey = "Surfboards",
        Name = "Kiama classic surfboard",
        Timestamp = DateTimeOffset.Now
    };
    
    await client.UpsertEntityAsync(
        entity: item,
        mode: TableUpdateMode.Replace
    );
    
  11. Ejecute la aplicación .NET.

    dotnet run
    

Uso del emulador en un flujo de trabajo de CI de Acciones de GitHub

Use el emulador de Azure Cosmos DB con un conjunto de pruebas del marco que prefiera para ejecutar una carga de trabajo de integración continua que valide automáticamente la aplicación. El emulador de Azure Cosmos DB está preinstalado en la variante windows-latest de los ejecutores hospedados de Acciones de GitHub.

Ejecute un conjunto de pruebas con el controlador de pruebas integrado para .NET y un marco de pruebas como MSTest, NUnit o XUnit.

  1. Compruebe que el conjunto de pruebas unitarias de la aplicación funciona según lo previsto.

    dotnet test
    
  2. Cree un nuevo flujo de trabajo en el repositorio de GitHub en un archivo denominado .github/workflows/ci.yml.

  3. Agregue un trabajo al flujo de trabajo para iniciar el emulador de Azure Cosmos DB mediante PowerShell y ejecutar el conjunto de pruebas unitarias.

    name: Continuous Integration
    on:
      push:
        branches:
          - main
    jobs:
      unit_tests:
        name: Run .NET unit tests
        runs-on: windows-latest
        steps:
          - name: Checkout (GitHub)
            uses: actions/checkout@v3
          - name: Start Azure Cosmos DB emulator
            run: |
              Write-Host "Launching Cosmos DB Emulator"
              Import-Module "$env:ProgramFiles\Azure Cosmos DB Emulator\PSModules\Microsoft.Azure.CosmosDB.Emulator"
              Start-CosmosDbEmulator
          - name: Run .NET tests
            run: dotnet test
    

    Nota:

    Inicie el emulador desde la línea de comandos mediante varios argumentos o comandos de PowerShell. Para obtener más información, consulte los argumentos de la línea de comandos del emulador.

Paso siguiente