Bookshelf Analytics: Use Gemini to build a Java Cloud Run Application that takes BigQuery data to the web

1. Introduction

Do you love digging into books but get overwhelmed by the sheer volume of choices? Imagine having an AI-powered app that not only recommends the perfect read but also offers a concise summary based on your genre of choice, giving you a glimpse into the book's essence. In this codelab, I'll walk you through building such an application with BigQuery, Vertex AI and Cloud Run assisted by Gemini.

Project Overview

Our use case centers around these 4 key components:

  • Book Database: The vast BigQuery public dataset of internet archive books will serve as our comprehensive book catalog.
  • AI Summarization Engine: Google Cloud Functions, equipped with the Gemini-Pro language model, will generate insightful summaries tailored to user requests.
  • BigQuery Integration: A remote function within BigQuery that calls our Cloud Function to deliver on-demand book summaries and themes.
  • User Interface: A web app hosted on Cloud Run that will offer a web application for users to view the results.

We have divided the entire project implementation into 3 codelabs, and this codelab covers Codelab 3 in the list below:

Codelab 1: Use Gemini to build a Java Cloud Function for a Gemini application.

Codelab 2: Use Gemini to build SQL-only Generative AI applications with BigQuery.

Codelab 3: Use Gemini to create a Java Spring Boot web application that interacts with BigQuery.

2. Use Gemini to build a Spring Boot web application with BigQuery

What you'll build

  • Create the necessary BigQuery dataset and table.
  • Java Spring Boot web application that interacts with BigQuery to fetch book data and displays on the web.
  • This app is deployed on Cloud Run.
  • You will implement these steps with the help of Gemini.

3. Requirements

Create your project

You can skip the steps below if you already activated a billing account and created a project using the link mentioned in the conditional step above.

  1. In the Google Cloud Console, on the project selector page, select or create a Google Cloud project.
  2. Make sure that billing is enabled for your Cloud project. Learn how to check if billing is enabled on a project.

Activate Cloud Shell

  1. You will use Cloud Shell, a command-line environment running in Google Cloud that comes preloaded with bq:

From the Cloud Console, click Activate Cloud Shell on the top right corner:

6757b2fb50ddcc2d.png

  1. Once connected to Cloud Shell, you should see that you are already authenticated and that the project is already set to your project ID. Run the following command in Cloud Shell to confirm that you are authenticated:
gcloud auth list
  1. Run the following command in Cloud Shell to confirm that the gcloud command knows about your project
gcloud config list project
  1. If your project is not set, use the following command to set it:
gcloud config set project <YOUR_PROJECT_ID>

Refer documentation for gcloud commands and usage.

4. Enabling Gemini and necessary APIs

Enable Gemini

  1. Navigate to Gemini Marketplace to enable the API. You can also use the following command:

gcloud services enable cloudaicompanion.googleapis.com --project PROJECT_ID

  1. Visit the Gemini page and click on "Start chatting".

Enable other necessary APIs

How would we do that? Let's ask Gemini that, shall we? But before that remember:

Note: LLMs are non-deterministic. So while you are trying these prompts, the response that you receive might look different from the ones in my screenshot.

Go to the Gemini chat console by clicking the "Open Gemini" icon on the top right corner adjacent to the search bar in the Google Cloud console.

26e1491322855614.png

Type this question in the "Enter a prompt here" section:

How do I enable the BigQuery and Cloud Run apis using gcloud command?

You get the response as seen in the following image:

b97a8a9fa9143b3f.png

Copy that (you can use the copy icon on the top of the command snippet) and run it in the Cloud Shell Terminal to enable the respective services:

  • bigquery.googleapis.com
  • run.googleapis.com

5. Explore the BigQuery public dataset for books data

Begin by familiarizing yourself with the BigQuery public dataset containing information on numerous internet archive books. If you are not able to land on the internetarchivebooks dataset from this link, feel free to follow the steps below to explore the dataset or alternatively follow this documentation:

You can find this public dataset in the BigQuery explorer pane. You can find this on the left side when you land on the BigQuery console.

39e2ac03cc99cbac.png

