১. সংক্ষিপ্ত বিবরণ
পূর্ববর্তী ল্যাবগুলিতে, আপনারা Pic-a-daily অ্যাপটির একটি ইভেন্ট-ড্রাইভেন সংস্করণ তৈরি করেছিলেন, যেখানে ইমেজ অ্যানালাইসিস সার্ভিসের জন্য গুগল ক্লাউড স্টোরেজ দ্বারা ট্রিগার করা একটি ক্লাউড ফাংশন, থাম্বনেইল সার্ভিসের জন্য পাব/সাব (Pub/Sub) এর মাধ্যমে জিসিএস (GCS) দ্বারা ট্রিগার করা একটি ক্লাউড রান কন্টেইনার এবং ক্লাউড রানে ইমেজ গারবেজ কালেক্টর সার্ভিসটি ট্রিগার করার জন্য ইভেন্টআর্ক (Eventarc) ব্যবহৃত হয়েছিল। এছাড়াও একটি ক্লাউড শিডিউলার দ্বারা ট্রিগার করা কোলাজ সার্ভিসও ছিল।

এই ল্যাবে, আপনি অ্যাপটির একটি অর্কেস্ট্রেটেড সংস্করণ তৈরি করবেন। সিস্টেমের মধ্য দিয়ে বিভিন্ন ধরণের ইভেন্ট প্রবাহিত হওয়ার পরিবর্তে, আপনি নিম্নলিখিতভাবে সার্ভিসগুলোকে অর্কেস্ট্রেট ও কল করার জন্য ওয়ার্কফ্লো ব্যবহার করবেন:

আপনি যা শিখবেন
- অ্যাপ ইঞ্জিন
- ক্লাউড ফায়ারস্টোর
- ক্লাউড ফাংশন
- ক্লাউড রান
- ওয়ার্কফ্লো
২. সেটআপ এবং প্রয়োজনীয়তা
স্ব-গতিতে পরিবেশ সেটআপ
- ক্লাউড কনসোলে সাইন ইন করুন এবং একটি নতুন প্রজেক্ট তৈরি করুন অথবা বিদ্যমান কোনো প্রজেক্ট পুনরায় ব্যবহার করুন। (যদি আপনার আগে থেকে Gmail বা Google Workspace অ্যাকাউন্ট না থাকে, তবে আপনাকে অবশ্যই একটি তৈরি করতে হবে।)



প্রজেক্ট আইডিটি মনে রাখবেন, যা সমস্ত গুগল ক্লাউড প্রজেক্ট জুড়ে একটি অনন্য নাম (উপরের নামটি ইতিমধ্যে ব্যবহৃত হয়েছে এবং আপনার জন্য কাজ করবে না, দুঃখিত!)। এই কোডল্যাবে এটিকে পরবর্তীতে PROJECT_ID হিসাবে উল্লেখ করা হবে।
- এরপরে, গুগল ক্লাউড রিসোর্স ব্যবহার করার জন্য আপনাকে ক্লাউড কনসোলে বিলিং চালু করতে হবে।
এই কোডল্যাবটি চালাতে খুব বেশি খরচ হওয়ার কথা নয়, এমনকি আদৌ কোনো খরচ নাও হতে পারে। "পরিষ্কার-পরিচ্ছন্নতা" (Cleaning up) বিভাগে দেওয়া নির্দেশাবলী অবশ্যই অনুসরণ করবেন, যেখানে রিসোর্স বন্ধ করার পরামর্শ দেওয়া হয়েছে, যাতে এই টিউটোরিয়ালের বাইরে আপনার কোনো বিল না আসে। গুগল ক্লাউডের নতুন ব্যবহারকারীরা ৩০০ মার্কিন ডলারের ফ্রি ট্রায়াল প্রোগ্রামের জন্য যোগ্য।
ক্লাউড শেল শুরু করুন
যদিও গুগল ক্লাউড আপনার ল্যাপটপ থেকে দূরবর্তীভাবে পরিচালনা করা যায়, এই কোডল্যাবে আপনি গুগল ক্লাউড শেল ব্যবহার করবেন, যা ক্লাউডে চালিত একটি কমান্ড লাইন পরিবেশ।
GCP কনসোল থেকে উপরের ডানদিকের টুলবারে থাকা ক্লাউড শেল আইকনে ক্লিক করুন:

পরিবেশটি প্রস্তুত করতে এবং এর সাথে সংযোগ স্থাপন করতে মাত্র কয়েক মুহূর্ত সময় লাগবে। এটি শেষ হলে, আপনি এইরকম কিছু দেখতে পাবেন:

এই ভার্চুয়াল মেশিনটিতে আপনার প্রয়োজনীয় সমস্ত ডেভেলপমেন্ট টুলস লোড করা আছে। এটি একটি স্থায়ী ৫ জিবি হোম ডিরেক্টরি প্রদান করে এবং গুগল ক্লাউডে চলে, যা নেটওয়ার্ক পারফরম্যান্স ও অথেনটিকেশনকে ব্যাপকভাবে উন্নত করে। এই ল্যাবে আপনার সমস্ত কাজ শুধুমাত্র একটি ব্রাউজার দিয়েই করা যাবে।
৩. ওয়ার্কফ্লো পরিচিতি

আপনি ওয়ার্কফ্লো ব্যবহার করে সার্ভারলেস ওয়ার্কফ্লো তৈরি করতে পারেন, যা আপনার সংজ্ঞায়িত ক্রমানুসারে একাধিক সার্ভারলেস টাস্ককে একসাথে সংযুক্ত করে। আপনি গুগল ক্লাউডের এপিআই, ক্লাউড ফাংশন ও ক্লাউড রানের মতো সার্ভারলেস প্রোডাক্ট এবং এক্সটার্নাল এপিআই কলের শক্তিকে একত্রিত করে নমনীয় সার্ভারলেস অ্যাপ্লিকেশন তৈরি করতে পারেন।
একজন অর্কেস্ট্রেটর হিসেবে যেমনটা আশা করা যায়, Workflows আপনাকে একটি YAML/JSON ভিত্তিক ওয়ার্কফ্লো ডেফিনিশন ল্যাঙ্গুয়েজে আপনার বিজনেস লজিকের প্রবাহ নির্ধারণ করার সুযোগ দেয় এবং সেই ফ্লোগুলোকে ট্রিগার করার জন্য একটি Workflows Execution API ও Workflows UI প্রদান করে।
এই অন্তর্নির্মিত এবং কনফিগারযোগ্য বৈশিষ্ট্যগুলির কারণে এটি কেবল একটি অর্কেস্ট্রেটরের চেয়েও বেশি কিছু:
- ধাপগুলোর নির্ভরযোগ্য সম্পাদনের জন্য সেগুলোর মধ্যে নমনীয় পুনঃপ্রচেষ্টা এবং ত্রুটি ব্যবস্থাপনা।
- গ্লু-কোড এড়ানোর জন্য JSON পার্সিং এবং ধাপগুলোর মধ্যে ভেরিয়েবল পাসিং।
- সিদ্ধান্তের জন্য ব্যবহৃত এক্সপ্রেশন ফর্মুলা শর্তসাপেক্ষ ধাপ সম্পাদনের সুযোগ দেয়।
- মডিউলার এবং পুনঃব্যবহারযোগ্য ওয়ার্কফ্লো-এর জন্য সাবওয়ার্কফ্লো।
- বাহ্যিক পরিষেবাগুলির জন্য সমর্থন গুগল ক্লাউডের বাইরেও পরিষেবাগুলির সমন্বয় সাধন করতে দেয়।
- নিরাপদ ধাপ সম্পাদনের জন্য গুগল ক্লাউড এবং বাহ্যিক পরিষেবাগুলোর প্রমাণীকরণ সমর্থন।
- সহজ ইন্টিগ্রেশনের জন্য গুগল ক্লাউড পরিষেবা যেমন পাব/সাব, ফায়ারস্টোর, টাস্ক, সিক্রেট ম্যানেজারের সাথে কানেক্টর।
উল্লেখ্য যে, Workflows একটি সম্পূর্ণ পরিচালিত সার্ভারবিহীন পণ্য। এখানে কোনো সার্ভার কনফিগার বা স্কেল করার প্রয়োজন নেই এবং আপনি কেবল আপনার ব্যবহারের জন্যই অর্থ প্রদান করেন।
৪. এপিআই সক্রিয় করুন
এই ল্যাবে, আপনারা ক্লাউড ফাংশন এবং ক্লাউড রান সার্ভিসগুলোকে ওয়ার্কফ্লো-এর সাথে সংযুক্ত করবেন। এছাড়াও আপনারা অ্যাপ ইঞ্জিন, ক্লাউড বিল্ড, ভিশন এপিআই এবং অন্যান্য সার্ভিস ব্যবহার করবেন।
ক্লাউড শেলে, প্রয়োজনীয় সকল সার্ভিস চালু আছে কিনা তা নিশ্চিত করুন:
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.
৫. কোডটি সংগ্রহ করুন।
আগের কোড ল্যাবগুলো থেকে কোডটি নিয়ে নিন, যদি আগে থেকে না নিয়ে থাকেন:
git clone https://github.com/GoogleCloudPlatform/serverless-photosharing-workshop
এই ল্যাবের জন্য প্রাসঙ্গিক ফোল্ডার কাঠামোটি নিম্নরূপ হবে:
frontend | workflows | ├── functions ├── |── trigger-workflow ├── |── vision-data-transform ├── services ├── |── collage ├── |── thumbnails ├── workflows.yaml
এইগুলো হলো প্রাসঙ্গিক ফোল্ডারগুলো:
-
frontendঅ্যাপ ইঞ্জিন ফ্রন্টএন্ডটি রয়েছে, যা আমরা ল্যাব ৪ থেকে পুনরায় ব্যবহার করব। -
functionsমধ্যে ওয়ার্কফ্লো-এর জন্য তৈরি করা ক্লাউড ফাংশনগুলো থাকে। -
servicesমধ্যে Workflow-এর জন্য পরিবর্তিত Cloud Run সার্ভিসগুলো অন্তর্ভুক্ত রয়েছে। -
workflows.yamlহলো ওয়ার্কফ্লো সংজ্ঞা ফাইল।
৬. ওয়ার্কফ্লো YAML অন্বেষণ করুন
workflows.yaml ফাইলটি কয়েকটি ধাপে ওয়ার্কফ্লো-কে সংজ্ঞায়িত করে। চলুন, বিষয়টি আরও ভালোভাবে বোঝার জন্য এটি পর্যালোচনা করা যাক।
ওয়ার্কফ্লোর শুরুতে কিছু প্যারামিটার পাস করা হয়। ওয়ার্কফ্লো চালু করার জন্য দুটি ক্লাউড ফাংশনের মাধ্যমে এই প্যারামিটারগুলো পাস করা হবে। আমরা এই ফাংশনগুলো নিয়ে পরে আলোচনা করব, কিন্তু ওয়ার্কফ্লোটি এভাবেই শুরু হয়:

