50
Lecture 11 Process Design

L11 Process Design

Embed Size (px)

DESCRIPTION

Ferli (processes) eru forrit sem keyra í enterprise kerfum til að framkvæma ákveðnar vinnslur. Þetta eru forrit sem sjá um vinnslur eins og innlestur (import), afstemmingar, eða daglegar uppfærslur og útreikninga. Þessi forrit hafa ekkert viðmót en sinna mikilvægu hlutverki. Í þessum fyrirlestri ætlum við að skoða hvernig hanna má Process Framework eða ramma fyrir ferli. Við kynnum Ru Process Framework sem er hluti af RuFramework og er dæmi um hvernig má skrifa ramma. Skoðað er nánar hvernig RU Process Framework er notað til að lesa RSS færslur. Einnig er litið á XML og leiðir til að lesa XML skjöl. Til eru tvær megin leiðir til að þátta XML skjöl og hvor hefur sína kosti og galla. RSS er dæmi um notkun á XML.

Citation preview

Page 1: L11 Process Design

Lecture 11Process Design

Page 2: L11 Process Design

Agenda Why Processes?

– Design Issues– Architecture Issues

RU Framework– RU Process Framework

Page 3: L11 Process Design

Reading RuFramework source code XML Processing XML (video) Build Scripts (video)

Java Technology and XML-Part One – http://java.sun.com/developer/

technicalArticles/xml/JavaTechandXML/

Page 4: L11 Process Design

Why Processes?

Page 5: L11 Process Design

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

for several reasons– Manual or automatic

Things in the “background”– Nightly update of customers– Reconciliation of systems

Lengthy operations– Recalculate of all accounts

Processes have no user interface– Traditionally know as “Jobs”

Page 6: L11 Process Design

Our Task We need to build a framework from

running processes. What patterns can we use?

Page 7: L11 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 8: L11 Process Design

RU Framework

Page 9: L11 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 10: L11 Process Design

Process Framework The idea is that the Process Framework

starts the process Process Developers must implement some

interface Information will be in a context XML file

Page 11: L11 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 12: L11 Process Design

Process Design Let’s implement this with

RuAbstractProcess– Processes can extend this classes – Template

Methodpackage 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 13: L11 Process Design

Process Design We needs some context,

RuProcessContext– Processes can get information about their

process from this contextpublic class RuProcessContext{ private String processName; private String processClass; private String importFile; private String importURL; private String dataSourceFile; private Map params;

...}

Page 14: L11 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 15: L11 Process Design

Process Design Change the RuAbstractProcess

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

Page 16: L11 Process Design

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 ...}

Page 17: L11 Process Design

Process Design Create a class to run the process,

RuProcessRunner– This class puts everything togetherpublic 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() { }}

Page 18: L11 Process Design

RU Process Framework Implementation

Page 19: L11 Process Design

Process Framework To create process, we must

– Create the process class that implements RuProcess

– Create the Process Context XML file

Page 20: L11 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 21: L11 Process Design

RuProcessContext Class for storing the Process Context

– The environment the process runs in– Attributes line process name, class, importURL,

data source

Page 22: L11 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 23: L11 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 24: L11 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 25: L11 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

Page 26: L11 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

Page 27: L11 Process Design

RuProcessFactory Factory that loads processes

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

Page 28: L11 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 29: L11 Process Design

RuProcessFactorypublic 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 30: L11 Process Design

RuProcessRunner Class that calls the factory and runs the

process– Name of Process Context file is parameter

Page 31: L11 Process Design

RuProcessRunner 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()); } }

Page 32: L11 Process Design

RuProcessRunner 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(); } }}

Page 33: L11 Process Design

Process Framework

Page 34: L11 Process Design

Process Framework

Data Transfer Object

Factory

Template Method

Plug-in

Layered Supertype

Dependency injection

Layered Supertype

Page 35: L11 Process Design

Import Content Process

Page 36: L11 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 37: L11 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 38: L11 Process Design

Import Content Process Process that reads contents from an URL Tasks

– The Process must “wire” all components together

Page 39: L11 Process Design

Import Content Process Process that reads contents from an URL Solution

– Create class ImportContentProcess that extends RuAbstractProcess

• beforeProcess• startProcess• afterProcess

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

components• Specified in app.xml

Page 40: L11 Process Design

Import Content Processpublic 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())); }

Page 41: L11 Process Design

Import Content ProcessApplicationContextctx = 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

Page 42: L11 Process Design

Import Content Process 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())); }

Page 43: L11 Process Design

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

Page 44: L11 Process Design

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

Page 45: L11 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} contentsprocessreaderror=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 46: L11 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 47: L11 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.ImportContentProcessstartProcessINFO: Starting process ImportContentProcessSep 28, 2008 3:09:32 PM is.ru.honn.tube.process.ImportContentProcessstartProcessINFO: Reading done. Read 12 contentsJapan's online social scene isn't so social (AP)

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

Page 48: L11 Process Design

Run with IntelliJ

Page 49: L11 Process Design

Running the ProcessINFO: Starting process ImportContentProcessSep 24, 2012 8:43:50 AM is.ru.honn.tube.process.ImportContentProcess startProcessINFO: Reading done. Read 40 contentsMany US stores report being sold out of iPhone 5sApple supplier halts China factory after violenceApple, Samsung demand changes to $1B verdictThis is Scary: Scientists find a way to erase frightening memoriesVerizon’s iPhone 5 being sold unlocked, allowing it to be used internationallyWhy Burberry Wants to Bring the Online Experience to Stores, and Not Vice VersaApple, Samsung demand changes to $1B verdictiPhone 5 launch draws Apple fans worldwideVerizon iPhone 5's secret feature: It's 'unlocked'Review: iPhone evolves into jewel-like '5'

Page 50: L11 Process Design

Summary Process Framework Import Content Process