1. खास जानकारी
इस लैब में, ऐसी सुविधाओं और क्षमताओं के बारे में बताया गया है जिन्हें कंटेनर वाले एनवायरमेंट में Java ऐप्लिकेशन डेवलप करने का काम करने वाले सॉफ़्टवेयर इंजीनियर के लिए, डेवलपमेंट वर्कफ़्लो को बेहतर बनाने के लिए डिज़ाइन किया गया है. कंटेनर को डेवलप करने के लिए, उपयोगकर्ता को कंटेनर और कंटेनर बनाने की प्रोसेस के बारे में जानकारी होनी चाहिए. इसके अलावा, डेवलपर को आम तौर पर अपने फ़्लो को रोकना पड़ता है. साथ ही, रिमोट एनवायरमेंट में अपने ऐप्लिकेशन की जांच करने और उन्हें डीबग करने के लिए, उन्हें अपने आईडीई से बाहर निकलना पड़ता है. इस ट्यूटोरियल में बताए गए टूल और टेक्नोलॉजी की मदद से, डेवलपर अपने आईडीई को छोड़े बिना, कंटेनर वाले ऐप्लिकेशन पर असरदार तरीके से काम कर सकते हैं.
आपको क्या सीखने को मिलेगा
इस लैब में, आपको GCP में कंटेनर का इस्तेमाल करके डेवलपमेंट करने के तरीकों के बारे में जानकारी मिलेगी. जैसे:
- Cloud Workstations की मदद से इनरलूप डेवलपमेंट करना
- नया Java स्टार्टर ऐप्लिकेशन बनाना
- डेवलपमेंट प्रोसेस के बारे में जानकारी
- सामान्य CRUD रेस्ट सर्विस डेवलप करना
- GKE क्लस्टर पर ऐप्लिकेशन को डीबग करना
- ऐप्लिकेशन को CloudSQL डेटाबेस से कनेक्ट करना

2. सेटअप और ज़रूरी शर्तें
अपनी स्पीड से एनवायरमेंट सेट अप करना
- Google Cloud Console में साइन इन करें और नया प्रोजेक्ट बनाएं या किसी मौजूदा प्रोजेक्ट का फिर से इस्तेमाल करें. अगर आपके पास पहले से कोई Gmail या Google Workspace खाता नहीं है, तो आपको एक खाता बनाना होगा.



- प्रोजेक्ट का नाम, इस प्रोजेक्ट में हिस्सा लेने वाले लोगों के लिए डिसप्ले नेम होता है. यह एक वर्ण स्ट्रिंग है, जिसका इस्तेमाल Google API नहीं करते. इसे कभी भी अपडेट किया जा सकता है.
- प्रोजेक्ट आईडी, सभी Google Cloud प्रोजेक्ट के लिए यूनीक होता है. साथ ही, इसे बदला नहीं जा सकता. Cloud Console, यूनीक स्ट्रिंग अपने-आप जनरेट करता है. आम तौर पर, आपको इससे कोई फ़र्क़ नहीं पड़ता. ज़्यादातर कोडलैब में, आपको प्रोजेक्ट आईडी का रेफ़रंस देना होगा. आम तौर पर, इसे
PROJECT_IDके तौर पर पहचाना जाता है. अगर आपको जनरेट किया गया आईडी पसंद नहीं है, तो कोई दूसरा रैंडम आईडी जनरेट किया जा सकता है. इसके अलावा, आपके पास अपना नाम आज़माने का विकल्प भी है. इससे आपको पता चलेगा कि वह नाम उपलब्ध है या नहीं. इस चरण के बाद, इसे बदला नहीं जा सकता. यह प्रोजेक्ट की अवधि तक बना रहेगा. - आपकी जानकारी के लिए बता दें कि एक तीसरी वैल्यू भी होती है, जिसे प्रोजेक्ट नंबर कहते हैं. इसका इस्तेमाल कुछ एपीआई करते हैं. इन तीनों वैल्यू के बारे में ज़्यादा जानने के लिए, दस्तावेज़ देखें.
- इसके बाद, आपको Cloud Console में बिलिंग चालू करनी होगी, ताकि Cloud संसाधनों/एपीआई का इस्तेमाल किया जा सके. इस कोडलैब को पूरा करने में ज़्यादा खर्च नहीं आएगा. इस ट्यूटोरियल के बाद बिलिंग से बचने के लिए, बनाए गए संसाधनों को बंद किया जा सकता है. इसके लिए, बनाए गए संसाधनों को मिटाएं या पूरे प्रोजेक्ट को मिटाएं. Google Cloud के नए उपयोगकर्ताओं को, मुफ़्त में आज़माने के लिए 300 डॉलर का क्रेडिट मिलता है.
Cloud Shell Editor शुरू करना
इस लैब को Google Cloud Shell Editor के साथ इस्तेमाल करने के लिए डिज़ाइन और टेस्ट किया गया है. एडिटर को ऐक्सेस करने के लिए,
- https://console.cloud.google.com पर जाकर, अपने Google प्रोजेक्ट को ऐक्सेस करें.
- सबसे ऊपर दाएं कोने में मौजूद, Cloud Shell एडिटर आइकॉन पर क्लिक करें

- आपकी विंडो में सबसे नीचे एक नया पैनल खुलेगा
- 'एडिटर खोलें' बटन पर क्लिक करें