YAML-এ আপনি দেখতে পারেন যে, init ধাপে এই প্যারামিটারগুলো ভেরিয়েবলে অ্যাসাইন করা হয়, যেমন ইভেন্টটি ট্রিগারকারী ফাইল ও বাকেটের নাম এবং কিছু ক্লাউড ফাংশন ও ক্লাউড রান সার্ভিসের URL, যেগুলোকে ওয়ার্কফ্লো কল করবে:
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 (কোনো ফাইল ডিলিট করার সময় এটি নির্গত হয়)। অন্য কিছু হলে 'ইভেন্ট সমর্থিত নয়' (event not supported) এক্সেপশন তৈরি হবে।

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
লক্ষ্য করুন, Workflow কীভাবে switch স্টেটমেন্ট এবং এক্সেপশন হ্যান্ডলিং সমর্থন করে; এর জন্য রয়েছে switch ইনস্ট্রাকশন ও এর বিভিন্ন শর্ত, এবং ইভেন্টটি শনাক্ত না হলে একটি এরর দেখানোর জন্য raise ইনস্ট্রাকশন।
এরপর, চলুন imageAnalysisCall টি দেখে নেওয়া যাক। এটি হলো ওয়ার্কফ্লো থেকে করা একাধিক কলের একটি সিরিজ, যা ছবিটি বিশ্লেষণ করার জন্য ভিশন এপিআই-কে কল করে, ছবিতে শনাক্ত করা জিনিসগুলোর লেবেল সাজানোর জন্য ভিশন এপিআই-এর রেসপন্স ডেটা রূপান্তর করে, প্রধান রঙগুলো বাছাই করে, ছবিটি প্রদর্শনের জন্য নিরাপদ কিনা তা পরীক্ষা করে এবং সবশেষে মেটাডেটা ক্লাউড ফায়ারস্টোরে সংরক্ষণ করে।
উল্লেখ্য যে, ভিশন ট্রান্সফর্ম ক্লাউড ফাংশনগুলো (যা আমরা পরে ডেপ্লয় করব) ছাড়া বাকি সবকিছুই ওয়ার্কফ্লো-তে করা হয়।

YAML-এ ধাপগুলো দেখতে এইরকম:
- 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
ছবিটি বিশ্লেষণ করা হয়ে গেলে, পরবর্তী দুটি ধাপ হলো ছবিটির থাম্বনেইল এবং সবচেয়ে সাম্প্রতিক ছবিগুলোর একটি কোলাজ তৈরি করা। এটি করার জন্য দুটি ক্লাউড রান সার্ভিস ডেপ্লয় করা হয় এবং 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}
এক্সিকিউশনের অন্য একটি পর্যায় হলো যখন মূল স্টোরেজ বাকেট থেকে কোনো ফাইল ডিলিট করা হয়, যেটিতে ছবিগুলোর হাই-রেজোলিউশন ভার্সনগুলো থাকে। এই পর্যায়ে, আমরা থাম্বনেইল ধারণকারী বাকেট থেকে ছবিটির থাম্বনেইল এবং ফায়ারস্টোর থেকে এর মেটাডেটা ডিলিট করতে চাই। এই দুটি কাজই ওয়ার্কফ্লো থেকে HTTP কলের মাধ্যমে করা হয়।

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}
পরবর্তী ধাপগুলোতে, আমরা ওয়ার্কফ্লো-এর সমস্ত বাহ্যিক নির্ভরতা তৈরি করব: বাকেট, ক্লাউড ফাংশন, ক্লাউড রান পরিষেবা এবং ফায়ারস্টোর ডেটাবেস।
৭. বালতিগুলো তৈরি করুন
ছবি সংরক্ষণের জন্য আপনার দুটি বাকেট প্রয়োজন: একটি মূল উচ্চ-রেজোলিউশনের ছবি সংরক্ষণের জন্য এবং অন্যটি ছবির থাম্বনেইল সংরক্ষণের জন্য।
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}
ক্লাউড কনসোলের ক্লাউড স্টোরেজ বিভাগে গিয়ে আপনি বাকেটগুলি তৈরি এবং পাবলিক করা হয়েছে কিনা তা পুনরায় যাচাই করতে পারেন:

৮. ভিশন ডেটা ট্রান্সফর্ম (ক্লাউড ফাংশন)
Workflows.yaml ফাইলটি init , eventTypeSwitch , eventTypeNotSupported স্টেপগুলো দিয়ে শুরু হয়। এগুলো নিশ্চিত করে যে বাকেট থেকে আসা ইভেন্টগুলো সঠিক স্টেপগুলোতে পাঠানো হচ্ছে।
object.finalize ইভেন্টের জন্য, imageAnalysisCall স্টেপটি তৈরি করা ইমেজের মেটাডেটা বের করার জন্য ভিশন এপিআই-কে (Vision API) কল করে। এই সমস্ত ধাপ ওয়ার্কফ্লো-এর (Workflows) মধ্যেই সম্পন্ন করা হয়:

