how to build customizable multitenant web applications - phpbnl11

83
How to build customizable multitenant web applications Stephan Hochdörfer, bitExpert AG "Building an application so customizable it's the last application you'll ever need to build" Harrie Verveer

Upload: stephan-hochdoerfer

Post on 18-Nov-2014

3.648 views

Category:

Technology


2 download

DESCRIPTION

 

TRANSCRIPT

Page 1: How to build customizable multitenant web applications - PHPBNL11

How to build customizable multitenant web applications

Stephan Hochdörfer, bitExpert AG

"Building an application so customizable it's the last

application you'll ever need to build"

Harrie Verveer

Page 2: How to build customizable multitenant web applications - PHPBNL11

About me

Stephan Hochdörfer, bitExpert AG

Department Manager Research Labs

enjoying PHP since 1999

[email protected]

@shochdoerfer

Page 3: How to build customizable multitenant web applications - PHPBNL11

Single Tenancy

Page 4: How to build customizable multitenant web applications - PHPBNL11

Developer vs. Businessman

Page 5: How to build customizable multitenant web applications - PHPBNL11

Single Tenancy – more customers

Page 6: How to build customizable multitenant web applications - PHPBNL11

Single Tenancy – even more customers

Page 7: How to build customizable multitenant web applications - PHPBNL11

Where will this lead to?

Page 8: How to build customizable multitenant web applications - PHPBNL11

Maintenance nightmare!

Page 9: How to build customizable multitenant web applications - PHPBNL11

Single Tenancy

Tenant 1

Application

Database

Hardware

Page 10: How to build customizable multitenant web applications - PHPBNL11

Single Tenancy

Tenant 2

Application

Database

Hardware

Tenant 1

Application

Database

Hardware

Tenant 3

Application

Database

Hardware

Page 11: How to build customizable multitenant web applications - PHPBNL11

Multi Tenancy

Tenant 2Tenant 1

Application

Database

Hardware

Tenant 3

Page 12: How to build customizable multitenant web applications - PHPBNL11

What should be customizable?

Page 13: How to build customizable multitenant web applications - PHPBNL11

What should be customizable?

Tenant 2Tenant 1

Application

Database

Hardware

Tenant 3

Page 14: How to build customizable multitenant web applications - PHPBNL11

What should be customizable?

Tenant 2Tenant 1

Application

Database

Hardware

Tenant 3

Page 15: How to build customizable multitenant web applications - PHPBNL11

How to skin an application?

Frontend | Branding

Page 16: How to build customizable multitenant web applications - PHPBNL11

How to skin an application?

Application | Frontend

Remember:It`s a web application!

Page 17: How to build customizable multitenant web applications - PHPBNL11

How to skin an application?

Application | Frontend

HTML

Page 18: How to build customizable multitenant web applications - PHPBNL11

How to skin an application?

Application | Frontend

HTML + CSS

Page 19: How to build customizable multitenant web applications - PHPBNL11

Application | Frontend

Page 20: How to build customizable multitenant web applications - PHPBNL11

Application | Frontend

Page 21: How to build customizable multitenant web applications - PHPBNL11

Application | Frontend

Page 22: How to build customizable multitenant web applications - PHPBNL11

How to customize?

Application | Frontend

<!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/myapp.css" /></head><body></body></html>

Page 23: How to build customizable multitenant web applications - PHPBNL11

How to customize?

Application | Frontend

<!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>

Page 24: How to build customizable multitenant web applications - PHPBNL11

How to customize?

Application | Frontend

<!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/myapp.css" /> <link rel="stylesheet" type="text/css" href="css/styles/<?php echo $tenant ?>.css" /></head><body></body></html>

Page 25: How to build customizable multitenant web applications - PHPBNL11

Feature driven CSS

Application | Frontend

Wait, there`s more...

Page 26: How to build customizable multitenant web applications - PHPBNL11

Feature driven CSS

Application | Frontend

display: none

Page 27: How to build customizable multitenant web applications - PHPBNL11

Application | Frontend

Next level...

Page 28: How to build customizable multitenant web applications - PHPBNL11

Menubar generation

Application | Backend

<?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); }

if($user->canAccess(OrderManagement::CANCEL_ORDER)) {

$this->renderLink(OrderManagement::CANCEL_ORDER); }}

Page 29: How to build customizable multitenant web applications - PHPBNL11

Menubar generation

Application | Backend

<?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);}

}}

Page 30: How to build customizable multitenant web applications - PHPBNL11

Menubar generation

Application | Backend

Modularize!

Page 31: How to build customizable multitenant web applications - PHPBNL11

Menubar generation

Application | Backend

Module 2Module 1

Application core

Module 3

register at start up

Page 32: How to build customizable multitenant web applications - PHPBNL11

Menubar generation

Application | Backend

Module 2Module 1

Application core

Module 3

register at start up

Configuration for tenant 1

Page 33: How to build customizable multitenant web applications - PHPBNL11

Menubar generation

Application | Backend

Module 2Module 1

Application core

Module 3

register at start up

Configuration for tenant 2

Page 34: How to build customizable multitenant web applications - PHPBNL11

Optimize workflows

Application | Backend

<?php

if('CC' == $paymentType){ // handle credit card payment}else if('COD' == $paymentType){ // handle cash on delivery payment}

Page 35: How to build customizable multitenant web applications - PHPBNL11

Optimize workflows

Application | Backend

<?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! if(in_array($tenant->getName(), array('tenant3')) {

// insert logic here... }}

Page 36: How to build customizable multitenant web applications - PHPBNL11

Optimize workflows

Application | Backend

Decouple functionality!

Page 37: How to build customizable multitenant web applications - PHPBNL11

Optimize workflows

Application | Backend

<?php

$paymentType = 'CC'; // set via request$payment = PaymentFactory::create($paymentType);

$payment->execute($order);

Page 38: How to build customizable multitenant web applications - PHPBNL11

Optimize workflows

Application | Backend

<?php

$paymentType = 'CC'; // set via request$payment = PaymentFactory::create($paymentType, $tenant);

$payment->execute($order);

Page 39: How to build customizable multitenant web applications - PHPBNL11

Optimize workflows

Application | Backend

How to add custom logic?

Page 40: How to build customizable multitenant web applications - PHPBNL11

Custom logic - Subclassing?

Application | Backend

AbstractPayment

CCPayment

CCPaymentTenant 1

CCPaymentTenant 2

Page 41: How to build customizable multitenant web applications - PHPBNL11

Custom logic

Application | Backend

Any alternatives?

Page 42: How to build customizable multitenant web applications - PHPBNL11

Custom logic

Application | Backend

Let`s add hooks...

Page 43: How to build customizable multitenant web applications - PHPBNL11

Custom logic - Hooks

Application | Backend

<?php

$paymentType = 'CC'; // set via request$payment = PaymentFactory::create($paymentType, $tenant);

if($this->paymentPreProcessor instanceof IPaymentPreProcessor) { $this->paymentPreProcessor->run($payment, $tenant, $order);}

$payment->execute($order);

if($this->paymentPostProcessor instanceof IPaymentPostProcessor) { $this->paymentPostProcessor->run($payment, $tenant, $order);}

Page 44: How to build customizable multitenant web applications - PHPBNL11

Custom logic

Application | Backend

How to set the dependencies?

Page 45: How to build customizable multitenant web applications - PHPBNL11

Custom logic

Application | Backend

Inject the dependencies!

Page 46: How to build customizable multitenant web applications - PHPBNL11

Custom logic – Dependency Injection

Application | Backend

<?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="MyApp.Service.Order" class="MyApp\Service\Order.php"></bean>

<bean id="Tenant1.Service.Order" class="MyApp\Service\Order.php"><property name="paymentPreProcessor"

ref="Tentant1.Payment.PaymentValidation" /></bean>

<bean id="Tenant2.Service.Order" class="MyApp\Service\Order.php"><property name="paymentPreProcessor"

ref="Tentant2.Payment.StrictValidation" /><property name="paymentPostProcessor"

ref="Tentant2.Payment.PushOrderToSAP" /></bean>

</beans>

Page 47: How to build customizable multitenant web applications - PHPBNL11

Custom logic

Application | Backend

Any improvements?

Page 48: How to build customizable multitenant web applications - PHPBNL11

Custom logic

Application | Backend

<?php

$paymentType = 'CC'; // set via request$payment = PaymentFactory::create($paymentType, $tenant);

if($this->paymentPreProcessor instanceof IPaymentPreProcessor) { $this->paymentPreProcessor->run($payment, $tenant, $order);}

$payment->execute($order);

if($this->paymentPostProcessor instanceof IPaymentPostProcessor) { $this->paymentPostProcessor->run($payment, $tenant, $order);}

Page 49: How to build customizable multitenant web applications - PHPBNL11

Custom logic

Application | Backend

<?php

$paymentType = 'CC'; // set via request$payment = PaymentFactory::create($paymentType, $tenant);

if($this->paymentPreProcessor instanceof IPaymentPreProcessor) { $this->paymentPreProcessor->run($payment, $tenant, $order);}

$payment->execute($order);

if($this->paymentPostProcessor instanceof IPaymentPostProcessor) { $this->paymentPostProcessor->run($payment, $tenant, $order);}

Page 50: How to build customizable multitenant web applications - PHPBNL11

Custom logic

Application | Backend

Aspect-oriented programming

Page 51: How to build customizable multitenant web applications - PHPBNL11

Custom logic – Aspects for the masses!

Application | Backend

/** * @aspect */class CustomPaymentProcessingAspect {

/** * @around MyApp\Service\Order->processPayment */public function customFilter(\AOP\JoinPointInterface $joinPoint) {

// @TODO: implement pre-processing logic// ...

$result = $joinPoint->getAdviceChain()->proceed($joinPoint);

// @TODO: implement post-processing logic// ...

return $result;}

}

Page 52: How to build customizable multitenant web applications - PHPBNL11

Custom logic - Result

Application | Backend

<?php

$paymentType = 'CC'; // set via request$payment = PaymentFactory::create($paymentType, $tenant);

$payment->execute($order);

Page 53: How to build customizable multitenant web applications - PHPBNL11

Application | Backend

Next level...

Page 54: How to build customizable multitenant web applications - PHPBNL11

Database – Where to store the data?

Database

Page 55: How to build customizable multitenant web applications - PHPBNL11

Database – Where to store the data?

Database

We need to store data for a tenant!

Page 56: How to build customizable multitenant web applications - PHPBNL11

Database – Where to store the data?

Database

Database per Tenant?

Page 57: How to build customizable multitenant web applications - PHPBNL11

Database – Where to store the data?

Database

Database per Tenant?

Schema per Tenant?

Page 58: How to build customizable multitenant web applications - PHPBNL11

Database – Where to store the data?

Database

Database per Tenant?

Schema per Tenant?

Tenant Id per Row?

Page 59: How to build customizable multitenant web applications - PHPBNL11

Database – How to access the data?

Database

ORM dynamic statements

vs.

Page 60: How to build customizable multitenant web applications - PHPBNL11

What`s beyond?

Generalize you should!

Page 61: How to build customizable multitenant web applications - PHPBNL11

Multi Tenancy

What`s beyond?

Software system family

Page 62: How to build customizable multitenant web applications - PHPBNL11

No single solution!

What`s beyond?

Page 63: How to build customizable multitenant web applications - PHPBNL11

A factory for mass production!

What`s beyond?

Page 64: How to build customizable multitenant web applications - PHPBNL11

Multi Tenancy – Single Instance

Tenant 2Tenant 1

Application

Database

Hardware

Tenant 3

What`s beyond?

Page 65: How to build customizable multitenant web applications - PHPBNL11

Multi Tenancy – Multi Instance

Tenant 2Tenant 1

Application

Database

Hardware

Tenant 3

What`s beyond?

Page 66: How to build customizable multitenant web applications - PHPBNL11

Generative Programming

ConfigurationConfiguration

Implementationcomponents

Implementationcomponents

Generatorapplication

Generatorapplication

ProductProductGenerator

Generator

1 ... n

What`s beyond?

Page 67: How to build customizable multitenant web applications - PHPBNL11

Generative Programming

ConfigurationConfiguration

Implementationcomponents

Implementationcomponents

Generatorapplication

Generatorapplication

Tenant 1Tenant 1

GeneratorGenerator

Tenant xTenant x

What`s beyond?

Page 68: How to build customizable multitenant web applications - PHPBNL11

Generative Programming - Goal

What`s beyond?

Create an optimized application!

Page 69: How to build customizable multitenant web applications - PHPBNL11

Generative Programming - Goal

What`s beyond?

Create an optimized applicationfor one tenant!

Page 70: How to build customizable multitenant web applications - PHPBNL11

Generative Programming – Bonus points

What`s beyond?

Reduce application complexity

Page 71: How to build customizable multitenant web applications - PHPBNL11

Generative Programming – Bonus points

What`s beyond?

FileFrm FILEOrderService_php5 { private String PreProcessor = ""; private String PostProcessor = "";

public FILEOrderService_php5() {setFilename("Order.php5");setRelativePath("/classes/MyApp/Service");

}

private void assign() {BEGINCONTENT()<?php

$paymentType = 'CC'; // set via request$payment = PaymentFactory::create($paymentType, $tenant);

<!{PreProcessor}!>$payment->execute($order);<!{PostProcessor}!>ENDCONTENT() }}

Page 72: How to build customizable multitenant web applications - PHPBNL11

Generative Programming – Bonus points

What`s beyond?

FileFrm FILEOrderService_php5 { [...]

private void configure() {if(this.getConfiguration().hasFeature('PreProcessor')) { PreProcessor = this.getPreProcessorContent(

this.getConfiguration.getTenant() );}

if(this.getConfiguration().hasFeature('PostProcessor')) { PostProcessor = this.getPostProcessorContent(

this.getConfiguration.getTenant() );}

}}

Page 73: How to build customizable multitenant web applications - PHPBNL11

Generative Programming – Bonus points

Application | Backend

Example:Preprocessor:Postprocessor:

Output:

Page 74: How to build customizable multitenant web applications - PHPBNL11

Generative Programming – Bonus points

Application | Backend

<?php

$paymentType = 'CC'; // set via request$payment = PaymentFactory::create($paymentType);

$payment->execute($order);

Example:Preprocessor:Postprocessor:

Output:

Page 75: How to build customizable multitenant web applications - PHPBNL11

Generative Programming – Bonus points

Application | Backend

Example:Preprocessor: $this->paymentPreProcessor->run($payment, $tenant, $order);

Postprocessor:

Output:

Page 76: How to build customizable multitenant web applications - PHPBNL11

Generative Programming – Bonus points

Application | Backend

Example:Preprocessor: $this->paymentPreProcessor->run($payment, $tenant, $order);

Postprocessor:

Output:

<?php

$paymentType = 'CC'; // set via request$payment = PaymentFactory::create($paymentType);

$this->paymentPreProcessor->run($payment, $tenant, $order);

$payment->execute($order);

Page 77: How to build customizable multitenant web applications - PHPBNL11

Generative Programming – Bonus points

What`s beyond?

Reduce maintenance support

Page 78: How to build customizable multitenant web applications - PHPBNL11

Generative Programming – Bonus points

What`s beyond?

FeatureImplementation

component

Page 79: How to build customizable multitenant web applications - PHPBNL11

Generative Programming – Bonus points

What`s beyond?

Feature

Implementationcomponent

Page 80: How to build customizable multitenant web applications - PHPBNL11

Generative Programming – Bonus points

What`s beyond?

Feature

Implementationcomponent

Customer

Page 81: How to build customizable multitenant web applications - PHPBNL11

Generative Programming – The book

What`s beyond?

Page 82: How to build customizable multitenant web applications - PHPBNL11

http://joind.in/2497

Page 83: How to build customizable multitenant web applications - PHPBNL11

Flickr Creditshttp://www.flickr.com/photos/andresrueda/3452940751/

http://www.flickr.com/photos/andresrueda/3455410635/