NHRActionBean.java
package nl.b3p.brmo.service.stripes;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.security.KeyStore;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
import java.util.Date;
import java.util.List;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.persistence.EntityManager;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import javax.servlet.http.HttpServletResponse;
import net.sourceforge.stripes.action.ActionBean;
import net.sourceforge.stripes.action.ActionBeanContext;
import net.sourceforge.stripes.action.DefaultHandler;
import net.sourceforge.stripes.action.FileBean;
import net.sourceforge.stripes.action.ForwardResolution;
import net.sourceforge.stripes.action.Resolution;
import net.sourceforge.stripes.action.StreamingResolution;
import net.sourceforge.stripes.validation.Validate;
import nl.b3p.brmo.loader.util.BrmoException;
import nl.b3p.brmo.persistence.staging.NHRInschrijving;
import nl.b3p.brmo.service.jobs.NHRJob;
import org.apache.commons.lang3.StringUtils;
import org.json.JSONArray;
import org.json.JSONObject;
import org.stripesstuff.stripersist.Stripersist;
public class NHRActionBean implements ActionBean {
private ActionBeanContext context;
private String[] selectedIds;
@Validate private int start;
@Validate private int limit;
@Validate private String sort;
@Validate private String dir;
@Validate(required = true, on = "upload")
private FileBean file;
private boolean statusActive;
private Date statusCertificateExpiry;
private long statusDaysUntilExpiry;
private String statusNotification;
private String statusEndpoint;
private boolean statusEndpointPreprod;
private float statusRefetchDays;
public boolean getStatusActive() {
return statusActive;
}
public Date getStatusCertificateExpiry() {
return statusCertificateExpiry;
}
public long getStatusDaysUntilExpiry() {
return statusDaysUntilExpiry;
}
public String getStatusNotification() {
return statusNotification;
}
public String getStatusEndpoint() {
return statusEndpoint;
}
public boolean getStatusEndpointPreprod() {
return statusEndpointPreprod;
}
public float getStatusRefetchDays() {
return statusRefetchDays;
}
public long getFetchCount() {
return NHRJob.getFetchCount();
}
public long getFetchErrorCount() {
return NHRJob.getFetchErrorCount();
}
public float getSecondsPerFetch() {
return NHRJob.getAverageFetchTime() / 1000.0f;
}
public String getEstimatedTime() {
float totalSeconds = getSecondsPerFetch() * getPendingCount();
int hours = (int) (totalSeconds / 3600);
int minutes = (int) (totalSeconds / 60) % 60;
int seconds = (int) totalSeconds % 60;
return String.format("%dh %02dm %02ds", hours, minutes, seconds);
}
private void getCertificateStatus() {
statusNotification = "";
try {
statusActive = InitialContext.doLookup("java:comp/env/brmo/nhr/active");
} catch (NamingException e) {
} catch (Exception e) {
statusNotification += String.format("nhr/active incorrect: %s\n", e.getMessage());
}
KeyStore keyStore;
try {
keyStore = KeyStore.getInstance("PKCS12");
try (FileInputStream keyStoreFile =
new FileInputStream(
(String) InitialContext.doLookup("java:comp/env/brmo/nhr/keystorePath"))) {
keyStore.load(
keyStoreFile,
((String) InitialContext.doLookup("java:comp/env/brmo/nhr/keystorePassword"))
.toCharArray());
}
String alias = keyStore.aliases().nextElement();
if (alias == null) {
statusNotification += "geen bruikbaar certificaat gevonden";
} else {
Certificate cert = keyStore.getCertificate(alias);
Date now = new Date();
statusCertificateExpiry = ((X509Certificate) cert).getNotAfter();
statusDaysUntilExpiry =
(statusCertificateExpiry.getTime() - now.getTime()) / (60 * 60 * 24);
if (statusCertificateExpiry.before(now)) {
statusNotification += "certificaat is verlopen!\n";
}
}
} catch (FileNotFoundException e) {
statusNotification += "keystore niet gevonden\n";
} catch (NamingException e) {
if (statusActive) {
statusNotification += String.format("geen keystore ingesteld: %s\n", e.getMessage());
}
} catch (Exception e) {
statusNotification += String.format("keystore incorrect: %s\n", e.getMessage());
}
try {
KeyStore trustStore = KeyStore.getInstance("PKCS12");
try (FileInputStream trustStoreFile =
new FileInputStream(
(String) InitialContext.doLookup("java:comp/env/brmo/nhr/truststorePath"))) {
trustStore.load(
trustStoreFile,
((String) InitialContext.doLookup("java:comp/env/brmo/nhr/truststorePassword"))
.toCharArray());
}
} catch (FileNotFoundException e) {
statusNotification += "truststore niet gevonden\n";
} catch (NamingException e) {
if (statusActive) {
statusNotification += String.format("geen truststore ingesteld: %s\n", e.getMessage());
}
} catch (Exception e) {
statusNotification += String.format("truststore incorrect: %s\n", e.getMessage());
}
try {
statusEndpoint = InitialContext.doLookup("java:comp/env/brmo/nhr/endpoint");
statusEndpointPreprod = InitialContext.doLookup("java:comp/env/brmo/nhr/endpointIsPreprod");
} catch (Exception e) {
statusNotification += String.format("endpoint incorrect: %s\n", e.getMessage());
}
try {
statusRefetchDays =
((float)
(Integer) InitialContext.doLookup("java:comp/env/brmo/nhr/secondsBetweenFetches"))
/ (60.0f * 60.0f * 24.0f);
} catch (Exception e) {
statusNotification += String.format("secondsBetweenFetches incorrect: %s\n", e.getMessage());
}
}
@DefaultHandler
public Resolution list() {
getCertificateStatus();
return new ForwardResolution("/WEB-INF/jsp/nhr/list.jsp");
}
private long getCount() {
EntityManager entityManager = Stripersist.getEntityManager();
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<Long> cq = cb.createQuery(Long.class);
Root<NHRInschrijving> from = cq.from(NHRInschrijving.class);
cq.select(cb.count(from));
return entityManager.createQuery(cq).getSingleResult();
}
public long getPendingCount() {
EntityManager entityManager = Stripersist.getEntityManager();
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<Long> cq = cb.createQuery(Long.class);
Root<NHRInschrijving> from = cq.from(NHRInschrijving.class);
cq.select(cb.count(from));
cq.where(cb.lessThan(from.get("volgendProberen"), cb.currentTimestamp()));
return entityManager.createQuery(cq).getSingleResult();
}
public Resolution getGridData() throws BrmoException {
EntityManager entityManager = Stripersist.getEntityManager();
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<NHRInschrijving> cq = cb.createQuery(NHRInschrijving.class);
Root<NHRInschrijving> from = cq.from(NHRInschrijving.class);
if (sort != null) {
if (dir == null || !dir.equalsIgnoreCase("desc")) {
cq.orderBy(cb.asc(from.get(sort)));
} else {
cq.orderBy(cb.desc(from.get(sort)));
}
}
if (start < 0) {
start = 0;
}
if (limit <= 0) {
limit = 40;
}
List<NHRInschrijving> procList =
entityManager.createQuery(cq).setMaxResults(limit).setFirstResult(start).getResultList();
JSONArray jsonBerichten = new JSONArray();
for (NHRInschrijving b : procList) {
jsonBerichten.put(laadproces2Json(b));
}
final JSONObject grid = new JSONObject();
grid.put("total", getCount());
grid.put("items", jsonBerichten);
return new StreamingResolution("application/json") {
@Override
public void stream(HttpServletResponse response) throws Exception {
response.getWriter().print(grid.toString());
}
};
}
public Resolution getLog() {
EntityManager entityManager = Stripersist.getEntityManager();
String responseString;
if (selectedIds == null || selectedIds.length != 1) {
responseString = "kan geen logs ophalen voor 0 of meer dan 1 item";
} else {
NHRInschrijving item = entityManager.find(NHRInschrijving.class, selectedIds[0]);
if (item == null) {
responseString = String.format("Log voor KVK nummer %s niet gevonden", selectedIds[0]);
} else {
responseString = item.getException();
}
}
return new StreamingResolution("text/plain") {
@Override
public void stream(HttpServletResponse response) throws Exception {
response.getWriter().print(responseString);
}
};
}
public Resolution runNow() throws BrmoException {
EntityManager entityManager = Stripersist.getEntityManager();
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<NHRInschrijving> cq = cb.createQuery(NHRInschrijving.class);
Root<NHRInschrijving> from = cq.from(NHRInschrijving.class);
CriteriaBuilder.In<String> in = cb.in(from.get("kvkNummer"));
for (String item : selectedIds) {
in.value(item);
}
cq.where(in);
List<NHRInschrijving> procList = entityManager.createQuery(cq).getResultList();
for (NHRInschrijving b : procList) {
b.setVolgendProberen(new java.util.Date());
b.setProbeerAantal(0);
}
entityManager.getTransaction().commit();
return new StreamingResolution("text/plain") {
@Override
public void stream(HttpServletResponse response) throws Exception {
response.getWriter().print("ok");
}
};
}
public Resolution upload() throws IOException {
EntityManager entityManager = Stripersist.getEntityManager();
try (BufferedReader reader = new BufferedReader(new InputStreamReader(file.getInputStream()))) {
while (true) {
String line = reader.readLine();
if (line == null) {
break;
}
// Parse the first column from a CSV, and accept KVK numbers with zeroes trimmed
// (e.g. spreadsheet software parsing the number as a decimal)
line = line.split(",")[0].replaceAll("\"", "");
if (line.length() < 8) {
line = StringUtils.leftPad(line, 8, "0");
}
NHRInschrijving proces;
proces = entityManager.find(NHRInschrijving.class, line);
if (proces == null) {
proces = new NHRInschrijving();
}
proces.setDatum(new Date());
proces.setVolgendProberen(new Date());
proces.setProbeerAantal(0);
proces.setKvkNummer(line);
entityManager.merge(proces);
}
}
file.delete();
entityManager.getTransaction().commit();
return list();
}
private JSONObject laadproces2Json(NHRInschrijving laadproces) {
JSONObject json = new JSONObject();
json.put("datum", laadproces.getDatum());
json.put("laatstGeprobeerd", laadproces.getLaatstGeprobeerd());
json.put("volgendProberen", laadproces.getVolgendProberen());
json.put("probeerAantal", laadproces.getProbeerAantal());
json.put("kvkNummer", laadproces.getKvkNummer());
return json;
}
@Override
public ActionBeanContext getContext() {
return context;
}
@Override
public void setContext(ActionBeanContext context) {
this.context = context;
}
public String[] getSelectedIds() {
return selectedIds;
}
public void setSelectedIds(String[] selectedIds) {
this.selectedIds = selectedIds;
}
public int getStart() {
return start;
}
public void setStart(int start) {
this.start = start;
}
public int getLimit() {
return limit;
}
public void setLimit(int limit) {
this.limit = limit;
}
public String getSort() {
return sort;
}
public void setSort(String sort) {
this.sort = sort;
}
public String getDir() {
return dir;
}
public void setDir(String dir) {
this.dir = dir;
}
public FileBean getFile() {
return file;
}
public void setFile(FileBean file) {
this.file = file;
}
}