Upload
stephan-hochdoerfer
View
9.945
Download
10
Embed Size (px)
DESCRIPTION
Citation preview
How to build customizablemultitenant web applications
Multitenant web applications
About me
Stephan Hochdörfer, bitExpert AG
Department Manager Research Labs
enjoying PHP since 1999
@shochdoerfer
Single Tenancy
Multitenant web applications
Developer vs. Businessman
Multitenant web applications
Single Tenancy – more customers
Multitenant web applications
Single Tenancy – even more customers
Multitenant web applications
Multitenant web applications
Where will this lead to?
Multitenant web applications
Maintenance nightmare!
Single Tenancy
Multitenant web applications
Tenant 1
Application
Database
Hardware
Single Tenancy
Multitenant web applications
Tenant 1
Application
Database
Hardware
Tenant 2
Application
Database
Hardware
Tenant 3
Application
Database
Hardware
Multi Tenancy
Multitenant web applications
Tenant 2Tenant 1
Application
Database
Hardware
Tenant 3
What should be customizable?
Multitenant web applications
What should be customizable?
Tenant 2Tenant 1
Application
Database
Hardware
Tenant 3
Multitenant web applications
What should be customizable?
Tenant 2Tenant 1
Application
Database
Hardware
Tenant 3
Multitenant web applications
How to skin an application?
Multitenant web applications
How to skin an application?
Multitenant web applications
Remember:It`s a web application!
How to skin an application?
Multitenant web applications
HTML
How to skin an application?
Multitenant web applications
HTML + CSS
Multitenant web applications
Multitenant web applications
Multitenant web applications
How to customize?
Multitenant web applications
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head> <title>My App</title> <meta http-equiv="Content-Type" content="text/html;charset=utf-8" /> <link rel="stylesheet" type="text/css"href="css/styles/myapp.css" /></head><body></body></html>
How to customize?
Multitenant web applications
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head> <title>My App</title> <meta http-equiv="Content-Type" content="text/html;charset=utf-8" /> <link rel="stylesheet" type="text/css"href="css/styles/<?php echo $tenant ?>.css" /></head><body></body></html>
How to customize?
Multitenant web applications
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head> <title>My App</title> <meta http-equiv="Content-Type" content="text/html;charset=utf-8" /> <link rel="stylesheet" type="text/css"href="css/styles/myapp.css" /> <link rel="stylesheet" type="text/css"href="css/styles/<?php echo $tenant ?>.css" /></head><body></body></html>
Feature driven CSS
Multitenant web applications
Wait, there`s more...
Feature driven CSS
Multitenant web applications
display: none
Multitenant web applications
This is not an security advice!
Multitenant web applications
Next level...
Menubar generation
Multitenant web applications
<?php
if($user->hasEnabled(Module::ORDERMANAGEMENT)){ if($user->canAccess(OrderManagement::LIST_ORDERS)) {
$this->renderLink(OrderManagement::LIST_ORDERS); }
if($user->canAccess(OrderManagement::ADD_ORDER)) {
$this->renderLink(OrderManagement::ADD_ORDER); }}
Menubar generation
Multitenant web applications
<?php
if($tenant->hasModule(Module::ORDERMANAGEMENT){ if($user->hasEnabled(Module::ORDERMANAGEMENT)) {
if($user->canAccess(OrderManagement::LIST_ORDERS)){ $this->renderLink(OrderManagement::LIST_ORDERS);}
if($user->canAccess(OrderManagement::ADD_ORDER)){ $this->renderLink(OrderManagement::ADD_ORDER);}
}}
Menubar generation
Multitenant web applications
Modularize!
Menubar generation
Multitenant web applications
Module 2Module 1
Application core
Module 3
register at start up
Menubar generation
Multitenant web applications
Module 2Module 1
Application core
Module 3
register at start up
Menubar generation
Multitenant web applications
Module 2Module 1
Application core
Module 3
register at start up
Optimize workflows
Multitenant web applications
Optimize workflows
Multitenant web applications
<?php
if('CC' == $paymentType){ // handle credit card payment}else if('COD' == $paymentType){ // handle cash on delivery payment}
Optimize workflows
Multitenant web applications
<?php
if('CC' == $paymentType){ // handle credit card payment for some tenants! if(in_array($tenant->getName(), array('tenant1', 'tenant2')) {
// insert logic here... }}else if('COD' == $paymentType){ // handle cash on delivery payment for some tenants!}
Optimize workflows
Multitenant web applications
Decouple functionality!
Optimize workflows
Multitenant web applications
<?php
$paymentType = 'CC'; // set via request$payment = PaymentFactory::create($paymentType);
$payment->execute($order);
Optimize workflows
Multitenant web applications
<?php
$paymentType = 'CC'; // set via request$payment = PaymentFactory::create($paymentType, $tenant);
$payment->execute($order);
Optimize workflows
Multitenant web applications
How to add custom logic?
Custom logic - Subclassing?
Multitenant web applications
AbstractPayment
CCPayment
CCPaymentTenant 1
CCPaymentTenant 2
Custom logic
Multitenant web applications
Any alternatives?
Custom logic
Multitenant web applications
Let`s add hooks...
Custom logic - Hooks
Multitenant web applications
<?php
$paymentType = 'CC'; // set via request$payment = PaymentFactory::create($paymentType, $tenant);
$payment->execute($order);
if($this->paymentPostProcessor instanceofIPaymentPostProcessor) { $this->paymentPostProcessor->run($payment, $tenant, $order);}
Custom logic
Multitenant web applications
How to set the dependencies?
Custom logic
Multitenant web applications
Dependency Injection!
Custom logic – Dependency Injection
Multitenant web applications
<?xml version="1.0" encoding="UTF-8" ?><beans xmlns="http://www.bitexpert.de/schema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.bitexpert.de/schema/
http://www.bitexpert.de/schema/bitFramework-beans.xsd">
<bean id="Service.Order" class="MyApp\Service\Order.php"></bean>
<bean id="Tenant1.Order" class="MyApp\Service\Order.php"><property name="paymentPostProcessor"
ref="Tentant1.Payment.SendOrderMail" /></bean>
</beans>
Custom logic – Dependency Injection
Multitenant web applications
<?xml version="1.0" encoding="UTF-8" ?><beans xmlns="http://www.bitexpert.de/schema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.bitexpert.de/schema/
http://www.bitexpert.de/schema/bitFramework-beans.xsd">
<bean id="Tenant2.Order" class="MyApp\Service\Order.php"><property name="paymentPostProcessor"
ref="Tentant1.Payment.PushToERP" /></bean>
</beans>
Custom logic
Multitenant web applications
Any further improvements?
Custom logic
Multitenant web applications
<?php
$paymentType = 'CC'; // set via request$payment = PaymentFactory::create($paymentType, $tenant);
$payment->execute($order);
if($this->paymentPostProcessor instanceofIPaymentPostProcessor) { $this->paymentPostProcessor->run($payment, $tenant, $order);}
Custom logic
Multitenant web applications
<?php
$paymentType = 'CC'; // set via request$payment = PaymentFactory::create($paymentType, $tenant);
$payment->execute($order);
if($this->paymentPostProcessor instanceofIPaymentPostProcessor) { $this->paymentPostProcessor->run($payment, $tenant, $order);}
Custom logic
Multitenant web applications
Aspect-oriented programming
Custom logic – Aspects for the masses!
Multitenant web applications
/** * @aspect */class CustomPaymentProcessingAspect {
/** * @around MyApp\Service\Order->processPayment */public function customFilter(JoinPointInterface $jP) {
$result = $jP->getAdviceChain()->proceed($jP);
// @TODO: implement post-processing logic
return $result;}
}
Custom logic - Result
Multitenant web applications
<?php
$paymentType = 'CC'; // set via request$payment = PaymentFactory::create($paymentType, $tenant);
$payment->execute($order);
Multitenant web applications
Next level...
Database – Where to store the data?
Multitenant web applications
Database – Where to store the data?
Multitenant web applications
We need to store data for a tenant!
Database – Where to store the data?
Multitenant web applications
Database per Tenant?
Database – Where to store the data?
Multitenant web applications
Database per Tenant?
Schema per Tenant?
Database – Where to store the data?
Multitenant web applications
Database per Tenant?
Schema per Tenant?
Tenant Id per Row?
Database – How to access the data?
Multitenant web applications
ORM dynamic statements
vs.
Multitenant web applications
Generalize you should!
No single solution!
Multitenant web applications
Multitenant web applications
Softwaresystemfamily
A factory for mass production!
Multitenant web applications
Multi Tenancy – Single Instance
Tenant 2Tenant 1
Application
Database
Hardware
Tenant 3
Multitenant web applications
Multi Tenancy – Multi Instance
Tenant 2Tenant 1
Application
Database
Hardware
Tenant 3
Multitenant web applications
Multi Tenancy – Multi Instance
Multitenant web applications
Generative Programming
Generative Programming
Multitenant web applications
GeneratorGenerator
Generative Programming
Multitenant web applications
Configuration(DSL)
Configuration(DSL)
GeneratorGenerator
Generative Programming
Multitenant web applications
Configuration(DSL)
Configuration(DSL)
Implementation-components
Implementation-components GeneratorGenerator
Generative Programming
Multitenant web applications
Configuration(DSL)
Configuration(DSL)
Implementation-components
Implementation-components GeneratorGenerator
ProductProduct
1..n
Generative Programming
Multitenant web applications
Configuration(DSL)
Configuration(DSL)
Implementation-components
Implementation-components GeneratorGenerator
Tenant 1Tenant 1
Generative Programming
Multitenant web applications
Configuration(DSL)
Configuration(DSL)
Implementation-components
Implementation-components GeneratorGenerator
Tenant 1Tenant 1
Tenant 2Tenant 2
Generative Programming
Multitenant web applications
Configuration(DSL)
Configuration(DSL)
Implementation-components
Implementation-components
Tenant 3Tenant 3
GeneratorGeneratorTenant 1Tenant 1
Tenant 2Tenant 2
Generative Programming - Goal
Multitenant web applications
Create an optimized application!
Generative Programming - Goal
Multitenant web applications
Create an optimized application for one tenant!
Generative Programming – Bonus points
Multitenant web applications
Generative Programming – Bonus points
Multitenant web applications
Reduce application complexity
Generative Programming – Bonus points
Multitenant web applications
<?php
$paymentType = 'CC'; // set via request$payment = PaymentFactory::create($paymentType, $tenant);
$payment->execute($order);
<!{PostProcessor}!>
Generative Programming – Bonus points
Multitenant web applications
public class PostProcessorFrame extends SimpleFrameController{
public void execute(Frame frame, FeatureConfig config) {if(config.hasFeature("order_send_mail")) { frame.setSlot("PostProcessor", "...");}
if(config.hasFeature("order_push_to_erp")) { frame.setSlot("PostProcessor", "...");}
}}
Generative Programming – Bonus points
Multitenant web applications
Reduce maintenance support
Generative Programming – Bonus points
Multitenant web applications
FeatureImplementation
component
Generative Programming – Bonus points
Multitenant web applications
Feature Tenant
Generative Programming – Bonus points
Multitenant web applications
Feature
Implementationcomponent
Tenant
Generative Programming – The book
Multitenant web applications
http://joind.in/3517
Flickr Creditshttp://www.flickr.com/photos/andresrueda/3452940751/
http://www.flickr.com/photos/andresrueda/3455410635/