├── .gitignore
├── README.md
└── spring-batch-scalability
├── etc
├── ffmq
│ └── conf
│ │ ├── ffmq-server.properties
│ │ ├── templates.mapping
│ │ └── templates
│ │ ├── queueTemplate-DEFAULT.properties
│ │ └── queueTemplate-TEMP.properties
└── jetty-env.xml
├── pom.xml
├── repo
├── javax
│ └── jms
│ │ └── jms
│ │ ├── 1.1
│ │ ├── jms-1.1.jar
│ │ ├── jms-1.1.jar.md5
│ │ ├── jms-1.1.jar.sha1
│ │ ├── jms-1.1.pom
│ │ ├── jms-1.1.pom.md5
│ │ └── jms-1.1.pom.sha1
│ │ ├── maven-metadata-local.xml
│ │ ├── maven-metadata-local.xml.md5
│ │ └── maven-metadata-local.xml.sha1
├── net
│ └── timewalker
│ │ └── ffmq
│ │ ├── ffmq3-core
│ │ ├── 3.0.5
│ │ │ ├── ffmq3-core-3.0.5.jar
│ │ │ ├── ffmq3-core-3.0.5.jar.md5
│ │ │ ├── ffmq3-core-3.0.5.jar.sha1
│ │ │ ├── ffmq3-core-3.0.5.pom
│ │ │ ├── ffmq3-core-3.0.5.pom.md5
│ │ │ └── ffmq3-core-3.0.5.pom.sha1
│ │ ├── maven-metadata-local.xml
│ │ ├── maven-metadata-local.xml.md5
│ │ └── maven-metadata-local.xml.sha1
│ │ ├── ffmq3-server
│ │ ├── 3.0.5
│ │ │ ├── ffmq3-server-3.0.5.jar
│ │ │ ├── ffmq3-server-3.0.5.jar.md5
│ │ │ ├── ffmq3-server-3.0.5.jar.sha1
│ │ │ ├── ffmq3-server-3.0.5.pom
│ │ │ ├── ffmq3-server-3.0.5.pom.md5
│ │ │ └── ffmq3-server-3.0.5.pom.sha1
│ │ ├── maven-metadata-local.xml
│ │ ├── maven-metadata-local.xml.md5
│ │ └── maven-metadata-local.xml.sha1
│ │ └── ffmq3
│ │ ├── 3.0.5
│ │ ├── ffmq3-3.0.5.pom
│ │ ├── ffmq3-3.0.5.pom.md5
│ │ └── ffmq3-3.0.5.pom.sha1
│ │ ├── maven-metadata-local.xml
│ │ ├── maven-metadata-local.xml.md5
│ │ └── maven-metadata-local.xml.sha1
└── uk
│ └── ac
│ └── shef
│ └── wit
│ └── simmetrics
│ ├── 1.6.2
│ ├── simmetrics-1.6.2.jar
│ ├── simmetrics-1.6.2.jar.md5
│ ├── simmetrics-1.6.2.jar.sha1
│ ├── simmetrics-1.6.2.pom
│ ├── simmetrics-1.6.2.pom.md5
│ └── simmetrics-1.6.2.pom.sha1
│ ├── maven-metadata.xml
│ ├── maven-metadata.xml.md5
│ └── maven-metadata.xml.sha1
└── src
├── main
├── java
│ └── com
│ │ └── ontheserverside
│ │ └── batch
│ │ └── bank
│ │ ├── controller
│ │ └── RootController.java
│ │ ├── processing
│ │ ├── Elixir0Mapper.java
│ │ ├── JobParameterExecutionDecider.java
│ │ ├── ModuloPartitioner.java
│ │ └── SynchronizedItemReaderDecorator.java
│ │ ├── screening
│ │ ├── FuzzyMatcher.java
│ │ ├── JaroBagFuzzyMatcher.java
│ │ ├── SDNEntity.java
│ │ ├── SanctionMatch.java
│ │ ├── SanctionScreeningContext.java
│ │ ├── SanctionScreeningProcessor.java
│ │ ├── SanctionScreeningRecoveryCleaner.java
│ │ └── UpdateScreenedTransactionStatusTasklet.java
│ │ └── tx
│ │ ├── Elixir0Generator.java
│ │ ├── Elixir0Transaction.java
│ │ ├── SimpleElixir0Generator.java
│ │ └── TransactionStatus.java
├── resources
│ ├── META-INF
│ │ ├── database
│ │ │ ├── init.sql
│ │ │ ├── sdn_addresses.csv
│ │ │ ├── sdn_alternate_names.csv
│ │ │ └── sdn_names.csv
│ │ └── spring
│ │ │ ├── applicationContext.xml
│ │ │ ├── batchContext.xml
│ │ │ ├── elixir0ImportJob.xml
│ │ │ ├── hibernateContext.xml
│ │ │ └── jmsContext.xml
│ ├── addresses.txt
│ ├── dictionary.txt
│ ├── log4j.properties
│ └── names.txt
└── webapp
│ └── WEB-INF
│ ├── spring
│ └── webmvc-config.xml
│ ├── views
│ └── home.jsp
│ └── web.xml
└── test
├── java
└── com
│ └── ontheserverside
│ └── batch
│ └── bank
│ ├── job
│ └── Elixir0LoadStepTest.java
│ ├── processing
│ ├── JobParameterExecutionDeciderTest.java
│ └── ModuloPartitionerTest.java
│ └── screening
│ ├── JaroBagFuzzyMatcherTest.java
│ └── SanctionScreeningProcessorTest.java
└── resources
└── elixir0
└── 5Tx.elixir0
/.gitignore:
--------------------------------------------------------------------------------
1 | target/
2 |
3 | #IntelliJ files
4 | .idea
5 | .DS_store
6 | *.iml
7 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Spring Batch scaling strategies - sample application
2 | ===
3 | http://www.ontheserverside.com/blog/2014/07/23/horizontal-and-vertical-scaling-strategies-for-batch-applications/
4 |
5 | This is sample application developed for ["Horizontal and Vertical Scaling Strategies for Batch Applications"](http://www.ontheserverside.com/blog/2014/07/23/horizontal-and-vertical-scaling-strategies-for-batch-applications/) article.
6 |
7 | Application is responsible for processing Elixir0 messages. Elixir0 is a country-domestic Polish bank message format that represents standard credit transfer transactions. All payments contained by Elixir0 are screened against OFAC's Specially Designated Nationals List. Screening algorithm performs fuzzy matching of beneficiary and ordering party name, address and alternate name against every SDN entity. If algorithm detects that sanctions might be imposed on ordering or receiving party, placement of the particular transaction is suspended and waits for manual approval.
8 |
9 | Please bear in mind that the implementation of payment sanction screening mechanism used here is not the most optimal and performant algorithm for this task. Also, it should not be considered as a complete solution.
10 |
11 | ## How to run
12 |
13 | Application is using Maven as a dependency management system, so all required libraries should be downloaded automatically. FFMQ is used as a JMS broker, Jetty is used as a web container and H2 running in in-memory mode is used as a database. All these services are configured automatically and no action from user is required to set them up.
14 |
15 | ```
16 | $ git clone git@github.com:pdyraga/spring-batch-samples.git
17 | $ cd spring-batch-samples/spring-batch-scalability/
18 | $ mvn clean jetty:run
19 | ```
20 |
21 |
22 | ## How to use
23 |
24 | Go to [http://localhost:8080](http://localhost:8080) and generate sample Elixir0 message first. To do so, please enter number of transactions that the generated file should contain (e.g. `500`) and desired location of the output file (e.g. `/tmp/elixir0.500`). Next, please click on `Generate` and wait for Elixir0 file to be created. When file generation process is complete, you should see `Elixir0 message created` information. Also, input file path is automatically filled with location of file that has just been created. In the menu drop down next to the input file location you can choose scaling strategy that should be used for performing payment sanctions screening. After choosing some scaling strategy, please click on `Run job` button and the import process should start immediately:
25 |
26 | 
27 |
28 | You can access database web interface by going to [http://localhost:8082](http://localhost:8082). The username is `sa` and password is `sa`. The most important job outcome is list of transactions that have been suspended together with sanctions matched for particular transaction. You can observe this list by querying the `SANCTION_PREVIEW` view: `SELECT * FROM SANCTION_PREVIEW `. Each row in this view represents suspended transaction. View displays all data from Elixir0 transactions that were analysed by fuzzy string matching algorithm, that is, beneficiary name, beneficiary address, ordering party name and ordering party address. Columns starting with `SDN_` prefix are data from entity on the OFAC's SDN list that could be potentially involved in the particular transaction. For instance, the first row represents transaction that has been suspended because the beneficiary name (`MOLDTRANSAVIA SRL`) is matching SDN entity with the same name.
29 |
30 | Please visit the article for more information: http://www.ontheserverside.com/blog/2014/07/23/horizontal-and-vertical-scaling-strategies-for-batch-applications/
31 |
32 | 
33 |
--------------------------------------------------------------------------------
/spring-batch-scalability/etc/ffmq/conf/ffmq-server.properties:
--------------------------------------------------------------------------------
1 | #---------------------------------------------------------------#
2 | # FFMQ Server settings #
3 | #---------------------------------------------------------------#
4 |
5 | #--------------------------------#
6 | # Management #
7 | #--------------------------------#
8 |
9 | # Destination definitions folder
10 | #--------------------------------
11 | # - Folder where to store/lookup destinations XML descriptors (can be relative)
12 | management.destinationDefinitions.directory=${FFMQ_WORKING_DIR}/destinations
13 |
14 | # Bridge definitions folder
15 | #--------------------------------
16 | # - Folder where to look for bridge definitions XML descriptors (can be relative)
17 | #management.bridgeDefinitions.directory=${FFMQ_BASE}/bridges
18 |
19 | # Templates folder
20 | #------------------
21 | # - Folder where to look for templates descriptors (can be relative)
22 | management.templates.directory=${FFMQ_BASE}/conf/templates
23 |
24 | # Templates mapping file
25 | #------------------------
26 | # - Path to the templates mapping file (can be relative)
27 | management.templates.mapping=${FFMQ_BASE}/conf/templates.mapping
28 |
29 | # Queues auto-creation
30 | #----------------------
31 | # - true : accessing an unknown queue will auto-create it if a corresponding
32 | # mapping exist in the templates mapping file
33 | # - false : accessing an unknown queue will throw a JMSException
34 | management.autoCreate.queues=true
35 |
36 | # Topics auto-creation
37 | #----------------------
38 | # - true : accessing an unknown topic will auto-create it if a corresponding
39 | # mapping exist in the templates mapping file
40 | # - false : accessing an unknown topic will throw a JMSException
41 | management.autoCreate.topics=true
42 |
43 | # Queues auto-deployment on startup
44 | #-----------------------------------
45 | # - true : the server will try to deploy all existing queues on startup
46 | # - false : queues are only deployed on first use
47 | management.deployOnStartup.queues=true
48 |
49 | # Topics auto-deployment on startup
50 | #-----------------------------------
51 | # - true : the server will try to deploy all existing topics on startup
52 | # - false : topics are only deployed on first use
53 | management.deployOnStartup.topics=true
54 |
55 | # Remote administration
56 | #-----------------------
57 | # - true : allows remote administration of the server through admin queues
58 | # (this is usually done through the ffmq-admin-client utility)
59 | # - false : disable the remote administration feature
60 | management.remoteAdmin.enabled=true
61 |
62 | # Default data directory
63 | #------------------------
64 | # - Folder to use as a data folder for destinations created through remote administration (can be relative)
65 | management.defaultData.directory=${FFMQ_WORKING_DIR}/data
66 |
67 | # JMX support
68 | #-------------
69 | # - true : start a JMX agent on server startup
70 | # - false : disable the JMX agent
71 | management.jmx.agent.enabled=true
72 | # RMI port to use for the agent registry
73 | management.jmx.agent.jndi.rmi.port=10003
74 | # RMI address to use for the agent registry (supports address auto-discovery using 'auto:eth0' for example)
75 | management.jmx.agent.rmi.listenAddr=0.0.0.0
76 |
77 | #--------------------------------#
78 | # Listeners #
79 | #--------------------------------#
80 | # Note : right now, there is only one available listener
81 | # using TCP sockets
82 |
83 | # General
84 | #--------
85 | # Time to wait for credentials before dropping the client (in seconds)
86 | listener.auth.timeout=5
87 |
88 | # TCP listener
89 | #--------------
90 | # - If enabled, the TCP listener will start on server startup
91 | # - You can set the listen address,port and backlog for the listen socket
92 | # (supports address auto-discovery using 'auto:eth0' for example)
93 | listener.tcp.enabled=true
94 | listener.tcp.useNIO=false
95 | listener.tcp.listenAddr=0.0.0.0
96 | listener.tcp.listenPort=10002
97 | listener.tcp.backLog=50
98 | listener.tcp.capacity=200
99 |
100 | # TCP transport settings
101 | #------------------------
102 | transport.tcp.pingInterval=30
103 | transport.tcp.sendQueueMaxSize=1000
104 | transport.tcp.packet.maxSize=1049600
105 | transport.tcp.stream.sendBufferSize=8192
106 | transport.tcp.stream.recvBufferSize=8192
107 | transport.tcp.initialPacketBufferSize=4096
108 | transport.tcp.socket.sendBufferSize=65536
109 | transport.tcp.socket.recvBufferSize=65536
110 | # SSL support (server-side)
111 | transport.tcp.ssl.enabled=false
112 | transport.tcp.ssl.protocol=SSLv3
113 | transport.tcp.ssl.keyManager.algorithm=SunX509
114 | transport.tcp.ssl.keyStore.type=JKS
115 | transport.tcp.ssl.keyStore.path=${FFMQ_BASE}/conf/server-keystore.jks
116 | transport.tcp.ssl.keyStore.password=ffmqpass
117 | transport.tcp.ssl.keyStore.keyPassword=ffmqpass
118 |
119 | #--------------------------------#
120 | # Security #
121 | #--------------------------------#
122 |
123 | # Global security switch
124 | #------------------------
125 | # - true : enable security checks (you also need to have a valid connector and configuration)
126 | # - false : disable security globally
127 | security.enabled=false
128 |
129 | # Security connector implementation
130 | #-----------------------------------
131 | # - Fully qualified class name of the security connector to use
132 | # Note : right now, there is only one available connector implementation
133 | # using an XML descriptor (net.timewalker.ffmq3.security.XMLSecurityConnector)
134 | security.connector=net.timewalker.ffmq3.security.XMLSecurityConnector
135 |
136 | # XML Security connector configuration file
137 | #-------------------------------------------
138 | # - Path to the XML configuration file for the XML security connector
139 | security.connector.xml.securityFile=${FFMQ_BASE}/conf/security.xml
140 |
141 | #--------------------------------#
142 | # Internal tuning #
143 | #--------------------------------#
144 |
145 | # Asynchronous task manager - Delivery
146 | # - Pool min size (ie. how many threads to create on startup)
147 | asyncTaskManager.notification.threadPool.minSize=5
148 | # - Pool max idle (ie. how many unused threads to keep ready in the pool)
149 | asyncTaskManager.notification.threadPool.maxIdle=10
150 | # - Pool max size (ie. how many threads should we allocate at most)
151 | asyncTaskManager.notification.threadPool.maxSize=15
152 |
153 | # Asynchronous task manager - Delivery
154 | # - Pool min size (ie. how many threads to create on startup)
155 | asyncTaskManager.delivery.threadPool.minSize=0
156 | # - Pool max idle (ie. how many unused threads to keep ready in the pool)
157 | asyncTaskManager.delivery.threadPool.maxIdle=5
158 | # - Pool max size (ie. how many threads should we allocate at most)
159 | asyncTaskManager.delivery.threadPool.maxSize=10
160 |
161 | # Asynchronous task manager - Disk I/O
162 | # - Pool min size (ie. how many threads to create on startup)
163 | asyncTaskManager.diskIO.threadPool.minSize=1
164 | # - Pool max idle (ie. how many unused threads to keep ready in the pool)
165 | asyncTaskManager.diskIO.threadPool.maxIdle=2
166 | # - Pool max size (ie. how many threads should we allocate at most)
167 | asyncTaskManager.diskIO.threadPool.maxSize=4
168 |
169 | # Consumer message prefetching
170 | consumer.prefetch.size=10
171 |
172 | # Redelivery delay (in milliseconds)
173 | # - If positive, delay message availability in queue after a rollback
174 | delivery.redeliveryDelay=0
175 |
176 |
177 | #--------------------------------#
178 | # Logging #
179 | #--------------------------------#
180 |
181 | # Loggers definitions
182 | log4j.logger.net.timewalker.ffmq3=INFO,logFile
183 | log4j.additivity.net.timewalker.ffmq3=false
184 |
185 | # JMX logging
186 | log4j.logger.javax.management=INFO,logFile
187 | log4j.additivity.javax.management=false
188 |
189 | # Appenders definitions
190 | log4j.appender.console=org.apache.log4j.ConsoleAppender
191 | log4j.appender.console.layout=org.apache.log4j.PatternLayout
192 | log4j.appender.console.layout.ConversionPattern=[%5p] %m%n
193 |
--------------------------------------------------------------------------------
/spring-batch-scalability/etc/ffmq/conf/templates.mapping:
--------------------------------------------------------------------------------
1 | queue:TEMP-QUEUE-*:TEMP_QUEUE_TEMPLATE
2 | queue:*:DEFAULT_QUEUE_TEMPLATE
3 |
--------------------------------------------------------------------------------
/spring-batch-scalability/etc/ffmq/conf/templates/queueTemplate-DEFAULT.properties:
--------------------------------------------------------------------------------
1 | #
2 | # This is the default template for queues
3 | #
4 | name = DEFAULT_QUEUE_TEMPLATE
5 |
6 | persistentStore.initialBlockCount = 1000
7 | persistentStore.autoExtendAmount = 1000
8 | persistentStore.maxBlockCount = 10000
9 | persistentStore.blockSize = 4096
10 | persistentStore.dataFolder = ${FFMQ_WORKING_DIR}/data
11 | persistentStore.useJournal = true
12 | persistentStore.syncMethod = 2
13 |
14 | persistentStore.journal.preAllocateFiles=false
15 |
16 | memoryStore.maxMessages = 1000
17 | memoryStore.overflowToPersistent = false
18 |
--------------------------------------------------------------------------------
/spring-batch-scalability/etc/ffmq/conf/templates/queueTemplate-TEMP.properties:
--------------------------------------------------------------------------------
1 | #
2 | # This is the default template for temporary queues
3 | #
4 | name = TEMP_QUEUE_TEMPLATE
5 |
6 | persistentStore.initialBlockCount = 100
7 | persistentStore.autoExtendAmount = 100
8 | persistentStore.maxBlockCount = 1000
9 | persistentStore.blockSize = 4096
10 | persistentStore.dataFolder = ${FFMQ_WORKING_DIR}/data
11 | persistentStore.useJournal = false
12 |
13 | memoryStore.maxMessages = 1000
14 |
--------------------------------------------------------------------------------
/spring-batch-scalability/etc/jetty-env.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | jdbc/DS
6 |
7 |
8 | jdbc:h2:mem:bank;DB_CLOSE_DELAY=-1
9 | sa
10 | sa
11 |
12 |
13 |
14 |
15 | ffmq
16 | etc/ffmq/conf/ffmq-server.properties
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/spring-batch-scalability/pom.xml:
--------------------------------------------------------------------------------
1 |
5 | 4.0.0
6 |
7 | com.ontheserverside.batch
8 | spring-batch-scalability
9 | 1.0
10 | war
11 |
12 | Spring Batch scalability samples
13 |
14 |
15 | 1.7
16 | 1.7
17 | UTF-8
18 |
19 | 4.0.0.RELEASE
20 | 2.2.3.RELEASE
21 | 1.3.0.M1
22 | 3.0.1.RELEASE
23 | 4.3.0.Final
24 | 9.1.1.v20140108
25 | 1.3.175
26 | 3.0.5
27 |
28 | etc/ffmq
29 | target/ffmq-data
30 |
31 |
32 |
33 |
34 |
35 | org.apache.maven.plugins
36 | maven-antrun-plugin
37 |
38 |
39 | setUpFFMQDataDirectories
40 | generate-sources
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 | run
50 |
51 |
52 |
53 |
54 |
55 | org.eclipse.jetty
56 | jetty-maven-plugin
57 | ${org.eclipse.jetty.version}
58 |
59 |
60 |
61 | FFMQ_BASE
62 | ${net.timewalker.ffmq.dir.config}
63 |
64 |
65 | FFMQ_WORKING_DIR
66 | ${net.timewalker.ffmq.dir.working}
67 |
68 |
69 |
70 | etc/jetty-env.xml
71 |
72 |
73 |
74 |
75 | com.h2database
76 | h2
77 | ${com.h2database.version}
78 |
79 |
80 | net.timewalker.ffmq
81 | ffmq3-server
82 | ${net.timewalker.ffmq.version}
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 | org.springframework
92 | spring-context
93 | ${org.springframework.version}
94 |
95 |
96 | org.springframework.batch
97 | spring-batch-core
98 | ${org.springframework.batch.version}
99 |
100 |
101 | org.springframework.batch
102 | spring-batch-integration
103 | ${org.springframework.batch.integration.version}
104 |
105 |
106 | org.springframework.integration
107 | spring-integration-core
108 |
109 |
110 |
111 |
112 | org.springframework.integration
113 | spring-integration-jms
114 | ${org.springframework.integration.version}
115 |
116 |
117 | org.springframework
118 | spring-orm
119 | ${org.springframework.version}
120 |
121 |
122 | org.springframework
123 | spring-webmvc
124 | ${org.springframework.version}
125 |
126 |
127 | org.hibernate
128 | hibernate-core
129 | ${org.hibernate.version}
130 |
131 |
132 | org.apache.commons
133 | commons-lang3
134 | 3.1
135 |
136 |
137 | uk.ac.shef.wit
138 | simmetrics
139 | 1.6.2
140 |
141 |
142 | net.timewalker.ffmq
143 | ffmq3-core
144 | ${net.timewalker.ffmq.version}
145 |
146 |
147 |
148 |
149 | junit
150 | junit
151 | 4.11
152 | test
153 |
154 |
155 | org.easymock
156 | easymock
157 | 3.2
158 | test
159 |
160 |
161 | org.springframework
162 | spring-test
163 | ${org.springframework.version}
164 | test
165 |
166 |
167 | org.springframework.batch
168 | spring-batch-test
169 | ${org.springframework.batch.version}
170 | test
171 |
172 |
173 | com.h2database
174 | h2
175 | ${com.h2database.version}
176 | test
177 |
178 |
179 |
180 |
181 |
182 | project.local
183 | project
184 | file:${project.basedir}/repo
185 |
186 |
187 | spring.release
188 | spring release
189 | http://maven.springframework.org/release/
190 |
191 |
192 |
193 |
194 |
195 |
196 | never
197 |
198 |
199 | false
200 |
201 | project.local
202 | project
203 | file:${project.basedir}/repo
204 |
205 |
206 |
207 |
208 |
--------------------------------------------------------------------------------
/spring-batch-scalability/repo/javax/jms/jms/1.1/jms-1.1.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pdyraga/spring-batch-samples/2cbe2caf03954a2899cc8d0bab079e292df39cb9/spring-batch-scalability/repo/javax/jms/jms/1.1/jms-1.1.jar
--------------------------------------------------------------------------------
/spring-batch-scalability/repo/javax/jms/jms/1.1/jms-1.1.jar.md5:
--------------------------------------------------------------------------------
1 | ad558b2376ce94b91bb72d67b30a4f05
--------------------------------------------------------------------------------
/spring-batch-scalability/repo/javax/jms/jms/1.1/jms-1.1.jar.sha1:
--------------------------------------------------------------------------------
1 | 5e106d07e523fb6d40cf086b9b413268f6302f26
--------------------------------------------------------------------------------
/spring-batch-scalability/repo/javax/jms/jms/1.1/jms-1.1.pom:
--------------------------------------------------------------------------------
1 |
2 | 4.0.0
3 | javax.jms
4 | jms
5 | 1.1
6 | Java Message Service
7 |
8 | The Java Message Service (JMS) API is a messaging standard that allows application components based on the Java 2 Platform, Enterprise Edition (J2EE) to create, send, receive, and read messages. It enables distributed communication that is loosely coupled, reliable, and asynchronous.
9 |
10 | http://java.sun.com/products/jms
11 |
12 | http://java.sun.com/products/jms/docs.html
13 |
14 |
--------------------------------------------------------------------------------
/spring-batch-scalability/repo/javax/jms/jms/1.1/jms-1.1.pom.md5:
--------------------------------------------------------------------------------
1 | 479233e944488d328423f24e67626b85
--------------------------------------------------------------------------------
/spring-batch-scalability/repo/javax/jms/jms/1.1/jms-1.1.pom.sha1:
--------------------------------------------------------------------------------
1 | 27a2e84f6118a2bbd0266edd9d53870528473f92
--------------------------------------------------------------------------------
/spring-batch-scalability/repo/javax/jms/jms/maven-metadata-local.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | javax.jms
4 | jms
5 |
6 | 1.1
7 |
8 | 1.1
9 |
10 | 20140309121905
11 |
12 |
13 |
--------------------------------------------------------------------------------
/spring-batch-scalability/repo/javax/jms/jms/maven-metadata-local.xml.md5:
--------------------------------------------------------------------------------
1 | 81a55a5edb7c5df00d0bf9b1b5322b3f
--------------------------------------------------------------------------------
/spring-batch-scalability/repo/javax/jms/jms/maven-metadata-local.xml.sha1:
--------------------------------------------------------------------------------
1 | 253655e6932da154607206f38f7325403b169d02
--------------------------------------------------------------------------------
/spring-batch-scalability/repo/net/timewalker/ffmq/ffmq3-core/3.0.5/ffmq3-core-3.0.5.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pdyraga/spring-batch-samples/2cbe2caf03954a2899cc8d0bab079e292df39cb9/spring-batch-scalability/repo/net/timewalker/ffmq/ffmq3-core/3.0.5/ffmq3-core-3.0.5.jar
--------------------------------------------------------------------------------
/spring-batch-scalability/repo/net/timewalker/ffmq/ffmq3-core/3.0.5/ffmq3-core-3.0.5.jar.md5:
--------------------------------------------------------------------------------
1 | d19d3b2789b7d5ae2c381aafa6b188fc
--------------------------------------------------------------------------------
/spring-batch-scalability/repo/net/timewalker/ffmq/ffmq3-core/3.0.5/ffmq3-core-3.0.5.jar.sha1:
--------------------------------------------------------------------------------
1 | 80c26745470ff9e962b7209c48ea6fe43f467861
--------------------------------------------------------------------------------
/spring-batch-scalability/repo/net/timewalker/ffmq/ffmq3-core/3.0.5/ffmq3-core-3.0.5.pom:
--------------------------------------------------------------------------------
1 |
4 | 4.0.0
5 | net.timewalker.ffmq
6 | ffmq3-core
7 | jar
8 | 3.0.5
9 | FFMQ Core
10 | FFMQ Core module
11 |
12 |
13 | net.timewalker.ffmq
14 | ffmq3
15 | 3.0.5
16 |
17 |
18 |
19 |
20 |
21 | src/main/resources
22 | true
23 |
24 |
25 |
26 |
27 |
28 | org.apache.maven.plugins
29 | maven-compiler-plugin
30 |
31 | 1.4
32 | 1.4
33 |
34 |
35 |
36 | org.apache.maven.plugins
37 | maven-surefire-plugin
38 |
39 | true
40 |
41 |
42 |
43 | org.apache.maven.plugins
44 | maven-eclipse-plugin
45 |
46 |
47 | temp/classes
48 |
49 |
50 |
51 |
52 | org.apache.maven.plugins
53 | maven-jar-plugin
54 |
55 |
56 |
57 |
58 | ${pom.name}
59 |
60 |
61 | ${pom.version}
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
80 |
81 |
82 |
83 | commons-logging
84 | commons-logging
85 | compile
86 |
87 |
88 | avalon-framework
89 | avalon-framework
90 |
91 |
92 | javax.servlet
93 | servlet-api
94 |
95 |
96 | logkit
97 | logkit
98 |
99 |
100 |
101 |
102 | log4j
103 | log4j
104 | compile
105 |
106 |
107 | com.sun.jdmk
108 | jmxtools
109 |
110 |
111 | com.sun.jmx
112 | jmxri
113 |
114 |
115 | javax.activation
116 | activation
117 |
118 |
119 | javax.mail
120 | mail
121 |
122 |
123 |
124 |
125 | javax.jms
126 | jms
127 | compile
128 |
129 |
130 | mx4j
131 | mx4j
132 | compile
133 |
134 |
135 | mx4j
136 | mx4j-remote
137 | compile
138 |
139 |
140 | junit
141 | junit
142 | test
143 |
144 |
145 |
146 |
147 |
--------------------------------------------------------------------------------
/spring-batch-scalability/repo/net/timewalker/ffmq/ffmq3-core/3.0.5/ffmq3-core-3.0.5.pom.md5:
--------------------------------------------------------------------------------
1 | 8c0c56f799f27df3bd955cb25824d0ec
--------------------------------------------------------------------------------
/spring-batch-scalability/repo/net/timewalker/ffmq/ffmq3-core/3.0.5/ffmq3-core-3.0.5.pom.sha1:
--------------------------------------------------------------------------------
1 | 91d60bd6dcd7a081b96c0d11c289fb95d0b19ce4
--------------------------------------------------------------------------------
/spring-batch-scalability/repo/net/timewalker/ffmq/ffmq3-core/maven-metadata-local.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | net.timewalker.ffmq3
4 | ffmq3-core
5 |
6 | 3.0.5
7 |
8 | 3.0.5
9 |
10 | 20140309122341
11 |
12 |
13 |
--------------------------------------------------------------------------------
/spring-batch-scalability/repo/net/timewalker/ffmq/ffmq3-core/maven-metadata-local.xml.md5:
--------------------------------------------------------------------------------
1 | c48dd932ffd057ea047b74c0fd5be7f4
--------------------------------------------------------------------------------
/spring-batch-scalability/repo/net/timewalker/ffmq/ffmq3-core/maven-metadata-local.xml.sha1:
--------------------------------------------------------------------------------
1 | b40e215c5e0906000d73d36dee383215613eb05a
--------------------------------------------------------------------------------
/spring-batch-scalability/repo/net/timewalker/ffmq/ffmq3-server/3.0.5/ffmq3-server-3.0.5.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pdyraga/spring-batch-samples/2cbe2caf03954a2899cc8d0bab079e292df39cb9/spring-batch-scalability/repo/net/timewalker/ffmq/ffmq3-server/3.0.5/ffmq3-server-3.0.5.jar
--------------------------------------------------------------------------------
/spring-batch-scalability/repo/net/timewalker/ffmq/ffmq3-server/3.0.5/ffmq3-server-3.0.5.jar.md5:
--------------------------------------------------------------------------------
1 | 45edca610e4c16300091326f224ae8b0
--------------------------------------------------------------------------------
/spring-batch-scalability/repo/net/timewalker/ffmq/ffmq3-server/3.0.5/ffmq3-server-3.0.5.jar.sha1:
--------------------------------------------------------------------------------
1 | 24eef0822f877290e3626c3d27ccd78ce21a5a1a
--------------------------------------------------------------------------------
/spring-batch-scalability/repo/net/timewalker/ffmq/ffmq3-server/3.0.5/ffmq3-server-3.0.5.pom:
--------------------------------------------------------------------------------
1 |
4 | 4.0.0
5 | net.timewalker.ffmq
6 | ffmq3-server
7 | jar
8 | 3.0.5
9 | FFMQ Server
10 | FFMQ Server module
11 |
12 |
13 | net.timewalker.ffmq
14 | ffmq3
15 | 3.0.5
16 |
17 |
18 |
19 |
20 |
21 | org.apache.maven.plugins
22 | maven-compiler-plugin
23 |
24 | 1.4
25 | 1.4
26 |
27 |
28 |
29 | org.apache.maven.plugins
30 | maven-surefire-plugin
31 |
32 | true
33 | runtime/bin
34 |
35 |
36 |
37 | org.apache.maven.plugins
38 | maven-eclipse-plugin
39 |
40 |
41 | temp/classes
42 |
43 |
44 |
45 |
46 | org.apache.maven.plugins
47 | maven-jar-plugin
48 |
49 |
50 |
51 | ${pom.name}
52 | ${pom.version}
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 | net.timewalker.ffmq
63 | ffmq3-core
64 | 3.0.5
65 |
66 |
67 | junit
68 | junit
69 | test
70 |
71 |
72 |
73 |
--------------------------------------------------------------------------------
/spring-batch-scalability/repo/net/timewalker/ffmq/ffmq3-server/3.0.5/ffmq3-server-3.0.5.pom.md5:
--------------------------------------------------------------------------------
1 | 54e9e7218e0829fa2e60758eb64b4dae
--------------------------------------------------------------------------------
/spring-batch-scalability/repo/net/timewalker/ffmq/ffmq3-server/3.0.5/ffmq3-server-3.0.5.pom.sha1:
--------------------------------------------------------------------------------
1 | c38295dea9985bfd1668d55ebf42d6e6f011f000
--------------------------------------------------------------------------------
/spring-batch-scalability/repo/net/timewalker/ffmq/ffmq3-server/maven-metadata-local.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | net.timewalker.ffmq3
4 | ffmq3-server
5 |
6 | 3.0.5
7 |
8 | 3.0.5
9 |
10 | 20140309122632
11 |
12 |
13 |
--------------------------------------------------------------------------------
/spring-batch-scalability/repo/net/timewalker/ffmq/ffmq3-server/maven-metadata-local.xml.md5:
--------------------------------------------------------------------------------
1 | daa060829c8434551ef657a35ac50461
--------------------------------------------------------------------------------
/spring-batch-scalability/repo/net/timewalker/ffmq/ffmq3-server/maven-metadata-local.xml.sha1:
--------------------------------------------------------------------------------
1 | 0eea2a8edd6a29ca0dda02c81e70f0bf3f1ae8ca
--------------------------------------------------------------------------------
/spring-batch-scalability/repo/net/timewalker/ffmq/ffmq3/3.0.5/ffmq3-3.0.5.pom:
--------------------------------------------------------------------------------
1 |
3 | 4.0.0
4 | net.timewalker.ffmq
5 | ffmq3
6 | pom
7 | 3.0.5
8 | FFMQ
9 | http://www.timewalker.net/ffmq
10 |
11 |
12 | core
13 | server
14 | tools
15 | distribution
16 |
17 |
18 |
19 |
20 |
21 | commons-logging
22 | commons-logging
23 | 1.1
24 |
25 |
26 | log4j
27 | log4j
28 | 1.2.15
29 |
30 |
31 | javax.jms
32 | jms
33 | 1.1
34 |
35 |
36 | mx4j
37 | mx4j
38 | 3.0.2
39 |
40 |
41 | mx4j
42 | mx4j-remote
43 | 3.0.2
44 |
45 |
46 | junit
47 | junit
48 | 3.8.1
49 |
50 |
51 |
52 |
53 |
54 |
--------------------------------------------------------------------------------
/spring-batch-scalability/repo/net/timewalker/ffmq/ffmq3/3.0.5/ffmq3-3.0.5.pom.md5:
--------------------------------------------------------------------------------
1 | 9db0dc1eb566063e51f9629dc17b8043
--------------------------------------------------------------------------------
/spring-batch-scalability/repo/net/timewalker/ffmq/ffmq3/3.0.5/ffmq3-3.0.5.pom.sha1:
--------------------------------------------------------------------------------
1 | 995bfc4e1701662f4b6060877353ae8318748b5b
--------------------------------------------------------------------------------
/spring-batch-scalability/repo/net/timewalker/ffmq/ffmq3/maven-metadata-local.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | net.timewalker.ffmq3
4 | ffmq3
5 |
6 | 3.0.5
7 |
8 | 3.0.5
9 |
10 | 20140309122205
11 |
12 |
13 |
--------------------------------------------------------------------------------
/spring-batch-scalability/repo/net/timewalker/ffmq/ffmq3/maven-metadata-local.xml.md5:
--------------------------------------------------------------------------------
1 | 20651b001a9e6a0d77d6ff4535b6a030
--------------------------------------------------------------------------------
/spring-batch-scalability/repo/net/timewalker/ffmq/ffmq3/maven-metadata-local.xml.sha1:
--------------------------------------------------------------------------------
1 | 329e36919c1f99e09c86b040cf35e59106f916c1
--------------------------------------------------------------------------------
/spring-batch-scalability/repo/uk/ac/shef/wit/simmetrics/1.6.2/simmetrics-1.6.2.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pdyraga/spring-batch-samples/2cbe2caf03954a2899cc8d0bab079e292df39cb9/spring-batch-scalability/repo/uk/ac/shef/wit/simmetrics/1.6.2/simmetrics-1.6.2.jar
--------------------------------------------------------------------------------
/spring-batch-scalability/repo/uk/ac/shef/wit/simmetrics/1.6.2/simmetrics-1.6.2.jar.md5:
--------------------------------------------------------------------------------
1 | d730f0b5e5b0b18a2931227b8d3e3820
--------------------------------------------------------------------------------
/spring-batch-scalability/repo/uk/ac/shef/wit/simmetrics/1.6.2/simmetrics-1.6.2.jar.sha1:
--------------------------------------------------------------------------------
1 | 546cfaf6de50dbdd53b35735567f456c37036113
--------------------------------------------------------------------------------
/spring-batch-scalability/repo/uk/ac/shef/wit/simmetrics/1.6.2/simmetrics-1.6.2.pom:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 | uk.ac.shef.wit
6 | simmetrics
7 | 1.6.2
8 |
9 |
--------------------------------------------------------------------------------
/spring-batch-scalability/repo/uk/ac/shef/wit/simmetrics/1.6.2/simmetrics-1.6.2.pom.md5:
--------------------------------------------------------------------------------
1 | e66c9ab9437bb1ec06d1c5ff0612e50f
--------------------------------------------------------------------------------
/spring-batch-scalability/repo/uk/ac/shef/wit/simmetrics/1.6.2/simmetrics-1.6.2.pom.sha1:
--------------------------------------------------------------------------------
1 | 59c77aed22cfd8395ddf3becff9feb7a187b4f17
--------------------------------------------------------------------------------
/spring-batch-scalability/repo/uk/ac/shef/wit/simmetrics/maven-metadata.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | uk.ac.shef.wit
4 | simmetrics
5 |
6 | 1.6.2
7 |
8 | 1.6.2
9 |
10 | 20140201152801
11 |
12 |
13 |
--------------------------------------------------------------------------------
/spring-batch-scalability/repo/uk/ac/shef/wit/simmetrics/maven-metadata.xml.md5:
--------------------------------------------------------------------------------
1 | 46680cf725265adfa2b7513b54b3ea9c
--------------------------------------------------------------------------------
/spring-batch-scalability/repo/uk/ac/shef/wit/simmetrics/maven-metadata.xml.sha1:
--------------------------------------------------------------------------------
1 | aa267239e66345cacd0d73dfbda42c2d5170015c
--------------------------------------------------------------------------------
/spring-batch-scalability/src/main/java/com/ontheserverside/batch/bank/controller/RootController.java:
--------------------------------------------------------------------------------
1 | package com.ontheserverside.batch.bank.controller;
2 |
3 | import com.ontheserverside.batch.bank.tx.Elixir0Generator;
4 | import org.apache.commons.logging.Log;
5 | import org.apache.commons.logging.LogFactory;
6 | import org.springframework.batch.core.*;
7 | import org.springframework.batch.core.launch.JobLauncher;
8 | import org.springframework.beans.factory.annotation.Autowired;
9 | import org.springframework.stereotype.Controller;
10 | import org.springframework.web.bind.annotation.RequestMapping;
11 | import org.springframework.web.bind.annotation.RequestMethod;
12 | import org.springframework.web.bind.annotation.RequestParam;
13 | import org.springframework.web.bind.annotation.ResponseBody;
14 |
15 | import java.io.File;
16 | import java.io.IOException;
17 | import java.util.concurrent.Callable;
18 |
19 | @Controller
20 | @RequestMapping("/")
21 | public final class RootController {
22 |
23 | private static final Log logger = LogFactory.getLog(RootController.class);
24 |
25 | @Autowired
26 | private Elixir0Generator elixir0Generator;
27 |
28 | @Autowired
29 | private JobLauncher jobLauncher;
30 |
31 | @Autowired
32 | private Job elixir0ImportJob;
33 |
34 | @RequestMapping(value = "/", method = RequestMethod.GET)
35 | public String goHome() {
36 | return "home";
37 | }
38 |
39 | @RequestMapping(value = "/generate", method = RequestMethod.POST)
40 | public @ResponseBody Callable generateElixir0(
41 | @RequestParam("destinationFilePath") final String destinationFilePath,
42 | @RequestParam("numberOfTransactions") final int numberOfTransactions) throws IOException {
43 |
44 | return new Callable() {
45 | @Override
46 | public String call() throws Exception {
47 | logger.info(String.format("Generating Elixir0 message with %d transactions into %s",
48 | numberOfTransactions, destinationFilePath));
49 | elixir0Generator.generate(new File(destinationFilePath), numberOfTransactions);
50 | return "Elixir0 message generated";
51 | }
52 | };
53 | }
54 |
55 | @RequestMapping(value = "/startJob", method = RequestMethod.POST)
56 | public @ResponseBody String startJob(
57 | @RequestParam("inputFilePath") final String inputFilePath,
58 | @RequestParam("scalingStrategy") final String scalingStrategy) throws JobExecutionException {
59 |
60 | logger.info(String.format("Starting import job for Elixir0 message %s", inputFilePath));
61 |
62 | final JobParameters jobParameters = new JobParametersBuilder()
63 | .addString("inputFile", inputFilePath)
64 | .addString("scalingStrategy", scalingStrategy)
65 | .toJobParameters();
66 | final JobExecution jobExecution = jobLauncher.run(elixir0ImportJob, jobParameters);
67 | return "Job started with ID=" + jobExecution.getJobId();
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/spring-batch-scalability/src/main/java/com/ontheserverside/batch/bank/processing/Elixir0Mapper.java:
--------------------------------------------------------------------------------
1 | package com.ontheserverside.batch.bank.processing;
2 |
3 | import com.ontheserverside.batch.bank.tx.Elixir0Transaction;
4 | import com.ontheserverside.batch.bank.tx.TransactionStatus;
5 | import org.springframework.batch.item.file.mapping.FieldSetMapper;
6 | import org.springframework.batch.item.file.transform.FieldSet;
7 | import org.springframework.validation.BindException;
8 |
9 | public final class Elixir0Mapper implements FieldSetMapper {
10 |
11 | /**
12 | * Elixir0 message column names definition as used by {@link org.springframework.batch.item.file.transform.LineTokenizer}.
13 | */
14 | public static final String COLUMN_NAMES = "paymentCode,paymentDate,amount,orderingPartySortCode,unused1,orderingPartyAccountNumber,"
15 | + "beneficiaryAccountNumber,orderingPartyNameAndAddress,beneficiaryNameAndAddress,unused2,beneficiarySortCode,"
16 | + "paymentDetails,unused3,unused4,transactionCode,clientBankInformation";
17 |
18 |
19 | @Override
20 | public Elixir0Transaction mapFieldSet(final FieldSet fieldSet) throws BindException {
21 |
22 | final Elixir0Transaction tx = new Elixir0Transaction();
23 | tx.setStatus(TransactionStatus.LOADED);
24 |
25 | tx.setPaymentCode(fieldSet.readInt("paymentCode"));
26 | tx.setPaymentDate(fieldSet.readDate("paymentDate", "yyyyMMdd"));
27 | tx.setAmount(fieldSet.readBigDecimal("amount"));
28 | tx.setOrderingPartySortCode(fieldSet.readString("orderingPartySortCode"));
29 | tx.setOrderingPartyAccountNumber(fieldSet.readString("orderingPartyAccountNumber"));
30 | tx.setBeneficiaryAccountNumber(fieldSet.readString("beneficiaryAccountNumber"));
31 |
32 | final String[] orderingPartyNameAndAddress = fieldSet.readString("orderingPartyNameAndAddress").split("\\|", 2);
33 | tx.setOrderingPartyName(orderingPartyNameAndAddress[0]);
34 | tx.setOrderingPartyAddress(orderingPartyNameAndAddress[1]);
35 |
36 | final String[] beneficiaryNameAndAddress = fieldSet.readString("beneficiaryNameAndAddress").split("\\|", 2);
37 | tx.setBeneficiaryName(beneficiaryNameAndAddress[0]);
38 | tx.setBeneficiaryAddress(beneficiaryNameAndAddress[1]);
39 |
40 | tx.setBeneficiarySortCode(fieldSet.readString("beneficiarySortCode"));
41 | tx.setPaymentDetails(fieldSet.readString("paymentDetails"));
42 | tx.setTransactionCode(fieldSet.readString("transactionCode"));
43 | tx.setClientBankInformation(fieldSet.readString("clientBankInformation"));
44 |
45 | return tx;
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/spring-batch-scalability/src/main/java/com/ontheserverside/batch/bank/processing/JobParameterExecutionDecider.java:
--------------------------------------------------------------------------------
1 | package com.ontheserverside.batch.bank.processing;
2 |
3 | import org.springframework.batch.core.JobExecution;
4 | import org.springframework.batch.core.StepExecution;
5 | import org.springframework.batch.core.job.flow.FlowExecutionStatus;
6 | import org.springframework.batch.core.job.flow.JobExecutionDecider;
7 | import org.springframework.beans.factory.annotation.Required;
8 |
9 | public final class JobParameterExecutionDecider implements JobExecutionDecider {
10 |
11 | private String jobParameterKey;
12 |
13 | @Override
14 | public FlowExecutionStatus decide(JobExecution jobExecution, StepExecution stepExecution) {
15 | return new FlowExecutionStatus(jobExecution.getJobParameters().getString(jobParameterKey));
16 | }
17 |
18 | @Required
19 | public void setJobParameterKey(String jobParameterKey) {
20 | this.jobParameterKey = jobParameterKey;
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/spring-batch-scalability/src/main/java/com/ontheserverside/batch/bank/processing/ModuloPartitioner.java:
--------------------------------------------------------------------------------
1 | package com.ontheserverside.batch.bank.processing;
2 |
3 | import org.springframework.batch.core.partition.support.Partitioner;
4 | import org.springframework.batch.item.ExecutionContext;
5 |
6 | import java.util.HashMap;
7 | import java.util.Map;
8 |
9 | public final class ModuloPartitioner implements Partitioner {
10 |
11 | public static final String MOD_DIVISOR_KEY = "mod.divisor";
12 | public static final String MOD_REMAINDER_KEY = "mod.remainder";
13 |
14 | @Override
15 | public Map partition(int gridSize) {
16 | final Map contextMap = new HashMap<>();
17 |
18 | for (int i = 0; i < gridSize; i++) {
19 | ExecutionContext context = new ExecutionContext();
20 | context.putInt(MOD_DIVISOR_KEY, gridSize);
21 | context.putInt(MOD_REMAINDER_KEY, i);
22 | contextMap.put(getPartitionName(i), context);
23 | }
24 |
25 | return contextMap;
26 | }
27 |
28 | private String getPartitionName(int index) {
29 | return String.format("partition-%d", index);
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/spring-batch-scalability/src/main/java/com/ontheserverside/batch/bank/processing/SynchronizedItemReaderDecorator.java:
--------------------------------------------------------------------------------
1 | package com.ontheserverside.batch.bank.processing;
2 |
3 | import org.springframework.batch.item.*;
4 |
5 | public final class SynchronizedItemReaderDecorator implements ItemStream, ItemReader {
6 |
7 | private final ItemReader delegate;
8 |
9 | public SynchronizedItemReaderDecorator(ItemReader delegate) {
10 | this.delegate = delegate;
11 | }
12 |
13 | @Override
14 | public synchronized T read() throws Exception, UnexpectedInputException, ParseException, NonTransientResourceException {
15 | return delegate.read();
16 | }
17 |
18 | @Override
19 | public synchronized void open(ExecutionContext executionContext) throws ItemStreamException {
20 | if (delegate instanceof ItemStream) {
21 | ((ItemStream) delegate).open(executionContext);
22 | }
23 | }
24 |
25 | @Override
26 | public synchronized void update(ExecutionContext executionContext) throws ItemStreamException {
27 | if (delegate instanceof ItemStream) {
28 | ((ItemStream) delegate).update(executionContext);
29 | }
30 | }
31 |
32 | @Override
33 | public synchronized void close() throws ItemStreamException {
34 | if (delegate instanceof ItemStream) {
35 | ((ItemStream) delegate).close();
36 | }
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/spring-batch-scalability/src/main/java/com/ontheserverside/batch/bank/screening/FuzzyMatcher.java:
--------------------------------------------------------------------------------
1 | package com.ontheserverside.batch.bank.screening;
2 |
3 | /**
4 | * Strategy performing fuzzy matching of two sequences. Implementations may use
5 | * various distance metrics that best fit the particular purpose.
6 | */
7 | public interface FuzzyMatcher {
8 |
9 | boolean sequencesMatching(String phrase1, String phrase2);
10 | }
11 |
--------------------------------------------------------------------------------
/spring-batch-scalability/src/main/java/com/ontheserverside/batch/bank/screening/JaroBagFuzzyMatcher.java:
--------------------------------------------------------------------------------
1 | package com.ontheserverside.batch.bank.screening;
2 |
3 | import org.springframework.stereotype.Component;
4 | import uk.ac.shef.wit.simmetrics.similaritymetrics.InterfaceStringMetric;
5 | import uk.ac.shef.wit.simmetrics.similaritymetrics.Jaro;
6 |
7 | import java.util.ArrayList;
8 | import java.util.Arrays;
9 | import java.util.List;
10 |
11 | /**
12 | * {@link FuzzyMatcher} strategy implementation using Jaro metrics.
13 | *
14 | * @see FuzzyMatcher
15 | */
16 | @Component
17 | public final class JaroBagFuzzyMatcher implements FuzzyMatcher {
18 |
19 | private static final double JARO_SINGLE_WORD_PHRASE_MIN_MATCH_FACTOR = 0.9;
20 | private static final double JARO_WORD_MIN_MATCH_FACTOR = 0.8333;
21 | private static final double BAG_MIN_MATCH_FACTOR = 0.932;
22 |
23 | private final InterfaceStringMetric jaroMetric = new Jaro();
24 |
25 | /**
26 | * {@inheritDoc}
27 | */
28 | @Override
29 | public boolean sequencesMatching(final String phrase1, final String phrase2) {
30 | final String phrase1LowerCase = removeNonAlphanumeric(phrase1).toLowerCase();
31 | final String phrase2LowerCase = removeNonAlphanumeric(phrase2).toLowerCase();
32 |
33 | final List phrase1Bag = new ArrayList<>(Arrays.asList(phrase1LowerCase.split("\\s+")));
34 | final List phrase2Bag = new ArrayList<>(Arrays.asList(phrase2LowerCase.split("\\s+")));
35 |
36 | if (phrase1Bag.size() == 1 && phrase2Bag.size() == 1) {
37 | // single-word phrases deserve special treatment...
38 | return jaroMetric(phrase1LowerCase, phrase2LowerCase) >= JARO_SINGLE_WORD_PHRASE_MIN_MATCH_FACTOR;
39 | } else if (phrase1Bag.size() < phrase2Bag.size()) {
40 | return compareBags(phrase1Bag, phrase2Bag) >= BAG_MIN_MATCH_FACTOR;
41 | } else {
42 | return compareBags(phrase2Bag, phrase1Bag) >= BAG_MIN_MATCH_FACTOR;
43 | }
44 | }
45 |
46 | private double compareBags(final List bagA, final List bagB) {
47 | if (bagA.size() > bagB.size()) {
48 | throw new IllegalArgumentException("bagA size must be less than bagB size for algorithm to work!");
49 | }
50 |
51 | double matchedLength = 0;
52 | double overalLength = 0;
53 | for (String word: bagA) {
54 | overalLength += word.length();
55 | }
56 | for (String word: bagB) {
57 | overalLength += word.length();
58 | }
59 |
60 | for (String a_word : bagA) {
61 | for (int i = 0; i < bagB.size(); i++) {
62 | String b_word = bagB.get(i);
63 |
64 | if (jaroMetric(a_word, b_word) > JARO_WORD_MIN_MATCH_FACTOR) {
65 | bagB.remove(i);
66 | matchedLength += a_word.length() + b_word.length();
67 | break;
68 | }
69 | }
70 | }
71 |
72 | return matchedLength / overalLength;
73 | }
74 |
75 | private double jaroMetric(final String word1, final String word2) {
76 | return jaroMetric.getSimilarity(word1, word2);
77 | }
78 |
79 | private String removeNonAlphanumeric(final String str) {
80 | return str.replaceAll("[^a-zA-Z0-9\\s]", "");
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/spring-batch-scalability/src/main/java/com/ontheserverside/batch/bank/screening/SDNEntity.java:
--------------------------------------------------------------------------------
1 | package com.ontheserverside.batch.bank.screening;
2 |
3 | import org.apache.commons.lang3.StringUtils;
4 | import org.hibernate.annotations.Immutable;
5 |
6 | import javax.persistence.*;
7 | import java.io.Serializable;
8 | import java.util.List;
9 |
10 | @Entity
11 | @Immutable
12 | @Table(name = "SDN_ENTITY")
13 | public final class SDNEntity implements Serializable {
14 |
15 | @Id
16 | @Column(name = "UID")
17 | private long id;
18 |
19 | @Column(name = "NAME")
20 | private String name;
21 |
22 | @OneToMany(fetch = FetchType.EAGER)
23 | @JoinColumn(name = "ENTITY_UID")
24 | private List addresses;
25 |
26 | @ElementCollection(fetch = FetchType.EAGER)
27 | @CollectionTable(
28 | name = "SDN_ALTERNATE_NAME",
29 | joinColumns=@JoinColumn(name = "ENTITY_UID")
30 | )
31 | @Column(name = "NAME")
32 | private List alternateNames;
33 |
34 | // hibernate requirement
35 | @Deprecated
36 | protected SDNEntity() {
37 | }
38 |
39 | public SDNEntity(String name, List addresses, List alternateNames) {
40 | this.name = name;
41 | this.addresses = addresses;
42 | this.alternateNames = alternateNames;
43 | }
44 |
45 | public String getName() {
46 | return this.name;
47 | }
48 |
49 | public List getAddresses() {
50 | return this.addresses;
51 | }
52 |
53 | public List getAlternateNames() {
54 | return this.alternateNames;
55 | }
56 |
57 | @Entity
58 | @Immutable
59 | @Table(name = "SDN_ADDRESS")
60 | public static class SDNAddress implements Serializable {
61 |
62 | @Id
63 | @Column(name = "ADDRESS_UID")
64 | private long id;
65 |
66 | @Column(name = "ADDRESS")
67 | private String address;
68 |
69 | @Column(name = "CITY")
70 | private String city;
71 |
72 | @Column(name = "COUNTRY")
73 | private String country;
74 |
75 | // hibernate requirement
76 | @Deprecated
77 | protected SDNAddress() {
78 | }
79 |
80 | public SDNAddress(String address, String city, String country) {
81 | this.address = address;
82 | this.city = city;
83 | this.country = country;
84 | }
85 |
86 | public String getFull() {
87 | return new StringBuilder()
88 | .append(StringUtils.defaultString(this.address)).append(" ")
89 | .append(StringUtils.defaultString(this.city)).append(" ")
90 | .append(StringUtils.defaultString(this.country))
91 | .toString();
92 | }
93 | }
94 | }
95 |
--------------------------------------------------------------------------------
/spring-batch-scalability/src/main/java/com/ontheserverside/batch/bank/screening/SanctionMatch.java:
--------------------------------------------------------------------------------
1 | package com.ontheserverside.batch.bank.screening;
2 |
3 | import com.ontheserverside.batch.bank.tx.Elixir0Transaction;
4 |
5 | import javax.persistence.*;
6 |
7 | @Entity
8 | @Table(name = "SANCTION_MATCH")
9 | public class SanctionMatch {
10 |
11 | @Id
12 | @GeneratedValue(strategy = GenerationType.AUTO)
13 | @Column(name = "ID")
14 | private long id;
15 |
16 | @OneToOne
17 | @JoinColumn(name = "TRANSACTION_ID")
18 | private Elixir0Transaction transaction;
19 |
20 | @OneToOne
21 | @JoinColumn(name = "SDN_ENTITY_ID")
22 | private SDNEntity sdnEntity;
23 |
24 | public SanctionMatch(Elixir0Transaction transaction, SDNEntity sdnEntity) {
25 | this.transaction = transaction;
26 | this.sdnEntity = sdnEntity;
27 | }
28 |
29 | public Elixir0Transaction getTransaction() {
30 | return transaction;
31 | }
32 |
33 | public SDNEntity getSdnEntity() {
34 | return sdnEntity;
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/spring-batch-scalability/src/main/java/com/ontheserverside/batch/bank/screening/SanctionScreeningContext.java:
--------------------------------------------------------------------------------
1 | package com.ontheserverside.batch.bank.screening;
2 |
3 | import com.ontheserverside.batch.bank.tx.Elixir0Transaction;
4 |
5 | import java.io.Serializable;
6 |
7 | public final class SanctionScreeningContext implements Serializable {
8 |
9 | private final Elixir0Transaction transaction;
10 | private final SDNEntity sdnEntity;
11 |
12 | public SanctionScreeningContext(Elixir0Transaction transaction, SDNEntity sdnEntity) {
13 | this.transaction = transaction;
14 | this.sdnEntity = sdnEntity;
15 | }
16 |
17 | public Elixir0Transaction getTransaction() {
18 | return this.transaction;
19 | }
20 |
21 | public SDNEntity getSdnEntity() {
22 | return this.sdnEntity;
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/spring-batch-scalability/src/main/java/com/ontheserverside/batch/bank/screening/SanctionScreeningProcessor.java:
--------------------------------------------------------------------------------
1 | package com.ontheserverside.batch.bank.screening;
2 |
3 | import com.ontheserverside.batch.bank.tx.Elixir0Transaction;
4 | import org.springframework.batch.item.ItemProcessor;
5 | import org.springframework.beans.factory.annotation.Autowired;
6 |
7 | import java.util.LinkedList;
8 | import java.util.List;
9 | import static java.util.Arrays.asList;
10 |
11 | public final class SanctionScreeningProcessor implements ItemProcessor {
12 |
13 | @Autowired
14 | private FuzzyMatcher fuzzyMatcher;
15 |
16 | private final AbstractMatcher matcher = new CompositeMatcher(asList(
17 | new BeneficiaryNameMatcher(),
18 | new OrderingPartyNameMatcher(),
19 | new BeneficiaryAddressMatcher(),
20 | new OrderingPartyAddressMatcher(),
21 | new BeneficiaryAlternateNameMatcher(),
22 | new OrderingPartyAlternateNameMatcher()
23 | ));
24 |
25 | @Override
26 | public SanctionMatch process(SanctionScreeningContext context) {
27 | final Elixir0Transaction transaction = context.getTransaction();
28 | final SDNEntity sdnEntity = context.getSdnEntity();
29 |
30 | if (matcher.matches(transaction, sdnEntity)) {
31 | return new SanctionMatch(transaction, sdnEntity);
32 | }
33 |
34 | return null;
35 | }
36 |
37 | private final class BeneficiaryNameMatcher extends AbstractMatcher {
38 | @Override
39 | public boolean matches(Elixir0Transaction tx, SDNEntity sdn) {
40 | return fuzzyMatch(tx.getBeneficiaryName(), sdn.getName());
41 | }
42 | }
43 |
44 | private final class OrderingPartyNameMatcher extends AbstractMatcher {
45 | @Override
46 | public boolean matches(Elixir0Transaction tx, SDNEntity sdn) {
47 | return fuzzyMatch(tx.getOrderingPartyName(), sdn.getName());
48 | }
49 | }
50 |
51 | private final class BeneficiaryAddressMatcher extends AbstractMatcher {
52 | @Override
53 | public boolean matches(Elixir0Transaction tx, SDNEntity sdn) {
54 | final List fullAddresses = new LinkedList<>();
55 | for (SDNEntity.SDNAddress address : sdn.getAddresses()) {
56 | fullAddresses.add(address.getFull());
57 | }
58 | return fuzzyMatch(tx.getBeneficiaryAddress(), fullAddresses);
59 | }
60 | }
61 |
62 | private final class OrderingPartyAddressMatcher extends AbstractMatcher {
63 | @Override
64 | public boolean matches(Elixir0Transaction tx, SDNEntity sdn) {
65 | final List fullAddresses = new LinkedList<>();
66 | for (SDNEntity.SDNAddress address : sdn.getAddresses()) {
67 | fullAddresses.add(address.getFull());
68 | }
69 | return fuzzyMatch(tx.getOrderingPartyAddress(), fullAddresses);
70 | }
71 | }
72 |
73 | private final class BeneficiaryAlternateNameMatcher extends AbstractMatcher {
74 | @Override
75 | public boolean matches(Elixir0Transaction tx, SDNEntity sdn) {
76 | return fuzzyMatch(tx.getBeneficiaryName(), sdn.getAlternateNames());
77 | }
78 | }
79 |
80 | private final class OrderingPartyAlternateNameMatcher extends AbstractMatcher {
81 | @Override
82 | public boolean matches(Elixir0Transaction tx, SDNEntity sdn) {
83 | return fuzzyMatch(tx.getOrderingPartyName(), sdn.getAlternateNames());
84 | }
85 | }
86 |
87 | private final class CompositeMatcher extends AbstractMatcher {
88 |
89 | private final List matchers;
90 |
91 | public CompositeMatcher(List matchers) {
92 | this.matchers = matchers;
93 | }
94 |
95 | @Override
96 | public boolean matches(Elixir0Transaction tx, SDNEntity sdn) {
97 | for (AbstractMatcher matcher: matchers) {
98 | if (matcher.matches(tx, sdn)) {
99 | return true;
100 | }
101 | }
102 |
103 | return false;
104 | }
105 | }
106 |
107 | private abstract class AbstractMatcher {
108 |
109 | public abstract boolean matches(Elixir0Transaction tx, SDNEntity sdn);
110 |
111 | protected boolean fuzzyMatch(String str, String searchStr) {
112 | return fuzzyMatcher.sequencesMatching(str, searchStr);
113 | }
114 |
115 | protected boolean fuzzyMatch(String str, Iterable searchStrs) {
116 | for (String searchStr : searchStrs) {
117 | if (fuzzyMatch(str, searchStr)) {
118 | return true;
119 | }
120 | }
121 |
122 | return false;
123 | }
124 | }
125 | }
126 |
--------------------------------------------------------------------------------
/spring-batch-scalability/src/main/java/com/ontheserverside/batch/bank/screening/SanctionScreeningRecoveryCleaner.java:
--------------------------------------------------------------------------------
1 | package com.ontheserverside.batch.bank.screening;
2 |
3 | import com.ontheserverside.batch.bank.tx.TransactionStatus;
4 | import org.hibernate.SessionFactory;
5 | import org.springframework.batch.core.StepExecution;
6 | import org.springframework.batch.core.listener.StepExecutionListenerSupport;
7 | import org.springframework.beans.factory.annotation.Autowired;
8 | import org.springframework.transaction.annotation.Transactional;
9 |
10 | /**
11 | * Cleans up stale date in case of re-entering sanction screening step during the job recovery.
12 | * Because of multithreaded nature of this step and unknown number of matches that are going to
13 | * be analysed for one transaction, this strategy fits better for this task than processing
14 | * status indicator column (can't really say if transaction has been completely screened or not).
15 | */
16 | public final class SanctionScreeningRecoveryCleaner extends StepExecutionListenerSupport {
17 |
18 | @Autowired
19 | private SessionFactory sessionFactory;
20 |
21 | @Transactional
22 | @Override
23 | public void beforeStep(StepExecution stepExecution) {
24 |
25 | sessionFactory.getCurrentSession()
26 | .createQuery("delete from SanctionMatch where transaction.id in (" +
27 | "select tx.id from Elixir0Transaction as tx where tx.status = :status)")
28 | .setParameter("status", TransactionStatus.LOADED)
29 | .executeUpdate();
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/spring-batch-scalability/src/main/java/com/ontheserverside/batch/bank/screening/UpdateScreenedTransactionStatusTasklet.java:
--------------------------------------------------------------------------------
1 | package com.ontheserverside.batch.bank.screening;
2 |
3 | import com.ontheserverside.batch.bank.tx.TransactionStatus;
4 | import org.hibernate.SessionFactory;
5 | import org.springframework.batch.core.StepContribution;
6 | import org.springframework.batch.core.scope.context.ChunkContext;
7 | import org.springframework.batch.core.step.tasklet.Tasklet;
8 | import org.springframework.batch.repeat.RepeatStatus;
9 | import org.springframework.beans.factory.annotation.Autowired;
10 |
11 | public final class UpdateScreenedTransactionStatusTasklet implements Tasklet {
12 |
13 | @Autowired
14 | private SessionFactory sessionFactory;
15 |
16 | @Override
17 | public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
18 |
19 | sessionFactory.getCurrentSession()
20 | .createQuery("update Elixir0Transaction as tx set tx.status = :status where tx in (" +
21 | "select sm.transaction from SanctionMatch as sm)")
22 | .setParameter("status", TransactionStatus.SUSPENDED)
23 | .executeUpdate();
24 |
25 | sessionFactory.getCurrentSession()
26 | .createQuery("update Elixir0Transaction as tx set tx.status = :status where tx not in (" +
27 | "select sm.transaction from SanctionMatch as sm)")
28 | .setParameter("status", TransactionStatus.ACCEPTED)
29 | .executeUpdate();
30 |
31 | return RepeatStatus.FINISHED;
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/spring-batch-scalability/src/main/java/com/ontheserverside/batch/bank/tx/Elixir0Generator.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.ontheserverside.batch.bank.tx;
18 |
19 | import java.io.File;
20 | import java.io.IOException;
21 |
22 | /**
23 | * Generates Elixir0 file containing random transactions.
24 | */
25 | public interface Elixir0Generator {
26 |
27 | void generate(File outputFile, int numberOfTransactions) throws IOException;
28 | }
29 |
--------------------------------------------------------------------------------
/spring-batch-scalability/src/main/java/com/ontheserverside/batch/bank/tx/Elixir0Transaction.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.ontheserverside.batch.bank.tx;
18 |
19 | import org.apache.commons.lang3.ArrayUtils;
20 | import org.apache.commons.lang3.builder.ToStringBuilder;
21 | import org.apache.commons.lang3.builder.ToStringStyle;
22 |
23 | import javax.persistence.*;
24 | import java.io.Serializable;
25 | import java.math.BigDecimal;
26 | import java.text.SimpleDateFormat;
27 | import java.util.Date;
28 |
29 | /**
30 | * Represents Elixir0 domestic transaction loaded from file.
31 | *
32 | * Elixir0 is a country-domestic format used by Polish banking systems.
33 | * It may contain standard credit transfer transactions as well as social
34 | * security and tax payments.
35 | */
36 | @Entity
37 | @Table(name = "ELIXIR0_TX")
38 | public final class Elixir0Transaction implements Serializable {
39 |
40 | public static final int PAYMENT_CODE_LOCAL = 110;
41 |
42 | public static final String TRANSACTION_CODE_CT = "51";
43 |
44 | /**
45 | * Names of fields declared as a 'text type' fields by the elixir0 format
46 | */
47 | private static final String[] TEXT_FIELDS = {
48 | "orderingPartyAccountNumber",
49 | "beneficiaryAccountNumber",
50 | "orderingPartyNameAndAddress",
51 | "beneficiaryNameAndAddress",
52 | "paymentDetails",
53 | "transactionCode",
54 | "clientBankInformation"
55 | };
56 |
57 | private static final ToStringStyle TO_STRING_STYLE = new TxToStringStyle();
58 |
59 | @Id
60 | @GeneratedValue(strategy = GenerationType.AUTO)
61 | @Column(name = "ID")
62 | private long id;
63 |
64 | @Enumerated(EnumType.STRING)
65 | @Column(name = "STATUS")
66 | private TransactionStatus status;
67 |
68 | @Column(name = "PAYMENT_CODE")
69 | private int paymentCode;
70 |
71 | @Column(name = "PAYMENT_DATE")
72 | private Date paymentDate;
73 |
74 | @Column(name = "AMOUNT")
75 | private BigDecimal amount;
76 |
77 | @Column(name = "ORDERING_PARTY_SORT_CODE")
78 | private String orderingPartySortCode;
79 |
80 | @Column(name = "ORDERING_PARTY_ACCOUNT_NUMBER")
81 | private String orderingPartyAccountNumber;
82 |
83 | @Column(name = "BENEFICIARY_ACCOUNT_NUMBER")
84 | private String beneficiaryAccountNumber;
85 |
86 | @Column(name = "ORDERING_PARTY_NAME")
87 | private String orderingPartyName;
88 |
89 | @Column(name = "ORDERING_PARTY_ADDRESS")
90 | private String orderingPartyAddress;
91 |
92 | @Column(name = "BENEFICIARY_NAME")
93 | private String beneficiaryName;
94 |
95 | @Column(name = "BENEFICIARY_ADDRESS")
96 | private String beneficiaryAddress;
97 |
98 | @Column(name = "BENEFICIARY_SORT_CODE")
99 | private String beneficiarySortCode;
100 |
101 | @Column(name = "PAYMENT_DETAILS")
102 | private String paymentDetails;
103 |
104 | // fields below are used only for social security and tax payments
105 | // their values should be extracted from 'paymentDetails' section
106 | @Column(name = "PAYERS_NIP")
107 | private String payersNip;
108 | @Column(name = "IDENTIFIER_TYPE")
109 | private String identifierType;
110 | @Column(name = "PAYERS_IDENTIFICATION")
111 | private String payersIdentification;
112 | @Column(name = "PAYMENT_TYPE")
113 | private String paymentType;
114 | @Column(name = "PAYMENT_PERIOD")
115 | private Date paymentPeriod;
116 | @Column(name = "PERIOD_FORM_NUMBER")
117 | private String periodFormNumber;
118 | @Column(name = "ADDITIONAL_CASE_ID")
119 | private String additionalCaseID;
120 |
121 | @Column(name = "TRANSACTION_CODE")
122 | private String transactionCode;
123 |
124 | @Column(name = "CLIENT_BANK_INFORMATION")
125 | private String clientBankInformation;
126 |
127 |
128 | public TransactionStatus getStatus() {
129 | return status;
130 | }
131 |
132 | public void setStatus(TransactionStatus status) {
133 | this.status = status;
134 | }
135 |
136 | public int getPaymentCode() {
137 | return paymentCode;
138 | }
139 |
140 | public void setPaymentCode(int paymentCode) {
141 | this.paymentCode = paymentCode;
142 | }
143 |
144 | public Date getPaymentDate() {
145 | return paymentDate;
146 | }
147 |
148 | public void setPaymentDate(Date paymentDate) {
149 | this.paymentDate = paymentDate;
150 | }
151 |
152 | public BigDecimal getAmount() {
153 | return amount;
154 | }
155 |
156 | public void setAmount(BigDecimal amount) {
157 | this.amount = amount;
158 | }
159 |
160 | public String getOrderingPartySortCode() {
161 | return orderingPartySortCode;
162 | }
163 |
164 | public void setOrderingPartySortCode(String orderingPartySortCode) {
165 | this.orderingPartySortCode = orderingPartySortCode;
166 | }
167 |
168 | public String getOrderingPartyAccountNumber() {
169 | return orderingPartyAccountNumber;
170 | }
171 |
172 | public void setOrderingPartyAccountNumber(String orderingPartyAccountNumber) {
173 | this.orderingPartyAccountNumber = orderingPartyAccountNumber;
174 | }
175 |
176 | public String getBeneficiaryAccountNumber() {
177 | return beneficiaryAccountNumber;
178 | }
179 |
180 | public void setBeneficiaryAccountNumber(String beneficiaryAccountNumber) {
181 | this.beneficiaryAccountNumber = beneficiaryAccountNumber;
182 | }
183 |
184 | public String getOrderingPartyName() {
185 | return orderingPartyName;
186 | }
187 |
188 | public void setOrderingPartyName(String orderingPartyName) {
189 | this.orderingPartyName = orderingPartyName;
190 | }
191 |
192 | public String getOrderingPartyAddress() {
193 | return orderingPartyAddress;
194 | }
195 |
196 | public void setOrderingPartyAddress(String orderingPartyAddress) {
197 | this.orderingPartyAddress = orderingPartyAddress;
198 | }
199 |
200 | public String getBeneficiaryName() {
201 | return beneficiaryName;
202 | }
203 |
204 | public void setBeneficiaryName(String beneficiaryName) {
205 | this.beneficiaryName = beneficiaryName;
206 | }
207 |
208 | public String getBeneficiaryAddress() {
209 | return beneficiaryAddress;
210 | }
211 |
212 | public void setBeneficiaryAddress(String beneficiaryAddress) {
213 | this.beneficiaryAddress = beneficiaryAddress;
214 | }
215 |
216 | public String getBeneficiarySortCode() {
217 | return beneficiarySortCode;
218 | }
219 |
220 | public void setBeneficiarySortCode(String beneficiarySortCode) {
221 | this.beneficiarySortCode = beneficiarySortCode;
222 | }
223 |
224 | public String getPaymentDetails() {
225 | return paymentDetails;
226 | }
227 |
228 | public void setPaymentDetails(String paymentDetails) {
229 | this.paymentDetails = paymentDetails;
230 | }
231 |
232 | public String getPayersNip() {
233 | return payersNip;
234 | }
235 |
236 | public void setPayersNip(String payersNip) {
237 | this.payersNip = payersNip;
238 | }
239 |
240 | public String getIdentifierType() {
241 | return identifierType;
242 | }
243 |
244 | public void setIdentifierType(String identifierType) {
245 | this.identifierType = identifierType;
246 | }
247 |
248 | public String getPayersIdentification() {
249 | return payersIdentification;
250 | }
251 |
252 | public void setPayersIdentification(String payersIdentification) {
253 | this.payersIdentification = payersIdentification;
254 | }
255 |
256 | public String getPaymentType() {
257 | return paymentType;
258 | }
259 |
260 | public void setPaymentType(String paymentType) {
261 | this.paymentType = paymentType;
262 | }
263 |
264 | public Date getPaymentPeriod() {
265 | return paymentPeriod;
266 | }
267 |
268 | public void setPaymentPeriod(Date paymentPeriod) {
269 | this.paymentPeriod = paymentPeriod;
270 | }
271 |
272 | public String getPeriodFormNumber() {
273 | return periodFormNumber;
274 | }
275 |
276 | public void setPeriodFormNumber(String periodFormNumber) {
277 | this.periodFormNumber = periodFormNumber;
278 | }
279 |
280 | public String getAdditionalCaseID() {
281 | return additionalCaseID;
282 | }
283 |
284 | public void setAdditionalCaseID(String additionalCaseID) {
285 | this.additionalCaseID = additionalCaseID;
286 | }
287 |
288 | public String getTransactionCode() {
289 | return transactionCode;
290 | }
291 |
292 | public void setTransactionCode(String transactionCode) {
293 | this.transactionCode = transactionCode;
294 | }
295 |
296 | public String getClientBankInformation() {
297 | return clientBankInformation;
298 | }
299 |
300 | public void setClientBankInformation(String clientBankInformation) {
301 | this.clientBankInformation = clientBankInformation;
302 | }
303 |
304 | @Override
305 | public String toString() {
306 | return new ToStringBuilder(this, TO_STRING_STYLE)
307 | .append("paymentCode", paymentCode)
308 | .append("paymentDate", paymentDate)
309 | .append("amount", amount)
310 | .append("orderingPartySortCode", orderingPartySortCode)
311 | .append("0") // hardcoded as '0' in the format definition
312 | .append("orderingPartyAccountNumber", orderingPartyAccountNumber)
313 | .append("beneficiaryAccountNumber", beneficiaryAccountNumber)
314 | .append("orderingPartyNameAndAddress", String.format("%s|%s",
315 | orderingPartyName != null ? orderingPartyName : "",
316 | orderingPartyAddress != null ? orderingPartyAddress : ""))
317 | .append("beneficiaryNameAndAddress", String.format("%s|%s",
318 | beneficiaryName != null ? beneficiaryName : "",
319 | beneficiaryAddress != null ? beneficiaryAddress : ""))
320 | .append("0") // hardcoded as '0' in the format definition
321 | .append("beneficiarySortCode", beneficiarySortCode)
322 | .append("paymentDetails", paymentDetails)
323 | .append("") // hardcoded as empty in the format definition
324 | .append("") // hardcoded as empty in the format definition
325 | .append("transactionCode", transactionCode)
326 | .append("clientBankInformation", clientBankInformation)
327 | .toString();
328 | }
329 |
330 | private static class TxToStringStyle extends ToStringStyle {
331 |
332 | TxToStringStyle() {
333 | super();
334 | this.setUseClassName(false);
335 | this.setUseIdentityHashCode(false);
336 | this.setUseFieldNames(false);
337 | this.setContentStart("");
338 | this.setContentEnd("");
339 | this.setNullText("");
340 | }
341 |
342 | @Override
343 | protected void appendFieldStart(StringBuffer buffer, String fieldName) {
344 | super.appendFieldStart(buffer, fieldName);
345 |
346 | if (ArrayUtils.contains(TEXT_FIELDS, fieldName)) {
347 | buffer.append("\"");
348 | }
349 | }
350 |
351 | @Override
352 | protected void appendFieldEnd(StringBuffer buffer, String fieldName) {
353 | if (ArrayUtils.contains(TEXT_FIELDS, fieldName)) {
354 | buffer.append("\"");
355 | }
356 |
357 | super.appendFieldEnd(buffer, fieldName);
358 | }
359 |
360 | @Override
361 | protected void appendDetail(StringBuffer buffer, String fieldName, Object value) {
362 | if (value instanceof Date) {
363 | value = new SimpleDateFormat("yyyyMMdd").format(value);
364 | }
365 |
366 | buffer.append(value);
367 | }
368 | }
369 | }
--------------------------------------------------------------------------------
/spring-batch-scalability/src/main/java/com/ontheserverside/batch/bank/tx/SimpleElixir0Generator.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.ontheserverside.batch.bank.tx;
18 |
19 | import org.springframework.beans.factory.annotation.Value;
20 | import org.springframework.core.io.Resource;
21 | import org.springframework.stereotype.Component;
22 |
23 | import javax.annotation.PostConstruct;
24 | import java.io.*;
25 | import java.math.BigDecimal;
26 | import java.math.BigInteger;
27 |
28 | import java.nio.charset.StandardCharsets;
29 | import java.nio.file.Files;
30 | import java.util.*;
31 |
32 | @Component
33 | public final class SimpleElixir0Generator implements Elixir0Generator {
34 |
35 | @javax.annotation.Resource
36 | @Value("classpath:names.txt")
37 | private Resource paymentPartyNamesResource;
38 |
39 | @javax.annotation.Resource
40 | @Value("classpath:addresses.txt")
41 | private Resource paymentPartyAddressesResource;
42 |
43 | @javax.annotation.Resource
44 | @Value("classpath:dictionary.txt")
45 | private Resource dictionaryResource;
46 |
47 | private final List paymentPartyNames = new LinkedList<>();
48 | private final List paymentPartyAddresses = new LinkedList<>();
49 | private final List words = new LinkedList<>();
50 |
51 | @PostConstruct
52 | private void loadExternalDataResources() throws IOException {
53 | paymentPartyNames.addAll(loadLinesFromFile(paymentPartyNamesResource));
54 | paymentPartyAddresses.addAll(loadLinesFromFile(paymentPartyAddressesResource));
55 | words.addAll(loadLinesFromFile(dictionaryResource));
56 | }
57 |
58 | // note: usage of this method is reasonable only for relatively small files!
59 | private List loadLinesFromFile(final Resource resource) throws IOException {
60 | return Files.readAllLines(resource.getFile().toPath(),
61 | StandardCharsets.UTF_8);
62 | }
63 |
64 | @Override
65 | public void generate(final File outputFile, final int numberOfTransactions) throws IOException {
66 | final TxGenerator txGenerator = new TxGenerator();
67 | final BufferedWriter writer = Files.newBufferedWriter(outputFile.toPath(), StandardCharsets.UTF_8);
68 | try {
69 | for (int i=0; i
2 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/spring-batch-scalability/src/main/resources/META-INF/spring/batchContext.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/spring-batch-scalability/src/main/resources/META-INF/spring/elixir0ImportJob.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 | SELECT NEW com.ontheserverside.batch.bank.screening.SanctionScreeningContext (tx, entity)
109 | FROM Elixir0Transaction tx, SDNEntity entity
110 | WHERE tx.status = :txStatus
111 | ORDER BY tx.id
112 |
113 |
114 |
115 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 | SELECT NEW com.ontheserverside.batch.bank.screening.SanctionScreeningContext (tx, entity)
130 | FROM Elixir0Transaction tx, SDNEntity entity
131 | WHERE tx.status = :txStatus
132 | ORDER BY tx.id
133 |
134 |
135 |
136 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 | SELECT NEW com.ontheserverside.batch.bank.screening.SanctionScreeningContext (tx, entity)
149 | FROM Elixir0Transaction tx, SDNEntity entity
150 | WHERE tx.status = :txStatus
151 | AND mod(tx.id, :modDivisor) = :modRemainder
152 | ORDER BY tx.id
153 |
154 |
155 |
156 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 | inputFile
182 | scalingStrategy
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 |
219 |
220 |
221 |
222 |
223 |
--------------------------------------------------------------------------------
/spring-batch-scalability/src/main/resources/META-INF/spring/hibernateContext.xml:
--------------------------------------------------------------------------------
1 |
2 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 | com.ontheserverside.batch.bank
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 | org.hibernate.dialect.H2Dialect
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
48 |
49 |
50 |
51 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
--------------------------------------------------------------------------------
/spring-batch-scalability/src/main/resources/META-INF/spring/jmsContext.xml:
--------------------------------------------------------------------------------
1 |
2 |
14 |
15 |
16 |
17 |
18 |
19 |
20 | java.naming.factory.initial=net.timewalker.ffmq3.jndi.FFMQInitialContextFactory
21 | java.naming.provider.url=tcp://localhost:10002
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
33 |
34 |
35 |
36 |
38 |
40 |
41 |
42 |
43 |
44 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
61 |
62 |
63 |
64 |
68 |
69 |
71 |
72 |
73 |
76 |
77 |
78 |
79 |
81 |
82 |
83 |
84 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
--------------------------------------------------------------------------------
/spring-batch-scalability/src/main/resources/addresses.txt:
--------------------------------------------------------------------------------
1 | 2067 Gentle Sky Orchard, Mousetail, Alabama, 35330-7376, US
2 | 4074 Heather Corner, Luck, Alabama, 35398-0918, US
3 | 4791 Golden Acres, Beans Corner, Ontario, L4A-8V5, CA
4 | 7375 Quiet Zephyr Avenue, Humble City, South Dakota, 57605-5698, US
5 | 7780 Hazy Autumn Line, Swastika, Oklahoma, 73436-8342, US
6 | 5191 Shady Wagon Common, Joshua Tree, Mississippi, 38801-7578, US
7 | 1470 Easy Ridge, Keen-Wik, Texas, 78009-8992, US
8 | 4182 Misty Embers Vista, Martensville, Nunavut, X0F-5J2, CA
9 | 4492 Tawny Village, Buddha, New Jersey, 08383-1228, US
10 | 8978 Merry Trace, Shaft Ox Corner, Vermont, 05618-6954, US
11 | 9144 Grand Gate Glade, Red Scaffold, Wyoming, 82305-1040, US
12 | 1444 Rustic Corners, Oddville, Wyoming, 83029-7376, US
13 | 9173 Quaking Panda Quay, Sand Draw, Missouri, 64091-6390, US
14 | 75 Round Rise Grounds, Jumpertown, Arkansas, 71941-9808, US
15 | 7058 Jagged Green, Purchase, Michigan, 48597-2405, US
16 | 5310 Fallen Rise, Kinistino, Arizona, 86334-1987, US
17 | 1709 Emerald Stead, Swisher, Yukon, Y0E-9S9, CA
18 | 2048 Umber Berry Townline, Doolittle, New Mexico, 88038-7543, US
19 | 3093 Green Forest Place, Benefit, Vermont, 05331-1955, US
20 | 8128 Rocky Pine Front, Nokomis, Alberta, T0K-1O3, CA
21 | 8905 Foggy Promenade, Musk Ox, Nebraska, 69995-8936, US
22 | 3943 Pleasant Plaza, Uncle Sam, Arizona, 85565-6408, US
23 | 8231 Sleepy Abbey, Shakespeare, New Mexico, 88069-6553, US
24 | 8200 Honey Impasse, Sigourney, Hawaii, 96875-4553, US
25 | 1501 Clear By-pass, Tilsonburg, Northwest Territories, X6X-7Q5, CA
26 | 8876 Harvest Leaf Harbour, Fighting Rock Corner, Maryland, 21069-9972, US
27 | 6822 Amber Landing, The Black Cat, Kansas, 67889-2191, US
28 | 3019 Blue Mount, Swindleville, Ohio, 43262-8184, US
29 | 127 Red Hills Cove, Weyauwega, Kansas, 66955-7256, US
30 | 1617 Little Concession, Muitzeskill, Indiana, 46129-4378, US
31 | 3997 Lost Square, Syndicate, Florida, 33682-2268, US
32 | 6310 Broad Alley, Seventysix, Ohio, 43624-2085, US
33 | 6309 Old Park, Loves Corner, Vermont, 05780-7002, US
34 | 2205 Cozy Prairie Turnabout, Miami Beach, Hawaii, 96813-3312, US
35 | 7782 Lazy Path, Tangipahoa, Massachusetts, 02010-6477, US
36 | 275 High Horse Carrefour, Speedway, South Dakota, 57963-6449, US
37 | 3653 Burning Shadow Island, Hustle, Maine, 04509-1256, US
38 | 7062 Cinder Spring Trail, Waldron, Hawaii, 96849-0191, US
39 | 2344 Cotton Grove Mountain, Blue Anchor, Utah, 84383-1180, US
40 | 4608 Velvet Elk Boulevard, Gnaw Bone, District of Columbia, 20038-6201, US
41 | 2441 Noble Bluff Close, Coldfoot, Illinois, 62518-4030, US
42 | 4489 Sunny Hickory Terrace, Enderby, Iowa, 50157-9431, US
43 | 3805 Wishing Centre, Presidential, New York, 12655-9090, US
44 | 5257 Silent Range, Eighty Four, Oregon, 97408-9448, US
45 | 603 Iron Fox Farm, Bacons Quarters, Prince Edward Island, C3X-7R3, CA
46 | 1116 Middle Pines, Jinks, Saskatchewan, S7R-1U8, CA
47 | 3799 Thunder Treasure Wynd, Chickville, Arkansas, 71917-4851, US
48 | 306 Hidden Campus, Chevy Chase, Montana, 59521-3813, US
49 | 5784 Crystal Villas, Freeze, Michigan, 49662-9562, US
50 | 9510 Silver Wood, Lick Skillet, Iowa, 51093-5843, US
--------------------------------------------------------------------------------
/spring-batch-scalability/src/main/resources/log4j.properties:
--------------------------------------------------------------------------------
1 | log4j.rootCategory=INFO, stdout
2 |
3 | log4j.appender.stdout=org.apache.log4j.ConsoleAppender
4 | log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
5 | log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %t %c{2}:%L - %m%n
--------------------------------------------------------------------------------
/spring-batch-scalability/src/main/resources/names.txt:
--------------------------------------------------------------------------------
1 | ABIDJAN FREIGHT
2 | AIR CESS
3 | AIR ZORY LTD.
4 | AIRBAS TRANSPORTATION FZE
5 | AL FIDA INTERNATIONAL GENERAL TRADING
6 | AL HILAL EXCHANGE
7 | AL MASHREQ INVESTMENT FUND
8 | ALLAN GRANGE FARM
9 | AMIN INVESTMENT BANK
10 | ATC LTD.
11 | AUCHENBURG FARM
12 | Abby Allbright
13 | Abd al-Rahman Al-Faqih
14 | Abdulbaqi Mohammed Khaled
15 | Abraham Pedroso
16 | Abu Bakr Yunis Jabir
17 | Abu Zaid Dorda
18 | Adan Grief
19 | Adelina Capobianco
20 | Adelina Royston
21 | Adena Ammon
22 | Adena Giraud
23 | Adena Tye
24 | Adrian Petri
25 | Adriane Schade
26 | Adrianna Falcone
27 | Adrianne Ballas
28 | Adriene Solorio
29 | Afton Hatter
30 | Aide Carrozza
31 | Aileen Zerangue
32 | Al Aburto
33 | Alan Dipiazza
34 | Alan Gabriel
35 | Alane Sondag
36 | Alberta Thackston
37 | Albertha Etheredge
38 | Albertina Michaux
39 | Alda Bullen
40 | Alejandra Corner
41 | Aleta Verdin
42 | Alfred Franceschini
43 | Ali Orellana
44 | Alicia Rusnak
45 | Alina Negron
46 | Alix Killion
47 | Alix Sprouse
48 | Allan Dymond
49 | Allegra Victorian
50 | Allena Earnest
51 | Alline Lamy
52 | Allyson Fleener
53 | Alma Hoehne
54 | Alma Kamm
55 | Almeta Cropper
56 | Alona Braga
57 | Alpha Horsman
58 | Alvina Wingerter
59 | Alysha Rosenow
60 | Alyssa Cermak
61 | Ambrose Braud
62 | Amina Brunson
63 | Amira Campoverde
64 | Amparo Harrah
65 | Anabel Babcock
66 | Anabel Ogles
67 | Anabel Reta
68 | Analisa Borge
69 | Anastacia Trepanier
70 | Andrea Spano
71 | Andria Morell
72 | Andria Zelman
73 | Andy Pulsifer
74 | Andy Yates
75 | Angelo Konecny
76 | Angie Elrod
77 | Anisa Bring
78 | Anja Hallum
79 | Ann Rogers
80 | Annalee Dees
81 | Annalisa Villavicencio
82 | Annamarie Hanline
83 | Anneliese Waterbury
84 | Annemarie Raphael
85 | Annita Silver
86 | Anthony Ung
87 | Antione Fortenberry
88 | Antoinette Gregory
89 | Antonina Auger
90 | Antonio Ford
91 | April Elsen
92 | Aracely Southward
93 | Arcelia White
94 | Ardella Blackston
95 | Ardelle Sabbagh
96 | Arianne Oathout
97 | Arica Boehmer
98 | Arlean Kantor
99 | Arleen Klassen
100 | Arlena Lavallee
101 | Arlene Warn
102 | Arlie Nylander
103 | Arlie Schaller
104 | Armanda Stalls
105 | Armida Kohout
106 | Artie Stanford
107 | Arvilla Marquess
108 | Asha Kaiser
109 | Ashanti Haigler
110 | Ashlea Nachman
111 | Ashli Rhynes
112 | Asia Lemanski
113 | Asia Mikesell
114 | Athena Nimmons
115 | Audie Michalik
116 | Audrea Eisen
117 | Audria Gassett
118 | Aura Maus
119 | Aurore Buckland
120 | Avery Fall
121 | Azzie Packett
122 | BAMBOO CREEK FARM
123 | BEHSAZ KASHANE TEHRAN CONSTRUCTION CO.
124 | BENA PROPERTIES
125 | BOURNE FARM
126 | BUKAVU AVIATION TRANSPORT
127 | BUSINESS AIR SERVICES
128 | Babette Heyd
129 | Bao Tomblin
130 | Barb Tribble
131 | Bari Dorris
132 | Bart Edberg
133 | Barton Cossette
134 | Barton Simo
135 | Beatrice Loeb
136 | Beatris Duane
137 | Becky Garrard
138 | Belkis Poff
139 | Benita Oquendo
140 | Benjamin Severe
141 | Benny Voisin
142 | Bernadine Hakala
143 | Bernadine Kentner
144 | Bernardina Lockard
145 | Bernardine Huson
146 | Berta Claeys
147 | Beryl Rothwell
148 | Bessie Ortiz
149 | Beth Hammond
150 | Bethany Reid
151 | Betty Hundt
152 | Beverly Bumgardner
153 | Billy Chumley
154 | Billye Bolanos
155 | Billye Cullinan
156 | Blair Rhynes
157 | Blanca Rojero
158 | Blanche Worthey
159 | Blossom Gau
160 | Blossom Vandervoort
161 | Bobbie Hackler
162 | Bobby Branch
163 | Bok Kitamura
164 | Bonita Donelan
165 | Boyce Aston
166 | Boyce Brannigan
167 | Boyce Herrada
168 | Boyce Mcintyre
169 | Boyd Holmes
170 | Brad Mcfaddin
171 | Branda Headley
172 | Brande Favero
173 | Brandie Elridge
174 | Brandon Beer
175 | Brandon Crary
176 | Breanne Shira
177 | Bree Macedo
178 | Brenda Berens
179 | Brigida Svendsen
180 | Britney Vierling
181 | Brittaney Caplinger
182 | Brittaney Witcher
183 | Brook Faries
184 | Bruce Cook
185 | Brunilda Pardon
186 | Buddy Pomerleau
187 | Buford Gehling
188 | CENTRAFRICAN AIRLINES
189 | CENTRAL AFRICA DEVELOPMENT FUND
190 | CET AVIATION ENTERPRISE, FZE
191 | CHAM HOLDING
192 | CHICHAKLI & ASSOCIATES PLLC
193 | COLD COMFORT FARM TRUST CO-OPERATIVE
194 | CONTINUE PROFESSIONAL EDUCATION INC.
195 | CORBURN 13 FARM
196 | CYLINDER SYSTEM L.T.D.
197 | Caitlin Kiker
198 | Calista Ko
199 | Cami Rico
200 | Camila Mixon
201 | Candra Wilkie
202 | Candyce Woerner
203 | Carey Eveland
204 | Carleen Scaglione
205 | Carlena Level
206 | Carley Teed
207 | Carmen Bones
208 | Carol Capito
209 | Carri Hitch
210 | Carrie Hinson
211 | Carrie Weber
212 | Carroll Stansell
213 | Carter Bellantoni
214 | Carter Kelly
215 | Carylon Canaday
216 | Casandra Vause
217 | Casimira Urquhart
218 | Catharine Wingard
219 | Catherin Krebs
220 | Catheryn Josephs
221 | Cathryn Mateo
222 | Catrina Richert
223 | Catrina Swanigan
224 | Cecelia Wood
225 | Cedrick Fabrizio
226 | Celestina Favor
227 | Celsa Schirmer
228 | Ceola Simms
229 | Chan Simpler
230 | Chandra Grewell
231 | Chanell Aguillard
232 | Chanelle Trollinger
233 | Chang Umana
234 | Chante Gatti
235 | Charita Beckford
236 | Charlette Stutz
237 | Charlie Armstrong
238 | Charlotte Woodring
239 | Charmaine Ekhoff
240 | Chase Fiscus
241 | Chelsey Bjornson
242 | Chelsey Bushman
243 | Cher Hypolite
244 | Chere Friberg
245 | Cheryll Deems
246 | Cheyenne Abeita
247 | Chia Bumpus
248 | Chin Marrinan
249 | China Shumway
250 | Chong Zimmer
251 | Christian Board
252 | Christinia Ickes
253 | Christoper Khalil
254 | Christopher Gourdine
255 | Christy Flowers
256 | Chun Hiller
257 | Ciara Averitt
258 | Clair Holaway
259 | Claretha Lastrapes
260 | Claretta Grillo
261 | Clarisa Widrick
262 | Clarissa Acuff
263 | Classie Hartin
264 | Clemente Fulp
265 | Cleta Chaney
266 | Clifford Berry
267 | Clint Tokar
268 | Cody Acres
269 | Colby Hitt
270 | Colby Klein
271 | Coletta Harshaw
272 | Colleen Palmer
273 | Collin Murnane
274 | Consuela Gisi
275 | Contessa Tisby
276 | Cora Fidler
277 | Coralee Vargas
278 | Cordia Oubre
279 | Coreen Ruble
280 | Corine Charette
281 | Corinna Tejera
282 | Corliss Ducker
283 | Cornelius Sobotka
284 | Corrine Fulcher
285 | Cortez Haggard
286 | Craig Robbins
287 | Cris Mayo
288 | Criselda Claggett
289 | Cristen Suddeth
290 | Cristi Michalec
291 | Crystle Schuh
292 | Cuc Levalley
293 | Curt Montiel
294 | Cyrstal Heasley
295 | DAYTONA POOLS, INC.
296 | DBARDI, S.A. DE C.V.
297 | DHH ENTERPRISES, INC.
298 | Daisey Symonds
299 | Dale Bright
300 | Dalia Greenberg
301 | Dalila Nakamura
302 | Dallas Klatt
303 | Damian Soller
304 | Dana Kisling
305 | Danica Mcdonalds
306 | Daniele Hagen
307 | Danika Hixon
308 | Danna Ciesielski
309 | Danny Harpe
310 | Dante Budzinski
311 | Dante Tankersley
312 | Danuta Hennessey
313 | Dara Seng
314 | Darcel Seymore
315 | Darci Telfer
316 | Darin Peters
317 | Darin Villanveva
318 | Darlena Ying
319 | Daron Tavarez
320 | Darrick Archer
321 | Darron Swindell
322 | Darryl Joseph
323 | Darwin Eure
324 | Davina Lukas
325 | Dayle Kyzer
326 | Deana Gaona
327 | Deann Wormley
328 | Debbra Lamorte
329 | Debera Auten
330 | Deeann Speaker
331 | Deeanna Vannatter
332 | Delena Mcgreevy
333 | Delfina Roses
334 | Delinda Wedel
335 | Della Aston
336 | Delmar Larocco
337 | Delora Courser
338 | Delpha Loughman
339 | Delta Crumbley
340 | Delta Griffie
341 | Demetra Blumstein
342 | Demetra Sutphin
343 | Denice Quan
344 | Denna Lones
345 | Dennise Arce
346 | Denver Bonier
347 | Deshawn Guardiola
348 | Desirae Twitchell
349 | Desmond Gravely
350 | Dewey Fox
351 | Diana Hutchens
352 | Dianna Linsley
353 | Dick Highfield
354 | Diego Newnam
355 | Dieman Abdulkadir Izzat
356 | Digna Radke
357 | Dione Shumpert
358 | Dionne Mair
359 | Dolores Novick
360 | Domenica Addison
361 | Domenica Bensley
362 | Dominica Pelfrey
363 | Domitila Latch
364 | Dong Deady
365 | Dong Petree
366 | Donnie Walko
367 | Donya Ingle
368 | Doreen Myers
369 | Dorethea Plumadore
370 | Dorian Blackledge
371 | Doris Freed
372 | Doris Santos
373 | Doug Mckenney
374 | Douglas Heald
375 | Douglass Voight
376 | Doyle White
377 | Drucilla Keese
378 | Duane Sparks
379 | Dylan Kanne
380 | EIRIN FARM
381 | EXECUTION OF IMAM KHOMEINI'S ORDER
382 | EYRIE FARM
383 | Earlene Severson
384 | Earlie Barcus
385 | Earline Stotz
386 | Earnest Doxey
387 | Earnest French
388 | Eboni Hetherington
389 | Eda Bucklin
390 | Edelmira Dacosta
391 | Edelmira Wever
392 | Eden Bump
393 | Edgar Mcphee
394 | Edie Barrington
395 | Edith Saunders
396 | Edmond Hoelscher
397 | Edmundo Mcbroom
398 | Edmundo Rutledge
399 | Eduardo Terry
400 | Edwardo Ehrhardt
401 | Edwin Hassett
402 | Edwin Roehl
403 | Edyth Reitzel
404 | Ehtel Poole
405 | Elana Packard
406 | Elayne Wykoff
407 | Elden Cooley
408 | Eldridge Capella
409 | Elena Jiggetts
410 | Elenora Havlik
411 | Eleonora Jan
412 | Eleonora Salas
413 | Elia Desrosier
414 | Eliana Maddock
415 | Elias Raye
416 | Elias Schmidt
417 | Elina Capel
418 | Elinore Cordoba
419 | Elizbeth Poll
420 | Ellie Jin
421 | Ellis Baskins
422 | Ellis Heckman
423 | Elly Miguez
424 | Ellyn Mahar
425 | Elmira Ohara
426 | Elmira Prall
427 | Elodia Gruner
428 | Elodia Mchargue
429 | Elsy Owenby
430 | Elva Penfield
431 | Elvia Rittenberry
432 | Elvie Enriguez
433 | Elvie Ryant
434 | Elyse Yingling
435 | Ema Ostler
436 | Emelia Camper
437 | Emelia Nye
438 | Emilee Carrick
439 | Emilee Stringham
440 | Emilia Wachter
441 | Emilio Matthews
442 | Emmett Lane
443 | Emmy Cedeno
444 | Enda Poissant
445 | Enid Novack
446 | Enrique Gonzales
447 | Era Gilstrap
448 | Erasmo Fellman
449 | Eric Rotenberry
450 | Erika Millner
451 | Erika Welty
452 | Erin Kyles
453 | Erlene Tibbetts
454 | Esmeralda Mishoe
455 | Estella Mccollom
456 | Ester Ayotte
457 | Esther Hollowell
458 | Estrella Oshaughnessy
459 | Ethel Castilla
460 | Ethel Greenwood
461 | Eufemia Hu
462 | Eufemia Rabon
463 | Eugene Collins
464 | Eula Stober
465 | Euna Salvo
466 | Eunice Prado
467 | Eura Schutt
468 | Evangelina Selders
469 | Evelia Mahi
470 | Evelyn Angel
471 | Evelynn Rockwell
472 | Evelynn Weatherhead
473 | Everett Ross
474 | Everette Profit
475 | Evita Hottle
476 | Exie Hinchman
477 | Exie Uribe
478 | Ezequiel Flicker
479 | FOUNTAIN FARM
480 | Fae Albanese
481 | Fannie Richardson
482 | Farrah Ingalls
483 | Fay Buttner
484 | Faye Huges
485 | Faye Oquendo
486 | Felipa Esqueda
487 | Felipa Shirkey
488 | Felipe Falgout
489 | Fernanda Steimle
490 | Fernande Debose
491 | Fernande Ganley
492 | Fidela Palazzolo
493 | Filomena Degregorio
494 | Florentino Noss
495 | Florine Bonk
496 | Florine Icenhour
497 | Florrie Willard
498 | Flossie Ledoux
499 | Floy Dollins
500 | Fran Cabezas
501 | Fran Charley
502 | Francesca Vo
503 | Francesco Brickman
504 | Francoise Mccreery
505 | Frederic Eleby
506 | Fredric Esteban
507 | Fumiko Connolly
508 | GAMBIA NEW MILLENIUM AIR COMPANY
509 | GOLDEN RESOURCES TRADING COMPANY L.L.C.
510 | GOWRIE FARM
511 | GRUPO CONSTRUCTOR SEGUNDO MILENIO, S.A. DE C.V.
512 | GRUPO FRACSA, S.A. DE C.V.
513 | Galen Wilde
514 | Garnett Coniglio
515 | Garret Monahan
516 | Garth Hudock
517 | Gary Kendall
518 | Gaynelle Boyer
519 | Gaynelle Emmerich
520 | Gemma Doutt
521 | Genevie Mcdevitt
522 | Geoffrey Page
523 | Georgene Brunelle
524 | Georgene Mccaul
525 | Georgiana Shear
526 | Georgina Tuley
527 | Gerald Darden
528 | Gerald Gatti
529 | Gerda Hord
530 | German Mcquillan
531 | Gertrude Dew
532 | Gertrudis Scudder
533 | Gertude Ouellette
534 | Gertude Resch
535 | Ghuma And'Rabbah
536 | Gia Mcgonigal
537 | Gidget Palumbo
538 | Gigi Stirling
539 | Gina Kitchell
540 | Giovanna Aguila
541 | Gisela Magnusson
542 | Gisela Quijas
543 | Giselle Roark
544 | Giuseppe Jawad
545 | Gladis Broe
546 | Glady Caul
547 | Glady Howery
548 | Glen Hartlage
549 | Glendora Ryerson
550 | Goldie Viger
551 | Gordon Arndt
552 | Grady Thoman
553 | Graig Bonn
554 | Granville Mizrahi
555 | Gretta Beane
556 | Grisel Lasso
557 | Guillermo Kimball
558 | Gwenda Ashlock
559 | HARMONY FARM
560 | HESONG TRADING CORPORATION
561 | Hank Doggett
562 | Hannibal Gaddafi
563 | Harold James
564 | Harvey Edelman
565 | Hassan Cheever
566 | Hattie Shellenberger
567 | Hattie Velasco
568 | Hayden Swindler
569 | Hazel Lefebure
570 | Heather Holland
571 | Heather Rieser
572 | Hedwig Studdard
573 | Helga Sherrick
574 | Hellen Gelinas
575 | Henrietta Tippens
576 | Heriberto Palmore
577 | Herminia Davies
578 | Hershel Galligan
579 | Herta Pucci
580 | Herta Singh
581 | Hilma Gioia
582 | Hoa Bayer
583 | Hope Frankel
584 | Horace King
585 | Howard Tropea
586 | Hsiu Vargas
587 | Humberto Arrowood
588 | Hung Bomba
589 | Hyo Deavers
590 | Hyo Demario
591 | IB OF AMERICA HOLDINGS INC.
592 | INMOBILIARIA PROMINENTE, S.A. DE C.V.
593 | IRAN & SHARGH COMPANY
594 | IRAN & SHARGH LEASING COMPANY
595 | IRBIS AIR COMPANY
596 | Ibrahim Mohamed Khalil
597 | Ida Liggett
598 | Iesha Cambridge
599 | Iesha Keely
600 | Ignacia Gorley
601 | Ileen Gallop
602 | Ilene Pedigo
603 | Iliana Kinzer
604 | Ilona Hermes
605 | Imogene Poplin
606 | In Lowy
607 | Inez Rodgers
608 | Inga Lemieux
609 | Ione Azcona
610 | Irena Clayborne
611 | Irma Lamb
612 | Isabel Hubbard
613 | Isabel Tongue
614 | Isabell Blann
615 | Isabell Charland
616 | Isabella Carlyle
617 | Isabelle Ponton
618 | Isaias Relyea
619 | Isis Siler
620 | Jacinto Echeverria
621 | Jacque Sellars
622 | Jade Stuhr
623 | Jaime Rencher
624 | Jalisa Hudgens
625 | Jamee Guida
626 | Jamee Hassan
627 | Jamison Greenhalgh
628 | Jammie Glines
629 | Jan Love
630 | Jana Clarke
631 | Janell Brumbaugh
632 | Janelle Hudson
633 | Janelle Im
634 | Janetta Fanelli
635 | Janis Straus
636 | Jannie Hesser
637 | Jared Gomez
638 | Jarred Knoblock
639 | Jayne Lavery
640 | Jayne Taunton
641 | Jayson Selig
642 | Jean Bernardo
643 | Jeane Strobel
644 | Jeanette Schuett
645 | Jeanie Lebeau
646 | Jeanie Titcomb
647 | Jeannette Norman
648 | Jenae Hartung
649 | Jenifer Blankenbaker
650 | Jeniffer Stark
651 | Jennette Weems
652 | Jennie Gorsuch
653 | Jennine Tekulve
654 | Jeremiah Phinney
655 | Jeremy Garner
656 | Jeri Battiste
657 | Jerica Joerling
658 | Jerilyn Kluth
659 | Jerlene Foss
660 | Jerlene Schmitmeyer
661 | Jermaine Keaton
662 | Jerome Parsons
663 | Jerry Bartlett
664 | Jesica Castellanos
665 | Jetta Byford
666 | Jettie Weast
667 | Joann Abril
668 | Joannie Roesch
669 | Jodee Ellisor
670 | Jodee Mateer
671 | Jodi Mcglamery
672 | Jodie Compos
673 | Joel Kuta
674 | Joella Mercedes
675 | Joelle Faires
676 | Joesph Poor
677 | John Gilmore
678 | Johnna Engstrom
679 | Johnnie Shortt
680 | Joi Engen
681 | Joleen Pardon
682 | Jolyn Friel
683 | Jolynn Ausmus
684 | Jona Nease
685 | Jonas Wesner
686 | Joni Cromley
687 | Joni Mundell
688 | Jonnie Powley
689 | Jonnie Shives
690 | Joselyn Regal
691 | Joseph Poole
692 | Josue Casillas
693 | Joy Barham
694 | Joy Statler
695 | Joye Camilleri
696 | Juan Cota
697 | Juana Sharma
698 | Jules Cisneros
699 | Jules Mcnab
700 | Julian Hill
701 | Juliane Taggert
702 | Julie Spurrier
703 | Junior Prock
704 | Junita Pasch
705 | KOREA COMPLEX EQUIPMENT IMPORT CORPORATION
706 | KOREA INTERNATIONAL CHEMICAL JOINT VENTURE COMPANY
707 | KOREA KWANGSONG TRADING CORPORATION
708 | KOREA PUGANG TRADING CORPORATION
709 | KOREA RYONGWANG TRADING CORPORATION
710 | KOREA RYONHA MACHINERY JOINT VENTURE CORPORATION
711 | Ka Hinkson
712 | Kai Hermosillo
713 | Kaitlin Fetterman
714 | Kaitlyn Sowell
715 | Kali Pyron
716 | Kalyn Kearney
717 | Kamchybek Asanbekovich Kolbayew
718 | Kandice Bailer
719 | Kanisha Flicker
720 | Karan Albus
721 | Karan Renfrew
722 | Karen Frappier
723 | Kari Aguilar
724 | Karima Albers
725 | Karima Klingensmith
726 | Karina Laughton
727 | Karla Ahner
728 | Karla Harper
729 | Karol Such
730 | Karoline Fogg
731 | Karolyn Dibernardo
732 | Karri Pierre
733 | Kassie Mcquillan
734 | Kassie Viruet
735 | Katelin Zurita
736 | Katharina Snuggs
737 | Katharine Ledezma
738 | Kathe Cronkhite
739 | Katherina Yuan
740 | Katherine Terpstra
741 | Katheryn Langston
742 | Kathleen Meserve
743 | Kathlyn Swigert
744 | Kathrin Leininger
745 | Kathryne Catledge
746 | Kati Kirkendoll
747 | Katie Landman
748 | Kattie Strickland
749 | Kay Kelly
750 | Kaycee Gamber
751 | Kayla Cannon
752 | Keeley Valdivia
753 | Keesha Tsosie
754 | Keiko Holtz
755 | Keith Bates
756 | Keith Galati
757 | Kellie Alejandro
758 | Kellye Spagnola
759 | Kelsey Relf
760 | Kelsie Wescott
761 | Kenya Plum
762 | Kerstin Ditzler
763 | Kesha Yerby
764 | Keva Walk
765 | Keven Mahaney
766 | Kim Higgins
767 | Kimberlie Burrowes
768 | Kimberlie Highfield
769 | Kirsten Hakala
770 | Kit Haug
771 | Kittie Gleason
772 | Kitty Arakaki
773 | Klara Summer
774 | Kortney Morel
775 | Kory Varela
776 | Kris Diemer
777 | Krista Bedoya
778 | Kristi Hibner
779 | Kristian Hermann
780 | Kristie Bynum
781 | Kristie Chi
782 | Kristina Loggins
783 | Kristina Ritz
784 | Kristyn Wroten
785 | Krystina Varden
786 | Kyle Morency
787 | Kyra Karp
788 | LOCHINVAR FARM
789 | LONGWOOD FARM
790 | LOTHAIN FARM
791 | Laci Coots
792 | Lakeisha Klug
793 | Lamonica Mcelwain
794 | Lana Gaylord
795 | Lana Plourde
796 | Lane Dufner
797 | Lane Lundin
798 | Lani Creasman
799 | Lannie Arens
800 | Lara Laning
801 | Lashaunda Browning
802 | Latarsha Fulmore
803 | Latia Napolitano
804 | Latonya Shellman
805 | Latosha Sax
806 | Latrice Goewey
807 | Latricia Sacks
808 | Launa Milbourn
809 | Laurena Rackley
810 | Laurette Violet
811 | Lavada Lamborn
812 | Lavenia Romanowski
813 | Lavon Greggs
814 | Lean Wire
815 | Leann Aikins
816 | Leann Kail
817 | Lecia Gossage
818 | Leena Donley
819 | Leia Gillan
820 | Leila Addison
821 | Lekisha Chavous
822 | Len Romero
823 | Lena Comacho
824 | Lena Fuller
825 | Leo Bomar
826 | Leonard Galeano
827 | Leonel Spradley
828 | Leonor Ahn
829 | Leopoldo Woolbright
830 | Lesley Pettit
831 | Leslie Vanduyn
832 | Lessie Derosier
833 | Lessie Plewa
834 | Leticia Burgess
835 | Letisha Niles
836 | Lexie Wilmore
837 | Lezlie Menjivar
838 | Liane Waterfield
839 | Librada Heineman
840 | Lien Matley
841 | Lillia Ramon
842 | Lillian Murdock
843 | Lillie Blake
844 | Lilly Vandermeulen
845 | Lincoln Scipio
846 | Linda Hansen
847 | Lindsay Furlong
848 | Lindsey Brackman
849 | Lindsey Stowell
850 | Ling Kerekes
851 | Linwood Boyden
852 | Lisa Lorance
853 | Lisabeth Patricia
854 | Lise Rampton
855 | Liza Brokaw
856 | Lizabeth Mayor
857 | Lizabeth Winsett
858 | Lola Geronimo
859 | Lola Lepine
860 | Lon Shafer
861 | Lonnie Lally
862 | Loralee Goodlow
863 | Loreen Raysor
864 | Lorelei Ruis
865 | Lorene Vanburen
866 | Lori Ropp
867 | Loria Nasser
868 | Lorinda Anglin
869 | Lorine Engelke
870 | Loris Hitchman
871 | Lorna Lovin
872 | Lorraine Wiltsie
873 | Lottie Mccrystal
874 | Lou Wyrick
875 | Louisa Norgard
876 | Lourdes Kellems
877 | Louvenia Lukens
878 | Loyd Demoss
879 | Luana Dowdle
880 | Lucas Eargle
881 | Lucinda Alexander
882 | Lucio Loftus
883 | Ludie Rook
884 | Luella Sawyer
885 | Luetta Mcclenton
886 | Luis Franklin
887 | Luise Kozel
888 | Luke Figueroa
889 | Lulu Clements
890 | Luther Chambers
891 | Luvenia Lundahl
892 | Lynda Maust
893 | Lyndsey Dolloff
894 | MARANGE RESOURCES (PRIVATE) LIMITED
895 | MARONDERA MAPLE LEAF FARM
896 | MBADA DIAMONDS (PRIVATE) LIMITED
897 | MCS ENGINEERING
898 | MCS INTERNATIONAL GMBH
899 | MELLAT INSURANCE COMPANY
900 | MODABER
901 | MOLDTRANSAVIA SRL
902 | Ma Okane
903 | Machelle Benes
904 | Macie Marois
905 | Mack Soucy
906 | Maddie Benally
907 | Madelene Delillo
908 | Madeline Hannah
909 | Madelyn Vashon
910 | Madlyn Pittard
911 | Mafalda Joaquin
912 | Magaly Ange
913 | Maggie Beaubien
914 | Maida Goodpaster
915 | Maida Syed
916 | Malisa Ezell
917 | Mallory Blystone
918 | Man Davilla
919 | Manual Finneran
920 | Manual Shao
921 | Maranda Kern
922 | Marc Mcclain
923 | Marcela Herbert
924 | Marcelina Newlin
925 | Marcelle Rhee
926 | Marg Salinas
927 | Margaret Cruz
928 | Margaret Mick
929 | Margarette Lucy
930 | Margery Jewett
931 | Margit Sober
932 | Margorie Acre
933 | Margot Bruhn
934 | Marguerita Racine
935 | Marguerite Yahn
936 | Marhta Franke
937 | Mariana Weatherholtz
938 | Marianna Stjacques
939 | Maricruz Tassin
940 | Mariela Bones
941 | Marietta Bugbee
942 | Marilyn Root
943 | Marinda Leavens
944 | Mario Hightower
945 | Mario Kanne
946 | Marisa Kingsland
947 | Marlana Gartrell
948 | Marleen Gainer
949 | Marlen Cyr
950 | Marlen Doshier
951 | Marlen Gregory
952 | Marlin Chunn
953 | Marlin Housel
954 | Marlin Miesner
955 | Marnie Verne
956 | Marquita Reck
957 | Marquitta Anker
958 | Marry Bradley
959 | Marshall Freeland
960 | Marshall Horsey
961 | Marshall Spece
962 | Marta Schutte
963 | Martine Haislip
964 | Marty Minjarez
965 | Mary Carpenter
966 | Maryanna Kerrigan
967 | Maryanna Loera
968 | Maryjane Cracraft
969 | Maryjo Twine
970 | Marylou Matlock
971 | Marylyn Knicely
972 | Maryrose Isherwood
973 | Matha Fey
974 | Mathew Joachim
975 | Mathilde Mcnaughton
976 | Matuq Mohammed Matuq
977 | Maud Goldberger
978 | Maureen Kilman
979 | Maxie Byfield
980 | Maxima Bachus
981 | Maybell Aldape
982 | Mayme Nevarez
983 | Maynard Wysocki
984 | Mayola Mccallon
985 | Mckinley Blom
986 | Meghan Pangburn
987 | Meghann Brezinski
988 | Mei Delman
989 | Melani Blundell
990 | Melina Karr
991 | Melony Eichelberger
992 | Melvin Vanburen
993 | Meredith Hauge
994 | Meri Eury
995 | Meri Morley
996 | Meridith Arends
997 | Merle Freeman
998 | Merlin Mai
999 | Merlyn Bauman
1000 | Mi Clinton
1001 | Mi Kneeland
1002 | Mi Reiter
1003 | Michale Iadarola
1004 | Michele Garcia
1005 | Miesha James
1006 | Mikaela Gaymon
1007 | Miki Lally
1008 | Mila Moretz
1009 | Milagros Corlew
1010 | Milly Judon
1011 | Milton Bade
1012 | Mina Suriel
1013 | Minh Spurlock
1014 | Miquel Redden
1015 | Miquel Thibeaux
1016 | Mira Konopka
1017 | Miranda Hohn
1018 | Mireille Knox
1019 | Miss Sokol
1020 | Mistie Killgore
1021 | Mitch Venable
1022 | Mitch Vieira
1023 | Mitchell Deland
1024 | Mitsue Pinnock
1025 | Mohammad Charboneau
1026 | Mollie Lacroix
1027 | Morris Miles
1028 | Mose Weyandt
1029 | Moshe Leisy
1030 | Mozella Stott
1031 | Mozelle Ehrlich
1032 | Muhammad Gaddafi
1033 | Myra Curtis
1034 | Myrna Schroth
1035 | Myrtle Fitzgerald
1036 | NDLOVU MOTORWAYS
1037 | NORDIC LTD.
1038 | Nadene Benzing
1039 | Nadene Fodor
1040 | Nadine Parker
1041 | Nadine Slevin
1042 | Nakesha Liang
1043 | Nam Witt
1044 | Nan Iliff
1045 | Nana Boyter
1046 | Nancy Myricks
1047 | Nancy Silvis
1048 | Nanette Northrop
1049 | Nannette Bellone
1050 | Nannie Statton
1051 | Napoleon Dorsett
1052 | Natalie Balli
1053 | Natashia Stanfield
1054 | Neal Wehner
1055 | Nedra Corchado
1056 | Neida Harring
1057 | Nellie Colon
1058 | Nellie Langone
1059 | Neoma Preston
1060 | Neta Fergus
1061 | Neville Vanover
1062 | Nguyet Featherston
1063 | Nia Nadal
1064 | Nick Trapp
1065 | Nicolas Barnett
1066 | Nicolette Sutphin
1067 | Nicolle Molock
1068 | Nida Infantino
1069 | Nida Jumper
1070 | Niesha Munro
1071 | Nilda Haight
1072 | Noel Cairns
1073 | Noelle Costa
1074 | Nohemi Schriver
1075 | Norene Ang
1076 | Nu Portman
1077 | ODESSA AIR
1078 | OLDHAM FARM
1079 | OMID REY CIVIL & CONSTRUCTION COMPANY
1080 | ORIENT STAR CORPORATION
1081 | Octavia Good
1082 | Octavia Overcash
1083 | Odilia Vitale
1084 | Ofelia Haapala
1085 | Ola Power
1086 | Olimpia Pawlak
1087 | Olin Coomer
1088 | Oma Crutcher
1089 | Oneida Grover
1090 | Orville Haar
1091 | Osvaldo Thornsberry
1092 | Otilia Decola
1093 | Owen Maresca
1094 | Ozella Cavallaro
1095 | PARDIS INVESTMENT COMPANY
1096 | PETRO LONDON, S. DE R.L. DE C.V.
1097 | PETRO MAS, S. DE R.L. DE C.V.
1098 | PIMENTO FARM
1099 | PISCILANEA, S.A. DE C.V.
1100 | PROMI FEL, S. DE R.L. DE C.V.
1101 | Paige Burkhead
1102 | Paige Herzog
1103 | Pamala Marsden
1104 | Pamela Joyner
1105 | Paola Villalta
1106 | Parthenia Gries
1107 | Particia Ferrante
1108 | Patria Boyer
1109 | Patrica Josey
1110 | Patsy Faz
1111 | Patti Hines
1112 | Paulette Thornton
1113 | Paulina Matsumoto
1114 | Pedro Roldan
1115 | Peggie Easler
1116 | Peggy Borunda
1117 | Pei Christian
1118 | Peter Dineen
1119 | Phil Hopkins
1120 | Phil Stalling
1121 | Philip Henderson
1122 | Ping Fujimoto
1123 | Piper Cayetano
1124 | Providencia Styles
1125 | Qiana Connally
1126 | Quincy Cupp
1127 | Quincy Macrae
1128 | Quincy Racette
1129 | Quinn Clingan
1130 | Quintin Elmendorf
1131 | Quinton Fox
1132 | R/E OF AUDREY FARM
1133 | R/E OF MLEMBWE FARM
1134 | RESTAURANT BAR LOS ANDARIEGOS, S.A. DE C.V.
1135 | REY INVESTMENT COMPANY
1136 | REYCO GMBH.
1137 | RICHARD A. CHICHAKLI PC
1138 | RISHMAK PRODUCTIVE & EXPORTS COMPANY
1139 | ROCKMAN LTD.
1140 | Rachel Fisher
1141 | Rachelle Scrivens
1142 | Racquel Master
1143 | Racquel Sattler
1144 | Rafael Jefferson
1145 | Rafik Mohamad Yousef
1146 | Raisa Vandeventer
1147 | Ralph Cedeno
1148 | Rana Westra
1149 | Randall Madson
1150 | Randall Sayers
1151 | Raphael Thorsen
1152 | Raul Fleetwood
1153 | Ray Miera
1154 | Raye Stenzel
1155 | Rayford Tapscott
1156 | Raymond Barrett
1157 | Raymond Lux
1158 | Raymond Myatt
1159 | Rayna Felter
1160 | Rayna Sampsell
1161 | Rebbeca Vineyard
1162 | Regena Steier
1163 | Reginia Cortes
1164 | Reid Bickers
1165 | Reid Hyndman
1166 | Reina Alberson
1167 | Reina Poff
1168 | Reinaldo Soderberg
1169 | Reita Lindo
1170 | Remona Benninger
1171 | Remona Gullette
1172 | Remona Landaverde
1173 | Renee Townsend
1174 | Renna Bookman
1175 | Retha Crater
1176 | Reva Willey
1177 | Rex Wesley
1178 | Rhoda Heyer
1179 | Rhoda Ormond
1180 | Richard Hayes
1181 | Rickey Flores
1182 | Ricky Koepsell
1183 | Rima Farwell
1184 | Rima Meadors
1185 | Rivka Kehr
1186 | Robbie Drost
1187 | Robby Mckinnie
1188 | Rochel Demers
1189 | Rochel Krause
1190 | Rocio Doom
1191 | Rodney Kershner
1192 | Rodolfo Hazelton
1193 | Rolanda Debellis
1194 | Rolanda Kreider
1195 | Rolanda Marriner
1196 | Ron Farnum
1197 | Rona Moulton
1198 | Rosalia Penrose
1199 | Rosalinda Meals
1200 | Rosamaria Bibbs
1201 | Roseann Booher
1202 | Roseann Frierson
1203 | Roseanna Weil
1204 | Roseanne Anselmo
1205 | Roselee Dandy
1206 | Rosena Giraldo
1207 | Rosena Montero
1208 | Rosenda Tilson
1209 | Roslyn Deckman
1210 | Ross Medlen
1211 | Rossie Singleterry
1212 | Roxana Alt
1213 | Roxane Holliman
1214 | Roxie Spieker
1215 | Roxy Gertsch
1216 | Rudolph Stransky
1217 | Rueben Fouch
1218 | Rusty Briski
1219 | Rusty Klein
1220 | Ryan Kitson
1221 | SAN AIR GENERAL TRADING FZE
1222 | SANTA CRUZ IMPERIAL AIRLINES
1223 | SERVICIO Y OPERADORA SANTA ANA, S.A. DE C.V.
1224 | SOUTHBOUND LTD.
1225 | SPRING SP FARM
1226 | SYRIAN AIR FORCE INTELLIGENCE
1227 | SYRIAN MILITARY INTELLIGENCE
1228 | SYRIAN NATIONAL SECURITY BUREAU
1229 | Saadi Gaddafi
1230 | Sabina Privette
1231 | Sabine Stelly
1232 | Sabrina Shahid
1233 | Sadie Martinez
1234 | Sadye Heidenreich
1235 | Sadye Shott
1236 | Safia Farkash
1237 | Saif Al-Arab Gaddafi
1238 | Sajid Mohammed Badat
1239 | Sal Munz
1240 | Salley Zenon
1241 | Samantha Chute
1242 | Samara Neher
1243 | Samira Stocking
1244 | Sammy Wheeler
1245 | Samual Groh
1246 | Sandi Hoopes
1247 | Sanora Polk
1248 | Santana Holte
1249 | Santiago Reese
1250 | Santos Hadnot
1251 | Saran Kingrey
1252 | Sari Busey
1253 | Sasha Bona
1254 | Sasha Layfield
1255 | Sasha Mckenney
1256 | Savannah Morfin
1257 | Scot Stlawrence
1258 | Sean Bragan
1259 | Sean Weaver
1260 | Seema Carcamo
1261 | Serita Migliore
1262 | Shalanda Linson
1263 | Shalon Dutil
1264 | Shanae Roepke
1265 | Shanel Albury
1266 | Shanel Lavine
1267 | Shantelle Liberatore
1268 | Shanti Briant
1269 | Sharee Hoppe
1270 | Sharice Jeter
1271 | Sharla Saenz
1272 | Sharon Claycomb
1273 | Sharron Mash
1274 | Shaun Munyon
1275 | Shauna Garst
1276 | Shavon Levron
1277 | Shawanda Thaler
1278 | Shawna Sheppard
1279 | Shawna Sorrels
1280 | Shawnna Deeds
1281 | Shayne Moreau
1282 | Sheila Hodges
1283 | Sheilah Kindell
1284 | Shela Karns
1285 | Shelton Copper
1286 | Sherie Rodriguz
1287 | Sherley Markowitz
1288 | Sherly Foraker
1289 | Sherrell Watkins
1290 | Sherron Rosenberger
1291 | Sherwood Mason
1292 | Shirl Stumbo
1293 | Shirlee Haskin
1294 | Shizuko Blais
1295 | Shizuko Faller
1296 | Shon Denbow
1297 | Shoshana Chauncey
1298 | Shoshana Golston
1299 | Sid Armand
1300 | Sid Rule
1301 | Siobhan Gammon
1302 | Sirena Cothran
1303 | Slyvia Factor
1304 | Solomon Blanchard
1305 | Stacy Camire
1306 | Stan Shelman
1307 | Stanley Lamers
1308 | Stefania Koster
1309 | Stefanie Surles
1310 | Stephan Bridgers
1311 | Stephani Umstead
1312 | Stephen Millet
1313 | Stephen Schacherer
1314 | Steven Langford
1315 | Summer Schieber
1316 | Susana Kloss
1317 | Susannah Patenaude
1318 | Susie Sturgis
1319 | Suzann Dewoody
1320 | Suzann Sessions
1321 | Suzanne Husain
1322 | Suzi Mcneel
1323 | TADBIR BROKERAGE COMPANY
1324 | TADBIR CONSTRUCTION DEVELOPMENT COMPANY
1325 | TADBIR ECONOMIC DEVELOPMENT GROUP
1326 | TADBIR ENERGY DEVELOPMENT GROUP CO.
1327 | TADBIR INVESTMENT COMPANY
1328 | TAXI AEREO NACIONAL DE CULIACAN, S.A.
1329 | TOSEE EQTESAD AYANDEHSAZAN COMPANY
1330 | TOSONG TECHNOLOGY TRADING CORPORATION
1331 | TRANS AVIATION GLOBAL GROUP INC.
1332 | Tabitha Eriksen
1333 | Tabitha Larson
1334 | Tahir Nasuf
1335 | Tai Maus
1336 | Tajuana Farlow
1337 | Tajuana Hunsaker
1338 | Talia Gaitan
1339 | Talia Gamino
1340 | Tam Cola
1341 | Tamara Dedman
1342 | Tammera Mestas
1343 | Tammie Macpherson
1344 | Taneka Plumber
1345 | Tanisha Mcshane
1346 | Tanja Tarbox
1347 | Tara Mcguire
1348 | Tarah Renwick
1349 | Taren Pusey
1350 | Tari Carstarphen
1351 | Tarra Denmon
1352 | Tatum Weimer
1353 | Tayna Mossman
1354 | Tayna Pakele
1355 | Temeka Olivares
1356 | Tempie Costello
1357 | Tempie Gabrielson
1358 | Tena Ardis
1359 | Tenesha Reichert
1360 | Tennille Licon
1361 | Teresa Wada
1362 | Terisa Frisch
1363 | Terrence Greaver
1364 | Terrence Wise
1365 | Terresa Klassen
1366 | Terry Hogan
1367 | Thalia Paine
1368 | Thanh Kirsh
1369 | Thelma Collar
1370 | Theodora Veasley
1371 | Theodore Wright
1372 | Therese Dye
1373 | Therese Gearing
1374 | Theressa Cabello
1375 | Thi Hilger
1376 | Tiana Fazio
1377 | Tiara Osorio
1378 | Tiera Hassler
1379 | Tiera Markus
1380 | Tifany Cornell
1381 | Tiffani Lozada
1382 | Tiffanie Boozer
1383 | Tisa Rolls
1384 | Tobie Amend
1385 | Tomas Dubiel
1386 | Tomas Griffin
1387 | Tomeka Bolden
1388 | Tomeka Mcwain
1389 | Tomika Gates
1390 | Tomiko Doetsch
1391 | Tommy Rivera
1392 | Tonette Poovey
1393 | Tonie Pier
1394 | Tonita Marti
1395 | Tonja Rinehart
1396 | Tony Garibay
1397 | Toshia Barkan
1398 | Tracee Averitt
1399 | Trang Thomas
1400 | Treasa Fryer
1401 | Treena Man
1402 | Trevor Platz
1403 | Trey Hung
1404 | Trista Rahman
1405 | Twana Falkner
1406 | Tyson Reaux
1407 | ULVA FARM
1408 | UMGUZA BLOCK FARM
1409 | VILLAS DEL COLLI S.A. DE C.V.
1410 | Valene Longerbeam
1411 | Valentin Gerlach
1412 | Valerie Soto
1413 | Valery Shuey
1414 | Vallie Ping
1415 | Vallie Sweat
1416 | Van Balla
1417 | Vashti Tew
1418 | Velma Hawkins
1419 | Velva Ehrman
1420 | Vena Riter
1421 | Vena Stubbs
1422 | Venetta Borchers
1423 | Venus Datta
1424 | Vera Fryer
1425 | Verena Horowitz
1426 | Verline Bautista
1427 | Verna Boyd
1428 | Vernie Boger
1429 | Vertie Manzi
1430 | Vesta Sylvest
1431 | Veta Laguardia
1432 | Vickie Parton
1433 | Vicky Donadio
1434 | Victor Mcgee
1435 | Victorina Grillo
1436 | Vina Walck
1437 | Vincenza Henkle
1438 | Viola Phelps
1439 | Viola Procter
1440 | Viva Stivers
1441 | Vivian Moody
1442 | Von Unsworth
1443 | Vonda Schlabach
1444 | Wanda Greenough
1445 | Wanita Wait
1446 | Warren Perez
1447 | Waylon Hoff
1448 | Wei Demaio
1449 | Weldon Newberg
1450 | Wendell Nelson
1451 | Wendell Ulman
1452 | Wesley Panek
1453 | Wesley Teamer
1454 | Weston Canning
1455 | Weston Ealey
1456 | Weston Haynie
1457 | Whitney Grimaldi
1458 | Wilber Obermiller
1459 | Wilbert Murphy
1460 | Wilfred Cartwright
1461 | William Glover
1462 | Williams Armitage
1463 | Willie Castleman
1464 | Willie Mack
1465 | Willow Goldenberg
1466 | Windy Ferrer
1467 | Winford Roller
1468 | Winnifred Swearingen
1469 | Wynona Obryant
1470 | Xenia Gaulding
1471 | YK-AQA
1472 | YK-AQB
1473 | YK-AQD
1474 | YK-AQE
1475 | YK-AQF
1476 | YK-AQG
1477 | YK-AYA
1478 | YK-AYB
1479 | YK-AYC
1480 | YK-AYD
1481 | YK-AYE
1482 | YK-AYF
1483 | Yasser Abu
1484 | Yer Lohse
1485 | Yevette Clendenin
1486 | Yoko Guebert
1487 | Yolando Droz
1488 | Yuk Hornyak
1489 | Yung Roda
1490 | Yuri Boyster
1491 | ZARIN RAFSANJAN CEMENT COMPANY
1492 | Zachariah Galyon
1493 | Zachariah Leeson
1494 | Zada Tison
1495 | Zelma Bluhm
1496 | Zenobia Chouinard
1497 | Zola Cearley
1498 | Zulma Armbruster
1499 | Zulma Bolton
1500 | Zulma Colger
--------------------------------------------------------------------------------
/spring-batch-scalability/src/main/webapp/WEB-INF/spring/webmvc-config.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
12 |
13 |
14 |
15 |
19 |
20 |
21 |
22 |
23 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/spring-batch-scalability/src/main/webapp/WEB-INF/views/home.jsp:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Spring Batch Samples - scalability
5 |
6 |
7 |
8 |
70 |
71 |
72 |
73 |
79 |
80 |
92 |
93 |
94 |
95 |
96 |
--------------------------------------------------------------------------------
/spring-batch-scalability/src/main/webapp/WEB-INF/web.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
9 | contextConfigLocation
10 | classpath*:META-INF/spring/applicationContext.xml
11 |
12 |
13 |
14 | spring.profiles.active
15 | prod
16 |
17 |
18 |
19 | org.springframework.web.context.ContextLoaderListener
20 |
21 |
22 |
23 | dispatcher-servlet
24 | org.springframework.web.servlet.DispatcherServlet
25 |
26 | contextConfigLocation
27 | /WEB-INF/spring/webmvc-config.xml
28 |
29 | 1
30 | true
31 |
32 |
33 |
34 | dispatcher-servlet
35 | /
36 |
37 |
38 |
39 | My DataSource Reference
40 | jdbc/DS
41 | javax.sql.DataSource
42 | Container
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/spring-batch-scalability/src/test/java/com/ontheserverside/batch/bank/job/Elixir0LoadStepTest.java:
--------------------------------------------------------------------------------
1 | package com.ontheserverside.batch.bank.job;
2 |
3 | import com.ontheserverside.batch.bank.tx.Elixir0Transaction;
4 | import com.ontheserverside.batch.bank.tx.TransactionStatus;
5 | import org.hibernate.SessionFactory;
6 | import org.hibernate.criterion.Order;
7 | import org.junit.Test;
8 | import org.junit.runner.RunWith;
9 | import org.springframework.batch.core.*;
10 | import org.springframework.batch.test.JobLauncherTestUtils;
11 | import org.springframework.beans.factory.annotation.Autowired;
12 | import org.springframework.context.annotation.Bean;
13 | import org.springframework.context.annotation.ComponentScan;
14 | import org.springframework.context.annotation.Configuration;
15 | import org.springframework.context.annotation.ImportResource;
16 | import org.springframework.core.task.TaskExecutor;
17 | import org.springframework.integration.Message;
18 | import org.springframework.integration.MessageChannel;
19 | import org.springframework.integration.channel.AbstractPollableChannel;
20 | import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
21 | import org.springframework.test.context.ActiveProfiles;
22 | import org.springframework.test.context.ContextConfiguration;
23 | import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
24 |
25 | import java.math.BigDecimal;
26 | import java.text.SimpleDateFormat;
27 | import java.util.List;
28 |
29 | import static org.hamcrest.CoreMatchers.is;
30 | import static org.junit.Assert.assertThat;
31 |
32 | @RunWith(SpringJUnit4ClassRunner.class)
33 | @ContextConfiguration
34 | @ActiveProfiles("test")
35 | public class Elixir0LoadStepTest {
36 |
37 | @Configuration
38 | @ComponentScan("com.ontheserverside.batch.bank")
39 | @ImportResource({ "classpath:/META-INF/spring/hibernateContext.xml",
40 | "classpath:/META-INF/spring/batchContext.xml" })
41 | static class ApplicationContext {
42 | @Bean
43 | public JobLauncherTestUtils jobLauncherTestUtils() {
44 | return new JobLauncherTestUtils();
45 | }
46 |
47 | @Bean
48 | public TaskExecutor executor() {
49 | return new ThreadPoolTaskExecutor();
50 | }
51 |
52 | @Bean(name = { "screening.requests.partitioning",
53 | "screening.replies.partitioning"})
54 | public MessageChannel channels() {
55 | return new AbstractPollableChannel() {
56 | @Override
57 | protected Message> doReceive(long timeout) {
58 | throw new UnsupportedOperationException("I'm just mocked test channel");
59 | }
60 |
61 | @Override
62 | protected boolean doSend(Message> message, long timeout) {
63 | throw new UnsupportedOperationException("I'm just mocked test channel");
64 | }
65 | };
66 | }
67 | }
68 |
69 | @Autowired
70 | private JobLauncherTestUtils jobLauncherTestUtils;
71 |
72 | @Autowired
73 | private SessionFactory sessionFactory;
74 |
75 | @Test
76 | public void shouldLoadElixir0TxFromFile() throws Exception {
77 | final JobParameters jobParameters = new JobParametersBuilder()
78 | .addString("inputFile", this.getClass().getResource("/elixir0/5Tx.elixir0").getPath())
79 | .toJobParameters();
80 |
81 | final JobExecution jobExecution = jobLauncherTestUtils.launchStep("elixir0LoadStep", jobParameters);
82 |
83 | final StepExecution stepExecution = jobExecution.getStepExecutions().iterator().next();
84 | assertThat(stepExecution.getExitStatus(), is(ExitStatus.COMPLETED));
85 | assertThat(stepExecution.getStatus(), is(BatchStatus.COMPLETED));
86 | assertThat(stepExecution.getReadCount(), is(5)); // 5 is a number of TX in the imported file
87 | assertThat(stepExecution.getWriteCount(), is(5));
88 |
89 | final List importedTransactions =
90 | sessionFactory.openSession()
91 | .createCriteria(Elixir0Transaction.class)
92 | .addOrder(Order.asc("paymentDate"))
93 | .list();
94 | assertThat(importedTransactions.size(), is(5));
95 |
96 | // we'll test mapping of the representative transaction, the rest can be proved by induction ;-)
97 | final Elixir0Transaction transaction = importedTransactions.get(0);
98 | assertThat(transaction.getStatus(), is(TransactionStatus.LOADED));
99 | assertThat(transaction.getPaymentCode(), is(110));
100 | assertThat(transaction.getPaymentDate().getTime(), is(new SimpleDateFormat("yyyyMMdd").parse("20140212").getTime()));
101 | assertThat(transaction.getAmount().compareTo(BigDecimal.valueOf(828749700184127L)), is(0));
102 | assertThat(transaction.getOrderingPartySortCode(), is("68578953"));
103 | assertThat(transaction.getOrderingPartyAccountNumber(), is("87685789534046696210183491"));
104 | assertThat(transaction.getBeneficiaryAccountNumber(), is("81878754069967016032059101"));
105 | assertThat(transaction.getOrderingPartyName(), is("SOUTHBOUND LTD."));
106 | assertThat(transaction.getOrderingPartyAddress(), is("8876 Harvest Leaf Harbour, Fighting Rock Corner, Maryland, 21069-9972, US"));
107 | assertThat(transaction.getBeneficiaryName(), is("Vincenza Henkle"));
108 | assertThat(transaction.getBeneficiaryAddress(), is("4489 Sunny Hickory Terrace, Enderby, Iowa, 50157-9431, US"));
109 | assertThat(transaction.getBeneficiarySortCode(), is("87875406"));
110 | assertThat(transaction.getPaymentDetails(), is("passkey deleaves rimmed sarsens sponsor"));
111 | assertThat(transaction.getTransactionCode(), is("51"));
112 | assertThat(transaction.getClientBankInformation(), is(""));
113 | }
114 | }
115 |
--------------------------------------------------------------------------------
/spring-batch-scalability/src/test/java/com/ontheserverside/batch/bank/processing/JobParameterExecutionDeciderTest.java:
--------------------------------------------------------------------------------
1 | package com.ontheserverside.batch.bank.processing;
2 |
3 | import org.junit.Before;
4 | import org.junit.Test;
5 | import org.springframework.batch.core.JobExecution;
6 | import org.springframework.batch.core.JobParameters;
7 | import org.springframework.batch.core.JobParametersBuilder;
8 | import org.springframework.batch.core.StepExecution;
9 | import org.springframework.batch.core.job.flow.FlowExecutionStatus;
10 |
11 | import static org.hamcrest.CoreMatchers.is;
12 | import static org.hamcrest.CoreMatchers.not;
13 | import static org.hamcrest.CoreMatchers.nullValue;
14 | import static org.junit.Assert.assertThat;
15 |
16 | public class JobParameterExecutionDeciderTest {
17 |
18 | private static final String JOB_PARAMETER_KEY = "someFancyKey";
19 |
20 | private JobParameterExecutionDecider decider;
21 |
22 | @Before
23 | public void setUp() {
24 | this.decider = new JobParameterExecutionDecider();
25 | decider.setJobParameterKey(JOB_PARAMETER_KEY);
26 | }
27 |
28 | @Test
29 | public void shouldReturnFlowStatusFromJobParameter() {
30 | JobParameters jobParameters = new JobParametersBuilder()
31 | .addString(JOB_PARAMETER_KEY, "PUFF")
32 | .toJobParameters();
33 |
34 | JobExecution jobExecution = new JobExecution(1L, jobParameters);
35 | StepExecution stepExecution = new StepExecution("myStep", jobExecution);
36 |
37 | final FlowExecutionStatus flowExecutionStatus = decider.decide(jobExecution, stepExecution);
38 |
39 | assertThat(flowExecutionStatus, is(not(nullValue())));
40 | assertThat(flowExecutionStatus, is(new FlowExecutionStatus("PUFF")));
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/spring-batch-scalability/src/test/java/com/ontheserverside/batch/bank/processing/ModuloPartitionerTest.java:
--------------------------------------------------------------------------------
1 | package com.ontheserverside.batch.bank.processing;
2 |
3 | import org.junit.Before;
4 | import org.junit.Test;
5 | import org.springframework.batch.item.ExecutionContext;
6 |
7 | import java.util.Map;
8 |
9 | import static org.hamcrest.CoreMatchers.is;
10 | import static org.hamcrest.CoreMatchers.not;
11 | import static org.hamcrest.CoreMatchers.nullValue;
12 | import static org.junit.Assert.assertThat;
13 |
14 | public class ModuloPartitionerTest {
15 |
16 | private ModuloPartitioner partitioner;
17 |
18 | @Before
19 | public void setUp() {
20 | this.partitioner = new ModuloPartitioner();
21 | }
22 |
23 | @Test
24 | public void shouldProduceNoContextspForZeroSizeGrid() {
25 | Map map = partitioner.partition(0);
26 |
27 | assertThat(map, is(not(nullValue())));
28 | assertThat(map.isEmpty(), is(true));
29 | }
30 |
31 | @Test
32 | public void shouldProduceContextsForNonEmptyGrid() {
33 | Map map = partitioner.partition(3);
34 |
35 | assertThat(map, is(not(nullValue())));
36 | assertThat(map.size(), is(3));
37 |
38 | ExecutionContext context0 = map.get("partition-0");
39 | ExecutionContext context1 = map.get("partition-1");
40 | ExecutionContext context2 = map.get("partition-2");
41 |
42 | assertThat(context0, is(not(nullValue())));
43 | assertThat(context1, is(not(nullValue())));
44 | assertThat(context2, is(not(nullValue())));
45 |
46 | assertThat((int) context0.get(ModuloPartitioner.MOD_REMAINDER_KEY), is(0));
47 | assertThat((int) context1.get(ModuloPartitioner.MOD_REMAINDER_KEY), is(1));
48 | assertThat((int) context2.get(ModuloPartitioner.MOD_REMAINDER_KEY), is(2));
49 |
50 | assertThat((int) context0.get(ModuloPartitioner.MOD_DIVISOR_KEY), is(3));
51 | assertThat((int) context1.get(ModuloPartitioner.MOD_DIVISOR_KEY), is(3));
52 | assertThat((int) context2.get(ModuloPartitioner.MOD_DIVISOR_KEY), is(3));
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/spring-batch-scalability/src/test/java/com/ontheserverside/batch/bank/screening/JaroBagFuzzyMatcherTest.java:
--------------------------------------------------------------------------------
1 | package com.ontheserverside.batch.bank.screening;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.hamcrest.CoreMatchers.is;
6 | import static org.junit.Assert.assertThat;
7 |
8 | /**
9 | * Group of tests used to adjust sensitivity factors of metrics - we don't want to test framework here, huh? ;)
10 | */
11 | public class JaroBagFuzzyMatcherTest {
12 |
13 | private JaroBagFuzzyMatcher matcher = new JaroBagFuzzyMatcher();
14 |
15 | @Test
16 | public void shouldNotConsiderWordsOrder() {
17 | assertThat(matcher.sequencesMatching("conan the conqueror", "the conqueror conan"), is(true));
18 | }
19 |
20 | @Test
21 | public void shouldBeCaseInsensitive() {
22 | assertThat(matcher.sequencesMatching("john rambo", "JOHN RAMBO"), is(true));
23 | }
24 |
25 | @Test
26 | public void shouldMatchForOneLetterTypos() {
27 | assertThat(matcher.sequencesMatching("jovn rambo", "john rambo"), is(true));
28 | assertThat(matcher.sequencesMatching("john rampo", "john rambo"), is(true));
29 | }
30 |
31 | @Test
32 | public void shouldMatchForOneLetterMissing() {
33 | assertThat(matcher.sequencesMatching("conan the onqueror", "conan the conqueror"), is(true));
34 | assertThat(matcher.sequencesMatching("coan the conqueror", "conan the conqueror"), is(true));
35 | }
36 |
37 | @Test
38 | public void shouldMatchForOneLetterAdded() {
39 | assertThat(matcher.sequencesMatching("terrorist", "terroristt"), is(true));
40 | assertThat(matcher.sequencesMatching("bomb", "bombb"), is(true));
41 | assertThat(matcher.sequencesMatching("my new gun", "my new gunn"), is(true));
42 | assertThat(matcher.sequencesMatching("gun", "gunn"), is(true));
43 | }
44 |
45 | @Test
46 | public void shouldMatchForOneLetterMisplaced() {
47 | assertThat(matcher.sequencesMatching("conna the conqueror", "conan the conqueror"), is(true));
48 | assertThat(matcher.sequencesMatching("conan the ocnqueror", "conan the conqueror"), is(true));
49 | }
50 |
51 | @Test
52 | public void shouldMatchForOneLetterTypoAndDifferentWordsOrder() {
53 | assertThat(matcher.sequencesMatching("rambo jovn", "john rambo"), is(true));
54 | assertThat(matcher.sequencesMatching("rampo john", "john rambo"), is(true));
55 | }
56 |
57 | @Test
58 | public void shouldMatchForOneLetterMissingAndDifferentWordsOrder() {
59 | assertThat(matcher.sequencesMatching("the brbarian conan", "conan the barbarian"), is(true));
60 | assertThat(matcher.sequencesMatching("barbarian conan th", "conan the barbarian"), is(true));
61 | }
62 |
63 | @Test
64 | public void shouldMatchForOneLetterMisplacedAndDifferentWordsOrder() {
65 | assertThat(matcher.sequencesMatching("the cnoan conqueror", "conan the conqueror"), is(true));
66 | assertThat(matcher.sequencesMatching("conan ocnqueror the", "conan the conqueror"), is(true));
67 | }
68 |
69 | @Test
70 | public void shouldNotMatchForDifferentWords() {
71 | // it's hard do define what "different words" are in terms of fuzzy matching;
72 | // this test (as well as all others within this class) should be considered just
73 | // as a way to adjust sensitivity factors of metrics
74 | assertThat(matcher.sequencesMatching("bombai", "bomb"), is(false));
75 | assertThat(matcher.sequencesMatching("attack", "attention"), is(false));
76 | assertThat(matcher.sequencesMatching("taliban", "talisman"), is(false));
77 | assertThat(matcher.sequencesMatching("nuclear", "uncle"), is(false));
78 | assertThat(matcher.sequencesMatching("gun", "gunner"), is(false));
79 | assertThat(matcher.sequencesMatching("uranium", "uranus"), is(false));
80 | assertThat(matcher.sequencesMatching("matshalaga", "matha"), is(false));
81 | }
82 |
83 | @Test
84 | public void shouldNotMatchForDifferentWordPhrases() {
85 | // just like in case of the test above, it's hard to define what "different phrases"
86 | // means in terms of fuzzy matching; this test should be also considered just as a way
87 | // to adjust sensitivity factors of metrics
88 | assertThat(matcher.sequencesMatching("matha fey", "matshalaga obert"), is(false));
89 | assertThat(matcher.sequencesMatching("tahir nasuf", "taghtiran pjs"), is(false));
90 | assertThat(matcher.sequencesMatching("sal munz", "mupenzi bernard"), is(false));
91 | assertThat(matcher.sequencesMatching("lochinvar farm", "farmacia la colina"), is(false));
92 | }
93 |
94 | @Test
95 | public void shouldNotConsiderNonAlphanumericCharacters() {
96 | assertThat(matcher.sequencesMatching("t,e,r,r,o,r,i,s,t", "terrorist"), is(true));
97 | }
98 | }
99 |
--------------------------------------------------------------------------------
/spring-batch-scalability/src/test/java/com/ontheserverside/batch/bank/screening/SanctionScreeningProcessorTest.java:
--------------------------------------------------------------------------------
1 | package com.ontheserverside.batch.bank.screening;
2 |
3 | import com.ontheserverside.batch.bank.tx.Elixir0Transaction;
4 | import org.junit.Before;
5 | import org.junit.Test;
6 | import org.springframework.test.util.ReflectionTestUtils;
7 |
8 | import java.util.LinkedList;
9 | import java.util.List;
10 |
11 | import static org.easymock.EasyMock.createMock;
12 | import static org.easymock.EasyMock.expect;
13 | import static org.easymock.EasyMock.replay;
14 | import static org.easymock.EasyMock.verify;
15 | import static org.hamcrest.CoreMatchers.is;
16 | import static org.hamcrest.CoreMatchers.not;
17 | import static org.hamcrest.CoreMatchers.nullValue;
18 | import static org.junit.Assert.assertThat;
19 |
20 | public class SanctionScreeningProcessorTest {
21 |
22 | private static final String BENEFICIARY_NAME = "Brandon Beer";
23 | private static final String ORDERING_PARTY_NAME = "Marcelle Rhee";
24 | private static final String BENEFICIARY_ADDRESS_FULL = "Sienkiewicza 10 Kielce Poland";
25 | private static final String ORDERING_PARTY_ADDRESS_FULL = "Meerschweinchen Platz 10 Berlin Germany";
26 |
27 | private static final String SDN_ENTITY_NAME = "Daniele Hagen";
28 | private static final String SDN_ENTITY_ALTERNATE_NAME = "Melanie Blundell";
29 | private static final String SDN_ENTITY_ADDRESS = "Sunnyside 13C";
30 | private static final String SDN_ENTITY_CITY = "New York";
31 | private static final String SDN_ENTITY_COUNTRY = "USA";
32 | private static final String SDN_ENTITY_ADDRESS_FULL = "Sunnyside 13C New York USA";
33 |
34 | private FuzzyMatcher mockFuzzyMatcher;
35 |
36 | private SanctionScreeningProcessor processor;
37 |
38 | private SanctionScreeningContext context;
39 |
40 | @Before
41 | public void setUp() {
42 | this.mockFuzzyMatcher = createMock(FuzzyMatcher.class);
43 | this.processor = new SanctionScreeningProcessor();
44 | ReflectionTestUtils.setField(processor, "fuzzyMatcher", mockFuzzyMatcher);
45 |
46 | Elixir0Transaction transaction = new Elixir0Transaction();
47 | transaction.setBeneficiaryName(BENEFICIARY_NAME);
48 | transaction.setBeneficiaryAddress(BENEFICIARY_ADDRESS_FULL);
49 | transaction.setOrderingPartyName(ORDERING_PARTY_NAME);
50 | transaction.setOrderingPartyAddress(ORDERING_PARTY_ADDRESS_FULL);
51 |
52 | SDNEntity.SDNAddress sdnAddress = new SDNEntity.SDNAddress(SDN_ENTITY_ADDRESS, SDN_ENTITY_CITY, SDN_ENTITY_COUNTRY);
53 | List sdnAddresses = new LinkedList<>();
54 | sdnAddresses.add(sdnAddress);
55 |
56 | List sdnAlternateNames = new LinkedList<>();
57 | sdnAlternateNames.add(SDN_ENTITY_ALTERNATE_NAME);
58 |
59 | SDNEntity sdnEntity = new SDNEntity(SDN_ENTITY_NAME, sdnAddresses, sdnAlternateNames);
60 |
61 | this.context = new SanctionScreeningContext(transaction, sdnEntity);
62 | }
63 |
64 | @Test
65 | public void shouldMatchSanctionForBeneficaryName() {
66 | expect(mockFuzzyMatcher.sequencesMatching(BENEFICIARY_NAME, SDN_ENTITY_NAME)).andReturn(true);
67 | replay(mockFuzzyMatcher);
68 |
69 | final SanctionMatch match = processor.process(context);
70 |
71 | verify(mockFuzzyMatcher);
72 | assertSanctionMatched(match);
73 | }
74 |
75 | @Test
76 | public void shouldMatchSanctionForOrderingPartyName() {
77 | expect(mockFuzzyMatcher.sequencesMatching(BENEFICIARY_NAME, SDN_ENTITY_NAME)).andReturn(false);
78 | expect(mockFuzzyMatcher.sequencesMatching(ORDERING_PARTY_NAME, SDN_ENTITY_NAME)).andReturn(true);
79 | replay(mockFuzzyMatcher);
80 |
81 | final SanctionMatch match = processor.process(context);
82 |
83 | verify(mockFuzzyMatcher);
84 | assertSanctionMatched(match);
85 | }
86 |
87 | @Test
88 | public void shouldMatchSanctionForBeneficiaryAddress() {
89 | expect(mockFuzzyMatcher.sequencesMatching(BENEFICIARY_NAME, SDN_ENTITY_NAME)).andReturn(false);
90 | expect(mockFuzzyMatcher.sequencesMatching(ORDERING_PARTY_NAME, SDN_ENTITY_NAME)).andReturn(false);
91 | expect(mockFuzzyMatcher.sequencesMatching(BENEFICIARY_ADDRESS_FULL, SDN_ENTITY_ADDRESS_FULL)).andReturn(true);
92 | replay(mockFuzzyMatcher);
93 |
94 | final SanctionMatch match = processor.process(context);
95 |
96 | verify(mockFuzzyMatcher);
97 | assertSanctionMatched(match);
98 | }
99 |
100 | @Test
101 | public void shouldMatchSanctionForOrderingPartyAddress() {
102 | expect(mockFuzzyMatcher.sequencesMatching(BENEFICIARY_NAME, SDN_ENTITY_NAME)).andReturn(false);
103 | expect(mockFuzzyMatcher.sequencesMatching(ORDERING_PARTY_NAME, SDN_ENTITY_NAME)).andReturn(false);
104 | expect(mockFuzzyMatcher.sequencesMatching(BENEFICIARY_ADDRESS_FULL, SDN_ENTITY_ADDRESS_FULL)).andReturn(false);
105 | expect(mockFuzzyMatcher.sequencesMatching(ORDERING_PARTY_ADDRESS_FULL, SDN_ENTITY_ADDRESS_FULL)).andReturn(true);
106 | replay(mockFuzzyMatcher);
107 |
108 | final SanctionMatch match = processor.process(context);
109 |
110 | verify(mockFuzzyMatcher);
111 | assertSanctionMatched(match);
112 | }
113 |
114 | @Test
115 | public void shouldMatchSanctionForBeneficiaryAlternateName() {
116 | expect(mockFuzzyMatcher.sequencesMatching(BENEFICIARY_NAME, SDN_ENTITY_NAME)).andReturn(false);
117 | expect(mockFuzzyMatcher.sequencesMatching(ORDERING_PARTY_NAME, SDN_ENTITY_NAME)).andReturn(false);
118 | expect(mockFuzzyMatcher.sequencesMatching(BENEFICIARY_ADDRESS_FULL, SDN_ENTITY_ADDRESS_FULL)).andReturn(false);
119 | expect(mockFuzzyMatcher.sequencesMatching(ORDERING_PARTY_ADDRESS_FULL, SDN_ENTITY_ADDRESS_FULL)).andReturn(false);
120 | expect(mockFuzzyMatcher.sequencesMatching(BENEFICIARY_NAME, SDN_ENTITY_ALTERNATE_NAME)).andReturn(true);
121 | replay(mockFuzzyMatcher);
122 |
123 | final SanctionMatch match = processor.process(context);
124 |
125 | verify(mockFuzzyMatcher);
126 | assertSanctionMatched(match);
127 | }
128 |
129 | @Test
130 | public void shouldMatchSanctionForOrderingPartyAlternateName() {
131 | expect(mockFuzzyMatcher.sequencesMatching(BENEFICIARY_NAME, SDN_ENTITY_NAME)).andReturn(false);
132 | expect(mockFuzzyMatcher.sequencesMatching(ORDERING_PARTY_NAME, SDN_ENTITY_NAME)).andReturn(false);
133 | expect(mockFuzzyMatcher.sequencesMatching(BENEFICIARY_ADDRESS_FULL, SDN_ENTITY_ADDRESS_FULL)).andReturn(false);
134 | expect(mockFuzzyMatcher.sequencesMatching(ORDERING_PARTY_ADDRESS_FULL, SDN_ENTITY_ADDRESS_FULL)).andReturn(false);
135 | expect(mockFuzzyMatcher.sequencesMatching(BENEFICIARY_NAME, SDN_ENTITY_ALTERNATE_NAME)).andReturn(false);
136 | expect(mockFuzzyMatcher.sequencesMatching(ORDERING_PARTY_NAME, SDN_ENTITY_ALTERNATE_NAME)).andReturn(true);
137 | replay(mockFuzzyMatcher);
138 |
139 | final SanctionMatch match = processor.process(context);
140 |
141 | verify(mockFuzzyMatcher);
142 | assertSanctionMatched(match);
143 | }
144 |
145 | @Test
146 | public void shouldNotWarnWhenSDNIsNotMatching() {
147 | expect(mockFuzzyMatcher.sequencesMatching(BENEFICIARY_NAME, SDN_ENTITY_NAME)).andReturn(false);
148 | expect(mockFuzzyMatcher.sequencesMatching(ORDERING_PARTY_NAME, SDN_ENTITY_NAME)).andReturn(false);
149 | expect(mockFuzzyMatcher.sequencesMatching(BENEFICIARY_ADDRESS_FULL, SDN_ENTITY_ADDRESS_FULL)).andReturn(false);
150 | expect(mockFuzzyMatcher.sequencesMatching(ORDERING_PARTY_ADDRESS_FULL, SDN_ENTITY_ADDRESS_FULL)).andReturn(false);
151 | expect(mockFuzzyMatcher.sequencesMatching(BENEFICIARY_NAME, SDN_ENTITY_ALTERNATE_NAME)).andReturn(false);
152 | expect(mockFuzzyMatcher.sequencesMatching(ORDERING_PARTY_NAME, SDN_ENTITY_ALTERNATE_NAME)).andReturn(false);
153 | replay(mockFuzzyMatcher);
154 |
155 | final SanctionMatch match = processor.process(context);
156 |
157 | verify(mockFuzzyMatcher);
158 | assertThat(match, is(nullValue()));
159 | }
160 |
161 | private void assertSanctionMatched(final SanctionMatch match) {
162 | assertThat(match, is(not(nullValue())));
163 | assertThat(match.getSdnEntity(), is(context.getSdnEntity()));
164 | assertThat(match.getTransaction(), is(context.getTransaction()));
165 | }
166 | }
167 |
--------------------------------------------------------------------------------
/spring-batch-scalability/src/test/resources/elixir0/5Tx.elixir0:
--------------------------------------------------------------------------------
1 | 110,20140212,828749700184127,68578953,0,"87685789534046696210183491","81878754069967016032059101","SOUTHBOUND LTD.|8876 Harvest Leaf Harbour, Fighting Rock Corner, Maryland, 21069-9972, US","Vincenza Henkle|4489 Sunny Hickory Terrace, Enderby, Iowa, 50157-9431, US",0,87875406,"passkey deleaves rimmed sarsens sponsor",,,"51",
2 | 110,20140213,755630840255762,28853259,0,"23288532597190914003754934","91516297662112552760987574","Brandon Beer|6822 Amber Landing, The Black Cat, Kansas, 67889-2191, US","Bernardina Lockard|4608 Velvet Elk Boulevard, Gnaw Bone, District of Columbia, 20038-6201, US",0,51629766,"candida abasia millage",,,"51",
3 | 110,20140214,376940880227580,64619795,0,"69646197957014147272359008","50293167282244484554930786","Marcelle Rhee|3943 Pleasant Plaza, Uncle Sam, Arizona, 85565-6408, US","Nan Iliff|5784 Crystal Villas, Freeze, Michigan, 49662-9562, US",0,29316728,"outraged unfrocks choanae vividest pant",,,"51",
4 | 110,20140215,91114132441329,33161821,0,"20331618211296712712480029","2940308962994003559139606","Daniele Hagen|5257 Silent Range, Eighty Four, Oregon, 97408-9448, US","Myrna Schroth|4608 Velvet Elk Boulevard, Gnaw Bone, District of Columbia, 20038-6201, US",0,94030896,"mantlet",,,"51",
5 | 110,20140216,970869239262078,30035007,0,"2300350075447436145403143","12752321065837035161948168","Melani Blundell|5784 Crystal Villas, Freeze, Michigan, 49662-9562, US","SANTA CRUZ IMPERIAL AIRLINES|1709 Emerald Stead, Swisher, Yukon, Y0E-9S9, CA",0,75232106,"circlet lampoon hectare velocity",,,"51",
--------------------------------------------------------------------------------