Cloud Workstations और Cloud Code के साथ डेवलप करना

1. खास जानकारी

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

आपको क्या सीखने को मिलेगा

इस लैब में, आपको GCP में कंटेनर का इस्तेमाल करके डेवलपमेंट करने के तरीकों के बारे में जानकारी मिलेगी. जैसे:

  • Cloud Workstations की मदद से इनरलूप डेवलपमेंट करना
  • नया Java स्टार्टर ऐप्लिकेशन बनाना
  • डेवलपमेंट प्रोसेस के बारे में जानकारी
  • सामान्य CRUD रेस्ट सर्विस डेवलप करना
  • GKE क्लस्टर पर ऐप्लिकेशन को डीबग करना
  • ऐप्लिकेशन को CloudSQL डेटाबेस से कनेक्ट करना

58a4cdd3ed7a123a.png

2. सेटअप और ज़रूरी शर्तें

अपनी स्पीड से एनवायरमेंट सेट अप करना

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

b35bf95b8bf3d5d8.png

a99b7ace416376c4.png

bd84a6d3004737c5.png

  • प्रोजेक्ट का नाम, इस प्रोजेक्ट में हिस्सा लेने वाले लोगों के लिए डिसप्ले नेम होता है. यह एक वर्ण स्ट्रिंग है, जिसका इस्तेमाल Google API नहीं करते. इसे कभी भी अपडेट किया जा सकता है.
  • प्रोजेक्ट आईडी, सभी Google Cloud प्रोजेक्ट के लिए यूनीक होता है. साथ ही, इसे बदला नहीं जा सकता. Cloud Console, यूनीक स्ट्रिंग अपने-आप जनरेट करता है. आम तौर पर, आपको इससे कोई फ़र्क़ नहीं पड़ता. ज़्यादातर कोडलैब में, आपको प्रोजेक्ट आईडी का रेफ़रंस देना होगा. आम तौर पर, इसे PROJECT_ID के तौर पर पहचाना जाता है. अगर आपको जनरेट किया गया आईडी पसंद नहीं है, तो कोई दूसरा रैंडम आईडी जनरेट किया जा सकता है. इसके अलावा, आपके पास अपना नाम आज़माने का विकल्प भी है. इससे आपको पता चलेगा कि वह नाम उपलब्ध है या नहीं. इस चरण के बाद, इसे बदला नहीं जा सकता. यह प्रोजेक्ट की अवधि तक बना रहेगा.
  • आपकी जानकारी के लिए बता दें कि एक तीसरी वैल्यू भी होती है, जिसे प्रोजेक्ट नंबर कहते हैं. इसका इस्तेमाल कुछ एपीआई करते हैं. इन तीनों वैल्यू के बारे में ज़्यादा जानने के लिए, दस्तावेज़ देखें.
  1. इसके बाद, आपको Cloud Console में बिलिंग चालू करनी होगी, ताकि Cloud संसाधनों/एपीआई का इस्तेमाल किया जा सके. इस कोडलैब को पूरा करने में ज़्यादा खर्च नहीं आएगा. इस ट्यूटोरियल के बाद बिलिंग से बचने के लिए, बनाए गए संसाधनों को बंद किया जा सकता है. इसके लिए, बनाए गए संसाधनों को मिटाएं या पूरे प्रोजेक्ट को मिटाएं. Google Cloud के नए उपयोगकर्ताओं को, मुफ़्त में आज़माने के लिए 300 डॉलर का क्रेडिट मिलता है.

Cloud Shell Editor शुरू करना

इस लैब को Google Cloud Shell Editor के साथ इस्तेमाल करने के लिए डिज़ाइन और टेस्ट किया गया है. एडिटर को ऐक्सेस करने के लिए,

  1. https://console.cloud.google.com पर जाकर, अपने Google प्रोजेक्ट को ऐक्सेस करें.
  2. सबसे ऊपर दाएं कोने में मौजूद, Cloud Shell एडिटर आइकॉन पर क्लिक करें

8560cc8d45e8c112.png

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

9e504cb98a6a8005.png

  1. एडिटर खुलेगा. इसमें दाईं ओर एक्सप्लोरर और बीच में एडिटर दिखेगा
  2. स्क्रीन पर सबसे नीचे एक टर्मिनल पैन भी उपलब्ध होना चाहिए
  3. अगर टर्मिनल खुला नहीं है, तो नई टर्मिनल विंडो खोलने के लिए `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 स्थिति में आने का इंतज़ार करें.

305e1a3d63ac7ff6.png

वर्कस्टेशन कॉन्फ़िगरेशन बनाना

अगर आपका 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 स्टेटस पर स्विच करने में दो मिनट लगेंगे.

7a6af5aa2807a5f2.png

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

a53adeeac81a78c8.png

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

f21c216997746097.png

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

66a9fc8b20543e32.png

Workstation लॉन्च करना

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

c91bb69b61ec8635.png

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

fcf9405b6957b7d7.png

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

36a84c0e2e3b85b.png

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

2259694328628fba.png

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

94874fba9b74cc22.png

3. नया Java स्टार्टर ऐप्लिकेशन बनाना

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

c31d48f2e4938c38.png

सैंपल ऐप्लिकेशन का क्लोन बनाना

  1. स्टार्टर ऐप्लिकेशन बनाना
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

अगर आपको यह मैसेज दिखता है, तो 'अनुमति दें' बटन पर क्लिक करें, ताकि आप इसे वर्कस्टेशन में कॉपी करके चिपका सकें.

58149777e5cc350a.png

  1. ऐप्लिकेशन को अनज़िप करना
unzip sample-app.zip -d sample-app
  1. "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> लिखा होता है

  1. 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>
  1. 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. इसके बाद, हर डायरेक्ट्री के लिए डिप्लॉयमेंट और सेवा मेनिफ़ेस्ट बनाया जाता है.

प्रोसेस शुरू करने के लिए, टर्मिनल में नीचे दी गई कमांड चलाएं.

d869e0cd38e983d7.png

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

फ़ाइल फ़ोल्डर skaffold.yaml और deployment.yaml में दो फ़ाइलें जोड़ी गई हैं

Skaffold का आउटपुट:

b33cc1e0c2077ab8.png

ऐप्लिकेशन का नाम अपडेट करना

कॉन्फ़िगरेशन में शामिल डिफ़ॉल्ट वैल्यू, फ़िलहाल आपके ऐप्लिकेशन के नाम से मेल नहीं खाती हैं. फ़ाइलों को अपडेट करें, ताकि वे डिफ़ॉल्ट वैल्यू के बजाय आपके ऐप्लिकेशन के नाम का रेफ़रंस दें.

  1. Skaffold कॉन्फ़िगरेशन में एंट्री बदलना
  • skaffold.yaml खोलें
  • फ़िलहाल pom-xml-image के तौर पर सेट की गई इमेज का नाम चुनें
  • राइट क्लिक करें और 'सभी बदलावों को बदलें' चुनें
  • demo-app के तौर पर नया नाम डालें
  1. Kubernetes कॉन्फ़िगरेशन में एंट्री बदलना
  • deployment.yaml फ़ाइल खोलो
  • फ़िलहाल pom-xml-image के तौर पर सेट की गई इमेज का नाम चुनें
  • राइट क्लिक करें और 'सभी बदलावों को बदलें' चुनें
  • demo-app के तौर पर नया नाम डालें

अपने-आप सिंक होने की सुविधा चालू करना

बेहतर हॉट रिलोड अनुभव के लिए, आपको Jib की सिंक करने की सुविधा का इस्तेमाल करना होगा. इस चरण में, Skaffold को कॉन्फ़िगर किया जाएगा, ताकि वह बिल्ड प्रोसेस में इस सुविधा का इस्तेमाल कर सके.

ध्यान दें कि Skaffold कॉन्फ़िगरेशन में कॉन्फ़िगर की जा रही "सिंक" प्रोफ़ाइल, Spring की उस "सिंक" प्रोफ़ाइल का इस्तेमाल करती है जिसे आपने पिछले चरण में कॉन्फ़िगर किया था. इसमें आपने spring-dev-tools के लिए सहायता चालू की थी.

  1. 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 नाम की फ़ाइल बनाओ.

a624f5dd0c477c09.png

डिफ़ॉल्ट एचटीटीपी रूट बनाने के लिए, फ़ाइल में यह कॉन्टेंट चिपकाएं.

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 में साइन इन करें" चुनें:

1769afd39be372ff.png

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

923bb1c8f63160f9.png

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

517fdd579c34aa21.png

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

db99b345f7a8e72c.png

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

a5376553c430ac84.png

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

6719421277b92eac.png

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

e9847cfe3fa8a2ce.png

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

  1. कोई क्लस्टर जोड़ना

62a3b97bdbb427e5.png

  1. Google Kubernetes Engine चुनें:

9577de423568bbaa.png

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

c5202fcbeebcd41c.png

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

366cfd8bc27cd3ed.png

9d68532c9bc4a89b.png

gcloud cli का इस्तेमाल करके, मौजूदा प्रोजेक्ट आईडी सेट करना

Qwiklabs पेज से, इस लैब के लिए प्रोजेक्ट आईडी कॉपी करें.

fcff2d10007ec5bc.png

प्रोजेक्ट आईडी सेट करने के लिए, gcloud cli कमांड चलाएं. कमांड चलाने से पहले, सैंपल प्रोजेक्ट आईडी बदलें.

gcloud config set project qwiklabs-gcp-project-id

आउटपुट का उदाहरण:

f1c03d01b7ac112c.png

Kubernetes पर डीबग करना

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

60b8e4e95868b561.png

  1. DEVELOPMENT SESSIONS में दिखने वाले पैनल में, Debug on Kubernetes को चुनें.

अगर आपको यह विकल्प नहीं दिख रहा है, तो नीचे की ओर स्क्रोल करें.

7d30833d96632ca0.png

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

a024a69b64de7e9e.png

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

faebabf372e3caf0.png

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

fabc6dce48bae1b4.png

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

86b44c59db58f8f3.png

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

9f37706a752829fe.png

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

6ad220e5d1980756.png

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

28c5539880194a8e.png

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

d67253ca16238f49.png

ब्रेकपॉइंट का इस्तेमाल करना

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

5027dc6da2618a39.png

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

71acfb426623cec2.png

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

a1160d2ed2bb5c82.png

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

वैल्यू को बदलकर "Cloud Workstations" करें

e597a556a5c53f32.png

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

ec17086191770d0d.png

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

6698a9db9e729925.png

  1. लाइन नंबर के बाईं ओर मौजूद लाल रंग के इंडिकेटर पर क्लिक करके, ब्रेकपॉइंट हटाएं. इससे, इस लैब में आगे बढ़ने पर, आपका कोड इस लाइन पर रुकने से बच जाएगा.

हॉट रीलोड

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

a541f928ec8f430e.png c2752bb28d82af86.png

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

984eb2fa34867d70.png

5. सामान्य CRUD रेस्ट सर्विस डेवलप करना

इस समय, आपका ऐप्लिकेशन कंटेनर में डेवलपमेंट के लिए पूरी तरह से कॉन्फ़िगर हो गया है. साथ ही, आपने Cloud Code की मदद से डेवलपमेंट के बुनियादी वर्कफ़्लो को समझ लिया है. यहां दिए गए सेक्शन में, आपने जो सीखा है उसे लागू करने का तरीका बताया गया है. इसके लिए, Google Cloud में मैनेज किए गए डेटाबेस से कनेक्ट होने वाले REST सेवा एंडपॉइंट जोड़े जाते हैं.

डिपेंडेंसी कॉन्फ़िगर करना

ऐप्लिकेशन कोड, बाकी सेवा से जुड़े डेटा को सेव करने के लिए डेटाबेस का इस्तेमाल करता है. पक्का करें कि डिपेंडेंसी उपलब्ध हैं. इसके लिए, pom.xl में यह कोड जोड़ें

  1. 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 वैल्यू को इंस्टेंस के आईपी पते से अपडेट किया गया है.

fd63c0aede14beba.png

ऐप्लिकेशन डिप्लॉय करना और उसकी पुष्टि करना

  1. Cloud Shell Editor में सबसे नीचे मौजूद पैनल में, Cloud Code चुनें. इसके बाद, स्क्रीन पर सबसे ऊपर मौजूद, Kubernetes पर डिबग करें चुनें.

33a5cf41aae91adb.png

  1. बिल्ड और टेस्ट पूरे होने पर, आउटपुट टैब में यह दिखता है: Resource deployment/demo-app status completed successfully. साथ ही, एक यूआरएल दिखता है: "Forwarded URL from service demo-app: http://localhost:8080". ध्यान दें कि कभी-कभी पोर्ट अलग हो सकता है, जैसे कि 8081. अगर ऐसा है, तो सही वैल्यू सेट करें. टर्मिनल में यूआरएल की वैल्यू सेट करना
export URL=localhost:8080
  1. कोई भी कोटेशन देखें

टर्मिनल से, random-quote एंडपॉइंट के ख़िलाफ़ नीचे दी गई कमांड को कई बार चलाएं. बार-बार कॉल करने पर अलग-अलग कोटेशन दिखना

curl $URL/random-quote | jq
  1. कोटेशन जोड़ना

नीचे दी गई कमांड का इस्तेमाल करके, 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
  1. कोटेशन मिटाना

अब मिटाने के तरीके का इस्तेमाल करके, उस कोटेशन को मिटाएं जिसे आपने अभी-अभी जोड़ा है. साथ ही, HTTP/1.1 204 रिस्पॉन्स कोड देखें.

curl -v -X DELETE $URL/quotes/6
  1. सर्वर गड़बड़ी

एंट्री मिटाए जाने के बाद, पिछले अनुरोध को फिर से चलाने पर गड़बड़ी की स्थिति का सामना करना

curl -v -X DELETE $URL/quotes/6

ध्यान दें कि जवाब में HTTP:500 Internal Server Error दिखता है.

ऐप्लिकेशन को डीबग करना

पिछले सेक्शन में, आपने देखा कि डेटाबेस में मौजूद नहीं है. इस सेक्शन में, समस्या का पता लगाने के लिए एक ब्रेकपॉइंट सेट किया जाएगा. गड़बड़ी DELETE ऑपरेशन में हुई है. इसलिए, आपको QuoteController क्लास के साथ काम करना होगा.

  1. src/main/java/com/example/springboot/QuoteController.java खोलें
  2. deleteQuote() तरीका ढूंढना
  3. लाइन ढूंढें: Optional<Quote> quote = quoteRepository.findById(id);
  4. लाइन नंबर के बाईं ओर मौजूद खाली जगह पर क्लिक करके, उस लाइन पर ब्रेकपॉइंट सेट करें.
  5. आपको एक लाल इंडिकेटर दिखेगा. इससे पता चलेगा कि ब्रेकपॉइंट सेट हो गया है
  6. delete निर्देश को फिर से चलाएं
curl -v -X DELETE $URL/quotes/6
  1. बाईं ओर मौजूद कॉलम में मौजूद आइकॉन पर क्लिक करके, डीबग व्यू पर वापस जाएं
  2. QuoteController क्लास में रोकी गई डीबग लाइन देखें.
  3. डीबगर में, step over आइकॉन b814d39b2e5f3d9e.png पर क्लिक करें
  4. ध्यान दें कि कोड, क्लाइंट को इंटरनल सर्वर की गड़बड़ी वाला एचटीटीपी 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 स्टेटस कोड वापस भेजा जा सके.

गड़बड़ी ठीक करें.

  1. डिबग सेशन चालू रहने के दौरान, डिबग कंट्रोल पैनल में "जारी रखें" बटन दबाकर अनुरोध पूरा करें.
  2. इसके बाद, 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);
        }
    }
  1. मिटाने के निर्देश को फिर से चलाएं
curl -v -X DELETE $URL/quotes/6
  1. डीबगर की मदद से, एचटीटीपी 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
  1. डीबग टूलबार में मौजूद लाल रंग के स्क्वेयर पर क्लिक करके, डीबग सेशन बंद करें

12bc3c82f63dcd8a.png

6f19c0f855832407.png

6. बधाई हो

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

आपने क्या सीखा

  • Cloud Workstations की मदद से इनरलूप डेवलपमेंट करना
  • नया Java स्टार्टर ऐप्लिकेशन बनाना
  • डेवलपमेंट प्रोसेस के बारे में जानकारी
  • सामान्य CRUD REST सेवा डेवलप करना
  • GKE क्लस्टर पर ऐप्लिकेशन को डीबग करना
  • ऐप्लिकेशन को CloudSQL डेटाबेस से कनेक्ट करना