325 lines
13 KiB
Java
325 lines
13 KiB
Java
package org.gcube.portlets.user.performfish;
|
|
|
|
import java.io.BufferedReader;
|
|
import java.io.IOException;
|
|
import java.io.InputStream;
|
|
import java.io.InputStreamReader;
|
|
import java.io.StringReader;
|
|
import java.net.URL;
|
|
import java.sql.Connection;
|
|
import java.util.ArrayList;
|
|
import java.util.Date;
|
|
import java.util.List;
|
|
|
|
import javax.portlet.PortletException;
|
|
import javax.portlet.PortletRequestDispatcher;
|
|
import javax.portlet.RenderRequest;
|
|
import javax.portlet.RenderResponse;
|
|
import javax.portlet.ResourceRequest;
|
|
import javax.portlet.ResourceResponse;
|
|
import javax.servlet.http.HttpServletRequest;
|
|
import javax.xml.parsers.DocumentBuilder;
|
|
import javax.xml.parsers.DocumentBuilderFactory;
|
|
|
|
import org.apache.http.HttpResponse;
|
|
import org.apache.http.client.methods.HttpGet;
|
|
import org.apache.http.impl.client.CloseableHttpClient;
|
|
import org.apache.http.impl.client.HttpClients;
|
|
import org.gcube.common.resources.gcore.ServiceEndpoint;
|
|
import org.gcube.common.resources.gcore.utils.XPathHelper;
|
|
import org.gcube.common.storagehubwrapper.server.tohl.Workspace;
|
|
import org.gcube.common.storagehubwrapper.shared.tohl.WorkspaceFolder;
|
|
import org.gcube.common.storagehubwrapper.shared.tohl.WorkspaceItem;
|
|
import org.gcube.portlets.user.performfish.util.Utils;
|
|
import org.gcube.portlets.user.performfish.util.ValidationResult;
|
|
import org.gcube.portlets.user.performfish.util.db.DBUtil;
|
|
import org.gcube.portlets.user.performfish.util.db.DatabaseConnection;
|
|
import org.gcube.vomanagement.usermanagement.impl.LiferayRoleManager;
|
|
import org.gcube.vomanagement.usermanagement.model.GCubeTeam;
|
|
import org.w3c.dom.Node;
|
|
import org.xml.sax.InputSource;
|
|
|
|
import com.liferay.portal.kernel.json.JSONFactoryUtil;
|
|
import com.liferay.portal.kernel.json.JSONObject;
|
|
import com.liferay.portal.kernel.log.LogFactoryUtil;
|
|
import com.liferay.portal.kernel.util.ParamUtil;
|
|
import com.liferay.portal.service.TeamLocalServiceUtil;
|
|
import com.liferay.portal.util.PortalUtil;
|
|
import com.liferay.util.bridges.mvc.MVCPortlet;
|
|
|
|
/**
|
|
* Portlet implementation class SubmittedFormValidation
|
|
*/
|
|
public class SubmittedFormValidation extends MVCPortlet {
|
|
private static com.liferay.portal.kernel.log.Log _log = LogFactoryUtil.getLog(SubmittedFormValidation.class);
|
|
|
|
private final static String XSLX_MIME = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
|
|
|
|
private static final int RETRY_NO = 3;
|
|
private static String XML_RESULT_ROOT_EXCEPTION = "ExceptionReport";
|
|
private static final String USER_AGENT = "Mozilla/5.0";
|
|
|
|
public static final String VALIDATOR_METHOD_ID = "org.gcube.dataanalysis.wps.statisticalmanager.synchserver.mappedclasses.transducerers.PERFORMFISH_DATA_VALIDATOR_V2";
|
|
|
|
public void render(RenderRequest request, RenderResponse response) {
|
|
GCubeTeam theCompany;
|
|
try {
|
|
HttpServletRequest httpReq = PortalUtil.getOriginalServletRequest(PortalUtil.getHttpServletRequest(request));
|
|
String[] farmIds = ParamUtil.getParameterValues(httpReq, Utils.ENCODED_FARM_PARAM);
|
|
|
|
GCubeTeam theFarm = null;
|
|
theCompany = Utils.checkBelongingToOneCompanyOnly(request, response, this);
|
|
request.setAttribute("theCompany", TeamLocalServiceUtil.getTeam(theCompany.getTeamId()));
|
|
if (farmIds == null || farmIds.length == 0) {
|
|
if (Utils.getUserFarmsNumber(request, response, this) < 2) {
|
|
theFarm = Utils.checkBelongingToOneFarmOnly(request, response, this);
|
|
request.setAttribute("theFarm", theFarm); //pass to the JSP
|
|
}
|
|
}
|
|
else { //the farmId is passed via param on the query string
|
|
long selectedFarmId = Utils.unmaskId(farmIds[0]);
|
|
theFarm = new LiferayRoleManager().getTeam(selectedFarmId);
|
|
if (Utils.checkBelongsToTeam(PortalUtil.getUserId(request), theFarm.getTeamId(), PortalUtil.getScopeGroupId(request)) ) {//check that the user belong ot the farm
|
|
request.setAttribute("theFarm", theFarm); //pass to the JSP
|
|
}
|
|
else {
|
|
PortletRequestDispatcher dispatcher = getPortletContext().getRequestDispatcher(Utils.NOT_BELONGING_ANY_FARM_PAGE_PATH);
|
|
dispatcher.include(request, response);
|
|
}
|
|
}
|
|
if (theFarm != null) {
|
|
request.setAttribute("theCompany", TeamLocalServiceUtil.getTeam(theCompany.getTeamId()));
|
|
request.setAttribute("theFarm", theFarm);
|
|
super.render(request, response);
|
|
} else {
|
|
_log.warn("theFarm is null");
|
|
super.render(request, response);
|
|
}
|
|
} catch (Exception e) {
|
|
e.printStackTrace();
|
|
PortletRequestDispatcher dispatcher = getPortletContext().getRequestDispatcher(Utils.NOT_BELONGING_ANY_FARM_PAGE_PATH);
|
|
try {
|
|
dispatcher.include(request, response);
|
|
} catch (PortletException | IOException e1) {
|
|
e1.printStackTrace();
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
public void serveResource(ResourceRequest resourceRequest, ResourceResponse resourceResponse) throws IOException, PortletException {
|
|
long companyId = ParamUtil.getLong(resourceRequest, "companyId");
|
|
long farmId = ParamUtil.getLong(resourceRequest, "farmId");
|
|
long userId = ParamUtil.getLong(resourceRequest, "userId");
|
|
long groupId = ParamUtil.getLong(resourceRequest, "groupId");
|
|
String encodedURI = ParamUtil.getString(resourceRequest, "encodedURI", null);
|
|
String fileName = ParamUtil.getString(resourceRequest, "fileName", null);
|
|
String username = Utils.getCurrentUser(userId).getUsername();
|
|
String phase = ParamUtil.getString(resourceRequest, "phase", null);
|
|
_log.debug("companyId: " + companyId);
|
|
_log.debug("farmId: " + farmId);
|
|
_log.debug("userId: " + userId);
|
|
_log.debug("groupId: " + groupId);
|
|
_log.debug("encodedURI: " + encodedURI);
|
|
_log.debug("phase: " + phase);
|
|
_log.debug("fileName: " + fileName);
|
|
|
|
|
|
String inputFileLink = encodedURI;
|
|
String template = Utils.getBatchTypeName(phase, fileName);
|
|
String context = Utils.getCurrentContext(groupId);
|
|
String token = Utils.getCurrentUserToken(context, username);
|
|
|
|
_log.debug("context: " + context);
|
|
_log.debug("token: " + token);
|
|
_log.debug("template: " + template);
|
|
|
|
ValidationResult result = doWPSCallToDataMiner(inputFileLink, context, token, template);
|
|
_log.debug("RESULT:\n"+result);
|
|
|
|
if (result.isSuccess()) {
|
|
try {
|
|
String decodedURL = new java.net.URI(inputFileLink).getPath();
|
|
uploadToCompanyRepository(username, context, companyId, farmId, fileName, new URL(decodedURL).openConnection().getInputStream());
|
|
Connection conn = DatabaseConnection.getInstance(Utils.getCurrentContext(groupId)).getConnection();
|
|
java.sql.Date lastActivity = new java.sql.Date(new Date().getTime());
|
|
DBUtil.updateFarmLastSubmissionActivity(conn, farmId, lastActivity);
|
|
} catch (Exception e) {
|
|
result.setComment("The file is valid but we could not upload it in the company repository, please report this issue at support.d4science.org");
|
|
e.printStackTrace();
|
|
}
|
|
}
|
|
JSONObject fileObject = JSONFactoryUtil.createJSONObject();
|
|
fileObject.put("success", result.isSuccess());
|
|
fileObject.put("comment", result.getComment());
|
|
resourceResponse.getWriter().println(fileObject);
|
|
}
|
|
|
|
private String uploadToCompanyRepository(String username, String context, long companyId, long farmId, String fileName, InputStream fileData) throws Exception {
|
|
GCubeTeam theCompany = new LiferayRoleManager().getTeam(companyId);
|
|
GCubeTeam theFarm = new LiferayRoleManager().getTeam(farmId);
|
|
Workspace ws = Utils.getWS(username, context);
|
|
WorkspaceFolder companyRepoFolder = Utils.getWSFarmFolder(username, context, theCompany, theFarm);
|
|
String toReturn = "";
|
|
WorkspaceItem item = ws.uploadFile(companyRepoFolder.getId(), fileData, fileName, "User form submission on " + new Date());
|
|
//ExternalFile item = companyRepoFolder.createExternalFileItem(fileName, "User form submission on " + new Date(), XSLX_MIME, fileData);
|
|
toReturn = item.getId();
|
|
_log.info("Uploaded " + fileName + " - Returned Workspace id=" +toReturn);
|
|
return toReturn;
|
|
}
|
|
|
|
/**
|
|
* performs tha actual call to the service
|
|
* @param peer session
|
|
* @param entry authEntry
|
|
* @param token token
|
|
* @param username username
|
|
* @param inputText
|
|
* @param options
|
|
* @return
|
|
*/
|
|
private ValidationResult doWPSCallToDataMiner(String inputFileLink, String context, String token, String template) {
|
|
_log.info("doWPSCallToDataMiner");
|
|
ValidationResult toReturn = null;
|
|
List<ServiceEndpoint> dms = null;
|
|
try {
|
|
dms = Utils.getDataMinerInstance(context);
|
|
if (dms == null || dms.isEmpty()) {
|
|
return new ValidationResult(false, "Error, no DataMiner cluster in this VRE, please report this issue at www.d4science.org/contact-us");
|
|
}
|
|
ServiceEndpoint se = dms.get(0);
|
|
ServiceEndpoint.AccessPoint ap = se.profile().accessPoints().asCollection().iterator().next();
|
|
_log.info("got DataMiner instance="+ap.address());
|
|
|
|
String apAddress = ap.address();
|
|
_log.info("inputFileLink at: " + inputFileLink);
|
|
String wpsParams = getWPSCallURLParameters(token, inputFileLink, template);
|
|
String responseXML = sendGet(apAddress, wpsParams, token);
|
|
String resultFileURL = parseResult(responseXML);
|
|
_log.info("PARSED OK resultFileURL: " + resultFileURL);
|
|
|
|
InputStream is = new URL(resultFileURL).openConnection().getInputStream();
|
|
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
|
|
String line;
|
|
List<String> resultLines = new ArrayList<>();
|
|
while ((line = reader.readLine()) != null) {
|
|
if (line.split("=").length > 1)
|
|
resultLines.add(line.substring(line.indexOf("=")+1));
|
|
else
|
|
resultLines.add("Validation is successful");
|
|
}
|
|
reader.close();
|
|
for (int i = 0; i < resultLines.size(); i++) {
|
|
_log.debug("Line " + i + ": " + resultLines.get(i));
|
|
}
|
|
toReturn = new ValidationResult(resultLines.get(0).equalsIgnoreCase("OK"), resultLines.get(1));
|
|
} catch (Exception e) {
|
|
e.printStackTrace();
|
|
return new ValidationResult(false, "There was a problem contacting the DataMiner cluster in this VRE ("
|
|
+ context+ ")"
|
|
+ "), please report this issue at http://support.d4science.org");
|
|
}
|
|
return toReturn;
|
|
}
|
|
|
|
|
|
|
|
private String parseResult(String xml) throws Exception {
|
|
String elem = removeXmlStringNamespaceAndPreamble(xml);
|
|
DocumentBuilder docBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
|
|
Node node = docBuilder.parse(new InputSource(new StringReader(elem))).getDocumentElement();
|
|
String rootElement = node.getNodeName();
|
|
XPathHelper helper = new XPathHelper(node);
|
|
List<String> currValue = null;
|
|
if (rootElement.compareTo(XML_RESULT_ROOT_EXCEPTION) == 0) {
|
|
currValue = helper.evaluate("/ExceptionReport");
|
|
if (currValue != null && currValue.size() > 0)
|
|
return currValue.get(0);
|
|
}
|
|
else {
|
|
currValue = helper.evaluate("//ProcessOutputs/Output/Data/ComplexData/FeatureCollection/featureMember/Result/Data/text()");
|
|
if (currValue != null && currValue.size() > 1)
|
|
return currValue.get(1);
|
|
}
|
|
return null;
|
|
}
|
|
|
|
//this remove all the namespaces causing parsing errors as i don't have time to deal with this.
|
|
private static String removeXmlStringNamespaceAndPreamble(String xmlString) {
|
|
return xmlString.replaceAll("(<\\?[^<]*\\?>)?", "") /* remove preamble */
|
|
.replaceAll("xmlns.*?(\"|\').*?(\"|\')", "") /* remove xmlns declaration */
|
|
.replaceAll("(<)(\\w+:)(.*?>)", "$1$3") /* remove opening tag prefix */
|
|
.replaceAll("(</)(\\w+:)(.*?>)", "$1$3")
|
|
.replaceAll("wps:", "")
|
|
.replaceAll("xsi:", "")
|
|
.replaceAll("ogr:",""); /* remove closing tags prefix */
|
|
}
|
|
|
|
// HTTP request
|
|
private String sendGet(String url, String urlParameters, String token) {
|
|
StringBuilder toReturn = new StringBuilder();
|
|
try {
|
|
int i = 1;
|
|
while (i <= RETRY_NO) {
|
|
CloseableHttpClient client = HttpClients.createDefault();
|
|
HttpGet request = new HttpGet(url+"?"+urlParameters);
|
|
_log.info("request to="+request.toString());
|
|
// add header
|
|
request.setHeader("User-Agent", USER_AGENT);
|
|
request.setHeader("Accept-Encoding","UTF-8");
|
|
request.setHeader("Accept-Charset","UTF-8");
|
|
request.setHeader("Content-Encoding","UTF-8");
|
|
|
|
HttpResponse response = client.execute(request);
|
|
|
|
// Get the response
|
|
BufferedReader rd = new BufferedReader
|
|
(new InputStreamReader(
|
|
response.getEntity().getContent()));
|
|
|
|
String line = "";
|
|
while ((line = rd.readLine()) != null) {
|
|
toReturn.append(line);
|
|
}
|
|
i++;
|
|
if (toReturn.toString().compareTo("") == 0 || toReturn.toString().startsWith("Error")) {
|
|
_log.warn("response from Dataminer is empty or an error occurred, retry tentative: " + i + " of " + RETRY_NO);
|
|
_log.error("here is the faulty response from Dataminer="+toReturn.toString());
|
|
} else {
|
|
_log.debug("response from Dataminer="+toReturn.toString());
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
catch (Exception e) {
|
|
e.printStackTrace();
|
|
}
|
|
return toReturn.toString();
|
|
}
|
|
/**
|
|
*
|
|
* @param token the token
|
|
* @param inputFileLink the http of the input file
|
|
* @param options
|
|
* @return the url paramters for WPS Call to perform
|
|
*/
|
|
private String getWPSCallURLParameters(String token, String inputFileLink, String template) {
|
|
StringBuilder sb = new StringBuilder("request=Execute&service=WPS&Version=1.0.0&gcube-token=")
|
|
.append(token)
|
|
.append("&lang=en-US&Identifier=")
|
|
.append(VALIDATOR_METHOD_ID)
|
|
.append("&DataInputs=CompanyData=")
|
|
.append(inputFileLink)
|
|
.append(";Template=")
|
|
.append(template)
|
|
.append(";")
|
|
.append("Overwrite=false;LatestCompanyData=")
|
|
.append(inputFileLink)
|
|
.append(";");
|
|
return sb.toString();
|
|
}
|
|
|
|
|
|
|
|
}
|