Skip to content
Snippets Groups Projects
Commit a7f9fecd authored by Tor-Einar Skog's avatar Tor-Einar Skog
Browse files

Support for storage (ORM) and viewing (REST/JSON) of results from model

parent 0a480775
No related branches found
No related tags found
No related merge requests found
package no.bioforsk.vips.logic.entity;
import java.io.IOException;
import java.io.Serializable;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Transient;
import javax.xml.bind.annotation.XmlRootElement;
import no.bioforsk.vips.entity.Result;
import no.bioforsk.vips.logic.entity.helpers.HstoreHelper;
import org.codehaus.jackson.annotate.JsonIgnore;
import org.codehaus.jackson.annotate.JsonProperty;
import org.codehaus.jackson.annotate.JsonValue;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.type.TypeReference;
/**
* @copyright 2013 <a href="http://www.bioforsk.no/">Bioforsk</a>
* @author Tor-Einar Skog <tor-einar.skog@bioforsk.no>
*/
@Entity
@Table(name = "forecast_result")
@XmlRootElement
@NamedQueries({
@NamedQuery(name = "ForecastResult.findAll", query = "SELECT f FROM ForecastResult f"),
@NamedQuery(name = "ForecastResult.findByForecastResultId", query = "SELECT f FROM ForecastResult f WHERE f.forecastResultId = :forecastResultId"),
@NamedQuery(name = "ForecastResult.findByResultValidTime", query = "SELECT f FROM ForecastResult f WHERE f.resultValidTime = :resultValidTime"),
@NamedQuery(name = "ForecastResult.findByWarningStatus", query = "SELECT f FROM ForecastResult f WHERE f.warningStatus = :warningStatus")})
public class ForecastResult implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@Column(name = "forecast_result_id")
private Integer forecastResultId;
@Column(name = "result_valid_time")
@Temporal(TemporalType.TIMESTAMP)
private Date resultValidTime;
@Column(name = "warning_status")
private Integer warningStatus;
@Column(name = "all_values")
private String allValues;
public ForecastResult() {
}
public ForecastResult(Result result){
try {
this.allValues = new ObjectMapper().writeValueAsString(result.getAllValues());
this.resultValidTime = result.getResultValidTime();
this.warningStatus = result.getWarningStatus();
} catch (IOException ex) {
Logger.getLogger(ForecastResult.class.getName()).log(Level.SEVERE, null, ex);
}
}
public ForecastResult(Integer forecastResultId) {
this.forecastResultId = forecastResultId;
}
public Integer getForecastResultId() {
return forecastResultId;
}
public void setForecastResultId(Integer forecastResultId) {
this.forecastResultId = forecastResultId;
}
public Date getResultValidTime() {
return resultValidTime;
}
public void setResultValidTime(Date resultValidTime) {
this.resultValidTime = resultValidTime;
}
public Integer getWarningStatus() {
return warningStatus;
}
public void setWarningStatus(Integer warningStatus) {
this.warningStatus = warningStatus;
}
@JsonIgnore
public String getAllValues() {
return allValues;
}
public void setAllValues(String allValues) {
this.allValues = allValues;
}
@Override
public int hashCode() {
int hash = 0;
hash += (forecastResultId != null ? forecastResultId.hashCode() : 0);
return hash;
}
@Override
public boolean equals(Object object) {
// TODO: Warning - this method won't work in the case the id fields are not set
if (!(object instanceof ForecastResult)) {
return false;
}
ForecastResult other = (ForecastResult) object;
if ((this.forecastResultId == null && other.forecastResultId != null) || (this.forecastResultId != null && !this.forecastResultId.equals(other.forecastResultId))) {
return false;
}
return true;
}
@Override
public String toString() {
return "no.bioforsk.vips.logic.entity.ForecastResult[ forecastResultId=" + forecastResultId + " ]";
}
/**
* Converting from JSON format
* @return
*/
@Transient
@JsonProperty("allValues")
public Map<String,String> getAllValuesAsMap()
{
try {
return new ObjectMapper().readValue(this.allValues, new TypeReference<HashMap<String,String>>(){});
} catch (IOException ex) {
Logger.getLogger(ForecastResult.class.getName()).log(Level.SEVERE, null, ex);
return new HashMap<>();
}
}
/**
* Converting to JSON string
* @param values
*/
@Transient
public void setAllValues(Map<String,String> values)
{
try {
this.allValues = new ObjectMapper().writeValueAsString(values);
System.out.println("this.allvalues=" + this.allValues);
} catch (IOException ex) {
Logger.getLogger(ForecastResult.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
package no.bioforsk.vips.logic.entity.helpers;
import java.util.HashMap;
import java.util.Map;
import no.bioforsk.vips.logic.util.StringUtils;
/** courtesy of: http://backtothefront.net/2011/storing-sets-keyvalue-pairs-single-db-column-hibernate-postgresql-hstore-type/
* Maps between String and Map<String, String> object
* @copyright 2013 <a href="http://www.bioforsk.no/">Bioforsk</a>
* @author Tor-Einar Skog <tor-einar.skog@bioforsk.no>
*/
public class HstoreHelper {
private static final String K_V_SEPARATOR = "=>";
public static String toString(Map<String, String> m) {
if (m.isEmpty()) {
return "";
}
StringBuilder sb = new StringBuilder();
int n = m.size();
for (String key : m.keySet()) {
sb.append("\"").append(key).append("\"" + K_V_SEPARATOR + "\"").append(m.get(key)).append("\"");
if (n > 1) {
sb.append(", ");
n--;
}
}
return sb.toString();
}
public static Map<String, String> toMap(String s) {
Map<String, String> m = new HashMap<>();
if (!StringUtils.containsText(s)) {
return m;
}
String[] tokens = s.split(", ");
for (String token : tokens) {
String[] kv = token.split(K_V_SEPARATOR);
String k = kv[0];
k = k.trim().substring(1, k.length() - 1);
String v = kv[1];
v = v.trim().substring(1, v.length() - 1);
m.put(k, v);
}
return m;
}
}
\ No newline at end of file
package no.bioforsk.vips.logic.service;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.Response;
import no.bioforsk.vips.coremanager.service.ManagerResource;
import no.bioforsk.vips.logic.entity.ForecastResult;
import no.bioforsk.vips.logic.session.SessionControllerGetter;
import org.jboss.resteasy.client.jaxrs.ResteasyWebTarget;
import org.jboss.resteasy.spi.HttpRequest;
......@@ -15,7 +20,7 @@ import org.jboss.resteasy.spi.HttpRequest;
* @copyright 2013 <a href="http://www.bioforsk.no/">Bioforsk</a>
* @author Tor-Einar Skog <tor-einar.skog@bioforsk.no>
*/
@Path("")
@Path("rest")
public class LogicService {
private final static String VIPSCOREMANAGER_URL = System.getProperty("no.bioforsk.vips.coremanager.VIPSCOREMANAGER_URL");
......@@ -25,10 +30,12 @@ public class LogicService {
private HttpServletRequest httpServletRequest;
@GET
@Path("testservice")
public void testFreemarker()
@Path("testforecastresults")
@Produces("application/json;charset=UTF-8")
public Response testForecastResults()
{
httpRequest.forward("/testfreemarker.ftl");
List<ForecastResult> results = SessionControllerGetter.getForecastBean().getForecastResults();
return Response.ok().entity(results).build();
}
......
package no.bioforsk.vips.logic.session;
import java.util.List;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import no.bioforsk.vips.logic.entity.ForecastResult;
/**
* @copyright 2013 <a href="http://www.bioforsk.no/">Bioforsk</a>
* @author Tor-Einar Skog <tor-einar.skog@bioforsk.no>
*/
@Stateless
public class ForecastBean {
@PersistenceContext(unitName="VIPSLogic-PU")
EntityManager em;
public List<ForecastResult> getForecastResults()
{
return em.createNamedQuery("ForecastResult.findAll").getResultList();
}
}
......@@ -20,6 +20,7 @@ import no.bioforsk.vips.coremanager.service.ManagerResource;
import no.bioforsk.vips.entity.ModelConfiguration;
import no.bioforsk.vips.entity.ModelRunRequest;
import no.bioforsk.vips.entity.Result;
import no.bioforsk.vips.logic.entity.ForecastResult;
import no.bioforsk.vips.logic.scheduling.SchedulingTest;
import no.bioforsk.vips.logic.scheduling.VIPSLogicTaskCollector;
import no.bioforsk.vips.logic.scheduling.model.AppleScabModelPreprocessor;
......@@ -93,7 +94,11 @@ public class SchedulingBean {
Response resp = this.getManagerResource().runModel("APPLESCABM", request);
List<Result> results = resp.readEntity(new GenericType<List<Result>>(){});
for(Result result:results)
{
ForecastResult fResult = new ForecastResult(result);
em.persist(fResult);
}
return results;
}
......
......@@ -56,6 +56,20 @@ public class SessionControllerGetter {
}
}
public static ForecastBean getForecastBean(){
try
{
InitialContext ic = new InitialContext();
ForecastBean retVal = (ForecastBean) ic.lookup(SessionControllerGetter.getJndiPath(ForecastBean.class));
return retVal;
}catch(NamingException ne)
{
System.out.println("Could not find " + ForecastBean.class.getSimpleName());
return null;
}
}
private static String getJndiPath(Class obj)
{
String retVal = SessionControllerGetter.JNDI_PATH + obj.getSimpleName();
......
......@@ -17,7 +17,8 @@ public class Globals {
"/login",
"/css",
"/403",
"/404"
"/404",
"/rest"
};
// Point of interest type IDs
......
package no.bioforsk.vips.logic.util;
/**
* @copyright 2013 <a href="http://www.bioforsk.no/">Bioforsk</a>
* @author Tor-Einar Skog <tor-einar.skog@bioforsk.no>
*/
public class StringUtils {
/**
* Check whether the given String contains actual text. More specifically, returns true if the string not null, its length is greater than 0, and it contains at least one non-whitespace character.
* <pre>
* StringUtils.containsText(null) = false
* StringUtils.containsText("") = false
* StringUtils.containsText(" ") = false
* StringUtils.containsText("12345") = true
* StringUtils.containsText(" 12345 ") = true
* </pre>
* @param str the String to check (may be null)
* @return true if the String is not null, its length is greater than 0, and it does not contain whitespace only
*/
public static boolean containsText(String str){
if(str == null) return false;
return !str.trim().isEmpty();
}
}
......@@ -67,7 +67,7 @@
<url-pattern>*</url-pattern>
</filter-mapping>
<!-- RestEASY listens to all requests with /rest/* PATH -->
<!--filter>
<filter>
<filter-name>Resteasy</filter-name>
<filter-class>
org.jboss.resteasy.plugins.server.servlet.FilterDispatcher
......@@ -81,7 +81,7 @@
<filter-mapping>
<filter-name>Resteasy</filter-name>
<url-pattern>/rest/*</url-pattern>
</filter-mapping-->
</filter-mapping>
<!-- FreeMarker configuration -->
<servlet>
<servlet-name>freemarker</servlet-name>
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment