package com.enioka.admin;
import java.io.Closeable;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.Map;
import org.apache.shiro.crypto.SecureRandomNumberGenerator;
import org.apache.shiro.crypto.hash.Sha512Hash;
import org.apache.shiro.util.ByteSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.enioka.api.admin.GlobalParameterDto;
import com.enioka.api.admin.JndiObjectResourceDto;
import com.enioka.api.admin.JobDefDto;
import com.enioka.api.admin.NodeDto;
import com.enioka.api.admin.QueueDto;
import com.enioka.api.admin.QueueMappingDto;
import com.enioka.api.admin.RRoleDto;
import com.enioka.api.admin.RUserDto;
import com.enioka.jqm.jdbc.DatabaseException;
import com.enioka.jqm.jdbc.DbConn;
import com.enioka.jqm.jdbc.NoResultException;
import com.enioka.jqm.jdbc.NonUniqueResultException;
import com.enioka.jqm.jdbc.QueryResult;
import com.enioka.jqm.model.DeploymentParameter;
import com.enioka.jqm.model.GlobalParameter;
import com.enioka.jqm.model.JndiObjectResource;
import com.enioka.jqm.model.JobDef;
import com.enioka.jqm.model.JobDefParameter;
import com.enioka.jqm.model.Node;
import com.enioka.jqm.model.Queue;
import com.enioka.jqm.model.RRole;
import com.enioka.jqm.model.JobDef.PathType;
/**
* Set of methods to handle metadata.
*/
public class MetaService
{
private static Logger jqmlogger = LoggerFactory.getLogger(MetaService.class);
private static void closeQuietly(Closeable closeable)
{
try
{
if (closeable != null)
{
closeable.close();
}
}
catch (Exception e)
{
// fail silently
}
}
///////////////////////////////////////////////////////////////////////////
// GLOBAL DELETE
///////////////////////////////////////////////////////////////////////////
/**
* Empty the database. <br>
* No commit performed.
*
* @param cnx
* database session to use. Not commited.
* @param force
* set to true if you want to delete metadata even if there is still transactional data depending on it.
*/
public static void deleteAllMeta(DbConn cnx, boolean force)
{
if (force)
{
deleteAllTransac(cnx);
}
cnx.runUpdate("globalprm_delete_all");
cnx.runUpdate("dp_delete_all");
cnx.runUpdate("jdprm_delete_all");
cnx.runUpdate("node_delete_all");
cnx.runUpdate("jd_delete_all");
cnx.runUpdate("q_delete_all");
cnx.runUpdate("jndiprm_delete_all");
cnx.runUpdate("jndi_delete_all");
cnx.runUpdate("pki_delete_all"); // No corresponding DTO.
cnx.runUpdate("perm_delete_all");
cnx.runUpdate("role_delete_all");
cnx.runUpdate("user_delete_all");
}
/**
* This method is an exception - it does not deal with metadata but transactional data. It is included here to allow easier purge of
* metadata.<br>
* No commit performed.
*
* @param cnx
*/
public static void deleteAllTransac(DbConn cnx)
{
cnx.runUpdate("deliverable_delete_all");
cnx.runUpdate("message_delete_all");
cnx.runUpdate("history_delete_all");
cnx.runUpdate("jiprm_delete_all");
cnx.runUpdate("ji_delete_all");
}
///////////////////////////////////////////////////////////////////////////
// GLOBAL PARAMETER
///////////////////////////////////////////////////////////////////////////
public static void deleteGlobalParameter(DbConn cnx, int id)
{
QueryResult qr = cnx.runUpdate("globalprm_delete_by_id", id);
if (qr.nbUpdated != 1)
{
cnx.setRollbackOnly();
throw new JqmAdminApiUserException("no item with ID " + id);
}
}
public static void upsertGlobalParameter(DbConn cnx, GlobalParameterDto dto)
{
if (dto == null || dto.getKey() == null || dto.getKey().isEmpty() || dto.getValue() == null || dto.getValue().isEmpty())
{
throw new IllegalArgumentException("invalid dto object");
}
GlobalParameter.setParameter(cnx, dto.getKey(), dto.getValue());
}
private static GlobalParameterDto mapGlobalParameter(ResultSet rs) throws SQLException
{
GlobalParameterDto res = new GlobalParameterDto();
res.setId(rs.getInt(1));
res.setKey(rs.getString(2));
res.setValue(rs.getString(3));
return res;
}
private static GlobalParameterDto getGlobalParameter(DbConn cnx, String query_key, Object key)
{
ResultSet rs = cnx.runSelect(query_key, key);
try
{
if (!rs.next())
{
throw new NoResultException("The query returned zero rows when one was expected.");
}
GlobalParameterDto res = mapGlobalParameter(rs);
if (rs.next())
{
throw new NonUniqueResultException("The query returned more than one row when one was expected");
}
rs.close();
return res;
}
catch (SQLException e)
{
throw new JqmAdminApiInternalException("An error occurred while querying the database", e);
}
}
public static GlobalParameterDto getGlobalParameter(DbConn cnx, String key)
{
return getGlobalParameter(cnx, "globalprm_select_by_key", key);
}
public static GlobalParameterDto getGlobalParameter(DbConn cnx, Integer key)
{
return getGlobalParameter(cnx, "globalprm_select_by_id", key);
}
public static List<GlobalParameterDto> getGlobalParameter(DbConn cnx)
{
ResultSet rs = cnx.runSelect("globalprm_select_all");
List<GlobalParameterDto> res = new ArrayList<GlobalParameterDto>();
try
{
while (rs.next())
{
res.add(mapGlobalParameter(rs));
}
rs.close();
}
catch (SQLException e)
{
throw new JqmAdminApiInternalException("An error occurred while querying the database", e);
}
return res;
}
public static void syncGlobalParameters(DbConn cnx, List<GlobalParameterDto> dtos)
{
for (GlobalParameterDto existing : getGlobalParameter(cnx))
{
boolean foundInNewSet = false;
for (GlobalParameterDto newdto : dtos)
{
if (newdto.getId() != null && newdto.getId().equals(existing.getId()))
{
foundInNewSet = true;
break;
}
}
if (!foundInNewSet)
{
deleteGlobalParameter(cnx, existing.getId());
}
}
for (GlobalParameterDto dto : dtos)
{
upsertGlobalParameter(cnx, dto);
}
}
///////////////////////////////////////////////////////////////////////////
// JNDI
///////////////////////////////////////////////////////////////////////////
public static void deleteJndiObjectResource(DbConn cnx, int id)
{
cnx.runUpdate("jndiprm_delete_for_resource", id);
QueryResult qr = cnx.runUpdate("globalprm_delete_by_id", id);
if (qr.nbUpdated != 1)
{
cnx.setRollbackOnly();
throw new JqmAdminApiUserException("no item with ID " + id);
}
}
/**
* Update or insert a resource. Convention is that if dto.id is null, we always insert. If non null, always update. (so we use the
* technical key, not the functional key - because the functional key can itself be updated!<br>
* <br>
* This method only updates (and sets the timestamp for last update) if there are actual modifications done. Modifications are detected
* by value comparison on all fields (except the ID, but including parameters).
*
* @param cnx
* @param dto
*/
public static void upsertJndiObjectResource(DbConn cnx, JndiObjectResourceDto dto)
{
if (dto.getId() != null)
{
QueryResult qr = cnx.runUpdate("jndi_update_changed_by_id", dto.getAuth(), dto.getDescription(), dto.getFactory(),
dto.getName(), dto.getSingleton(), dto.getTemplate(), dto.getType(), dto.getId(), dto.getAuth(), dto.getDescription(),
dto.getFactory(), dto.getName(), dto.getSingleton(), dto.getTemplate(), dto.getType());
if (qr.nbUpdated != 1)
{
jqmlogger.debug("No update was done as object either does not exist or no modifications were done");
}
// Sync parameters too
for (Map.Entry<String, String> e : dto.getParameters().entrySet())
{
QueryResult qr2 = cnx.runUpdate("jndiprm_update_changed_by_id", e.getValue(), e.getKey(), e.getValue());
if (qr2.nbUpdated == 0)
{
cnx.runUpdate("jndiprm_insert", e.getKey(), e.getValue(), dto.getId());
}
}
ResultSet rs = cnx.runSelect("jndiprm_select_all_in_jndisrc", dto.getId());
try
{
while (rs.next())
{
String key = rs.getString(2);
int id = rs.getInt(1);
if (!dto.getParameters().containsKey(key))
{
cnx.runUpdate("jndiprm_delete_by_id", id);
}
}
rs.close();
}
catch (Exception e)
{
throw new JqmAdminApiInternalException(e);
}
}
else
{
JndiObjectResource.create(cnx, dto.getName(), dto.getType(), dto.getFactory(), dto.getDescription(), dto.getSingleton(),
dto.getParameters());
}
}
private static JndiObjectResourceDto mapJndiObjectResource(ResultSet rs) throws SQLException
{
JndiObjectResourceDto res = new JndiObjectResourceDto();
res.setId(rs.getInt(1));
res.setName(rs.getString(2));
res.setAuth(rs.getString(3));
res.setType(rs.getString(4));
res.setFactory(rs.getString(5));
res.setDescription(rs.getString(6));
res.setTemplate(rs.getString(7));
res.setSingleton(rs.getBoolean(8));
return res;
}
private static JndiObjectResourceDto getJndiObjectResource(DbConn cnx, String query_key, Object key)
{
ResultSet rs = cnx.runSelect(query_key, key);
try
{
if (!rs.next())
{
throw new NoResultException("The query returned zero rows when one was expected.");
}
JndiObjectResourceDto res = mapJndiObjectResource(rs);
if (rs.next())
{
throw new NonUniqueResultException("The query returned more than one row when one was expected");
}
rs.close();
return res;
}
catch (SQLException e)
{
throw new JqmAdminApiInternalException("An error occurred while querying the database", e);
}
}
public static JndiObjectResourceDto getJndiObjectResource(DbConn cnx, String key)
{
return getJndiObjectResource(cnx, "globalprm_select_by_key", key);
}
public static JndiObjectResourceDto getJndiObjectResource(DbConn cnx, Integer key)
{
return getJndiObjectResource(cnx, "globalprm_select_by_id", key);
}
public static List<JndiObjectResourceDto> getJndiObjectResource(DbConn cnx)
{
ResultSet rs = cnx.runSelect("jndi_select_all");
List<JndiObjectResourceDto> res = new ArrayList<JndiObjectResourceDto>();
List<Integer> rscIds = new ArrayList<Integer>();
try
{
// The resources
while (rs.next())
{
JndiObjectResourceDto tmp = mapJndiObjectResource(rs);
rscIds.add(tmp.getId());
res.add(tmp);
}
rs.close();
// The parameters
rs = cnx.runSelect("jndiprm_select_all_in_jndisrc_list", rscIds);
while (rs.next())
{
String key = rs.getString(2);
String value = rs.getString(4);
int rid = rs.getInt(5);
for (JndiObjectResourceDto tmp : res)
{
if (tmp.getId().equals(rid))
{
tmp.addParameter(key, value);
break;
}
}
}
rs.close();
}
catch (SQLException e)
{
throw new JqmAdminApiInternalException("An error occurred while querying the database", e);
}
return res;
}
public static void syncJndiObjectResource(DbConn cnx, List<JndiObjectResourceDto> dtos)
{
for (JndiObjectResourceDto existing : getJndiObjectResource(cnx))
{
boolean foundInNewSet = false;
for (JndiObjectResourceDto newdto : dtos)
{
if (newdto.getId() != null && newdto.getId().equals(existing.getId()))
{
foundInNewSet = true;
break;
}
}
if (!foundInNewSet)
{
deleteJndiObjectResource(cnx, existing.getId());
}
}
for (JndiObjectResourceDto dto : dtos)
{
upsertJndiObjectResource(cnx, dto);
}
}
///////////////////////////////////////////////////////////////////////////
// JOB DEF
///////////////////////////////////////////////////////////////////////////
public static void deleteJobDef(DbConn cnx, int id)
{
int countRunning = cnx.runSelectSingle("ji_select_count_by_jd", Integer.class, id);
if (countRunning > 0)
{
throw new JqmAdminApiUserException(
"cannot delete a job definition with running instances. Disable it, wait for the end of all running instances, then retry.");
}
cnx.runUpdate("jdprm_delete_all_for_jd", id);
QueryResult qr = cnx.runUpdate("jd_delete_by_id", id);
if (qr.nbUpdated != 1)
{
cnx.setRollbackOnly();
throw new JqmAdminApiUserException("no item with ID " + id);
}
}
private static JobDefDto mapJobDef(ResultSet rs, int colShift)
{
JobDefDto tmp = new JobDefDto();
try
{
tmp.setId(rs.getInt(1 + colShift));
tmp.setApplication(rs.getString(2 + colShift));
tmp.setApplicationName(rs.getString(3 + colShift));
tmp.setCLassLoaderId(rs.getInt(4 + colShift));
tmp.setCanBeRestarted(true);
tmp.setDescription(rs.getString(5 + colShift));
tmp.setEnabled(rs.getBoolean(6 + colShift));
// tmp. = rs.getBoolean(7 + colShift); // TODO: external exposure?
tmp.setHighlander(rs.getBoolean(8 + colShift));
tmp.setJarPath(rs.getString(9 + colShift));
tmp.setJavaClassName(rs.getString(10 + colShift));
// tmp.javaOpts = rs.getString(11 + colShift);
tmp.setKeyword1(rs.getString(12 + colShift));
tmp.setKeyword2(rs.getString(13 + colShift));
tmp.setKeyword3(rs.getString(14 + colShift));
tmp.setReasonableRuntimeLimitMinute(rs.getInt(15 + colShift));
tmp.setModule(rs.getString(16 + colShift));
tmp.setQueueId(rs.getInt(18 + colShift));
}
catch (SQLException e)
{
throw new JqmAdminApiInternalException(e);
}
return tmp;
}
private static void addJobDefParametersToDto(DbConn cnx, List<JobDefDto> dtos)
{
List<Integer> ids = new ArrayList<Integer>();
for (JobDefDto dto : dtos)
{
ids.add(dto.getId());
}
try
{
ResultSet rs = cnx.runSelect("jdprm_select_all_for_jd_list", ids);
while (rs.next())
{
String key = rs.getString(2);
String value = rs.getString(3);
int id = rs.getInt(4);
for (JobDefDto dto : dtos)
{
if (dto.getId().equals(id))
{
dto.getParameters().put(key, value);
break;
}
}
}
rs.close();
}
catch (Exception e)
{
throw new JqmAdminApiInternalException(e);
}
}
public static List<JobDefDto> getJobDef(DbConn cnx)
{
List<JobDefDto> res = new ArrayList<JobDefDto>();
try
{
ResultSet rs = cnx.runSelect("jd_select_all");
while (rs.next())
{
res.add(mapJobDef(rs, 0));
}
rs.close();
addJobDefParametersToDto(cnx, res);
}
catch (SQLException e)
{
throw new DatabaseException(e);
}
return res;
}
public static JobDefDto getJobDef(DbConn cnx, int id)
{
ResultSet rs = null;
try
{
rs = cnx.runSelect("jd_select_by_id");
if (!rs.next())
{
throw new JqmAdminApiUserException("no result");
}
JobDefDto tmp = mapJobDef(rs, 0);
List<JobDefDto> tmp2 = new ArrayList<JobDefDto>();
tmp2.add(tmp);
addJobDefParametersToDto(cnx, tmp2);
return tmp;
}
catch (SQLException e)
{
throw new DatabaseException(e);
}
finally
{
closeQuietly(cnx);
}
}
public static void upsertJobDef(DbConn cnx, JobDefDto dto)
{
if (dto.getId() != null)
{
// Job: do it in a brutal way (no date to update here).
cnx.runUpdate("jd_update_all_fields_by_id", dto.getApplication(), dto.getApplicationName(), false, dto.getDescription(),
dto.isEnabled(), false, dto.isHighlander(), dto.getJarPath(), dto.getJavaClassName(), null, dto.getKeyword1(),
dto.getKeyword2(), dto.getKeyword3(), dto.getReasonableRuntimeLimitMinute(), dto.getModule(), PathType.FS,
dto.getClassLoaderId(), dto.getQueueId(), dto.getId());
cnx.runUpdate("jdprm_delete_all_for_jd", dto.getId());
for (Map.Entry<String, String> e : dto.getParameters().entrySet())
{
JobDefParameter.create(cnx, e.getKey(), e.getValue(), dto.getId());
}
}
else
{
JobDef.create(cnx, dto.getDescription(), dto.getJavaClassName(), dto.getParameters(), dto.getJarPath(), dto.getQueueId(),
dto.getReasonableRuntimeLimitMinute(), dto.getApplicationName(), dto.getApplication(), dto.getModule(),
dto.getKeyword1(), dto.getKeyword2(), dto.getKeyword3(), dto.isHighlander(), dto.getClassLoaderId(), PathType.FS);
}
}
public static void syncJobDefs(DbConn cnx, List<JobDefDto> dtos)
{
for (JobDefDto existing : getJobDef(cnx))
{
boolean foundInNewSet = false;
for (JobDefDto newdto : dtos)
{
if (newdto.getId() != null && newdto.getId().equals(existing.getId()))
{
foundInNewSet = true;
break;
}
}
if (!foundInNewSet)
{
deleteJobDef(cnx, existing.getId());
}
}
for (JobDefDto dto : dtos)
{
upsertJobDef(cnx, dto);
}
}
///////////////////////////////////////////////////////////////////////////
// NODE
///////////////////////////////////////////////////////////////////////////
public static void deleteNode(DbConn cnx, int id)
{
int countRunning = cnx.runSelectSingle("ji_select_count_by_node", Integer.class, id);
if (countRunning > 0)
{
cnx.setRollbackOnly();
throw new JqmAdminApiUserException(
"cannot delete a node with running instances. Disable it, wait for the end of all running instances, then retry.");
}
try
{
Node n = Node.select_single(cnx, "node_select_by_id", id);
Calendar limit = Calendar.getInstance();
limit.add(Calendar.MINUTE, -10);
if (n.getLastSeenAlive() != null && n.getLastSeenAlive().after(limit))
{
cnx.setRollbackOnly();
throw new JqmAdminApiUserException(
"Can only remove a node either properly shut down or that has crashed more than 10 minutes ago.");
}
}
catch (NoResultException e)
{
throw new JqmAdminApiUserException("no item with ID " + id);
}
cnx.runUpdate("dp_delete_for_node", id);
QueryResult qr = cnx.runUpdate("node_delete_by_id", id);
if (qr.nbUpdated != 1)
{
cnx.setRollbackOnly();
throw new JqmAdminApiUserException("no item with ID " + id);
}
}
static NodeDto mapNode(ResultSet rs, int colShift)
{
try
{
NodeDto tmp = new NodeDto();
tmp.setId(rs.getInt(1 + colShift));
tmp.setOutputDirectory(rs.getString(2 + colShift));
tmp.setDns(rs.getString(3 + colShift));
tmp.setEnabled(rs.getBoolean(4 + colShift));
tmp.setJmxRegistryPort(rs.getInt(6 + colShift));
tmp.setJmxServerPort(rs.getInt(7 + colShift));
tmp.setLoadApiAdmin(rs.getBoolean(8 + colShift));
tmp.setLoadApiClient(rs.getBoolean(9 + colShift));
tmp.setLoapApiSimple(rs.getBoolean(10 + colShift));
tmp.setName(rs.getString(11 + colShift));
tmp.setPort(rs.getInt(12 + colShift));
tmp.setJobRepoDirectory(rs.getString(13 + colShift));
tmp.setRootLogLevel(rs.getString(14 + colShift));
tmp.setStop(rs.getBoolean(15 + colShift));
tmp.setTmpDirectory(rs.getString(16 + colShift));
Calendar c = null;
if (rs.getTimestamp(17 + colShift) != null)
{
c = Calendar.getInstance();
c.setTimeInMillis(rs.getTimestamp(17 + colShift).getTime());
}
tmp.setLastSeenAlive(c);
return tmp;
}
catch (SQLException e)
{
throw new DatabaseException(e);
}
}
public static List<NodeDto> getNodes(DbConn cnx)
{
List<NodeDto> res = new ArrayList<NodeDto>();
try
{
ResultSet rs = cnx.runSelect("node_select_all");
while (rs.next())
{
res.add(mapNode(rs, 0));
}
rs.close();
}
catch (SQLException e)
{
throw new DatabaseException(e);
}
return res;
}
public static NodeDto getNode(DbConn cnx, int id)
{
ResultSet rs = null;
try
{
rs = cnx.runSelect("node_select_by_id");
if (!rs.next())
{
throw new JqmAdminApiUserException("no result");
}
return mapNode(rs, 0);
}
catch (SQLException e)
{
throw new DatabaseException(e);
}
finally
{
closeQuietly(cnx);
}
}
public static void upsertNode(DbConn cnx, NodeDto dto)
{
if (dto.getId() != null)
{
cnx.runUpdate("node_update_changed_by_id", dto.getOutputDirectory(), dto.getDns(), dto.getEnabled(), dto.getJmxRegistryPort(),
dto.getJmxServerPort(), dto.getLoadApiAdmin(), dto.getLoadApiClient(), dto.getLoapApiSimple(), dto.getName(),
dto.getPort(), dto.getJobRepoDirectory(), dto.getRootLogLevel(), dto.getStop(), dto.getTmpDirectory(), dto.getId(),
dto.getOutputDirectory(), dto.getDns(), dto.getEnabled(), dto.getJmxRegistryPort(), dto.getJmxServerPort(),
dto.getLoadApiAdmin(), dto.getLoadApiClient(), dto.getLoapApiSimple(), dto.getName(), dto.getPort(),
dto.getJobRepoDirectory(), dto.getRootLogLevel(), dto.getStop(), dto.getTmpDirectory());
}
else
{
// Should actually never be used... nodes should be created through CLI.
Node.create(cnx, dto.getName(), dto.getPort(), dto.getOutputDirectory(), dto.getJobRepoDirectory(), dto.getTmpDirectory(),
dto.getDns());
}
}
public static void syncNodes(DbConn cnx, List<NodeDto> dtos)
{
for (NodeDto existing : getNodes(cnx))
{
boolean foundInNewSet = false;
for (NodeDto newdto : dtos)
{
if (newdto.getId() != null && newdto.getId().equals(existing.getId()))
{
foundInNewSet = true;
break;
}
}
if (!foundInNewSet)
{
deleteQueue(cnx, existing.getId());
}
}
for (NodeDto dto : dtos)
{
upsertNode(cnx, dto);
}
}
///////////////////////////////////////////////////////////////////////////
// QUEUE
///////////////////////////////////////////////////////////////////////////
public static void deleteQueue(DbConn cnx, int id)
{
int countRunning = cnx.runSelectSingle("ji_select_count_by_queue", Integer.class, id);
if (countRunning > 0)
{
cnx.setRollbackOnly();
throw new JqmAdminApiUserException(
"cannot delete a queue with running instances. Disable it, wait for the end of all running instances, then retry.");
}
cnx.runUpdate("dp_delete_for_queue", id);
QueryResult qr = cnx.runUpdate("q_delete_by_id", id);
if (qr.nbUpdated != 1)
{
cnx.setRollbackOnly();
throw new JqmAdminApiUserException("no item with ID " + id);
}
}
private static QueueDto mapQueue(ResultSet rs, int colShift)
{
try
{
QueueDto tmp = new QueueDto();
tmp.setId(rs.getInt(1 + colShift));
tmp.setDefaultQueue(rs.getBoolean(2 + colShift));
tmp.setDescription(rs.getString(3 + colShift));
tmp.setName(rs.getString(4 + colShift));
return tmp;
}
catch (SQLException e)
{
throw new JqmAdminApiInternalException(e);
}
}
public static List<QueueDto> getQueues(DbConn cnx)
{
List<QueueDto> res = new ArrayList<QueueDto>();
try
{
ResultSet rs = cnx.runSelect("q_select_all");
while (rs.next())
{
res.add(mapQueue(rs, 0));
}
rs.close();
}
catch (SQLException e)
{
throw new DatabaseException(e);
}
return res;
}
public static QueueDto getQueue(DbConn cnx, int id)
{
ResultSet rs = null;
try
{
rs = cnx.runSelect("q_select_by_id");
if (!rs.next())
{
throw new JqmAdminApiUserException("no result");
}
return mapQueue(rs, 0);
}
catch (SQLException e)
{
throw new DatabaseException(e);
}
finally
{
closeQuietly(cnx);
}
}
public static void upsertQueue(DbConn cnx, QueueDto dto)
{
if (dto.getId() != null)
{
cnx.runUpdate("q_update_changed_by_id", dto.isDefaultQueue(), dto.getDescription(), dto.getName(), dto.getId(),
dto.isDefaultQueue(), dto.getDescription(), dto.getName());
}
else
{
Queue.create(cnx, dto.getName(), dto.getDescription(), dto.isDefaultQueue());
}
}
public static void syncQueues(DbConn cnx, List<QueueDto> dtos)
{
for (QueueDto existing : getQueues(cnx))
{
boolean foundInNewSet = false;
for (QueueDto newdto : dtos)
{
if (newdto.getId() != null && newdto.getId().equals(existing.getId()))
{
foundInNewSet = true;
break;
}
}
if (!foundInNewSet)
{
deleteQueue(cnx, existing.getId());
}
}
for (QueueDto dto : dtos)
{
upsertQueue(cnx, dto);
}
}
///////////////////////////////////////////////////////////////////////////
// DEPLOYMENT PARAMETER
///////////////////////////////////////////////////////////////////////////
public static void deleteQueueMapping(DbConn cnx, int id)
{
QueryResult qr = cnx.runUpdate("dp_delete_by_id", id);
if (qr.nbUpdated != 1)
{
cnx.setRollbackOnly();
throw new JqmAdminApiUserException("no item with ID " + id);
}
}
private static QueueMappingDto mapQueueMapping(ResultSet rs, int colShift)
{
try
{
QueueMappingDto tmp = new QueueMappingDto();
tmp.setId(rs.getInt(1 + colShift));
tmp.setEnabled(rs.getBoolean(2 + colShift));
tmp.setNbThread(rs.getInt(4 + colShift));
tmp.setPollingInterval(rs.getInt(5 + colShift));
tmp.setNodeId(rs.getInt(6 + colShift));
tmp.setQueueId(rs.getInt(7 + colShift));
tmp.setNodeName(rs.getString(8 + colShift));
tmp.setQueueName(rs.getString(9 + colShift));
return tmp;
}
catch (SQLException e)
{
throw new JqmAdminApiInternalException(e);
}
}
public static List<QueueMappingDto> getQueueMappings(DbConn cnx)
{
List<QueueMappingDto> res = new ArrayList<QueueMappingDto>();
try
{
ResultSet rs = cnx.runSelect("dp_select_all_with_names");
while (rs.next())
{
res.add(mapQueueMapping(rs, 0));
}
rs.close();
}
catch (SQLException e)
{
throw new DatabaseException(e);
}
return res;
}
public static QueueMappingDto getQueueMapping(DbConn cnx, int id)
{
ResultSet rs = null;
try
{
rs = cnx.runSelect("dp_select_with_names_by_id");
if (!rs.next())
{
throw new JqmAdminApiUserException("no result");
}
return mapQueueMapping(rs, 0);
}
catch (SQLException e)
{
throw new DatabaseException(e);
}
finally
{
closeQuietly(cnx);
}
}
public static void upsertQueueMapping(DbConn cnx, QueueMappingDto dto)
{
if (dto.getId() != null)
{
cnx.runUpdate("dp_update_changed_by_id", dto.getEnabled(), dto.getNbThread(), dto.getPollingInterval(), dto.getNodeId(),
dto.getQueueId(), dto.getId(), dto.getEnabled(), dto.getNbThread(), dto.getPollingInterval(), dto.getNodeId(),
dto.getQueueId());
}
else
{
DeploymentParameter.create(cnx, dto.getNodeId(), dto.getNbThread(), dto.getPollingInterval(), dto.getQueueId());
}
}
public static void syncQueueMappings(DbConn cnx, List<QueueMappingDto> dtos)
{
for (QueueMappingDto existing : getQueueMappings(cnx))
{
boolean foundInNewSet = false;
for (QueueMappingDto newdto : dtos)
{
if (newdto.getId() != null && newdto.getId().equals(existing.getId()))
{
foundInNewSet = true;
break;
}
}
if (!foundInNewSet)
{
deleteQueue(cnx, existing.getId());
}
}
for (QueueMappingDto dto : dtos)
{
upsertQueueMapping(cnx, dto);
}
}
///////////////////////////////////////////////////////////////////////////
// ROLE
///////////////////////////////////////////////////////////////////////////
public static void deleteRole(DbConn cnx, int id, boolean force)
{
if (force)
{
cnx.runUpdate("user_remove_role", id);
}
else
{
int userUsingRole = cnx.runSelectSingle("user_select_count_using_role", Integer.class, id);
if (userUsingRole > 0)
{
cnx.setRollbackOnly();
throw new JqmAdminApiUserException(
"cannot delete a role currently attributed to a user. Remove role attribution of use force parameter.");
}
}
QueryResult qr = cnx.runUpdate("role_delete_by_id", id);
if (qr.nbUpdated != 1)
{
cnx.setRollbackOnly();
throw new JqmAdminApiUserException("no item with ID " + id);
}
}
private static RRoleDto mapRole(ResultSet rs, int colShift)
{
try
{
RRoleDto tmp = new RRoleDto();
tmp.setId(rs.getInt(1 + colShift));
tmp.setName(rs.getString(2 + colShift));
tmp.setDescription(rs.getString(3 + colShift));
return tmp;
}
catch (SQLException e)
{
throw new JqmAdminApiInternalException(e);
}
}
private static List<RRoleDto> getRoles(DbConn cnx, String query_key, int colShift, Object... args)
{
List<RRoleDto> res = new ArrayList<RRoleDto>();
try
{
ResultSet rs = cnx.runSelect(query_key, args);
RRoleDto tmp = null;
while (rs.next())
{
tmp = mapRole(rs, colShift);
res.add(tmp);
}
rs.close();
List<Integer> ids = new ArrayList<Integer>();
for (RRoleDto dto : res)
{
ids.add(dto.getId());
}
rs = cnx.runSelect("perm_select_all_in_role_list", ids);
while (rs.next())
{
int role_id = rs.getInt(3);
String permName = rs.getString(2);
for (RRoleDto dto : res)
{
if (dto.getId().equals(role_id))
{
dto.addPermission(permName);
}
}
}
rs.close();
}
catch (SQLException e)
{
throw new DatabaseException(e);
}
return res;
}
public static List<RRoleDto> getRoles(DbConn cnx)
{
return getRoles(cnx, "role_select_all", 0);
}
public static RRoleDto getRole(DbConn cnx, int id)
{
List<RRoleDto> res = getRoles(cnx, "role_select_by_id", 0, id);
if (res.size() == 1)
{
return res.get(0);
}
else
{
throw new JqmAdminApiUserException("no result");
}
}
public static void upsertRole(DbConn cnx, RRoleDto dto)
{
if (dto.getId() != null)
{
cnx.runUpdate("role_update_all_by_id", dto.getName(), dto.getDescription(), dto.getId());
// Permissions
cnx.runUpdate("perm_delete_for_role", dto.getId());
for (String i : dto.getPermissions())
{
cnx.runUpdate("perm_insert", i, dto.getId());
}
}
else
{
RRole.create(cnx, dto.getName(), dto.getDescription(), dto.getPermissions().toArray(new String[dto.getPermissions().size()]));
}
}
public static void syncRoles(DbConn cnx, List<RRoleDto> dtos)
{
for (RRoleDto existing : getRoles(cnx))
{
boolean foundInNewSet = false;
for (RRoleDto newdto : dtos)
{
if (newdto.getId() != null && newdto.getId().equals(existing.getId()))
{
foundInNewSet = true;
break;
}
}
if (!foundInNewSet)
{
deleteRole(cnx, existing.getId(), false);
}
}
for (RRoleDto dto : dtos)
{
upsertRole(cnx, dto);
}
}
///////////////////////////////////////////////////////////////////////////
// USER
///////////////////////////////////////////////////////////////////////////
public static void deleteUser(DbConn cnx, int id)
{
QueryResult qr = cnx.runUpdate("user_delete_by_id", id);
if (qr.nbUpdated != 1)
{
cnx.setRollbackOnly();
throw new JqmAdminApiUserException("no item with ID " + id);
}
}
private static RUserDto mapUser(ResultSet rs, int colShift, DbConn cnx)
{
try
{
RUserDto tmp = new RUserDto();
tmp.setId(rs.getInt(1 + colShift));
tmp.setLogin(rs.getString(2 + colShift));
tmp.setLocked(rs.getBoolean(5 + colShift));
tmp.setExpirationDate(cnx.getCal(rs, 6 + colShift));
tmp.setCreationDate(cnx.getCal(rs, 7 + colShift));
tmp.setEmail(rs.getString(9 + colShift));
tmp.setFreeText(rs.getString(10 + colShift));
tmp.setInternal(rs.getBoolean(11 + colShift));
return tmp;
}
catch (SQLException e)
{
throw new JqmAdminApiInternalException(e);
}
}
private static List<RUserDto> getUsers(DbConn cnx, String query_key, int colShift, Object... params)
{
List<RUserDto> res = new ArrayList<RUserDto>();
try
{
ResultSet rs = cnx.runSelect(query_key);
RUserDto tmp = null;
while (rs.next())
{
tmp = mapUser(rs, colShift, cnx);
res.add(tmp);
}
rs.close();
List<Integer> ids = new ArrayList<Integer>();
for (RUserDto dto : res)
{
ids.add(dto.getId());
}
rs = cnx.runSelect("role_select_id_for_user_list", ids);
while (rs.next())
{
int userId = rs.getInt(2);
int roleId = rs.getInt(1);
for (RUserDto dto : res)
{
if (dto.getId().equals(userId))
{
dto.addRole(roleId);
}
}
}
rs.close();
}
catch (SQLException e)
{
throw new DatabaseException(e);
}
return res;
}
public static List<RUserDto> getUsers(DbConn cnx)
{
return getUsers(cnx, "user_select_all", 0);
}
public static RUserDto getUser(DbConn cnx, int id)
{
List<RUserDto> res = getUsers(cnx, "user_select_by_id", 0, id);
if (res.size() == 1)
{
return res.get(0);
}
else
{
throw new JqmAdminApiUserException("no result");
}
}
public static void changeUserPassword(DbConn cnx, int userId, String newPassword)
{
ByteSource salt = new SecureRandomNumberGenerator().nextBytes();
String hash = new Sha512Hash(newPassword, salt, 100000).toHex();
QueryResult qr = cnx.runUpdate("user_update_password_by_id", hash, salt, userId);
if (qr.nbUpdated == 0)
{
throw new JqmAdminApiUserException("user with this ID does not exist");
}
}
public static void upsertUser(DbConn cnx, RUserDto dto)
{
if (dto.getId() != null)
{
cnx.runUpdate("user_update_changed", dto.getLogin(), dto.getLocked(), dto.getExpirationDate(), dto.getEmail(),
dto.getFreeText(), dto.getId(), dto.getLogin(), dto.getLocked(), dto.getExpirationDate(), dto.getEmail(),
dto.getFreeText());
// Password
if (dto.getNewPassword() != null && !dto.getNewPassword().isEmpty())
{
changeUserPassword(cnx, dto.getId(), dto.getNewPassword());
}
// Roles
cnx.runUpdate("user_remove_all_roles_by_id", dto.getId());
for (int i : dto.getRoles())
{
cnx.runUpdate("user_add_role_by_id", dto.getId(), i);
}
}
else
{
QueryResult r = cnx.runUpdate("user_insert", dto.getEmail(), dto.getExpirationDate(), dto.getFreeText(), null,
dto.getInternal(), false, dto.getLogin(), null);
int newId = r.getGeneratedId();
if (dto.getNewPassword() != null && !dto.getNewPassword().isEmpty())
{
changeUserPassword(cnx, newId, dto.getNewPassword());
}
for (int i : dto.getRoles())
{
cnx.runUpdate("user_add_role_by_id", newId, i);
}
}
}
public static void syncUsers(DbConn cnx, List<RUserDto> dtos)
{
for (RUserDto existing : getUsers(cnx))
{
boolean foundInNewSet = false;
for (RUserDto newdto : dtos)
{
if (newdto.getId() != null && newdto.getId().equals(existing.getId()))
{
foundInNewSet = true;
break;
}
}
if (!foundInNewSet)
{
deleteUser(cnx, existing.getId());
}
}
for (RUserDto dto : dtos)
{
upsertUser(cnx, dto);
}
}
}