Quartz: Show list of completed task - quartz-scheduler

I don't know if this is the best place to ask, but is it possible to query Quartz completed jobs ?
I can't find a solution, I already visited quartz website and googled it.

If you are looking for information on historical run like start, end time (duration), params with which it was invoked you need to create your own table to persist those information.
The way i have done this in the past is
Created a new JOB_LOG table
Created a Custom Quartz Job Listener by extending JobListenerSupport http://www.quartz-scheduler.org/api/2.1.7/org/quartz/listeners/JobListenerSupport.html
Depending on your requirement add your persistence logic to
#Override
public void jobToBeExecuted(JobExecutionContext context) {
//insert here
}
#Override
public void jobWasExecuted(JobExecutionContext context, JobExecutionException jobException) {
//insert here
}

Related

CQ5 modify event fired on page delete

I'm trying to use CQ5 workflow to control my resources (page in particular).
I want to start different scripts on different events (Add/Delete/Modify). I have registered a launcher on each event.
When I delete a page anyway both the delete and modify events get fired and so both the script run. I can't understand how to exclude the modify event on delete.
Thanks for any advice
When deleting a page, a version of the page is created before it is actually deleted. Which means it would actually fire a PageModification Event with ModificationType as VERSION_CREATED.
You can verify the same using the following Sample EventHandler which would just log the PageModifications.
#Component
#Service
#Property(name="event.topics", value=PageEvent.EVENT_TOPIC)
public class MyPageEventHandler implements EventHandler {
private final Logger log = LoggerFactory.getLogger(this.getClass().getName());
#Override
public void handleEvent(Event event) {
PageEvent pgEvent = PageEvent.fromEvent(event);
Iterator<PageModification> modifications = pgEvent.getModifications();
while(modifications.hasNext()) {
log.info("Page Modifications are {}", modifications.next().getType());
}
}
}

where should I locatemy Quartz Code in asp.net

I have an asp.net website and want to do a task once a day.
the task is: sending email to users 2 days before expiration of their registration.
I used Quartz.NET version 1.0. I have wrote a sample code that opens a window in each second. Now I don't know where should I locate this code in my asp.net project?! it is now in a simple page. I want it to be independent from pages.
public class DumbJob : IJob
{
public DumbJob()
{
}
public void Execute(JobExecutionContext context)
{
Console.WriteLine("DumbJob is executing.");
System.Windows.Forms.MessageBox.Show("NICE");
}
}
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
// construct a scheduler factory
ISchedulerFactory schedFact = new StdSchedulerFactory();
// get a scheduler
IScheduler sched = schedFact.GetScheduler();
sched.Start();
// construct job info
JobDetail jobDetail = new JobDetail("myJob", null, typeof(DumbJob));
// fire every hour
Trigger trigger = TriggerUtils.MakeSecondlyTrigger();//.MakeHourlyTrigger();
// start on the next even hour
trigger.StartTimeUtc = TriggerUtils.GetEvenSecondDate(DateTime.UtcNow);
trigger.Name = "myTrigger";
sched.ScheduleJob(jobDetail, trigger);
}
}
There are various ways you can do that...but certainly it's probably better o build some sort of console applications for your case.
Frankly the simplest of which could be a windows schedule task that would trigger every day and launch an exe program (that you'd write using console dotnet) that would check soon-to-expire users and send an email when found...
If you don't want to have user + email code in various places (and centralize all this in your dotnet web app), then I'd create a SOAP/REST end point in your .NET webapp that would be called by a thin client, which would be scheduled by that "windows schedule task"
Quartz would give you more flexibility when it comes to scheduling and doing more enterprise things like job clustering / job high availability / job monitoring for example...
But that'd still be a .NET console app which would start a quartz scheduler, create a trigger, and run forever...(possibly wrapped into a windows "wrapper" service for more control)

How to distinguish whether a page is published first time or multiple times in publish environment of Adobe CQ5

I need to display labels "New" and "Updated" besides the links displayed on a page on my website.
For this I applied a logic of checking number of versions. If number of versions are more than 2 I displayed "updated" else i displayed "New". I am able to achieve it in the Author environment.
But in Publish environment, number of versions created for a page, even though the page is modified and republished, are one only. So how can i identify that whether the page is published first time or it has been published multiple times.
One suggestion to this is to implement you own servlet/listener that listens to the replication events. Look at the EventHandler and JobProcessor interfaces. This servlet could then for example set a property value on the component instance so that the component could be displayed different the first time. It could just be a small counter variable that keeps track of how many times the actualy thing has been published or some more fancy logic there :)
//imports
#Service...
#Component...
#Property(name = "event.topics", value = ReplicationAction.EVENT_TOPIC)
public class MyCustomEventHandler implements EventHandler, JobProcessor {
private static final Logger LOGGER = LoggerFactory.getLogger(MyCustomEventHandler.class);
#Override
public void handleEvent(Event event) {
LOGGER.info("Handling an event of some kind !!");
process (event);
}
#Override
public boolean process(Event event) {
LOGGER.info("Processing an event !!");
ReplicationAction action = ReplicationAction.fromEvent(event);
if (action.getType().equals(ReplicationActionType.ACTIVATE)) {
LOGGER.info("Processing an activation job, this is just what we are looking for !!!!!");
//Logic for fetching/setting the properties you want from the component you want
//goes here. Here you can make use of the action.getPath(); to get hold of the containing page
//and then later on any specific components...
}
return true;
}
}
To see my original answer head over to: http://help-forums.adobe.com/content/adobeforums/en/experience-manager-forum/adobe-experience-manager.topic.html/forum__kbyb-i_need_to_displayla.html

