1. खास जानकारी
पिछले लैब में, आपने Pic-a-daily ऐप्लिकेशन का इवेंट-ड्रिवन वर्शन बनाया था. इसमें इमेज विश्लेषण सेवा के लिए, Google Cloud Storage से ट्रिगर होने वाली Cloud Function का इस्तेमाल किया गया था. साथ ही, थंबनेल सेवा के लिए, Pub/Sub के ज़रिए GCS से ट्रिगर होने वाले Cloud Run कंटेनर का इस्तेमाल किया गया था. इसके अलावा, Cloud Run पर इमेज गार्बेज कलेक्टर सेवा को ट्रिगर करने के लिए, Eventarc का इस्तेमाल किया गया था. इसके अलावा, Cloud Scheduler ने Collage सेवा को भी ट्रिगर किया था:

इस लैब में, आपको ऐप्लिकेशन का ऑर्केस्ट्रेटेड वर्शन बनाना होगा. सिस्टम में अलग-अलग तरह के इवेंट भेजने के बजाय, आपको वर्कफ़्लो का इस्तेमाल करके सेवाओं को ऑर्केस्ट्रेट और कॉल करना होगा. इसके लिए, यह तरीका अपनाएं:

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



प्रोजेक्ट आईडी याद रखें. यह सभी Google Cloud प्रोजेक्ट के लिए एक यूनीक नाम होता है. ऊपर दिया गया नाम पहले ही इस्तेमाल किया जा चुका है. इसलिए, यह आपके लिए काम नहीं करेगा. माफ़ करें! इस कोड लैब में इसे बाद में PROJECT_ID के तौर पर दिखाया जाएगा.
- इसके बाद, Google Cloud संसाधनों का इस्तेमाल करने के लिए, आपको Cloud Console में बिलिंग चालू करनी होगी.
इस कोडलैब को पूरा करने में ज़्यादा खर्च नहीं आएगा. "सफ़ाई करना" सेक्शन में दिए गए निर्देशों का पालन करना न भूलें. इसमें बताया गया है कि संसाधनों को कैसे बंद किया जाए, ताकि इस ट्यूटोरियल के बाद आपको बिलिंग न करनी पड़े. Google Cloud के नए उपयोगकर्ताओं को, मुफ़्त में आज़माने के लिए 300 डॉलर का क्रेडिट मिलता है.
Cloud Shell शुरू करें
Google Cloud को अपने लैपटॉप से रिमोटली ऐक्सेस किया जा सकता है. हालांकि, इस कोडलैब में Google Cloud Shell का इस्तेमाल किया जाएगा. यह क्लाउड में चलने वाला कमांड लाइन एनवायरमेंट है.
GCP Console में, सबसे ऊपर दाईं ओर मौजूद टूलबार पर मौजूद Cloud Shell आइकॉन पर क्लिक करें:

इसे चालू करने और एनवायरमेंट से कनेक्ट करने में सिर्फ़ कुछ सेकंड लगेंगे. यह प्रोसेस पूरी होने के बाद, आपको कुछ ऐसा दिखेगा:

इस वर्चुअल मशीन में, डेवलपमेंट के लिए ज़रूरी सभी टूल पहले से मौजूद हैं. यह 5 जीबी की होम डायरेक्ट्री उपलब्ध कराता है. साथ ही, यह Google Cloud पर काम करता है. इससे नेटवर्क की परफ़ॉर्मेंस और पुष्टि करने की प्रोसेस बेहतर होती है. इस लैब में मौजूद सभी टास्क को सिर्फ़ ब्राउज़र की मदद से पूरा किया जा सकता है.
3. Workflows के बारे में जानकारी

Workflows का इस्तेमाल करके, बिना सर्वर वाले वर्कफ़्लो बनाए जा सकते हैं. ये वर्कफ़्लो, बिना सर्वर वाले कई टास्क को एक साथ लिंक करते हैं. इन टास्क को उसी क्रम में लिंक किया जाता है जिस क्रम में आपने इन्हें तय किया है. Google Cloud के एपीआई, Cloud Functions और Cloud Run जैसे बिना सर्वर वाले प्रॉडक्ट, और बाहरी एपीआई को कॉल करने की सुविधा का इस्तेमाल करके, बिना सर्वर वाले ऐप्लिकेशन बनाए जा सकते हैं.
ऑर्केस्ट्रेटर के तौर पर, Workflows की मदद से अपने कारोबार के लॉजिक के फ़्लो को YAML/JSON पर आधारित वर्कफ़्लो की परिभाषा वाली भाषा में तय किया जा सकता है. साथ ही, यह उन फ़्लो को ट्रिगर करने के लिए Workflows Execution API और Workflows UI उपलब्ध कराता है.
इसमें पहले से मौजूद और कॉन्फ़िगर की जा सकने वाली ये सुविधाएं हैं. इसलिए, यह सिर्फ़ एक ऑर्केस्ट्रेटर से कहीं ज़्यादा है:
- भरोसेमंद तरीके से चरणों को पूरा करने के लिए, चरणों के बीच में फिर से कोशिश करने और गड़बड़ी ठीक करने की सुविधा.
- JSON पार्सिंग और चरणों के बीच वैरिएबल पास करने की सुविधा, ताकि ग्लू-कोड से बचा जा सके.
- फ़ैसले लेने के लिए एक्सप्रेशन फ़ॉर्मूले, शर्तों के आधार पर चरण पूरे करने की अनुमति देते हैं.
- मॉड्यूलर और फिर से इस्तेमाल किए जा सकने वाले वर्कफ़्लो के लिए सबवर्कफ़्लो.
- बाहरी सेवाओं के साथ काम करने की सुविधा की मदद से, Google Cloud के अलावा अन्य सेवाओं को भी व्यवस्थित किया जा सकता है.
- सुरक्षित तरीके से चरण पूरे करने के लिए, Google Cloud और बाहरी सेवाओं के लिए पुष्टि करने की सुविधा.
- आसानी से इंटिग्रेट करने के लिए, Google Cloud की सेवाओं से कनेक्ट करने वाले कनेक्टर. जैसे, Pub/Sub, Firestore, Tasks, Secret Manager.
इसके अलावा, Workflows एक पूरी तरह से मैनेज किया जाने वाला सर्वरलेस प्रॉडक्ट है. सर्वर को कॉन्फ़िगर या स्केल करने की ज़रूरत नहीं होती. साथ ही, आपको सिर्फ़ इस्तेमाल की गई सुविधाओं के लिए पेमेंट करना होता है.
4. एपीआई चालू करें
इस लैब में, Cloud Functions और Cloud Run सेवाओं को Workflows से कनेक्ट किया जाएगा. आपको App Engine, Cloud Build, Vision API, और अन्य सेवाओं का इस्तेमाल भी करना होगा.
Cloud Shell में, पक्का करें कि सभी ज़रूरी सेवाएं चालू हों:
gcloud services enable \ appengine.googleapis.com \ cloudbuild.googleapis.com \ cloudfunctions.googleapis.com \ compute.googleapis.com \ firestore.googleapis.com \ run.googleapis.com \ vision.googleapis.com \ workflows.googleapis.com \
कुछ समय बाद, आपको यह दिखेगा कि ऑपरेशन पूरा हो गया है:
Operation "operations/acf.5c5ef4f6-f734-455d-b2f0-ee70b5a17322" finished successfully.
5. कोड प्राप्त करें
अगर आपने पिछले कोड लैब में कोड नहीं लिया है, तो यहां से कोड लें:
git clone https://github.com/GoogleCloudPlatform/serverless-photosharing-workshop
आपके पास इस लैब के लिए, फ़ोल्डर का यह स्ट्रक्चर होगा:
frontend | workflows | ├── functions ├── |── trigger-workflow ├── |── vision-data-transform ├── services ├── |── collage ├── |── thumbnails ├── workflows.yaml
ये काम के फ़ोल्डर हैं:
frontendमें App Engine का फ़्रंटएंड शामिल है. हम इसे Lab 4 से फिर से इस्तेमाल करेंगे.functionsमें, वर्कफ़्लो के लिए बनाई गई Cloud Functions शामिल होती हैं.servicesमें, Cloud Run की उन सेवाओं की जानकारी होती है जिनमें वर्कफ़्लो के लिए बदलाव किया गया है.workflows.yamlवर्कफ़्लो की परिभाषा वाली फ़ाइल है.
6. Workflows YAML के बारे में जानकारी
workflows.yaml फ़ाइल में, वर्कफ़्लो को चरणों की सीरीज़ में तय किया जाता है. आइए, इसे बेहतर तरीके से समझने के लिए, इसके बारे में जानें.
वर्कफ़्लो की शुरुआत में, कुछ पैरामीटर पास किए जाते हैं. इन्हें Workflows को ट्रिगर करने वाले दो Cloud Functions से पास किया जाएगा. हम इन फ़ंक्शन के बारे में बाद में जानेंगे, लेकिन वर्कफ़्लो इस तरह शुरू होता है:

YAML में, आपको दिखेगा कि इन पैरामीटर को init चरण में मौजूद वैरिएबल को असाइन किया गया है. जैसे, इवेंट को ट्रिगर करने वाली फ़ाइल और बकेट के नाम. साथ ही, कुछ Cloud Functions और Cloud Run सेवाओं के यूआरएल जिन्हें Workflows कॉल करेगा:
main:
params: [args]
steps:
- init:
assign:
- file: ${args.file}
- bucket: ${args.bucket}
- gsUri: ${"gs://" + bucket + "/" + file}
- projectId: ${sys.get_env("GOOGLE_CLOUD_PROJECT_ID")}
- urls: ${args.urls}
इसके बाद, वर्कफ़्लो इवेंट टाइप की जांच करते हैं. दो तरह के इवेंट काम करते हैं: object.finalize (यह इवेंट तब ट्रिगर होता है, जब क्लाउड स्टोरेज बकेट में कोई फ़ाइल सेव की जाती है) और object.delete (यह इवेंट तब ट्रिगर होता है, जब कोई फ़ाइल मिटाई जाती है). इसके अलावा, किसी भी अन्य कार्रवाई से, 'इवेंट काम नहीं करता' अपवाद की समस्या आएगी.

यहां YAML वर्कफ़्लो की परिभाषा में वह चरण दिया गया है जहां हम फ़ाइल स्टोरेज इवेंट के टाइप की जांच करते हैं:
- eventTypeSwitch:
switch:
- condition: ${args.eventType == "google.storage.object.finalize"}
next: imageAnalysisCall
- condition: ${args.eventType == "google.storage.object.delete"}
next: pictureGarbageCollectionGCS
- eventTypeNotSupported:
raise: ${"eventType " + args.eventType + " is not supported"}
next: end
ध्यान दें कि Workflows, स्विच स्टेटमेंट और अपवाद हैंडलिंग की सुविधा देता है. इसमें स्विच निर्देश और उसकी अलग-अलग स्थितियां शामिल होती हैं. साथ ही, इवेंट की पहचान न होने पर गड़बड़ी की सूचना देने के लिए, रेज़ निर्देश शामिल होता है.
अब आइए, imageAnalysisCall के बारे में जानते हैं. यह Workflows से Vision API को कॉल करने की एक सीरीज़ है. इसका इस्तेमाल इमेज का विश्लेषण करने, Vision API से मिले जवाब के डेटा को बदलकर, इमेज में पहचानी गई चीज़ों के लेबल को क्रम से लगाने, मुख्य रंगों को चुनने, यह देखने के लिए किया जाता है कि इमेज को दिखाया जा सकता है या नहीं. इसके बाद, मेटाडेटा को Cloud Firestore में सेव किया जाता है.
ध्यान दें कि विज़न ट्रांसफ़ॉर्म क्लाउड फ़ंक्शन को छोड़कर, बाकी सभी काम वर्कफ़्लो में किए जाते हैं. विज़न ट्रांसफ़ॉर्म क्लाउड फ़ंक्शन को हम बाद में डिप्लॉय करेंगे:

वाईएएमएल में चरण इस तरह दिखते हैं:
- imageAnalysisCall:
call: http.post
args:
url: https://vision.googleapis.com/v1/images:annotate
headers:
Content-Type: application/json
auth:
type: OAuth2
body:
requests:
- image:
source:
gcsImageUri: ${gsUri}
features:
- type: LABEL_DETECTION
- type: SAFE_SEARCH_DETECTION
- type: IMAGE_PROPERTIES
result: imageAnalysisResponse
- transformImageAnalysisData:
call: http.post
args:
url: ${urls.VISION_DATA_TRANSFORM_URL}
auth:
type: OIDC
body: ${imageAnalysisResponse.body}
result: imageMetadata
- checkSafety:
switch:
- condition: ${imageMetadata.body.safe == true}
next: storeMetadata
next: end
- storeMetadata:
call: http.request
args:
url: ${"https://firestore.googleapis.com/v1/projects/" + projectId + "/databases/(default)/documents/pictures/" + file + "?updateMask.fieldPaths=color&updateMask.fieldPaths=labels&updateMask.fieldPaths=created"}
auth:
type: OAuth2
method: PATCH
body:
name: ${"projects/" + projectId + "/databases/(default)/documents/pictures/" + file}
fields:
color:
stringValue: ${imageMetadata.body.color}
created:
timestampValue: ${imageMetadata.body.created}
labels:
arrayValue:
values: ${imageMetadata.body.labels}
result: storeMetadataResponse
इमेज का विश्लेषण हो जाने के बाद, अगले दो चरण इमेज का थंबनेल बनाना और सबसे हाल की इमेज का कोलाज बनाना है. इसके लिए, दो Cloud Run सेवाओं को डिप्लॉय किया जाता है. साथ ही, thumbnailCall और collageCall चरणों से उन्हें कॉल किया जाता है:

YAML में दिए गए चरण:
- thumbnailCall:
call: http.post
args:
url: ${urls.THUMBNAILS_URL}
auth:
type: OIDC
body:
gcsImageUri: ${gsUri}
result: thumbnailResponse
- collageCall:
call: http.get
args:
url: ${urls.COLLAGE_URL}
auth:
type: OIDC
result: collageResponse
finalizeCompleted चरण में, हर सेवा से स्टेटस कोड वापस करके, एक्ज़ीक्यूशन की यह ब्रांच खत्म हो जाती है:
- finalizeCompleted:
return:
imageAnalysis: ${imageAnalysisResponse.code}
storeMetadata: ${storeMetadataResponse.code}
thumbnail: ${thumbnailResponse.code}
collage: ${collageResponse.code}
दूसरी ब्रांच तब काम करती है, जब मुख्य स्टोरेज बकेट से कोई फ़ाइल मिटाई जाती है. इस बकेट में, तस्वीरों के हाई रिज़ॉल्यूशन वाले वर्शन होते हैं. इस ब्रांच में, हमें इमेज का थंबनेल मिटाना है. साथ ही, थंबनेल वाले बकेट से थंबनेल और Firestore से उसका मेटाडेटा मिटाना है. ये दोनों काम, Workflows से एचटीटीपी कॉल के ज़रिए किए जाते हैं:

YAML में दिए गए चरण:
- pictureGarbageCollectionGCS:
try:
call: http.request
args:
url: ${"https://storage.googleapis.com/storage/v1/b/thumbnails-" + projectId + "/o/" + file}
auth:
type: OAuth2
method: DELETE
result: gcsDeletionResult
except:
as: e
steps:
- dummyResultInOutVar:
assign:
- gcsDeletionResult:
code: 200
body: "Workaround for empty body response"
- pictureGarbageCollectionFirestore:
call: http.request
args:
url: ${"https://firestore.googleapis.com/v1/projects/" + projectId + "/databases/(default)/documents/pictures/" + file}
auth:
type: OAuth2
method: DELETE
result: firestoreDeletionResult
मिटाने की प्रोसेस, हर चरण से नतीजे / कोड वापस करके खत्म होती है:
- deleteCompleted:
return:
gcsDeletion: ${gcsDeletionResult}
firestoreDeletion: ${firestoreDeletionResult.code}
यहां दिए गए चरणों में, हम Workflows की सभी बाहरी डिपेंडेंसी बनाएंगे: बकेट, Cloud Functions, Cloud Run सेवाएं, और Firestore डेटाबेस.
7. बकेट बनाना
आपको इमेज के लिए दो बकेट की ज़रूरत होगी: एक में ओरिजनल हाई-रिज़ॉल्यूशन इमेज सेव करने के लिए और दूसरी में इमेज के थंबनेल सेव करने के लिए.
gsutil टूल का इस्तेमाल करके, यूरोप में मौजूद लोगों के लिए एक ऐसा सार्वजनिक बकेट बनाएं जिसमें सभी लोग एक जैसा ऐक्सेस पा सकें और फ़ोटो अपलोड कर सकें:
export BUCKET_PICTURES=uploaded-pictures-${GOOGLE_CLOUD_PROJECT}
gsutil mb -l EU gs://${BUCKET_PICTURES}
gsutil uniformbucketlevelaccess set on gs://${BUCKET_PICTURES}
gsutil iam ch allUsers:objectViewer gs://${BUCKET_PICTURES}
थंबनेल के लिए, दूसरा सार्वजनिक रीजनल बकेट बनाएं:
export BUCKET_THUMBNAILS=thumbnails-${GOOGLE_CLOUD_PROJECT}
gsutil mb -l EU gs://${BUCKET_THUMBNAILS}
gsutil uniformbucketlevelaccess set on gs://${BUCKET_THUMBNAILS}
gsutil iam ch allUsers:objectViewer gs://${BUCKET_THUMBNAILS}
Cloud Console के Cloud Storage सेक्शन में जाकर, यह पक्का किया जा सकता है कि बकेट बन गई हैं और वे सार्वजनिक हैं:

8. Vision Data Transform (Cloud Function)
Workflows.yaml फ़ाइल में init, eventTypeSwitch, eventTypeNotSupported चरणों से शुरुआत होती है. इनसे यह पक्का किया जाता है कि बकेट से आने वाले इवेंट सही चरणों पर भेजे जाएं.
object.finalize इवेंट के लिए, imageAnalysisCall चरण में Vision API को कॉल किया जाता है, ताकि बनाई गई इमेज का मेटाडेटा निकाला जा सके. ये सभी चरण, Workflows में पूरे किए जाते हैं:

इसके बाद, हमें Vision API से मिले डेटा को बदलना होगा, ताकि हम उसे Firestore में सेव कर सकें. खास तौर पर, हमें:
- इमेज के लिए दिखाए गए लेबल की सूची.
- इमेज का मुख्य रंग वापस पाएं.
- यह पता लगाना कि इमेज सुरक्षित है या नहीं.
यह काम, Cloud Functions में कोड के ज़रिए किया जाता है. Workflows सिर्फ़ इस फ़ंक्शन को कॉल करता है:

