Thursday, March 24, 2016
Wednesday, January 27, 2016
Software develepment and arhitecture
Here I will add links to interesting articles/blogs
What's in a Story?
The Clean Architecture
Robert C. Martin - Clean Architecture - video
How to Design a Good, Regular API
What's in a Story?
The Clean Architecture
Robert C. Martin - Clean Architecture - video
How to Design a Good, Regular API
Tuesday, November 10, 2015
Web services FAQ
Using cxf 2.7, generated wsdl contains 2 files, because interface and implementation are not in same package.
Solution annotate implementation and override targetNamespace
@WebService(targetNamespace = "om.samara.hr")
Solution annotate implementation and override targetNamespace
@WebService(targetNamespace = "om.samara.hr")
Friday, August 28, 2015
Sftp notes
Dependencies
sftp client:
org="com.jcraft" name="jsch" rev="0.1.53"
sftp server:
org="org.apache.sshd" name="sshd-core" rev="0.14.0"
org="org.apache.sshd" name="sshd-sftp" rev="0.11.0"
Ref:
http://www.jcraft.com/jsch/
https://mina.apache.org/sshd-project/
https://dzone.com/articles/spring-integration-mock-0
https://stackoverflow.com/questions/11837948/using-apache-mina-as-a-mock-in-memory-sftp-server-for-unit-testing
Wednesday, July 29, 2015
Quartz troubleshooting
Problem:
Quartz in clustered mode, nodes are sync via db.
There are many lines like these in logs:
[2015-07-04 00:00:01,620] WARN [QuartzScheduler_scheduler-prov011435933239135_ClusterManager] (JobStoreSupport.java:3298) - This scheduler instance (prov011435933239135) is still active but was recovered by another instance in the cluster. This may cause inconsistent behavior.
Ref:
http://quartz-scheduler.org/documentation/faq
Quartz in clustered mode, nodes are sync via db.
There are many lines like these in logs:
[2015-07-04 00:00:01,620] WARN [QuartzScheduler_scheduler-prov011435933239135_ClusterManager] (JobStoreSupport.java:3298) - This scheduler instance (prov011435933239135) is still active but was recovered by another instance in the cluster. This may cause inconsistent behavior.
"The most probable cause of such a cluster-related
error is having cluster nodes with system clock not synchronized."
Ref:
http://quartz-scheduler.org/documentation/faq
Tuesday, July 28, 2015
web service client
Server is returning soap fault with http status 400
SOAP UI is displaying nicely
When using cxf Java client I get strange, misleading message:
org.apache.cxf.interceptor.Fault: Could not send Message.
On server side I see everything is as expected soap fault is returned with bad request status code 400.
After little debugging I found this in org.apache.cxf.transport.http.HTTPConduit class:
// "org.apache.cxf.transport.process_fault_on_http_400" property should be set in case a
// soap fault because of a HTTP 400 should be returned back to the client (SOAP 1.2 spec)
So before making a call configure client:
Client client = ClientProxy.getClient(port); client.getBus().setProperty("org.apache.cxf.transport.process_fault_on_http_400", true);
After that I get expected exception:
Caused by: org.apache.cxf.binding.soap.SoapFault: some validation message
One more example of calling web service with Apache CXF - now within the same project I'm doing integration test with Spock and SpringBootTest.
HelloWorldWs is interface annotated with @WebService
def setup() { JaxWsProxyFactoryBean proxyFactory = new JaxWsProxyFactoryBean() proxyFactory.setServiceClass(HelloWorldWs) this.pismaUrl = "http://localhost:" + this.port + "/services/pisma"
proxyFactory.setAddress(pismaUrl) this.client = (HelloWorldWs) proxyFactory.create() Client client = ClientProxy.getClient(this.client); client.getBus().setProperty("org.apache.cxf.transport.process_fault_on_http_400", true); }
web service client example
//web service interface to be called
@WebService(targetNamespace = "http://services.crm.ticketing.samara.com", name = "ticketingServicePortTypes")
@XmlSeeAlso({ObjectFactory.class})
public interface TicketingServicePortTypes {
// web service client that was generated with wsdltojava
// This class was generated by Apache CXF 3.0.3
TicketingService extends javax.xml.ws.Service
Java client that calls TicketingService, using basic authentication with u/p.
final TicketingService service = new TicketingService(); // should be singleton
final TicketingServicePortTypes port = service.getTicketingServicePort();
javax.xml.ws.BindingProvider bp = (BindingProvider) port;
log.trace("username: " + username + ", password: " + password);
bp.getRequestContext().put(BindingProvider.USERNAME_PROPERTY, username);
bp.getRequestContext().put(BindingProvider.PASSWORD_PROPERTY, password);
bp.getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, "http://10.105.100.127:8445/");
Using spring cxf xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:task="http://www.springframework.org/schema/task" xmlns:jaxws="http://cxf.apache.org/jaxws"
xmlns:soap="http://cxf.apache.org/bindings/soap" xmlns:cxf="http://cxf.apache.org/core"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/task
http://www.springframework.org/schema/task/spring-task.xsd
http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd
http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd
http://cxf.apache.org/bindings/soap http://cxf.apache.org/schemas/configuration/soap.xsd
">
<!-- jaxws client to front end -->
<jaxws:client id="crmService"
serviceClass="com.samara.generated.crm.api.TicketingServicePortTypes"
address="${crm.url}" username="${crm.username}" password="${crm.password}">
<jaxws:binding>
<soap:soapBinding mtomEnabled="false" version="1.1" />
</jaxws:binding>
</jaxws:client>
</beans>
Monday, July 27, 2015
Generating random integers in a range
Random rand;
int randomNum = rand.nextInt((max - min) + 1) + min;
or
int randomNum = ThreadLocalRandom.current().nextInt(min, max + 1);
Ref:
stackoverflow - Generating random integers in a range with Java
Random - nextInt
Monday, July 20, 2015
Disjuction (OR operator)
Writing OR clause using criteria API.
In this case operation parameter can be passed as optional / varargs (arbitrary number of values ).
In this case operation parameter can be passed as optional / varargs (arbitrary number of values ).
private void addOperationToCriteria(Criteria criteria, SomeOperation ... operation)
{
if (operation == null)
return;
if (operation.length == 1)
criteria.add(Restrictions.eq("operation", operation[0]));
else
{
Disjunction dis = Restrictions.disjunction(); // OR
for (SomeOperation o : operation)
{
dis.add(Restrictions.eq("operation", o));
}
criteria.add(dis);
}
}
Friday, July 17, 2015
Quartz with Spring and embedded database
I'm was testing quartz at localhost with H2 embedded database.
In this case I need quartz tables prepared.
In spring config define database and wha script to load:
Example of spring 3.2 integration with quart 1.8:
Job implementation
Schedule job in real time
I'm using injected org.springframework.scheduling.quartz.SchedulerFactoryBean.
DeactivateOrderJob will be waken and it will read orderId from map.
In this case I need quartz tables prepared.
In spring config define database and wha script to load:
<jdbc:embedded-database id="dataSource" type="H2">
<jdbc:script location="classpath:recycle/quartz-h2.sql" />
</jdbc:embedded-database>
Example of spring 3.2 integration with quart 1.8:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns = "http://www.springframework.org/schema/beans"
xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
xmlns:task = "http://www.springframework.org/schema/task"
xsi:schemaLocation = "http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/task
http://www.springframework.org/schema/task/spring-task.xsd">
<!-- Setting pool to 10 threads -->
<task:scheduler id="taskScheduler" pool-size="10"/>
<!-- Scheduler -->
<bean id="scheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="configLocation" value="recycle/quartz.properties"/>
<property name="dataSource" ref="dataSource"/>
<property name="transactionManager" ref="transactionManager" />
<property name="triggers">
<list>
<ref bean="txRecycleTrigger" />
</list>
</property>
<!-- Fill the schedulerFactoryBeans scheduleContextMap with ALL spring
beans that shall be available for the Job implementations. The SpringBeanJobFactory will inject these beans into newly instantiated workers if they have a setter that corresponds to the beans key. This makes spring beans available even for (persisted and) deserialized Jobs. NOTE: This mechanism isn't supported by Spring 3.0 for the latest Quartz version 2.0.1 but for the previous version 1.8.5 -->
<property name="schedulerContextAsMap">
<map>
<entry key="recycleSimService" value-ref="RecycleSimService" />
<entry key="logEnabled" value="${job.logEnabled}" />
</map>
</property>
</bean>
<!-- Property ""MISFIRE_INSTRUCTION_FIRE_ONCE_NOW" means that The job is executed immediately after the scheduler discovers misfire situation. -->
<bean id="txRecycleTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
<property name="jobDetail" ref ="recycleSimJob" />
<property name="cronExpression" value="${job.recycleScheduler.cronExpression}" />
<property name="misfireInstructionName" value="MISFIRE_INSTRUCTION_FIRE_ONCE_NOW" />
</bean>
<bean id="recycleSimJob" class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
<property name="jobClass" value="com.samara.job.RecycleSimJob" />
</bean>
</beans>
Job implementation
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.StatefulJob;
import org.springframework.scheduling.quartz.QuartzJobBean;
public class RecycleSimJob extends QuartzJobBean implements StatefulJob
{
private transient static final Logger log = LoggerFactory.getLogger(RecycleSimJob.class);
private transient RecycleSimService recycleSimService;
@Override
protected void executeInternal(JobExecutionContext context) throws JobExecutionException
{
if (getRecycleSimService() == null)
{
log.warn("recycleSimService is not set!");
return;
}
getRecycleSimService().recycleSims(new Date());
}
public RecycleSimService getRecycleSimService()
{
return recycleSimService;
}
public void setRecycleSimService(RecycleSimService recycleSimService)
{
this.recycleSimService = recycleSimService;
}
}
Schedule job in real time
I'm using injected org.springframework.scheduling.quartz.SchedulerFactoryBean.
JobDetail jobDetail = new JobDetail("deactivation_" + orderId, DeactivateOrderJob.class);
Map<String, Long> params = new HashMap<String, Long>();
params.put("orderId", orderId);
jobDetail.setJobDataMap(new JobDataMap(params));
final SimpleTrigger simpleTrigger = new SimpleTrigger("deactivationTrigger_" + orderId, expiryTime);
schedulerFactory.getScheduler().scheduleJob(jobDetail, simpleTrigger);
DeactivateOrderJob will be waken and it will read orderId from map.
@Override
protected void executeInternal(JobExecutionContext context) throws JobExecutionException
{
Map params = context.getJobDetail().getJobDataMap();
Long orderId = (Long) params.get("orderId");
.....
}
Thursday, April 23, 2015
Moving project to git repository
I have git repo at bitbucket
- create repository on bitbucket via web UI
- go to project directory folder on your machine
- git init
- git remote add origin "URL to repo"
- eclipse (with egit plugin) - share project using git
- commit & push
Ref:
Tuesday, April 7, 2015
SELECT FOR UPDATE
We have 2 machines with active active configuration and there is table with column for counters.
Db is on 3rd machine.
How to update these columns?
Example from code:
Ref:
https://docs.jboss.org/hibernate/orm/3.3/reference/en/html/transactions.html
Db is on 3rd machine.
How to update these columns?
Example from code:
public InitialStateEntity findByIdWithLock(Long id)
{
DetachedCriteria criteria = DetachedCriteria.forClass(InitialStateEntity.class);
criteria.add(Restrictions.idEq(id));
criteria.setLockMode(LockMode.PESSIMISTIC_WRITE);
return (InitialStateEntity) criteria.getExecutableCriteria(getSession()).uniqueResult();
}
Ref:
https://docs.jboss.org/hibernate/orm/3.3/reference/en/html/transactions.html
Monday, March 23, 2015
Download file
Implemented using Spring MVC, rest service.
Display file on screen or download as attachment.
@Controller
public class FileController
{
private static final Logger log = LoggerFactory.getLogger(FileController.class);
@RequestMapping(value = "/file/{id}", method = RequestMethod.GET)
public void getFileViaAttachment(@PathVariable String id, HttpServletResponse response)
{
log.info("getFile " + id);
try
{
String content = "testing file download";
String fileName = "mojFileIzStringa.txt";
InputStream in = new ByteArrayInputStream(content.getBytes(StandardCharsets.UTF_8));
IOUtils.copy(in, response.getOutputStream());
response.setContentType("application/text");
response.setHeader("Content-Disposition", "attachment; filename=" + fileName);
response.flushBuffer();
}
catch (IOException e)
{
e.printStackTrace();
}
}
@RequestMapping(value = "/many", method = RequestMethod.GET)
public void getManyLinesViaAttachment(HttpServletResponse response)
{
log.info("getManyLines ");
try
{
String[] linesArrays = { "prva linija", "druga linija", "xxx linija" };
List<String> linesList = Arrays.asList(linesArrays);
String fileName = "mojFileSpunoLinija.csv";
IOUtils.writeLines(linesList, null, response.getOutputStream(), StandardCharsets.UTF_8);
response.setContentType("application/text");
response.setHeader("Content-Disposition", "attachment; filename=" + fileName);
response.flushBuffer();
}
catch (IOException e)
{
e.printStackTrace();
}
}
// every line in new row
@RequestMapping(value = "/getFileAsItIs", method = RequestMethod.GET, produces = "text/plain")
@ResponseBody
public String getFileAsItIs()
{
log.info("getFileAsItIs ");
String[] linesArrays = { "prva linija", "druga linija", "xxx linija" };
List<String> linesList = Arrays.asList(linesArrays);
StringBuilder sb = new StringBuilder();
for (String s : linesList)
{
sb.append(s).append(System.lineSeparator());
}
return sb.toString();
}
}
Display file on screen or download as attachment.
@Controller
public class FileController
{
private static final Logger log = LoggerFactory.getLogger(FileController.class);
@RequestMapping(value = "/file/{id}", method = RequestMethod.GET)
public void getFileViaAttachment(@PathVariable String id, HttpServletResponse response)
{
log.info("getFile " + id);
try
{
String content = "testing file download";
String fileName = "mojFileIzStringa.txt";
InputStream in = new ByteArrayInputStream(content.getBytes(StandardCharsets.UTF_8));
IOUtils.copy(in, response.getOutputStream());
response.setContentType("application/text");
response.setHeader("Content-Disposition", "attachment; filename=" + fileName);
response.flushBuffer();
}
catch (IOException e)
{
e.printStackTrace();
}
}
@RequestMapping(value = "/many", method = RequestMethod.GET)
public void getManyLinesViaAttachment(HttpServletResponse response)
{
log.info("getManyLines ");
try
{
String[] linesArrays = { "prva linija", "druga linija", "xxx linija" };
List<String> linesList = Arrays.asList(linesArrays);
String fileName = "mojFileSpunoLinija.csv";
IOUtils.writeLines(linesList, null, response.getOutputStream(), StandardCharsets.UTF_8);
response.setContentType("application/text");
response.setHeader("Content-Disposition", "attachment; filename=" + fileName);
response.flushBuffer();
}
catch (IOException e)
{
e.printStackTrace();
}
}
// every line in new row
@RequestMapping(value = "/getFileAsItIs", method = RequestMethod.GET, produces = "text/plain")
@ResponseBody
public String getFileAsItIs()
{
log.info("getFileAsItIs ");
String[] linesArrays = { "prva linija", "druga linija", "xxx linija" };
List<String> linesList = Arrays.asList(linesArrays);
StringBuilder sb = new StringBuilder();
for (String s : linesList)
{
sb.append(s).append(System.lineSeparator());
}
return sb.toString();
}
}
Change constraint
Table simmapping has foreign key to msisdn on 2 columns msisdn and providerId.
Change key so you can do update on providerId
Database: postgres.
ALTER TABLE public.simmapping
DROP CONSTRAINT fk_simmapping_msisdn,
ADD CONSTRAINT fk_simmapping_msisdn
FOREIGN KEY (msisdn, msisdn_providerid)
REFERENCES msisdn(msisdn, providerid)
ON UPDATE CASCADE;
Change key so you can do update on providerId
Database: postgres.
ALTER TABLE public.simmapping
DROP CONSTRAINT fk_simmapping_msisdn,
ADD CONSTRAINT fk_simmapping_msisdn
FOREIGN KEY (msisdn, msisdn_providerid)
REFERENCES msisdn(msisdn, providerid)
ON UPDATE CASCADE;
Tuesday, March 3, 2015
JPA Composite Key
Create class that will represent composite key and has implemented hashCode and equals methods.
Class that uses this composite key needs to be annotated with @IdClass and have same fields (msisdn and providedId as in example).
Ref:
https://stackoverflow.com/questions/13032948/how-to-create-and-handle-composite-primary-key-in-jpa
public class MsisdnCompositeKey implements Serializable
{
private static final long serialVersionUID = 1L;
private String msisdn;
private Long providerId;
.....
Class that uses this composite key needs to be annotated with @IdClass and have same fields (msisdn and providedId as in example).
@Entity
@Table(name = "MSISDN")
@IdClass(value = MsisdnCompositeKey.class)
public class Msisdn
{
private static final long serialVersionUID = 1L;
@Id
private String msisdn;
@Id
private Long providerId;
.....Ref:
https://stackoverflow.com/questions/13032948/how-to-create-and-handle-composite-primary-key-in-jpa
Thursday, February 26, 2015
Spring MessageSource
Read message source without injecting it or using spring context
ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
messageSource.setDefaultEncoding("UTF-8");
messageSource.setBasename("messages");
Use message source as you want now on.
Tuesday, February 3, 2015
wsdl2java notes
* Simple type "MAXEXTGBRUPL_OutType" was not mapped to Enum due to EnumMemberSizeCap limit. Facets count: 502, current limit: 256. You can use customization attribute "typesafeEnumMaxMembers" to extend the limit.
<jaxb:globalBindings typesafeEnumMaxMembers="2000">
* Problems with underscores in names:
<jaxb:globalBindings underscoreBinding="asCharInWord" >
* A class/interface with the same name "hr.samara.RspHeaderType" is already in use. Use a class customization or the -autoNameResolution option to resolve this conflict.
add -autoNameResolution to wsdl2java.bat
"%JAVA_HOME%\bin\java" -Xmx128M -Djava.endorsed.dirs="%CXF_HOME%\lib\endorsed" -cp "%CXF_JAR%;%TOOLS_JAR%;%CLASSPATH%" -Djava.util.logging.config.file="%CXF_HOME%\etc\logging.properties" org.apache.cxf.tools.wadlto.WADLToJava -autoNameResolution %*
Example of jaxb bindings file:
<jaxb:bindingsxmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
jaxb:extensionBindingPrefixes="xjc"
jaxb:version="2.0">
<jaxb:globalBindings typesafeEnumMaxMembers="2000" >
<xjc:serializable/>
</jaxb:globalBindings>
</jaxb:bindings>
Ant script code:
<property name="cxf.home" location="/apache-cxf-2.7.10/" /><!-- generate classes from wsdl -->
<path id="cxf.classpath">
<fileset dir="${cxf.home}/lib">
<include name="*.jar"/>
</fileset>
</path>
<target name="cxfWSDLToJava-HSS9860WSDL.wsdl">
<java classname="org.apache.cxf.tools.wsdlto.WSDLToJava" fork="true">
<arg value="-p"/>
<arg value="hr.samara.generated.HSS9860"/>
<arg value="-d"/>
<arg value="src/main/java"/>
<arg value="-verbose"/>
<arg value="-b" />
<arg value="src/main/resources/jaxbbindings.xml" />
<arg value="-autoNameResolution" />
<arg value="src/main/resources/HSS9860/HSS9860WSDL.wsdl"/>
<classpath>
<path refid="cxf.classpath"/>
</classpath>
</java>
</target>
Ref:
http://cwweng.tumblr.com/post/7000245700/wsdltojava-error-thrown-by-jaxb-two-declarations
https://cxf.apache.org/docs/wsdl-to-java.html
Monday, December 15, 2014
Mockito notes
Mocking
In service class make dao class package private (no modifier - optional).
Write test in same package (under test subfolder, not main).
Dao class has method called testingMockito(String someString);
Mock void methods:
1st service returns some response, 2nd service calls void method.
Ref:
https://stackoverflow.com/questions/14889951/how-to-verify-a-method-is-called-two-times-with-mockito-verify
http://www.baeldung.com/mockito-behavior
https://stackoverflow.com/questions/2276271/how-to-make-mock-to-void-methods-with-mockito
Scenario:
In service class you want to mock dao call.In service class make dao class package private (no modifier - optional).
Write test in same package (under test subfolder, not main).
Dao class has method called testingMockito(String someString);
Code example:
SomeService service; //injected
SomeDao dao = Mockito.mock(SomeDao.class);
service.setDao(dao); // or service.dao = dao;
//throw Exception when calling dao class
Mockito.doThrow(someException).when(dao).testingMockito(Mockito.anyString());
Verify
Mockito.verify(simCardServiceMock, Mockito.times(1)).findSimCard(simIdentifier);Mock void methods:
1st service returns some response, 2nd service calls void method.
CustomerSearchService customerSearchService = Mockito.mock(CustomerSearchService.class);
Mockito.when(customerSearchService.searchSubscription(providerId, searchCriteria)).thenReturn(subscription);
final SubscriptionService subscriptionService = Mockito.mock(SubscriptionService.class);
Mockito.doNothing()
.when(subscriptionService)
.activateSubscription(providerId, subscription.getId());
Ref:
https://stackoverflow.com/questions/14889951/how-to-verify-a-method-is-called-two-times-with-mockito-verify
http://www.baeldung.com/mockito-behavior
https://stackoverflow.com/questions/2276271/how-to-make-mock-to-void-methods-with-mockito
Wednesday, October 22, 2014
Redis notes
KEYS * - Returns all keys matching pattern.
FLUSHDB - Delete all the keys of the currently selected DB
FLUSHALL - Delete all the keys of all the existing databases, not just the currently selected one.
(eg: A User with a number of fields like name, surname, age, and so forth)
HGETALL key - lists all fields
SMEMBERS key - Get all the members in a set
ZCARD key - Get the number of members in a sorted set
ZRANGE key start stop [WITHSCORES] - Return a range of members in a sorted set, by index
Ref:
Redis homepage
Redis for the real world (IBM - Java development 2.0)
FLUSHDB - Delete all the keys of the currently selected DB
FLUSHALL - Delete all the keys of all the existing databases, not just the currently selected one.
Hashes
Hashes are maps between string fields and string values, so they are the perfect data type to represent objects(eg: A User with a number of fields like name, surname, age, and so forth)
HGETALL key - lists all fields
Sets
Sets are an unordered collection of Strings.SMEMBERS key - Get all the members in a set
Sorted Sets
Sorted Sets are, similarly to Redis Sets, non repeating collections of Strings. The difference is that every member of a Sorted Set is associated with score, that is used in order to take the sorted set ordered, from the smallest to the greatest score. While members are unique, scores may be repeated.ZCARD key - Get the number of members in a sorted set
ZRANGE key start stop [WITHSCORES] - Return a range of members in a sorted set, by index
Ref:
Redis homepage
Redis for the real world (IBM - Java development 2.0)
Tuesday, October 21, 2014
Quartz notes
The key interfaces of the Quartz API are:
Scheduler - the main API for interacting with the Scheduler.Job - an interface to be implemented by components that you want the Scheduler to execute.
JobDetail - used to define instances of Jobs.
The JobDataMap can be used to hold any amount of (serializable) data objects which you wish to have made available to the job instance when it executes.
Trigger - a component that defines the schedule upon which a given Job will be executed.
(Quartz ships with a handful of different trigger types, but the most commonly used types are SimpleTriggerand CronTrigger.)
JobBuilder - used to define/build JobDetail instances, which define instances of Jobs.
TriggerBuilder - used to define/build Trigger instances.
Misfire Instructions
A misfire occurs if a persistent trigger misses its firing time because of the scheduler being shutdown, or because there are no available threads in Quartz's thread pool for executing the job.The different trigger types have different misfire instructions available to them. By default they use a 'smart policy' instruction - which has dynamic behavior based on trigger type and configuration. When the scheduler starts, it searches for any persistent triggers that have misfired, and it then updates each of them based on their individually configured misfire instructions.
For CronTriggers: The 'smart policy' instruction is interpreted as MISFIRE_INSTRUCTION_FIRE_NOW
Note that if a trigger's time to fire arrives, and there isn't an available thread, Quartz will block (pause) until a thread comes available, then the Job will execute some number of milliseconds later than it should have.
This may even cause the thread to misfire if there is no available thread for the duration of the scheduler's configured “misfire threshold”.
Listeners
Listeners are objects that you create to perform actions based on events occurring within the scheduler.As indicated by their names, TriggerListeners receive events related to triggers, and JobListeners receive events related to jobs.
Trigger-related events include: trigger firings, trigger misfirings, and trigger completions (the jobs fired off by the trigger is finished).
JobDataMap
JobDetail contains various property settings for the job, as well as a JobDataMap, which can be used to store state information or provide properties/configuration for a given instance of your Job class.Triggers may also have a JobDataMap associated with them. A JobDataMap is useful for passing to a job parameters that are specific to the firings of the trigger.
The JobDataMap that is found on the JobExecutionContext during Job execution serves as a convenience.
It is a merge of the JobDataMap found on the JobDetail and the one found on the Trigger, with the values in the latter overriding any same-named values in the former.
If you add setter methods to your job class that correspond to the names of keys in the JobDataMap, then Quartz's default JobFactory implementation will automatically call those setters when the job is instantiated, thus preventing the need to explicitly get the values out of the map within your execute method.
JobStores
JobStores are responsible for keeping track of all the work data you give to the scheduler: jobs, triggers, calendars, and so forth.How to fire scheduled job asap?
Example:select * from qrtz_triggers;
trigger_name | trigger_group | job_name | job_group | is_volatile | description | next_fire_time | prev_fire_time | priority |
trigger_state | trigger_type | start_time | end_time | calendar_name | misfire_instr | job_data
----------------------------------+---------------+------------------------------+-----------+-------------+-------------+----------------+----------------+----------+-
--------------+--------------+---------------+----------+---------------+---------------+----------
portReconciliationProcessTrigger | DEFAULT | portReconciliationProcessJob | DEFAULT | f | | 1426579200000 | 1426492800000 | 5 |
WAITING | CRON | 1378612922000 | 0 | | 0 | \x
next fire time: 1426579200000 -> http://www.epochconverter.com/ ->
GMT: Tue, 17 Mar 2015 08:00:00 GMT
Your time zone: 3/17/2015, 9:00:00 AM GMT+1:00
Fire it in near future: 13.3.2015 15:00 -> converter ->
Epoch timestamp: 1426518000
Timestamp in milliseconds: 1426518000000
Update db
UPDATE qrtz_triggers SET next_fire_time = '1426518000000' WHERE trigger_name = 'portReconciliationProcessTrigger';
Delete triggers from db
delete from qrtz_cron_triggers;
delete from qrtz_triggers;
delete from qrtz_job_details;
delete from qrtz_triggers;
delete from qrtz_job_details;
Ref:
Quartz_Scheduler_Developer_Guide v2.2.1
Quartz scheduler misfire instructions explained
Quartz 1.8.x to Quartz 2.0 Migration Guide
Spring - Task Execution and Scheduling
Friday, October 17, 2014
svn tips
status
$ svn statusupdate
$ svn up
revert
$ svn revert *
revert to previous version (undo commit)
$ svn merge -r HEAD:12345 .
ignore files
$ svn propset svn:ignore "someFile" .link to another/external directory as part of your project
set property:$ svn propset svn:externals https://myServer/build/common common
checkout
$ svn checkout repositoryURL destinationDirectory
Ref
How do I ignore files in Subversion?Revert to a Previous Version in Subversion
Subscribe to:
Posts (Atom)