- एडिटर खुलेगा. इसमें दाईं ओर एक्सप्लोरर और बीच में एडिटर दिखेगा
- स्क्रीन पर सबसे नीचे एक टर्मिनल पैन भी उपलब्ध होना चाहिए
- अगर टर्मिनल खुला नहीं है, तो नई टर्मिनल विंडो खोलने के लिए `ctrl+`` कीबोर्ड शॉर्टकट का इस्तेमाल करें
gcloud सेट अप करना
Cloud Shell में, अपना प्रोजेक्ट आईडी और वह क्षेत्र सेट करें जहां आपको अपना ऐप्लिकेशन डिप्लॉय करना है. इन्हें PROJECT_ID और REGION वैरिएबल के तौर पर सेव करें.
export REGION=us-central1
export PROJECT_ID=$(gcloud config get-value project)
export PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID --format='value(projectNumber)')
सोर्स कोड को क्लोन करना
इस लैब का सोर्स कोड, GitHub पर GoogleCloudPlatform में container-developer-workshop में मौजूद है. नीचे दिए गए निर्देश का इस्तेमाल करके इसे क्लोन करें. इसके बाद, डायरेक्ट्री में बदलाव करें.
git clone https://github.com/GoogleCloudPlatform/container-developer-workshop.git
cd container-developer-workshop/labs/spring-boot
इस लैब में इस्तेमाल किए गए इंफ़्रास्ट्रक्चर को उपलब्ध कराएं
इस लैब में, आपको GKE पर कोड डिप्लॉय करना होगा. साथ ही, CloudSQL डेटाबेस में सेव किए गए डेटा को ऐक्सेस करना होगा. नीचे दी गई सेटअप स्क्रिप्ट, आपके लिए इस इन्फ़्रास्ट्रक्चर को तैयार करती है. प्रोविज़निंग की प्रोसेस में 25 मिनट से ज़्यादा समय लगेगा. अगले सेक्शन पर जाने से पहले, स्क्रिप्ट के पूरा होने का इंतज़ार करें.
./setup_with_cw.sh &
Cloud Workstations क्लस्टर
Cloud Console में Cloud Workstations खोलें. क्लस्टर के READY स्थिति में आने का इंतज़ार करें.
वर्कस्टेशन कॉन्फ़िगरेशन बनाना
अगर आपका Cloud Shell सेशन डिसकनेक्ट हो गया है, तो "फिर से कनेक्ट करें" पर क्लिक करें. इसके बाद, प्रोजेक्ट आईडी सेट करने के लिए gcloud cli कमांड चलाएं. कमांड चलाने से पहले, यहां दिए गए सैंपल प्रोजेक्ट आईडी की जगह अपना Qwiklabs प्रोजेक्ट आईडी डालें.
gcloud config set project qwiklabs-gcp-project-id
Cloud Workstations कॉन्फ़िगरेशन बनाने के लिए, टर्मिनल में नीचे दी गई स्क्रिप्ट चलाएं.
cd ~/container-developer-workshop/labs/spring-boot
./workstation_config_setup.sh
कॉन्फ़िगरेशन सेक्शन में जाकर, नतीजों की पुष्टि करें. READY स्टेटस पर स्विच करने में दो मिनट लगेंगे.

Console में Cloud Workstations खोलें और नया इंस्टेंस बनाएं.

नाम बदलकर my-workstation करें और मौजूदा कॉन्फ़िगरेशन चुनें: codeoss-java.

वर्कस्टेशन सेक्शन में जाकर, नतीजों की पुष्टि करें.

Workstation लॉन्च करना
वर्कस्टेशन शुरू करें और लॉन्च करें.

पता बार में मौजूद आइकॉन पर क्लिक करके, तीसरे पक्ष की कुकी को अनुमति दें. 

"साइट काम नहीं कर रही है?" पर क्लिक करें.

"कुकी को अनुमति दें" पर क्लिक करें.

वर्कस्टेशन लॉन्च होने के बाद, आपको Code OSS IDE दिखेगा. वर्कस्टेशन आईडीई के 'शुरू करें' पेज पर, "हो गया के तौर पर मार्क करें" पर क्लिक करें

3. नया Java स्टार्टर ऐप्लिकेशन बनाना
इस सेक्शन में, आपको Java Spring Boot का नया ऐप्लिकेशन बनाना होगा. इसके लिए, spring.io से मिले सैंपल ऐप्लिकेशन का इस्तेमाल करें. नया टर्मिनल खोलें.

सैंपल ऐप्लिकेशन का क्लोन बनाना
- स्टार्टर ऐप्लिकेशन बनाना
curl https://start.spring.io/starter.zip -d dependencies=web -d type=maven-project -d javaVersion=17 -d packageName=com.example.springboot -o sample-app.zip
अगर आपको यह मैसेज दिखता है, तो 'अनुमति दें' बटन पर क्लिक करें, ताकि आप इसे वर्कस्टेशन में कॉपी करके चिपका सकें.

- ऐप्लिकेशन को अनज़िप करना
unzip sample-app.zip -d sample-app
- "sample-app" फ़ोल्डर खोलें
cd sample-app && code-oss-cloud-workstations -r --folder-uri="$PWD"
spring-boot-devtools और Jib जोड़ना
Spring Boot DevTools को चालू करने के लिए, अपने एडिटर में एक्सप्लोरर से pom.xml ढूंढें और खोलें. इसके बाद, ब्यौरे वाली लाइन के बाद यहां दिया गया कोड चिपकाएं. ब्यौरे वाली लाइन में <description>Demo project for Spring Boot</description> लिखा होता है
- pom.xml में spring-boot-devtools जोड़ें
प्रोजेक्ट की रूट डायरेक्ट्री में मौजूद pom.xml फ़ाइल खोलें. Description एंट्री के बाद, यह कॉन्फ़िगरेशन जोड़ें.
pom.xml
<!-- Spring profiles-->
<profiles>
<profile>
<id>sync</id>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
</dependencies>
</profile>
</profiles>
- pom.xml में jib-maven-plugin चालू करें
Jib, Google का एक ओपन-सोर्स Java कंटेनर बनाने वाला टूल है. इसकी मदद से, Java डेवलपर उन Java टूल का इस्तेमाल करके कंटेनर बना सकते हैं जिनके बारे में उन्हें जानकारी है. Jib, कंटेनर इमेज बनाने वाला एक तेज़ और आसान टूल है. यह आपके ऐप्लिकेशन को कंटेनर इमेज में पैकेज करने के सभी चरणों को मैनेज करता है. इसके लिए, आपको Dockerfile लिखने या Docker इंस्टॉल करने की ज़रूरत नहीं होती. साथ ही, यह Maven और Gradle में सीधे तौर पर इंटिग्रेट हो जाता है.
pom.xml फ़ाइल में नीचे की ओर स्क्रोल करें और Jib प्लगिन को शामिल करने के लिए, Build सेक्शन को अपडेट करें. बिल्ड सेक्शन पूरा होने के बाद, इससे मेल खाना चाहिए.
pom.xml
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<!-- Jib Plugin-->
<plugin>
<groupId>com.google.cloud.tools</groupId>
<artifactId>jib-maven-plugin</artifactId>
<version>3.2.0</version>
</plugin>
<!-- Maven Resources Plugin-->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>3.1.0</version>
</plugin>
</plugins>
</build>
मेनिफ़ेस्ट जनरेट करना
Skaffold, कंटेनर डेवलपमेंट को आसान बनाने के लिए इंटिग्रेटेड टूल उपलब्ध कराता है. इस चरण में, Skaffold को शुरू किया जाएगा. इससे Kubernetes की बुनियादी YAML फ़ाइलें अपने-आप बन जाएंगी. इस प्रोसेस में, कंटेनर इमेज की परिभाषाओं वाली डायरेक्ट्री की पहचान करने की कोशिश की जाती है. जैसे, Dockerfile. इसके बाद, हर डायरेक्ट्री के लिए डिप्लॉयमेंट और सेवा मेनिफ़ेस्ट बनाया जाता है.
प्रोसेस शुरू करने के लिए, टर्मिनल में नीचे दी गई कमांड चलाएं.

- टर्मिनल में यह कमांड चलाएं
skaffold init --generate-manifests
- जब कहा जाए, तब:
- अपने कर्सर को
Jib Maven Pluginपर ले जाने के लिए, ऐरो बटन का इस्तेमाल करें - विकल्प चुनने के लिए, स्पेसबार दबाएं.
- जारी रखने के लिए Enter दबाएं
- पोर्ट के लिए 8080 डालें
- कॉन्फ़िगरेशन सेव करने के लिए, y डालें
फ़ाइल फ़ोल्डर skaffold.yaml और deployment.yaml में दो फ़ाइलें जोड़ी गई हैं
Skaffold का आउटपुट:

ऐप्लिकेशन का नाम अपडेट करना
कॉन्फ़िगरेशन में शामिल डिफ़ॉल्ट वैल्यू, फ़िलहाल आपके ऐप्लिकेशन के नाम से मेल नहीं खाती हैं. फ़ाइलों को अपडेट करें, ताकि वे डिफ़ॉल्ट वैल्यू के बजाय आपके ऐप्लिकेशन के नाम का रेफ़रंस दें.
- Skaffold कॉन्फ़िगरेशन में एंट्री बदलना
skaffold.yamlखोलें- फ़िलहाल
pom-xml-imageके तौर पर सेट की गई इमेज का नाम चुनें - राइट क्लिक करें और 'सभी बदलावों को बदलें' चुनें
demo-appके तौर पर नया नाम डालें
- Kubernetes कॉन्फ़िगरेशन में एंट्री बदलना
deployment.yamlफ़ाइल खोलो- फ़िलहाल
pom-xml-imageके तौर पर सेट की गई इमेज का नाम चुनें - राइट क्लिक करें और 'सभी बदलावों को बदलें' चुनें
demo-appके तौर पर नया नाम डालें
अपने-आप सिंक होने की सुविधा चालू करना
बेहतर हॉट रिलोड अनुभव के लिए, आपको Jib की सिंक करने की सुविधा का इस्तेमाल करना होगा. इस चरण में, Skaffold को कॉन्फ़िगर किया जाएगा, ताकि वह बिल्ड प्रोसेस में इस सुविधा का इस्तेमाल कर सके.
ध्यान दें कि Skaffold कॉन्फ़िगरेशन में कॉन्फ़िगर की जा रही "सिंक" प्रोफ़ाइल, Spring की उस "सिंक" प्रोफ़ाइल का इस्तेमाल करती है जिसे आपने पिछले चरण में कॉन्फ़िगर किया था. इसमें आपने spring-dev-tools के लिए सहायता चालू की थी.
- Skaffold कॉन्फ़िगरेशन अपडेट करना
skaffold.yaml फ़ाइल में, फ़ाइल के पूरे बिल्ड सेक्शन को इस स्पेसिफ़िकेशन से बदलें. फ़ाइल के अन्य सेक्शन में बदलाव न करें.
skaffold.yaml
build:
artifacts:
- image: demo-app
jib:
project: com.example:demo
type: maven
args:
- --no-transfer-progress
- -Psync
fromImage: gcr.io/distroless/java17-debian11:debug
sync:
auto: true
डिफ़ॉल्ट रूट जोड़ना
/src/main/java/com/example/springboot/ फ़ोल्डर में HelloController.java नाम की फ़ाइल बनाओ.

डिफ़ॉल्ट एचटीटीपी रूट बनाने के लिए, फ़ाइल में यह कॉन्टेंट चिपकाएं.
HelloController.java
package com.example.springboot;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.beans.factory.annotation.Value;
@RestController
public class HelloController {
@Value("${target:local}")
String target;
@GetMapping("/")
public String hello()
{
return String.format("Hello from your %s environment!", target);
}
}
4. डेवलपमेंट प्रोसेस के बारे में जानकारी
इस सेक्शन में, Cloud Code प्लगिन का इस्तेमाल करके कुछ चरणों को पूरा करने का तरीका बताया गया है. इससे आपको बुनियादी प्रोसेस के बारे में जानने में मदद मिलेगी. साथ ही, आपको अपने स्टार्टर ऐप्लिकेशन के कॉन्फ़िगरेशन और सेटअप की पुष्टि करने का तरीका भी पता चलेगा.
Cloud Code, Skaffold के साथ इंटिग्रेट होता है, ताकि डेवलपमेंट की प्रोसेस को आसान बनाया जा सके. नीचे दिए गए चरणों में GKE पर डिप्लॉय करने पर, Cloud Code और Skaffold आपकी कंटेनर इमेज को अपने-आप बना देंगे. इसके बाद, वे इसे Container Registry में पुश कर देंगे. इसके बाद, वे आपके ऐप्लिकेशन को GKE पर डिप्लॉय कर देंगे. यह प्रोसेस बैकग्राउंड में होती है. इससे डेवलपर को जानकारी नहीं मिलती. Cloud Code, कंटेनर पर आधारित डेवलपमेंट के लिए, डीबग करने और हॉटसिंक करने की सुविधाएं उपलब्ध कराता है. इससे डेवलपमेंट की प्रोसेस को बेहतर बनाया जा सकता है.
Google Cloud में साइन इन करें
क्लाउड कोड आइकॉन पर क्लिक करें और "Google Cloud में साइन इन करें" चुनें:

"साइन इन करने के लिए आगे बढ़ें" पर क्लिक करें.

टर्मिनल में आउटपुट देखें और लिंक खोलें:

Qwiklabs के छात्र-छात्राओं के क्रेडेंशियल से लॉग इन करें.

"अनुमति दें" को चुनें:

पुष्टि करने वाले कोड को कॉपी करें और Workstation टैब पर वापस जाएं.

पुष्टि करने के लिए कोड चिपकाएं और Enter दबाएं.

Kubernetes क्लस्टर जोड़ना
- कोई क्लस्टर जोड़ना

- Google Kubernetes Engine चुनें:

- प्रोजेक्ट चुनें.

- शुरुआती सेटअप में बनाए गए "quote-cluster" को चुनें.


gcloud cli का इस्तेमाल करके, मौजूदा प्रोजेक्ट आईडी सेट करना
Qwiklabs पेज से, इस लैब के लिए प्रोजेक्ट आईडी कॉपी करें.

प्रोजेक्ट आईडी सेट करने के लिए, gcloud cli कमांड चलाएं. कमांड चलाने से पहले, सैंपल प्रोजेक्ट आईडी बदलें.
gcloud config set project qwiklabs-gcp-project-id
आउटपुट का उदाहरण:

Kubernetes पर डीबग करना
- बाईं ओर मौजूद पैनल में सबसे नीचे, Cloud Code को चुनें.

- DEVELOPMENT SESSIONS में दिखने वाले पैनल में, Debug on Kubernetes को चुनें.
अगर आपको यह विकल्प नहीं दिख रहा है, तो नीचे की ओर स्क्रोल करें.

- मौजूदा कॉन्टेक्स्ट का इस्तेमाल करने के लिए, "हां" चुनें.

- शुरुआती सेटअप के दौरान बनाए गए "quote-cluster" को चुनें.

- कंटेनर रिपॉज़िटरी चुनें.

- प्रोग्रेस और सूचनाएं देखने के लिए, नीचे वाले पैन में मौजूद आउटपुट टैब चुनें
- ज़्यादा जानकारी और कंटेनर से लाइव स्ट्रीम किए जा रहे लॉग देखने के लिए, दाईं ओर मौजूद चैनल ड्रॉप-डाउन में "Kubernetes: Run/Debug - Detailed" चुनें

ऐप्लिकेशन के डिप्लॉय होने का इंतज़ार करें.

- Cloud Console में, GKE पर डिप्लॉय किए गए ऐप्लिकेशन की समीक्षा करें.

- OUTPUT टैब पर मौजूद ड्रॉपडाउन से "Kubernetes: Run/Debug" को चुनकर, सरल बनाए गए व्यू पर वापस जाएं.
- बिल्ड और टेस्ट पूरे होने पर, आउटपुट टैब में यह दिखता है:
Resource deployment/demo-app status completed successfully. साथ ही, एक यूआरएल दिखता है: "Forwarded URL from service demo-app: http://localhost:8080" - Cloud Code टर्मिनल में, आउटपुट (http://localhost:8080) में मौजूद यूआरएल पर कर्सर घुमाएं. इसके बाद, दिखने वाले टूलटिप में, लिंक फ़ॉलो करें को चुनें.

एक नया टैब खुलेगा और आपको नीचे दिया गया आउटपुट दिखेगा:

ब्रेकपॉइंट का इस्तेमाल करना
/src/main/java/com/example/springboot/HelloController.javaपर मौजूदHelloController.javaऐप्लिकेशन खोलें- रूट पाथ के लिए,
return String.format("Hello from your %s environment!", target);वाला रिटर्न स्टेटमेंट ढूंढें - लाइन नंबर के बाईं ओर मौजूद खाली जगह पर क्लिक करके, उस लाइन में ब्रेकपॉइंट जोड़ें. ब्रेकपॉइंट सेट होने पर, लाल रंग का इंडिकेटर दिखेगा

- अपने ब्राउज़र को फिर से लोड करें और ध्यान दें कि डीबगर, ब्रेकपॉइंट पर प्रोसेस को रोक देता है. साथ ही, आपको उन वैरिएबल और ऐप्लिकेशन की स्थिति की जांच करने की अनुमति देता है जो GKE में रिमोटली चल रहा है

- वैरिएबल सेक्शन में नीचे की ओर तब तक क्लिक करें, जब तक आपको "Target" वैरिएबल न मिल जाए.
- मौजूदा वैल्यू को "स्थानीय" के तौर पर देखें

- वैरिएबल के नाम "target" पर दो बार क्लिक करें. इसके बाद, पॉप-अप में,
वैल्यू को बदलकर "Cloud Workstations" करें

- डीबग कंट्रोल पैनल में मौजूद, जारी रखें बटन पर क्लिक करें

- अपने ब्राउज़र में जवाब देखें. इसमें अब वह अपडेट की गई वैल्यू दिखेगी जिसे आपने अभी डाला है.

- लाइन नंबर के बाईं ओर मौजूद लाल रंग के इंडिकेटर पर क्लिक करके, ब्रेकपॉइंट हटाएं. इससे, इस लैब में आगे बढ़ने पर, आपका कोड इस लाइन पर रुकने से बच जाएगा.
हॉट रीलोड
- स्टेटमेंट को बदलकर, कोई दूसरी वैल्यू दिखाएं. जैसे, "Hello from %s Code"
- यह फ़ाइल, GKE में मौजूद रिमोट कंटेनर में अपने-आप सेव हो जाती है और सिंक हो जाती है
- अपडेट किए गए नतीजे देखने के लिए, अपने ब्राउज़र को रीफ़्रेश करें.
- डीबग टूलबार में मौजूद लाल रंग के स्क्वेयर पर क्लिक करके, डीबग सेशन बंद करें

"हां, हर बार स्कैन करने के बाद साफ़ करें" चुनें.

5. सामान्य CRUD रेस्ट सर्विस डेवलप करना
इस समय, आपका ऐप्लिकेशन कंटेनर में डेवलपमेंट के लिए पूरी तरह से कॉन्फ़िगर हो गया है. साथ ही, आपने Cloud Code की मदद से डेवलपमेंट के बुनियादी वर्कफ़्लो को समझ लिया है. यहां दिए गए सेक्शन में, आपने जो सीखा है उसे लागू करने का तरीका बताया गया है. इसके लिए, Google Cloud में मैनेज किए गए डेटाबेस से कनेक्ट होने वाले REST सेवा एंडपॉइंट जोड़े जाते हैं.
डिपेंडेंसी कॉन्फ़िगर करना
ऐप्लिकेशन कोड, बाकी सेवा से जुड़े डेटा को सेव करने के लिए डेटाबेस का इस्तेमाल करता है. पक्का करें कि डिपेंडेंसी उपलब्ध हैं. इसके लिए, pom.xl में यह कोड जोड़ें
pom.xmlफ़ाइल खोलें और कॉन्फ़िगरेशन के dependencies सेक्शन में यह जोड़ें
pom.xml
<!-- Database dependencies-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-core</artifactId>
</dependency>
<dependency>
<groupId>javax.persistence</groupId>
<artifactId>javax.persistence-api</artifactId>
<version>2.2</version>
</dependency>
कोड REST सेवा
Quote.java
/src/main/java/com/example/springboot/ में Quote.java नाम की फ़ाइल बनाएं और उसमें यहां दिया गया कोड कॉपी करें. इससे ऐप्लिकेशन में इस्तेमाल किए गए Quote ऑब्जेक्ट के लिए Entity मॉडल तय होता है.
package com.example.springboot;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import java.util.Objects;
@Entity
@Table(name = "quotes")
public class Quote
{
@Id
@Column(name = "id")
private Integer id;
@Column(name="quote")
private String quote;
@Column(name="author")
private String author;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getQuote() {
return quote;
}
public void setQuote(String quote) {
this.quote = quote;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
Quote quote1 = (Quote) o;
return Objects.equals(id, quote1.id) &&
Objects.equals(quote, quote1.quote) &&
Objects.equals(author, quote1.author);
}
@Override
public int hashCode() {
return Objects.hash(id, quote, author);
}
}
QuoteRepository.java
src/main/java/com/example/springboot पर QuoteRepository.java नाम की एक फ़ाइल बनाएं और उसमें यह कोड कॉपी करें
package com.example.springboot;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
public interface QuoteRepository extends JpaRepository<Quote,Integer> {
@Query( nativeQuery = true, value =
"SELECT id,quote,author FROM quotes ORDER BY RANDOM() LIMIT 1")
Quote findRandomQuote();
}
यह कोड, डेटा को सेव करने के लिए JPA का इस्तेमाल करता है. यह क्लास, Spring JPARepository इंटरफ़ेस को बढ़ाती है और कस्टम कोड बनाने की अनुमति देती है. आपने जोड़े गए कोड में findRandomQuote कस्टम तरीका जोड़ा हो.
QuoteController.java
सर्विस के लिए एंडपॉइंट को दिखाने के लिए, QuoteController क्लास यह सुविधा देगी.
src/main/java/com/example/springboot पर QuoteController.java नाम की फ़ाइल बनाएं और इसमें यह कॉन्टेंट कॉपी करें
package com.example.springboot;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class QuoteController {
private final QuoteRepository quoteRepository;
public QuoteController(QuoteRepository quoteRepository) {
this.quoteRepository = quoteRepository;
}
@GetMapping("/random-quote")
public Quote randomQuote()
{
return quoteRepository.findRandomQuote();
}
@GetMapping("/quotes")
public ResponseEntity<List<Quote>> allQuotes()
{
try {
List<Quote> quotes = new ArrayList<Quote>();
quoteRepository.findAll().forEach(quotes::add);
if (quotes.size()==0 || quotes.isEmpty())
return new ResponseEntity<List<Quote>>(HttpStatus.NO_CONTENT);
return new ResponseEntity<List<Quote>>(quotes, HttpStatus.OK);
} catch (Exception e) {
System.out.println(e.getMessage());
return new ResponseEntity<List<Quote>>(HttpStatus.INTERNAL_SERVER_ERROR);
}
}
@PostMapping("/quotes")
public ResponseEntity<Quote> createQuote(@RequestBody Quote quote) {
try {
Quote saved = quoteRepository.save(quote);
return new ResponseEntity<Quote>(saved, HttpStatus.CREATED);
} catch (Exception e) {
System.out.println(e.getMessage());
return new ResponseEntity<Quote>(HttpStatus.INTERNAL_SERVER_ERROR);
}
}
@PutMapping("/quotes/{id}")
public ResponseEntity<Quote> updateQuote(@PathVariable("id") Integer id, @RequestBody Quote quote) {
try {
Optional<Quote> existingQuote = quoteRepository.findById(id);
if(existingQuote.isPresent()){
Quote updatedQuote = existingQuote.get();
updatedQuote.setAuthor(quote.getAuthor());
updatedQuote.setQuote(quote.getQuote());
return new ResponseEntity<Quote>(updatedQuote, HttpStatus.OK);
} else {
return new ResponseEntity<Quote>(HttpStatus.NOT_FOUND);
}
} catch (Exception e) {
System.out.println(e.getMessage());
return new ResponseEntity<Quote>(HttpStatus.INTERNAL_SERVER_ERROR);
}
}
@DeleteMapping("/quotes/{id}")
public ResponseEntity<HttpStatus> deleteQuote(@PathVariable("id") Integer id) {
Optional<Quote> quote = quoteRepository.findById(id);
if (quote.isPresent()) {
quoteRepository.deleteById(id);
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
} else {
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
}
}
}
डेटाबेस कॉन्फ़िगरेशन जोड़ना
application.yaml
सेवा से ऐक्सेस किए गए बैकएंड डेटाबेस के लिए कॉन्फ़िगरेशन जोड़ें. src/main/resources में मौजूद application.yaml फ़ाइल में बदलाव करें. अगर यह फ़ाइल मौजूद नहीं है, तो इसे बनाएं. इसके बाद, बैकएंड के लिए पैरामीटर वाला Spring कॉन्फ़िगरेशन जोड़ें.
target: local
spring:
config:
activate:
on-profile: cloud-dev
datasource:
url: 'jdbc:postgresql://${DB_HOST:127.0.0.1}/${DB_NAME:quote_db}'
username: '${DB_USER:user}'
password: '${DB_PASS:password}'
jpa:
properties:
hibernate:
jdbc:
lob:
non_contextual_creation: true
dialect: org.hibernate.dialect.PostgreSQLDialect
hibernate:
ddl-auto: update
Database Migration जोड़ें
src/main/resources में db/migration फ़ोल्डर बनाना
एसक्यूएल फ़ाइल बनाएं: V1__create_quotes_table.sql
नीचे दिए गए कॉन्टेंट को फ़ाइल में चिपकाएं
V1__create_quotes_table.sql
CREATE TABLE quotes(
id INTEGER PRIMARY KEY,
quote VARCHAR(1024),
author VARCHAR(256)
);
INSERT INTO quotes (id,quote,author) VALUES (1,'Never, never, never give up','Winston Churchill');
INSERT INTO quotes (id,quote,author) VALUES (2,'While there''s life, there''s hope','Marcus Tullius Cicero');
INSERT INTO quotes (id,quote,author) VALUES (3,'Failure is success in progress','Anonymous');
INSERT INTO quotes (id,quote,author) VALUES (4,'Success demands singleness of purpose','Vincent Lombardi');
INSERT INTO quotes (id,quote,author) VALUES (5,'The shortest answer is doing','Lord Herbert');
Kubernetes कॉन्फ़िगरेशन
deployment.yaml फ़ाइल में ये बदलाव करने से, ऐप्लिकेशन को CloudSQL इंस्टेंस से कनेक्ट करने की अनुमति मिलती है.
- TARGET - यह वैरिएबल को कॉन्फ़िगर करता है, ताकि यह पता चल सके कि ऐप्लिकेशन किस एनवायरमेंट में एक्ज़ीक्यूट किया गया है
- SPRING_PROFILES_ACTIVE - shows the active Spring profile, which will be configured to
cloud-dev - DB_HOST - यह डेटाबेस का निजी आईपी है. इसे डेटाबेस इंस्टेंस बनाते समय नोट किया गया था. इसके अलावा, इसे Google Cloud Console के नेविगेशन मेन्यू में मौजूद
SQLपर क्लिक करके भी देखा जा सकता है - कृपया वैल्यू बदलें ! - DB_USER और DB_PASS - CloudSQL इंस्टेंस कॉन्फ़िगरेशन में सेट किए गए हैं. इन्हें GCP में सीक्रेट के तौर पर सेव किया जाता है
नीचे दिए गए कॉन्टेंट के साथ, deployment.yaml फ़ाइल को अपडेट करें.
deployment.yaml
apiVersion: v1
kind: Service
metadata:
name: demo-app
labels:
app: demo-app
spec:
ports:
- port: 8080
protocol: TCP
clusterIP: None
selector:
app: demo-app
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: demo-app
labels:
app: demo-app
spec:
replicas: 1
selector:
matchLabels:
app: demo-app
template:
metadata:
labels:
app: demo-app
spec:
containers:
- name: demo-app
image: demo-app
env:
- name: PORT
value: "8080"
- name: TARGET
value: "Local Dev - CloudSQL Database - K8s Cluster"
- name: SPRING_PROFILES_ACTIVE
value: cloud-dev
- name: DB_HOST
value: ${DB_INSTANCE_IP}
- name: DB_PORT
value: "5432"
- name: DB_USER
valueFrom:
secretKeyRef:
name: gke-cloud-sql-secrets
key: username
- name: DB_PASS
valueFrom:
secretKeyRef:
name: gke-cloud-sql-secrets
key: password
- name: DB_NAME
valueFrom:
secretKeyRef:
name: gke-cloud-sql-secrets
key: database
टर्मिनल में यहां दिए गए कमांड चलाकर, DB_HOST वैल्यू को अपने डेटाबेस के पते से बदलें:
export DB_INSTANCE_IP=$(gcloud sql instances describe quote-db-instance \
--format=json | jq \
--raw-output ".ipAddresses[].ipAddress")
envsubst < deployment.yaml > deployment.new && mv deployment.new deployment.yaml
deployment.yaml खोलें और पुष्टि करें कि DB_HOST वैल्यू को इंस्टेंस के आईपी पते से अपडेट किया गया है.

ऐप्लिकेशन डिप्लॉय करना और उसकी पुष्टि करना
- Cloud Shell Editor में सबसे नीचे मौजूद पैनल में, Cloud Code चुनें. इसके बाद, स्क्रीन पर सबसे ऊपर मौजूद, Kubernetes पर डिबग करें चुनें.

- बिल्ड और टेस्ट पूरे होने पर, आउटपुट टैब में यह दिखता है:
Resource deployment/demo-app status completed successfully. साथ ही, एक यूआरएल दिखता है: "Forwarded URL from service demo-app: http://localhost:8080". ध्यान दें कि कभी-कभी पोर्ट अलग हो सकता है, जैसे कि 8081. अगर ऐसा है, तो सही वैल्यू सेट करें. टर्मिनल में यूआरएल की वैल्यू सेट करना
export URL=localhost:8080
- कोई भी कोटेशन देखें
टर्मिनल से, random-quote एंडपॉइंट के ख़िलाफ़ नीचे दी गई कमांड को कई बार चलाएं. बार-बार कॉल करने पर अलग-अलग कोटेशन दिखना
curl $URL/random-quote | jq
- कोटेशन जोड़ना
नीचे दी गई कमांड का इस्तेमाल करके, id=6 वाला नया कोटेशन बनाएं. साथ ही, देखें कि अनुरोध वापस कैसे भेजा जाता है
curl -H 'Content-Type: application/json' -d '{"id":"6","author":"Henry David Thoreau","quote":"Go confidently in the direction of your dreams! Live the life you have imagined"}' -X POST $URL/quotes
- कोटेशन मिटाना
अब मिटाने के तरीके का इस्तेमाल करके, उस कोटेशन को मिटाएं जिसे आपने अभी-अभी जोड़ा है. साथ ही, HTTP/1.1 204 रिस्पॉन्स कोड देखें.
curl -v -X DELETE $URL/quotes/6
- सर्वर गड़बड़ी
एंट्री मिटाए जाने के बाद, पिछले अनुरोध को फिर से चलाने पर गड़बड़ी की स्थिति का सामना करना
curl -v -X DELETE $URL/quotes/6
ध्यान दें कि जवाब में HTTP:500 Internal Server Error दिखता है.
ऐप्लिकेशन को डीबग करना
पिछले सेक्शन में, आपने देखा कि डेटाबेस में मौजूद नहीं है. इस सेक्शन में, समस्या का पता लगाने के लिए एक ब्रेकपॉइंट सेट किया जाएगा. गड़बड़ी DELETE ऑपरेशन में हुई है. इसलिए, आपको QuoteController क्लास के साथ काम करना होगा.
src/main/java/com/example/springboot/QuoteController.javaखोलेंdeleteQuote()तरीका ढूंढना- लाइन ढूंढें:
Optional<Quote> quote = quoteRepository.findById(id); - लाइन नंबर के बाईं ओर मौजूद खाली जगह पर क्लिक करके, उस लाइन पर ब्रेकपॉइंट सेट करें.
- आपको एक लाल इंडिकेटर दिखेगा. इससे पता चलेगा कि ब्रेकपॉइंट सेट हो गया है
deleteनिर्देश को फिर से चलाएं
curl -v -X DELETE $URL/quotes/6
- बाईं ओर मौजूद कॉलम में मौजूद आइकॉन पर क्लिक करके, डीबग व्यू पर वापस जाएं
- QuoteController क्लास में रोकी गई डीबग लाइन देखें.
- डीबगर में,
step overआइकॉन
पर क्लिक करें - ध्यान दें कि कोड, क्लाइंट को इंटरनल सर्वर की गड़बड़ी वाला एचटीटीपी 500 कोड दिखाता है, जो सही नहीं है.
Trying 127.0.0.1:8080... * Connected to 127.0.0.1 (127.0.0.1) port 8080 (#0) > DELETE /quotes/6 HTTP/1.1 > Host: 127.0.0.1:8080 > User-Agent: curl/7.74.0 > Accept: */* > * Mark bundle as not supporting multiuse < HTTP/1.1 500 < Content-Length: 0 < Date: < * Connection #0 to host 127.0.0.1 left intact
कोड अपडेट करना
कोड गलत है. इसलिए, else ब्लॉक को फिर से तैयार किया जाना चाहिए, ताकि एचटीटीपी 404 स्टेटस कोड वापस भेजा जा सके.
गड़बड़ी ठीक करें.
- डिबग सेशन चालू रहने के दौरान, डिबग कंट्रोल पैनल में "जारी रखें" बटन दबाकर अनुरोध पूरा करें.
- इसके बाद,
elseब्लॉक को इस कोड में बदलें:
else {
return new ResponseEntity<HttpStatus>(HttpStatus.NOT_FOUND);
}
यह तरीका कुछ ऐसा दिखना चाहिए
@DeleteMapping("/quotes/{id}")
public ResponseEntity<HttpStatus> deleteQuote(@PathVariable("id") Integer id) {
Optional<Quote> quote = quoteRepository.findById(id);
if (quote.isPresent()) {
quoteRepository.deleteById(id);
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
} else {
return new ResponseEntity<HttpStatus>(HttpStatus.NOT_FOUND);
}
}
- मिटाने के निर्देश को फिर से चलाएं
curl -v -X DELETE $URL/quotes/6
- डीबगर की मदद से, एचटीटीपी 404 Not Found की गड़बड़ी को ठीक करें.
Trying 127.0.0.1:8080... * Connected to 127.0.0.1 (127.0.0.1) port 8080 (#0) > DELETE /quotes/6 HTTP/1.1 > Host: 127.0.0.1:8080 > User-Agent: curl/7.74.0 > Accept: */* > * Mark bundle as not supporting multiuse < HTTP/1.1 404 < Content-Length: 0 < Date: < * Connection #0 to host 127.0.0.1 left intact
- डीबग टूलबार में मौजूद लाल रंग के स्क्वेयर पर क्लिक करके, डीबग सेशन बंद करें


6. बधाई हो
बधाई हो! इस लैब में, आपने स्क्रैच से एक नया Java ऐप्लिकेशन बनाया है. साथ ही, इसे कंटेनर के साथ असरदार तरीके से काम करने के लिए कॉन्फ़िगर किया है. इसके बाद, आपने अपने ऐप्लिकेशन को रिमोट GKE क्लस्टर पर डिप्लॉय किया और उसे डीबग किया. इसके लिए, आपने डेवलपर के उसी फ़्लो का इस्तेमाल किया जो ऐप्लिकेशन के ट्रेडिशनल स्टैक में मिलता है.
आपने क्या सीखा
- Cloud Workstations की मदद से इनरलूप डेवलपमेंट करना
- नया Java स्टार्टर ऐप्लिकेशन बनाना
- डेवलपमेंट प्रोसेस के बारे में जानकारी
- सामान्य CRUD REST सेवा डेवलप करना
- GKE क्लस्टर पर ऐप्लिकेशन को डीबग करना
- ऐप्लिकेशन को CloudSQL डेटाबेस से कनेक्ट करना