कोड के बारे में ज़्यादा जानें
Cloud फ़ंक्शन को vision-data-transform कहा जाता है. इसका पूरा कोड index.js में देखा जा सकता है. जैसा कि आप देख सकते हैं, इस फ़ंक्शन का मुख्य मकसद JSON को JSON में बदलना है, ताकि फ़ोटो के मेटाडेटा को Firestore में आसानी से सेव किया जा सके.
Cloud Functions पर डिप्लॉय करना
इस फ़ोल्डर पर जाएं:
cd workflows/functions/vision-data-transform/nodejs
अपनी पसंद का क्षेत्र सेट करें:
export REGION=europe-west1
gcloud config set functions/region ${REGION}
इस फ़ंक्शन को इनके साथ डिप्लॉय करें:
export SERVICE_NAME=vision-data-transform
gcloud functions deploy ${SERVICE_NAME} \
--source=. \
--runtime nodejs10 \
--entry-point=vision_data_transform \
--trigger-http \
--allow-unauthenticated
फ़ंक्शन डिप्लॉय होने के बाद, Workflows transformImageAnalysisData चरण इस फ़ंक्शन को कॉल कर पाएगा, ताकि Vision API के डेटा को बदला जा सके.
9. डेटाबेस तैयार करना
वर्कफ़्लो में अगला चरण, इमेज के डेटा से इमेज की सुरक्षा की जांच करना है. इसके बाद, Vision API से मिली इमेज की जानकारी को Cloud Firestore डेटाबेस में सेव करना है. यह एक तेज़, पूरी तरह से मैनेज किया जाने वाला, सर्वरलेस, क्लाउड-नेटिव NoSQL दस्तावेज़ डेटाबेस है:

