Applicazione Spring Boot con Cloud Datastore

1. Panoramica

Google Cloud Datastore è un database di documenti NoSQL creato per offrire scalabilità automatica, prestazioni elevate e facilità dello sviluppo di applicazioni.

Cosa imparerai a fare

  • Come utilizzare Cloud Datastore per salvare e recuperare oggetti Java in Spring Boot

Che cosa ti serve

  • Un progetto Google Cloud
  • Un browser, ad esempio Chrome o Firefox

Come utilizzerai questo tutorial?

Leggilo e basta Leggilo e completa gli esercizi

Come valuti la tua esperienza di utilizzo dei servizi Google Cloud Platform?

Principiante Intermedio Avanzato

2. Configurazione e requisiti

Configurazione dell'ambiente autonomo

  1. Accedi alla console Google Cloud e crea un nuovo progetto o riutilizzane uno esistente. Se non hai ancora un account Gmail o Google Workspace, devi crearne uno.

b35bf95b8bf3d5d8.png

a99b7ace416376c4.png

bd84a6d3004737c5.png

  • Il nome del progetto è il nome visualizzato per i partecipanti a questo progetto. È una stringa di caratteri non utilizzata dalle API di Google. Puoi sempre aggiornarlo.
  • L'ID progetto è univoco in tutti i progetti Google Cloud ed è immutabile (non può essere modificato dopo l'impostazione). La console Cloud genera automaticamente una stringa univoca, di solito non ti interessa di cosa si tratta. Nella maggior parte dei codelab, dovrai fare riferimento all'ID progetto (in genere identificato come PROJECT_ID). Se non ti piace l'ID generato, puoi generarne un altro casuale. In alternativa, puoi provare a crearne uno e vedere se è disponibile. Non può essere modificato dopo questo passaggio e rimane per tutta la durata del progetto.
  • Per tua informazione, esiste un terzo valore, un numero di progetto, utilizzato da alcune API. Scopri di più su tutti e tre questi valori nella documentazione.
  1. Successivamente, devi abilitare la fatturazione in Cloud Console per utilizzare le risorse/API Cloud. Completare questo codelab non costa molto, se non nulla. Per arrestare le risorse ed evitare addebiti oltre a quelli previsti in questo tutorial, puoi eliminare le risorse che hai creato o il progetto. I nuovi utenti di Google Cloud possono usufruire del programma prova senza costi di 300$.

Attiva Cloud Shell

  1. Nella console Cloud, fai clic su Attiva Cloud Shell 853e55310c205094.png.

55efc1aaa7a4d3ad.png

Se è la prima volta che avvii Cloud Shell, viene visualizzata una schermata intermedia che ne descrive le funzionalità. Se è stata visualizzata una schermata intermedia, fai clic su Continua.

9c92662c6a846a5c.png

Bastano pochi istanti per eseguire il provisioning e connettersi a Cloud Shell.

9f0e51b578fecce5.png

Questa macchina virtuale è caricata con tutti gli strumenti di sviluppo necessari. Offre una home directory permanente da 5 GB e viene eseguita in Google Cloud, migliorando notevolmente le prestazioni e l'autenticazione della rete. Gran parte del lavoro per questo codelab, se non tutto, può essere svolto con un browser.

Una volta eseguita la connessione a Cloud Shell, dovresti vedere che il tuo account è autenticato e il progetto è impostato sul tuo ID progetto.

  1. Esegui questo comando in Cloud Shell per verificare che l'account sia autenticato:
gcloud auth list

Output comando

 Credentialed Accounts
ACTIVE  ACCOUNT
*       <my_account>@<my_domain.com>

To set the active account, run:
    $ gcloud config set account `ACCOUNT`
  1. Esegui questo comando in Cloud Shell per verificare che il comando gcloud conosca il tuo progetto:
gcloud config list project

Output comando

[core]
project = <PROJECT_ID>

In caso contrario, puoi impostarlo con questo comando:

gcloud config set project <PROJECT_ID>

Output comando

Updated property [core/project].

3. Inizializza Cloud Datastore

Nella console di GCP, vai a Menu -> Datastore (nella sezione Archiviazione) o fai clic qui.

Se non hai mai utilizzato Datastore nel progetto attuale, visualizzerai la schermata "Seleziona una modalità Cloud Firestore". Seleziona l'opzione "Modalità Datastore".

f938295c7ff297f4.png

Dopodiché, vedrai la schermata "Scegli dove archiviare i tuoi dati". Seleziona us-east1 o qualsiasi altra località regionale e fai clic su "Crea database":

916ac84fec10fae7.png

4. Bootstrap di una nuova applicazione Java Spring Boot

Dall'ambiente Cloud Shell, utilizza questo comando per inizializzare e avviare una nuova applicazione Spring Boot:

$ curl https://start.spring.io/starter.tgz \
  -d packaging=war \
  -d dependencies=cloud-gcp \
  -d type=maven-project \
  -d baseDir=datastore-example \
  -d bootVersion=3.0.5 | tar -xzvf -

Verrà creata una nuova directory datastore-example/ con un nuovo progetto Maven, insieme a pom.xml, un wrapper Maven e un punto di ingresso dell'applicazione.

La nostra applicazione fornirà una CLI per consentire agli utenti di inserire comandi e visualizzare i risultati. Creeremo una classe per rappresentare un libro e poi la salveremo in Cloud Datastore utilizzando Datastore Repository.

Dobbiamo anche aggiungere un'altra dipendenza necessaria a pom.xml.

Apri l'editor di codice web facendo clic su Apri editor dal menu di Cloud Shell.

6d823258c76a7452.png

Dopo il caricamento dell'editor, modifica il file pom.xml per aggiungere le dipendenze di Google Cloud Datastore Starter e Spring Shell Starter:

pom.xml

<project>
  ...
  <dependencies>
        ...
        <!-- Add GCP Datastore Starter -->
        <dependency>
                <groupId>com.google.cloud</groupId>
                <artifactId>spring-cloud-gcp-starter-data-datastore</artifactId>
        </dependency>

        <!-- Add Spring Shell Starter -->
        <dependency>
                <groupId>org.springframework.shell</groupId>
                <artifactId>spring-shell-starter</artifactId>
                <version>3.0.2</version>
        </dependency>

  </dependencies>
</project>

5. Crea la classe Book

Utilizzando l'editor, crea la classe Book con il seguente contenuto:

datastore-example/src/main/java/com/example/demo/Book.java

package com.example.demo;

import com.google.cloud.spring.data.datastore.core.mapping.Entity;
import org.springframework.data.annotation.Id;

@Entity(name = "books")
public class Book {
  @Id
  Long id;

  String title;

  String author;

  int year;

  public Book(String title, String author, int year) {
    this.title = title;
    this.author = author;
    this.year = year;
  }

  public long getId() {
    return this.id;
  }

  @Override
  public String toString() {
    return "Book{" +
        "id=" + this.id +
        ", title='" + this.title + '\'' +
        ", author='" + this.author + '\'' +
        ", year=" + this.year +
        '}';
  }
}

Come puoi vedere, si tratta di un semplice POJO. La classe è annotata con @Entity per indicare che può essere archiviata in Datastore e fornire il nome del tipo (pensa a un tipo come a una tabella nei database SQL. Per ulteriori dettagli, consulta la documentazione). Il nome del tipo è facoltativo. Se viene omesso, verrà generato in base al nome della classe.

Tieni presente che abbiamo annotato la proprietà id con @Id. Ciò indica che vogliamo che questo campo venga utilizzato come parte dell'identificatore della chiave Datastore. Ogni entità Datastore ha bisogno di un identificatore. I tipi supportati sono String e Long.

Eseguiamo l'override del metodo toString per rendere più leggibile la rappresentazione stringa degli oggetti, il che sarà utile quando li stampiamo.

6. Crea l'interfaccia BookRepository

Crea la classe BookRepository con i seguenti contenuti:

datastore-example/src/main/java/com/example/demo/BookRepository.java

package com.example.demo;

import java.util.List;

import com.google.cloud.spring.data.datastore.repository.DatastoreRepository;


public interface BookRepository extends DatastoreRepository<Book, Long> {

  List<Book> findByAuthor(String author);

  List<Book> findByYearGreaterThan(int year);

  List<Book> findByAuthorAndYear(String author, int year);
}

L'interfaccia estende DatastoreRepository<Book, Long>, dove Book è la classe di dominio e Long è il tipo Id. Nel nostro repository dichiariamo tre metodi di query per i quali le implementazioni vengono generate automaticamente dietro le quinte.

Il primo è findByAuthor. Come puoi immaginare, l'implementazione di questo metodo eseguirà una query che utilizzerà un valore fornito dall'utente nel filtro della condizione per l'uguaglianza al campo Autore.

Il metodo findByYearGreaterThan esegue una query che filtra il campo dell'anno in base a un valore superiore a quello fornito dall'utente.

findByAuthorAndYear esegue una query che cerca entità in cui i campi autore e anno corrispondono ai valori forniti dall'utente.

7. Crea l'applicazione CLI interattiva

Apri la classe dell'applicazione principale DemoApplication e modificala in modo che abbia il seguente aspetto:

datastore-example/src/main/java/com/example/demo/DemoApplication.java

package com.example.demo;

import java.util.List;

import com.google.common.collect.Lists;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.shell.standard.ShellComponent;
import org.springframework.shell.standard.ShellMethod;

@ShellComponent
@SpringBootApplication
public class DemoApplication {
  @Autowired
  BookRepository bookRepository;

