Commit ed2adf95 authored by Matija Obreza's avatar Matija Obreza

Germplasm requests are checked with ITPGRFA's PID server

parent d0101db9
......@@ -18,6 +18,7 @@ package org.genesys2.server.persistence.domain;
import java.util.Collection;
import java.util.List;
import java.util.Set;
import org.genesys2.server.model.genesys.Accession;
import org.genesys2.server.model.genesys.Taxonomy;
......@@ -93,4 +94,7 @@ public interface AccessionRepository extends JpaRepository<Accession, Long> {
Accession findByInstituteCodeAndAccessionNameAndGenus(String holdingInstitute, String accessionName, String genus);
@Query("select count(a.id) from Accession a where a.id in ( ?1 ) and a.availability = 'Y'")
long countAvailable(Set<Long> accessionIds);
}
......@@ -19,6 +19,7 @@ package org.genesys2.server.service;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.genesys2.server.model.genesys.Accession;
import org.genesys2.server.model.genesys.AllAccnames;
......@@ -110,4 +111,6 @@ public interface GenesysService {
void saveSvalbards(List<SvalbardData> svalbards);
long countAvailable(Set<Long> accessionIds);
}
package org.genesys2.server.service.impl;
import java.io.BufferedReader;
import java.io.IOException;
import org.apache.commons.io.IOUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
@Component
public class EasySMTAConnector {
private static final Log LOG = LogFactory.getLog(EasySMTAConnector.class);
// FIXME Use the safe URL
// private static final String ITPGRFA_PID_URL =
// "https://www.itworks.it/itt/index.php?r=extsys/getUserDetails2";
private static final String ITPGRFA_PID_URL = "https://www.itworks.it/itt/index.php?r=extsys/getUserDetails2&esUsername=XXX&esPassword=YYY&usEmail=ZZZ";
@Value("${itpgrfa.easysmta.username}")
private String serverUsername;
@Value("${itpgrfa.easysmta.password}")
private String serverPassword;
public EasySMTAUserData getUserData(String emailAddress) {
final HttpClient httpclient = new DefaultHttpClient();
// FIXME Url contains username+password, see below
String url = ITPGRFA_PID_URL.replace("XXX", serverUsername);
url = url.replace("YYY", serverPassword);
url = url.replace("ZZZ", emailAddress);
LOG.warn("Using unsafe fetch URL: " + url);
final HttpGet httpget = new HttpGet(url);
HttpResponse response = null;
BufferedReader br = null;
try {
LOG.info("Using " + serverUsername + " as Easy-SMTA username.");
// FIXME Use these when Easy-SMTA is fixed
// httpclient.getParams().setParameter("esUsername",
// serverUsername);
// httpclient.getParams().setParameter("esPassword",
// serverPassword);
// httpclient.getParams().setParameter("usEmail", emailAddress);
response = httpclient.execute(httpget);
// Get hold of the response entity
final HttpEntity entity = response.getEntity();
LOG.debug(entity.getContentType() + " " + entity.getContentLength());
// If the response does not enclose an entity, there is no
// need to bother about connection release
if (entity != null) {
ObjectMapper objectMapper = new ObjectMapper();
JsonNode tree = objectMapper.readTree(entity.getContent());
LOG.debug(tree);
if (tree.has("errorCode")) {
// Check failed
LOG.warn("Checking PID server failed with: " + tree);
// TODO Report various errorCodes!
} else {
if (LOG.isDebugEnabled()) {
LOG.debug(tree);
}
return new EasySMTAUserData(tree.get("pid").asText(), tree.get("name").asText(), tree.get("surname").asText(), tree.get("email").asText(),
tree.get("orgName").asText(), tree.get("country").asText());
}
}
} catch (final ClientProtocolException e) {
LOG.error(e.getMessage(), e);
} catch (IOException e) {
LOG.error(e);
} finally {
IOUtils.closeQuietly(br);
httpget.releaseConnection();
LOG.debug("EasySMTA streams closed.");
}
return null;
}
/**
* Data returned by Easy-SMTA
*
* @author matijaobreza
*/
public class EasySMTAUserData {
public String pid;
public String firstName;
public String lastName;
public String email;
public String organization;
public String countryIsoCode3;
public EasySMTAUserData(String pid, String firstName, String lastName, String email, String organization, String countryIsoCode3) {
this.pid = pid;
this.firstName = firstName;
this.lastName = lastName;
this.email = email;
this.organization = organization;
this.countryIsoCode3 = countryIsoCode3;
}
@Override
public String toString() {
return "PID " + firstName + " " + lastName + ", " + organization + ", country=" + countryIsoCode3;
}
}
}
......@@ -20,6 +20,7 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
......@@ -358,4 +359,11 @@ public class GenesysServiceImpl implements GenesysService, TraitService {
public void saveSvalbards(List<SvalbardData> svalbards) {
svalbardRepository.save(svalbards);
}
@Override
public long countAvailable(Set<Long> accessionIds) {
if (accessionIds == null || accessionIds.size() == 0)
return 0;
return accessionRepository.countAvailable(accessionIds);
}
}
......@@ -111,7 +111,7 @@ public class HtmlController extends BaseController {
try {
InetAddress remoteInetAddr = InetAddress.getByName(remoteAddr);
isLocalRequest = remoteInetAddr.isAnyLocalAddress() || remoteInetAddr.isLoopbackAddress();
_logger.debug("Remote addr: " + remoteAddr + " " + remoteInetAddr + " isLocal=" + isLocalRequest);
_logger.warn("Remote addr: " + remoteAddr + " " + remoteInetAddr + " isLocal=" + isLocalRequest);
} catch (UnknownHostException e1) {
_logger.warn(e1.getMessage());
}
......
/**
* Copyright 2013 Global Crop Diversity Trust
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
package org.genesys2.server.servlet.controller;
import org.apache.commons.lang.StringUtils;
import org.genesys2.server.service.ContentService;
import org.genesys2.server.service.GenesysService;
import org.genesys2.server.service.impl.EasySMTAConnector;
import org.genesys2.server.service.impl.EasySMTAConnector.EasySMTAUserData;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
/**
* Controller to manage request processing.
*
* @author matijaobreza
*/
@Controller
@Scope("request")
@RequestMapping("/request")
public class RequestController extends BaseController {
@Autowired
private SelectionBean selectionBean;
@Autowired
private GenesysService genesysService;
@Autowired
private ContentService contentService;
@Autowired
private EasySMTAConnector pidChecker;
/**
* Give information about the request process
*
* @param model
* @return
*/
@RequestMapping
public String view(ModelMap model, @RequestParam(value = "page", required = false, defaultValue = "1") int page) {
model.addAttribute("blurp", contentService.getGlobalArticle("request-intro", getLocale()));
model.addAttribute("totalCount", selectionBean.size());
model.addAttribute("availableCount", genesysService.countAvailable(selectionBean.copy()));
model.addAttribute("pagedData", genesysService.listAccessions(selectionBean.copy(), new PageRequest(page - 1, 50, new Sort("accessionName"))));
return "/request/index";
}
@RequestMapping(method = RequestMethod.POST, value = "/start")
public String start(ModelMap model) {
model.addAttribute("blurp", contentService.getGlobalArticle("request-personal", getLocale()));
return "/request/personal";
}
@RequestMapping(method = RequestMethod.POST, value = "/submit")
public String submit(ModelMap model, @RequestParam(value = "email", defaultValue = "", required = true) String emailAddress) {
emailAddress = emailAddress.trim();
if (StringUtils.isBlank(emailAddress)) {
_logger.warn("No email address was specified for request. Stopping here.");
return "/request/personal";
}
_logger.info("Checking for ITPGRFA PID account for " + emailAddress);
EasySMTAUserData pid = pidChecker.getUserData(emailAddress);
if (pid == null) {
_logger.warn("No such user in ITPGRFA system");
} else {
// TODO send email to registered email address, wait for response
_logger.info("TODO TODO TODO : Send email to : " + pid);
}
// Whatever the response is, we render the same message
model.addAttribute("blurp", contentService.getGlobalArticle("request-received", getLocale()));
return "/request/received";
}
}
......@@ -53,10 +53,9 @@ public class SelectionController extends BaseController {
return "/selection/index";
}
@RequestMapping("/order")
@RequestMapping(value = "/order")
public String order(ModelMap model) {
// TODO
return "/todo";
return "redirect:/request";
}
@RequestMapping("/add/{id}")
......
......@@ -186,6 +186,11 @@ accession.sampleStatus.415=Segregating population
accession.sampleStatus.420=Mutant/genetic stock
accession.sampleStatus.500=Advanced/improved cultivar
accession.sampleStatus.999=Other
accession.availability=Availability
accession.availability.=Unknown
accession.availability.true=Available
accession.availability.false=Not available
accession.page.profile.title=Accession profile: {0}
accession.page.resolve.title=Multiple accessions found
......@@ -292,5 +297,11 @@ maps.view-map=View map
audit.createdBy=Created by {0}
audit.lastModifiedBy=Last updated by {0}
itpgrfa.page.list.title=Parties to the ITPGRFA
request.page.title=Requesting material from holding institutes
request.total-vs-available=Out of {0} accessions listed, {1} are known to be available for distribution.
request.start-request=Request available germplasm
request.your-email=Your E-mail address:
{
"en": {
"title": "Start requesting material",
"body": "<p>In the table below you will find the accessions you have added to your list. The table indicates whether or not these accessions are available for distribution.</p><p>Please note that only accessions marked as <b>Available</b> will be included in your request for germplasm.</p><p>Once you have reviewed your selection, click <b>Continue</b> button below to initiate the process of requesting for germplasm.</p>"
}
}
\ No newline at end of file
{
"en": {
"title": "Initiate material request",
"body": "<p>An account with ITPGRFA's Easy-SMTA is required to request for germplasm with this system. Please provide the email address you have used with ITPGRFA's Easy-SMTA.</p><p>We will check the email address against their system and only then proceed with your request.</p>"
}
}
\ No newline at end of file
{
"en": {
"title": "Material request received",
"body": "<p>We have checked the provided email address against ITPGRFA server.</p><p>Within a few minutes you will have received our message at the email address you have provided with further instructions to confirm your request for germplasm.</p><p>Make sure you also check your <b>SPAM</b> folder.</p><p>If the message does not arrive, please initiate the request again by going to 'My List'.</p>"
}
}
\ No newline at end of file
......@@ -37,7 +37,7 @@
</div>
</c:if>
<c:if test="${not accession.availability}">
<c:if test="${accession.availability eq false}">
<div class="alert alert-warning">
<spring:message code="accession.not-available-for-distribution" />
</div>
......@@ -91,6 +91,13 @@
<td><a href="<c:url value="/acn/t/${accession.taxonomy.genus}/${accession.taxonomy.species}" />"><c:out value="${accession.taxonomy.taxonName}" /></a> <br /> <a
href="<c:url value="/wiews/${accession.institute.code.toLowerCase()}/t/${accession.taxonomy.genus}/${accession.taxonomy.species}" />"><spring:message code="accession.taxonomy-at-institute" arguments="${accession.taxonomy.taxonName}|||${accession.institute.code}" argumentSeparator="|||" /></a></td>
</tr>
<tr>
<td><spring:message code="accession.availability" /></td>
<td><spring:message code="accession.availability.${accession.availability}" /></td>
</tr>
<tr>
<td><spring:message code="accession.otherNames" /></td>
<td><c:out value="${accessionNames.accNames}" /><br /> <c:out value="${accessionNames.otherIds}" /></td>
......
<!DOCTYPE html>
<%@include file="/WEB-INF/jsp/init.jsp"%>
<html>
<head>
<title><spring:message code="request.page.title" /></title>
</head>
<body>
<h1>
<spring:message code="request.page.title" />
</h1>
<c:if test="${pagedData == null}">
<div class="alert alert-info">
<spring:message code="selection.empty-list-warning" />
</div>
</c:if>
<c:if test="${pagedData != null}">
<div class="alert alert-info">
<spring:message code="request.total-vs-available" arguments="${totalCount},${availableCount}" />
</div>
<%@include file="/WEB-INF/jsp/content/include/blurp-display.jsp"%>
<div class="nav-header">
<spring:message code="accessions.number" arguments="${pagedData.totalElements}" />
<br />
<spring:message code="paged.pageOfPages" arguments="${pagedData.number+1},${pagedData.totalPages}" />
<a class="${pagedData.number eq 0 ? 'disabled' :''}" href="?page=${pagedData.number eq 0 ? 1 : pagedData.number}"><spring:message code="pagination.previous-page" /></a> <a href="?page=${pagedData.number + 2}"><spring:message code="pagination.next-page" /></a>
</div>
<table class="accessions">
<thead>
<tr>
<td class="idx-col"></td>
<td><spring:message code="accession.availability" /></td>
<td><spring:message code="accession.accessionName" /></td>
<td class="notimportant"><spring:message code="accession.taxonomy" /></td>
<%-- <td class="notimportant"><spring:message code="accession.origin" /></td> --%>
<td><spring:message code="accession.holdingInstitute" /></td>
</tr>
</thead>
<tbody>
<c:forEach items="${pagedData.content}" var="accession" varStatus="status">
<tr id="a${accession.id}" class="acn targeted ${status.count % 2 == 0 ? 'even' : 'odd'} ${accession.availability ? '' : 'not-available'}">
<td class="idx-col">${status.count + pagedData.size * pagedData.number}</td>
<td><spring:message code="accession.availability.${accession.availability}" /></td>
<td><a href="<c:url value="/acn/id/${accession.id}" />"><b><c:out value="${accession.accessionName}" /></b></a></td>
<td class="notimportant"><c:out value="${accession.taxonomy.taxonName}" /></td>
<%-- <td class="notimportant"><c:out value="${accession.countryOfOrigin.getName(pageContext.response.locale)}" /></td> --%>
<td class="notimportant"><a href="<c:url value="/wiews/${accession.institute.code.toLowerCase()}" />"><c:out value="${accession.institute.code}" /></a></td>
</tr>
</c:forEach>
</tbody>
</table>
<c:if test="${availableCount gt 0}">
<form method="post" action="<c:url value="/request/start" />" class="form-horizontal">
<div class="form-actions">
<input class="btn btn-primary" type="submit" value="<spring:message code="request.start-request" />" />
</div>
</form>
</c:if>
</c:if>
<script type="text/javascript">
/* jQuery(document).ready(function(){
if(document.location.hash != '') {
setTimeout(function() { document.location.hash=''; }, 2000);
}
}); */
</script>
</body>
</html>
\ No newline at end of file
<!DOCTYPE html>
<%@include file="/WEB-INF/jsp/init.jsp"%>
<html>
<head>
<title><spring:message code="request.page.title" /></title>
</head>
<body>
<h1>
<spring:message code="request.page.title" />
</h1>
<%@include file="/WEB-INF/jsp/content/include/blurp-display.jsp"%>
<form method="post" action="<c:url value="/request/submit" />" class="form-horizontal">
<div class="form-group">
<label class="col-lg-2 control-label"><spring:message code="request.your-email" /></label>
<div class="col-lg-3">
<input type="text" name="email" class="span3 required email form-control" />
</div>
</div>
<div class="form-actions">
<input class="btn btn-primary" type="submit" value="<spring:message code="request.start-request" />" />
</div>
</form>
</body>
</html>
\ No newline at end of file
<!DOCTYPE html>
<%@include file="/WEB-INF/jsp/init.jsp"%>
<html>
<head>
<title><spring:message code="request.page.title" /></title>
</head>
<body>
<h1>
<spring:message code="request.page.title" />
</h1>
<%@include file="/WEB-INF/jsp/content/include/blurp-display.jsp"%>
</body>
</html>
\ No newline at end of file
......@@ -553,3 +553,8 @@ tr.acn .sel.picked {
height: 300px;
margin-top: 1em;
}
table.accessions tr.not-available > td {
text-decoration: line-through;
opacity: .5;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment