Package com.abiquo.server.core.task

Source Code of com.abiquo.server.core.task.AsyncTaskRep

/**
* Copyright (C) 2008 - Abiquo Holdings S.L. All rights reserved.
*
* Please see /opt/abiquo/tomcat/webapps/legal/ on Abiquo server
* or contact contact@abiquo.com for licensing information.
*/
package com.abiquo.server.core.task;

import static java.lang.String.format;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.Transaction;

import com.abiquo.server.core.task.enums.TaskOwnerType;
import com.abiquo.server.core.task.enums.TaskState;
import com.google.common.collect.Lists;

/**
* Repository to manage the redis-based DAOs {@link TaskDAO} and {@link JobDAO} and to manage the
* indexes of task system.
*
* @author eruiz@abiquo.com
*/
@Component
public class AsyncTaskRep
{
    @Autowired
    private JedisPool jedisPool;

    @Autowired
    private TaskDAO taskDao;

    @Autowired
    private JobDAO jobDao;

    /**
     * Saves the indicated task. Just insert their jobs if they have not been previously persisted
     * (cascade on insert).
     *
     * @param task the task to save
     * @return the saved task
     */
    public Task save(final Task task)
    {
        Jedis jedis = jedisPool.getResource();

        // Collect the not inserted jobs (insert cascade)
        List<Job> jobsToInsert = Lists.newArrayList();

        for (Job job : task.getJobs())
        {
            if (!jedis.exists(job.getEntityKey()))
            {
                jobsToInsert.add(job);
            }
        }

        // Save logic
        Transaction transaction = jedis.multi();
        boolean discard = true;

        try
        {
            // Persist not persisted Jobs
            for (Job job : jobsToInsert)
            {
                job.setParentTaskId(task.getTaskId());
                jobDao.save(job, transaction);
            }

            // Persist task
            taskDao.save(task, transaction);

            // Index task and owner
            deindexTaskByOwner(task, transaction);
            indexTaskByOwner(task, transaction);
            indexTaskOwner(task, transaction);

            transaction.exec();
            discard = false;
        }
        finally
        {
            if (discard)
            {
                transaction.discard();
            }

            jedisPool.returnResource(jedis);
        }

        return task;
    }

    public void delete(final Task task)
    {
        Jedis jedis = jedisPool.getResource();
        Transaction transaction = jedis.multi();
        boolean discard = true;

        try
        {
            delete(task, transaction);
            transaction.exec();
            discard = false;
        }
        finally
        {
            if (discard)
            {
                transaction.discard();
            }

            jedisPool.returnResource(jedis);
        }
    }

    public void delete(final List<Task> tasks)
    {
        Jedis jedis = jedisPool.getResource();
        Transaction transaction = jedis.multi();
        boolean discard = true;

        try
        {
            for (Task task : tasks)
            {
                delete(task, transaction);
            }

            transaction.exec();
            discard = false;
        }
        finally
        {
            if (discard)
            {
                transaction.discard();
            }

            jedisPool.returnResource(jedis);
        }
    }

    private void delete(final Task task, final Transaction transaction)
    {
        // Delete referenced jobs
        for (Job job : task.getJobs())
        {
            jobDao.delete(job, transaction);
        }

        // Deindex task and owner
        deindexTaskByOwner(task, transaction);

        // Delete task
        taskDao.delete(task, transaction);
    }

    public List<Task> findTasksByOwnerId(final TaskOwnerType type, final String ownerId)
    {
        Jedis jedis = jedisPool.getResource();

        try
        {
            // Get the list of tasks indexed by owner type and id
            List<String> taskKeys = jedis.lrange(taskOwnerKey(type, ownerId), 0, -1);

            // Retrieve the whole Task entity
            List<Task> tasks = new ArrayList<Task>();

            for (String taskKey : taskKeys)
            {
                Task task = taskDao.find(taskKey, jedis);

                if (task != null)
                {
                    fillJobCollection(task, jedis);
                    tasks.add(task);
                }
            }

            return tasks;
        }
        finally
        {
            jedisPool.returnResource(jedis);
        }
    }

    public Task findTask(final String taskId)
    {
        Jedis jedis = jedisPool.getResource();

        try
        {
            Task task = taskDao.findById(taskId, jedis);
            fillJobCollection(task, jedis);

            return task;
        }
        finally
        {
            jedisPool.returnResource(jedis);
        }
    }

    public Task findNewestTask(final TaskOwnerType type, final String ownerId)
    {
        Jedis jedis = jedisPool.getResource();

        try
        {
            List<String> result = jedis.lrange(taskOwnerKey(type, ownerId), 0, 0);

            if (result.isEmpty())
            {
                return null;
            }

            Task task = taskDao.find(result.get(0), jedis);
            fillJobCollection(task, jedis);

            return task;
        }
        finally
        {
            jedisPool.returnResource(jedis);
        }
    }

    public TaskState findNewestTaskState(final TaskOwnerType type, final String ownerId)
    {
        Jedis jedis = jedisPool.getResource();

        try
        {
            List<String> result = jedis.lrange(taskOwnerKey(type, ownerId), 0, 0);

            if (result.isEmpty())
            {
                return null;
            }

            String taskKey = result.get(0);
            return taskDao.findTaskState(taskKey, jedis);
        }
        finally
        {
            jedisPool.returnResource(jedis);
        }
    }

    public Task findTaskByJobId(final String jobId)
    {
        Jedis jedis = jedisPool.getResource();

        try
        {
            Job job = findJob(jobId);
            return job != null ? findTask(job.getParentTaskId()) : null;
        }
        finally
        {
            jedisPool.returnResource(jedis);
        }
    }

    private Task fillJobCollection(final Task task, final Jedis jedis)
    {
        if (task != null)
        {
            task.getJobs().addAll(
                jobDao.findJobs(taskDao.getTaskJobsEntityKey(task.getIdAsString()), jedis));
        }

        return task;
    }

    public Job save(final Job job)
    {
        Jedis jedis = jedisPool.getResource();
        Transaction transaction = jedis.multi();
        boolean discard = true;

        try
        {
            jobDao.save(job, transaction);
            transaction.exec();
            discard = false;
        }
        finally
        {
            if (discard)
            {
                transaction.discard();
            }

            jedisPool.returnResource(jedis);
        }

        return job;
    }

    public Job findJob(final String jobId)
    {
        Jedis jedis = jedisPool.getResource();

        try
        {
            return jobDao.findById(jobId, jedis);
        }
        finally
        {
            jedisPool.returnResource(jedis);
        }
    }

    public void trimOwnersTasks(final TaskOwnerType type, final long numberOfTasks)
    {
        Jedis jedis = jedisPool.getResource();
        Jedis jedisTx = jedisPool.getResource();
        Transaction transaction = jedisTx.multi();
        boolean discard = true;

        try
        {
            Set<String> owners = jedis.smembers(ownerIndexKey(type));

            for (String owner : owners)
            {
                for (String taskKey : jedis.lrange(owner, numberOfTasks, -1))
                {
                    Task task = taskDao.find(taskKey, jedis);
                    delete(task, transaction);
                }
            }

            transaction.exec();
            discard = false;
        }
        finally
        {
            if (discard)
            {
                transaction.discard();
            }

            jedisPool.returnResource(jedisTx);
            jedisPool.returnResource(jedis);
        }
    }

    private void indexTaskByOwner(final Task task, final Transaction transaction)
    {
        transaction.lpush(taskOwnerKey(task), task.getEntityKey());
    }

    private void indexTaskOwner(final Task task, final Transaction transaction)
    {
        transaction.sadd(ownerIndexKey(task), taskOwnerKey(task));
    }

    private void deindexTaskByOwner(final Task task, final Transaction transaction)
    {
        transaction.lrem(taskOwnerKey(task), 0, task.getEntityKey());
    }

    private String taskOwnerKey(final Task task)
    {
        return taskOwnerKey(task.getType().getOwnerType(), task.getOwnerId());
    }

    private String taskOwnerKey(final TaskOwnerType type, final String ownerId)
    {
        return format("Owner:%s:%s", type.getName(), ownerId);
    }

    private String ownerIndexKey(final Task task)
    {
        return ownerIndexKey(task.getType().getOwnerType());
    }

    private String ownerIndexKey(final TaskOwnerType type)
    {
        return format("Owner:%s", type.getName());
    }
}
TOP

Related Classes of com.abiquo.server.core.task.AsyncTaskRep

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.