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

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



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

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

এই ভার্চুয়াল মেশিনটিতে আপনার প্রয়োজনীয় সমস্ত ডেভেলপমেন্ট টুলস লোড করা আছে। এটি একটি স্থায়ী ৫ জিবি হোম ডিরেক্টরি প্রদান করে এবং গুগল ক্লাউডে চলে, যা নেটওয়ার্ক পারফরম্যান্স ও অথেনটিকেশনকে ব্যাপকভাবে উন্নত করে। এই ল্যাবে আপনার সমস্ত কাজ শুধুমাত্র একটি ব্রাউজার দিয়েই করা যাবে।
৩. এপিআই সক্রিয় করুন
এই ল্যাবে কন্টেইনার ইমেজ তৈরি করার জন্য আপনার ক্লাউড বিল্ড এবং কন্টেইনারটি ডেপ্লয় করার জন্য ক্লাউড রান প্রয়োজন হবে।
ক্লাউড শেল থেকে উভয় এপিআই সক্রিয় করুন:
gcloud services enable cloudbuild.googleapis.com \ run.googleapis.com
অপারেশনটি সফলভাবে সম্পন্ন হতে দেখা উচিত:
Operation "operations/acf.5c5ef4f6-f734-455d-b2f0-ee70b5a17322" finished successfully.
৪. আরেকটি বাকেট তৈরি করুন
আপনি আপলোড করা ছবিগুলোর থাম্বনেইল অন্য একটি বাকেটে সংরক্ষণ করবেন। চলুন, gsutil ব্যবহার করে দ্বিতীয় বাকেটটি তৈরি করি।
ক্লাউড শেলের ভিতরে, অনন্য বাকেট নামের জন্য একটি ভেরিয়েবল সেট করুন। ক্লাউড শেলে ইতিমধ্যেই GOOGLE_CLOUD_PROJECT আপনার অনন্য প্রজেক্ট আইডি হিসাবে সেট করা আছে। আপনি সেটি বাকেট নামের সাথে যুক্ত করতে পারেন। তারপর, ইউরোপে ইউনিফর্ম লেভেল অ্যাক্সেস সহ একটি পাবলিক মাল্টি-রিজিওন বাকেট তৈরি করুন:
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
অবশেষে, আপনার একটি নতুন পাবলিক বাকেট তৈরি হবে:

৫. কোডটি ক্লোন করুন
কোডটি ক্লোন করুন এবং সার্ভিসটি যে ডিরেক্টরিতে রয়েছে সেখানে যান:
git clone https://github.com/GoogleCloudPlatform/serverless-photosharing-workshop cd serverless-photosharing-workshop/services/thumbnails/nodejs
পরিষেবাটির জন্য আপনার কাছে নিম্নলিখিত ফাইল বিন্যাস থাকবে:
services
|
├── thumbnails
|
├── nodejs
|
├── Dockerfile
├── index.js
├── package.json
thumbnails/nodejs ফোল্ডারের ভিতরে ৩টি ফাইল আছে:
-
index.jsNode.js কোড রয়েছে -
package.jsonলাইব্রেরির নির্ভরতাগুলো সংজ্ঞায়িত করে। -
Dockerfileকন্টেইনার ইমেজ সংজ্ঞায়িত করে।
৬. কোডটি অন্বেষণ করুন
কোডটি দেখার জন্য, আপনি ক্লাউড শেল উইন্ডোর উপরে থাকা Open Editor বোতামে ক্লিক করে বিল্ট-ইন টেক্সট এডিটরটি ব্যবহার করতে পারেন:

আরও বেশি স্ক্রিন স্পেসের জন্য, আপনি এডিটরটি একটি ডেডিকেটেড ব্রাউজার উইন্ডোতেও খুলতে পারেন।
নির্ভরশীলতা
package.json ফাইলটি প্রয়োজনীয় লাইব্রেরি নির্ভরতাগুলো নির্ধারণ করে:
{
"name": "thumbnail_service",
"version": "0.0.1",
"main": "index.js",
"scripts": {
"start": "node index.js"
},
"dependencies": {
"bluebird": "^3.7.2",
"express": "^4.17.1",
"imagemagick": "^0.1.3",
"@google-cloud/firestore": "^4.9.9",
"@google-cloud/storage": "^5.8.3"
}
}
ক্লাউড স্টোরেজ লাইব্রেরি ক্লাউড স্টোরেজের মধ্যে ইমেজ ফাইল পড়া এবং সংরক্ষণ করতে ব্যবহৃত হয়। ছবির মেটাডেটা আপডেট করার জন্য ফায়ারস্টোর ব্যবহৃত হয়। এক্সপ্রেস একটি জাভাস্ক্রিপ্ট / নোড ওয়েব ফ্রেমওয়ার্ক। বডি-পার্সার মডিউলটি আগত রিকোয়েস্ট সহজে পার্স করতে ব্যবহৃত হয়। প্রমিজ হ্যান্ডেল করার জন্য ব্লুবার্ড ব্যবহৃত হয়, এবং ইমেজম্যাজিক হলো ইমেজ ম্যানিপুলেট করার একটি লাইব্রেরি।
ডকারফাইল
Dockerfile অ্যাপ্লিকেশনটির জন্য কন্টেইনার ইমেজ নির্ধারণ করে:
FROM node:14-slim
# installing Imagemagick
RUN set -ex; \
apt-get -y update; \
apt-get -y install imagemagick; \
rm -rf /var/lib/apt/lists/*; \
mkdir /tmp/original; \
mkdir /tmp/thumbnail;
WORKDIR /picadaily/services/thumbnails
COPY package*.json ./
RUN npm install --production
COPY . .
CMD [ "npm", "start" ]
বেস ইমেজটি হলো নোড ১৪ এবং ইমেজ সম্পাদনার জন্য ইমেজম্যাজিক লাইব্রেরি ব্যবহার করা হয়েছে। মূল এবং থাম্বনেইল ছবির ফাইলগুলো রাখার জন্য কয়েকটি অস্থায়ী ডিরেক্টরি তৈরি করা হয়েছে। এরপর, কোড শুরু করার আগে npm start কমান্ড দিয়ে আমাদের কোডের জন্য প্রয়োজনীয় এনপিএম মডিউলগুলো ইনস্টল করা হয়।
index.js
চলুন কোডটি খণ্ড খণ্ড করে বিশ্লেষণ করি, যাতে আমরা প্রোগ্রামটি কী করছে তা আরও ভালোভাবে বুঝতে পারি।
const express = require('express');
const imageMagick = require('imagemagick');
const Promise = require("bluebird");
const path = require('path');
const {Storage} = require('@google-cloud/storage');
const Firestore = require('@google-cloud/firestore');
const app = express();
app.use(express.json());
আমরা প্রথমে প্রয়োজনীয় ডিপেন্ডেন্সিগুলো রিকোয়ার করছি এবং আমাদের এক্সপ্রেস ওয়েব অ্যাপ্লিকেশনটি তৈরি করছি। সেই সাথে এটাও উল্লেখ করছি যে আমরা JSON বডি পার্সার ব্যবহার করতে চাই, কারণ আগত রিকোয়েস্টগুলো আসলে আমাদের অ্যাপ্লিকেশনে POST রিকোয়েস্টের মাধ্যমে পাঠানো JSON পেলোড মাত্র।
app.post('/', async (req, res) => {
try {
// ...
} catch (err) {
console.log(`Error: creating the thumbnail: ${err}`);
console.error(err);
res.status(500).send(err);
}
});
আমরা / বেস ইউআরএল-এ সেই ইনকামিং পেলোডগুলো গ্রহণ করছি, এবং আমাদের কোডকে কিছু এরর লজিক হ্যান্ডলিং দিয়ে মুড়ে দিচ্ছি, যাতে গুগল ক্লাউড ওয়েব কনসোলের স্ট্যাকড্রাইভার লগিং ইন্টারফেস থেকে দৃশ্যমান লগগুলো দেখে আমাদের কোডের কোনো কিছু ব্যর্থ হওয়ার কারণ সম্পর্কে আরও ভালো তথ্য পাওয়া যায়।
const pubSubMessage = req.body;
console.log(`PubSub message: ${JSON.stringify(pubSubMessage)}`);
const fileEvent = JSON.parse(Buffer.from(pubSubMessage.message.data, 'base64').toString().trim());
console.log(`Received thumbnail request for file ${fileEvent.name} from bucket ${fileEvent.bucket}`);
ক্লাউড রান প্ল্যাটফর্মে, পাব/সাব মেসেজগুলো HTTP POST রিকোয়েস্টের মাধ্যমে, নিম্নলিখিত ফর্ম্যাটের JSON পেলোড হিসেবে পাঠানো হয়:
{
"message": {
"attributes": {
"bucketId": "uploaded-pictures",
"eventTime": "2020-02-27T09:22:43.255225Z",
"eventType": "OBJECT_FINALIZE",
"notificationConfig": "projects/_/buckets/uploaded-pictures/notificationConfigs/28",
"objectGeneration": "1582795363255481",
"objectId": "IMG_20200213_181159.jpg",
"payloadFormat": "JSON_API_V1"
},
"data": "ewogICJraW5kIjogInN0b3JhZ2Ujb2JqZWN...FQUU9Igp9Cg==",
"messageId": "1014308302773399",
"message_id": "1014308302773399",
"publishTime": "2020-02-27T09:22:43.973Z",
"publish_time": "2020-02-27T09:22:43.973Z"
},
"subscription": "projects/serverless-picadaily/subscriptions/gcs-events-subscription"
}
কিন্তু এই JSON ডকুমেন্টের সবচেয়ে আকর্ষণীয় বিষয়টি হলো message.data অ্যাট্রিবিউটের ভেতরে যা রয়েছে, যা কেবল একটি স্ট্রিং হলেও আসল পেলোডকে Base 64-এ এনকোড করে। এ কারণেই আমাদের উপরের কোডটি এই অ্যাট্রিবিউটের Base 64 কন্টেন্টকে ডিকোড করছে। ডিকোড করার পর সেই data অ্যাট্রিবিউটের ভেতরে আরেকটি JSON ডকুমেন্ট পাওয়া যায়, যা ক্লাউড স্টোরেজ ইভেন্টের বিস্তারিত তথ্য উপস্থাপন করে এবং যেখানে অন্যান্য মেটাডেটার পাশাপাশি ফাইলের নাম ও বাকেটের নাম উল্লেখ থাকে।
{
"kind": "storage#object",
"id": "uploaded-pictures/IMG_20200213_181159.jpg/1582795363255481",
"selfLink": "https://www.googleapis.com/storage/v1/b/uploaded-pictures/o/IMG_20200213_181159.jpg",
"name": "IMG_20200213_181159.jpg",
"bucket": "uploaded-pictures",
"generation": "1582795363255481",
"metageneration": "1",
"contentType": "image/jpeg",
"timeCreated": "2020-02-27T09:22:43.255Z",
"updated": "2020-02-27T09:22:43.255Z",
"storageClass": "STANDARD",
"timeStorageClassUpdated": "2020-02-27T09:22:43.255Z",
"size": "4944335",
"md5Hash": "QzBIoPJBV2EvqB1EVk1riw==",
"mediaLink": "https://www.googleapis.com/download/storage/v1/b/uploaded-pictures/o/IMG_20200213_181159.jpg?generation=1582795363255481&alt=media",
"crc32c": "hQ3uHg==",
"etag": "CLmJhJu08ecCEAE="
}
আমরা ইমেজ এবং বাকেটের নাম জানতে আগ্রহী, কারণ আমাদের কোড থাম্বনেইল তৈরির জন্য বাকেট থেকে সেই ইমেজটি নিয়ে আসবে।
const bucket = storage.bucket(fileEvent.bucket);
const thumbBucket = storage.bucket(process.env.BUCKET_THUMBNAILS);
const originalFile = path.resolve('/tmp/original', fileEvent.name);
const thumbFile = path.resolve('/tmp/thumbnail', fileEvent.name);
await bucket.file(fileEvent.name).download({
destination: originalFile
});
console.log(`Downloaded picture into ${originalFile}`);
আমরা একটি এনভায়রনমেন্ট ভেরিয়েবল থেকে আউটপুট স্টোরেজ বাকেটের নামটি নিচ্ছি।
আমাদের কাছে অরিজিন বাকেটটি আছে, যার ফাইল তৈরি হওয়ার ফলে আমাদের ক্লাউড রান সার্ভিসটি চালু হয়েছে, এবং ডেস্টিনেশন বাকেটটিও আছে যেখানে আমরা চূড়ান্ত ছবিটি সংরক্ষণ করব। আমরা লোকাল ফাইল হ্যান্ডলিংয়ের জন্য path বিল্ট-ইন এপিআই ব্যবহার করছি, কারণ ইমেজম্যাজিক লাইব্রেরিটি /tmp টেম্পোরারি ডিরেক্টরিতে স্থানীয়ভাবে থাম্বনেইলটি তৈরি করবে। আপলোড করা ইমেজ ফাইলটি ডাউনলোড করার জন্য আমরা একটি অ্যাসিঙ্ক্রোনাস কলের await ।
const resizeCrop = Promise.promisify(im.crop);
await resizeCrop({
srcPath: originalFile,
dstPath: thumbFile,
width: 400,
height: 400
});
console.log(`Created local thumbnail in ${thumbFile}`);
ইমেজম্যাজিক মডিউলটি async / await ব্যবহারের জন্য খুব একটা উপযোগী নয়, তাই আমরা এটিকে একটি জাভাস্ক্রিপ্ট প্রমিজের (যা ব্লুবার্ড মডিউল দ্বারা সরবরাহকৃত) মধ্যে রাখছি। এরপর, আমরা সোর্স ও ডেস্টিনেশন ফাইলের প্যারামিটার এবং যে থাম্বনেইলটি তৈরি করতে চাই তার ডাইমেনশনসহ আমাদের তৈরি করা অ্যাসিঙ্ক্রোনাস রিসাইজিং / ক্রপিং ফাংশনটিকে কল করছি।
await thumbBucket.upload(thumbFile);
console.log(`Uploaded thumbnail to Cloud Storage bucket ${process.env.BUCKET_THUMBNAILS}`);
থাম্বনেইল ফাইলটি ক্লাউড স্টোরেজে আপলোড হয়ে গেলে, আমরা ক্লাউড ফায়ারস্টোরের মেটাডেটাও আপডেট করব এবং একটি বুলিয়ান ফ্ল্যাগ যোগ করব যা নির্দেশ করবে যে এই ছবিটির জন্য থাম্বনেইলটি সত্যিই তৈরি হয়েছে।
const pictureStore = new Firestore().collection('pictures');
const doc = pictureStore.doc(fileEvent.name);
await doc.set({
thumbnail: true
}, {merge: true});
console.log(`Updated Firestore about thumbnail creation for ${fileEvent.name}`);
res.status(204).send(`${fileEvent.name} processed`);
আমাদের অনুরোধটি সম্পন্ন হলে, আমরা HTTP POST অনুরোধের উত্তরে জানাই যে ফাইলটি সঠিকভাবে প্রক্রিয়াজাত করা হয়েছে।
const PORT = process.env.PORT || 8080;
app.listen(PORT, () => {
console.log(`Started thumbnail generator on port ${PORT}`);
});
আমাদের সোর্স ফাইলের শেষে, এক্সপ্রেসকে দিয়ে আমাদের ওয়েব অ্যাপ্লিকেশনটি ডিফল্ট ৮০৮০ পোর্টে চালু করানোর নির্দেশনা রয়েছে।
৭. স্থানীয়ভাবে পরীক্ষা করুন
ক্লাউডে ডেপ্লয় করার আগে কোডটি ঠিকমতো কাজ করছে কিনা তা নিশ্চিত করতে আপনার লোকাল মেশিনে পরীক্ষা করে নিন।
thumbnails/nodejs ফোল্ডারের ভিতরে, npm ডিপেন্ডেন্সিগুলো ইনস্টল করুন এবং সার্ভারটি চালু করুন:
npm install; npm start
সবকিছু ঠিকঠাক থাকলে, সার্ভারটি ৮০৮০ পোর্টে চালু হয়ে যাবে:
Started thumbnail generator on port 8080
প্রস্থান করতে CTRL-C ব্যবহার করুন।
৮. কন্টেইনার ইমেজটি বিল্ড এবং পাবলিশ করুন।
ক্লাউড রান কন্টেইনার চালাতে পারে, কিন্তু তার জন্য প্রথমে আপনাকে কন্টেইনার ইমেজটি বিল্ড করতে হবে (যা Dockerfile সংজ্ঞায়িত থাকে)। কন্টেইনার ইমেজ বিল্ড করার জন্য এবং তারপর গুগল কন্টেইনার রেজিস্ট্রি-তে হোস্ট করার জন্য গুগল ক্লাউড বিল্ড ব্যবহার করা যেতে পারে।
thumbnails/nodejs ফোল্ডারের ভিতরে যেখানে Dockerfile আছে, সেখানে কন্টেইনার ইমেজটি বিল্ড করার জন্য নিম্নলিখিত কমান্ডটি দিন:
gcloud builds submit --tag gcr.io/$GOOGLE_CLOUD_PROJECT/thumbnail-service
এক বা দুই মিনিট পর বিল্ডটি সফল হওয়া উচিত:

ক্লাউড বিল্ডের "হিস্ট্রি" সেকশনে সফল বিল্ডটিও দেখানো উচিত:

বিস্তারিত দেখার জন্য বিল্ড আইডি-তে ক্লিক করলে, 'বিল্ড আর্টিফ্যাক্টস' ট্যাবে আপনি দেখতে পাবেন যে কন্টেইনার ইমেজটি ক্লাউড রেজিস্ট্রি (GCR)-তে আপলোড করা হয়েছে:

আপনি চাইলে, কন্টেইনার ইমেজটি স্থানীয়ভাবে ক্লাউড শেলে চলছে কিনা তা পুনরায় যাচাই করে দেখতে পারেন:
docker run -p 8080:8080 gcr.io/$GOOGLE_CLOUD_PROJECT/thumbnail-service
এটি কন্টেইনারের মধ্যে ৮০৮০ পোর্টে সার্ভারটি চালু করবে:
Started thumbnail generator on port 8080
প্রস্থান করতে CTRL-C ব্যবহার করুন।
৯. ক্লাউড রান-এ ডেপ্লয় করুন
Cloud Run-এ ডেপ্লয় করার আগে, Cloud Run-এর অঞ্চলটি সমর্থিত অঞ্চলগুলির মধ্যে একটিতে এবং প্ল্যাটফর্মটি managed এ সেট করুন।
gcloud config set run/region europe-west1 gcloud config set run/platform managed
আপনি যাচাই করে দেখতে পারেন যে কনফিগারেশনটি সেট করা আছে কিনা:
gcloud config list ... [run] platform = managed region = europe-west1
ক্লাউড রানে কন্টেইনার ইমেজটি ডেপ্লয় করতে নিম্নলিখিত কমান্ডটি চালান:
SERVICE_NAME=thumbnail-service
gcloud run deploy $SERVICE_NAME \
--image gcr.io/$GOOGLE_CLOUD_PROJECT/thumbnail-service \
--no-allow-unauthenticated \
--update-env-vars BUCKET_THUMBNAILS=$BUCKET_THUMBNAILS
--no-allow-unauthenticated ফ্ল্যাগটি লক্ষ্য করুন। এটি ক্লাউড রান সার্ভিসকে একটি অভ্যন্তরীণ সার্ভিসে পরিণত করে, যা শুধুমাত্র নির্দিষ্ট সার্ভিস অ্যাকাউন্ট দ্বারাই চালু হবে।
ডেপ্লয়মেন্ট সফল হলে, আপনি নিম্নলিখিত আউটপুট দেখতে পাবেন:

আপনি যদি ক্লাউড কনসোল UI-তে যান, তাহলে আপনি এটাও দেখতে পাবেন যে পরিষেবাটি সফলভাবে স্থাপন করা হয়েছে:

১০. পাব/সাব এর মাধ্যমে ক্লাউড স্টোরেজ ইভেন্টসমূহ ক্লাউড রান-এ প্রেরণ
সার্ভিসটি প্রস্তুত, কিন্তু আপনাকে নতুন তৈরি করা ক্লাউড রান সার্ভিসে ক্লাউড স্টোরেজ ইভেন্ট পাঠাতে হবে। ক্লাউড স্টোরেজ, ক্লাউড পাব/সাব-এর মাধ্যমে ফাইল তৈরির ইভেন্ট পাঠাতে পারে, তবে এটি চালু করার জন্য কয়েকটি ধাপ অনুসরণ করতে হবে।
যোগাযোগের মাধ্যম হিসেবে একটি পাব/সাব টপিক তৈরি করুন:
TOPIC_NAME=cloudstorage-cloudrun-topic gcloud pubsub topics create $TOPIC_NAME
বাকেটে ফাইল জমা হলে পাব/সাব নোটিফিকেশন তৈরি করুন:
BUCKET_PICTURES=uploaded-pictures-$GOOGLE_CLOUD_PROJECT gsutil notification create -t $TOPIC_NAME -f json gs://$BUCKET_PICTURES
পাব/সাব সাবস্ক্রিপশনের জন্য একটি সার্ভিস অ্যাকাউন্ট তৈরি করুন যা আমরা পরে তৈরি করব:
SERVICE_ACCOUNT=$TOPIC_NAME-sa
gcloud iam service-accounts create $SERVICE_ACCOUNT \
--display-name "Cloud Run Pub/Sub Invoker"
সার্ভিস অ্যাকাউন্টকে ক্লাউড রান সার্ভিস চালু করার অনুমতি দিন:
SERVICE_NAME=thumbnail-service gcloud run services add-iam-policy-binding $SERVICE_NAME \ --member=serviceAccount:$SERVICE_ACCOUNT@$GOOGLE_CLOUD_PROJECT.iam.gserviceaccount.com \ --role=roles/run.invoker
যদি আপনি ৮ই এপ্রিল, ২০২১ তারিখে বা তার আগে পাব/সাব সার্ভিস অ্যাকাউন্টটি সক্রিয় করে থাকেন, তাহলে পাব/সাব সার্ভিস অ্যাকাউন্টটিকে iam.serviceAccountTokenCreator রোলটি প্রদান করুন:
PROJECT_NUMBER=$(gcloud projects describe $GOOGLE_CLOUD_PROJECT --format='value(projectNumber)')
gcloud projects add-iam-policy-binding $GOOGLE_CLOUD_PROJECT \
--member=serviceAccount:service-$PROJECT_NUMBER@gcp-sa-pubsub.iam.gserviceaccount.com \
--role=roles/iam.serviceAccountTokenCreator
IAM পরিবর্তনগুলো কার্যকর হতে কয়েক মিনিট সময় লাগতে পারে।
অবশেষে, সার্ভিস অ্যাকাউন্টটি দিয়ে একটি পাব/সাব সাবস্ক্রিপশন তৈরি করুন:
SERVICE_URL=$(gcloud run services describe $SERVICE_NAME --format 'value(status.url)') gcloud pubsub subscriptions create $TOPIC_NAME-subscription --topic $TOPIC_NAME \ --push-endpoint=$SERVICE_URL \ --push-auth-service-account=$SERVICE_ACCOUNT@$GOOGLE_CLOUD_PROJECT.iam.gserviceaccount.com
একটি সাবস্ক্রিপশন তৈরি হয়েছে কিনা তা আপনি যাচাই করতে পারেন। কনসোলে Pub/Sub-এ যান, gcs-events টপিকটি নির্বাচন করুন এবং একদম নিচে আপনি সাবস্ক্রিপশনটি দেখতে পাবেন:

১১. পরিষেবাটি পরীক্ষা করুন
সেটআপটি কাজ করছে কিনা তা পরীক্ষা করতে, uploaded-pictures বাকেটে একটি নতুন ছবি আপলোড করুন এবং thumbnails বাকেটে দেখুন যে নতুন রিসাইজ করা ছবিগুলো প্রত্যাশিতভাবে দেখা যাচ্ছে কিনা।
ক্লাউড রান পরিষেবার বিভিন্ন ধাপ চলার সময় লগিং বার্তাগুলো দেখা যাচ্ছে কিনা, তা দেখতে আপনি লগগুলো পুনরায় যাচাই করতে পারেন:

১২. পরিষ্কার করা (ঐচ্ছিক)
আপনি যদি এই সিরিজের অন্য ল্যাবগুলো চালিয়ে যেতে না চান, তাহলে খরচ বাঁচাতে এবং সার্বিকভাবে একজন ভালো ক্লাউড ব্যবহারকারী হতে রিসোর্সগুলো পরিষ্কার করতে পারেন। আপনি নিম্নলিখিত উপায়ে একে একে রিসোর্সগুলো পরিষ্কার করতে পারেন।
বাকেটটি মুছে ফেলুন:
gsutil rb gs://$BUCKET_THUMBNAILS
পরিষেবাটি মুছে ফেলুন:
gcloud run services delete $SERVICE_NAME -q
পাব/সাব টপিকটি মুছে ফেলুন:
gcloud pubsub topics delete $TOPIC_NAME
বিকল্পভাবে, আপনি পুরো প্রজেক্টটি মুছে ফেলতে পারেন:
gcloud projects delete $GOOGLE_CLOUD_PROJECT
১৩. অভিনন্দন!
এখন সবকিছু প্রস্তুত আছে:
- ক্লাউড স্টোরেজে একটি নোটিফিকেশন তৈরি করা হয়েছে, যা নতুন ছবি আপলোড হলে একটি নির্দিষ্ট টপিকে পাব/সাব মেসেজ পাঠায়।
- প্রয়োজনীয় IAM বাইন্ডিং এবং অ্যাকাউন্টগুলো নির্ধারণ করা হয়েছে (ক্লাউড ফাংশনের মতো নয়, যেখানে সবকিছু স্বয়ংক্রিয়ভাবে হয়, এখানে এটি ম্যানুয়ালি কনফিগার করতে হয়)।
- একটি সাবস্ক্রিপশন তৈরি করা হয়েছে যাতে আমাদের ক্লাউড রান পরিষেবা পাব/সাব বার্তাগুলো গ্রহণ করতে পারে।
- যখনই বাকেটে কোনো নতুন ছবি আপলোড করা হয়, নতুন ক্লাউড রান পরিষেবার সৌজন্যে ছবিটির আকার পরিবর্তিত হয়ে যায়।
আমরা যা আলোচনা করেছি
- ক্লাউড রান
- ক্লাউড স্টোরেজ
- ক্লাউড পাব/সাব