  public static void main(String[] args) {
     SpringApplication.run(DemoApplication.class, args);
  }

  @ShellMethod("Saves a book to Cloud Datastore: save-book <title> <author> <year>")
  public String saveBook(String title, String author, int year) {
     Book savedBook = this.bookRepository.save(new Book(title, author, year));
     return savedBook.toString();
  }

  @ShellMethod("Loads all books")
  public String findAllBooks() {
     Iterable<Book> books = this.bookRepository.findAll();
     return Lists.newArrayList(books).toString();
  }

  @ShellMethod("Loads books by author: find-by-author <author>")
  public String findByAuthor(String author) {
     List<Book> books = this.bookRepository.findByAuthor(author);
     return books.toString();
  }

  @ShellMethod("Loads books published after a given year: find-by-year-after <year>")
  public String findByYearAfter(int year) {
     List<Book> books = this.bookRepository.findByYearGreaterThan(year);
     return books.toString();
  }

  @ShellMethod("Loads books by author and year: find-by-author-year <author> <year>")
  public String findByAuthorYear(String author, int year) {
     List<Book> books = this.bookRepository.findByAuthorAndYear(author, year);
     return books.toString();
  }

  @ShellMethod("Removes all books")
  public void removeAllBooks() {
     this.bookRepository.deleteAll();
  }
}

Nota come abbiamo annotato la classe con @ShellComponent. In questo modo, Spring sa che vogliamo utilizzare questa classe come origine per i comandi CLI. I metodi annotati con @ShellMethod verranno esposti come comandi CLI nella nostra applicazione.

Qui utilizziamo i metodi dichiarati nell'interfaccia BookRepository: findByAuthor, findByYearGreaterThan, findByAuthorAndYear. Inoltre, utilizziamo tre metodi integrati: save, findAll e deleteAll.

Esaminiamo il metodo saveBook. Creiamo un oggetto Book utilizzando i valori forniti dall'utente per titolo, autore e anno. Come puoi vedere, non forniamo un valore id, quindi verrà allocato e assegnato automaticamente al campo id al momento del salvataggio. Il metodo save accetta un oggetto di tipo Book e lo salva in Cloud Datastore. Restituisce un oggetto Book con tutti i campi compilati, incluso il campo id. Alla fine restituiamo una rappresentazione stringa di questo oggetto.

Il resto dei metodi funziona in modo simile: accettano i parametri passati ai metodi del repository appropriati e restituiscono i risultati in formato stringa.

8. Eseguire l'applicazione

Per creare e avviare l'applicazione, assicurati innanzitutto che JAVA_HOME sia impostato sulla versione corretta:

$ export JAVA_HOME=/usr/lib/jvm/java-1.17.0-openjdk-amd64

Esegui questo comando in Cloud Shell (dalla radice del progetto datastore-example/ in cui si trova pom.xml):

$ ./mvnw spring-boot:run
export JAVA_HOME=/usr/lib/jvm/java-1.17.0-openjdk-amd64

Dopo una fase di build riuscita, viene visualizzato il logo di Spring e il prompt della shell:

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::                (v3.0.5)



shell:>

Ora puoi sperimentare con i comandi che abbiamo definito in precedenza. Per visualizzare l'elenco dei comandi, utilizza il comando help:

shell:> help
...
find-all-books: Loads all books
find-by-author: Loads books by author: find-by-author <author>
find-by-author-year: Loads books by author and year: find-by-author-year <author> <year>
find-by-year-after: Loads books published after a given year: find-by-year-after <year>
remove-all-books: Removes all books
save-book: Saves a book to Cloud Datastore: save-book <title> <author> <year>

Procedi nel seguente modo:

  1. Crea alcuni libri utilizzando il comando save-book
  2. Esegui una ricerca utilizzando il comando find-all-books
  3. Trovare libri di un autore specifico: find-by-author <author>
  4. Trova libri pubblicati dopo un anno specifico: find-by-year-after <year>
  5. Trova libri di un autore e di un anno specifici: find-by-author-year <author> <year>

9. Visualizzare i contenuti archiviati in Datastore utilizzando l'interfaccia web

Per vedere come vengono archiviate le entità in Cloud Datastore, vai alla console GCP. Se necessario, inserisci "books" nel campo Tipo.

5fab21a6c89f45a.png

10. Esegui la pulizia

Per fare pulizia, rimuovi tutti i libri utilizzando il comando remove-all-books dall'interfaccia dell'applicazione.

shell:> remove-all-books

Per uscire dall'applicazione, utilizza il comando quit, poi Ctrl+C.

11. Complimenti!

In questo codelab hai creato un'applicazione CLI interattiva in grado di archiviare e recuperare oggetti da Cloud Datastore.

Scopri di più

Licenza

Questo lavoro è concesso in licenza ai sensi di una licenza Creative Commons Attribution 2.0 Generic.