Handle Window close event

I'm trying to handle the event when the close button of a Window is clicked:
// View Code
#Override
public void attachWindowListener(WindowListener listener) {
window.addWindowListener(listener);
}
// Presenter code
view.attachWindowListener(new WindowListener(){
public void windowHide(WindowEvent we) {
GWT.log("Window Event - Processing fields");
processFields();
}
});
However, the windowHide function seems to be not executed since I can't see the log I placed there.
How to properly handle that event?
How about
Window.addCloseHandler(
new CloseHandler<Window>()
{
public void onClose( CloseEvent<Window> windowCloseEvent )
{
// Do your worst here
}
} );
I usually put this in onModuleLoad() in my EntryPoint class.
Cheers,
Based on the information provided I would guess that either a.) the events you think are firing do not fire for the Window component (even if it seems like they should) or b.) the events are firing but in a different order than you expect.
For example, it's possible that a BrowserEvent or some other event is firing first as the window is being closed and the Window object's WindowEvent never fires. According to the API docs for GXT 2.x, the WindowEvent will fire on hide and deactivate but it does not specify that it fires on close. The GXT 3.0.x API doc is less clear on this point but I would assume the same behavior. Unfortunately Sencha does not provide good documentation on what events fire for a given component and in what order.
With that said, I have had some luck working through similar issues to this by using a debug class which outputs all the events on a component to which it is attached. This may shed some light on which events are firing and their order of execution, and you may find an optimal event to which you can attach your processFields() method.
For a good example of a debugger class, see this answer from a related post: https://stackoverflow.com/a/2891746/460638. It also includes an example of how to attach the debugger to your component.
API Doc for Window, GXT 2.x: http://dev.sencha.com/deploy/gxt-2.2.5/docs/api/com/extjs/gxt/ui/client/widget/Window.html
API Doc for Window, GXT 3.0.x: http://dev.sencha.com/deploy/gxt-3.0.0/javadoc/gxt/com/sencha/gxt/widget/core/client/Window.html
This worked:
window.addListener(Events.Hide, new Listener<ComponentEvent>() {
#Override
public void handleEvent(ComponentEvent be) {
// Do stuff
}
});

Problem in Large scale application development and MVP tutorial

I recently tried to follow the Large scale application development and MVP tutorial. The tutorial was great but I am having a hard time with a few things.
If you try and add a contact to the list, the contact is created. If you try and add another contact, you are taken to the edit screen of the last contact you created. No more contacts can be added once you add your first contact. What needs to be changed so you can add more than one contact.
Changes I have made to try and get it to work:
Create a new editContactsView each time the add button is pressed. This brings up a blank edit screen, but the new contact still overwrites the previous addition.
Changed contacts.size() to contacts.size()+1 when determining the ID of the new contact.
Actually, there are a couple of problems (from what I can see):
like Lumpy already mentioned, the new Contact created via EditContactPresenter doesn't get an id assigned (it's null). This is because EditContactPresenter uses the default Contact() constructor which doesn't set the id. There are many possible solutions to this: add setting the id in the default constructor (so that you don't have to keep track of the ids somewhere else in the app), delegate that function to your server (for example, make your DB generate the next available id and send it back) or just add a contact.setId(whatever); in the appropriate place in EditContactsPresenter
AppController.java:134 - this example reuses the view (which is a good idea), but it doesn't clear it if you use it for creating a new Contact. Solution: either disable view reusing (just make a new EditContactsView every time) or add a clear() or sth similar to your Views and make the Presenters call it when they want to create a new entry, instead of editing an exisiting one (in which case, the values from the current entry overwrite the old values, so it's ok).
It's weird that this sample was left with such bugs - although I understand that it's main purpose was to show how MVP and GWT go together, but still :/
When a new contact is added it's id is never set. Because the id field is a string it is stored as "". That is how the first contact is added. Now every time you create a new contact you overwrite the contact with key "". To fix this you need to set the value of the id. I did this by changing the doSave method in EditContactsPresenter.
private void doSave() {
contact.setFirstName(display.getFirstName().getValue());
contact.setLastName(display.getLastName().getValue());
contact.setEmailAddress(display.getEmailAddress().getValue());
if(History.getToken.equals("add")
rpcService.updateContact(contact, new AsyncCallback<Contact>() {
public void onSuccess(Contact result) {
eventBus.fireEvent(new ContactUpdatedEvent(result));
}
public void onFailure(Throwable caught) {
Window.alert("Error updating contact");
}
});
else
rpcService.updateContact(contact, new AsyncCallback<Contact>() {
public void onSuccess(Contact result) {
eventBus.fireEvent(new ContactUpdatedEvent(result));
}
public void onFailure(Throwable caught) {
Window.alert("Error updating contact");
}
});
}