ये दोनों काम Workflows में किए जाते हैं. हालाँकि, मेटाडेटा को सेव करने के लिए, आपको Firestore डेटाबेस बनाना होगा.
सबसे पहले, उस इलाके में App Engine ऐप्लिकेशन बनाएं जहां आपको Firestore डेटाबेस चाहिए. Firestore के लिए यह ज़रूरी है:
export REGION_FIRESTORE=europe-west2
gcloud app create --region=${REGION_FIRESTORE}
इसके बाद, उसी क्षेत्र में Firestore डेटाबेस बनाएं:
gcloud firestore databases create --region=${REGION_FIRESTORE}
दस्तावेज़, हमारे कलेक्शन में प्रोग्राम के हिसाब से बनाए जाएंगे. इनमें चार फ़ील्ड होंगे:
- name (string): अपलोड की गई फ़ोटो का फ़ाइल नाम. यह दस्तावेज़ की कुंजी भी है
- labels (स्ट्रिंग की ऐरे): Vision API से पहचाने गए आइटम के लेबल
- color (string): मुख्य रंग का हेक्साडेसिमल कलर कोड (जैसे, #ab12ef)
- created (date): इस इमेज के मेटाडेटा को सेव किए जाने का टाइमस्टैंप
- thumbnail (बूलियन): यह एक ज़रूरी नहीं है. अगर इस फ़ोटो के लिए थंबनेल इमेज जनरेट की गई है, तो यह फ़ील्ड मौजूद होगा और इसकी वैल्यू true होगी
हमें Firestore में उन फ़ोटो को खोजना है जिनके थंबनेल उपलब्ध हैं. साथ ही, उन्हें बनाने की तारीख के हिसाब से क्रम से लगाना है. इसलिए, हमें एक खोज इंडेक्स बनाना होगा. इस निर्देश का इस्तेमाल करके इंडेक्स बनाया जा सकता है:
gcloud firestore indexes composite create --collection-group=pictures \ --field-config field-path=thumbnail,order=descending \ --field-config field-path=created,order=descending
ध्यान दें कि इंडेक्स बनने में 10 मिनट या उससे ज़्यादा समय लग सकता है.
इंडेक्स बन जाने के बाद, इसे Cloud Console में देखा जा सकता है:

वर्कफ़्लो storeMetadata चरण अब इमेज के मेटाडेटा को Firestore में सेव कर पाएगा.
10. थंबनेल सेवा (Cloud Run)
इसके बाद, इमेज का थंबनेल बनाया जाता है. यह काम, Cloud Run सेवा में कोड के ज़रिए किया जाता है. Workflows, इस सेवा को thumbnailCall चरण में कॉल करता है:

कोड के बारे में ज़्यादा जानें
Cloud Run सेवा को thumbnails कहा जाता है. इसका पूरा कोड index.js में देखा जा सकता है.
कंटेनर इमेज बनाना और उसे पब्लिश करना
Cloud Run, कंटेनर चलाता है. हालांकि, आपको पहले कंटेनर इमेज बनानी होगी. इसे Dockerfile में तय किया गया है. Google Cloud Build का इस्तेमाल, कंटेनर इमेज बनाने के लिए किया जा सकता है. इसके बाद, इसे Google Container Registry पर होस्ट किया जा सकता है.
इस फ़ोल्डर पर जाएं:
cd workflows/services/thumbnails/nodejs
बिल्ड:
export SERVICE_SRC=thumbnails
export SERVICE_NAME=${SERVICE_SRC}-service
gcloud builds submit \
. \
--tag gcr.io/${GOOGLE_CLOUD_PROJECT}/${SERVICE_NAME}
एक या दो मिनट के बाद, बिल्ड पूरा हो जाएगा और कंटेनर को Google Container Registry पर डिप्लॉय कर दिया जाएगा.
Cloud Run पर डिप्लॉय करना
ज़रूरी वैरिएबल और कॉन्फ़िगरेशन सेट करें:
export BUCKET_THUMBNAILS=thumbnails-${GOOGLE_CLOUD_PROJECT}
export REGION=europe-west1
gcloud config set run/region ${REGION}
gcloud config set run/platform managed
इस कमांड का इस्तेमाल करके डिप्लॉय करें:
gcloud run deploy ${SERVICE_NAME} \
--image gcr.io/${GOOGLE_CLOUD_PROJECT}/${SERVICE_NAME} \
--no-allow-unauthenticated \
--memory=1Gi \
--update-env-vars BUCKET_THUMBNAILS=${BUCKET_THUMBNAILS}
सेवा को डिप्लॉय करने के बाद, Workflows thumbnailCall चरण इस सेवा को कॉल कर पाएगा.
11. कोलाज सेवा (Cloud Run)
इसके बाद, सबसे नई इमेज से कोलाज बनाया जाता है. यह काम, Cloud Run सेवा में कोड के ज़रिए किया जाता है. Workflows, इस सेवा को collageCall चरण में कॉल करता है:

कोड के बारे में ज़्यादा जानें
Cloud Run सेवा को collage कहा जाता है. इसका पूरा कोड index.js में देखा जा सकता है.
कंटेनर इमेज बनाना और उसे पब्लिश करना
Cloud Run, कंटेनर चलाता है. हालांकि, आपको पहले कंटेनर इमेज बनानी होगी. इसे Dockerfile में तय किया गया है. Google Cloud Build का इस्तेमाल, कंटेनर इमेज बनाने के लिए किया जा सकता है. इसके बाद, इसे Google Container Registry पर होस्ट किया जा सकता है.
इस फ़ोल्डर पर जाएं:
cd services/collage/nodejs
बिल्ड:
export SERVICE_SRC=collage
export SERVICE_NAME=${SERVICE_SRC}-service
gcloud builds submit \
. \
--tag gcr.io/${GOOGLE_CLOUD_PROJECT}/${SERVICE_NAME}
एक या दो मिनट के बाद, बिल्ड पूरा हो जाएगा और कंटेनर को Google Container Registry पर डिप्लॉय कर दिया जाएगा.
Cloud Run पर डिप्लॉय करना
ज़रूरी वैरिएबल और कॉन्फ़िगरेशन सेट करें:
export BUCKET_THUMBNAILS=thumbnails-${GOOGLE_CLOUD_PROJECT}
export REGION=europe-west1
gcloud config set run/region ${REGION}
gcloud config set run/platform managed
डिप्लॉय करना:
gcloud run deploy ${SERVICE_NAME} \
--image gcr.io/${GOOGLE_CLOUD_PROJECT}/${SERVICE_NAME} \
--no-allow-unauthenticated \
--memory=1Gi \
--update-env-vars BUCKET_THUMBNAILS=${BUCKET_THUMBNAILS}
सेवा को डिप्लॉय करने के बाद, Cloud Console के Cloud Run सेक्शन में जाकर देखा जा सकता है कि दोनों सेवाएं चल रही हैं या नहीं. साथ ही, Workflows collageCall चरण इस सेवा को कॉल कर पाएगा:

12. वर्कफ़्लो डिप्लॉयमेंट
हमने Workflows की सभी बाहरी डिपेंडेंसी को डिप्लॉय कर दिया है. बाकी सभी चरणों (finalizeCompleted, pictureGarbageCollectionGCS, pictureGarbageCollectionFirestore, deleteCompleted) को Workflows अपने-आप पूरा कर सकता है.
अब वर्कफ़्लो को डिप्लॉय करने का समय आ गया है!
उस फ़ोल्डर पर जाएं जिसमें workflows.yaml फ़ाइल मौजूद है. इसके बाद, इसे इस कमांड की मदद से डिप्लॉय करें:
export WORKFLOW_REGION=europe-west4
export WORKFLOW_NAME=picadaily-workflows
gcloud workflows deploy ${WORKFLOW_NAME} \
--source=workflows.yaml \
--location=${WORKFLOW_REGION}
कुछ ही सेकंड में, वर्कफ़्लो डिप्लॉय हो जाएगा. इसे Cloud Console के Workflows सेक्शन में देखा जा सकता है:

अगर आपको पसंद है, तो वर्कफ़्लो पर क्लिक करके उसमें बदलाव किया जा सकता है. बदलाव करते समय, आपको वर्कफ़्लो का विज़ुअल मिलता है:

सही पैरामीटर का इस्तेमाल करके, Cloud Console से वर्कफ़्लो को मैन्युअल तरीके से भी लागू किया जा सकता है. इसके बजाय, हम अगले चरण में Cloud Storage इवेंट के जवाब में इसे अपने-आप लागू करेंगे.
13. Workflows ट्रिगर (Cloud Functions)
वर्कफ़्लो को डिप्लॉय कर दिया गया है और यह इस्तेमाल के लिए तैयार है. अब हमें Workflows को तब ट्रिगर करना है, जब Cloud Storage बकेट में कोई फ़ाइल बनाई या मिटाई जाती है. ये storage.object.finalize और storage.object.delete इवेंट हैं.
Workflows में, Workflows बनाने, मैनेज करने, और उन्हें लागू करने के लिए एपीआई और क्लाइंट लाइब्रेरी होती हैं. इनका इस्तेमाल किया जा सकता है. इस मामले में, वर्कफ़्लो को ट्रिगर करने के लिए, Workflows Execution API और खास तौर पर इसकी Node.js क्लाइंट लाइब्रेरी का इस्तेमाल किया जाएगा.
Cloud Storage इवेंट सुनने वाले Cloud फ़ंक्शन से, Workflows को ट्रिगर किया जाएगा. Cloud Functions सिर्फ़ एक तरह के इवेंट को सुन सकता है. इसलिए, आपको दो Cloud Functions डिप्लॉय करने होंगे, ताकि क्रिएट और डिलीट, दोनों तरह के इवेंट को सुना जा सके:

कोड के बारे में ज़्यादा जानें
Cloud फ़ंक्शन को trigger-workflow कहा जाता है. इसका पूरा कोड index.js में देखा जा सकता है.
Cloud Functions पर डिप्लॉय करना
इस फ़ोल्डर पर जाएं:
cd workflows/functions/trigger-workflow/nodejs
ज़रूरी वैरिएबल और कॉन्फ़िगरेशन सेट करें:
export BUCKET_PICTURES=uploaded-pictures-${GOOGLE_CLOUD_PROJECT}
export REGION=europe-west1
export WORKFLOW_NAME=picadaily-workflows
export WORKFLOW_REGION=europe-west4
export COLLAGE_URL=$(gcloud run services describe collage-service --format 'value(status.url)')
export THUMBNAILS_URL=$(gcloud run services describe thumbnails-service --format 'value(status.url)')
export VISION_DATA_TRANSFORM_URL=$(gcloud functions describe vision-data-transform --format 'value(httpsTrigger.url)')
gcloud config set functions/region ${REGION}
फ़ाइनलाइज़ इवेंट के जवाब में काम करने वाले फ़ंक्शन को डिप्लॉय करें:
export SERVICE_NAME=trigger-workflow-on-finalize
gcloud functions deploy ${SERVICE_NAME} \
--source=. \
--runtime nodejs10 \
--entry-point=trigger_workflow \
--trigger-resource=${BUCKET_PICTURES} \
--trigger-event=google.storage.object.finalize \
--allow-unauthenticated \
--set-env-vars GOOGLE_CLOUD_PROJECT=${GOOGLE_CLOUD_PROJECT},WORKFLOW_REGION=${WORKFLOW_REGION},WORKFLOW_NAME=${WORKFLOW_NAME},THUMBNAILS_URL=${THUMBNAILS_URL},COLLAGE_URL=${COLLAGE_URL},VISION_DATA_TRANSFORM_URL=${VISION_DATA_TRANSFORM_URL}
मिटाने के इवेंट का जवाब देने वाले दूसरे फ़ंक्शन को डिप्लॉय करें:
export SERVICE_NAME=trigger-workflow-on-delete
gcloud functions deploy ${SERVICE_NAME} \
--source=. \
--runtime nodejs10 \
--entry-point=trigger_workflow \
--trigger-resource=${BUCKET_PICTURES} \
--trigger-event=google.storage.object.delete \
--allow-unauthenticated \
--set-env-vars GOOGLE_CLOUD_PROJECT=${GOOGLE_CLOUD_PROJECT},WORKFLOW_REGION=${WORKFLOW_REGION},WORKFLOW_NAME=${WORKFLOW_NAME},THUMBNAILS_URL=${THUMBNAILS_URL},COLLAGE_URL=${COLLAGE_URL},VISION_DATA_TRANSFORM_URL=${VISION_DATA_TRANSFORM_URL}
डप्लॉयमेंट पूरा होने के बाद, आपको Cloud Console में दोनों फ़ंक्शन दिखेंगे:

14. फ़्रंटएंड (App Engine)
इस चरण में, आपको Google App Engine पर एक वेब फ़्रंटएंड बनाना होगा. इसके लिए, Pic-a-daily: Lab 4—Create a web frontend का इस्तेमाल करें. इससे उपयोगकर्ता, वेब ऐप्लिकेशन से फ़ोटो अपलोड कर पाएंगे. साथ ही, अपलोड की गई फ़ोटो और उनके थंबनेल ब्राउज़ कर पाएंगे.

App Engine के बारे में ज़्यादा जानें. साथ ही, Pic-a-daily: Lab 4—Create a web frontend में कोड के बारे में पढ़ें.
कोड के बारे में ज़्यादा जानें
App Engine ऐप्लिकेशन का नाम frontend है. इसका पूरा कोड index.js में देखा जा सकता है.
App Engine पर डिप्लॉय करना
इस फ़ोल्डर पर जाएं:
cd frontend
अपनी पसंद का देश/इलाका सेट करें. साथ ही, app.yaml में मौजूद GOOGLE_CLOUD_PROJECT की जगह अपना असल प्रोजेक्ट आईडी डालें:
export REGION=europe-west1
gcloud config set compute/region ${REGION}
sed -i -e "s/GOOGLE_CLOUD_PROJECT/${GOOGLE_CLOUD_PROJECT}/" app.yaml
डिप्लॉय करना:
gcloud app deploy app.yaml -q
एक या दो मिनट के बाद, आपको बताया जाएगा कि ऐप्लिकेशन ट्रैफ़िक दिखा रहा है या नहीं:
Beginning deployment of service [default]... ╔════════════════════════════════════════════════════════════╗ ╠═ Uploading 8 files to Google Cloud Storage ═╣ ╚════════════════════════════════════════════════════════════╝ File upload done. Updating service [default]...done. Setting traffic split for service [default]...done. Deployed service [default] to [https://GOOGLE_CLOUD_PROJECT.appspot.com] You can stream logs from the command line by running: $ gcloud app logs tail -s default To view your application in the web browser run: $ gcloud app browse
ऐप्लिकेशन को डिप्लॉय किया गया है या नहीं, यह देखने के लिए Cloud Console के App Engine सेक्शन पर जाएं. साथ ही, App Engine की सुविधाओं के बारे में जानें. जैसे, वर्शनिंग और ट्रैफ़िक स्प्लिटिंग:

15. Workflows की जांच करना
जांच करने के लिए, ऐप्लिकेशन के डिफ़ॉल्ट App Engine यूआरएल (https://<YOUR_PROJECT_ID>.appspot.com/) पर जाएं. आपको फ़्रंटएंड यूज़र इंटरफ़ेस (यूआई) चालू दिखेगा!

कोई फ़ोटो अपलोड करें. इससे वर्कफ़्लो ट्रिगर हो जाना चाहिए. साथ ही, आपको Cloud Console में वर्कफ़्लो के एक्ज़ीक्यूशन की स्थिति Active के तौर पर दिखनी चाहिए:

वर्कफ़्लो पूरा होने के बाद, एक्ज़ीक्यूशन आईडी पर क्लिक करके, अलग-अलग सेवाओं से मिला आउटपुट देखा जा सकता है:

तीन और फ़ोटो अपलोड करें. आपको Cloud Storage बकेट और App Engine फ़्रंटएंड में अपडेट की गई इमेज का थंबनेल और कोलाज भी दिखना चाहिए:

16. डेटा साफ़ करना (ज़रूरी नहीं)
अगर आपको ऐप्लिकेशन नहीं रखना है, तो लागत बचाने के लिए संसाधनों को क्लीन अप किया जा सकता है. साथ ही, पूरे प्रोजेक्ट को मिटाकर, क्लाउड का बेहतर तरीके से इस्तेमाल किया जा सकता है:
gcloud projects delete ${GOOGLE_CLOUD_PROJECT}
17. बधाई हो!
आपने सेवाओं को व्यवस्थित करने और उन्हें कॉल करने के लिए, Workflows का इस्तेमाल करके ऐप्लिकेशन का ऑर्केस्ट्रेटेड वर्शन बनाया हो.
हमने क्या-क्या बताया
- App Engine
- Cloud Firestore
- Cloud Functions
- Cloud Run
- वर्कफ़्लो