Type "gdelt-bq" or "internetarchivebooks" in the search bar and click SEARCH ALL PROJECTS. Expand in the result and star internet archive books as shown in the image below:

68dba68a79cddfc9.png.

Expand the dataset, click gdelt-bq.internetarchivebooks, and then preview the data in the 1920 table. This table includes books from the year 1920 archived.

To take a look at the schema that we will be using in subsequent sections, run the following query:

select * from  `gdelt-bq.internetarchivebooks.1920` limit 5;

We will be using the following three fields for our codelab:

  • BookMeta_Title (title)
  • Themes (themes separated by ‘;')
  • BookMeta_FullText (full text of the book)

6. Create the basic Java Cloud Run template with Gemini

Open Cloud Shell Editor by clicking on the Open Editor icon on the top right corner of your Cloud Shell Terminal (I usually prefer opening the terminal and editor in separate tabs in parallel so we can write code in one and build in another).

edd258384bc74f1f.png

Once you have the editor open, make sure the Gemini logo in the bottom right corner of the editor console is active (and not canceled out). Also make sure that your Google Cloud Project on the bottom left corner is pointing to your current active project that you want to work with. If they are inactive, click them, authorize, select the Google Cloud Project that you want it to point to and get them activated.

Once both are active, click the project name in the bottom left corner and in the pop up list that opens up titled "Cloud Code", scroll down to "New Application".

db998cc557e83f40.png

In that list, select Cloud Run application. From the list that pops-up, select Java:

c7748de85120507b.png

In the resulting list, type the project name "bookshelf-web" instead of helloworld and click OK.

7c58c764277c571f.png

Hooray! You have bootstrapped your simple Java Cloud Run application with Gemini and you didn't do much apart from enabling and activation configurations, agreed?

This is the project structure you should see:

e6be37bbee730bd1.png

Right now, you are good to deploy the application. But that's not why we started this. We still need to include the main functionality of the web application which is to fetch the analytics data from the BigQuery database and display it on the web.

To do this, you are free to add more prompts and get your code incrementally developed with Gemini or write the logic on your own. I am going to a mix of both.

7. Add dependencies to use BigQuery in the web app

Now that the application is bootstrapped, we are ready to make changes to the application source and properties. First, let's add dependencies. Let's ask Gemini to recommend it.

In the Cloud Code Editor, make sure the status bar is showing Gemini active on the bottom right corner and the active Google Cloud project selected on the bottom left corner.

In the Cloud Code Editor navigate to the pom.xml file, right above the </dependencies> tag, type in the following prompt comment :

171d1c40ff8124e8.png

<!-- What maven dependency should I include to access BigQuery in the app-->

I got this result as shown in the image below:

2df51efd655a3557.png

Pasting the dependency here for convenience. If in your case the suggestion comes up with a version tag, you can ignore that.

<dependency>
 <groupId>com.google.cloud</groupId>
 <artifactId>google-cloud-bigquery</artifactId>
</dependency>

8. Update source to get the bookshelf data to web

Replace the HelloWorldController.java code with the following:

package cloudcode.helloworld.web;
import java.util.UUID;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import com.google.cloud.bigquery.BigQuery;
import com.google.cloud.bigquery.BigQueryOptions;
import com.google.cloud.bigquery.JobId;
import com.google.cloud.bigquery.Job;
import com.google.cloud.bigquery.JobInfo;
import com.google.cloud.bigquery.QueryJobConfiguration;
import com.google.cloud.bigquery.TableResult;
import com.google.cloud.bigquery.FieldValueList;


@RestController
public final class HelloWorldController {


  /**
   * Create an endpoint for the landing page
   * @return the BigQuery analytics results string to the web
   */


  @GetMapping("/")
  public String helloWorld() throws Exception {
    /* Connect to bigquery and write a select SQL to fetch Title, Theme and Summary fields from the table `bookshelf.bookshelf_theme` if you have executed the codelab 1 of this series, if not just directly use records from gdelt-bq.internetarchivebooks.1920 table */

 
String query = "SELECT  BookMeta_Title || ' (' || Themes || ') ' as summary  from gdelt-bq.internetarchivebooks.1920 limit 10 ";


    BigQuery bigquery = BigQueryOptions.getDefaultInstance().getService();
    QueryJobConfiguration queryConfig =
        QueryJobConfiguration.newBuilder(query)
            .setUseLegacySql(false)
            .build();
    // Create a job ID so that we can safely retry.
    JobId jobId = JobId.of(UUID.randomUUID().toString());
    Job queryJob = bigquery.create(JobInfo.newBuilder(queryConfig).setJobId(jobId).build());
    // Wait for the query to complete.
    queryJob = queryJob.waitFor();
    // Check for errors
    if (queryJob == null) {
      throw new RuntimeException("Job no longer exists");
    } else if (queryJob.getStatus().getError() != null) {
      throw new RuntimeException(queryJob.getStatus().getError().toString());
    }
    // Get the results.
    TableResult result = queryJob.getQueryResults();
    String responseString = "";
    // Print all pages of the results.
    for (FieldValueList row : result.iterateAll()) {
      responseString += row.get("summary").getStringValue() + ".         \n";
      System.out.printf("%s\n", row.get("summary").getStringValue());
    }
    return responseString;
  }
}

We have made the following changes to the source files:

  1. In HelloWorldController.java Updated the @Controller to @RestController.
  2. Replaced the content of the helloWorld() method to include the call to BigQuery, execution of the query that fetches the data to list the title and the themes for the book.
  3. Instead of returning the index view template on load, it is updated to return the response as a string to the web.

Important Note: Remember to do update the below

  1. Update the HelloWorldControllerTests.Java file to comment out the current mvc.perform(...) invocation.

Gemini for Code Explanation

We provided the code to you and described the changes that we did to the source files. You could have used Gemini to get code explanations and/or code comments as needed too. Here are a few things that you can try out:

  1. With the HelloWorldController.java file open in the IDE, go to the Chat Panel in the IDE and provide the following prompt: Explain this. Check out the detailed explanation that Gemini provides. This can be used by you anytime to get some explanation on the code.
  2. You can highlight any specific snippet or line in the code (e.g. @GetMapping("/") )and then use the following prompt: Explain this. This will provide a detailed explanation only on the line of code or snippet that you selected.
  3. You can even try out some queries that inquire about the code in a different way. For e.g. you can select the following line of code

BigQuery bigquery = BigQueryOptions.getDefaultInstance().getService();

and ask the following query "What will happen if the bigquery variable is null?" 4. You can also ask for code improvements or refactoring with the help of Gemini. For e.g. you can select the entire code for the helloWorld() method and give the following prompt: "How do I improve or refactor this code?". Check out the suggestions that Gemini provides.

9. Build and Deploy

Navigate to Cloud Shell Terminal. Make sure it is pointing to your project id in the terminal.

4b3392dd050340a3.png

Navigate into the project directory by using the cd command:

cd bookshelf-web

Run the commands below one by one to make sure your app is running locally.

mvn package

mvn spring-boot:run

Now, click the "Web Preview" button and click the "Preview on port 8080" option as shown below:

ea9464498b6bd9df.png

Make sure you are able to see the app running locally on your cloud shell machine.

Now, let's ask Gemini how to deploy this web application on Cloud Run. Navigate to Gemini Chat by clicking on the "Open Gemini" button on the Google Cloud Console.

This is my prompt:

What is the gcloud command to deploy my app to cloud run without having to containerize, only by giving the source file?

Below is the response:

6f21c2d59b6dc416.png

Let's replace the service name and region placeholders in the gcloud command as shown in the snippet below:

gcloud run deploy bookshelf-web --source . --allow-unauthenticated --region $REGION

Run this command from the Cloud Shell Terminal. You should see a few follow-up questions, select the appropriate responses and you should be able to see the deployment in progress:

66f5d6e00c16a4db.png

It takes a few minutes and the app is deployed to Google Cloud serverless-ly. Click the Cloud Run deployed app and view the result on the web:

fd342d8f16e664ab.png

10. Congratulations

Congratulations! We have successfully built, deployed and tested a Java Cloud Run web application to perform bookshelf analytics using Gemini. As a followup task, ask Gemini how to delete the deployed Cloud Run Service from the Google Cloud Console and follow the steps it responds with, to clean up the resource.