/**
* Copyright 2017 The University of North Carolina at Chapel Hill
*
* Licensed 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 edu.unc.lib.dl.util;
import static edu.unc.lib.dl.util.RedisWorkerConstants.DEPOSIT_MANIFEST_PREFIX;
import static edu.unc.lib.dl.util.RedisWorkerConstants.DEPOSIT_SET;
import static edu.unc.lib.dl.util.RedisWorkerConstants.DEPOSIT_STATUS_PREFIX;
import static edu.unc.lib.dl.util.RedisWorkerConstants.INGESTS_CONFIRMED_PREFIX;
import static edu.unc.lib.dl.util.RedisWorkerConstants.INGESTS_UPLOADED_PREFIX;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import edu.unc.lib.dl.util.RedisWorkerConstants.DepositAction;
import edu.unc.lib.dl.util.RedisWorkerConstants.DepositField;
import edu.unc.lib.dl.util.RedisWorkerConstants.DepositState;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
public class DepositStatusFactory {
private static final Logger log = LoggerFactory.getLogger(DepositStatusFactory.class);
JedisPool jedisPool;
public JedisPool getJedisPool() {
return jedisPool;
}
public void setJedisPool(JedisPool jedisPool) {
this.jedisPool = jedisPool;
}
public DepositStatusFactory() {}
public Map<String, String> get(String depositUUID) {
try (Jedis jedis = getJedisPool().getResource()) {
return jedis.hgetAll(DEPOSIT_STATUS_PREFIX + depositUUID);
}
}
public Set<Map<String, String>> getAll() {
Set<Map<String, String>> result = new HashSet<>();
try (Jedis jedis = getJedisPool().getResource()) {
Set<String> deposits = jedis.smembers(DEPOSIT_SET);
if (deposits != null) {
for(String uuid : deposits) {
result.add(jedis.hgetAll(DEPOSIT_STATUS_PREFIX + uuid));
}
}
}
return result;
}
public void addManifest(String depositUUID, String value) {
try (Jedis jedis = getJedisPool().getResource()) {
jedis.rpush(DEPOSIT_MANIFEST_PREFIX + depositUUID, value);
}
}
public List<String> getManifestURIs(String depositUUID) {
try (Jedis jedis = getJedisPool().getResource()) {
return jedis.lrange(DEPOSIT_MANIFEST_PREFIX + depositUUID, 0, -1);
}
}
/**
* Save deposit status, with the exception of incremented fields (jobs, octets, objects)
* @param status
*/
public void save(String depositUUID, Map<String, String> status) {
try (Jedis jedis = getJedisPool().getResource()) {
jedis.hmset(DEPOSIT_STATUS_PREFIX + depositUUID, status);
jedis.sadd(DEPOSIT_SET, depositUUID);
}
}
/**
* Set a single deposit field.
* @param status
*/
public void set(String depositUUID, DepositField field, String value) {
try (Jedis jedis = getJedisPool().getResource()) {
jedis.hset(DEPOSIT_STATUS_PREFIX + depositUUID, field.name(), value);
}
}
/**
* Locks the given deposit for a designated supervisor. These
* are short term locks and should be released after every
* set of jobs are queued.
* @param depositUUID identify of the deposit
* @param owner identity of the supervisor
* @return true if lock acquired
*/
public boolean addSupervisorLock(String depositUUID, String owner) {
try (Jedis jedis = getJedisPool().getResource()) {
Long result = jedis.hsetnx(DEPOSIT_STATUS_PREFIX + depositUUID,
DepositField.lock.name(), owner);
return result == 1;
}
}
/**
* Unlocks the given deposit, allowing a new supervisor to manage it.
* @param depositUUID
*/
public void removeSupervisorLock(String depositUUID) {
try (Jedis jedis = getJedisPool().getResource()) {
jedis.hdel(DEPOSIT_STATUS_PREFIX + depositUUID, DepositField.lock.name());
}
}
public DepositState getState(String depositUUID) {
try (Jedis jedis = getJedisPool().getResource()) {
String state = jedis.hget(DEPOSIT_STATUS_PREFIX + depositUUID, DepositField.state.name());
if (state == null) {
log.debug("No state was found for deposit {}", depositUUID);
return null;
}
return DepositState.valueOf(state);
}
}
public boolean isResumedDeposit(String depositUUID) {
try (Jedis jedis = getJedisPool().getResource()) {
return jedis.exists(INGESTS_UPLOADED_PREFIX + depositUUID);
}
}
public Set<String> getUnconfirmedUploads(String depositUUID) {
try (Jedis jedis = getJedisPool().getResource()) {
return jedis.sdiff(INGESTS_UPLOADED_PREFIX + depositUUID, INGESTS_CONFIRMED_PREFIX + depositUUID);
}
}
public Set<String> getConfirmedUploads(String depositUUID) {
try (Jedis jedis = getJedisPool().getResource()) {
return jedis.smembers(INGESTS_CONFIRMED_PREFIX + depositUUID);
}
}
public void addUploadedPID(String depositUUID, String pid) {
try (Jedis jedis = getJedisPool().getResource()) {
jedis.sadd(INGESTS_UPLOADED_PREFIX + depositUUID, pid);
}
}
public void addConfirmedPID(String depositUUID, String pid) {
try (Jedis jedis = getJedisPool().getResource()) {
jedis.sadd(INGESTS_CONFIRMED_PREFIX + depositUUID, pid);
}
}
public void setState(String depositUUID, DepositState state) {
try (Jedis jedis = getJedisPool().getResource()) {
jedis.hset(DEPOSIT_STATUS_PREFIX + depositUUID, DepositField.state.name(),
state.name());
}
}
public void setActionRequest(String depositUUID, DepositAction action) {
try (Jedis jedis = getJedisPool().getResource()) {
jedis.hset(DEPOSIT_STATUS_PREFIX + depositUUID, DepositField.actionRequest.name(), action.name());
}
}
public void incrIngestedObjects(String depositUUID, int amount) {
try (Jedis jedis = getJedisPool().getResource()) {
jedis.hincrBy(DEPOSIT_STATUS_PREFIX + depositUUID, DepositField.ingestedObjects.name(), amount);
}
}
public void fail(String depositUUID, String message) {
try (Jedis jedis = getJedisPool().getResource()) {
jedis.hset(DEPOSIT_STATUS_PREFIX + depositUUID, DepositField.state.name(), DepositState.failed.name());
if (message != null) {
jedis.hset(DEPOSIT_STATUS_PREFIX + depositUUID, DepositField.errorMessage.name(), message);
}
}
}
public void fail(String depositUUID) {
fail(depositUUID, null);
}
/**
* Delete deposit status.
* @param depositUUID
*/
public void delete(String depositUUID) {
try (Jedis jedis = getJedisPool().getResource()) {
jedis.del(DEPOSIT_STATUS_PREFIX + depositUUID);
}
}
public void deleteField(String depositUUID, DepositField field) {
try (Jedis jedis = getJedisPool().getResource()) {
jedis.hdel(DEPOSIT_STATUS_PREFIX + depositUUID, field.name());
}
}
public void requestAction(String depositUUID, DepositAction action) {
try (Jedis jedis = getJedisPool().getResource()) {
jedis.hset(DEPOSIT_STATUS_PREFIX + depositUUID, DepositField.actionRequest.name(),
action.name());
}
}
public void clearActionRequest(String depositUUID) {
try (Jedis jedis = getJedisPool().getResource()) {
jedis.hdel(DEPOSIT_STATUS_PREFIX + depositUUID, DepositField.actionRequest.name());
}
}
/**
* Expire the deposit status key after given interval.
* @param depositUUID
* @param seconds time until expire
*/
public void expireKeys(String depositUUID, int seconds) {
try (Jedis jedis = getJedisPool().getResource()) {
jedis.expire(DEPOSIT_STATUS_PREFIX + depositUUID, seconds);
jedis.expire(INGESTS_CONFIRMED_PREFIX + depositUUID, seconds);
jedis.expire(INGESTS_UPLOADED_PREFIX + depositUUID, seconds);
}
}
}