added methods for creating revert operation urls. Started working on notification methods.
git-svn-id: http://svn.research-infrastructures.eu/public/d4science/gcube/trunk/portlets/widgets/grsf-manage-widget@162826 82a268e6-3cf1-43bd-a215-b396298e98cf
This commit is contained in:
parent
bdf27ff071
commit
b13f1eafc9
|
@ -4,6 +4,9 @@
|
|||
<wb-resource deploy-path="/" source-path="/src/main/webapp" tag="defaultRootSource"/>
|
||||
<wb-resource deploy-path="/WEB-INF/classes" source-path="/src/main/java"/>
|
||||
<wb-resource deploy-path="/WEB-INF/classes" source-path="/src/main/resources"/>
|
||||
<dependent-module archiveName="grsf-common-library-1.0.1-SNAPSHOT.jar" deploy-path="/WEB-INF/lib" handle="module:/resource/grsf-common-library/grsf-common-library">
|
||||
<dependency-type>uses</dependency-type>
|
||||
</dependent-module>
|
||||
<property name="context-root" value="grsf-manage-widget"/>
|
||||
<property name="java-output-path" value="/grsf-manage-widget/target/grsf-manage-widget-1.0.0-SNAPSHOT/WEB-INF/classes"/>
|
||||
</wb-module>
|
||||
|
|
18
pom.xml
18
pom.xml
|
@ -83,6 +83,15 @@
|
|||
<artifactId>portal-manager</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.gcube.portal</groupId>
|
||||
<artifactId>notifications-common-library</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.gcube.portlets.user</groupId>
|
||||
<artifactId>gcube-url-shortener</artifactId>
|
||||
<version>[1.0.0-SNAPSHOT,2.0.0-SNAPSHOT)</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.portlet</groupId>
|
||||
<artifactId>portlet-api</artifactId>
|
||||
|
@ -112,18 +121,18 @@
|
|||
<dependency>
|
||||
<groupId>org.gcube.core</groupId>
|
||||
<artifactId>common-scope-maps</artifactId>
|
||||
<scope>provided</scope>
|
||||
<scope>compile</scope>
|
||||
<!-- put at provided for deploying -->
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.gcube.core</groupId>
|
||||
<artifactId>common-encryption</artifactId>
|
||||
<scope>provided</scope>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.gcube.common</groupId>
|
||||
<artifactId>authorization-client</artifactId>
|
||||
<scope>provided</scope>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
|
@ -131,7 +140,7 @@
|
|||
<version>4.11</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-log4j12</artifactId>
|
||||
<scope>provided</scope>
|
||||
|
@ -234,4 +243,5 @@
|
|||
</plugins>
|
||||
</build>
|
||||
|
||||
<packaging>war</packaging>
|
||||
</project>
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
package org.gcube.datacatalogue.grsf_manage_widget.client;
|
||||
|
||||
import org.gcube.datacatalogue.grsf_manage_widget.client.view.ManageProductWidget;
|
||||
|
||||
import com.google.gwt.core.client.EntryPoint;
|
||||
import com.google.gwt.event.shared.HandlerManager;
|
||||
import com.google.gwt.user.client.ui.RootPanel;
|
||||
|
||||
/**
|
||||
* Entry point classes define <code>onModuleLoad()</code>.
|
||||
|
@ -11,7 +15,7 @@ public class GRSFManageWidget implements EntryPoint {
|
|||
* This is the entry point method.
|
||||
*/
|
||||
public void onModuleLoad(){
|
||||
//HandlerManager eventBus = new HandlerManager(null);
|
||||
//RootPanel.get("manageDiv").add(new ManageProductWidget("fffb6167-b570-42a8-92b9-5be28549c3b8", eventBus));
|
||||
HandlerManager eventBus = new HandlerManager(null);
|
||||
RootPanel.get("manageDiv").add(new ManageProductWidget("fffb6167-b570-42a8-92b9-5be28549c3b8", eventBus));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,9 +21,7 @@ import org.gcube.datacatalogue.grsf_manage_widget.shared.SourceRecord;
|
|||
import org.gcube.datacatalogue.grsf_manage_widget.shared.ex.NoGRSFRecordException;
|
||||
import org.gcube.vomanagement.usermanagement.RoleManager;
|
||||
import org.gcube.vomanagement.usermanagement.impl.LiferayRoleManager;
|
||||
import org.gcube.vomanagement.usermanagement.model.GCubeRole;
|
||||
import org.gcube.vomanagement.usermanagement.model.GCubeTeam;
|
||||
import org.gcube.vomanagement.usermanagement.model.GatewayRolesNames;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
@ -162,7 +160,7 @@ public class GRSFNotificationService extends RemoteServiceServlet implements GRS
|
|||
for (String similarGRSFRecord : similarGrsfRecordsAsStrings) {
|
||||
if(similarGRSFRecord.equals(Constants.NO_SIMILAR_GRSF_RECORDS)) // stop here if there is a single element with this information
|
||||
break;
|
||||
|
||||
|
||||
similarRecords.add(Utils.similarGRSFRecordFromJson(similarGRSFRecord));
|
||||
}
|
||||
}
|
||||
|
@ -194,7 +192,7 @@ public class GRSFNotificationService extends RemoteServiceServlet implements GRS
|
|||
// set the values
|
||||
toReturn = new ManageProductBean(semanticId, catalogueIdentifier, uuidKB, grsfType,
|
||||
grsfDomain, grsfName, shortName, traceabilityFlag, Status.fromString(status), null,
|
||||
null, null, sources, similarRecords, connectedBeans);
|
||||
null, null, sources, similarRecords, connectedBeans, false);
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -223,32 +221,31 @@ public class GRSFNotificationService extends RemoteServiceServlet implements GRS
|
|||
String username = pContext.getCurrentUser(getThreadLocalRequest()).getUsername();
|
||||
long userId = pContext.getCurrentUser(getThreadLocalRequest()).getUserId();
|
||||
long groupId = pContext.getCurrentGroupId(getThreadLocalRequest());
|
||||
List<GCubeRole> vreRoles = roleManager.listRolesByUserAndGroup(userId, groupId);
|
||||
List<GCubeTeam> teamRoles = new LiferayRoleManager().listTeamsByUserAndGroup(userId, groupId);
|
||||
// List<GCubeRole> vreRoles = roleManager.listRolesByUserAndGroup(userId, groupId);
|
||||
List<GCubeTeam> teamRoles = roleManager.listTeamsByUserAndGroup(userId, groupId);
|
||||
boolean toSetInSession = false;
|
||||
for (GCubeTeam team : teamRoles) {
|
||||
if(team.getTeamName().equals(Constants.GRSF_CATALOGUE_MANAGER_ROLE)){
|
||||
logger.info("User " + username + " is " + Constants.GRSF_CATALOGUE_MANAGER_ROLE);
|
||||
if(team.getTeamName().equals(Constants.GRSF_CATALOGUE_EDITOR_ROLE) || team.getTeamName().equals(Constants.GRSF_CATALOGUE_REVIEWER_ROLE)){
|
||||
logger.info("User " + username + " is allowed to modify GRSF records");
|
||||
toSetInSession = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(!toSetInSession)
|
||||
for (GCubeRole gCubeTeam : vreRoles) {
|
||||
if(gCubeTeam.getRoleName().equals(GatewayRolesNames.VRE_MANAGER.getRoleName())){
|
||||
logger.info("User " + username + " is " + GatewayRolesNames.VRE_MANAGER.getRoleName());
|
||||
toSetInSession = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// if(!toSetInSession)
|
||||
// for (GCubeRole gCubeTeam : vreRoles) {
|
||||
// if(gCubeTeam.getRoleName().equals(GatewayRolesNames.VRE_MANAGER.getRoleName())){
|
||||
// logger.info("User " + username + " is " + GatewayRolesNames.VRE_MANAGER.getRoleName());
|
||||
// toSetInSession = true;
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
|
||||
getThreadLocalRequest().getSession().setAttribute(Constants.GRSF_ADMIN_SESSION_KEY, toSetInSession);
|
||||
return toSetInSession;
|
||||
}
|
||||
}catch(Exception e){
|
||||
logger.error("Failed to check if the user has team " + Constants.GRSF_CATALOGUE_MANAGER_ROLE
|
||||
+ " or " + GatewayRolesNames.VRE_MANAGER.getRoleName() +"!", e);
|
||||
logger.error("Failed to check if the user belongs to team " + Constants.GRSF_CATALOGUE_EDITOR_ROLE + " or " + Constants.GRSF_CATALOGUE_REVIEWER_ROLE +"!", e);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -342,7 +339,8 @@ public class GRSFNotificationService extends RemoteServiceServlet implements GRS
|
|||
baseUrl = Utils.discoverEndPoint(context);
|
||||
getThreadLocalRequest().getSession().setAttribute(keyPerContext, baseUrl);
|
||||
}
|
||||
return Utils.updateRecord(baseUrl, bean, catalogue, username, administratorFullName);
|
||||
return Utils.updateRecord(baseUrl, bean, catalogue, username, administratorFullName, getThreadLocalRequest(),
|
||||
PortalContext.getConfiguration().getCurrentGroupId(getThreadLocalRequest()));
|
||||
|
||||
}catch(Exception e){
|
||||
logger.error("Unable to update the product.." + e.getMessage());
|
||||
|
|
|
@ -5,7 +5,9 @@ import static org.gcube.resources.discovery.icclient.ICFactory.clientFor;
|
|||
import static org.gcube.resources.discovery.icclient.ICFactory.queryFor;
|
||||
|
||||
import java.io.StringReader;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
|
@ -20,6 +22,7 @@ import javax.servlet.http.HttpSession;
|
|||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
|
||||
import org.gcube.common.encryption.StringEncrypter;
|
||||
import org.gcube.common.portal.PortalContext;
|
||||
import org.gcube.common.resources.gcore.ServiceEndpoint;
|
||||
import org.gcube.common.resources.gcore.ServiceEndpoint.AccessPoint;
|
||||
|
@ -27,15 +30,25 @@ import org.gcube.common.resources.gcore.utils.XPathHelper;
|
|||
import org.gcube.common.scope.api.ScopeProvider;
|
||||
import org.gcube.datacatalogue.ckanutillibrary.server.ApplicationProfileScopePerUrlReader;
|
||||
import org.gcube.datacatalogue.ckanutillibrary.server.DataCatalogue;
|
||||
import org.gcube.datacatalogue.ckanutillibrary.server.DataCatalogueRunningCluster;
|
||||
import org.gcube.datacatalogue.ckanutillibrary.shared.ex.ApplicationProfileNotFoundException;
|
||||
import org.gcube.datacatalogue.common.Constants;
|
||||
import org.gcube.datacatalogue.common.enums.Status;
|
||||
import org.gcube.datacatalogue.grsf_manage_widget.shared.ConnectedBean;
|
||||
import org.gcube.datacatalogue.grsf_manage_widget.shared.ManageProductBean;
|
||||
import org.gcube.datacatalogue.grsf_manage_widget.shared.RevertOperationUrl;
|
||||
import org.gcube.datacatalogue.grsf_manage_widget.shared.RevertOperationUrl.Operation;
|
||||
import org.gcube.datacatalogue.grsf_manage_widget.shared.SimilarGRSFRecord;
|
||||
import org.gcube.portlets.user.urlshortener.UrlShortener;
|
||||
import org.gcube.resources.discovery.client.api.DiscoveryClient;
|
||||
import org.gcube.resources.discovery.client.queries.api.Query;
|
||||
import org.gcube.resources.discovery.client.queries.api.SimpleQuery;
|
||||
import org.gcube.resources.discovery.client.queries.impl.QueryBox;
|
||||
import org.gcube.vomanagement.usermanagement.RoleManager;
|
||||
import org.gcube.vomanagement.usermanagement.UserManager;
|
||||
import org.gcube.vomanagement.usermanagement.impl.LiferayRoleManager;
|
||||
import org.gcube.vomanagement.usermanagement.impl.LiferayUserManager;
|
||||
import org.gcube.vomanagement.usermanagement.model.GCubeTeam;
|
||||
import org.gcube.vomanagement.usermanagement.model.GCubeUser;
|
||||
import org.json.simple.JSONArray;
|
||||
import org.json.simple.JSONObject;
|
||||
|
@ -203,6 +216,32 @@ public class Utils {
|
|||
return toReturn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the extras of this dataset as hashmap
|
||||
* @param extrasAsPairs
|
||||
* @return
|
||||
*/
|
||||
public static Map<String, List<String>> getExtras(List<CkanPair> extrasAsPairs){
|
||||
|
||||
Map<String, List<String>> toReturn = new HashMap<String, List<String>>();
|
||||
|
||||
for (CkanPair ckanPair : extrasAsPairs) {
|
||||
String pairKey = ckanPair.getKey();
|
||||
String pairValue = ckanPair.getValue();
|
||||
|
||||
List<String> values = null;
|
||||
if(toReturn.containsKey(pairKey))
|
||||
values = toReturn.get(pairKey);
|
||||
else
|
||||
values = new ArrayList<String>(1);
|
||||
|
||||
values.add(pairValue);
|
||||
|
||||
toReturn.put(pairKey, values);
|
||||
}
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Discover the service endpoint and return its url
|
||||
* @param context
|
||||
|
@ -257,9 +296,8 @@ public class Utils {
|
|||
* @param catalogue
|
||||
* @return true on success, false otherwise
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static String updateRecord(String serviceUrl, ManageProductBean bean, DataCatalogue catalogue, String username,
|
||||
String fullName) throws Exception{
|
||||
String fullName, HttpServletRequest httpServletRequest, long groupId) throws Exception{
|
||||
|
||||
if(serviceUrl == null)
|
||||
throw new IllegalArgumentException("GRSF Updater service url cannot be null");
|
||||
|
@ -269,82 +307,218 @@ public class Utils {
|
|||
|
||||
try(CloseableHttpClient httpClient = HttpClientBuilder.create().build();){
|
||||
|
||||
JSONObject obj = new JSONObject();
|
||||
obj.put(Constants.ADMINISTRATOR_FULLNAME, fullName);
|
||||
obj.put(Constants.CATALOGUE_ID, bean.getCatalogueIdentifier());
|
||||
obj.put(Constants.KB_ID, bean.getKnowledgeBaseIdentifier());
|
||||
obj.put(Constants.NEW_STATUS, bean.getNewStatus().toString().toLowerCase());
|
||||
obj.put(Constants.OLD_STATUS, bean.getCurrentStatus().toString().toLowerCase());
|
||||
obj.put(Constants.TRACEABILITY_FLAG, bean.isTraceabilityFlag());
|
||||
// if there are merges, update the status of the involved records immediately
|
||||
if(bean.isMergesInvolved())
|
||||
updateStatusInvolvedRecords(bean, catalogue);
|
||||
|
||||
String annotation = bean.getAnnotation();
|
||||
if(annotation != null)
|
||||
obj.put(Constants.ANNOTATION, annotation.replaceAll("\"", ""));
|
||||
// send update to the knowledge base
|
||||
updateKB(httpClient, serviceUrl, bean, catalogue, username, fullName);
|
||||
|
||||
obj.put(Constants.SHORT_NAME_OLD, bean.getShortName());
|
||||
// send email to Editors and Reviewers if merges are involved or the record was rejected (but the record was the result of a merge) TODO
|
||||
if(bean.isMergesInvolved() || bean.getNewStatus().equals(Status.Rejected))
|
||||
sendEmailAdministrators(bean, catalogue, username, fullName, groupId, httpServletRequest);
|
||||
|
||||
if(bean.getShortNameUpdated() == null || bean.getShortNameUpdated().isEmpty())
|
||||
bean.setShortNameUpdated(bean.getShortName());
|
||||
|
||||
obj.put(Constants.SHORT_NAME_NEW, bean.getShortNameUpdated());
|
||||
obj.put(Constants.OLD_STATUS, bean.getCurrentStatus().toString().toLowerCase());
|
||||
|
||||
// prepare connections
|
||||
List<ConnectedBean> connections = bean.getConnectTo();
|
||||
JSONArray connectionsJson = new JSONArray();
|
||||
|
||||
for(ConnectedBean c: connections){
|
||||
JSONObject cc = new JSONObject();
|
||||
cc.put(Constants.SOURCE_KNOWLEDGE_BASE_ID, c.getSourceKnowledgeBaseId());
|
||||
cc.put(Constants.DEST_KNOWLEDGE_BASE_ID, c.getDestKnowledgeBaseId());
|
||||
cc.put(Constants.SOURCE_DOMAIN, c.getSourceDomain());
|
||||
// cc.put(Constants.SUGGESTED, c.isExtra());
|
||||
// cc.put(Constants.TO_BE_KEPT, c.isToBeKept());
|
||||
connectionsJson.add(cc);
|
||||
}
|
||||
obj.put(Constants.CONNECTIONS, connectionsJson);
|
||||
|
||||
// prepare similar grsf records
|
||||
List<SimilarGRSFRecord> similarRecords = bean.getSimilarGrsfRecords();
|
||||
JSONArray similarRecordsJson = new JSONArray();
|
||||
for(SimilarGRSFRecord s: similarRecords){
|
||||
JSONObject ss = new JSONObject();
|
||||
ss.put(Constants.KB_ID, s.getKnowledgeBaseId());
|
||||
ss.put(Constants.MERGE, s.isSuggestedMerge());
|
||||
similarRecordsJson.add(ss);
|
||||
}
|
||||
obj.put(Constants.SIMILAR_GRSF_RECORDS, similarRecordsJson);
|
||||
|
||||
logger.info("Update request looks like " + obj.toJSONString());
|
||||
|
||||
HttpPost request = new HttpPost(serviceUrl + Constants.SERVICE_POST_METHOD);
|
||||
request.setHeader("Accept", "application/json");
|
||||
request.setHeader("Content-type", "application/json");
|
||||
StringEntity params = new StringEntity(obj.toJSONString());
|
||||
request.setEntity(params);
|
||||
HttpResponse response = httpClient.execute(request);
|
||||
|
||||
logger.debug("Response code is " + response.getStatusLine().getStatusCode() + " and response message is " + response.getStatusLine().getReasonPhrase());
|
||||
|
||||
String result = EntityUtils.toString(response.getEntity());
|
||||
JSONParser parser = new JSONParser();
|
||||
JSONObject parsedJSON = (JSONObject)parser.parse(result);
|
||||
|
||||
if(response.getStatusLine().getStatusCode() != Constants.STATUS_SUCCESS){
|
||||
throw new Exception("Update failed at knowledge base side!");
|
||||
}else if(!(boolean) parsedJSON.get(Constants.UPDATE_RESULT))
|
||||
throw new IllegalArgumentException(
|
||||
"Update failed for the following reason " + parsedJSON.get(Constants.ERROR_MESSAGE));
|
||||
|
||||
// send email to VRE administrators and the user as well TODO
|
||||
// create a post about the operation
|
||||
createSocialPost(bean, catalogue, username, fullName);
|
||||
|
||||
}catch(Exception e){
|
||||
logger.error("Unable to update this Item " + e);
|
||||
logger.error("Unable to update this Item ", e);
|
||||
throw e;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the status of the involved records to "to be merged"
|
||||
* @param bean
|
||||
* @param catalogue
|
||||
* @param username
|
||||
* @param fullName
|
||||
* @throws Exception
|
||||
*/
|
||||
private static void updateStatusInvolvedRecords(ManageProductBean bean, DataCatalogue catalogue) throws Exception {
|
||||
|
||||
String context = ScopeProvider.instance.get();
|
||||
String sysApi = fetchSysAPI(context);
|
||||
for(SimilarGRSFRecord s: bean.getSimilarGrsfRecords()){
|
||||
if(s.isSuggestedMerge()){
|
||||
String productId = s.getKnowledgeBaseId();
|
||||
Map<String, List<String>> extrasMap = getExtras(catalogue.getDataset(productId, sysApi).getExtras());
|
||||
extrasMap.put(Constants.STATUS_OF_THE_GRSF_RECORD_CUSTOM_KEY, Arrays.asList(Status.To_be_Merged.getOrigName()));
|
||||
catalogue.patchProductCustomFields(productId, sysApi, extrasMap);
|
||||
}
|
||||
}
|
||||
|
||||
// update the current status record
|
||||
String productId = bean.getKnowledgeBaseIdentifier();
|
||||
Map<String, List<String>> extrasMap = getExtras(catalogue.getDataset(productId, sysApi).getExtras());
|
||||
extrasMap.put(Constants.STATUS_OF_THE_GRSF_RECORD_CUSTOM_KEY, Arrays.asList(Status.To_be_Merged.getOrigName()));
|
||||
catalogue.patchProductCustomFields(productId, sysApi, extrasMap);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a post with proper hashtags of the action taken by who and on which record
|
||||
* @param bean
|
||||
* @param catalogue
|
||||
* @param username
|
||||
* @param fullName
|
||||
*/
|
||||
private static void createSocialPost(ManageProductBean bean,
|
||||
DataCatalogue catalogue, String username, String fullName) {
|
||||
List<String> hashtags = getHashTagsFromActions(bean);
|
||||
// TODO
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Send an email to the administrator as well as the
|
||||
* @param bean
|
||||
* @param catalogue
|
||||
* @param username
|
||||
* @param fullName
|
||||
* @param httpSession
|
||||
* @throws Exceptio
|
||||
*/
|
||||
private static void sendEmailAdministrators(ManageProductBean bean,
|
||||
DataCatalogue catalogue, String username, String fullName, long groupId, HttpServletRequest httpServletRequest) throws Exception {
|
||||
|
||||
// get the list of GRSF Reviewers to alert as well
|
||||
RoleManager roleManager = new LiferayRoleManager();
|
||||
List<GCubeTeam> teamRoles = roleManager.listTeamsByGroup(groupId);
|
||||
List<GCubeUser> reviewers = new ArrayList<>();
|
||||
UserManager um = new LiferayUserManager();
|
||||
|
||||
for(GCubeTeam tr: teamRoles){
|
||||
if(tr.getTeamName().equals(Constants.GRSF_CATALOGUE_REVIEWER_ROLE))
|
||||
reviewers.add(um.getUserById(tr.getUserId()));
|
||||
}
|
||||
|
||||
logger.info("List of " + Constants.GRSF_CATALOGUE_REVIEWER_ROLE + " is " + reviewers);
|
||||
|
||||
// build the url that allows to revert the operation TODO
|
||||
Operation operation = bean.isMergesInvolved() ? Operation.MERGE : Operation.DISSECT;
|
||||
getEncodedUrlManage(operation, username, System.currentTimeMillis(), bean.getKnowledgeBaseIdentifier(), httpServletRequest);
|
||||
|
||||
String object = "A GRSF Record has been modified";
|
||||
|
||||
// send the emails reviewers
|
||||
String messageReviewer = "";
|
||||
|
||||
// send email to the editor
|
||||
String messageEditor = "";
|
||||
|
||||
// TODO
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the url to be send for reverting the operation
|
||||
* @param httpSession
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static String getEncodedUrlManage(Operation operation, String administrator, long timestamp, String uuid, HttpServletRequest httpServletRequest) throws Exception{
|
||||
|
||||
String clientUrl = getCurrentClientUrl(httpServletRequest).split("\\?")[0]; // ignore other parameters
|
||||
RevertOperationUrl operationUrl = new RevertOperationUrl(clientUrl, administrator, timestamp, uuid, operation, operation);
|
||||
String shortUrl = operationUrl.getShortUrl();
|
||||
logger.info("Encrypted and shortened url " + shortUrl);
|
||||
return shortUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of hashtags from the actions taken onto the record
|
||||
* @param bean
|
||||
* @return
|
||||
*/
|
||||
private static List<String> getHashTagsFromActions(ManageProductBean bean) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send updates to the knowledge base
|
||||
* @param httpClient
|
||||
* @param serviceUrl
|
||||
* @param bean
|
||||
* @param catalogue
|
||||
* @param username
|
||||
* @param fullName
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
private static void updateKB(CloseableHttpClient httpClient, String serviceUrl, ManageProductBean bean,
|
||||
DataCatalogue catalogue, String username, String fullName) throws Exception{
|
||||
|
||||
JSONObject obj = new JSONObject();
|
||||
obj.put(Constants.ADMINISTRATOR_FULLNAME, fullName);
|
||||
obj.put(Constants.CATALOGUE_ID, bean.getCatalogueIdentifier());
|
||||
obj.put(Constants.KB_ID, bean.getKnowledgeBaseIdentifier());
|
||||
obj.put(Constants.NEW_STATUS, bean.getNewStatus().toString().toLowerCase());
|
||||
obj.put(Constants.OLD_STATUS, bean.getCurrentStatus().toString().toLowerCase());
|
||||
obj.put(Constants.TRACEABILITY_FLAG, bean.isTraceabilityFlag());
|
||||
|
||||
String annotation = bean.getAnnotation();
|
||||
if(annotation != null)
|
||||
obj.put(Constants.ANNOTATION, annotation.replaceAll("\"", ""));
|
||||
|
||||
obj.put(Constants.SHORT_NAME_OLD, bean.getShortName());
|
||||
|
||||
if(bean.getShortNameUpdated() == null || bean.getShortNameUpdated().isEmpty())
|
||||
bean.setShortNameUpdated(bean.getShortName());
|
||||
|
||||
obj.put(Constants.SHORT_NAME_NEW, bean.getShortNameUpdated());
|
||||
obj.put(Constants.OLD_STATUS, bean.getCurrentStatus().toString().toLowerCase());
|
||||
|
||||
// prepare connections
|
||||
List<ConnectedBean> connections = bean.getConnectTo();
|
||||
JSONArray connectionsJson = new JSONArray();
|
||||
|
||||
for(ConnectedBean c: connections){
|
||||
JSONObject cc = new JSONObject();
|
||||
if(c.isRemove() || (c.isConnect() && !c.isRemove())){ // do not send it if it needs to be unconnected but not removed
|
||||
cc.put(Constants.SOURCE_KNOWLEDGE_BASE_ID, c.getSourceKnowledgeBaseId());
|
||||
cc.put(Constants.DEST_KNOWLEDGE_BASE_ID, c.getDestKnowledgeBaseId());
|
||||
cc.put(Constants.SOURCE_DOMAIN, c.getSourceDomain());
|
||||
cc.put(Constants.CONNECTION_TO_REMOVE, c.isRemove());
|
||||
}
|
||||
connectionsJson.add(cc);
|
||||
}
|
||||
obj.put(Constants.CONNECTIONS, connectionsJson);
|
||||
|
||||
// prepare similar grsf records
|
||||
List<SimilarGRSFRecord> similarRecords = bean.getSimilarGrsfRecords();
|
||||
JSONArray similarRecordsJson = new JSONArray();
|
||||
for(SimilarGRSFRecord s: similarRecords){
|
||||
JSONObject ss = new JSONObject();
|
||||
ss.put(Constants.KB_ID, s.getKnowledgeBaseId());
|
||||
ss.put(Constants.MERGE, s.isSuggestedMerge());
|
||||
similarRecordsJson.add(ss);
|
||||
}
|
||||
obj.put(Constants.SIMILAR_GRSF_RECORDS, similarRecordsJson);
|
||||
|
||||
logger.info("Update request looks like " + obj.toJSONString());
|
||||
|
||||
HttpPost request = new HttpPost(serviceUrl + Constants.SERVICE_POST_METHOD);
|
||||
request.setHeader("Accept", "application/json");
|
||||
request.setHeader("Content-type", "application/json");
|
||||
StringEntity params = new StringEntity(obj.toJSONString());
|
||||
request.setEntity(params);
|
||||
HttpResponse response = httpClient.execute(request);
|
||||
|
||||
logger.debug("Response code is " + response.getStatusLine().getStatusCode() + " and response message is " + response.getStatusLine().getReasonPhrase());
|
||||
|
||||
String result = EntityUtils.toString(response.getEntity());
|
||||
JSONParser parser = new JSONParser();
|
||||
JSONObject parsedJSON = (JSONObject)parser.parse(result);
|
||||
|
||||
if(response.getStatusLine().getStatusCode() != Constants.STATUS_SUCCESS){
|
||||
throw new Exception("Update failed at knowledge base side!");
|
||||
}else if(!(boolean) parsedJSON.get(Constants.UPDATE_RESULT))
|
||||
throw new IllegalArgumentException(
|
||||
"Update failed for the following reason " + parsedJSON.get(Constants.ERROR_MESSAGE));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the scope in which ckan information needs to be discovered from the url
|
||||
* @param httpServletRequest
|
||||
|
@ -619,4 +793,16 @@ public class Utils {
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch the sysadmin key from the IS
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static String fetchSysAPI(String context) throws Exception{
|
||||
|
||||
DataCatalogueRunningCluster catalogueRunningInstance = new DataCatalogueRunningCluster(context);
|
||||
return catalogueRunningInstance.getSysAdminToken();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -16,8 +16,8 @@ public class ConnectedBean implements Serializable{
|
|||
private String destSemanticIdentifier;
|
||||
private String destKnowledgeBaseId; // the dest indentifier of a Fishery or Stock (the link is from a Stock to a Fishery and viceversa)
|
||||
private String url;
|
||||
// private boolean isExtra;
|
||||
private boolean toBeKept = true;
|
||||
private boolean remove;
|
||||
private boolean connect;
|
||||
|
||||
public ConnectedBean() {
|
||||
super();
|
||||
|
@ -45,6 +45,14 @@ public class ConnectedBean implements Serializable{
|
|||
|
||||
}
|
||||
|
||||
public boolean isConnect() {
|
||||
return connect;
|
||||
}
|
||||
|
||||
public void setConnect(boolean connect) {
|
||||
this.connect = connect;
|
||||
}
|
||||
|
||||
public String getDestShortName() {
|
||||
return destShortName;
|
||||
}
|
||||
|
@ -83,21 +91,13 @@ public class ConnectedBean implements Serializable{
|
|||
this.sourceDomain = sourceDomain;
|
||||
}
|
||||
|
||||
public boolean isToBeKept() {
|
||||
return toBeKept;
|
||||
public boolean isRemove() {
|
||||
return remove;
|
||||
}
|
||||
|
||||
public void setToBeKept(boolean toBeKept) {
|
||||
this.toBeKept = toBeKept;
|
||||
public void setRemove(boolean remove) {
|
||||
this.remove = remove;
|
||||
}
|
||||
//
|
||||
// public boolean isExtra() {
|
||||
// return isExtra;
|
||||
// }
|
||||
//
|
||||
// public void setExtra(boolean isExtra) {
|
||||
// this.isExtra = isExtra;
|
||||
// }
|
||||
|
||||
public String getUrl() {
|
||||
return url;
|
||||
|
@ -105,15 +105,6 @@ public class ConnectedBean implements Serializable{
|
|||
public void setUrl(String url) {
|
||||
this.url = url;
|
||||
}
|
||||
// @Override
|
||||
// public String toString() {
|
||||
// return "ConnectedBean [sourceKnowledgeBaseId=" + sourceKnowledgeBaseId
|
||||
// + ", sourceDomain=" + sourceDomain + ", destShortName="
|
||||
// + destShortName + ", destSemanticIdentifier="
|
||||
// + destSemanticIdentifier + ", destKnowledgeBaseId="
|
||||
// + destKnowledgeBaseId + ", url=" + url + ", isExtra=" + isExtra
|
||||
// + ", toBeKept=" + toBeKept + "]";
|
||||
// }
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
|
@ -121,11 +112,8 @@ public class ConnectedBean implements Serializable{
|
|||
+ ", sourceDomain=" + sourceDomain + ", destShortName="
|
||||
+ destShortName + ", destSemanticIdentifier="
|
||||
+ destSemanticIdentifier + ", destKnowledgeBaseId="
|
||||
+ destKnowledgeBaseId + ", url=" + url + ", toBeKept="
|
||||
+ toBeKept + "]";
|
||||
+ destKnowledgeBaseId + ", url=" + url + ", remove=" + remove
|
||||
+ ", connect=" + connect + "]";
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -29,6 +29,7 @@ public class ManageProductBean implements Serializable{
|
|||
private List<SourceRecord> sources; // sources for this record
|
||||
private List<SimilarGRSFRecord> similarGrsfRecords;
|
||||
private List<ConnectedBean> connectTo;
|
||||
private boolean mergesInvolved;
|
||||
|
||||
public ManageProductBean() {
|
||||
super();
|
||||
|
@ -40,7 +41,7 @@ public class ManageProductBean implements Serializable{
|
|||
String shortName, boolean traceabilityFlag, Status currentStatus,
|
||||
Status newStatus, String annotation,
|
||||
Map<String, String> extrasIfAvailable, List<SourceRecord> sources,
|
||||
List<SimilarGRSFRecord> similarGrsfRecords, List<ConnectedBean> connectedBeans) {
|
||||
List<SimilarGRSFRecord> similarGrsfRecords, List<ConnectedBean> connectedBeans, boolean mergesInvolved) {
|
||||
super();
|
||||
this.semanticIdentifier = semanticIdentifier;
|
||||
this.catalogueIdentifier = catalogueIdentifier;
|
||||
|
@ -58,6 +59,7 @@ public class ManageProductBean implements Serializable{
|
|||
this.sources = sources;
|
||||
this.similarGrsfRecords = similarGrsfRecords;
|
||||
this.connectTo = connectedBeans;
|
||||
this.mergesInvolved = mergesInvolved;
|
||||
}
|
||||
|
||||
public String getSemanticIdentifier() {
|
||||
|
@ -190,6 +192,14 @@ public class ManageProductBean implements Serializable{
|
|||
this.connectTo = connectTo;
|
||||
}
|
||||
|
||||
public boolean isMergesInvolved() {
|
||||
return mergesInvolved;
|
||||
}
|
||||
|
||||
public void setMergesInvolved(boolean mergesInvolved) {
|
||||
this.mergesInvolved = mergesInvolved;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ManageProductBean [semanticIdentifier=" + semanticIdentifier
|
||||
|
@ -202,6 +212,7 @@ public class ManageProductBean implements Serializable{
|
|||
+ currentStatus + ", newStatus=" + newStatus + ", annotation="
|
||||
+ annotation + ", extrasIfAvailable=" + extrasIfAvailable
|
||||
+ ", sources=" + sources + ", similarGrsfRecords="
|
||||
+ similarGrsfRecords + ", connectTo=" + connectTo + "]";
|
||||
+ similarGrsfRecords + ", connectTo=" + connectTo
|
||||
+ ", mergesInvolved=" + mergesInvolved + "]";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,245 @@
|
|||
package org.gcube.datacatalogue.grsf_manage_widget.shared;
|
||||
|
||||
import java.net.URLDecoder;
|
||||
import java.net.URLEncoder;
|
||||
|
||||
import org.gcube.common.encryption.StringEncrypter;
|
||||
import org.gcube.portlets.user.urlshortener.UrlShortener;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Encode and decode the url for reverting operations
|
||||
* @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it)
|
||||
*/
|
||||
public class RevertOperationUrl {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(RevertOperationUrl.class);
|
||||
|
||||
// parameters for reverting operations
|
||||
public static final String MANAGE_QUERY_PARAM = "manage=true&";
|
||||
public static final String ADMIN_QUERY_PARAM = "admin";
|
||||
public static final String TIMESTAMP_QUERY_PARAM = "t";
|
||||
public static final String UUID_QUERY_PARAM = "uuid";
|
||||
public static final String OPERATION_REVERT_QUERY_PARAM = "operation_revert";
|
||||
|
||||
public enum Operation {
|
||||
|
||||
MERGE("merge"),
|
||||
DISSECT("dissect");
|
||||
private String name;
|
||||
|
||||
private Operation(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private String baseUrl;
|
||||
private String admin;
|
||||
private long timestamp;
|
||||
private String uuid;
|
||||
private Operation operation;
|
||||
private Operation op;
|
||||
|
||||
/**
|
||||
* @param admin
|
||||
* @param timestamp
|
||||
* @param uuid
|
||||
* @param operation
|
||||
* @param op
|
||||
*/
|
||||
public RevertOperationUrl(String baseUrl, String admin, long timestamp, String uuid,
|
||||
Operation operation, Operation op) {
|
||||
super();
|
||||
this.baseUrl = baseUrl;
|
||||
this.admin = admin;
|
||||
this.timestamp = timestamp;
|
||||
this.uuid = uuid;
|
||||
this.operation = operation;
|
||||
this.op = op;
|
||||
}
|
||||
|
||||
|
||||
public String getShortUrl() throws Exception{
|
||||
|
||||
String query = ADMIN_QUERY_PARAM + "=" + admin + "&" + TIMESTAMP_QUERY_PARAM + "=" + timestamp +"&" + UUID_QUERY_PARAM + "=" + uuid + "&" + OPERATION_REVERT_QUERY_PARAM + "=" + operation;
|
||||
logger.info("Query is " + query);
|
||||
String encryptedQuery = StringEncrypter.getEncrypter().encrypt(query);
|
||||
encryptedQuery = URLEncoder.encode(encryptedQuery, "UTF-8");
|
||||
String encryptedUrl =
|
||||
baseUrl
|
||||
+ MANAGE_QUERY_PARAM + "&"
|
||||
+ encryptedQuery;
|
||||
UrlShortener shortener = new UrlShortener();
|
||||
String shortUrl = null;
|
||||
try{
|
||||
if(shortener!=null && shortener.isAvailable())
|
||||
shortUrl = shortener.shorten(encryptedUrl);
|
||||
}catch (Exception e) {
|
||||
logger.warn("Unable to get short url", e);
|
||||
shortUrl = encryptedUrl;
|
||||
}
|
||||
|
||||
logger.debug("Encrypted and shortened url " + shortUrl);
|
||||
return shortUrl;
|
||||
|
||||
}
|
||||
|
||||
public RevertOperationUrl(String encryptedUrl) throws Exception{
|
||||
|
||||
if(encryptedUrl == null)
|
||||
throw new IllegalArgumentException("encryptedUrl is null");
|
||||
|
||||
String params = encryptedUrl.split("\\?")[1];
|
||||
logger.debug("Params encrypted are " + params);
|
||||
|
||||
// remove MANAGE_QUERY_PARAM
|
||||
params = params.replace(MANAGE_QUERY_PARAM + "&", "");
|
||||
|
||||
String decoded = URLDecoder.decode(params, "UTF-8");
|
||||
String decrypted = StringEncrypter.getEncrypter().decrypt(decoded);
|
||||
|
||||
logger.info("Decrypted is " + decrypted);
|
||||
|
||||
try{
|
||||
String[] splittedQuery = decrypted.split("&");
|
||||
for (int i = 0; i < splittedQuery.length; i++) {
|
||||
String subParam = splittedQuery[i];
|
||||
String[] queryAndValue = subParam.split("=");
|
||||
String query = queryAndValue[0];
|
||||
String value = queryAndValue[1];
|
||||
|
||||
switch (query) {
|
||||
case ADMIN_QUERY_PARAM:
|
||||
this.admin = value;
|
||||
break;
|
||||
case TIMESTAMP_QUERY_PARAM:
|
||||
this.timestamp = Long.valueOf(value);
|
||||
break;
|
||||
case UUID_QUERY_PARAM:
|
||||
this.uuid = value;
|
||||
break;
|
||||
case OPERATION_REVERT_QUERY_PARAM:
|
||||
this.operation = Operation.valueOf(value);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}catch(Exception e){
|
||||
logger.error("Failed to parse url", e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public String getBaseUrl() {
|
||||
return baseUrl;
|
||||
}
|
||||
|
||||
|
||||
public void setBaseUrl(String baseUrl) {
|
||||
this.baseUrl = baseUrl;
|
||||
}
|
||||
|
||||
|
||||
public String getAdmin() {
|
||||
return admin;
|
||||
}
|
||||
|
||||
|
||||
public void setAdmin(String admin) {
|
||||
this.admin = admin;
|
||||
}
|
||||
|
||||
|
||||
public long getTimestamp() {
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
|
||||
public void setTimestamp(long timestamp) {
|
||||
this.timestamp = timestamp;
|
||||
}
|
||||
|
||||
|
||||
public String getUuid() {
|
||||
return uuid;
|
||||
}
|
||||
|
||||
|
||||
public void setUuid(String uuid) {
|
||||
this.uuid = uuid;
|
||||
}
|
||||
|
||||
|
||||
public Operation getOperation() {
|
||||
return operation;
|
||||
}
|
||||
|
||||
|
||||
public void setOperation(Operation operation) {
|
||||
this.operation = operation;
|
||||
}
|
||||
|
||||
|
||||
public Operation getOp() {
|
||||
return op;
|
||||
}
|
||||
|
||||
|
||||
public void setOp(Operation op) {
|
||||
this.op = op;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "RevertOperationUrl [baseUrl=" + baseUrl + ", admin=" + admin
|
||||
+ ", timestamp=" + timestamp + ", uuid=" + uuid
|
||||
+ ", operation=" + operation + ", op=" + op + "]";
|
||||
}
|
||||
|
||||
// public static void main(String[] args) throws Exception {
|
||||
//
|
||||
// ScopeProvider.instance.set("/gcube/devNext/NextNext");
|
||||
// String url = "https://bluebridge.d4science.org/group/grsf_admin/data-catalogue?";
|
||||
//
|
||||
// // try encrypt + encode
|
||||
// String query = "admin=costantino.perciante&t="+ System.currentTimeMillis() +"&uuid=" + UUID.randomUUID().toString() + "&operation_revert=merge";
|
||||
// String encrypted = StringEncrypter.getEncrypter().encrypt(query);
|
||||
// encrypted = URLEncoder.encode(encrypted, "UTF-8");
|
||||
//
|
||||
//
|
||||
// String encryptedUrl = url + encrypted;
|
||||
// System.out.println("Encrypted is " + encryptedUrl);
|
||||
//
|
||||
// UrlShortener shortener = new UrlShortener();
|
||||
// String shortUrl = null;
|
||||
// try{
|
||||
// if(shortener!=null && shortener.isAvailable())
|
||||
// shortUrl = shortener.shorten(encryptedUrl);
|
||||
// }catch (Exception e) {
|
||||
// e.printStackTrace();
|
||||
// shortUrl = encryptedUrl;
|
||||
// }
|
||||
//
|
||||
// System.out.println("Encrypted is " + shortUrl);
|
||||
//
|
||||
//
|
||||
// // try decode + decrypt
|
||||
// String params = encryptedUrl.split("\\?")[1];
|
||||
// System.out.println("Params encrypted are " + params);
|
||||
// String decoded = URLDecoder.decode(encrypted, "UTF-8");
|
||||
// String decrypted = StringEncrypter.getEncrypter().decrypt(decoded);
|
||||
//
|
||||
// System.out.println("Decrypted is " + decrypted);
|
||||
//}
|
||||
|
||||
}
|
|
@ -16,8 +16,6 @@ public class SimilarGRSFRecord implements Serializable{
|
|||
private String shortName;
|
||||
private String url;
|
||||
private boolean suggestedMerge;
|
||||
// private boolean isExtra;
|
||||
// private boolean toBeKept = true;
|
||||
|
||||
public SimilarGRSFRecord() {
|
||||
super();
|
||||
|
@ -108,23 +106,4 @@ public class SimilarGRSFRecord implements Serializable{
|
|||
+ suggestedMerge + "]";
|
||||
}
|
||||
|
||||
// public boolean isExtra() {
|
||||
// return isExtra;
|
||||
// }
|
||||
//
|
||||
// public void setExtra(boolean isExtra) {
|
||||
// this.isExtra = isExtra;
|
||||
// }
|
||||
// @Override
|
||||
// public String toString() {
|
||||
// return "SimilarGRSFRecord [description=" + description
|
||||
// + ", knowledgeBaseId=" + knowledgeBaseId
|
||||
// + ", semanticIdentifier=" + semanticIdentifier + ", shortName="
|
||||
// + shortName + ", url=" + url + ", suggestedMerge="
|
||||
// + suggestedMerge + ", isExtra=" + isExtra + ", toBeKept="
|
||||
// + toBeKept + "]";
|
||||
// }
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue