Migra de App Engine Datastore a Firestore en modo Datastore

En esta guía, se muestra cómo migrar de App Engine Datastore a Firestore en modo Datastore (también conocido como Datastore).

Firestore en modo Datastore es similar a App Engine Datastore, ya que ambos hacen referencia al mismo servicio subyacente de Datastore. Si bien App Engine Datastore es accesible solo a través de los servicios agrupados en paquetes heredados de App Engine, Firestore en modo Datastore es un producto independiente de Google Cloud al que se accede a través de las bibliotecas cliente de Cloud.

Firestore en modo Datastore también ofrece un nivel gratuito y te permite administrar una base de datos de documentos NoSQL altamente escalable y te da la flexibilidad de migrar en el futuro a Cloud Run o a otra plataforma de hosting de apps de Google Cloud.

Antes de comenzar

  1. Revisa los diferentes modos de base de datos de Firestore para asegurarte de comprender el mejor caso de uso de tu app. Ten en cuenta que en esta guía se explica cómo migrar al modo Datastore.

  2. Revisa y comprende los precios y las cuotas de Firestore en modo Datastore.

    Firestore en modo Datastore ofrece uso gratuito con límites diarios, además de almacenamiento, lectura y operaciones de escritura ilimitados para cuentas pagadas. Aunque las aplicaciones de App Engine estén inhabilitadas, no recibirán tráfico que genere cargos. Sin embargo, el uso de Datastore puede facturarse si supera los límites de la cuota gratuita.

  3. Habilita las siguientes API en el proyecto que contiene tu app:

    • API de Artifact Registry para almacenar y administrar artefactos de compilación
    • API de Cloud Build para compilar, implementar y probar tu aplicación de forma continua.
    • API de Cloud Datastore para migrar desde Datastore empaquetado de App Engine a Firestore en modo Datastore.

      Habilita las API

  4. Tener una app de App Engine existente que ejecute Java 8 o 11 y que esté conectada al servicio de App Engine Datastore.

Descripción general del proceso

En un nivel alto, el proceso para migrar a Firestore en modo Datastore desde App Engine Datastore consta de los siguientes pasos:

  1. Actualiza archivos de configuración
  2. Actualiza tu app de Java
    1. Actualiza las declaraciones de importación
    2. Modifica la forma en que la app accede al servicio de Datastore
    3. Obtén una clave generada de Datastore
    4. Modifica la creación de entidades
  3. Confirma la transacción
  4. Resultados de la consulta

Actualiza archivos de configuración

Actualiza tus archivos de configuración para usar las bibliotecas cliente en modo Datastore.

Actualiza el archivo pom.xml de tu aplicación de Java de referencia:

  1. Quita las importaciones appengine-api-1.0-sdk del SDK de App Engine, como las que se muestran a continuación:

    <dependency>
      <groupId>com.google.appengine</groupId>
      <artifactId>appengine-api-1.0-sdk</artifactId>
      <version>2.0.4</version>
    </dependency>
    
  2. Agrega el cliente Datastore de la siguiente manera:

    <dependency>
      <groupId>com.google.cloud</groupId>
      <artifactId>google-cloud-datastore</artifactId>
      <!-- Use latest version -->
      <version>2.2.9</version>
    </dependency>
    

Actualiza tu app de Java

Actualiza las declaraciones de importación

Para modificar los archivos de la aplicación, actualiza las líneas de importación y de inicialización:

  1. Quita las siguientes declaraciones de importación de App Engine para App Engine Datastore com.google.appengine.api.datastore.*:

      import com.google.appengine.api.datastore.DatastoreService;
      import com.google.appengine.api.datastore.DatastoreServiceFactory;
      import com.google.appengine.api.datastore.Entity;
      import com.google.appengine.api.datastore.FetchOptions;
      import com.google.appengine.api.datastore.Query;
    
  2. Agrega las siguientes importaciones com.google.cloud.datastore.* de Firestore en modo Datastore:

      import com.google.cloud.Timestamp;
      import com.google.cloud.datastore.Datastore;
      import com.google.cloud.datastore.DatastoreOptions;
      import com.google.cloud.datastore.Entity;
      import com.google.cloud.datastore.Key;
      import com.google.cloud.datastore.FullEntity;
      import com.google.cloud.datastore.KeyFactory;
      import com.google.cloud.datastore.Query;
      import com.google.cloud.datastore.QueryResults;
      import com.google.cloud.datastore.StructuredQuery;
    

Modifica la forma en que tu app accede al servicio de Datastore

Firestore en modo Datastore usa la clase Datastore en lugar de DatastoreService. Para modificar cómo tu app accede al servicio de Datastore, haz lo siguiente:

  1. Busca las líneas que usan el método DatastoreServiceFactory.getDatastoreService(), como se muestra a continuación:

    // Initialize a client
    DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
    
  2. Reemplaza DatastoreServiceFactory.getDatastoreService() por el método DatastoreOptions.getDefaultInstance().getService(), como se muestra a continuación:

    // Initialize a client
    Datastore datastore = DatastoreOptions.getDefaultInstance().getService();
    

Obtén una clave generada de Datastore

Después de inicializar un cliente, obtén tu clave mediante la creación de una nueva KeyFactory del Kind adecuado y, luego, haz que Datastore genere uno. Para obtener una clave generada por Datastore, haz lo siguiente:

  1. Crea una newKeyFactory.

  2. Llama al método setKind() a fin de determinar el kind de la entidad que se usa para las categorizaciones de consultas.

  3. Agrega el método newKey() para generar una clave de Datastore:

    //Prepare a new entity
    String kind = "visit";
    Key key = datastore.allocateId(datastore.newKeyFactory().setKind(kind).newKey());
    

Modifica la creación de entidades

Después de obtener una clave de Datastore, crea entidades con los siguientes métodos:

  1. Usa Entity.newBuilder y pasa la clave que genera el almacén de datos.

    Busca las líneas que usan la llamada al constructor Entity, como la que se muestra a continuación:

    Entity visit = new Entity(kind);
    

    Reemplaza la llamada del constructor Entity por la llamada del constructor Entity.newBuilder, de la siguiente manera:

    Entity visit = Entity.newBuilder(key);
    
  2. Usa el método set para establecer las propiedades de las entidades.

    El primer parámetro es la propiedad deseada y el segundo es el valor. En el caso de la propiedad timestamp, el valor es Timestamp en lugar de Instant.toString().

    Busca las líneas que usan el método setProperty, como se muestra a continuación:

    visit.setProperty("user_ip", userIp);
    visit.setProperty("timestamp", Instant.now().toString());
    

    Reemplaza el método setProperty por el set, como se muestra a continuación:

    Entity visit = Entity.newBuilder(key).set("user_ip", userIp).set("timestamp", Timestamp.now()).build();
    

Confirma la transacción

La biblioteca cliente de Firestore en modo Datastore usa el método add() para confirmar una transacción. Sigue estos pasos para confirmar la transacción:

  1. Busca líneas que usen el método put(), como se muestra a continuación:

    // Save the entity
    datastore.put(visit);
    
  2. Reemplaza el método put() por el add(), como se muestra a continuación:

    // Save the entity
    datastore.add(visit);
    

Resultados de la consulta

Las consultas recuperan entities que cumplan con un conjunto específico de condiciones. Puedes usar los siguientes métodos para mostrar los resultados:

  • El método OrderBy muestra los resultados en orden ascendente o descendente.

  • El método Limit limita la cantidad máxima de resultados recuperados mediante el mismo compilador.

La consulta usa un método de patrón de compilador con la variable kind. La variable kind se establece en Visit del paso Obtén una clave generada por Datastore.

Para recuperar los primeros 10 resultados, sigue estos pasos:

  1. Busca líneas que usen el método addSort(), como se muestra a continuación:

      // Retrieve the last 10 visits from the datastore, ordered by timestamp.
      Query query = new Query(kind).addSort("timestamp", Query.SortDirection.DESCENDING);
      List<Entity> results = datastore.prepare(query).asList(FetchOptions.Builder.withLimit(10));
    
  2. Reemplaza el método addSort() por setOrderBy() y agrega el método setLimit(), como se muestra a continuación:

    // Retrieve the last 10 visits from the datastore, ordered by timestamp.
    Query<Entity> query = Query.newEntityQueryBuilder()
                            .setKind(kind)
                            .setOrderBy(StructuredQuery.OrderBy.desc("timestamp"))
                            .setLimit(10)
                            .build();
    
  3. Una vez que la consulta esté lista, ejecuta el código mediante datastore.run() y recopila los resultados en una colección QueryResultsEntity.

    El objeto QueryResults resultante es un iterador con una función hasNext().

  4. Comprueba si el conjunto de resultados tiene un objeto next para su procesamiento, en lugar de repetir la lista de resultados. Por ejemplo:

    QueryResults<Entity> results = datastore.run(query);
    
          resp.setContentType("text/plain");
          PrintWriter out = resp.getWriter();
          out.print("Last 10 visits:\n");
          while (results.hasNext()) {
              Entity entity = results.next();
              out.format(
                      "Time: %s Addr: %s\n", entity.getTimestamp("timestamp"), entity.getString("user_ip"));
          }
    

Ejemplos

Para ver un ejemplo de cómo migrar una app de Java 8 a Firestore en modo Datastore, compara laMuestra del código de App Engine Datastore para Java 8 yMuestra de código de Firestore en modo Datastore en GitHub.

¿Qué sigue?