এরপরে, ফায়ারস্টোরে সংরক্ষণ করার আগে, ভিশন এপিআই থেকে প্রাপ্ত ডেটা রূপান্তর করতে হবে। আরও নির্দিষ্টভাবে বললে, আমাদের যা করতে হবে তা হলো:
- ছবিটির জন্য প্রাপ্ত লেবেলগুলো তালিকাভুক্ত করুন।
- ছবিটির প্রধান রঙটি শনাক্ত করুন।
- ছবিটি নিরাপদ কিনা তা নির্ধারণ করুন।
এটি একটি ক্লাউড ফাংশনের কোডে করা হয় এবং ওয়ার্কফ্লো কেবল এই ফাংশনটিকে কল করে:

কোডটি অন্বেষণ করুন
ক্লাউড ফাংশনটির নাম হলো vision-data-transform । আপনি এর সম্পূর্ণ কোড index.js- এ দেখতে পারেন। যেমনটি দেখতে পাচ্ছেন, এই ফাংশনটির একমাত্র উদ্দেশ্য হলো JSON থেকে JSON-এ রূপান্তর করা, যাতে ছবির মেটাডেটা ফায়ারস্টোরে সুবিধাজনকভাবে সংরক্ষণ করা যায়।
ক্লাউড ফাংশনে স্থাপন করুন
ফোল্ডারটিতে যান:
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
ফাংশনটি ডেপ্লয় করা হয়ে গেলে, ওয়ার্কফ্লো-এর transformImageAnalysisData স্টেপটি ভিশন এপিআই ডেটা ট্রান্সফরমেশন করার জন্য এই ফাংশনটিকে কল করতে পারবে।
৯. ডাটাবেস প্রস্তুত করুন।
ওয়ার্কফ্লো-এর পরবর্তী ধাপে ইমেজ ডেটা থেকে ছবিটির নিরাপত্তা যাচাই করা হয় এবং তারপর ভিশন এপিআই (Vision API) দ্বারা প্রাপ্ত ছবিটির তথ্য ক্লাউড ফায়ারস্টোর (Cloud Firestore) ডেটাবেসে সংরক্ষণ করা হয়, যা একটি দ্রুত, সম্পূর্ণভাবে পরিচালিত, সার্ভারবিহীন, ক্লাউড-নেটিভ নোএসকিউএল (NoSQL) ডকুমেন্ট ডেটাবেস।

