Servie Oriented Architecture

You might also like

Download as pdf or txt
Download as pdf or txt
You are on page 1of 25

Practical 1

Aim : Design SOA for the E-Commerce using the following features:
i) Service granularity
ii) Service versioning and evolution

CODE:-

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>

using namespace std;


struct Customer {
int id;
string name;
string email;
string address;
string phoneNumber;
};
class CustomerManagementService {
public:
virtual Customer getCustomerById(int customerId) = 0;
virtual void updateCustomerProfile(int customerId, string newName,
string newEmail, string newAddress,
string newPhoneNumber) = 0;
virtual void addCustomer(Customer &customer) = 0;
virtual void deleteCustomer(int customerId) = 0;
virtual ~CustomerManagementService() {}
};
class CustomerManagementService_v1 : public CustomerManagementService {
private:
vector<Customer> customers;
public:
CustomerManagementService_v1() {
customers.push_back(
{1, "John Doe", "john@example.com", "123 Main St", "555-1234"});
customers.push_back(
{2, "Jane Smith", "jane@example.com", "456 Elm St", "555-5678"});
}

Customer getCustomerById(int customerId) override {


for (auto customer : customers) {
if (customer.id == customerId) {
return customer;
}
}
throw runtime_error("Customer not found");
}

void updateCustomerProfile(int customerId, string newName,


string newEmail, string newAddress,
string newPhoneNumber) override {
for (auto &customer : customers) {
if (customer.id == customerId) {
customer.name = newName;
customer.email = newEmail;
customer.address = newAddress;
customer.phoneNumber = newPhoneNumber;
return;} }
throw runtime_error("Customer not found");}
void addCustomer(Customer &customer) override {
customers.push_back(customer); }
void deleteCustomer(int customerId) override {
auto it =
remove_if(customers.begin(), customers.end(),
[customerId](Customer &c) { return c.id == customerId; });
if (it == customers.end()) {
throw runtime_error("Customer not found"); }
customers.erase(it, customers.end()); }};
int main() {
CustomerManagementService *customerService =
new CustomerManagementService_v1();
try {
Customer newCustomer = {3, "Alice Brown", "alice@example.com", "789 Oak St",
"555-9012"};
customerService->addCustomer(newCustomer);
Customer customer = customerService->getCustomerById(3);
cout << "Newly added customer: ID: " << customer.id
<< ", Name: " << customer.name << ", Email: " << customer.email
<< ", Address: " << customer.address
<< ", Phone Number: " << customer.phoneNumber << endl;
customerService->updateCustomerProfile(
1, "John Smith", "john.smith@example.com", "321 Pine St", "555-3456");
customer = customerService->getCustomerById(1);
cout << "Updated Customer Profile: ID: " << customer.id
<< ", Name: " << customer.name << ", Email: " << customer.email
<< ", Address: " << customer.address
<< ", Phone Number: " << customer.phoneNumber << endl;
customerService->deleteCustomer(2);
cout << "Customer with ID 2 has been deleted." << endl;
} catch (const runtime_error &e) {
cerr << "Error: " << e.what() << endl;
}
delete customerService;

return 0;
}
OUTPUT:-
Practical 2

Aim: Write a program to illustrate any five services for components such as Order Processing,
Payment Processing and stock list using SOA characteristics

CODE:-

#include <iostream>

#include <unordered_map>

#include <vector>

#include <string>

class Service {

public:

virtual ~Service() {}

virtual std::string getName() const = 0;

};

