Source code
git clone https://github.com/saturnism/spring-cloud-gcp-guestbook.git
export PROJECT_ID=$(gcloud config list --format 'value(core.project)')
gcloud config list --format 'value(core.project)'
gsutil ls gs://$PROJECT_ID
gsutil -m cp -r gs://$PROJECT_ID/* ~/
Bring to local
# Create GCP service-account
gcloud iam service-accounts create guestbook
# Assign Editor role to service-account
gcloud projects add-iam-policy-binding ${PROJECT_ID} --member serviceAccount:guestbook@${PROJECT_ID}.iam.gserviceaccount.com --role roles/editor
# Create service-account key file
gcloud iam service-accounts keys create ~/service-account.json --iam-account guestbook@${PROJECT_ID}.iam.gserviceaccount.com
gcloud auth login
gcloud config configurations list
gcloud config configurations create guestbook
gcloud config configurations activate guestbook
gcloud config set compute/region europe-west2
gcloud config set compute/zone europe-west2-b
gcloud config set project qwiklabs-gcp-03-f61e7813f2e5
/Users/zcui/Library/Application Support/google-cloud-tools-java/managed-cloud-sdk/downloads/google-cloud-sdk.tar.gz
Day 1
- GCP CloudSQL
Spring Cloud Tech Learned:
- spring-cloud-openfeign
- spring-cloud-gcp
- spring-cloud-gcp-starter-sql-mysql
- hikari: jdbc connection-pool: (https://www.baeldung.com/hikaricp)
Side tools
GCP CloudSQL + Spring Cloud GCP SQL
gcloud services list
gcloud services enable sqladmin.googleapis.com
gcloud sql instances list
gcloud sql instances create guestbook --region=europe-west2
gcloud sql instances describe guestbook --format=value(connectionName)
gcloud sql databases create messages --intance guestbook
gcloud sql connect guestbook
show databases;
use messages;
show tables;
CREATE TABLE guestbook_message (
id BIGINT NOT NULL AUTO_INCREMENT,
name CHAR(128) NOT NULL,
message CHAR(255),
image_uri CHAR(255),
PRIMARY KEY (id)
);
./mvnw -q spring-boot:run -Dspring-boot.run.jvmArguments="-Dspring.profiles.active=cloud"
curl -XPOST -H "content-type: application/json" \
-d '{"name": "Ray", "message": "Hello CloudSQL"}' \
http://localhost:8081/guestbookMessages
curl http://localhost:8081/guestbookMessages
Day 2
- GCP Runtime Configuration api
- GCP Cloud Trace api
Spring Tech ToLearn:
bootstrap.properties
that disables the
Spring Cloud GCP starter
GCP RuntimeConfig + Spring Cloud Config
# Enable GCP runtime configuration api
gcloud services enable runtimeconfig.googleapis.com
# Create GCP runtime configuration for local profile
gcloud beta runtime-config configs create frontend_local
# Set a variable in config file
gcloud beta runtime-config configs variables set greeting "Hi from Runtime Config" --config-name frontend_local
# List a variable in config file
gcloud beta runtime-config configs variables list --config-name=frontend_local
# Get a variable in config file
gcloud beta runtime-config configs variables get-value greeting --config-name=frontend_local
# Set new value to variable in config file
gcloud beta runtime-config configs variables set greeting "Hi from Updated Config" --config-name frontend_local
# Hot reload the config to the application
curl -XPOST http://localhost:8080/actuator/refresh
# Check application properties through Spring Boot Actuator
curl http://localhost:8080/actuator/configprops | jq
GCP Cloud Trace + Spring Cloud GCP Trace
export PROJECT_ID=$(gcloud config list --format 'value(core.project)')
# Enable GCP CloudTrace api
gcloud services enable cloudtrace.googleapis.com
# Create GCP service-account
gcloud iam service-accounts create guestbook
# Assign Editor role to service-account
gcloud projects add-iam-policy-binding ${PROJECT_ID} --member serviceAccount:guestbook@${PROJECT_ID}.iam.gserviceaccount.com --role roles/editor
# Create service-account key file
gcloud iam service-accounts keys create ~/service-account.json --iam-account guestbook@${PROJECT_ID}.iam.gserviceaccount.com
# Run application with service-account key
./mvnw spring-boot:run -Dspring-boot.run.jvmArguments="-Dspring.profiles.active=cloud -Dspring.cloud.gcp.credentials.location=file:///$HOME/service-account.json"
Day 3
Objectives
Objectives 1 - GCP Cloud Pub/Sub api
- In this lab, you learn how to perform the following tasks:
- Enable Cloud Pub/Sub and create a Cloud Pub/Sub topic
- Use Spring to add Cloud Pub/Sub support to your application
- Modify an application to publish Cloud Pub/Sub messages
- Create a Cloud Pub/Sub subscription
- Modify an application to process messages from a Cloud Pub/Sub subscription
Objectives 2 - Spring Integration
- Add Spring Integration Core to an application
- Create an outbound message gateway in your application
- Configure an application to publish messages through a gateway
- Bind the output channel of a message gateway to Cloud Pub/Sub
Objectives 3 - GCP Cloud Storage api
- Add the Spring starter for Cloud Storage
- Create a Cloud Storage bucket
- Modify the HTML template of the frontend application to enable file uploads
- Modify the frontend application to process and store images on Cloud Storage
- Modify the frontend application to display uploaded message images
Objectives 4 - GCP Vision API
- Add a GCP API Java library to an application
- Create a GCP credential scope for Spring
- Create a Java bean that implements Vision API features
- Use Vision API to add image analysis to an application
Objectives 5 - GCP Serverless AppEngine
- Initialize App Engine
- Reconfigure an application to work with App Engine
- Configure the Cloud Runtime Runtime Configuration API to automatically provide the backend URL to the Frontend application
- Deploy the application to App Engine
Spring SDK
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-gcp-starter-storage</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-gcp-starter-vision</artifactId>
</dependency>
<plugin>
<groupId>com.google.cloud.tools</groupId>
<artifactId>appengine-maven-plugin</artifactId>
<version>2.2.0</version>
<configuration>
<version>1</version>
<deploy.projectId>GCLOUD_CONFIG</deploy.projectId>
</configuration>
</plugin>
CLIs
GCP Cloud PubSub
gcloud services enable pubsub.googleapis.com
gcloud pubsub topics create messages
gcloud pubsub subscriptions create messages-subscription-1 --topic=messages
# The message remains in the subscription until it is acknowledged.
gcloud pubsub subscriptions pull messages-subscription-1
# Pull the message again and remove it from the subscription by using the auto-acknowledgement switch at the command line.
gcloud pubsub subscriptions pull messages-subscription-1 --auto-ack
# Initiate SpringBoot project
curl https://start.spring.io/starter.tgz -d dependencies=web,cloud-gcp-pubsub -d baseDir=message-processor | tar -xzvf -
GCP Visioning API
gcloud services enable vision.googleapis.com
gcloud app browse -s guestbook-service
GCP App Engine
gcloud app create --region=europe-west2
gcloud app browse
gcloud app browse -s guestbook-service
gcloud app logs tail -s guestbook-service
Spring Tech ToLearn:
Samples:
Day 4
Objectives
Objective 1 - GCP Cloud Debugger
- Configure Cloud Logging for an App Engine application
- Configure Cloud Debugger source content for App Engine debugging
- Configure Cloud Debugger logpoints and snapshots
- Enable Cloud Monitoring
Objective 2 - GCP Cloud Spanner
- Create a Cloud Spanner instance and database
- Use the data definition language (DDL) to create a Cloud Spanner table
- Use Spring to add support for Cloud Spanner to an application
- Modify a Java application to use Cloud Spanner instead of Cloud SQL
Objective 3 - GCP Kubernetes
- Create a Kubernetes Engine cluster
- Create a containerized version of a Java application
- Create a Kubernetes deployment for a containerized application
Objective 4 - GCP Kubernetes Monitoring (Prometheus)
- Enable Cloud Monitoring for Kubernetes Engine
- Enable Prometheus monitoring in a Kubernetes Engine cluster
- Expose Prometheus metrics from inside a Spring Boot application
- Explore live application metrics using Cloud Monitoring
CLIs
GCP GitRepo
gcloud beta debug source upload --project=qwiklabs-gcp-04-cbf6d2d0d399 --branch=4026E982E356B8AFF02C LOCAL_PATH
gcloud services enable sourcerepo.googleapis.com
gcloud source repos create google-source-captures
git config --global user.email $(gcloud config get-value core/account)
git config --global user.name "devstar"
gcloud beta debug source upload --project=$PROJECT_ID \
--branch=4026E982E356B8AFF02C ./src/
GCP Spanner
gcloud services enable spanner.googleapis.com
gcloud spanner instances create guestbook --config=regional-us-central1 --nodes=1 --description="Guestbook messages"
gcloud spanner databases create messages --instance=guestbook
gcloud spanner databases list --instance=guestbook
cd ~/guestbook-service
mkdir db
# spanner.ddl
CREATE TABLE guestbook_message (
id STRING(36) NOT NULL,
name STRING(255) NOT NULL,
image_uri STRING(255),
message STRING(255)
) PRIMARY KEY (id);
gcloud spanner databases ddl update messages --instance=guestbook --ddl="$(<~/guestbook-service/db/spanner.ddl)"
gcloud spanner databases execute-sql messages --instance=guestbook --sql="SELECT * FROM guestbook_message WHERE name = 'Ray'"
GCP K8s
# Enable service
gcloud services enable container.googleapis.com
# Create cluster
gcloud container clusters create guestbook-cluster \
--zone=us-central1-a \
--num-nodes=2 \
--machine-type=n1-standard-2 \
--enable-autorepair \
--enable-stackdriver-kubernetes
# check k8s version
kubectl version
# Enable container registry
gcloud services enable containerregistry.googleapis.com
# Project info
export PROJECT_ID=$(gcloud config list --format 'value(core.project)')
echo $PROJECT_ID
# Project maven build plugin
<plugin>
<groupId>com.google.cloud.tools</groupId>
<artifactId>jib-maven-plugin</artifactId>
<version>2.4.0</version>
<configuration>
<to>
<!-- Replace [PROJECT_ID]! -->
<image>gcr.io/[PROJECT_ID]/guestbook-frontend</image>
</to>
</configuration>
</plugin>
# Project container build
./mvnw clean compile jib:build
# Create service-account
gcloud iam service-accounts create guestbook
# Binding project role to account
gcloud projects add-iam-policy-binding ${PROJECT_ID} --member serviceAccount:guestbook@${PROJECT_ID}.iam.gserviceaccount.com --role roles/editor
# Create credentials of the account
gcloud iam service-accounts keys create ~/service-account.json --iam-account guestbook@${PROJECT_ID}.iam.gserviceaccount.com
# Create K8s secret with above credential
kubectl create secret generic guestbook-service-account --from-file=$HOME/service-account.json
# Verify k8s secret created
kubectl describe secret guestbook-service-account
watch kubectl get pods
K8s Prometheus
gcloud container clusters get-credentials guestbook-cluster --zone=us-central1-a
kubectl apply -f https://raw.githubusercontent.com/coreos/prometheus-operator/v0.38.1/bundle.yaml
cd ~/prometheus
export PROJECT_ID=$(gcloud config list --format 'value(core.project)')
echo $PROJECT_ID
cat prometheus.yaml | envsubst | kubectl apply -f -
kubectl apply -f pod-monitors.yaml
Spring SDK
# Spanner
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-gcp-starter-data-spanner</artifactId>
</dependency>
# Prometheus
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
<scope>runtime</scope>
</dependency>
# Spanner
spring.cloud.gcp.spanner.instance-id=guestbook
spring.cloud.gcp.spanner.database=messages
# Prometheus
management.server.port=9000
management.endpoints.web.exposure.include=*
# logback-spring.xml
<configuration>
<include resource="org/springframework/boot/logging/logback/defaults.xml" />
<include resource="org/springframework/boot/logging/logback/console-appender.xml" />
<springProfile name="cloud">
<include resource="org/springframework/cloud/gcp/logging/logback-json-appender.xml"/>
<root level="INFO">
<appender-ref ref="CONSOLE_JSON"/>
</root>
</springProfile>
<springProfile name="default">
<root level="INFO">
<appender-ref ref="CONSOLE"/>
</root>
</springProfile>
</configuration>