...
Interest
...
of
...
a
...
buffering
...
system
...
A
...
captcha
...
(picture
...
or
...
sound)
...
needs
...
a
...
lot
...
of
...
computing
...
time
...
comparing
...
to
...
the
...
time
...
usually
...
required
...
to
...
generate
...
a
...
web
...
page.
...
The
...
more
...
captchas
...
are
...
hard
...
to
...
crack
...
by
...
computers,
...
the
...
more
...
it
...
takes
...
time
...
to
...
create.
...
Conceptual
...
solution
...
Pre
...
generating
...
captcha
...
can
...
prevent
...
web
...
site
...
overloading.
...
Considering
...
the
...
need,
...
there
...
is
...
two
...
possible
...
solutions:
...
- Captchas
...
- can
...
- be
...
- stored
...
- in
...
- volatile
...
- memory
...
- to
...
- prevent
...
- overload,
...
- this
...
- solution
...
- fits
...
- well
...
- for
...
- quick
...
- response
...
- time
...
- but
...
- require
...
- lot
...
- of
...
- RAM.
...
- Captchas
...
- can
...
- be
...
- stored
...
- in
...
- persistent
...
- memory,
...
- like
...
- database,
...
- or
...
- simple
...
- files,
...
- this
...
- solution
...
- fits
...
- well
...
- for
...
- large
...
- volume
...
- of
...
- captcha.
...
The
...
JCaptcha
...
buffering
...
system
...
implements
...
the
...
two
...
solutions
...
with
...
- scheduled
...
- captcha
...
- swapping
...
- :
...
- captcha
...
- can
...
- be
...
- automaticaly
...
- moved
...
- between
...
- buffer
...
- scheduled
...
- buffer
...
- feeding
...
- :
...
- automatic
...
- captcha
...
- generation
...
Technical
...
solution
...
A
...
component,
...
BufferedEngineContainer
...
,
...
which
...
implements
...
the
...
CaptchaEngine
...
interface,
...
produces
...
captchas
...
through
...
a
...
normal
...
captcha
...
engine.
...
It
...
uses
...
two
...
buffers;
...
one
...
to
...
store
...
captchas
...
in
...
a
...
persistent
...
way,
...
implementation
...
of
...
this
...
buffer
...
is
...
either
...
a
...
file
...
buffer
...
on
...
disk,
...
or
...
a
...
database.
...
Another
...
buffer
...
is
...
used
...
to
...
quickly
...
deliver
...
captchas;
...
this
...
is
...
implemented
...
with
...
a
...
RAM
...
buffer,
...
like
...
a
...
stack,
...
or
...
a
...
list.
...
The
...
BufferedEngineContainer
...
component
...
has
...
two
...
main
...
operations:
...
- Feeding
...
- of
...
- the
...
- persistent
...
- buffer.
...
- Swapping
...
- from
...
- the
...
- persistent
...
- buffer
...
- to
...
- the
...
- volatile
...
- buffer.
...
These
...
operations
...
are
...
controlled
...
by
...
timing
...
components.
...
JCaptcha
...
provide
...
implementations
...
of
...
timing
...
components
...
:
...
- A
...
- simple
...
- one
...
- with
...
- ClockDaemon
...
- API.
...
- A
...
- much
...
- richer
...
- one
...
- with
...
- the
...
- Quartz
...
- API.
...
At
...
least
...
but
...
not
...
last,
...
a
...
management
...
component
...
provided
...
real
...
time
...
control
...
on
...
the
...
Quartz
...
implementation:
...
- Defining
...
- the
...
- max
...
- size
...
- of
...
- both
...
- buffers
...
- Defining
...
- the
...
- number
...
- of
...
- captchas
...
- to
...
- feed
...
- the
...
- persistent
...
- buffer
...
- Defining
...
- the
...
- number
...
- of
...
- captcha
...
- to
...
- be
...
- swapped
...
- between
...
- the
...
- two
...
- buffers.
...
- Defining
...
- the
...
- time
...
- of
...
- feeding
...
- operations
...
- Defining
...
- the
...
- time
...
- of
...
- swapping
...
- operations
...
- Defining
...
- the
...
- ratio
...
- of
...
- Localized
...
- captchas
...
- (For
...
- instance:
...
- 25%
...
- of
...
- English,
...
- 75%
...
- of
...
- French
...
- ...)
...
- Stopping
...
- and
...
- starting
...
- every
...
- different
...
- operation
...
Setting
...
the
...
Captcha
...
buffering
...
system
...
in
...
Spring
...
The
...
captcha
...
buffering
...
system
...
can
...
be
...
configured
...
the
...
same
...
way
...
as
...
Captcha
...
Engines,
...
but
...
it
...
can
...
be
...
less
...
explicit
...
as
...
not
...
all
...
components
...
are
...
part
...
of
...
JCaptcha.
...
Tip | ||
---|---|---|
| ||
Some Spring configuration files are available as testing resources |
The first root component is the BufferedEngineContainer, which feed a persistent buffer and swap captchas from this buffer to a volatile buffer. So to build this component you need :
- a captcha engine, well known
- a persistent buffer, where captchas are store from mass production
- a volatile buffer, where captcha are stored just before been used
- a configuration, to set some parameters like buffers limits, feed and swap size ...
Code Block | ||||
---|---|---|---|---|
| ||||
<bean class="com.octo.captcha.engine.bufferedengine.QuartzBufferedEngineContainer" id="imageContainer" singleton="true">
<constructor-arg type="com.octo.captcha.engine.CaptchaEngine" index="0"><ref bean="imageEngine"/></constructor-arg>
<constructor-arg type="com.octo.captcha.engine.bufferedengine.buffer.CaptchaBuffer" index="1"><ref bean="imageMemBuffer"/></constructor-arg>
<constructor-arg type="com.octo.captcha.engine.bufferedengine.buffer.CaptchaBuffer" index="2"><ref bean="imagePersistantBuffer"/></constructor-arg>
<constructor-arg type="com.octo.captcha.engine.bufferedengine.ContainerConfiguration" index="3"><ref bean="imageConfiguration"/></constructor-arg>
</bean>
{code}
+ |
The
...
ContainerConfiguration
...
sets:
...
- The
...
- map
...
- of
...
- ratio
...
- corresponding
...
- to
...
- locales
...
- The
...
- maximal
...
- size
...
- of
...
- the
...
- volatile
...
- buffer
...
- The
...
- maximal
...
- size
...
- of
...
- the
...
- persistent
...
- buffer
...
- The
...
- size
...
- of
...
- the
...
- swap
...
- The
...
- size
...
- of
...
- the
...
- feed
...
- The
...
- Boolean
...
- to
...
- know
...
- if
...
- the
...
- container
...
- only
...
- serves
...
- configured
...
- locales
...
- The
...
- Default
...
- local
...
- to
...
- use
...
Code Block xml xml <bean id="imageConfiguration" class="com.octo.captcha.engine.bufferedengine.ContainerConfiguration"> <constructor-arg index="0"> <map> <entry key-ref="java.util.Locale.FRENCH" value-ref="ratioFR"/> </map> </constructor-arg> <\!--memory size--> <constructor-arg index="1"><value>1000</value></constructor-arg> <\!--persistent size--> <constructor-arg index="2"><value>100000</value></constructor-arg> <\!--swap size--> <constructor-arg index="3"><value>1000</value></constructor-arg> <\!--feed size--> <constructor-arg index="4"><value>100000</value></constructor-arg> <\!--feed batch size--> <constructor-arg index="5"><value>100</value></constructor-arg> <\!--Serve only configured locales?--> <constructor-arg index="6"><value>true</value></constructor-arg> <\!--default locale to serve--> <constructor-arg index="7"><ref bean="java.util.Locale.FRENCH"/></constructor-arg> </bean>
...
And
...
- the
...
- declaration
...
- of
...
- the
...
- map
...
- of
...
- ratio
...
- corresponding
...
- to
...
- locales
...
- uses
...
- :
...
Code Block xml xml <bean id="java.util.Locale.FRENCH" class="org.springframework.beans.factory.config.FieldRetrievingFactoryBean" /> <bean id="ratioFR" class="java.lang.Double"> <constructor-arg index="0"><value>1.0</value></constructor-arg> </bean>
...
Next
...
- we
...
- define
...
- buffers,
...
- the
...
- volatile
...
- buffer
...
- is
...
- simple:
...
Code Block xml xml <bean class="com.octo.captcha.engine.bufferedengine.buffer.MemoryCaptchaBuffer" id="imageMemBuffer"> </bean>
...
The
...
- persistant
...
- buffer
...
- can
...
- be
...
- more
...
- complex,
...
- the
...
- following
...
- sample
...
- use
...
- a
...
- database
...
- implementation,
...
- with
...
- a
...
- data
...
- source:
...
Code Block | ||||
---|---|---|---|---|
| ||||
<bean class="com.octo.captcha.engine.bufferedengine.buffer.DatabaseCaptchaBuffer" id="imagePersistantBuffer">
<constructor-arg index="0"><ref bean="dataSource"/></constructor-arg>
<!--table name-->
<constructor-arg type="java.lang.String" index="1"><value>jcaptcha_t</value></constructor-arg>
</bean>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" singleton="true">
<property name="driverClassName">
<value>org.hsqldb.jdbcDriver</value>
</property>
<property name="url">
<value>jdbc:hsqldb:jcaptchaDB</value>
</property>
<property name="username">
<value>jcaptcha</value>
</property>
<property name="password">
<value>jcaptcha</value>
</property>
</bean>
{code}
|
The
...
next
...
part
...
is
...
about
...
Quartz,
...
the
...
scheduling
...
framework.
...
We
...
first
...
define
...
a
...
Scheduler,
...
which:
...
- Start
...
- at
...
- start
...
- up
...
- of
...
- the
...
- container
...
- (tomcat/App
...
- server...)
...
- Complete
...
- a
...
- job
...
- in
...
- process
...
- when
...
- it
...
- shut
...
- down,
...
- meaning
...
- it
...
- doesn't
...
- "cut"
...
- a
...
- process
...
- Use
...
- 2
...
- triggers
...
- for
...
- the
...
- feeding
...
- operation
...
- and
...
- for
...
- the
...
- swapping
...
- operation
...
Code Block xml xml <bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean" id="imageScheduler"> <property name="autoStartup"> <value>true</value> </property> <property name="waitForJobsToCompleteOnShutdown"> <value>true</value> </property> <property name="triggers"> <list> <ref local="imageCronTriggerFeeder" /> <ref local="imageCronTriggerSwapper" /> </list> </property> </bean>
...
Each
...
- trigger
...
- are
...
- cron
...
- type,
...
- which
...
- means
...
- there
...
- use
...
- a
...
- Cron
...
- expression
...
- to
...
- define
...
- when
...
- operations
...
- have
...
- to
...
- be
...
- launch,
...
- (see
...
...
...
- ).
...
- These
...
- tow
...
- trigger
...
- use
...
- a
...
- JobDetail,
...
- because,
...
- after
...
- telling
...
- to
...
- the
...
- scheduler
...
- when
...
- to
...
- execute,
...
- we
...
- need
...
- to
...
- tell
...
- what.
...
Code Block xml xml <bean id="imageCronTriggerFeeder" class="org.springframework.scheduling.quartz.CronTriggerBean"> <property name="jobDetail"> <ref bean="imageFeederJobDetail" /> </property> <property name="cronExpression"> <value>0 * * * * ?</value> </property> </bean> <bean id="imageCronTriggerSwapper" class="org.springframework.scheduling.quartz.CronTriggerBean"> <property name="jobDetail"> <ref bean="imageSwapperJobDetail" /> </property> <property name="cronExpression"> <value>0/1 * * * * ?</value> </property> </bean>
...
As
...
- Quartz
...
- is
...
- fully
...
- intergrated
...
- in
...
- Spring,
...
- they
...
- have
...
- design
...
- a
...
- very
...
- usefull
...
- JobDetail,
...
- which
...
- launch
...
- a
...
- particular
...
- method
...
- of
...
- a
...
- bean.
...
- So
...
- both
...
- JobDetail
...
- are
...
- from
...
- this
...
- particular
...
- kind.
...
- You
...
- have
...
- to
...
- set
...
- three
...
- properties
...
- :
...
- targetObject,
...
- the
...
- component
...
- which
...
- contains
...
- the
...
- method
...
- targetMethod,
...
- the
...
- target
...
- method
...
- concurrent,
...
- Boolean
...
- to
...
- know
...
- if
...
- two
...
- job
...
- of
...
- the
...
- same
...
- kind
...
- can
...
- happen
...
- at
...
- the
...
- same
...
- time.
...
Code Block xml xml <bean id="imageFeederJobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"> <property name="targetObject"><ref bean="imageContainer"/></property> <property name="targetMethod"><value>feedPersistentBuffer</value></property> <property name="concurrent"><value>false</value></property> </bean> <!-- Constructs job detail, which invoke a precise methode from a bean.--> <bean id="imageSwapperJobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"> <property name="targetObject"><ref bean="imageContainer"/></property> <property name="targetMethod"><value>swapCaptchasFromPersistentToVolatileMemory</value></property> <property name="concurrent"><value>false</value></property> </bean>
...
A
...
- transverse,
...
- but
...
- very
...
- important,
...
- component
...
- is
...
- the
...
- ContainerManager,
...
- allowing
...
- real
...
- time
...
- management
...
- of
...
- the
...
- buffering
...
- system.
...
- The
...
- component
...
- can
...
- be
...
- exposed
...
- through
...
- JMX.
...
- It
...
- control
...
- most
...
- of
...
- components
...
- set
...
- in
...
- the
...
- upper
...
- part.
...
Code Block xml xml <bean class="com.octo.captcha.engine.bufferedengine.manager.QuartzBufferedEngineManager" id="imageContainerManager"> <constructor-arg type="com.octo.captcha.engine.bufferedengine.QuartzBufferedEngineContainer" index="0"><ref bean="imageContainer"/></constructor-arg> <constructor-arg type="org.quartz.Scheduler" index="1"><ref bean="imageScheduler"/></constructor-arg> <constructor-arg type="org.quartz.CronTrigger" index="2"><ref bean="imageCronTriggerFeeder"/></constructor-arg> <constructor-arg type="org.quartz.CronTrigger" index="3"><ref bean="imageCronTriggerSwapper"/></constructor-arg> <constructor-arg type="org.quartz.JobDetail" index="4"><ref bean="imageFeederJobDetail"/></constructor-arg> <constructor-arg type="org.quartz.JobDetail" index="5"><ref bean="imageSwapperJobDetail"/></constructor-arg> </bean>
...