class ProductService : public Service {

private:

std::unordered_map<int, std::string> products;

public:

ProductService() {

products = {

{1, "T-Shirt"},

{2, "Mug"},

};}

std::string getName() const override { return "Product Service"; }

std::string getProduct(int id) const {

auto it = products.find(id);

if (it != products.end()) {

return it->second;

return "";
}};

class InventoryService : public Service {

private:

std::unordered_map<int, int> stock;

public:

InventoryService() {

stock = {

{1, 10},

{2, 5},

};}

std::string getName() const override { return "Inventory Service"; }

int getStock(int id) const {

auto it = stock.find(id);

if (it != stock.end()) {

return it->second;

return 0;

}};

class OrderService : public Service {

private:

const ProductService& productService;

const InventoryService& inventoryService;

public:

OrderService(const ProductService& productService, const InventoryService& inventoryService) :

productService(productService), inventoryService(inventoryService) {}

std::string getName() const override { return "Order Service"; }

std::string placeOrder(int product_id, int quantity) {

std::string product_name = productService.getProduct(product_id);

if (product_name.empty()) {

return "Product not found";

}
int available_stock = inventoryService.getStock(product_id);

if (available_stock < quantity) {

return "Insufficient stock";}

return "Order placed successfully for " + product_name + " (x" + std::to_string(quantity) + ")";

}};

class PaymentService : public Service {

public:

std::string getName() const override { return "Payment Service"; }

bool processPayment() {

return true;

}};

class ServiceLocator {

private:

std::unordered_map<std::string, const Service*> services;

public:

void registerService(const std::string& name, const Service* service) {

services[name] = service;

const Service* getService(const std::string& name) const {

auto it = services.find(name);

if (it != services.end()) {

return it->second; }

return nullptr;

};

int main() {

ProductService productService;

InventoryService inventoryService;

PaymentService paymentService;

OrderService orderService(productService, inventoryService);


std::string result = orderService.placeOrder(1, 2);

std::cout << result << std::endl;

if (paymentService.processPayment()) {

std::cout << "Payment successful!" << std::endl;

} else {

std::cout << "Payment failed!" << std::endl;

return 0;

OUTPUT:-

This output explain about the following sequence:


1. Product Service: Since the placeOrder function directly calls the getProduct function from
ProductService, it retrieves product information before proceeding. The output simulates retrieving
product details for product ID 1 (T-Shirt).
2. Order Processing: The placeOrder function successfully places an order for two T-Shirts.
3. Payment Processing (simulated): The processPayment function simulates successful payment
processing.
This program demonstrates the following SOA characteristics:
• Loose Coupling: Services interact through well-defined interfaces without depending on each
other's implementation details.
• Standardized Services: Each service follows a standard approach for communication (e.g.,
messages).
• Service Reusability: Services can be reused in different applications.
• Location Transparency: Consumers don't need to know the physical location of a service.
• Interoperability: Services can be built using different technologies and still communicate
effectively.
Practical 3

Aim: Write RESTful APIs for E-Commerce to illustrate the following:


(i) Stateless
(ii) Resource-based
(iii) Cacheable

CODE:-

const express = require('express');

const bodyParser = require('body-parser');

const app = express();

const PORT = 3000;

let products = [

"id": 1,

" tle": "Fjallraven - Foldsack No. 1 Backpack, Fits 15 Laptops",

"price": 109.95,

"descrip on": "Your perfect pack for everyday use and walks in the forest. Stash your laptop (up to 15 inches) in
the padded sleeve, your everyday",

"category": "men's clothing",

"image": "h ps://fakestoreapi.com/img/81fPKd-2AYL._AC_SL1500_.jpg",

"ra ng": {

"rate": 3.9,

"count": 120

} },

"id": 2,

" tle": "Mens Casual Premium Slim Fit T-Shirts ",

"price": 22.3,

"descrip on": "Slim- ng style, contrast raglan long sleeve, three-bu on henley placket, light weight & so fabric
for breathable and comfortable wearing. And Solid s tched shirts with round neck made for durability and a great t
for casual fashion wear and diehard baseball fans. The Henley style round neckline includes a three-bu on placket.",
ti
ti
ti
ti
ti
tt
fi
tti
ti
tt
tt
ft
fi
"category": "men's clothing",

"image": "h ps://fakestoreapi.com/img/71-3HjGNDUL._AC_SY879._SX._UX._SY._UY_.jpg",

"ra ng": {

"rate": 4.1,

"count": 259

} },

"id": 3,

" tle": "Mens Co on Jacket",

"price": 55.99,

"descrip on": "great outerwear jackets for Spring/Autumn/Winter, suitable for many occasions, such as working,
hiking, camping, mountain/rock climbing, cycling, traveling or other outdoors. Good gi choice for you or your family
member. A warm hearted love to Father, husband or son in this thanksgiving or Christmas Day.",

"category": "men's clothing",

"image": "h ps://fakestoreapi.com/img/71li-ujtlUL._AC_UX679_.jpg",

"ra ng": {

"rate": 4.7,

"count": 500

},

];

app.use(bodyParser.json());

app.get('/products', (req, res) => {

res.json(products);

});

app.get('/products/:id', (req, res) => {

const productId = parseInt(req.params.id);

const product = products. nd(product => product.id === productId);

if (!product) {
ti
ti
ti
ti
tt
tt
tt
fi
ft
return res.status(404).json({ message: 'Product not found' });

res.json(product);

});

app.post('/products', (req, res) => {

const { name, price } = req.body;

const newProduct = { id: products.length + 1, name, price };

products.push(newProduct);

res.status(201).json(newProduct);

});

app.put('/products/:id', (req, res) => {

const productId = parseInt(req.params.id);

const { name, price } = req.body;

const productIndex = products. ndIndex(product => product.id === productId);

if (productIndex === -1) {

return res.status(404).json({ message: 'Product not found' });

products[productIndex] = { id: productId, name, price };

res.json(products[productIndex]);

});

app.delete('/products/:id', (req, res) => {

const productId = parseInt(req.params.id);

const productIndex = products. ndIndex(product => product.id === productId);

if (productIndex === -1) {

return res.status(404).json({ message: 'Product not found' });


fi
fi
}

products.splice(productIndex, 1);

res.status(204).end();

});

app.listen(PORT, () => {

console.log(`Server is running on h p://localhost:${PORT}`);

});

Principles of stateless, resource based and cacheable are implemented in the following manner:

Stateless:

The statelessness principle is depicted by the fact that the server does not maintain any client state between
requests. This is evident in how each route handler func on (e.g., GET /products, POST /products, etc.) only relies on
the informa on provided in the request itself (e.g., request body, URL parameters) to perform its opera on.

Resource-Based:

The resource-based principle is depicted by the fact that products are represented as resources, each iden ed by a
unique ID.

The routes follow a resource-oriented URI pa ern, where /products represents the collec on of products and /
products/:id represents an individual product by its ID.

Cacheable:

By se ng appropriate caching headers (e.g., Cache-Control, Expires, ETag) in the response, clients and intermediary
caches can cache the responses from these APIs.

Cacheability improves the e ciency of the API by allowing clients to reuse previously fetched responses, reducing
the need for repeated requests to the server.
tti
ti
ffi
tt
tt
ti
ti
ti
ti
fi
OUTPUT:-

RESPONSES FOR API REQUESTS:


Practical 4

Aim: Design SOA-Based examination system with the following features:

(i) Service Modeling and Design standards

(ii) Security in SOA and Quality of Service

#include <iostream>
#include <unordered_map>
#include <string>

using namespace std;


class User {
private:
string username;
string password;
public:
User(){}
User(string _username, string _password) : username(_username), password(_password) {}
string getUsername() const { return username; }
string getPassword() const { return password; }
};
unordered_map<string, User> userDatabase;

class AuthenticationService {
public:
bool authenticateUser(const string& username, const string& password) {
if (userDatabase.find(username) != userDatabase.end()) {
if (userDatabase[username].getPassword() == password) {
cout << "User '" << username << "' authenticated successfully." << endl;
return true;
}
}
cout << "Authentication failed. Invalid username or password." << endl;
return false;
}
};
class TestService {
public:
void takeTest(const string& username, const string& testName) {
cout << "User '" << username << "' is taking the test '" << testName << "'." << endl;
}
};
int main() {
userDatabase["yukti"] = User("yukti", "Yukti@0212");
userDatabase["user2"] = User("user2", "password2");
AuthenticationService authService;
TestService testService;
string username, password;
cout << "Enter username: ";
cin >> username;
cout << "Enter password: ";
cin >> password;

if (authService.authenticateUser(username, password)) {
// If authentication succeeds, allow the user to take a test
string testName;
cout << "Authentication successful. Enter test name: ";
cin >> testName;
testService.takeTest(username, testName);
}

return 0;
}

OUTPUT:-
Practical 5

Aim: Design Banking SOA with the following features:

(i) Service contracts

(ii) SOA Policy

(iii) SOA governance and management

(iv) Security in SOA

#include "AccountServiceImpl.h"
#include "TransactionServiceImpl.h"
#include "CustomerServiceImpl.h"
#include <iostream>

using namespace std;


// AccountServiceImpl.h
#pragma once

#include "AccountService.h"
#include <unordered_map>
#include <vector>
#include <utility>

class AccountServiceImpl : public AccountService {


private:
unordered_map<string, double> accounts;
unordered_map<string, vector<pair<string, double>>> transactionHistory; // accountId -> (type, amount)
history

public:
bool createAccount(const string& accountId, double initialBalance) override {
if (accounts.find(accountId) != accounts.end()) {
return false; // Account already exists
}
accounts[accountId] = initialBalance;
transactionHistory[accountId]; // Initialize transaction history
return true;
}

bool deleteAccount(const string& accountId) override {


auto it = accounts.find(accountId);
if (it == accounts.end()) {
return false; // Account does not exist
}
accounts.erase(it);
transactionHistory.erase(accountId);
return true;
}

double getAccountBalance(const string& accountId) override {


auto it = accounts.find(accountId);
if (it == accounts.end()) {
return -1; // Account not found
}
return it->second;
}

bool updateAccountBalance(const string& accountId, double amount) override {


auto it = accounts.find(accountId);
if (it == accounts.end()) {
return false; // Account not found
}
it->second += amount;
transactionHistory[accountId].emplace_back(amount > 0 ? "Deposit" : "Withdraw", amount);
return true;
}

vector<pair<string, double>> getTransactionHistory(const string& accountId) {


return transactionHistory[accountId];
}
};

//TransactionServiceImpl
#pragma once

#include "TransactionService.h"
#include "AccountService.h"

class TransactionServiceImpl : public TransactionService {


private:
AccountService& accountService;

public:
TransactionServiceImpl(AccountService& accountService) : accountService(accountService) {}
bool deposit(const string& accountId, double amount) override {
return accountService.updateAccountBalance(accountId, amount);
}

bool withdraw(const string& accountId, double amount) override {


return accountService.updateAccountBalance(accountId, -amount);
}

bool transfer(const string& fromAccount, const string& toAccount, double amount) override {
if (!accountService.updateAccountBalance(fromAccount, -amount)) {
return false; // Insufficient balance
}
return accountService.updateAccountBalance(toAccount, amount);
}
};
//TransactionService
#pragma once

#include <string>

using namespace std;

class TransactionService {
public:
virtual bool deposit(const string& accountId, double amount) = 0;
virtual bool withdraw(const string& accountId, double amount) = 0;
virtual bool transfer(const string& fromAccount, const string& toAccount, double amount) = 0;
virtual ~TransactionService() {}
};
//CustumerServiceIMPL
#pragma once

#include "CustomerService.h"
#include <unordered_map>

class CustomerServiceImpl : public CustomerService {


private:
unordered_map<string, string> customers; // customerID -> password

public:
CustomerServiceImpl() {
// Initialize with some dummy data
customers["user1"] = "password1";
customers["user2"] = "password2";
}

bool authenticate(const string& customerId, const string& password) override {


auto it = customers.find(customerId);
if (it == customers.end()) {
return false; // Customer not found
}
return it->second == password;
}
};
//customerService

#pragma once

#include "CustomerService.h"
#include <unordered_map>

class CustomerServiceImpl : public CustomerService {


private:
unordered_map<string, string> customers; // customerID -> password

public:
CustomerServiceImpl() {
// Initialize with some dummy data
customers["user1"] = "password1";
customers["user2"] = "password2";
}

bool authenticate(const string& customerId, const string& password) override {


auto it = customers.find(customerId);
if (it == customers.end()) {
return false; // Customer not found
}
return it->second == password;
}
};
//customerService

#pragma once

#include <string>

using namespace std;


class CustomerService {
public:
virtual bool authenticate(const string& customerId, const string& password) = 0;
virtual ~CustomerService() {}
};
int main() {
AccountServiceImpl accountService;
TransactionServiceImpl transactionService(accountService);
CustomerServiceImpl customerService;
accountService.createAccount("acc1", 1000.0);
accountService.createAccount("acc2", 500.0);
transactionService.deposit("acc1", 200.0);
transactionService.withdraw("acc1", 100.0);
transactionService.transfer("acc1", "acc2", 300.0);
vector<pair<string, double>> history = accountService.getTransactionHistory("acc1");
cout << "Transaction history of acc1:\n";
for (const auto& entry : history) {
cout << entry.first << ": " << entry.second << endl;
}
cout << "Authentication result for user1: " << (customerService.authenticate("user1", "password1") ?
"Success" : "Failure") << endl;

return 0;
}

OUTPUT:-
Practical 6

Aim: Design SOA for an Organization with the following features

(1) Service identification and modeling

(ii) Service contracts

#include <iostream>
#include <string>
using namespace std;
class ServiceContract {
private:
string clientName;
string developerName;
string fee;
string paymentSchedule;
string penaltyPercentage;
string jurisdiction;
public:
ServiceContract(string clientName, string developerName, string fee, string paymentSchedule, string
penaltyPercentage, string jurisdiction) {
this->clientName = clientName;
this->developerName = developerName;
this->fee = fee;
this->paymentSchedule = paymentSchedule;
this->penaltyPercentage = penaltyPercentage;
this->jurisdiction = jurisdiction;
}
void generateContract() {
cout << "*Service Contract for E-Marketing*\n\n";
cout << "*Parties:*\n\n";
cout << "Client: " << clientName << endl;
cout << "Developers: " << developerName << endl << endl;
cout << "*Payment Terms:*\n\n";
cout << "1. The Client agrees to pay the Developers the agreed-upon fee of " << fee << " for the e-
marketing services provided.\n\n";
cout << "2. Payment will be made in installments as follows:\n - " << paymentSchedule << endl <<
endl;
cout << "3. Late payments will incur a penalty of " << penaltyPercentage << "% per week.\n\n";
cout << "*Governing Law:*\n\n";
cout << "This contract shall be governed by and construed in accordance with the laws of " <<
jurisdiction << ".\n\n";
}};
int main() {
string clientName = "XYZ Company";
string developerName = "ABC Marketing Agency";
string fee = "$5000";
string paymentSchedule = "50% upfront, 25% upon reaching milestones, and 25% upon completion";
string penaltyPercentage = "5";
string jurisdiction = "New York";
ServiceContract contract(clientName, developerName, fee, paymentSchedule, penaltyPercentage,
jurisdiction);
contract.generateContract();
return 0;
}

OUTPUT:-
Practical 7
Aim : Implement SOAP based web service to create to-do list application in XML language.

<?xml version="1.0" encoding="UTF-8"?>


<definitions name="ToDoListService" targetNamespace="http://todolist.example.com">
<messages>
<message name="GetToDoListRequest">
</message>
<message name="GetToDoListResponse">
<part name="todos" type="tns:ToDoList"/>
</message>
<message name="AddToDoItemRequest">
<part name="item" type="tns:ToDoItem"/>
</message>
<message name="AddToDoItemResponse">
<part name="message" type="xsd:string"/>
</message>
</messages>
<portType name="ToDoListPortType">
<operation name="getToDoList">
<input message="tns:GetToDoListRequest"/>
<output message="tns:GetToDoListResponse"/>
</operation>
<operation name="addTodoItem">
<input message="tns:AddToDoItemRequest"/>
<output message="tns:AddToDoItemResponse"/>
</operation>
</portType>
<types>
<schema targetNamespace="http://todolist.example.com" xmlns:tns="http://todolist.example.com"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<complexType name="ToDoItem">
<sequence>
<element name="id" type="xsd:int"/>
<element name="text" type="xsd:string"/>
<element name="completed" type="xsd:boolean"/>
</sequence>
</complexType>
<complexType name="ToDoList">
<sequence>
<element name="item" type="tns:ToDoItem" minOccurs="0" maxOccurs="unbounded"/>
</sequence>
</complexType>
</schema>
</types>
<service name="ToDoListService">
<port name="ToDoListPort" binding="tns:ToDoListBinding">
<soap:address location="http://localhost:8080/todolist"/>
</port>
</service>
<binding name="ToDoListBinding" type="tns:ToDoListPortType">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http"/>
<operation name="getToDoList">
<soap:operation soapAction="http://todolist.example.com/getToDoList"/>
<input>
<soap:body use="literal" parts="tns:GetToDoListRequest"/>
</input>
<output>
<soap:body use="literal" parts="tns:GetToDoListResponse"/>
</output>
</operation>
<operation name="addTodoItem">
<soap:operation soapAction="http://todolist.example.com/addTodoItem"/>
<input>
<soap:body use="literal" parts="tns:AddToDoItemRequest"/>
</input>
<output>
<soap:body use="literal" parts="tns:AddToDoItemResponse"/>
</output>
</operation>
</binding>
</definitions>

OUTPUT:-

You might also like