L09 Process Design

49
HÖNNUN OG SMÍÐI HUGBÚNAÐAR 2015 L09 PROCESS DESIGN

Transcript of L09 Process Design

Page 1: L09 Process Design

HÖNNUN OG SMÍÐI HUGBÚNAÐAR 2015L09 PROCESS DESIGN

Page 2: L09 Process Design

Agenda

Why processes?Ru FrameworkRU Process Framework ImplementationImport Content Process

Page 3: L09 Process Design

Why Processes?

Page 4: L09 Process Design

What is a Processes anyway?▪ Enterprise system need to run processes for several

reasons– Manual, event-driven, scheduled▪ Things in the “background”, for exampe:– Nightly update of customers– Reconciliation of systems▪ Lengthy operations– Recalculate of all accounts▪ Processes have no user interface– Traditionally know as “Jobs”

Page 5: L09 Process Design

Our Task

We need to build a framework from running processesWhat patterns can we use?

Page 6: L09 Process Design

Design Issues▪ Each process has simple task▪ Each process can be re-run at any time▪ Locations are always the same▪ Logging is always the same▪ Customer specific functionality

can be added to generic processes▪ Other considerations– Must handle large amount of data– Must support multiple threads for performance

Process Framework

Generic Process

Customer Specific Plugin

Page 7: L09 Process Design

RU Framework

Page 8: L09 Process Design

RU Framework▪ Simple Framework developed during the course– Illustrates design ideas– Application Framework– Reduce dependence on other frameworks by wrapping

them in interfaces and classes– Builds on Spring▪ Package– is.ruframework• domain• process– All classes are prefixed with “Ru”

Page 9: L09 Process Design

▪ The idea is that the Process Framework starts the process▪ Process Developers must implement some interface▪ Information will be in a context XML file

Process Framework

Process Framework

processContext.xmlProcess Class

read CreateCall methods

Page 10: L09 Process Design

Process Design▪ Let’s create an interface, RuProcess– This is what all processes have to implement

package is.ruframework.process;

public interface RuProcess { public void startProcess (); public void beforeProcess (); public void afterProcess (); }

Page 11: L09 Process Design

Process Design▪ Let’s implement this with RuAbstractProcess– Processes can extend this classes – Layer Supertype

package is.ruframework.process;

import is.ruframework.domain.RuObject;

abstract public class RuAbstractProcess extends RuObject implements RuProcess { abstract public void startProcess (); public void beforeProcess () { } public void afterProcess () { } }

Page 12: L09 Process Design

Process Design▪ We needs some context, RuProcessContext– Processes can get information about their process from this

context

public class RuProcessContext { private String processName; private String processClass; private String importFile; private String importURL; private String dataSourceFile; private Map params;

... }

Page 13: L09 Process Design

Process Design▪ Let’s change the interface, RuProcess

– Dependency Injection

package is.ruframework.process;

public interface RuProcess { public void setProcessContext (RuProcessContext processContext); public void setParameters(String[] params); abstract public void startProcess (); public void beforeProcess (); public void afterProcess (); }

Page 14: L09 Process Design

▪ Change the RuAbstractProcess– Let this class implement the injection

abstract public class RuAbstractProcess extends RuObject implements RuProcess { private RuProcessContext processContext; private String contextFile; private String parameters[]; ... public void setProcessContext(RuProcessContext processContext) { this.processContext = processContext; } ...

Process Design

Page 15: L09 Process Design

▪ Let’s use a factory to create the process, RuProcessFactory– This class can load the context file

public class RuProcessFactory { private String contextFile; private RuProcessContext processContext;

public RuProcess loadProcess(RuProcessContext ctx) throws RuProcessException public void loadProcessContext(String contextFile) throws RuProcessException ... }

Process Design

Page 16: L09 Process Design

▪ Create a class to run the process, RuProcessRunner– This class puts everything together

public class RuProcessRunner extends RuObject implements Runnable { private RuProcess process = null;

public static void main(String[] args) { } public RuProcessRunner(String contextFile) throws RuProcessException public void run() { } }

Process Design

Page 17: L09 Process Design

RU Process Framework Implementation

Page 18: L09 Process Design

Process Framework▪ To create process, we must

– Create the process class that implements RuProcess– Create the Process Context XML file

Process Framework

processContext.xmlProcess Class

read CreateCall methods

Page 19: L09 Process Design

Process Context XML file▪ The framework will create the object RuProcessContext

<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" http://www.springframework.org/dtd/spring-beans.dtd> <beans> <bean id="processContext” class="is.ruframework.process.RuProcessContext"> <property name="processName"> <value>RSSProcess</value> </property> <property name="importURL"> <value>http://rss.news.yahoo.com/rss/tech</value> </property> <property name="processClass"> <value>is.ru.honn.blog.process.RssReaderProcess</value> </property> </bean> </beans>

Page 20: L09 Process Design

RuProcessContext

▪ Class for storing the Process Context– The environment the process runs in– Attributes line process name, class, importURL, data source

Page 21: L09 Process Design

The RuProcess Interface▪ RuProcess is the interface for all processes▪ The framework will load the process context and set

with setProcessContext– Dependency Injection▪ The Framework will call the process methods– beforeProcess, startProcess, afterProcess

Page 22: L09 Process Design

RuProcess▪ RuProcess is the interface for all processes

– The Process Factory will call setProcessContext

public interface RuProcess { public void setProcessContext(RuProcessContextprocessContext); public void setParameters(String[] params); public void startProcess (); public void beforeProcess (); public void afterProcess (); }

Page 23: L09 Process Design

RuAbstractProcess▪ Abstract class that implements RuProcess

– Takes care of handling Process Context– Overrides beforeProcess

and afterProcess with empty methods, allowing them to become optional

– Declares startProcessas abstract

Page 24: L09 Process Design

Template Method▪ Interface defines the methods needed

– Some are generic for all derived classes▪ Use abstract super classes to implement some but not all of

the interface methods

InterfacemethodA methodB

abstract super classmethodA

abstract methodB

Concrete classmethodB

implements

extends

Page 25: L09 Process Design

RuAbstractProcessabstract public class RuAbstractProcess extends RuObject implements RuProcess { private RuProcessContextprocessContext; private String contextFile; private String parameters[];

public void setProcessContext(RuProcessContextprocessContext) { this.processContext = processContext; }

public RuProcessContextgetProcessContext() { return processContext; } ... abstract public void startProcess (); public void beforeProcess () {} public void afterProcess () {} }

Eat these methods

Page 26: L09 Process Design

RuProcessFactory▪ Factory that loads processes

– Factroy and Plugin Patterns– loadProcess method returns RuProcess– Extends the generic RuFactory

Page 27: L09 Process Design

RuProcessFactorypublic class RuProcessFactory extends RuFactory { private static final String PROCESS_CONTEXT = "process.xml"; private RuProcessContextprocessContext;

public RuProcessloadProcess(RuProcessContextctx) throws RuProcessException { RuProcess process = null;

// Load the process specified in the context file try { Class cls = Class.forName(ctx.getProcessClass()); process = (RuProcess)cls.newInstance(); process.setProcessContext(ctx); } catch (Exception e) { ... } return process; }

Page 28: L09 Process Design

RuProcessFactory

public void loadProcessContext(String contextFile) throws RuProcessException { try { processContext = (RuProcessContext)getObject("processContext"); } catch (BeansException e) { String tmp = "File '" + contextFile + "' not found. Exception: " + e.getMessage(); log.severe(tmp); throw new RuProcessException(tmp, e); }

}

Page 29: L09 Process Design

RuProcessRunner▪ Class that calls the factory and runs the process

– Name of Process Context file is parameter

Page 30: L09 Process Design

public static void main(String[] args) { RuProcessRunner runner;

if (args.length> 0) { runner = new RuProcessRunner(args[0]); } else { runner = new RuProcessRunner(); }

try { runner.run(); } catch (RuProcessExceptionfwpe) { System.out.println(fwpe.getMessage()); } }

RuProcessRunner

Page 31: L09 Process Design

public RuProcessRunner(String contextFile) throws RuProcessException { if (contextFile == null) { String tmp = "Parameter contextFile must not be null"; log.severe(tmp); throw new RuProcessException(tmp); } RuProcessFactory factory = new RuProcessFactory(contextFile); process = factory.loadProcess(); } public void run() { if (process != null) { process.beforeProcess(); process.startProcess(); process.afterProcess(); } } }

RuProcessRunner

Page 32: L09 Process Design

Process Framework

Page 33: L09 Process Design

Data Transfer Object

Factory

Plug-in

Layered Supertype

Dependency injection

Layered Supertype

Process Framework

Template Method

Page 34: L09 Process Design

Import Content Process

Page 35: L09 Process Design

Import Content Process▪ Problem– We need to import RSS feeds into our database– Example URL:

http://rss.news.yahoo.com/rss/tech

▪ Solution– Use the RU Framework• ImportContentPrcess– Use the FeedReader

Page 36: L09 Process Design

Import Content Process▪ Process that reads contents from an URL▪ Tasks

– Creates a FeedReader to read entries– The process implements the processContent callback– Uses ContentService from our Domain Layer to store each

content– Must log out the progress using a message source

Page 37: L09 Process Design

▪ Process that reads contents from an URL▪ Tasks

– The Process must “wire” all components together– Mapper Design Pattern

Import Content Process

Import ContentProcess

process.xml

uses

reads

FeedReader

ContentService

uses

app.xml

reads

Page 38: L09 Process Design

▪ Process that reads contents from an URL▪ Solution

– Create class ImportContentProcess that extends RuAbstractProcessbeforeProcessstartProcessafterProcess

– Define the Process Context in process.xml– Use Spring ApplicationContext to load all the components

• Specified in app.xml

Import Content Process

Page 39: L09 Process Design

public class ImportContentProcess extends RuAbstractProcess implements FeedHandler { protected ContentServicecontentService; FeedReader reader; MessageSourcemsg;

public void beforeProcess() { ApplicationContextctx = new FileSystemXmlApplicationContext("app.xml"); contentService = (ContentService)ctx.getBean("contentService"); reader = (FeedReader)ctx.getBean("feedReader"); reader.setFeedHandler(this); msg = (MessageSource)ctx.getBean("messageSource"); log.info(msg.getMessage("processbefore", new Object[] { getProcessContext().getProcessName() } , Locale.getDefault())); }

Import Content Process

Page 40: L09 Process Design

ApplicationContextctx = new FileSystemXmlApplicationContext("app.xml"); contentService = (ContentService)ctx.getBean("contentService"); reader = (FeedReader)ctx.getBean("feedReader"); reader.setFeedHandler(this); msg = (MessageSource)ctx.getBean("messageSource");

<beans> <bean id="messageSource“ class= "org.springframework.context.support.ResourceBundleMessageSource"> <property name="basename“><value>messages</value></property> </bean> <bean id="contentService" class="is.ru.honn.tube.service.content.ContentServiceStub"> </bean> <bean id="feedReader" class="is.ru.honn.tube.feeds.RssReader"> </bean> </beans>

app.xml

Import Content ProcessImportContentProcess.java

Page 41: L09 Process Design

public void startProcess() { log.info(msg.getMessage("processstart", new Object[] { getProcessContext().getProcessName() }, Locale.getDefault())); try { reader.read(getProcessContext().getImportURL()); } catch (FeedException e) { log.info(msg.getMessage("processreaderror", new Object[] { getProcessContext().getImportFile() }, Locale.getDefault())); log.info(e.getMessage()); } log.info(msg.getMessage("processstartdone", new Object[] {contentService.getContents().size()}, Locale.getDefault())); }

Import Content Process

Page 42: L09 Process Design

Collecting the Entries public void processContent(Object content) { contentService.addContent((Content)content); }

Call-back Handler

Page 43: L09 Process Design

Running the Process public void afterProcess() { Collection<Content>col = contentService.getContents(); for (Content cnt: col) { System.out.println(cnt); } }

Page 44: L09 Process Design

Message Source

log.info(msg.getMessage("processstart", new Object[] { getProcessContext().getProcessName() }, Locale.getDefault()));

processbefore=The process {0} is starting (beforeProcess). processstart=Starting process {0} processstartdone=Reading done. Read {0} contents processreaderror=Unable to read file ''{0}''.

messages.properties

msg = (MessageSource)ctx.getBean("messageSource");

<bean id="messageSource“ class= "org.springframework.context.support.ResourceBundleMessageSource"> <property name="basename“><value>messages</value></property> </bean>

app.xml

startProcess in ImportContentProcess.java

beforeProcess in ImportContentProcess.java

Page 45: L09 Process Design

Using the ContentService

public void processContent(Content content) { contentService.addContent(content); }

public interface ContentService { public void addContent(Content content); public Collection<Content>getContents(); }

while (i.hasNext()) { ent = (SyndEntry)i.next(); content = new Content(); content.setTitle(ent.getTitle()); ... handler.processContent(content); }

read in RssReader.java

ImportContentProcess.java

ContentService.java

Page 46: L09 Process Design

Printing out values public void afterProcess() { Collection<Content>col = contentService.getContents(); for (Content cnt: col) { System.out.println(cnt); } }

INFO: The process ImportContentProcess is starting (beforeProcess). Sep 28, 2008 3:09:31 PM is.ru.honn.tube.process.ImportContentProcessstartProcess INFO: Starting process ImportContentProcess Sep 28, 2008 3:09:32 PM is.ru.honn.tube.process.ImportContentProcessstartProcess INFO: Reading done. Read 12 contents Japan's online social scene isn't so social (AP)

Unlocked iPhone 3G on sale in Hong Kong (AP)

Page 47: L09 Process Design

Run with IntelliJ

Page 48: L09 Process Design

Running the ProcessSep 13, 2015 1:14:45 PM org.springframework.context.support.FileSystemXmlApplicationContext prepareRefresh INFO: Refreshing org.springframework.context.support.FileSystemXmlApplicationContext@5ef04b5: startup date [Sun Sep 13 13:14:45 GMT 2015]; root of context hierarchy Sep 13, 2015 1:14:45 PM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions INFO: Loading XML bean definitions from file [/Users/Andri/Work/ImportContentProcess/process.xml] Sep 13, 2015 1:14:45 PM org.springframework.context.support.FileSystemXmlApplicationContext prepareRefresh INFO: Refreshing org.springframework.context.support.FileSystemXmlApplicationContext@31dc339b: startup date [Sun Sep 13 13:14:45 GMT 2015]; root of context hierarchy Sep 13, 2015 1:14:45 PM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions INFO: Loading XML bean definitions from class path resource [app.xml] Sep 13, 2015 1:14:45 PM is.ru.honn.tube.process.ImportContentProcess beforeProcess INFO: processbefore: ImportContentProcess Sep 13, 2015 1:14:45 PM is.ru.honn.tube.process.ImportContentProcess startProcess INFO: processstart: ImportContentProcess Prosecutors file charges against ex-CEO of Mt.Gox bitcoin exchange Sprint's plan for new iPhone trumps other U.S. carriers Obama says Chinese cyber practices are not acceptable, calls for faster U.S. response High-profile busts signal caution in start-up investing Court approves settlement over Curt Schilling's failed game studio What to look out for at the Frankfurt auto show Washington state fines a crowdfunding project for stiffing backers Go to the dark side of debt with this $28,500 'Star Wars' watch Self-destructing computer chip can protect top secret data iPhone 6s, 6s Plus Australian pricing Plex will bring its media streaming to Apple TV Professor says he's grateful feds dropped China secrets case

Page 49: L09 Process Design

Summary▪ Process Framework▪ Import Content Process