Skill

প্র্যাকটিস প্রোজেক্টস

অ্যাপাচি থ্রিফট (Apache Thrift) - Latest Technologies

287

Thrift প্র্যাকটিস প্রোজেক্টস

নিচে কিছু Thrift প্র্যাকটিস প্রোজেক্টের ধারণা দেওয়া হলো যা আপনাকে Thrift এর ফিচার এবং কার্যকারিতা বাস্তবে প্রয়োগ করতে সাহায্য করবে। এগুলি বাস্তব জীবনের সমস্যা সমাধানে সহায়ক এবং আপনার কোডিং দক্ষতা বৃদ্ধি করতে সহায়ক।


১. মাইক্রোসার্ভিস আর্কিটেকচার তৈরি

বিবরণ: একটি মাইক্রোসার্ভিস আর্কিটেকচার তৈরি করুন যেখানে বিভিন্ন সার্ভিস একে অপরের সাথে Thrift ব্যবহার করে যোগাযোগ করবে।

ফিচার:

  • ব্যবহারকারী পরিচালনা (User Management)
  • প্রোডাক্ট ক্যাটালগ
  • অর্ডার প্রসেসিং

কৌশল:

  • Thrift IDL ফাইল তৈরি করুন এবং বিভিন্ন সার্ভিসের জন্য কোড জেনারেট করুন।
  • সার্ভার এবং ক্লায়েন্টের জন্য বিভিন্ন ভাষা (যেমন Java, Python) ব্যবহার করুন।

২. ডেটা স্ট্রিমিং সার্ভিস

বিবরণ: একটি ডেটা স্ট্রিমিং সার্ভিস তৈরি করুন যা Thrift ব্যবহার করে বিভিন্ন IoT ডিভাইস থেকে তথ্য সংগ্রহ করবে।

ফিচার:

  • রিয়েল-টাইম ডেটা সংগ্রহ
  • ডেটা বিশ্লেষণ এবং প্রতিবেদন

কৌশল:

  • Thrift এর আসিনক্রোনাস কল ব্যবহার করে ডেটা সংগ্রহ করুন।
  • ডেটা সংগ্রহের জন্য একটি ব্যাকগ্রাউন্ড প্রসেস তৈরি করুন।

৩. চ্যাট অ্যাপ্লিকেশন

বিবরণ: একটি সিম্পল চ্যাট অ্যাপ্লিকেশন তৈরি করুন যেখানে ব্যবহারকারীরা Thrift সার্ভিসের মাধ্যমে একে অপরের সাথে যোগাযোগ করতে পারে।

ফিচার:

  • ব্যবহারকারীর নিবন্ধন এবং লগইন
  • বার্তা পাঠানো এবং গ্রহণ করা
  • ব্যবহারকারীদের তালিকা

কৌশল:

  • Thrift IDL ব্যবহার করে চ্যাট সার্ভিসের API ডিজাইন করুন।
  • ব্যবহারকারীর তথ্য সংরক্ষণের জন্য একটি ডাটাবেস সংযুক্ত করুন।

৪. REST API কে Thrift এ রূপান্তর

বিবরণ: একটি বিদ্যমান REST API কে Thrift সার্ভিসে রূপান্তর করুন।

ফিচার:

  • বিদ্যমান API ফিচারগুলি Thrift সার্ভিসে অন্তর্ভুক্ত করুন।
  • API ব্যবহারকারীদের জন্য Thrift ক্লায়েন্ট তৈরি করুন।

কৌশল:

  • REST API এর URL এবং প্যারামিটারগুলি Thrift IDL ফাইলে সংজ্ঞায়িত করুন।
  • Thrift ক্লায়েন্ট ব্যবহার করে সার্ভিসে অনুরোধ পাঠান।

৫. পারফরম্যান্স টেস্টিং এবং অপটিমাইজেশন

বিবরণ: একটি Thrift সার্ভিস তৈরি করুন এবং তার পারফরম্যান্স পরীক্ষা করুন, পরে অপটিমাইজ করুন।

ফিচার:

  • থ্রেড পুলিং এবং ক্যাশিং বাস্তবায়ন করুন।
  • পারফরম্যান্স ডেটা বিশ্লেষণ করুন এবং অপটিমাইজেশন কৌশল প্রয়োগ করুন।

কৌশল:

  • লোড টেস্টিং টুল (যেমন Apache JMeter) ব্যবহার করে সার্ভিসের লোড পরীক্ষা করুন।
  • ফলস্বরূপ ডেটার ভিত্তিতে উন্নতি সাধন করুন।

সারসংক্ষেপ

এই Thrift প্র্যাকটিস প্রোজেক্টগুলি আপনাকে Thrift-এর ব্যবহারিক দিকগুলি শেখার এবং বাস্তবে প্রয়োগ করার সুযোগ দেবে। প্রকল্পগুলি সম্পূর্ণ করার মাধ্যমে আপনি থ্রিফ্টের বিভিন্ন ফিচার এবং টেকনিক্যাল দক্ষতা বৃদ্ধি করতে সক্ষম হবেন।

Content added By

একটি Basic Thrift সার্ভার এবং ক্লায়েন্ট তৈরি করা

এখানে একটি মৌলিক Thrift সার্ভার এবং ক্লায়েন্ট তৈরি করার পদক্ষেপ দেওয়া হলো, যেখানে আমরা একটি সাধারণ গণনা পরিষেবা তৈরি করব যা দুটি সংখ্যা যোগ এবং বিয়োগ করতে সক্ষম হবে।

পদক্ষেপ ১: Thrift IDL ফাইল তৈরি করা

প্রথমে, একটি Thrift IDL ফাইল তৈরি করুন। ফাইলের নাম হতে পারে Calculator.thrift.

namespace py calculator  // Python namespace

// Calculator service definition
service CalculatorService {
  i32 add(1: i32 num1, 2: i32 num2),
  i32 subtract(1: i32 num1, 2: i32 num2)
}

পদক্ষেপ ২: Thrift কম্পাইলার ব্যবহার করে কোড জেনারেট করা

Thrift IDL ফাইল থেকে কোড জেনারেট করতে Thrift কম্পাইলার ব্যবহার করুন। কমান্ড লাইন থেকে নিচের কমান্ডটি চালান:

thrift --gen py Calculator.thrift

এটি gen-py ফোল্ডারে Python কোড তৈরি করবে।

পদক্ষেপ ৩: সার্ভার বাস্তবায়ন

এখন সার্ভারের কোড লিখুন। একটি নতুন ফাইল তৈরি করুন, server.py নামক।

from thrift import Thrift
from thrift.transport import TTransport
from thrift.transport import TSocket
from thrift.protocol import TBinaryProtocol
from calculator import CalculatorService

class CalculatorServiceHandler:
    def add(self, num1, num2):
        return num1 + num2

    def subtract(self, num1, num2):
        return num1 - num2

def main():
    handler = CalculatorServiceHandler()
    processor = CalculatorService.Processor(handler)
    transport = TSocket.TServerSocket(host='127.0.0.1', port=9090)
    tfactory = TTransport.TBufferedTransportFactory()
    pfactory = TBinaryProtocol.TBinaryProtocolFactory()

    server = TServer.TSimpleServer(processor, transport, tfactory, pfactory)

    print("Starting the server...")
    server.serve()

if __name__ == '__main__':
    main()

পদক্ষেপ ৪: ক্লায়েন্ট বাস্তবায়ন

এখন ক্লায়েন্টের কোড লিখুন। একটি নতুন ফাইল তৈরি করুন, client.py নামক।

from thrift import Thrift
from thrift.transport import TTransport
from thrift.transport import TSocket
from thrift.protocol import TBinaryProtocol
from calculator import CalculatorService

def main():
    transport = TSocket.TSocket('127.0.0.1', 9090)
    tfactory = TTransport.TBufferedTransportFactory()
    pfactory = TBinaryProtocol.TBinaryProtocolFactory()

    transport = tfactory.getTransport(transport)
    protocol = pfactory.getProtocol(transport)

    client = CalculatorService.Client(protocol)

    try:
        transport.open()
        num1 = 10
        num2 = 5
        print("Add:", client.add(num1, num2))
        print("Subtract:", client.subtract(num1, num2))
    finally:
        transport.close()

if __name__ == '__main__':
    main()

পদক্ষেপ ৫: সার্ভার এবং ক্লায়েন্ট চালানো

সার্ভার চালান:

python server.py

ক্লায়েন্ট চালান:

python client.py

ফলাফল

ক্লায়েন্ট চলাকালীন, আপনি সার্ভারের থেকে যোগফল এবং বিয়োগফল পাওয়ার জন্য ক্লায়েন্টে দুটি সংখ্যা (১০ এবং ৫) প্রদান করবেন। সার্ভারটি ক্লায়েন্টের অনুরোধগুলি গ্রহণ করে সঠিক ফলাফল প্রদান করবে।

সারসংক্ষেপ

এই পদক্ষেপগুলি অনুসরণ করে, আপনি একটি মৌলিক Thrift সার্ভার এবং ক্লায়েন্ট তৈরি করেছেন যা দুটি সংখ্যার যোগফল এবং বিয়োগফল বের করতে পারে। এটি Thrift এর ভিত্তি এবং এটি বিভিন্ন ভাষার মধ্যে যোগাযোগ স্থাপন করার জন্য একটি কার্যকরী প্ল্যাটফর্ম সরবরাহ করে।

Content added By

Thrift ব্যবহার করে Cross-Language RPC কল করা

Apache Thrift বিভিন্ন প্রোগ্রামিং ভাষার মধ্যে RPC (Remote Procedure Call) যোগাযোগ সহজ করে। নিচে Thrift ব্যবহার করে বিভিন্ন ভাষার মধ্যে RPC কল করার প্রক্রিয়া এবং উদাহরণ দেওয়া হলো।

পদক্ষেপ ১: Thrift IDL ফাইল তৈরি করা

প্রথমে একটি Thrift IDL ফাইল তৈরি করুন। উদাহরণস্বরূপ, আমরা একটি Calculator.thrift ফাইল তৈরি করব।

namespace java calculator  // Java namespace
namespace py calculator    // Python namespace

service CalculatorService {
  i32 add(1: i32 num1, 2: i32 num2),
  i32 subtract(1: i32 num1, 2: i32 num2)
}

পদক্ষেপ ২: Thrift কম্পাইলার ব্যবহার করে কোড জেনারেট করা

Thrift IDL ফাইল থেকে কোড জেনারেট করতে Thrift কম্পাইলার ব্যবহার করুন। নিচের কমান্ডগুলি ব্যবহার করুন:

thrift --gen py Calculator.thrift
thrift --gen java Calculator.thrift

এটি Python এবং Java এর জন্য পৃথক কোড তৈরি করবে।

পদক্ষেপ ৩: Python ক্লায়েন্ট তৈরি করা

Python ক্লায়েন্ট কোড লিখুন। একটি নতুন ফাইল তৈরি করুন, client.py নামক।

from thrift import Thrift
from thrift.transport import TTransport
from thrift.transport import TSocket
from thrift.protocol import TBinaryProtocol
from calculator import CalculatorService

def main():
    # Connect to the Java server
    transport = TSocket.TSocket('localhost', 9090)
    tfactory = TTransport.TBufferedTransportFactory()
    pfactory = TBinaryProtocol.TBinaryProtocolFactory()

    transport = tfactory.getTransport(transport)
    protocol = pfactory.getProtocol(transport)

    client = CalculatorService.Client(protocol)

    try:
        transport.open()
        num1 = 10
        num2 = 5
        print("Python Client - Add:", client.add(num1, num2))
        print("Python Client - Subtract:", client.subtract(num1, num2))
    finally:
        transport.close()

if __name__ == '__main__':
    main()

পদক্ষেপ ৪: Java সার্ভার তৈরি করা

Java সার্ভার কোড লিখুন। একটি নতুন ফাইল তৈরি করুন, CalculatorServer.java নামক।

import org.apache.thrift.TException;
import org.apache.thrift.server.TServer;
import org.apache.thrift.server.TSimpleServer;
import org.apache.thrift.transport.TServerSocket;
import org.apache.thrift.transport.TTransport;
import org.apache.thrift.transport.TTransportException;

public class CalculatorServer {

    public static class CalculatorServiceHandler implements CalculatorService.Iface {
        @Override
        public int add(int num1, int num2) throws TException {
            return num1 + num2;
        }

        @Override
        public int subtract(int num1, int num2) throws TException {
            return num1 - num2;
        }
    }

    public static void main(String[] args) {
        try {
            CalculatorServiceHandler handler = new CalculatorServiceHandler();
            CalculatorService.Processor<CalculatorServiceHandler> processor = new CalculatorService.Processor<>(handler);

            TServerSocket serverTransport = new TServerSocket(9090);
            TServer server = new TSimpleServer(processor, serverTransport);

            System.out.println("Starting the Java server...");
            server.serve();
        } catch (TTransportException e) {
            e.printStackTrace();
        }
    }
}

পদক্ষেপ ৫: সার্ভার এবং ক্লায়েন্ট চালানো

Java সার্ভার চালান:

  • Java প্রোগ্রামটি কম্পাইল এবং চালাতে নিচের কমান্ডগুলি ব্যবহার করুন (Maven ব্যবহার করলে):

Python ক্লায়েন্ট চালান:

ফলাফল

ক্লায়েন্ট চলাকালীন, Python ক্লায়েন্ট Java সার্ভারের সাথে সংযুক্ত হয়ে দুটি সংখ্যা (১০ এবং ৫) যোগ এবং বিয়োগ করবে এবং ফলাফল প্রদর্শন করবে।

সারসংক্ষেপ

এই পদক্ষেপগুলি অনুসরণ করে, আপনি Thrift ব্যবহার করে Cross-Language RPC কল তৈরি করেছেন। Java সার্ভার এবং Python ক্লায়েন্ট একটি Thrift IDL ফাইল ব্যবহার করে একে অপরের সাথে যোগাযোগ করছে। Thrift এর মাধ্যমে বিভিন্ন প্রোগ্রামিং ভাষার মধ্যে কার্যকরী যোগাযোগ স্থাপন করা সম্ভব, যা আধুনিক সফটওয়্যার আর্কিটেকচারের জন্য খুবই কার্যকরী।

Content added By

Custom প্রোটোকল এবং ট্রান্সপোর্ট লেয়ার কনফিগারেশন

Apache Thrift ব্যবহার করে আপনি আপনার অ্যাপ্লিকেশনের জন্য কাস্টম প্রোটোকল এবং ট্রান্সপোর্ট কনফিগারেশন তৈরি করতে পারেন। এই কাস্টমাইজেশন থ্রিফ্ট অ্যাপ্লিকেশনের কার্যকারিতা এবং পারফরম্যান্স বাড়াতে সাহায্য করে। নিচে কাস্টম প্রোটোকল এবং ট্রান্সপোর্ট লেয়ার কনফিগারেশনের প্রক্রিয়া এবং উদাহরণ দেওয়া হলো।

১. কাস্টম প্রোটোকল তৈরি করা

Thrift-এ প্রোটোকল হল ডেটা সিরিয়ালাইজেশন এবং ডেসিরিয়ালাইজেশনের জন্য ব্যবহৃত পদ্ধতি। আপনি যদি আপনার প্রয়োজন অনুসারে একটি কাস্টম প্রোটোকল তৈরি করতে চান, তাহলে আপনাকে TProtocol ক্লাসের উপর ভিত্তি করে একটি নতুন ক্লাস তৈরি করতে হবে।

উদাহরণ: CustomProtocol.py

from thrift.protocol.TProtocol import TProtocol, TProtocolException
from thrift.transport.TTransport import TTransport

class CustomProtocol(TProtocol):
    def __init__(self, trans):
        self.trans = trans
        self.buffer = b""
        
    def readMessageBegin(self):
        # Custom logic to read message begin
        pass

    def readMessageEnd(self):
        # Custom logic to read message end
        pass

    def writeMessageBegin(self, name, ttype, seqid):
        # Custom logic to write message begin
        pass

    def writeMessageEnd(self):
        # Custom logic to write message end
        pass

    # Implement other required methods

২. কাস্টম ট্রান্সপোর্ট তৈরি করা

Thrift-এ ট্রান্সপোর্ট হল ডেটা স্থানান্তরের শারীরিক উপায়। কাস্টম ট্রান্সপোর্ট তৈরি করতে, TTransport ক্লাসের উপর ভিত্তি করে একটি নতুন ক্লাস তৈরি করতে হবে।

উদাহরণ: CustomTransport.py

from thrift.transport.TTransport import TTransport

class CustomTransport(TTransport):
    def __init__(self):
        self.buffer = b""
        
    def isOpen(self):
        return True  # Return True if transport is open

    def open(self):
        pass  # Custom logic to open the transport

    def close(self):
        pass  # Custom logic to close the transport

    def read(self, sz):
        # Custom logic to read data
        return self.buffer[:sz]

    def write(self, buf):
        # Custom logic to write data
        self.buffer += buf

৩. সার্ভার এবং ক্লায়েন্ট কনফিগারেশন

একবার কাস্টম প্রোটোকল এবং ট্রান্সপোর্ট তৈরি হলে, আপনি সার্ভার এবং ক্লায়েন্টের কনফিগারেশনে এটি ব্যবহার করতে পারেন।

সার্ভার উদাহরণ

from thrift.server import TServer
from thrift.transport import TSocket
from thrift.protocol import TBinaryProtocol
from CustomTransport import CustomTransport
from CustomProtocol import CustomProtocol
from calculator import CalculatorService

class CalculatorServiceHandler:
    # Implement methods

def main():
    handler = CalculatorServiceHandler()
    processor = CalculatorService.Processor(handler)
    
    transport = TSocket.TServerSocket(host='127.0.0.1', port=9090)
    tfactory = CustomTransport()  # Use custom transport
    pfactory = CustomProtocol()    # Use custom protocol

    server = TServer.TSimpleServer(processor, transport, tfactory, pfactory)
    print("Starting the custom server...")
    server.serve()

if __name__ == '__main__':
    main()

ক্লায়েন্ট উদাহরণ

from thrift.transport import TTransport
from thrift.protocol import TBinaryProtocol
from CustomTransport import CustomTransport
from CustomProtocol import CustomProtocol
from calculator import CalculatorService

def main():
    transport = CustomTransport()  # Use custom transport
    protocol = CustomProtocol(transport)  # Use custom protocol
    client = CalculatorService.Client(protocol)

    try:
        transport.open()
        print("Add:", client.add(10, 5))
        print("Subtract:", client.subtract(10, 5))
    finally:
        transport.close()

if __name__ == '__main__':
    main()

সারসংক্ষেপ

Custom প্রোটোকল এবং ট্রান্সপোর্ট লেয়ার কনফিগারেশন ব্যবহার করে আপনি আপনার Thrift অ্যাপ্লিকেশনকে বিশেষভাবে প্রয়োজনীয় করে তুলতে পারেন। Thrift-এর ভিতরে কাস্টমাইজেশন করে, আপনি বিভিন্ন প্রোটোকল এবং ট্রান্সপোর্টের পারফরম্যান্স বাড়াতে এবং আপনার অ্যাপ্লিকেশনকে আরও কার্যকরভাবে কাজ করার সুযোগ পাবেন। এটি সফটওয়্যার উন্নয়নকে আরও নমনীয় এবং উপযোগী করে তোলে।

Content added By

সার্ভার ডিপ্লয়মেন্ট এবং সুরক্ষা নিশ্চিতকরণের প্রোজেক্ট

এখানে একটি প্রকল্পের ধারণা দেওয়া হলো যা সার্ভার ডিপ্লয়মেন্ট এবং সুরক্ষা নিশ্চিতকরণের উপর ভিত্তি করে। এই প্রকল্পে একটি Thrift সার্ভার ডিপ্লয় করা হবে এবং তার নিরাপত্তা ব্যবস্থা প্রতিষ্ঠিত করা হবে।

প্রকল্পের লক্ষ্য

  • একটি Thrift সার্ভার তৈরি করা যা বিভিন্ন ক্লায়েন্টের থেকে অনুরোধ গ্রহণ করতে পারে।
  • সার্ভারের নিরাপত্তা নিশ্চিত করা, যাতে অবৈধ প্রবেশ এবং আক্রমণ প্রতিরোধ করা যায়।
  • সার্ভারের কার্যকারিতা পর্যবেক্ষণ করা এবং লগিং ব্যবস্থা বাস্তবায়ন করা।

ধাপ ১: সার্ভার তৈরি এবং কনফিগারেশন

  1. Thrift IDL ফাইল তৈরি করুন: Calculator.thrift
namespace py calculator

service CalculatorService {
  i32 add(1: i32 num1, 2: i32 num2),
  i32 subtract(1: i32 num1, 2: i32 num2)
}
  1. Thrift কোড জেনারেট করুন:
thrift --gen py Calculator.thrift
  1. Python সার্ভার তৈরি করুন: server.py
from thrift import Thrift
from thrift.transport import TTransport
from thrift.transport import TSocket
from thrift.protocol import TBinaryProtocol
from calculator import CalculatorService
import logging

# Set up logging
logging.basicConfig(level=logging.INFO)

class CalculatorServiceHandler:
    def add(self, num1, num2):
        return num1 + num2

    def subtract(self, num1, num2):
        return num1 - num2

def main():
    handler = CalculatorServiceHandler()
    processor = CalculatorService.Processor(handler)
    
    transport = TSocket.TServerSocket(host='0.0.0.0', port=9090)
    tfactory = TTransport.TBufferedTransportFactory()
    pfactory = TBinaryProtocol.TBinaryProtocolFactory()

    server = TServer.TSimpleServer(processor, transport, tfactory, pfactory)

    logging.info("Starting the server...")
    server.serve()

if __name__ == '__main__':
    main()

ধাপ ২: সার্ভার ডিপ্লয়মেন্ট

  1. সার্ভার পরিবেশ তৈরি:
    • Ubuntu বা CentOS সার্ভারে Python এবং Thrift ইনস্টল করুন।
sudo apt update
sudo apt install python3-pip
pip3 install thrift

কোড আপলোড করুন:

  • সার্ভার কোড এবং IDL ফাইল সার্ভারে আপলোড করুন।

সার্ভার চালান:

  • সার্ভারে python3 server.py চালান।

ধাপ ৩: সুরক্ষা নিশ্চিতকরণ

  1. ফায়ারওয়াল কনফিগারেশন:
    • সার্ভার ফায়ারওয়াল সেটআপ করুন যাতে 9090 পোর্টে ট্রাফিক অনুমোদন করা হয়।
sudo ufw allow 9090/tcp
  1. TLS/SSL এনক্রিপশন:
    • সার্ভারের জন্য TLS/SSL সার্টিফিকেট কনফিগার করুন। এটি করতে আপনি OpenSSL ব্যবহার করতে পারেন।
# Create a self-signed certificate
openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 365 -nodes
  1. Thrift সার্ভারে TLS সক্রিয় করুন:
    • server.py ফাইলে TLS সক্রিয় করার জন্য পরিবর্তন করুন।
from thrift.transport import TTransport, TSSLSocket

# Create an SSL socket
transport = TSSLSocket.TSSLServerSocket(host='0.0.0.0', port=9090, certfile='cert.pem', keyfile='key.pem')

ধাপ ৪: ক্লায়েন্ট ডেভেলপমেন্ট এবং টেস্টিং

  1. Python ক্লায়েন্ট তৈরি করুন: client.py
from thrift import Thrift
from thrift.transport import TTransport
from thrift.transport import TSSLSocket
from thrift.protocol import TBinaryProtocol
from calculator import CalculatorService

def main():
    transport = TSSLSocket.TSSLSocket('localhost', 9090)
    tfactory = TTransport.TBufferedTransportFactory()
    pfactory = TBinaryProtocol.TBinaryProtocolFactory()

    transport = tfactory.getTransport(transport)
    protocol = pfactory.getProtocol(transport)

    client = CalculatorService.Client(protocol)

    try:
        transport.open()
        print("Add:", client.add(10, 5))
        print("Subtract:", client.subtract(10, 5))
    finally:
        transport.close()

if __name__ == '__main__':
    main()
  1. ক্লায়েন্ট চালান:
    • python3 client.py চালান এবং সার্ভারের সঙ্গে যোগাযোগ নিশ্চিত করুন।

সারসংক্ষেপ

এই প্রকল্পের মাধ্যমে আপনি একটি Thrift সার্ভার ডিপ্লয় করেছেন এবং তার সুরক্ষা নিশ্চিত করেছেন। TLS/SSL ব্যবহারের মাধ্যমে ডেটা স্থানান্তরের সময় সুরক্ষা নিশ্চিত করা হয়েছে, এবং ফায়ারওয়াল কনফিগারেশন করা হয়েছে। এই প্রকল্পটি বাস্তব জীবনের উদাহরণ হিসেবে কাজ করে এবং Thrift ব্যবহারের জন্য একটি কার্যকরী প্ল্যাটফর্ম প্রদান করে।

Content added By
Promotion

Are you sure to start over?

Loading...