use of org.mycore.common.MCRSession in project mycore by MyCoRe-Org.
the class MCRSwordUtil method createTempFileFromStream.
/**
* Stores stream to temp file and checks md5
*
* @param inputStream the stream which holds the File
* @param checkMd5 the md5 to compare with (or null if no md5 check is needed)
* @return the path to the temp file
* @throws IOException if md5 does mismatch or if stream could not be read
*/
public static Path createTempFileFromStream(String fileName, InputStream inputStream, String checkMd5) throws IOException {
MCRSession currentSession = MCRSessionMgr.getCurrentSession();
if (currentSession.isTransactionActive()) {
currentSession.commitTransaction();
}
final Path zipTempFile = Files.createTempFile("swordv2_", fileName);
MessageDigest md5Digest = null;
if (checkMd5 != null) {
try {
md5Digest = MessageDigest.getInstance("MD5");
inputStream = new DigestInputStream(inputStream, md5Digest);
} catch (NoSuchAlgorithmException e) {
currentSession.beginTransaction();
throw new MCRConfigurationException("No MD5 available!", e);
}
}
Files.copy(inputStream, zipTempFile, StandardCopyOption.REPLACE_EXISTING);
if (checkMd5 != null) {
final String md5String = MCRUtils.toHexString(md5Digest.digest());
if (!md5String.equals(checkMd5)) {
currentSession.beginTransaction();
throw new IOException("MD5 mismatch, expected " + checkMd5 + " got " + md5String);
}
}
currentSession.beginTransaction();
return zipTempFile;
}
use of org.mycore.common.MCRSession in project mycore by MyCoRe-Org.
the class MCRSwordUtil method addDirectoryToZip.
private static void addDirectoryToZip(ZipArchiveOutputStream zipOutputStream, Path directory) {
MCRSession currentSession = MCRSessionMgr.getCurrentSession();
final DirectoryStream<Path> paths;
try {
paths = Files.newDirectoryStream(directory);
} catch (IOException e) {
throw new MCRException(e);
}
paths.forEach(p -> {
final boolean isDir = Files.isDirectory(p);
final ZipArchiveEntry zipArchiveEntry;
try {
final String fileName = getFilename(p);
LOGGER.info("Addding {} to zip file!", fileName);
if (isDir) {
addDirectoryToZip(zipOutputStream, p);
} else {
zipArchiveEntry = new ZipArchiveEntry(fileName);
zipArchiveEntry.setSize(Files.size(p));
zipOutputStream.putArchiveEntry(zipArchiveEntry);
if (currentSession.isTransactionActive()) {
currentSession.commitTransaction();
}
Files.copy(p, zipOutputStream);
currentSession.beginTransaction();
zipOutputStream.closeArchiveEntry();
}
} catch (IOException e) {
LOGGER.error("Could not add path {}", p);
}
});
}
use of org.mycore.common.MCRSession in project mycore by MyCoRe-Org.
the class MCRJobMaster method run.
/**
* Starts local threads ({@link MCRJobThread}) and gives {@link MCRJob} instances to them.
* Use property <code>"MCR.QueuedJob.JobThreads"</code> to specify how many concurrent threads should be running.<br>
* <code>"MCR.QueuedJob.activated"</code> can be used activate or deactivate general {@link MCRJob} running.
*/
@Override
public void run() {
Thread.currentThread().setName(getName());
// get this MCRSession a speaking name
MCRSession mcrSession = MCRSessionMgr.getCurrentSession();
mcrSession.setUserInformation(MCRSystemUserInformation.getSystemUserInstance());
boolean activated = CONFIG.getBoolean(MCRJobQueue.CONFIG_PREFIX + "activated", true);
activated = activated && CONFIG.getBoolean(MCRJobQueue.CONFIG_PREFIX + JOB_QUEUE.CONFIG_PREFIX_ADD + "activated", true);
LOGGER.info("JobQueue{} is {}", MCRJobQueue.singleQueue ? "" : " for \"" + action.getName() + "\"", activated ? "activated" : "deactivated");
if (activated) {
running = true;
int jobThreadCount = CONFIG.getInt(MCRJobQueue.CONFIG_PREFIX + "JobThreads", 2);
jobThreadCount = CONFIG.getInt(MCRJobQueue.CONFIG_PREFIX + JOB_QUEUE.CONFIG_PREFIX_ADD + "JobThreads", jobThreadCount);
ThreadFactory slaveFactory = new ThreadFactory() {
AtomicInteger tNum = new AtomicInteger();
ThreadGroup tg = new ThreadGroup("MCRJob slave job thread group");
public Thread newThread(Runnable r) {
return new Thread(tg, r, getPreLabel() + "Slave#" + tNum.incrementAndGet());
}
};
final AtomicInteger activeThreads = new AtomicInteger();
final LinkedBlockingQueue<Runnable> workQueue = new LinkedBlockingQueue<>();
ThreadPoolExecutor executor = new ThreadPoolExecutor(jobThreadCount, jobThreadCount, 1, TimeUnit.DAYS, workQueue, slaveFactory) {
@Override
protected void afterExecute(Runnable r, Throwable t) {
super.afterExecute(r, t);
activeThreads.decrementAndGet();
}
@Override
protected void beforeExecute(Thread t, Runnable r) {
super.beforeExecute(t, r);
activeThreads.incrementAndGet();
}
};
jobServe = MCRProcessableFactory.newPool(executor, processableCollection);
processableCollection.setProperty("running", running);
LOGGER.info("JobMaster{} with {} thread(s) is started", MCRJobQueue.singleQueue ? "" : " for \"" + action.getName() + "\"", jobThreadCount);
while (running) {
try {
while (activeThreads.get() < jobThreadCount) {
runLock.lock();
try {
if (!running)
break;
EntityManager em = MCREntityManagerProvider.getCurrentEntityManager();
EntityTransaction transaction = em.getTransaction();
MCRJob job = null;
MCRJobAction action = null;
try {
transaction.begin();
job = JOB_QUEUE.poll();
processableCollection.setProperty("queue size", JOB_QUEUE.size());
if (job != null) {
action = toMCRJobAction(job.getAction());
if (action != null && !action.isActivated()) {
job.setStatus(MCRJobStatus.NEW);
job.setStart(null);
}
}
transaction.commit();
} catch (RollbackException e) {
LOGGER.error("Error while getting next job.", e);
if (transaction != null) {
try {
transaction.rollback();
} catch (RuntimeException re) {
LOGGER.warn("Could not rollback transaction.", re);
}
}
} finally {
em.close();
}
if (job != null && action != null && action.isActivated() && !jobServe.getExecutor().isShutdown()) {
LOGGER.info("Creating:{}", job);
jobServe.submit(new MCRJobThread(job));
} else {
try {
synchronized (JOB_QUEUE) {
if (running) {
LOGGER.debug("No job in queue going to sleep");
// fixes a race conditioned deadlock situation
// do not wait longer than 60 sec. for a new MCRJob
JOB_QUEUE.wait(60000);
}
}
} catch (InterruptedException e) {
LOGGER.error("Job thread was interrupted.", e);
}
}
} finally {
runLock.unlock();
}
}
// while(activeThreads.get() < jobThreadCount)
if (activeThreads.get() < jobThreadCount)
try {
LOGGER.info("Waiting for a job to finish");
Thread.sleep(1000);
} catch (InterruptedException e) {
LOGGER.error("Job thread was interrupted.", e);
}
} catch (PersistenceException e) {
LOGGER.warn("We have an database error, sleep and run later.", e);
try {
Thread.sleep(60000);
} catch (InterruptedException ie) {
LOGGER.error("Waiting for database was interrupted.", ie);
}
} catch (Throwable e) {
LOGGER.error("Keep running while catching exceptions.", e);
}
}
// while(running)
processableCollection.setProperty("running", running);
}
LOGGER.info("{} thread finished", getName());
MCRSessionMgr.releaseCurrentSession();
}
use of org.mycore.common.MCRSession in project mycore by MyCoRe-Org.
the class MCRSessionResource method list.
/**
* Lists all {@link MCRSession}'s in json format.
*
* @param resolveHostname (false) if the host names are resolved. Resolving host names takes some
* time, so this is deactivated by default
* @return list of sessions
*/
@GET
@Produces(MediaType.APPLICATION_JSON)
@Path("list")
public Response list(@DefaultValue("false") @QueryParam("resolveHostname") Boolean resolveHostname) {
// check permissions
MCRJerseyUtil.checkPermission("manage-sessions");
// get all sessions
JsonArray rootJSON = new ArrayList<>(MCRSessionMgr.getAllSessions().values()).parallelStream().map(s -> generateSessionJSON(s, resolveHostname)).collect(JsonArray::new, JsonArray::add, JsonArray::addAll);
return Response.status(Status.OK).entity(rootJSON.toString()).build();
}
use of org.mycore.common.MCRSession in project mycore by MyCoRe-Org.
the class MCRSessionResource method kill.
/**
* Kills the session with the specified session identifier.
*
* @return 200 OK if the session could be killed
*/
@POST
@Path("kill/{id}")
public Response kill(@PathParam("id") String sessionID) {
// check permissions
MCRJerseyUtil.checkPermission("manage-sessions");
// kill
MCRSession session = MCRSessionMgr.getSession(sessionID);
session.close();
return Response.status(Status.OK).build();
}
Aggregations