Commit b2f5ecb3 authored by Michael Ritter's avatar Michael Ritter

Merge branch 'release-1.10'

parents 06cc89a4 c66b09c5
......@@ -4,7 +4,7 @@
<parent>
<artifactId>ace</artifactId>
<groupId>edu.umiacs.ace</groupId>
<version>1.10-SNAPSHOT</version>
<version>1.10</version>
<relativePath>../pom.xml</relativePath>
</parent>
<groupId>edu.umiacs.ace</groupId>
......@@ -252,7 +252,7 @@
<dependency>
<groupId>edu.umiacs.ace</groupId>
<artifactId>ace-ims-ws</artifactId>
<version>1.10-SNAPSHOT</version>
<version>1.10</version>
<type>jar</type>
</dependency>
<dependency>
......
......@@ -30,23 +30,25 @@
// $Id$
package edu.umiacs.ace.monitor.access;
import edu.umiacs.ace.util.PersistUtil;
import edu.umiacs.ace.monitor.core.Collection;
import edu.umiacs.ace.util.PersistUtil;
import edu.umiacs.sql.SQL;
import org.apache.log4j.Logger;
import org.apache.log4j.NDC;
import javax.persistence.EntityManager;
import javax.persistence.Query;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import javax.persistence.EntityManager;
import javax.persistence.Query;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.sql.DataSource;
import org.apache.log4j.Logger;
import org.apache.log4j.NDC;
/**
* Class to gather a count of all collections at startup.
......@@ -70,6 +72,7 @@ public class CollectionCountContext implements ServletContextListener {
private static Map<Collection, Long> totalSizeMap = new HashMap<Collection, Long>();
private static Map<Collection, Long> fileRemoteMissing = new HashMap<Collection, Long>();
private static Map<Collection, Long> fileRemoteCorrupt = new HashMap<Collection, Long>();
private static AtomicInteger totalCollections = new AtomicInteger(0);
private static Lock lock = new ReentrantLock();
private static boolean abort = false;
......@@ -99,6 +102,7 @@ public class CollectionCountContext implements ServletContextListener {
return;
}
queryCollection((Collection) o);
incrementTotalCollections();
}
em.close();
} catch (Exception e) {
......@@ -208,6 +212,18 @@ public class CollectionCountContext implements ServletContextListener {
return -1;
}
public static void incrementTotalCollections() {
totalCollections.incrementAndGet();
}
public static void decrementTotalCollections() {
totalCollections.decrementAndGet();
}
public static int getTotalCollections() {
return totalCollections.get();
}
/**
* Update statistics for a collection.
*
......
......@@ -33,17 +33,16 @@ package edu.umiacs.ace.monitor.access.browse;
import edu.umiacs.ace.hashtree.Proof;
import edu.umiacs.ace.hashtree.ProofValidator;
import edu.umiacs.ace.monitor.core.MonitoredItem;
import edu.umiacs.ace.util.EntityManagerServlet;
import edu.umiacs.ace.monitor.access.browse.DirectoryTree.DirectoryNode;
import edu.umiacs.ace.monitor.audit.AuditThreadFactory;
import edu.umiacs.ace.monitor.audit.AuditTokens;
import edu.umiacs.ace.monitor.access.browse.DirectoryTree.DirectoryNode;
import edu.umiacs.ace.monitor.core.Collection;
import edu.umiacs.ace.monitor.core.MonitoredItem;
import edu.umiacs.ace.util.EntityManagerServlet;
import edu.umiacs.ace.util.HashValue;
import edu.umiacs.ace.util.TokenUtil;
import java.io.IOException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import org.apache.log4j.Logger;
import javax.persistence.EntityManager;
import javax.persistence.EntityNotFoundException;
import javax.servlet.RequestDispatcher;
......@@ -51,7 +50,9 @@ import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.apache.log4j.Logger;
import java.io.IOException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
/**
* Servlet to manage browsing a collection. This will store a directorytree in
......@@ -102,6 +103,7 @@ public class BrowseServlet extends EntityManagerServlet {
isRunning = true;
}
dt = new DirectoryTree(c);
request.setAttribute("collection", c);
session.setAttribute(SESSION_DIRECTORY_TREE, dt);
} else if ( itemId > 0 ) {
LOG.trace("Toggling item: " + itemId);
......@@ -114,6 +116,8 @@ public class BrowseServlet extends EntityManagerServlet {
AuditThreadFactory.isQueued(c)) {
isRunning = true;
}
request.setAttribute("collection", c);
session.setAttribute(SESSION_FILE,
loadFileBean(dt.getDirectoryNode(itemId), em,c));
if ( dt.getDirectoryNode(itemId).isDirectory() ) {
......@@ -131,7 +135,12 @@ public class BrowseServlet extends EntityManagerServlet {
dispatcher.forward(request, response);
}
private FileBean loadFileBean( DirectoryNode node, EntityManager em,Collection c ) {
private FileBean loadFileBean( DirectoryNode node, EntityManager em, Collection c ) {
// avoid possible null references below
if (node == null) {
return null;
}
FileBean retBean = new FileBean();
try {
......
......@@ -191,6 +191,7 @@ public final class AuditThread extends Thread implements CancelCallback {
iterableItems.cancel();
}
/*
if (batch != null) {
batch.close();
}
......@@ -198,10 +199,12 @@ public final class AuditThread extends Thread implements CancelCallback {
if (validator != null) {
validator.close();
}
*/
if (AuditThreadFactory.isRunning(coll) || AuditThreadFactory.isQueued(coll)) {
AuditThreadFactory.finished(coll);
}
this.interrupt();
}
......
......@@ -63,7 +63,7 @@ public final class AuditTokens extends Thread implements CancelCallback {
new ConcurrentHashMap<>();
// private Map<TokenResponse, Token> tokenMap = new ConcurrentHashMap<TokenResponse, Token>();
private Map<AceToken, MonitoredItem> itemMap =
new ConcurrentHashMap<AceToken, MonitoredItem>();
new ConcurrentHashMap<>();
private static final Logger LOG = Logger.getLogger(AuditTokens.class);
private Collection collection;
private boolean cancel = false;
......@@ -186,7 +186,7 @@ public final class AuditTokens extends Thread implements CancelCallback {
} catch ( Throwable e ) {
LOG.fatal("UNcaught exception in doWork()", e);
} finally {
itemMap.clear(); // free memory in case this gets stuck hianging around
itemMap.clear(); // free memory in case this gets stuck hanging around
}
}
......@@ -235,6 +235,7 @@ public final class AuditTokens extends Thread implements CancelCallback {
TokenValidator validator = openIms();
if ( validator == null ) {
runningThreads.remove(collection);
return;
}
em = PersistUtil.getEntityManager();
......
......@@ -30,15 +30,14 @@
// $Id$
package edu.umiacs.ace.monitor.core;
import edu.umiacs.ace.util.EntityManagerServlet;
import edu.umiacs.ace.util.PersistUtil;
import edu.umiacs.ace.driver.StorageDriver;
import edu.umiacs.ace.driver.StorageDriverFactory;
import edu.umiacs.ace.monitor.access.CollectionCountContext;
import edu.umiacs.ace.util.EntityManagerServlet;
import edu.umiacs.ace.util.PersistUtil;
import edu.umiacs.util.Strings;
import java.io.IOException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import org.apache.log4j.Logger;
import javax.persistence.EntityManager;
import javax.persistence.EntityTransaction;
import javax.persistence.Query;
......@@ -47,7 +46,10 @@ import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.log4j.Logger;
import java.io.IOException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
/**
* add,modify,remove the settings of a collection
......@@ -154,6 +156,7 @@ public class ManageCollectionServlet extends EntityManagerServlet {
PersistUtil.persist(collection);
storage = StorageDriverFactory.createStorageAccess(collection,
em);
CollectionCountContext.incrementTotalCollections();
}
dispatcher = request.getRequestDispatcher("collectionmodify.jsp");
......@@ -206,6 +209,7 @@ public class ManageCollectionServlet extends EntityManagerServlet {
storage.remove(em);
}
em.remove(collection);
CollectionCountContext.decrementTotalCollections();
trans.commit();
}
......
package edu.umiacs.ace.monitor.support;
/**
* A Bean to hold each collection status as well as its definition
*
* Created by shake on 4/5/16.
*/
public enum CStateBean {
NO_FILTER(""),
ACTIVE("A"),
ERROR("E"),
NEVER_SCANNED("N");
private final String state;
CStateBean(String state) {
this.state = state;
}
public String getState() {
return state;
}
}
package edu.umiacs.ace.monitor.support;
import edu.umiacs.ace.monitor.access.CollectionCountContext;
import org.apache.log4j.Logger;
/**
*
* Created by shake on 1/28/16.
*/
public class PageBean {
private static Logger LOG = Logger.getLogger(PageBean.class);
// current page
int page;
// page number
int count;
// item offset (for db queries)
int offset;
int previous;
int next;
int end;
StringBuilder url;
private boolean firstParam;
public PageBean(int page, int count, String root) {
this.firstParam = true;
this.page = page;
this.count = count;
this.offset = page*count;
if (page == 0) {
this.previous = 0;
} else {
this.previous = page - 1;
}
setPages(CollectionCountContext.getTotalCollections());
this.url = new StringBuilder(root);
LOG.info("Next page is " + next);
}
private void setPages(int totalCollections) {
double endPrecise = totalCollections / (double) count;
double endRounded = Math.floor(endPrecise);
// If divided evenly, the last page will have nothing on it
// Else keep it to show the remainder
if (endRounded >= endPrecise) {
this.end =(int) endRounded - 1;
} else {
this.end = (int) endRounded;
}
if (page == end) {
this.next = end;
} else {
this.next = page + 1;
}
}
public void setUrl(StringBuilder url) {
this.url = url;
}
public void addParam(String param, String value) {
if (firstParam) {
url.append("?");
firstParam = false;
} else {
url.append("&");
}
url.append(param).append("=").append(value);
}
public int getPage() {
return page;
}
public int getCount() {
return count;
}
public int getOffset() {
return offset;
}
public String getFirst() {
return getUrl(0, count);
}
public String getPrevious() {
return getUrl(previous, count);
}
public String getNext() {
return getUrl(next, count);
}
public String getEnd() {
return getUrl(end, count);
}
public String getCount(int count) {
return getUrl(0, count);
}
private String getUrl(int page, int count) {
StringBuilder copy = new StringBuilder(url);
if (firstParam) {
copy.append("?");
} else {
copy.append("&");
}
copy.append("page=").append(page);
copy.append("&count=").append(count);
return copy.toString();
}
public void update(long totalResults) {
setPages((int) totalResults);
}
}
......@@ -7,6 +7,7 @@ package edu.umiacs.ace.rest;
import edu.umiacs.ace.driver.StorageDriver;
import edu.umiacs.ace.driver.StorageDriverFactory;
import edu.umiacs.ace.monitor.access.CollectionCountContext;
import edu.umiacs.ace.monitor.audit.AuditThreadFactory;
import edu.umiacs.ace.monitor.core.Collection;
import edu.umiacs.ace.monitor.core.MonitoredItem;
......@@ -150,6 +151,7 @@ public class CollectionManagement {
EntityTransaction trans = em.getTransaction();
trans.begin();
em.persist(coll);
CollectionCountContext.incrementTotalCollections();
trans.commit();
em.close();
......
......@@ -3,6 +3,9 @@ package edu.umiacs.ace.util;
import edu.umiacs.ace.monitor.core.Collection;
/**
* Encapsulate metadata about a Runnable to keep track of information regarding
* the type of task being run
*
* Created by shake on 9/11/15.
*/
public class Submittable<V extends Runnable> implements Comparable<Submittable> {
......
......@@ -79,12 +79,55 @@ on Libraries node in Projects view can be used to add the JSTL 1.1 library.
.badreplica {
}
#collectionHeader {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: -1px;
border-bottom: 1px solid black;
}
.container {
flex: 1 1 0%;
}
.heading {
letter-spacing: 1px;
font-size: 11px;
margin-bottom: 5px;
text-transform: uppercase;
color: #868686;
}
.subheading {
font-size: 16px;
line-height: 1;
font-weight: 300;
margin-top: 0px;
}
.is-centered {
text-align: center;
}
</style>
</head>
<body>
<jsp:include page="header.jsp" />
<div id="collectionHeader">
<div class="container">
<p class="heading is-centered">Group</p>
<p class="subheading is-centered">${collection.group}</p>
<%--<h2 style="font-size: 1.5em; margin-bottom: 2px">${collection.group}</h2>--%>
</div>
<div class="container">
<p class="heading is-centered">Collection</p>
<p class="subheading is-centered">${collection.name}</p>
<%--<h3 style="font-size: 1.25em; font-weight: 100; margin-top: 2px">${collection.name}</h3>--%>
</div>
</div>
<div id="scrollContainer">
<div id="scrollDirectory">
<c:forEach var="dir" items="${directoryTree.roots}">
......
<%@page contentType="text/html"%>
<%@page pageEncoding="UTF-8"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@taglib tagdir="/WEB-INF/tags" prefix="h" %>
<%@taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<%@taglib uri="/WEB-INF/tlds/monitor" prefix="d"%>
......@@ -80,10 +80,14 @@
background-color: #FFFFFF;
}
#linktable {
width: 655px;
margin-left: auto;
margin-right: auto;
}
#threaddetailsTD:hover div {
display: block;
}
#threaddetailsDIV {
......@@ -128,6 +132,57 @@
{
background-color: #e8e8e8;
}
#searchtable {
margin-top: 10px;
margin-bottom: -10px;
margin-left: auto;
margin-right: auto;
width: 650px;
}
.input {
padding: 2px;
display: flex;
width: 650px;
}
.input-group-addon {
border: 1px solid #ccc;
font-size: 12px;
background-color: #e8e8e8;
text-align: center;
width: 75px;
height: 20px;
line-height: 20px;
padding: 3px 10px;
}
.form-input {
border: 1px solid #ccc;
width: 100%;
height: 20px;
padding: 3px 8px;
margin-left: -1px;
margin-right: 5px;
}
.form-select {
border: 1px solid #ccc;
width: 100%;
padding: 3px 8px;
margin-left: -3px;
margin-right: 5px;
}
.btn {
padding: 2px;
width: 75px;
height: 25px;
border: 1px solid #e8e8e8;
margin-left: 2px;
margin-top: 2px;
}
</style>
</head>
......@@ -141,6 +196,28 @@
</c:if>
<div id="searchtable">
<form method="GET" role="form">
<div class="input">
<span class="input-group-addon">Group</span>
<input type="text" class="form-input" id="group-filter" name="group" placeholder="Search Group"/>
</div>
<div class="input">
<span class="input-group-addon">Collection</span>
<input type="text" class="form-input" id="coll-filter" name="collection" placeholder="Search Collection"/>
</div>
<div class="input">
<span class="input-group-addon">State</span>
<select name="state" id="state-filter" class="form-select">
<c:forEach var="state" items="${states}">
<option value="${state.state}">${state.name()}</option>
</c:forEach>
</select>
</div>
<button type="submit" class="btn" value="Submit"><span>Submit</span></button>
</form>
</div>
<table id="statustable">
<thead>
<td></td><td width="45%">Collection Name</td>
......@@ -201,7 +278,7 @@
</c:choose>
</td>
<td>
<a href="Status?collectionid=${item.collection.id}">${item.collection.name}</a>
<a href="Status?collectionid=${item.collection.id}&page=${page.page}&count=${page.count}">${item.collection.name}</a>
</td>
<td>${item.collection.storage}</td>
<td><h:DefaultValue test="${item.totalFiles > -1}" success="${item.totalFiles}" failure="Unknown" /></td>
......@@ -257,6 +334,30 @@
</table>
<table id="linktable">
<tr>
<td align="left">
<%-- <a href="Status?count=${count}">|&lt;</a>&nbsp;&nbsp;&nbsp;
<a href="Status?page=${page - 1}&count=${count}">&lt;&lt;</a> --%>
<a href="${page.first}">|&lt;</a>&nbsp;&nbsp;&nbsp;
<a href="${page.previous}">&lt;&lt;</a>
</td>
<td align="center">
Show per page:
<a href="${page.getCount(100)}">100</a>
<a href="${page.getCount(500)}">500</a>
<a href="${page.getCount(1000)}">1000</a>
</td>
<td align="right">
<%--
<a href="Status?page=${page + 1}&count=${count}">&gt;&gt;</a>&nbsp;&nbsp;&nbsp;
<a href="Status?count=${count}&start=0&top=0">&gt;|</a> --%>
<a href="${page.next}">&gt;&gt;</a>&nbsp;&nbsp;&nbsp;
<a href="${page.end}">&gt;|</a>
</td>
</tr>
</table>
<jsp:include page="footer.jsp" />
</body>
</html>
......@@ -4,7 +4,7 @@
<parent>
<artifactId>ace</artifactId>
<groupId>edu.umiacs.ace</groupId>
<version>1.10-SNAPSHOT</version>
<version>1.10</version>
</parent>
<groupId>edu.umiacs.ace</groupId>
<artifactId>ace-common</artifactId>
......
......@@ -4,7 +4,7 @@
<parent>
<artifactId>ace</artifactId>
<groupId>edu.umiacs.ace</groupId>
<version>1.10-SNAPSHOT</version>
<version>1.10</version>
</parent>
<groupId>edu.umiacs.ace</groupId>
<artifactId>ace-dist</artifactId>
......
......@@ -4,7 +4,7 @@
<parent>
<artifactId>ace</artifactId>
<groupId>edu.umiacs.ace</groupId>
<version>1.10-SNAPSHOT</version>
<version>1.10</version>
<relativePath>../pom.xml</relativePath>
</parent>