এই দুটি কাজই ওয়ার্কফ্লো-এর মাধ্যমে করা হয়, কিন্তু মেটাডেটা সংরক্ষণের জন্য আপনাকে ফায়ারস্টোর ডেটাবেস তৈরি করতে হবে।
প্রথমে, যে অঞ্চলে আপনি ফায়ারস্টোর ডেটাবেসটি চান, সেখানে একটি অ্যাপ ইঞ্জিন অ্যাপ তৈরি করুন (ফায়ারস্টোরের জন্য এটি একটি পূর্বশর্ত):
export REGION_FIRESTORE=europe-west2
gcloud app create --region=${REGION_FIRESTORE}
এরপরে, একই অঞ্চলে ফায়ারস্টোর ডাটাবেস তৈরি করুন:
gcloud firestore databases create --region=${REGION_FIRESTORE}
ডকুমেন্টগুলো আমাদের সংগ্রহে প্রোগ্রাম্যাটিকভাবে তৈরি করা হবে এবং এতে ৪টি ফিল্ড থাকবে:
- নাম (স্ট্রিং): আপলোড করা ছবির ফাইলের নাম, যা ডকুমেন্টটির কী-ও বটে।
- লেবেল (স্ট্রিং-এর অ্যারে): ভিশন এপিআই দ্বারা শনাক্তকৃত আইটেমগুলোর লেবেল।
- color (string): প্রধান রঙের হেক্সাডেসিমাল কোড (যেমন, #ab12ef)
- তৈরি হওয়ার তারিখ: এই ছবিটির মেটাডেটা সংরক্ষণের সময়কার টাইমস্ট্যাম্প।
- থাম্বনেইল (বুলিয়ান): একটি ঐচ্ছিক ক্ষেত্র যা তখনই উপস্থিত থাকবে এবং 'ট্রু' হবে, যদি এই ছবিটির জন্য একটি থাম্বনেইল ছবি তৈরি করা হয়ে থাকে।
যেহেতু আমরা ফায়ারস্টোরে থাম্বনেইল সহ ছবি খুঁজব এবং তৈরির তারিখ অনুসারে সাজাব, তাই আমাদের একটি সার্চ ইনডেক্স তৈরি করতে হবে। আপনি নিম্নলিখিত কমান্ডটি ব্যবহার করে ইনডেক্সটি তৈরি করতে পারেন:
gcloud firestore indexes composite create --collection-group=pictures \ --field-config field-path=thumbnail,order=descending \ --field-config field-path=created,order=descending
মনে রাখবেন, ইনডেক্স তৈরি হতে প্রায় ১০ মিনিট পর্যন্ত সময় লাগতে পারে।
ইনডেক্সটি তৈরি হয়ে গেলে, আপনি এটি ক্লাউড কনসোলে দেখতে পাবেন:

এখন থেকে ওয়ার্কফ্লো-এর storeMetadata ধাপটি ফায়ারস্টোরে ছবির মেটাডেটা সংরক্ষণ করতে পারবে।
১০. থাম্বনেইল পরিষেবা (ক্লাউড রান)
এর পরের ধাপ হলো একটি ছবির থাম্বনেইল তৈরি করা। এই কাজটি কোডের মাধ্যমে একটি ক্লাউড রান সার্ভিসে করা হয় এবং ওয়ার্কফ্লো তার thumbnailCall ধাপে এই সার্ভিসটিকে কল করে:

কোডটি অন্বেষণ করুন
ক্লাউড রান সার্ভিসটির নাম হলো thumbnails । আপনি এর সম্পূর্ণ কোড index.js- এ দেখতে পারেন।
কন্টেইনার ইমেজটি বিল্ড এবং পাবলিশ করুন
ক্লাউড রান কন্টেইনার চালাতে পারে, কিন্তু তার জন্য প্রথমে আপনাকে কন্টেইনার ইমেজটি বিল্ড করতে হবে (যা Dockerfile সংজ্ঞায়িত থাকে)। কন্টেইনার ইমেজ বিল্ড করার জন্য এবং তারপর গুগল কন্টেইনার রেজিস্ট্রি-তে হোস্ট করার জন্য গুগল ক্লাউড বিল্ড ব্যবহার করা যেতে পারে।
ফোল্ডারটিতে যান:
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}
এক বা দুই মিনিটের মধ্যে বিল্ডটি সফল হবে এবং কন্টেইনারটি গুগল কন্টেইনার রেজিস্ট্রি-তে ডেপ্লয় করা হবে।
ক্লাউড রানে স্থাপন করুন
প্রয়োজনীয় কিছু ভেরিয়েবল ও কনফিগারেশন সেট করুন:
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 স্টেপটি এই সার্ভিসটিকে কল করতে পারবে।
১১. কলেজ পরিষেবা (ক্লাউড রান)
এর পরের ধাপ হলো সবচেয়ে সাম্প্রতিক ছবিগুলো থেকে একটি কোলাজ তৈরি করা। এই কাজটি একটি ক্লাউড রান সার্ভিসে কোডের মাধ্যমে করা হয় এবং ওয়ার্কফ্লো তার collageCall ধাপে এই সার্ভিসটিকে কল করে:

কোডটি অন্বেষণ করুন
ক্লাউড রান সার্ভিসটির নাম হলো collage । আপনি এর সম্পূর্ণ কোড index.js- এ দেখতে পারেন।
কন্টেইনার ইমেজটি বিল্ড এবং পাবলিশ করুন
ক্লাউড রান কন্টেইনার চালাতে পারে, কিন্তু তার জন্য প্রথমে আপনাকে কন্টেইনার ইমেজটি বিল্ড করতে হবে (যা Dockerfile সংজ্ঞায়িত থাকে)। কন্টেইনার ইমেজ বিল্ড করার জন্য এবং তারপর গুগল কন্টেইনার রেজিস্ট্রি-তে হোস্ট করার জন্য গুগল ক্লাউড বিল্ড ব্যবহার করা যেতে পারে।
ফোল্ডারটিতে যান:
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}
এক বা দুই মিনিটের মধ্যে বিল্ডটি সফল হবে এবং কন্টেইনারটি গুগল কন্টেইনার রেজিস্ট্রি-তে ডেপ্লয় করা হবে।
ক্লাউড রানে স্থাপন করুন
প্রয়োজনীয় কিছু ভেরিয়েবল ও কনফিগারেশন সেট করুন:
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}
সার্ভিসটি ডেপ্লয় করা হয়ে গেলে, আপনি ক্লাউড কনসোলের ক্লাউড রান সেকশনে উভয় সার্ভিসই চালু আছে কিনা তা পরীক্ষা করতে পারবেন এবং ওয়ার্কফ্লো-এর collageCall স্টেপটি এই সার্ভিসটিকে কল করতে পারবে:

১২. ওয়ার্কফ্লো স্থাপন
আমরা 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}
কয়েক সেকেন্ডের মধ্যেই ওয়ার্কফ্লোটি ডেপ্লয় হয়ে যাবে এবং আপনি এটি ক্লাউড কনসোলের ওয়ার্কফ্লো বিভাগে দেখতে পাবেন:

আপনি চাইলে ওয়ার্কফ্লো-টিতে ক্লিক করে তা সম্পাদনা করতে পারেন। সম্পাদনা করার সময়, আপনি ওয়ার্কফ্লো-টির একটি সুন্দর ভিজ্যুয়াল উপস্থাপনা দেখতে পাবেন:

আপনি সঠিক প্যারামিটার ব্যবহার করে ক্লাউড কনসোল থেকে ম্যানুয়ালিও ওয়ার্কফ্লোটি চালাতে পারেন। এর পরিবর্তে, আমরা পরবর্তী ধাপে ক্লাউড স্টোরেজ ইভেন্টের প্রতিক্রিয়ায় এটি স্বয়ংক্রিয়ভাবে চালাব।
১৩. ওয়ার্কফ্লো ট্রিগার (ক্লাউড ফাংশন)
ওয়ার্কফ্লোটি ডেপ্লয় করা হয়েছে এবং প্রস্তুত। এখন, ক্লাউড স্টোরেজ বাকেটে কোনো ফাইল তৈরি বা ডিলিট করা হলে ওয়ার্কফ্লোটি ট্রিগার করতে হবে। এগুলো হলো যথাক্রমে storage.object.finalize এবং storage.object.delete ইভেন্ট।
ওয়ার্কফ্লো তৈরি, পরিচালনা এবং কার্যকর করার জন্য এপিআই (API) ও ক্লায়েন্ট লাইব্রেরি রয়েছে, যা আপনি ব্যবহার করতে পারেন। এক্ষেত্রে, ওয়ার্কফ্লোটি চালু করার জন্য আপনি ওয়ার্কফ্লো এক্সিকিউশন এপিআই (Workflows Execution API) এবং বিশেষত এর নোড.জেএস (Node.js) ক্লায়েন্ট লাইব্রেরি ব্যবহার করবেন।
আপনি ক্লাউড স্টোরেজ ইভেন্ট লিসেন করা ক্লাউড ফাংশন থেকে ওয়ার্কফ্লোগুলো ট্রিগার করবেন। যেহেতু একটি ক্লাউড ফাংশন শুধুমাত্র এক ধরনের ইভেন্ট লিসেন করতে পারে, তাই আপনি ক্রিয়েট এবং ডিলিট উভয় ইভেন্ট লিসেন করার জন্য দুটি ক্লাউড ফাংশন ডেপ্লয় করবেন:

কোডটি অন্বেষণ করুন
ক্লাউড ফাংশনটির নাম trigger-workflow । আপনি এর সম্পূর্ণ কোড index.js- এ দেখতে পারেন।
ক্লাউড ফাংশনে স্থাপন করুন
ফোল্ডারটিতে যান:
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}
ডেপ্লয়মেন্ট সম্পূর্ণ হলে, আপনি ক্লাউড কনসোলে উভয় ফাংশনই দেখতে পাবেন:

১৪. ফ্রন্টএন্ড (অ্যাপ ইঞ্জিন)

আপনি অ্যাপ ইঞ্জিন সম্পর্কে আরও জানতে এবং কোডের বিবরণ পড়তে পারেন পিক-এ-ডেইলি: ল্যাব ৪—একটি ওয়েব ফ্রন্টএন্ড তৈরি করুন -এ।
কোডটি অন্বেষণ করুন
অ্যাপ ইঞ্জিন অ্যাপটিকে frontend বলা হয়। আপনি এর সম্পূর্ণ কোড index.js- এ দেখতে পারেন।
অ্যাপ ইঞ্জিনে স্থাপন করুন
ফোল্ডারটিতে যান:
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
অ্যাপটি ডেপ্লয় করা হয়েছে কিনা তা দেখতে এবং ভার্সনিং ও ট্র্যাফিক স্প্লিটিং-এর মতো অ্যাপ ইঞ্জিনের ফিচারগুলো অন্বেষণ করতে আপনি ক্লাউড কনসোলের অ্যাপ ইঞ্জিন সেকশনেও যেতে পারেন:

১৫. ওয়ার্কফ্লোগুলো পরীক্ষা করুন
পরীক্ষা করার জন্য, অ্যাপটির ডিফল্ট অ্যাপ ইঞ্জিন ইউআরএল-এ ( https://<YOUR_PROJECT_ID>.appspot.com/ ) যান এবং আপনি ফ্রন্টএন্ড ইউআইটি চালু দেখতে পাবেন!

একটি ছবি আপলোড করুন। এটি ওয়ার্কফ্লো চালু করবে এবং আপনি ক্লাউড কনসোলে ওয়ার্কফ্লো এক্সিকিউশন Active অবস্থায় দেখতে পাবেন।

ওয়ার্কফ্লো সম্পন্ন হয়ে গেলে, আপনি এক্সিকিউশন আইডিতে ক্লিক করে বিভিন্ন সার্ভিস থেকে আউটপুট দেখতে পারবেন:

আরও ৩টি ছবি আপলোড করুন। এছাড়াও আপনি ক্লাউড স্টোরেজ বাকেট এবং অ্যাপ ইঞ্জিন ফ্রন্টএন্ডে ছবিগুলোর থাম্বনেইল ও কোলাজ আপডেট হতে দেখবেন।

১৬. পরিষ্কার করা (ঐচ্ছিক)
যদি আপনি অ্যাপটি রাখতে না চান, তাহলে খরচ বাঁচাতে এবং সার্বিকভাবে একজন ভালো ক্লাউড ব্যবহারকারী হতে পুরো প্রজেক্টটি ডিলিট করে রিসোর্সগুলো পরিষ্কার করতে পারেন:
gcloud projects delete ${GOOGLE_CLOUD_PROJECT}
১৭. অভিনন্দন!
আপনি সার্ভিসগুলোকে অর্কেস্ট্রেট ও কল করার জন্য ওয়ার্কফ্লো ব্যবহার করে অ্যাপটির একটি অর্কেস্ট্রেটেড সংস্করণ তৈরি করেছেন।
আমরা যা আলোচনা করেছি
- অ্যাপ ইঞ্জিন
- ক্লাউড ফায়ারস্টোর
- ক্লাউড ফাংশন
- ক্লাউড রান
- ওয়ার্কফ্লো