You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by ka...@apache.org on 2008/10/06 23:23:06 UTC

svn commit: r702270 - in /directory/sandbox/kayyagari/server-scheduler: ./ src/ src/main/ src/main/java/ src/main/java/org/ src/main/java/org/apahe/ src/main/java/org/apahe/directory/ src/main/java/org/apahe/directory/server/ src/main/java/org/apahe/di...

Author: kayyagari
Date: Mon Oct  6 14:23:05 2008
New Revision: 702270

URL: http://svn.apache.org/viewvc?rev=702270&view=rev
Log:
LDAP job store for quartz scheduler

Added:
    directory/sandbox/kayyagari/server-scheduler/
    directory/sandbox/kayyagari/server-scheduler/pom.xml
    directory/sandbox/kayyagari/server-scheduler/src/
    directory/sandbox/kayyagari/server-scheduler/src/main/
    directory/sandbox/kayyagari/server-scheduler/src/main/java/
    directory/sandbox/kayyagari/server-scheduler/src/main/java/org/
    directory/sandbox/kayyagari/server-scheduler/src/main/java/org/apahe/
    directory/sandbox/kayyagari/server-scheduler/src/main/java/org/apahe/directory/
    directory/sandbox/kayyagari/server-scheduler/src/main/java/org/apahe/directory/server/
    directory/sandbox/kayyagari/server-scheduler/src/main/java/org/apahe/directory/server/scheduler/
    directory/sandbox/kayyagari/server-scheduler/src/main/java/org/apahe/directory/server/scheduler/store/
    directory/sandbox/kayyagari/server-scheduler/src/main/java/org/apahe/directory/server/scheduler/store/DefaultJobStore.java
    directory/sandbox/kayyagari/server-scheduler/src/main/java/org/apahe/directory/server/scheduler/store/LdapJobStore.java
    directory/sandbox/kayyagari/server-scheduler/src/main/java/org/apahe/directory/server/scheduler/store/QuartzSchemaCostants.java
    directory/sandbox/kayyagari/server-scheduler/src/test/
    directory/sandbox/kayyagari/server-scheduler/src/test/java/
    directory/sandbox/kayyagari/server-scheduler/src/test/java/org/
    directory/sandbox/kayyagari/server-scheduler/src/test/java/org/apahe/
    directory/sandbox/kayyagari/server-scheduler/src/test/java/org/apahe/directory/
    directory/sandbox/kayyagari/server-scheduler/src/test/java/org/apahe/directory/server/
    directory/sandbox/kayyagari/server-scheduler/src/test/java/org/apahe/directory/server/scheduler/
    directory/sandbox/kayyagari/server-scheduler/src/test/java/org/apahe/directory/server/scheduler/store/
    directory/sandbox/kayyagari/server-scheduler/src/test/java/org/apahe/directory/server/scheduler/store/LdapJobStoreITest.java
    directory/sandbox/kayyagari/server-scheduler/src/test/resources/
    directory/sandbox/kayyagari/server-scheduler/src/test/resources/log4j.properties

Added: directory/sandbox/kayyagari/server-scheduler/pom.xml
URL: http://svn.apache.org/viewvc/directory/sandbox/kayyagari/server-scheduler/pom.xml?rev=702270&view=auto
==============================================================================
--- directory/sandbox/kayyagari/server-scheduler/pom.xml (added)
+++ directory/sandbox/kayyagari/server-scheduler/pom.xml Mon Oct  6 14:23:05 2008
@@ -0,0 +1,94 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+  
+  http://www.apache.org/licenses/LICENSE-2.0
+  
+  Unless required by applicable law or agreed to in writing,
+  software distributed under the License is distributed on an
+  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  KIND, either express or implied.  See the License for the
+  specific language governing permissions and limitations
+  under the License.
+--><project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>org.apache.directory.server</groupId>
+    <artifactId>apacheds-parent</artifactId>
+    <version>1.5.5-SNAPSHOT</version>
+  </parent>
+  <artifactId>apacheds-scheduler</artifactId>
+  <name>ApacheDS Scheduler</name>
+
+  <description>
+   Integrated quartz scheduler of ApacheDS
+  </description>
+
+  <packaging>jar</packaging>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.directory.server</groupId>
+      <artifactId>apacheds-core-shared</artifactId>
+      <version>${pom.version}</version>
+    </dependency>
+
+    <dependency>
+      <groupId>org.apache.directory.server</groupId>
+      <artifactId>apacheds-core-constants</artifactId>
+      <version>${pom.version}</version>
+    </dependency>
+    
+    <dependency>
+      <groupId>org.apache.directory.server</groupId>
+      <artifactId>apacheds-core</artifactId>
+      <version>1.5.5-SNAPSHOT</version>
+    </dependency>
+    
+    <dependency>
+      <groupId>org.apache.directory.server</groupId>
+      <artifactId>apacheds-xdbm-base</artifactId>
+      <version>1.5.5-SNAPSHOT</version>
+    </dependency>
+
+    <dependency>
+      <groupId>quartz</groupId>
+      <artifactId>quartz</artifactId>
+      <version>1.5.2</version>
+    </dependency>
+
+    <dependency>
+      <groupId>org.apache.directory.server</groupId>
+      <artifactId>apacheds-server-unit</artifactId>
+      <version>1.5.5-SNAPSHOT</version>
+    </dependency>
+  </dependencies>
+
+  <build>
+    <plugins>
+      <plugin>
+        <artifactId>maven-surefire-plugin</artifactId>
+        <configuration>
+          <systemProperties>
+            <property>
+             <name>keeprunning</name>
+             <value>${keeprunning}</value>
+            </property>
+          </systemProperties>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+  
+  <properties>
+    <!-- let.the.test.server.run -->
+    <keeprunning>false</keeprunning>
+  </properties>
+  
+</project>
\ No newline at end of file

Added: directory/sandbox/kayyagari/server-scheduler/src/main/java/org/apahe/directory/server/scheduler/store/DefaultJobStore.java
URL: http://svn.apache.org/viewvc/directory/sandbox/kayyagari/server-scheduler/src/main/java/org/apahe/directory/server/scheduler/store/DefaultJobStore.java?rev=702270&view=auto
==============================================================================
--- directory/sandbox/kayyagari/server-scheduler/src/main/java/org/apahe/directory/server/scheduler/store/DefaultJobStore.java (added)
+++ directory/sandbox/kayyagari/server-scheduler/src/main/java/org/apahe/directory/server/scheduler/store/DefaultJobStore.java Mon Oct  6 14:23:05 2008
@@ -0,0 +1,334 @@
+/*
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *   or more contributor license agreements.  See the NOTICE file
+ *   distributed with this work for additional information
+ *   regarding copyright ownership.  The ASF licenses this file
+ *   to you under the Apache License, Version 2.0 (the
+ *   "License"); you may not use this file except in compliance
+ *   with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing,
+ *   software distributed under the License is distributed on an
+ *   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *   KIND, either express or implied.  See the License for the
+ *   specific language governing permissions and limitations
+ *   under the License.
+ *
+ */
+package org.apahe.directory.server.scheduler.store;
+
+import java.util.Set;
+
+import org.quartz.Calendar;
+import org.quartz.JobDetail;
+import org.quartz.JobPersistenceException;
+import org.quartz.ObjectAlreadyExistsException;
+import org.quartz.SchedulerConfigException;
+import org.quartz.SchedulerException;
+import org.quartz.Trigger;
+import org.quartz.core.SchedulingContext;
+import org.quartz.spi.ClassLoadHelper;
+import org.quartz.spi.JobStore;
+import org.quartz.spi.SchedulerSignaler;
+import org.quartz.spi.TriggerFiredBundle;
+
+// FIXME this is a dummy clas to help incremental development of the original implementation of JobStore
+// which helps in avoiding this eclipse TODO boilerplate stuff
+public class DefaultJobStore implements JobStore
+{
+
+    public Trigger acquireNextTrigger( SchedulingContext ctxt, long noLaterThan ) throws JobPersistenceException
+    {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+
+    public String[] getCalendarNames( SchedulingContext ctxt ) throws JobPersistenceException
+    {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+
+    public String[] getJobGroupNames( SchedulingContext ctxt ) throws JobPersistenceException
+    {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+
+    public String[] getJobNames( SchedulingContext ctxt, String groupName ) throws JobPersistenceException
+    {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+
+    public int getNumberOfCalendars( SchedulingContext ctxt ) throws JobPersistenceException
+    {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+
+    public int getNumberOfJobs( SchedulingContext ctxt ) throws JobPersistenceException
+    {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+
+    public int getNumberOfTriggers( SchedulingContext ctxt ) throws JobPersistenceException
+    {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+
+    public Set getPausedTriggerGroups( SchedulingContext ctxt ) throws JobPersistenceException
+    {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+
+    public String[] getTriggerGroupNames( SchedulingContext ctxt ) throws JobPersistenceException
+    {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+
+    public String[] getTriggerNames( SchedulingContext ctxt, String groupName ) throws JobPersistenceException
+    {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+
+    public int getTriggerState( SchedulingContext ctxt, String triggerName, String triggerGroup )
+        throws JobPersistenceException
+    {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+
+    public Trigger[] getTriggersForJob( SchedulingContext ctxt, String jobName, String groupName )
+        throws JobPersistenceException
+    {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+
+    public void initialize( ClassLoadHelper loadHelper, SchedulerSignaler signaler ) throws SchedulerConfigException
+    {
+        // TODO Auto-generated method stub
+
+    }
+
+
+    public void pauseAll( SchedulingContext ctxt ) throws JobPersistenceException
+    {
+        // TODO Auto-generated method stub
+
+    }
+
+
+    public void pauseJob( SchedulingContext ctxt, String jobName, String groupName ) throws JobPersistenceException
+    {
+        // TODO Auto-generated method stub
+
+    }
+
+
+    public void pauseJobGroup( SchedulingContext ctxt, String groupName ) throws JobPersistenceException
+    {
+        // TODO Auto-generated method stub
+
+    }
+
+
+    public void pauseTrigger( SchedulingContext ctxt, String triggerName, String groupName )
+        throws JobPersistenceException
+    {
+        // TODO Auto-generated method stub
+
+    }
+
+
+    public void pauseTriggerGroup( SchedulingContext ctxt, String groupName ) throws JobPersistenceException
+    {
+        // TODO Auto-generated method stub
+
+    }
+
+
+    public void releaseAcquiredTrigger( SchedulingContext ctxt, Trigger trigger ) throws JobPersistenceException
+    {
+        // TODO Auto-generated method stub
+
+    }
+
+
+    public boolean removeCalendar( SchedulingContext ctxt, String calName ) throws JobPersistenceException
+    {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+
+    public boolean removeJob( SchedulingContext ctxt, String jobName, String groupName ) throws JobPersistenceException
+    {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+
+    public boolean removeTrigger( SchedulingContext ctxt, String triggerName, String groupName )
+        throws JobPersistenceException
+    {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+
+    public boolean replaceTrigger( SchedulingContext ctxt, String triggerName, String groupName, Trigger newTrigger )
+        throws JobPersistenceException
+    {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+
+    public void resumeAll( SchedulingContext ctxt ) throws JobPersistenceException
+    {
+        // TODO Auto-generated method stub
+
+    }
+
+
+    public void resumeJob( SchedulingContext ctxt, String jobName, String groupName ) throws JobPersistenceException
+    {
+        // TODO Auto-generated method stub
+
+    }
+
+
+    public void resumeJobGroup( SchedulingContext ctxt, String groupName ) throws JobPersistenceException
+    {
+        // TODO Auto-generated method stub
+
+    }
+
+
+    public void resumeTrigger( SchedulingContext ctxt, String triggerName, String groupName )
+        throws JobPersistenceException
+    {
+        // TODO Auto-generated method stub
+
+    }
+
+
+    public void resumeTriggerGroup( SchedulingContext ctxt, String groupName ) throws JobPersistenceException
+    {
+        // TODO Auto-generated method stub
+
+    }
+
+
+    public Calendar retrieveCalendar( SchedulingContext ctxt, String calName ) throws JobPersistenceException
+    {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+
+    public JobDetail retrieveJob( SchedulingContext ctxt, String jobName, String groupName )
+        throws JobPersistenceException
+    {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+
+    public Trigger retrieveTrigger( SchedulingContext ctxt, String triggerName, String groupName )
+        throws JobPersistenceException
+    {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+
+    public void schedulerStarted() throws SchedulerException
+    {
+        // TODO Auto-generated method stub
+
+    }
+
+
+    public void shutdown()
+    {
+        // TODO Auto-generated method stub
+
+    }
+
+
+    public void storeCalendar( SchedulingContext ctxt, String name, Calendar calendar, boolean replaceExisting,
+        boolean updateTriggers ) throws ObjectAlreadyExistsException, JobPersistenceException
+    {
+        // TODO Auto-generated method stub
+
+    }
+
+
+    public void storeJob( SchedulingContext ctxt, JobDetail newJob, boolean replaceExisting )
+        throws ObjectAlreadyExistsException, JobPersistenceException
+    {
+        // TODO Auto-generated method stub
+
+    }
+
+
+    public void storeJobAndTrigger( SchedulingContext ctxt, JobDetail newJob, Trigger newTrigger )
+        throws ObjectAlreadyExistsException, JobPersistenceException
+    {
+        // TODO Auto-generated method stub
+
+    }
+
+
+    public void storeTrigger( SchedulingContext ctxt, Trigger newTrigger, boolean replaceExisting )
+        throws ObjectAlreadyExistsException, JobPersistenceException
+    {
+        // TODO Auto-generated method stub
+
+    }
+
+
+    public boolean supportsPersistence()
+    {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+
+    public TriggerFiredBundle triggerFired( SchedulingContext ctxt, Trigger trigger ) throws JobPersistenceException
+    {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+
+    public void triggeredJobComplete( SchedulingContext ctxt, Trigger trigger, JobDetail jobDetail, int triggerInstCode )
+        throws JobPersistenceException
+    {
+        // TODO Auto-generated method stub
+
+    }
+
+}

Added: directory/sandbox/kayyagari/server-scheduler/src/main/java/org/apahe/directory/server/scheduler/store/LdapJobStore.java
URL: http://svn.apache.org/viewvc/directory/sandbox/kayyagari/server-scheduler/src/main/java/org/apahe/directory/server/scheduler/store/LdapJobStore.java?rev=702270&view=auto
==============================================================================
--- directory/sandbox/kayyagari/server-scheduler/src/main/java/org/apahe/directory/server/scheduler/store/LdapJobStore.java (added)
+++ directory/sandbox/kayyagari/server-scheduler/src/main/java/org/apahe/directory/server/scheduler/store/LdapJobStore.java Mon Oct  6 14:23:05 2008
@@ -0,0 +1,482 @@
+/*
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *   or more contributor license agreements.  See the NOTICE file
+ *   distributed with this work for additional information
+ *   regarding copyright ownership.  The ASF licenses this file
+ *   to you under the Apache License, Version 2.0 (the
+ *   "License"); you may not use this file except in compliance
+ *   with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing,
+ *   software distributed under the License is distributed on an
+ *   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *   KIND, either express or implied.  See the License for the
+ *   specific language governing permissions and limitations
+ *   under the License.
+ *
+ */
+package org.apahe.directory.server.scheduler.store;
+
+
+import static org.apahe.directory.server.scheduler.store.QuartzSchemaCostants.*;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.directory.server.core.DirectoryService;
+import org.apache.directory.server.core.entry.DefaultServerEntry;
+import org.apache.directory.server.core.entry.ServerEntry;
+import org.apache.directory.server.core.filtering.EntryFilteringCursor;
+import org.apache.directory.server.core.interceptor.context.AddOperationContext;
+import org.apache.directory.server.core.interceptor.context.EntryOperationContext;
+import org.apache.directory.server.core.interceptor.context.ModifyOperationContext;
+import org.apache.directory.server.core.interceptor.context.SearchOperationContext;
+import org.apache.directory.server.core.partition.Partition;
+import org.apache.directory.server.schema.registries.AttributeTypeRegistry;
+import org.apache.directory.server.schema.registries.Registries;
+import org.apache.directory.shared.ldap.constants.SchemaConstants;
+import org.apache.directory.shared.ldap.entry.EntryAttribute;
+import org.apache.directory.shared.ldap.entry.client.ClientStringValue;
+import org.apache.directory.shared.ldap.filter.AndNode;
+import org.apache.directory.shared.ldap.filter.EqualityNode;
+import org.apache.directory.shared.ldap.filter.SearchScope;
+import org.apache.directory.shared.ldap.name.LdapDN;
+import org.quartz.JobDataMap;
+import org.quartz.JobDetail;
+import org.quartz.JobPersistenceException;
+import org.quartz.ObjectAlreadyExistsException;
+import org.quartz.SchedulerConfigException;
+import org.quartz.SchedulerException;
+import org.quartz.core.SchedulingContext;
+import org.quartz.spi.ClassLoadHelper;
+import org.quartz.spi.SchedulerSignaler;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * 
+ * TODO LdapJobStore.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+//FIXME : the quartz veersion present in maven repo is 1.5.2 need to uplod 1.6.0
+public class LdapJobStore extends DefaultJobStore //implements JobStore
+{
+
+    /** the partition to store the schedular data*/
+    private Partition partition;
+
+    /** container under the partition which holds all the schedular related data*/
+    private LdapDN schedulerRootDn;
+
+    private DirectoryService directoryService;
+
+    private Registries registries;
+    private AttributeTypeRegistry attrTypeRegistry;
+
+    /** containers */
+    private LdapDN jobDetailsDn;
+    private LdapDN triggersDn;
+
+    private static final Logger LOG = LoggerFactory.getLogger( LdapJobStore.class );
+
+
+    /**
+     * 
+     * Creates a new instance of LdapJobStore.
+     *
+     * @param partition the partition to store the schedular data
+     * @param schedulerContainer name of the container in the above given partition
+     * @param directoryService the DirectoryService
+     * @throws Exception if the schedulerContainer is not a valid LDAP name
+     */
+    public LdapJobStore( DirectoryService directoryService, Partition partition, String schedulerContainer ) throws Exception
+    {
+        if ( partition == null )
+        {
+            throw new IllegalArgumentException( "Schedular partition cannot be null" );
+        }
+
+        if ( schedulerContainer == null || schedulerContainer.trim().length() == 0 )
+        {
+            throw new IllegalArgumentException( "Name of LDAP container to store schedular data cannot be null" );
+        }
+
+        this.partition = partition;
+        this.directoryService = directoryService;
+
+        schedulerRootDn = new LdapDN( schedulerContainer );
+
+        registries = directoryService.getRegistries();
+        attrTypeRegistry = registries.getAttributeTypeRegistry();
+
+        schedulerRootDn.normalize( attrTypeRegistry.getNormalizerMapping() );
+    }
+
+
+    private void initializeContainers() throws Exception
+    {
+        EntryOperationContext opContext = new EntryOperationContext( directoryService.getAdminSession(), schedulerRootDn );
+        if ( !partition.hasEntry( opContext ) )
+        {
+            ServerEntry entry = new DefaultServerEntry( directoryService.getRegistries() );
+            entry.setDn( schedulerRootDn );
+            entry.add( "objectClass", "top", "organizationalUnit" );
+            entry.add( "ou", schedulerRootDn.getRdn().getUpName().split( "=" )[1] );
+
+            AddOperationContext addContext = new AddOperationContext( directoryService.getAdminSession(), entry );
+            partition.add( addContext );
+        }
+
+        List<LdapDN> childDns = new ArrayList<LdapDN>();
+
+        jobDetailsDn = getChildDn( "ou=jobs", schedulerRootDn );
+        childDns.add( jobDetailsDn );
+
+        triggersDn = getChildDn( "ou=triggers", schedulerRootDn );
+        childDns.add( triggersDn );
+
+        for ( LdapDN dn : childDns )
+        {
+            opContext = new EntryOperationContext( directoryService.getAdminSession(), dn );
+            if ( partition.hasEntry( opContext ) )
+            {
+                continue;
+            }
+
+            ServerEntry entry = new DefaultServerEntry( directoryService.getRegistries() );
+            entry.setDn( dn );
+            entry.add( "objectClass", "top", "organizationalUnit" );
+            entry.add( "ou", dn.getRdn().getUpName().split( "=" )[1] );
+
+            AddOperationContext addContext = new AddOperationContext( directoryService.getAdminSession(), entry );
+            partition.add( addContext );
+        }
+
+        if ( LOG.isInfoEnabled() )
+        {
+            LOG.info( "Schedular entry containers initialized" );
+        }
+    }
+
+
+    public void initialize( ClassLoadHelper loadHelper, SchedulerSignaler signaler ) throws SchedulerConfigException
+    {
+        try
+        {
+            initializeContainers();
+        }
+        catch ( Exception e )
+        {
+            throw new SchedulerConfigException( e.getMessage(), e );
+        }
+    }
+
+
+    @Override
+    public void schedulerStarted() throws SchedulerException
+    {
+        //TODO what to do here? :D
+    }
+
+
+    @Override
+    public void storeJob( SchedulingContext ctxt, JobDetail newJob, boolean replaceExisting )
+        throws ObjectAlreadyExistsException, JobPersistenceException
+    {
+        ServerEntry jobEntry;
+
+        jobEntry = getJobEntry( newJob.getName(), newJob.getGroup() );
+
+        try
+        {
+            if ( jobEntry != null )
+            {
+                if ( !replaceExisting )
+                {
+                    throw new ObjectAlreadyExistsException( newJob );
+                }
+
+                updateJob( newJob, jobEntry );
+            }
+            else
+            {
+                storeNewJob( newJob );
+            }
+        }
+        catch ( ObjectAlreadyExistsException e )
+        {
+            throw e;
+        }
+        catch ( Exception e )
+        {
+            throw new JobPersistenceException( "Failed to persist the job ", e );
+        }
+
+    }
+
+
+    public JobDetail retrieveJob( SchedulingContext ctxt, String jobName, String groupName )
+        throws JobPersistenceException
+    {
+        /*
+        try
+        {
+            SearchOperationContext soc = new SearchOperationContext( dirService.getAdminSession() );
+            soc.setDn( jobDetailsDn );
+            
+            EqualityNode nameNode = new EqualityNode( JOBNAME, new ClientStringValue( jobName ) );
+            EqualityNode groupNode = new EqualityNode( JOBGROUP, new ClientStringValue( groupName ) );
+            
+            AndNode filter = new AndNode();
+            filter.addNode( nameNode );
+            filter.addNode( groupNode );
+            
+            soc.setFilter( filter );
+            
+            EntryFilteringCursor cursor = partition.search( soc );
+            
+            if( cursor.next() )
+            {
+                return cursor.get().getOriginalEntry();
+            }
+        }
+        catch( Exception e )
+        {
+            LOG.error( "Failed to search job with name {} and group {}", jobName, groupName );
+            throw new JobPersistenceException( "Failed to search job", e );
+        }
+        */
+
+        ServerEntry jobEntry = getJobEntry( jobName, groupName );
+        JobDetail job = null;
+
+        try
+        {
+            if ( jobEntry != null )
+            {
+                job = new JobDetail();
+                job.setName( ( String ) jobEntry.get( JOBNAME ).getString() );
+                job.setGroup( ( String ) jobEntry.get( JOBGROUP ).getString() );
+
+                EntryAttribute descAttr = jobEntry.get( JOBNAME );
+                if ( descAttr != null )
+                {
+                    job.setDescription( descAttr.getString() );
+                }
+
+                job.setDurability( Boolean.valueOf( jobEntry.get( ISDURABLE ).getString() ) );
+                job.setVolatility( Boolean.valueOf( jobEntry.get( ISVOLATILE ).getString() ) );
+                job.setRequestsRecovery( Boolean.valueOf( jobEntry.get( REQUESTSRECOVERY ).getString() ) );
+
+                EntryAttribute dataAttr = jobEntry.get( JOBDATA );
+                if ( dataAttr != null )
+                {
+                    job.setJobDataMap( bytesToJobData( dataAttr.getBytes() ) );
+                }
+                
+                job.setJobClass( Class.forName( jobEntry.get( JOBCLASSNAME ).getString() ) );
+            }
+        }
+        catch ( Exception e )
+        {
+            LOG.error( "Failed to retrieve job", e );
+            throw new JobPersistenceException( "Failed to retrieve job", e );
+        }
+
+        return job;
+    }
+
+
+    
+    // ---------------------- private utility methods ---------------------------
+
+    private void storeNewJob( JobDetail job ) throws Exception
+    {
+        createJobGroupIfNotExixts( job );
+
+        ServerEntry jobEntry = new DefaultServerEntry( registries );
+        jobEntry.setDn( getJobDn( job.getName(), job.getGroup() ) );
+        jobEntry.add( SchemaConstants.OBJECT_CLASS_AT, JOBDETAIL );
+
+        jobEntry.add( JOBNAME, job.getName() );
+        jobEntry.add( JOBGROUP, job.getGroup() );
+
+        if ( job.getDescription() != null )
+        {
+            jobEntry.add( DESCRIPTION, job.getDescription() );
+        }
+
+        jobEntry.add( JOBCLASSNAME, job.getJobClass().getName() );
+        jobEntry.add( ISDURABLE, String.valueOf( job.isDurable() ) );
+        jobEntry.add( ISVOLATILE, String.valueOf( job.isVolatile() ) );
+        jobEntry.add( ISSTATEFUL, String.valueOf( job.isStateful() ) );
+        jobEntry.add( REQUESTSRECOVERY, String.valueOf( job.requestsRecovery() ) );
+        jobEntry.add( JOBCLASSNAME, job.getJobClass().getName() );
+
+        if ( job.getJobDataMap() != null )
+        {
+            jobEntry.add( JOBDATA, jobDataToBytes( job.getJobDataMap() ) );
+        }
+        
+        AddOperationContext aoc = new AddOperationContext( directoryService.getAdminSession(), jobEntry );
+        partition.add( aoc );
+    }
+
+
+    private void updateJob( JobDetail job, ServerEntry jobEntry ) throws Exception
+    {
+        ModifyOperationContext moc = new ModifyOperationContext( directoryService.getAdminSession() );
+        //        moc.se
+    }
+
+
+    private ServerEntry getJobEntry( String jobName, String jobGroup )
+    {
+        ServerEntry entry = null;
+        EntryFilteringCursor cursor = null;
+
+        try
+        {
+            SearchOperationContext soc = new SearchOperationContext( directoryService.getAdminSession() );
+            soc.setDn( getJobDn( jobName, jobGroup ) );
+            soc.setScope( SearchScope.OBJECT );
+
+            EqualityNode nameNode = new EqualityNode( JOBNAME, new ClientStringValue( jobName ) );
+            EqualityNode groupNode = new EqualityNode( JOBGROUP, new ClientStringValue( jobGroup ) );
+            
+            AndNode filter = new AndNode();
+            filter.addNode( nameNode );
+            filter.addNode( groupNode );
+            soc.setFilter( filter );
+            
+            cursor = partition.search( soc );
+            if ( cursor.next() )
+            {
+                entry = cursor.get().getOriginalEntry();
+            }
+            
+            cursor.close();
+        }
+        catch ( Exception e )
+        {
+            LOG.error( "Failed to search for job with name '{}' and group '{}'", jobName, jobGroup );
+            e.printStackTrace();
+        }
+
+        return entry;
+    }
+
+
+    private boolean hasDn( LdapDN dn )
+    {
+        try
+        {
+            SearchOperationContext soc = new SearchOperationContext( directoryService.getAdminSession() );
+            soc.setDn( dn );
+            soc.setScope( SearchScope.OBJECT );
+
+            EntryFilteringCursor cursor = partition.search( soc );
+            if ( cursor.next() )
+            {
+                return true;
+            }
+            
+            cursor.close();
+        }
+        catch ( Exception e )
+        {
+            LOG.error( "Failed to find DN '{}'", dn.getUpName() );
+        }
+
+        return false;
+    }
+
+
+    private void createJobGroupIfNotExixts( JobDetail job ) throws Exception
+    {
+        LdapDN dn = getChildDn( JOBGROUP + "=" + job.getGroup(), jobDetailsDn );
+        if ( !hasDn( dn ) )
+        {
+            ServerEntry entry = new DefaultServerEntry( directoryService.getRegistries() );
+            entry.setDn( dn );
+            entry.add( "objectClass", "quartzGroup" );
+            entry.add( JOBGROUP, job.getGroup() );
+
+            AddOperationContext addContext = new AddOperationContext( directoryService.getAdminSession(), entry );
+            partition.add( addContext );
+        }
+    }
+
+
+    private LdapDN getChildDn( String childRdn, LdapDN parent ) throws Exception
+    {
+        LdapDN childDn = new LdapDN( parent.getUpName() );
+
+        childDn.add( childRdn );
+        childDn.normalize( attrTypeRegistry.getNormalizerMapping() );
+
+        return childDn;
+    }
+
+
+    private LdapDN getJobDn( String jobName, String jobGroup ) throws Exception
+    {
+        LdapDN jobDn = new LdapDN( jobDetailsDn.getUpName() );
+
+        jobDn.add( "jobGroup=" + jobGroup );
+        jobDn.add( "jobName=" + jobName );
+        jobDn.normalize( attrTypeRegistry.getNormalizerMapping() );
+
+        return jobDn;
+    }
+
+
+    private byte[] jobDataToBytes( JobDataMap data )
+    {
+        if ( data != null )
+        {
+            try
+            {
+                ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
+                ObjectOutputStream objOut = new ObjectOutputStream( byteOut );
+
+                objOut.writeObject( data );
+                byte[] bytes = byteOut.toByteArray(); 
+                byteOut.close();
+
+                return bytes;
+            }
+            catch ( IOException e )
+            {
+                LOG.error( "Failed to serialize the job data", e );
+            }
+        }
+
+        return null;
+    }
+
+
+    private JobDataMap bytesToJobData( byte[] data ) throws Exception
+    {
+        if ( data == null )
+        {
+            return null;
+        }
+
+        ObjectInputStream in = new ObjectInputStream( new ByteArrayInputStream( data ) );
+        JobDataMap dataMap = ( JobDataMap ) in.readObject();
+        in.close();
+
+        return dataMap;
+    }
+}

Added: directory/sandbox/kayyagari/server-scheduler/src/main/java/org/apahe/directory/server/scheduler/store/QuartzSchemaCostants.java
URL: http://svn.apache.org/viewvc/directory/sandbox/kayyagari/server-scheduler/src/main/java/org/apahe/directory/server/scheduler/store/QuartzSchemaCostants.java?rev=702270&view=auto
==============================================================================
--- directory/sandbox/kayyagari/server-scheduler/src/main/java/org/apahe/directory/server/scheduler/store/QuartzSchemaCostants.java (added)
+++ directory/sandbox/kayyagari/server-scheduler/src/main/java/org/apahe/directory/server/scheduler/store/QuartzSchemaCostants.java Mon Oct  6 14:23:05 2008
@@ -0,0 +1,93 @@
+/*
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *   or more contributor license agreements.  See the NOTICE file
+ *   distributed with this work for additional information
+ *   regarding copyright ownership.  The ASF licenses this file
+ *   to you under the Apache License, Version 2.0 (the
+ *   "License"); you may not use this file except in compliance
+ *   with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing,
+ *   software distributed under the License is distributed on an
+ *   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *   KIND, either express or implied.  See the License for the
+ *   specific language governing permissions and limitations
+ *   under the License.
+ *
+ */
+package org.apahe.directory.server.scheduler.store;
+
+/**
+ * 
+ * QuartzSchemaCostants.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class QuartzSchemaCostants
+{
+    public static final String JOBNAME = "jobName";
+
+    public static final String JOBDATA = "jobData";
+
+    public static final String CALENDAR = "calendar";
+
+    public static final String CALENDARNAME = "calendarName";
+
+    public static final String CHECKININTERVAL = "checkinInterval";
+
+    public static final String CRONEXPRESSION = "cronExpression";
+
+    public static final String STARTTIME = "startTime";
+
+    public static final String ENDTIME = "endTime";
+
+    public static final String FIREDTIME = "firedTime";
+
+    public static final String QUARTZENTRYID = "quartzEntryId";
+
+    public static final String INSTANCENAME = "instanceName";
+
+    public static final String ISDURABLE = "isDurable";
+
+    public static final String ISSTATEFUL = "isStateful";
+
+    public static final String ISVOLATILE = "isVolatile";
+
+    public static final String JOBCLASSNAME = "jobClassName";
+
+    public static final String JOBGROUP = "jobGroup";
+
+    public static final String LASTCHECKINTIME = "lastCheckinTime";
+
+    public static final String PREVFIRETIME = "prevFireTime";
+
+    public static final String NEXTFIRETIME = "nextFireTime";
+
+    public static final String PRIORITY = "priority";
+
+    public static final String REPEATCOUNT = "repeatCount";
+
+    public static final String REPEATINTERVAL = "repeatInterval";
+
+    public static final String TIMESTRIGGERED = "timesTriggered";
+
+    public static final String REQUESTSRECOVERY = "requestsRecovery";
+
+    public static final String TRIGGERSTATE = "triggerState";
+
+    public static final String TRIGGERNAME = "triggerName";
+
+    public static final String TRIGGERTYPE = "triggerType";
+
+    public static final String MISFIREINSTR = "misFireInstr";
+
+    public static final String TRIGGER = "trigger";
+
+    public static final String JOBDETAIL = "jobDetail";
+
+    public static final String DESCRIPTION = "description";
+
+}

Added: directory/sandbox/kayyagari/server-scheduler/src/test/java/org/apahe/directory/server/scheduler/store/LdapJobStoreITest.java
URL: http://svn.apache.org/viewvc/directory/sandbox/kayyagari/server-scheduler/src/test/java/org/apahe/directory/server/scheduler/store/LdapJobStoreITest.java?rev=702270&view=auto
==============================================================================
--- directory/sandbox/kayyagari/server-scheduler/src/test/java/org/apahe/directory/server/scheduler/store/LdapJobStoreITest.java (added)
+++ directory/sandbox/kayyagari/server-scheduler/src/test/java/org/apahe/directory/server/scheduler/store/LdapJobStoreITest.java Mon Oct  6 14:23:05 2008
@@ -0,0 +1,174 @@
+/*
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *   or more contributor license agreements.  See the NOTICE file
+ *   distributed with this work for additional information
+ *   regarding copyright ownership.  The ASF licenses this file
+ *   to you under the Apache License, Version 2.0 (the
+ *   "License"); you may not use this file except in compliance
+ *   with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing,
+ *   software distributed under the License is distributed on an
+ *   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *   KIND, either express or implied.  See the License for the
+ *   specific language governing permissions and limitations
+ *   under the License.
+ *
+ */
+package org.apahe.directory.server.scheduler.store;
+
+import java.io.File;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.directory.server.core.partition.Partition;
+import org.apache.directory.server.schema.SerializableComparator;
+import org.apache.directory.server.schema.bootstrap.ApacheSchema;
+import org.apache.directory.server.schema.bootstrap.ApachemetaSchema;
+import org.apache.directory.server.schema.bootstrap.BootstrapSchemaLoader;
+import org.apache.directory.server.schema.bootstrap.CoreSchema;
+import org.apache.directory.server.schema.bootstrap.JavaSchema;
+import org.apache.directory.server.schema.bootstrap.QuartzSchema;
+import org.apache.directory.server.schema.bootstrap.Schema;
+import org.apache.directory.server.schema.bootstrap.SystemSchema;
+import org.apache.directory.server.schema.registries.DefaultOidRegistry;
+import org.apache.directory.server.schema.registries.DefaultRegistries;
+import org.apache.directory.server.schema.registries.OidRegistry;
+import org.apache.directory.server.schema.registries.Registries;
+import org.apache.directory.server.unit.AbstractServerTest;
+import org.apache.directory.shared.ldap.name.LdapDN;
+import org.junit.Before;
+import org.junit.Test;
+import org.quartz.Job;
+import org.quartz.JobDataMap;
+import org.quartz.JobDetail;
+import org.quartz.JobExecutionContext;
+import org.quartz.JobExecutionException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * 
+ * TODO LdapJobStoreTest.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class LdapJobStoreITest extends AbstractServerTest
+{
+    
+    private static final Logger LOG = LoggerFactory.getLogger( LdapJobStoreITest.class );
+    
+    private boolean keepRunning = false;
+    
+    private LdapJobStore store;
+    
+    public LdapJobStoreITest()
+    {
+        keepRunning = Boolean.valueOf( System.getProperty( "keeprunning", "false") );
+    }
+    
+    @Before
+    public void setUp() throws Exception
+    {
+        super.setUp();
+
+        LdapDN sysDn = new LdapDN( "ou=system" );
+        sysDn.normalize( directoryService.getRegistries().getAttributeTypeRegistry().getNormalizerMapping() );
+        
+        Partition partition = directoryService.getPartitionNexus().getPartition( sysDn );
+        
+        store = new LdapJobStore( directoryService, partition, "ou=scheduler,ou=system" );
+        store.initialize( null, null );
+    }
+    
+    @Override
+    protected void configureDirectoryService() throws Exception
+    {
+        BootstrapSchemaLoader loader = new BootstrapSchemaLoader();
+        OidRegistry oidRegistry = new DefaultOidRegistry();
+        Registries registries = new DefaultRegistries( "bootstrap", loader, oidRegistry );
+        SerializableComparator.setRegistry( registries.getComparatorRegistry() );
+
+        // load essential bootstrap schemas
+        Set<Schema> bootstrapSchemas = new HashSet<Schema>();
+        bootstrapSchemas.add( new ApacheSchema() );
+        bootstrapSchemas.add( new ApachemetaSchema() );
+        bootstrapSchemas.add( new CoreSchema() );
+        bootstrapSchemas.add( new SystemSchema() );
+        bootstrapSchemas.add( new JavaSchema() );
+        bootstrapSchemas.add( new QuartzSchema() );
+        
+        loader.loadWithDependencies( bootstrapSchemas, registries );
+        
+        File wkdir = new File( System.getProperty( "java.io.tmpdir" ) + File.separator + getClass().getSimpleName() + System.currentTimeMillis() ) ;
+        wkdir.mkdirs();
+        
+        directoryService.setWorkingDirectory( wkdir );
+        directoryService.setRegistries( registries );
+    }
+    
+    
+    @Test
+    public void testStoreJob() throws Exception
+    {
+        Map<String,Object> map = new HashMap<String,Object>();
+        map.put( "key1", "value1" );
+        map.put( "key2", 1 );
+        map.put( "key3", TestJob.class );
+        
+        JobDataMap data = new JobDataMap( map );
+        
+        JobDetail job = new JobDetail( "testJobName", "testJobGroup", TestJob.class );
+        job.setRequestsRecovery( true );
+        job.setVolatility( true );
+        job.setJobDataMap( data );
+        
+        store.storeJob( null, job, false );
+        
+        JobDetail retrievedJob = store.retrieveJob( null, job.getName(), job.getGroup() );
+        LOG.warn( "retrievedjob {}", retrievedJob );
+        
+        assertNotNull( retrievedJob );
+        assertEquals( job.getName(), retrievedJob.getName() );
+        assertEquals( job.getGroup(), retrievedJob.getGroup() );
+        assertEquals( job.requestsRecovery(), retrievedJob.requestsRecovery() );
+        assertEquals( job.isDurable(), retrievedJob.isDurable() );
+        assertEquals( job.isVolatile(), retrievedJob.isVolatile() );
+        assertEquals( job.isStateful(), retrievedJob.isStateful() );
+        assertEquals( job.getClass(), retrievedJob.getClass() );
+        
+        for( Object key : job.getJobDataMap().keySet() )
+        {
+            assertEquals( job.getJobDataMap().get( key ), retrievedJob.getJobDataMap().get( key ) );
+        }
+    }
+    
+    
+    public void runServer() throws Exception
+    {
+        if( keepRunning )
+        {
+            LOG.warn( "Test Server listening on port :" + port );
+            LOG.warn( "Press Ctrl + C to stop. To disable test server running please set keeprunning system property to false" );
+            while( true )
+            {
+                Thread.sleep( 10000 );
+            }
+        }
+    }
+    
+    
+    class TestJob implements Job
+    {
+
+        public void execute( JobExecutionContext context ) throws JobExecutionException
+        {
+            
+        }
+    }
+}

Added: directory/sandbox/kayyagari/server-scheduler/src/test/resources/log4j.properties
URL: http://svn.apache.org/viewvc/directory/sandbox/kayyagari/server-scheduler/src/test/resources/log4j.properties?rev=702270&view=auto
==============================================================================
--- directory/sandbox/kayyagari/server-scheduler/src/test/resources/log4j.properties (added)
+++ directory/sandbox/kayyagari/server-scheduler/src/test/resources/log4j.properties Mon Oct  6 14:23:05 2008
@@ -0,0 +1,21 @@
+#############################################################################
+#    Licensed to the Apache Software Foundation (ASF) under one or more
+#    contributor license agreements.  See the NOTICE file distributed with
+#    this work for additional information regarding copyright ownership.
+#    The ASF licenses this file to You under the Apache License, Version 2.0
+#    (the "License"); you may not use this file except in compliance with
+#    the License.  You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS,
+#    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#    See the License for the specific language governing permissions and
+#    limitations under the License.
+#############################################################################
+log4j.rootCategory=WARN, stdout
+
+log4j.appender.stdout=org.apache.log4j.ConsoleAppender
+log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
+log4j.appender.stdout.layout.ConversionPattern=[%d{HH:mm:ss}] %p [%c] - %m%n