/**
* Abiquo community edition
* cloud management application for hybrid clouds
* Copyright (C) 2008-2010 - Abiquo Holdings S.L.
*
* This application is free software; you can redistribute it and/or
* modify it under the terms of the GNU LESSER GENERAL PUBLIC
* LICENSE as published by the Free Software Foundation under
* version 3 of the License
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* LESSER GENERAL PUBLIC LICENSE v.3 for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
package com.abiquo.server.core.task;
import static com.abiquo.model.redis.RedisEntityUtils.getEntityKey;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import org.springframework.stereotype.Component;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.Transaction;
import com.abiquo.model.redis.KeyMaker;
import com.abiquo.model.redis.RedisDAOBase;
import com.abiquo.model.redis.RedisEntityUtils;
import com.abiquo.server.core.task.Job.JobState;
import com.abiquo.server.core.task.Job.JobType;
/**
* This base class provides Redis-persistence logic for {@link Job} entity. <h3>Instance to persist</h3>
*
* <pre>
* job.id = 0
* job.type = RESET
* job.state = PENDING
* job.rollbackState = PENDING
* job.description = ""
* job.parentTaskId = 1
* job.timestamp = 123456789
* job.data = { "one":"somenicedata" }
* </pre>
*
* <h3>Redis structure</h3>
*
* <pre>
* HMSET Job:0 "id" "0" "type" "RESET" "state" "PENDING" "rollbackState" "PENDING "description" "parentTaskId" "1" "timestamp" "123456789" "data" "Job:0:data"
* HMSET Job:0:data "one" "somenicedata"
* </pre>
*
* @author eruiz@abiquo.com
*/
@Component
public class JobDAO extends RedisDAOBase<Job>
{
protected final KeyMaker keyMaker = new KeyMaker(Job.class);
public Job findById(final String jobId, Jedis jedis)
{
return find(getEntityKey(Job.class, jobId), jedis);
}
public List<Job> findJobs(final String jobsKey, Jedis jedis)
{
List<Job> jobs = new LinkedList<Job>();
for (String jobKey : jedis.lrange(jobsKey, 0, -1))
{
Job job = find(jobKey, jedis);
if (job != null)
{
jobs.add(job);
}
}
return jobs;
}
protected Job find(final String jobKey, Jedis jedis)
{
Map<String, String> hashed = jedis.hgetAll(jobKey);
if (hashed.isEmpty())
{
return null;
}
Job job = new Job();
job.setId(hashed.get("id"));
job.setType(JobType.valueOf(hashed.get("type")));
job.setState(JobState.valueOf(hashed.get("state")));
job.setRollbackState(JobState.valueOf(hashed.get("rollbackState")));
job.setDescription(hashed.get("description"));
job.setTimestamp(Long.parseLong(hashed.get("timestamp")));
job.setParentTaskId(hashed.get("parentTaskId"));
Map<String, String> data = jedis.hgetAll(getJobDataKey(job.getIdAsString()));
if (data != null && !data.isEmpty())
{
job.getData().putAll(data);
}
return job;
}
protected void updateTimestamp(final Job job, Transaction transaction)
{
String entityKey = job.getEntityKey();
transaction.hdel(entityKey, "timestamp");
transaction.hset(entityKey, "timestamp", String.valueOf(RedisEntityUtils.getUnixtime()));
}
@Override
public void delete(Job job, Transaction transaction)
{
transaction.del(job.getEntityKey());
transaction.del(getJobDataKey(job.getIdAsString()));
}
@Override
public void save(Job job, Transaction transaction)
{
// Clear to persist
delete(job, transaction);
// Hash plain fields
Map<String, String> hashed = new HashMap<String, String>();
hashed.put("id", job.getId());
hashed.put("type", job.getType().name());
hashed.put("state", job.getState().name());
hashed.put("rollbackState", job.getRollbackState().name());
hashed.put("description", job.getDescription());
hashed.put("parentTaskId", job.getParentTaskId());
hashed.put("timestamp", String.valueOf(RedisEntityUtils.getUnixtime()));
// Hash extra data map
String jobDataKey = getJobDataKey(job.getIdAsString());
hashed.put("data", jobDataKey);
// Persist
transaction.hmset(job.getEntityKey(), hashed);
if (!job.getData().isEmpty())
{
transaction.hmset(jobDataKey, job.getData());
}
}
private String getJobDataKey(final String jobId)
{
return keyMaker.make(jobId, "data");
}
}