server side revised
git-svn-id: http://svn.research-infrastructures.eu/public/d4science/gcube/trunk/portlets/widgets/grsf-manage-widget@162863 82a268e6-3cf1-43bd-a215-b396298e98cf
This commit is contained in:
parent
b13f1eafc9
commit
aee48d3ecd
|
@ -3,11 +3,11 @@ org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
|
|||
org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
|
||||
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
|
||||
org.eclipse.jdt.core.compiler.compliance=1.7
|
||||
org.eclipse.jdt.core.compiler.compliance=1.8
|
||||
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
|
||||
org.eclipse.jdt.core.compiler.debug.localVariable=generate
|
||||
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
|
||||
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
|
||||
org.eclipse.jdt.core.compiler.source=1.7
|
||||
org.eclipse.jdt.core.compiler.source=1.8
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
<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">
|
||||
<dependent-module archiveName="ckan-util-library-2.4.1-SNAPSHOT.jar" deploy-path="/WEB-INF/lib" handle="module:/resource/ckan-util-library/ckan-util-library">
|
||||
<dependency-type>uses</dependency-type>
|
||||
</dependent-module>
|
||||
<property name="context-root" value="grsf-manage-widget"/>
|
||||
|
|
|
@ -27,22 +27,21 @@ public interface GRSFManageWidgetService extends RemoteService {
|
|||
*/
|
||||
String notifyProductUpdate(ManageProductBean bean) throws Exception;
|
||||
|
||||
/**
|
||||
* Check that a record with such semantic identifier exists
|
||||
* @param semanticIdentifier
|
||||
* @return true or false
|
||||
*/
|
||||
boolean checkSemanticIdentifierExists(String semanticIdentifier) throws Exception;
|
||||
|
||||
/**
|
||||
* Check that a record with such semantic identifier exists in a given domain
|
||||
* @param semanticIdentifier
|
||||
* @param domain
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
boolean checkSemanticIdentifierExistsInDomain(String semanticIdentifier, String domain) throws Exception;
|
||||
|
||||
// /**
|
||||
// * Check that a record with such semantic identifier exists
|
||||
// * @param semanticIdentifier
|
||||
// * @return true or false
|
||||
// */
|
||||
// boolean checkSemanticIdentifierExists(String semanticIdentifier) throws Exception;
|
||||
//
|
||||
// /**
|
||||
// * Check that a record with such semantic identifier exists in a given domain
|
||||
// * @param semanticIdentifier
|
||||
// * @param domain
|
||||
// * @return
|
||||
// * @throws Exception
|
||||
// */
|
||||
// boolean checkSemanticIdentifierExistsInDomain(String semanticIdentifier, String domain) throws Exception;
|
||||
|
||||
/**
|
||||
* Identifier of the record (UUID)
|
||||
|
@ -61,4 +60,11 @@ public interface GRSFManageWidgetService extends RemoteService {
|
|||
*/
|
||||
String checkIdentifierExistsInDomain(String id, String domain) throws Exception;
|
||||
|
||||
/**
|
||||
* Check if the given url for revertin the operation is valid and send the request to the knowledge base
|
||||
* @param url
|
||||
* @throws Exception
|
||||
*/
|
||||
void validateRevertOperation(String url) throws Exception;
|
||||
|
||||
}
|
||||
|
|
|
@ -21,11 +21,11 @@ public interface GRSFManageWidgetServiceAsync {
|
|||
|
||||
void isAdminUser(AsyncCallback<Boolean> callback);
|
||||
|
||||
void checkSemanticIdentifierExists(String semanticIdentifier,
|
||||
AsyncCallback<Boolean> callback);
|
||||
|
||||
void checkSemanticIdentifierExistsInDomain(String semanticIdentifier,
|
||||
String domain, AsyncCallback<Boolean> callback);
|
||||
// void checkSemanticIdentifierExists(String semanticIdentifier,
|
||||
// AsyncCallback<Boolean> callback);
|
||||
//
|
||||
// void checkSemanticIdentifierExistsInDomain(String semanticIdentifier,
|
||||
// String domain, AsyncCallback<Boolean> callback);
|
||||
|
||||
void checkIdentifierExists(String id,
|
||||
AsyncCallback<String> callback);
|
||||
|
@ -33,4 +33,6 @@ public interface GRSFManageWidgetServiceAsync {
|
|||
void checkIdentifierExistsInDomain(String id,
|
||||
String domain, AsyncCallback<String> callback);
|
||||
|
||||
void validateRevertOperation(String url, AsyncCallback<Void> callback);
|
||||
|
||||
}
|
||||
|
|
|
@ -5,7 +5,12 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpSession;
|
||||
|
||||
import org.gcube.common.authorization.library.provider.SecurityTokenProvider;
|
||||
import org.gcube.common.portal.PortalContext;
|
||||
import org.gcube.common.scope.api.ScopeProvider;
|
||||
import org.gcube.datacatalogue.ckanutillibrary.server.DataCatalogue;
|
||||
import org.gcube.datacatalogue.ckanutillibrary.server.DataCatalogueFactory;
|
||||
import org.gcube.datacatalogue.ckanutillibrary.server.utils.UtilMethods;
|
||||
|
@ -22,11 +27,14 @@ import org.gcube.datacatalogue.grsf_manage_widget.shared.ex.NoGRSFRecordExceptio
|
|||
import org.gcube.vomanagement.usermanagement.RoleManager;
|
||||
import org.gcube.vomanagement.usermanagement.impl.LiferayRoleManager;
|
||||
import org.gcube.vomanagement.usermanagement.model.GCubeTeam;
|
||||
import org.gcube.vomanagement.usermanagement.model.GCubeUser;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.google.gwt.user.server.rpc.RemoteServiceServlet;
|
||||
|
||||
import eu.trentorise.opendata.jackan.internal.org.apache.http.impl.client.CloseableHttpClient;
|
||||
import eu.trentorise.opendata.jackan.internal.org.apache.http.impl.client.HttpClientBuilder;
|
||||
import eu.trentorise.opendata.jackan.model.CkanDataset;
|
||||
import eu.trentorise.opendata.jackan.model.CkanPair;
|
||||
import eu.trentorise.opendata.jackan.model.CkanResource;
|
||||
|
@ -52,7 +60,7 @@ public class GRSFNotificationService extends RemoteServiceServlet implements GRS
|
|||
String currentScope = Utils.getCurrentContext(getThreadLocalRequest(), true);
|
||||
DataCatalogue instance = null;
|
||||
try{
|
||||
String scopeInWhichDiscover = discoverScope != null && !discoverScope.isEmpty() ? discoverScope : currentScope;
|
||||
String scopeInWhichDiscover = (discoverScope != null && !discoverScope.isEmpty()) ? discoverScope : currentScope;
|
||||
logger.debug("Discovering ckan utils library into scope " + scopeInWhichDiscover);
|
||||
instance = DataCatalogueFactory.getFactory().getUtilsPerScope(scopeInWhichDiscover);
|
||||
}catch(Exception e){
|
||||
|
@ -65,17 +73,29 @@ public class GRSFNotificationService extends RemoteServiceServlet implements GRS
|
|||
@Override
|
||||
public ManageProductBean getProductBeanById(String productIdentifier) throws Exception {
|
||||
|
||||
|
||||
ManageProductBean toReturn = null;
|
||||
|
||||
// check into session first
|
||||
HttpSession httpSession = getThreadLocalRequest().getSession();
|
||||
String sessionProductKey = ScopeProvider.instance.get() + productIdentifier;
|
||||
if(httpSession.getAttribute(sessionProductKey) != null)
|
||||
return (ManageProductBean) httpSession.getAttribute(sessionProductKey);
|
||||
|
||||
if(!Utils.isIntoPortal()){
|
||||
|
||||
toReturn = new ManageProductBean();
|
||||
toReturn.setCatalogueIdentifier(UUID.randomUUID().toString());
|
||||
List<ConnectedBean> connectTo = new ArrayList<>();
|
||||
connectTo.add(new ConnectedBean("91f1e413-dc9f-3b4e-b1c5-0e8560177253","Stock",
|
||||
"aksldsam asd", "asdasjnk:fas", UUID.randomUUID().toString(), "http://data.d4science.org/ctlg/GRSF_Admin/91f1e413-dc9f-3b4e-b1c5-0e8560177253"));
|
||||
toReturn.setConnectTo(connectTo);
|
||||
connectTo.add(new ConnectedBean(
|
||||
"91f1e413-dc9f-3b4e-b1c5-0e8560177253",
|
||||
"Stock",
|
||||
"http://data.d4science.org/ctlg/GRSF_Admin/91f1e413-dc9f-3b4e-b1c5-0e8560177253",
|
||||
"89f1e413-dc9f-3b4e-b1c5-0e8560177254",
|
||||
"Random title",
|
||||
"http://data.d4science.org/ctlg/GRSF_Admin/89f1e413-dc9f-3b4e-b1c5-0e8560177254",
|
||||
"Fishery"
|
||||
));
|
||||
toReturn.setCurrentConnections(connectTo);
|
||||
toReturn.setGrsfDomain("Stock");
|
||||
toReturn.setGrsfType("Assessment Unit");
|
||||
toReturn.setKnowledgeBaseIdentifier("91f1e413-dc9f-3b4e-b1c5-0e8560177253");
|
||||
|
@ -105,52 +125,63 @@ public class GRSFNotificationService extends RemoteServiceServlet implements GRS
|
|||
|
||||
}else{
|
||||
|
||||
// retrieve scope per current portlet url
|
||||
String scopePerCurrentUrl = Utils.getScopeFromClientUrl(getThreadLocalRequest());
|
||||
DataCatalogue catalogue = getCatalogue(scopePerCurrentUrl);
|
||||
String username = Utils.getCurrentUser(getThreadLocalRequest()).getUsername();
|
||||
CkanDataset record = catalogue.getDataset(productIdentifier, catalogue.getApiKeyFromUsername(username));
|
||||
String apiKey = catalogue.getApiKeyFromUsername(username);
|
||||
CkanDataset record = catalogue.getDataset(productIdentifier, apiKey);
|
||||
|
||||
// it cannot be enabled in this case ...
|
||||
if(record == null)
|
||||
throw new Exception("Unable to retrieve information for the selected record, sorry");
|
||||
else{
|
||||
|
||||
logger.debug("Trying to fetch record....");
|
||||
logger.debug("Trying to fetch the record....");
|
||||
|
||||
// check it is a grsf record (Source records have a different System Type)
|
||||
String systemType = record.getExtrasAsHashMap().get(Constants.SYSTEM_TYPE_CUSTOM_KEY);
|
||||
if(systemType == null || systemType.isEmpty() || systemType.equals(Constants.SYSTEM_TYPE_FOR_SOURCES_VALUE))
|
||||
throw new NoGRSFRecordException("This is not a GRSF Record");
|
||||
Map<String, String> extrasAsMap = record.getExtrasAsHashMap();
|
||||
|
||||
// get extras as hashmap and pairs
|
||||
List<CkanPair> extrasAsPairs = record.getExtras();
|
||||
|
||||
String systemType = extrasAsMap.get(Constants.SYSTEM_TYPE_CUSTOM_KEY);
|
||||
if(systemType == null || systemType.isEmpty() || systemType.equals(Constants.SYSTEM_TYPE_FOR_SOURCES_VALUE))
|
||||
throw new NoGRSFRecordException("This is not a GRSF Record");
|
||||
|
||||
boolean isStock = record.getExtrasAsHashMap().get(Constants.DOMAIN_CUSTOM_KEY).contains(Product_Type.STOCK.getOrigName());
|
||||
|
||||
// fetch map for namespaces
|
||||
Map<String, String> fieldsNamespacesMap = Utils.getFieldToFieldNameSpaceMapping(getThreadLocalRequest().getSession(),
|
||||
record.getExtrasAsHashMap().get(Constants.DOMAIN_CUSTOM_KEY).contains(Product_Type.STOCK.getOrigName()) ? Constants.GENERIC_RESOURCE_NAME_MAP_KEY_NAMESPACES_STOCK
|
||||
: Constants.GENERIC_RESOURCE_NAME_MAP_KEY_NAMESPACES_FISHERY);
|
||||
Map<String, String> fieldsNamespacesMap =
|
||||
Utils.getFieldToFieldNameSpaceMapping(httpSession, isStock ?
|
||||
Constants.GENERIC_RESOURCE_NAME_MAP_KEY_NAMESPACES_STOCK : Constants.GENERIC_RESOURCE_NAME_MAP_KEY_NAMESPACES_FISHERY);
|
||||
|
||||
Map<String, List<String>> extrasWithoutNamespaces = Utils.replaceFieldsKey(extrasAsPairs, fieldsNamespacesMap);
|
||||
// get extras fields (wrt the mandatory ones) to show in the management panel TODO
|
||||
// Utils.getExtrasToShow();
|
||||
String catalogueIdentifier = record.getId();
|
||||
String status = extrasWithoutNamespaces.get(Constants.STATUS_OF_THE_GRSF_RECORD_CUSTOM_KEY).get(0);
|
||||
Status status = Status.fromString(extrasWithoutNamespaces.get(Constants.STATUS_OF_THE_GRSF_RECORD_CUSTOM_KEY).get(0));
|
||||
String uuidKB = extrasWithoutNamespaces.get(Constants.UUID_KB_CUSTOM_KEY).get(0);
|
||||
String grsfDomain = extrasWithoutNamespaces.get(Constants.DOMAIN_CUSTOM_KEY).get(0);
|
||||
|
||||
logger.debug(Constants.DOMAIN_CUSTOM_KEY + " is " + grsfDomain);
|
||||
|
||||
if(status == null || uuidKB == null)
|
||||
throw new Exception("Some information is missing in this record: Status = " + status + ", knowledge base uuid = " + uuidKB +
|
||||
", and grsf domain is = " + grsfDomain);
|
||||
|
||||
if(status.equals(Status.To_be_Merged) || status.equals(Status.Rejected))
|
||||
throw new Exception("Records under merging activity or rejected cannot be updated");
|
||||
|
||||
String semanticId = extrasWithoutNamespaces.get(Constants.GRSF_SEMANTIC_IDENTIFIER_CUSTOM_KEY).get(0);
|
||||
String shortName = extrasWithoutNamespaces.get(Constants.SHORT_NAME_CUSTOM_KEY).get(0);
|
||||
String grsfType = extrasWithoutNamespaces.get(Constants.GRSF_TYPE_CUSTOM_KEY).get(0);
|
||||
String grsfName = extrasWithoutNamespaces.get(grsfDomain.contains(Product_Type.STOCK.getOrigName()) ?
|
||||
Constants.STOCK_NAME_CUSTOM_KEY : Constants.FISHERY_NAME_CUSTOM_KEY).get(0);
|
||||
boolean traceabilityFlag = extrasWithoutNamespaces.get(Constants.TRACEABILITY_FLAG_CUSTOM_KEY).get(0).equalsIgnoreCase("true");
|
||||
String recordUrl = extrasWithoutNamespaces.get(Constants.ITEM_URL_FIELD).get(0);
|
||||
String grsfName = extrasWithoutNamespaces.get(grsfDomain.contains(Product_Type.STOCK.getOrigName()) ? Constants.STOCK_NAME_CUSTOM_KEY : Constants.FISHERY_NAME_CUSTOM_KEY).get(0);
|
||||
boolean traceabilityFlag = false;
|
||||
try{
|
||||
traceabilityFlag = extrasWithoutNamespaces.get(Constants.TRACEABILITY_FLAG_CUSTOM_KEY).get(0).equalsIgnoreCase("true");
|
||||
}catch(Exception e){
|
||||
logger.warn("Unable to fetch traceability flag", e);
|
||||
}
|
||||
|
||||
// Get similar GRSF records, if any (each of which should have name, description, url and id(i.e semantic identifier))
|
||||
List<String> similarGrsfRecordsAsStrings = extrasWithoutNamespaces.containsKey(Constants.SIMILAR_GRSF_RECORDS_CUSTOM_KEY) ? extrasWithoutNamespaces.get(Constants.SIMILAR_GRSF_RECORDS_CUSTOM_KEY): null;
|
||||
|
@ -160,87 +191,87 @@ 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));
|
||||
}
|
||||
}
|
||||
|
||||
logger.debug("SimilarGRSFRecords are " + similarRecords);
|
||||
|
||||
// get connected records
|
||||
List<String> connectedBeansAsStrings = extrasWithoutNamespaces.containsKey(Constants.CONNECTED_CUSTOM_KEY) ? extrasWithoutNamespaces.get(Constants.CONNECTED_CUSTOM_KEY): null;
|
||||
// get connected records (and the proposed ones)
|
||||
List<String> connectedBeanUrls =
|
||||
extrasWithoutNamespaces.containsKey(Constants.CONNECTED_CUSTOM_KEY) ? extrasWithoutNamespaces.get(Constants.CONNECTED_CUSTOM_KEY): null;
|
||||
|
||||
List<ConnectedBean> connectedBeans = new ArrayList<ConnectedBean>(0);
|
||||
if(connectedBeansAsStrings != null){
|
||||
for (String connectedBean : connectedBeansAsStrings) {
|
||||
if(connectedBean.equals(Constants.NO_CONNECTED_RECORDS)) // stop here if there is a single element with this information
|
||||
break;
|
||||
connectedBeans.add(Utils.connectedBeanRecordFromJson(connectedBean, uuidKB, grsfDomain, catalogue));
|
||||
}
|
||||
}
|
||||
List<ConnectedBean> connectedBeans = new ArrayList<ConnectedBean>(0);
|
||||
if(connectedBeanUrls != null){
|
||||
for (String connectedBean : connectedBeanUrls) {
|
||||
if(connectedBean.equals(Constants.NO_CONNECTED_RECORDS)) // stop here if there is a single element with this information
|
||||
break;
|
||||
ConnectedBean builtBean = Utils.connectedBeanRecordFromUrl(recordUrl, connectedBean, uuidKB, grsfDomain, catalogue, apiKey);
|
||||
if(builtBean != null)
|
||||
connectedBeans.add(builtBean);
|
||||
}
|
||||
}
|
||||
|
||||
logger.debug("Connected records are " + connectedBeans);
|
||||
logger.debug("Already connected records are " + connectedBeans);
|
||||
|
||||
// Get sources
|
||||
List<CkanResource> resources = record.getResources();
|
||||
List<SourceRecord> sources = new ArrayList<SourceRecord>(3);
|
||||
for (CkanResource ckanResource : resources) {
|
||||
if(Sources.getListNames().contains(ckanResource.getName()))
|
||||
sources.add(new SourceRecord(ckanResource.getName(), ckanResource.getUrl()));
|
||||
}
|
||||
// get the connections the knowledge base suggests
|
||||
List<ConnectedBean> suggestedConnectionsByKnowledgeBase = new ArrayList<ConnectedBean>(0);
|
||||
List<String> exploitedResourcesUrls = isStock ?
|
||||
(extrasWithoutNamespaces.containsKey(Constants.EXPLOITING_FISHERY_JSON_KEY) ?
|
||||
extrasWithoutNamespaces.get(Constants.EXPLOITING_FISHERY_JSON_KEY) : null):
|
||||
(extrasWithoutNamespaces.containsKey(Constants.RESOURCES_EXPLOITED_JSON_KEY) ? extrasWithoutNamespaces.get(Constants.RESOURCES_EXPLOITED_JSON_KEY) : null);
|
||||
|
||||
// set the values
|
||||
toReturn = new ManageProductBean(semanticId, catalogueIdentifier, uuidKB, grsfType,
|
||||
grsfDomain, grsfName, shortName, traceabilityFlag, Status.fromString(status), null,
|
||||
null, null, sources, similarRecords, connectedBeans, false);
|
||||
if(exploitedResourcesUrls != null && !exploitedResourcesUrls.isEmpty()){
|
||||
for (String exploited : exploitedResourcesUrls) {
|
||||
ConnectedBean builtBean = Utils.connectedBeanRecordFromUrl(recordUrl, exploited, uuidKB, grsfDomain, catalogue, apiKey);
|
||||
if(builtBean != null)
|
||||
suggestedConnectionsByKnowledgeBase.add(builtBean);
|
||||
}
|
||||
}
|
||||
|
||||
logger.debug("Knowledge base suggests " + suggestedConnectionsByKnowledgeBase);
|
||||
|
||||
// Get sources
|
||||
List<CkanResource> resources = record.getResources();
|
||||
List<SourceRecord> sources = new ArrayList<SourceRecord>(3);
|
||||
for (CkanResource ckanResource : resources) {
|
||||
if(Sources.getListNames().contains(ckanResource.getName()))
|
||||
sources.add(new SourceRecord(ckanResource.getName(), ckanResource.getUrl()));
|
||||
}
|
||||
|
||||
// set the values
|
||||
toReturn = new ManageProductBean(semanticId, catalogueIdentifier, uuidKB, grsfType,
|
||||
grsfDomain, grsfName, shortName, traceabilityFlag, status, recordUrl,
|
||||
null, sources, similarRecords, connectedBeans, suggestedConnectionsByKnowledgeBase);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
logger.info("Returning item bean " + toReturn);
|
||||
httpSession.setAttribute(sessionProductKey, toReturn);
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAdminUser() {
|
||||
try{
|
||||
|
||||
Boolean inSession = (Boolean)getThreadLocalRequest().getSession().getAttribute(Constants.GRSF_ADMIN_SESSION_KEY);
|
||||
|
||||
if(inSession != null)
|
||||
return inSession;
|
||||
else{
|
||||
|
||||
if(!Utils.isIntoPortal()){
|
||||
getThreadLocalRequest().getSession().setAttribute(Constants.GRSF_ADMIN_SESSION_KEY, true);
|
||||
return true;
|
||||
}
|
||||
|
||||
PortalContext pContext = PortalContext.getConfiguration();
|
||||
RoleManager roleManager = new LiferayRoleManager();
|
||||
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 = roleManager.listTeamsByUserAndGroup(userId, groupId);
|
||||
boolean toSetInSession = false;
|
||||
for (GCubeTeam team : teamRoles) {
|
||||
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(!Utils.isIntoPortal()){
|
||||
toSetInSession = true;
|
||||
}else{
|
||||
PortalContext pContext = PortalContext.getConfiguration();
|
||||
RoleManager roleManager = new LiferayRoleManager();
|
||||
String username = pContext.getCurrentUser(getThreadLocalRequest()).getUsername();
|
||||
long userId = pContext.getCurrentUser(getThreadLocalRequest()).getUserId();
|
||||
long groupId = pContext.getCurrentGroupId(getThreadLocalRequest());
|
||||
List<GCubeTeam> teamRoles = roleManager.listTeamsByUserAndGroup(userId, groupId);
|
||||
toSetInSession = isEditor(username, teamRoles) | isReviewer(username, teamRoles);
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
@ -251,42 +282,132 @@ public class GRSFNotificationService extends RemoteServiceServlet implements GRS
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean checkSemanticIdentifierExists(String semanticIdentifier)
|
||||
throws Exception {
|
||||
public String notifyProductUpdate(ManageProductBean bean) throws Exception{
|
||||
|
||||
return getDataset(semanticIdentifier) != null;
|
||||
logger.info("Creating notification for the bean " + bean + " to send to the knowledge base");
|
||||
try{
|
||||
|
||||
String context = Utils.getScopeFromClientUrl(getThreadLocalRequest());
|
||||
String token = SecurityTokenProvider.instance.get();
|
||||
DataCatalogue catalogue = getCatalogue(context);
|
||||
String administratorFullName = Utils.getCurrentUser(getThreadLocalRequest()).getFullname();
|
||||
String username = Utils.getCurrentUser(getThreadLocalRequest()).getUsername();
|
||||
// check if the base url of the service is in session
|
||||
String keyPerContext = UtilMethods.concatenateSessionKeyScope(Constants.GRSF_UPDATER_SERVICE, context);
|
||||
HttpServletRequest threadRequest = getThreadLocalRequest();
|
||||
String baseUrl = (String)threadRequest.getSession().getAttribute(keyPerContext);
|
||||
if(baseUrl == null || baseUrl.isEmpty()){
|
||||
baseUrl = GRSFUpdaterServiceClient.discoverEndPoint(context);
|
||||
threadRequest.getSession().setAttribute(keyPerContext, baseUrl);
|
||||
}
|
||||
|
||||
// remove it from the session
|
||||
String sessionProductKey = ScopeProvider.instance.get() + bean.getCatalogueIdentifier();
|
||||
threadRequest.getSession().removeAttribute(sessionProductKey);
|
||||
|
||||
return Utils.updateRecord(baseUrl, bean, catalogue, username, administratorFullName, threadRequest,
|
||||
PortalContext.getConfiguration().getCurrentGroupId(threadRequest), context, token);
|
||||
|
||||
}catch(Exception e){
|
||||
logger.error("Unable to update the product", e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkSemanticIdentifierExistsInDomain(String semanticIdentifier, String domain)
|
||||
throws Exception {
|
||||
public void validateRevertOperation(String encryptedUrl) throws Exception {
|
||||
|
||||
PortalContext pContext = PortalContext.getConfiguration();
|
||||
String context = Utils.getScopeFromClientUrl(getThreadLocalRequest());
|
||||
RoleManager roleManager = new LiferayRoleManager();
|
||||
GCubeUser user = pContext.getCurrentUser(getThreadLocalRequest());
|
||||
String username = user.getUsername();
|
||||
String fullName = user.getFullname();
|
||||
long userId = pContext.getCurrentUser(getThreadLocalRequest()).getUserId();
|
||||
long groupId = pContext.getCurrentGroupId(getThreadLocalRequest());
|
||||
List<GCubeTeam> teamRoles = roleManager.listTeamsByUserAndGroup(userId, groupId);
|
||||
|
||||
CkanDataset dataset = getDataset(semanticIdentifier);
|
||||
boolean isEditor = isEditor(username, teamRoles);
|
||||
boolean isReviewer = isReviewer(username, teamRoles);
|
||||
|
||||
// look for the right domain this time
|
||||
List<CkanPair> extrasAsPairs = dataset.getExtras();
|
||||
if(!(isEditor | isReviewer))
|
||||
throw new Exception("You are not allowed to perform this operation!");
|
||||
|
||||
for (CkanPair ckanPair : extrasAsPairs) {
|
||||
if(ckanPair.getKey().contains(Constants.DOMAIN_CUSTOM_KEY)){
|
||||
return ckanPair.getValue().equalsIgnoreCase(domain);
|
||||
}
|
||||
// decrypt the url
|
||||
RevertOperationUrl decryptedUrl = new RevertOperationUrl(encryptedUrl);
|
||||
String adminInUrl = decryptedUrl.getAdmin();
|
||||
String uuid = decryptedUrl.getUuid();
|
||||
|
||||
logger.info("User " + username + " has requested to invert an operation on record with id " + uuid + " and admin in url was " + adminInUrl);
|
||||
|
||||
// we need to check the timestamp (it has 24h validity)
|
||||
boolean isValidTimestamp = decryptedUrl.isTimestampValid();
|
||||
|
||||
if(!isValidTimestamp)
|
||||
throw new Exception("This operation can no longer be reverted (link expired)!");
|
||||
|
||||
String keyPerContext = UtilMethods.concatenateSessionKeyScope(Constants.GRSF_UPDATER_SERVICE, context);
|
||||
String baseUrl = (String)getThreadLocalRequest().getSession().getAttribute(keyPerContext);
|
||||
if(baseUrl == null || baseUrl.isEmpty()){
|
||||
baseUrl = GRSFUpdaterServiceClient.discoverEndPoint(context);
|
||||
getThreadLocalRequest().getSession().setAttribute(keyPerContext, baseUrl);
|
||||
}
|
||||
|
||||
if(baseUrl == null || baseUrl.isEmpty())
|
||||
throw new Exception("Unable to discover grsf-updater service!");
|
||||
|
||||
// check if it is a reviewer, than he can do what he wants (no matter the admin)
|
||||
try(CloseableHttpClient httpClient = HttpClientBuilder.create().build();){
|
||||
if(isReviewer){
|
||||
GRSFUpdaterServiceClient.revertOperation(httpClient, baseUrl, fullName, uuid);
|
||||
}else{
|
||||
|
||||
if(!username.equals(adminInUrl))
|
||||
throw new Exception("You are not the editor allowed to perform this operation!");
|
||||
else
|
||||
GRSFUpdaterServiceClient.revertOperation(httpClient, baseUrl, fullName, uuid);
|
||||
}
|
||||
}catch(Exception e){
|
||||
logger.error("Unable to update this Item ", e);
|
||||
throw e;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the current user is an editor
|
||||
* @param username
|
||||
* @param teamRoles
|
||||
* @return true if he/she is an editor, false otherwise
|
||||
*/
|
||||
private boolean isEditor(String username, List<GCubeTeam> teamRoles){
|
||||
|
||||
for (GCubeTeam team : teamRoles) {
|
||||
if(team.getTeamName().equals(Constants.GRSF_CATALOGUE_EDITOR_ROLE)){
|
||||
logger.info("User " + username + " is allowed to modify GRSF records as editor");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private CkanDataset getDataset(String semanticIdentifier) throws Exception{
|
||||
|
||||
String scopePerCurrentUrl = Utils.getScopeFromClientUrl(getThreadLocalRequest());
|
||||
DataCatalogue catalogue = getCatalogue(scopePerCurrentUrl);
|
||||
String username = Utils.getCurrentUser(getThreadLocalRequest()).getUsername();
|
||||
CkanDataset dataset = Utils.getRecordBySemanticIdentifier(semanticIdentifier, catalogue, catalogue.getApiKeyFromUsername(username));
|
||||
return dataset;
|
||||
/**
|
||||
* Check if the current user is a reviewer
|
||||
* @param username
|
||||
* @param teamRoles
|
||||
* @return true if he/she is an reviewer, false otherwise
|
||||
*/
|
||||
private boolean isReviewer(String username, List<GCubeTeam> teamRoles){
|
||||
|
||||
for (GCubeTeam team : teamRoles) {
|
||||
if(team.getTeamName().equals(team.getTeamName().equals(Constants.GRSF_CATALOGUE_REVIEWER_ROLE))){
|
||||
logger.info("User " + username + " is allowed to modify GRSF records as reviewer");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String checkIdentifierExists(String id)
|
||||
throws Exception {
|
||||
|
@ -295,8 +416,7 @@ public class GRSFNotificationService extends RemoteServiceServlet implements GRS
|
|||
String username = Utils.getCurrentUser(getThreadLocalRequest()).getUsername();
|
||||
CkanDataset dataset = catalogue.getDataset(id, catalogue.getApiKeyFromUsername(username));
|
||||
if(dataset == null)
|
||||
throw new Exception("This record doesn't exist");
|
||||
|
||||
throw new Exception("A record with id " + id + " doesn't exist");
|
||||
return dataset.getExtrasAsHashMap().get(Constants.ITEM_URL_FIELD);
|
||||
}
|
||||
|
||||
|
@ -308,7 +428,7 @@ public class GRSFNotificationService extends RemoteServiceServlet implements GRS
|
|||
String username = Utils.getCurrentUser(getThreadLocalRequest()).getUsername();
|
||||
CkanDataset dataset = catalogue.getDataset(id, catalogue.getApiKeyFromUsername(username));
|
||||
if(dataset == null)
|
||||
throw new Exception("This record doesn't exist");
|
||||
throw new Exception("A record with id " + id + " doesn't exist");
|
||||
|
||||
List<CkanPair> extrasAsPairs = dataset.getExtras();
|
||||
|
||||
|
@ -319,33 +439,39 @@ public class GRSFNotificationService extends RemoteServiceServlet implements GRS
|
|||
}
|
||||
}
|
||||
|
||||
throw new Exception("This record doesn't exist in the specified domain");
|
||||
throw new Exception("A record with id " + id + " doesn't exist in domain " + domain);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String notifyProductUpdate(ManageProductBean bean) throws Exception{
|
||||
// @Override
|
||||
// public boolean checkSemanticIdentifierExists(String semanticIdentifier)
|
||||
// throws Exception {
|
||||
//
|
||||
// return getDataset(semanticIdentifier) != null;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public boolean checkSemanticIdentifierExistsInDomain(String semanticIdentifier, String domain)
|
||||
// throws Exception {
|
||||
// CkanDataset dataset = getDataset(semanticIdentifier);
|
||||
//
|
||||
// // look for the right domain this time
|
||||
// List<CkanPair> extrasAsPairs = dataset.getExtras();
|
||||
//
|
||||
// for (CkanPair ckanPair : extrasAsPairs) {
|
||||
// if(ckanPair.getKey().contains(Constants.DOMAIN_CUSTOM_KEY)){
|
||||
// return ckanPair.getValue().equalsIgnoreCase(domain);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// return false;
|
||||
// }
|
||||
|
||||
logger.info("Creating notification for the bean " + bean + " to send to the knowledge base");
|
||||
try{
|
||||
|
||||
String context = Utils.getScopeFromClientUrl(getThreadLocalRequest());
|
||||
DataCatalogue catalogue = getCatalogue(context);
|
||||
String administratorFullName = Utils.getCurrentUser(getThreadLocalRequest()).getFullname();
|
||||
String username = Utils.getCurrentUser(getThreadLocalRequest()).getUsername();
|
||||
// check if the base url of the service is in session
|
||||
String keyPerContext = UtilMethods.concatenateSessionKeyScope(Constants.GRSF_UPDATER_SERVICE, context);
|
||||
String baseUrl = (String)getThreadLocalRequest().getSession().getAttribute(keyPerContext);
|
||||
if(baseUrl == null || baseUrl.isEmpty()){
|
||||
baseUrl = Utils.discoverEndPoint(context);
|
||||
getThreadLocalRequest().getSession().setAttribute(keyPerContext, baseUrl);
|
||||
}
|
||||
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());
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
// private CkanDataset getDataset(String semanticIdentifier) throws Exception{
|
||||
// String scopePerCurrentUrl = Utils.getScopeFromClientUrl(getThreadLocalRequest());
|
||||
// DataCatalogue catalogue = getCatalogue(scopePerCurrentUrl);
|
||||
// String username = Utils.getCurrentUser(getThreadLocalRequest()).getUsername();
|
||||
// CkanDataset dataset = Utils.getRecordBySemanticIdentifier(semanticIdentifier, catalogue, catalogue.getApiKeyFromUsername(username));
|
||||
// return dataset;
|
||||
// }
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,214 @@
|
|||
package org.gcube.datacatalogue.grsf_manage_widget.server.manage;
|
||||
|
||||
import static org.gcube.resources.discovery.icclient.ICFactory.clientFor;
|
||||
import static org.gcube.resources.discovery.icclient.ICFactory.queryFor;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import org.gcube.common.resources.gcore.ServiceEndpoint;
|
||||
import org.gcube.common.resources.gcore.ServiceEndpoint.AccessPoint;
|
||||
import org.gcube.common.scope.api.ScopeProvider;
|
||||
import org.gcube.datacatalogue.ckanutillibrary.server.DataCatalogue;
|
||||
import org.gcube.datacatalogue.common.Constants;
|
||||
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.SimilarGRSFRecord;
|
||||
import org.gcube.resources.discovery.client.api.DiscoveryClient;
|
||||
import org.gcube.resources.discovery.client.queries.api.SimpleQuery;
|
||||
import org.json.simple.JSONArray;
|
||||
import org.json.simple.JSONObject;
|
||||
import org.json.simple.parser.JSONParser;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import eu.trentorise.opendata.jackan.internal.org.apache.http.HttpResponse;
|
||||
import eu.trentorise.opendata.jackan.internal.org.apache.http.client.methods.HttpPost;
|
||||
import eu.trentorise.opendata.jackan.internal.org.apache.http.entity.StringEntity;
|
||||
import eu.trentorise.opendata.jackan.internal.org.apache.http.impl.client.CloseableHttpClient;
|
||||
import eu.trentorise.opendata.jackan.internal.org.apache.http.util.EntityUtils;
|
||||
|
||||
/**
|
||||
* Exploits the grsf-services-updater service's methods https://app.swaggerhub.com/apis/ymark/grsf-services-updater/1.1.0
|
||||
* @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it)
|
||||
*/
|
||||
public class GRSFUpdaterServiceClient {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(GRSFUpdaterServiceClient.class);
|
||||
|
||||
/**
|
||||
* Discover the service endpoint of the GRSF Updater service and return its url
|
||||
* @param context
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static String discoverEndPoint(String context) throws Exception{
|
||||
|
||||
String oldContext = ScopeProvider.instance.get();
|
||||
ScopeProvider.instance.set(context);
|
||||
String toReturn = null;
|
||||
try{
|
||||
SimpleQuery query = queryFor(ServiceEndpoint.class);
|
||||
query.addCondition("$resource/Profile/Name/text() eq '"+ Constants.SERVICE_NAME +"'");
|
||||
query.addCondition("$resource/Profile/Category/text() eq '"+ Constants.SERVICE_CATEGORY +"'");
|
||||
DiscoveryClient<ServiceEndpoint> client = clientFor(ServiceEndpoint.class);
|
||||
List<ServiceEndpoint> resources = client.submit(query);
|
||||
|
||||
if (resources.size() == 0){
|
||||
logger.error("There is no Runtime Resource having name " + Constants.SERVICE_NAME +" and Category " + Constants.SERVICE_CATEGORY + " in this scope.");
|
||||
throw new Exception("There is no Runtime Resource having name " + Constants.SERVICE_NAME +" and Category " + Constants.SERVICE_CATEGORY + " in this scope.");
|
||||
}
|
||||
else {
|
||||
|
||||
for (ServiceEndpoint res : resources) {
|
||||
Iterator<AccessPoint> accessPointIterator = res.profile().accessPoints().iterator();
|
||||
|
||||
while (accessPointIterator.hasNext()) {
|
||||
ServiceEndpoint.AccessPoint accessPoint = (ServiceEndpoint.AccessPoint) accessPointIterator
|
||||
.next();
|
||||
|
||||
// return the path
|
||||
toReturn = accessPoint.address();
|
||||
}
|
||||
}
|
||||
}
|
||||
}catch(Exception e){
|
||||
logger.error("Unable to retrieve such service endpoint information!", e);
|
||||
throw e;
|
||||
}finally{
|
||||
if(oldContext != null && !oldContext.equals(context))
|
||||
ScopeProvider.instance.set(oldContext);
|
||||
}
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send updates to the knowledge base
|
||||
* @param httpClient
|
||||
* @param serviceUrl
|
||||
* @param bean
|
||||
* @param catalogue
|
||||
* @param username
|
||||
* @param fullName
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public 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.getConnections();
|
||||
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_UPDATER_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(parsedJSON == null)
|
||||
throw new Exception("There was a problem while performing this operation at knowledge base side");
|
||||
|
||||
if(response.getStatusLine().getStatusCode() == 200){
|
||||
logger.info("Record updated " + bean);
|
||||
}else if(!(boolean) parsedJSON.get(Constants.UPDATE_RESULT))
|
||||
throw new IllegalArgumentException(
|
||||
"Update failed for the following reason " + parsedJSON.get(Constants.ERROR_MESSAGE));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Send updates to the knowledge base
|
||||
* @param httpClient
|
||||
* @param serviceUrl
|
||||
* @param bean
|
||||
* @param catalogue
|
||||
* @param username
|
||||
* @param fullName
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static void revertOperation(CloseableHttpClient httpClient, String serviceUrl, String fullName, String uuid) throws Exception{
|
||||
|
||||
JSONObject obj = new JSONObject();
|
||||
obj.put(Constants.ADMINISTRATOR_FULLNAME, fullName);
|
||||
obj.put(Constants.KB_ID, uuid);
|
||||
|
||||
logger.info("Update request looks like " + obj.toJSONString());
|
||||
|
||||
HttpPost request = new HttpPost(serviceUrl + Constants.SERVICE_POST_REVERT_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(parsedJSON == null)
|
||||
throw new Exception("There was a problem while performing this operation at knowledge base side");
|
||||
|
||||
if(response.getStatusLine().getStatusCode() == 200){
|
||||
logger.info("Request has been submitted");
|
||||
}else if(!(boolean) parsedJSON.get(Constants.UPDATE_RESULT))
|
||||
throw new IllegalArgumentException(
|
||||
"Request failed for the following reason " + parsedJSON.get(Constants.ERROR_MESSAGE));
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package org.gcube.datacatalogue.grsf_manage_widget.shared;
|
||||
package org.gcube.datacatalogue.grsf_manage_widget.server.manage;
|
||||
|
||||
import java.net.URLDecoder;
|
||||
import java.net.URLEncoder;
|
||||
|
@ -22,11 +22,16 @@ public class RevertOperationUrl {
|
|||
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 static final long TTL = 1000 * 60 * 60 * 24;
|
||||
|
||||
/**
|
||||
* For now only Merge can be reverted
|
||||
* @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it)
|
||||
*/
|
||||
public enum Operation {
|
||||
|
||||
MERGE("merge"),
|
||||
DISSECT("dissect");
|
||||
MERGE("merge");
|
||||
// DISSECT("dissect");
|
||||
private String name;
|
||||
|
||||
private Operation(String name) {
|
||||
|
@ -45,7 +50,6 @@ public class RevertOperationUrl {
|
|||
private long timestamp;
|
||||
private String uuid;
|
||||
private Operation operation;
|
||||
private Operation op;
|
||||
|
||||
/**
|
||||
* @param admin
|
||||
|
@ -55,17 +59,20 @@ public class RevertOperationUrl {
|
|||
* @param op
|
||||
*/
|
||||
public RevertOperationUrl(String baseUrl, String admin, long timestamp, String uuid,
|
||||
Operation operation, Operation op) {
|
||||
Operation operation) {
|
||||
super();
|
||||
this.baseUrl = baseUrl;
|
||||
this.admin = admin;
|
||||
this.timestamp = timestamp;
|
||||
this.uuid = uuid;
|
||||
this.operation = operation;
|
||||
this.op = op;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Build a crypted, encoded and shortened url
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public String getShortUrl() throws Exception{
|
||||
|
||||
String query = ADMIN_QUERY_PARAM + "=" + admin + "&" + TIMESTAMP_QUERY_PARAM + "=" + timestamp +"&" + UUID_QUERY_PARAM + "=" + uuid + "&" + OPERATION_REVERT_QUERY_PARAM + "=" + operation;
|
||||
|
@ -131,13 +138,16 @@ public class RevertOperationUrl {
|
|||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}catch(Exception e){
|
||||
logger.error("Failed to parse url", e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public boolean isTimestampValid() {
|
||||
return TTL + this.timestamp < System.currentTimeMillis();
|
||||
}
|
||||
|
||||
public String getBaseUrl() {
|
||||
return baseUrl;
|
||||
|
@ -188,58 +198,11 @@ public class RevertOperationUrl {
|
|||
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 + "]";
|
||||
+ ", operation=" + operation + "]";
|
||||
}
|
||||
|
||||
// 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);
|
||||
//}
|
||||
|
||||
}
|
|
@ -0,0 +1,400 @@
|
|||
package org.gcube.datacatalogue.grsf_manage_widget.server.manage;
|
||||
|
||||
import static org.gcube.resources.discovery.icclient.ICFactory.client;
|
||||
import static org.gcube.resources.discovery.icclient.ICFactory.queryFor;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.gcube.common.authorization.library.provider.SecurityTokenProvider;
|
||||
import org.gcube.common.resources.gcore.GCoreEndpoint;
|
||||
import org.gcube.common.scope.api.ScopeProvider;
|
||||
import org.gcube.datacatalogue.ckanutillibrary.server.DataCatalogue;
|
||||
import org.gcube.datacatalogue.common.Constants;
|
||||
import org.gcube.datacatalogue.grsf_manage_widget.server.manage.RevertOperationUrl.Operation;
|
||||
import org.gcube.datacatalogue.grsf_manage_widget.shared.ManageProductBean;
|
||||
import org.gcube.resources.discovery.client.api.DiscoveryClient;
|
||||
import org.gcube.resources.discovery.client.queries.api.SimpleQuery;
|
||||
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.json.simple.JSONArray;
|
||||
import org.json.simple.JSONObject;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
|
||||
import eu.trentorise.opendata.jackan.internal.org.apache.http.HttpEntity;
|
||||
import eu.trentorise.opendata.jackan.internal.org.apache.http.HttpResponse;
|
||||
import eu.trentorise.opendata.jackan.internal.org.apache.http.client.methods.HttpPost;
|
||||
import eu.trentorise.opendata.jackan.internal.org.apache.http.entity.StringEntity;
|
||||
import eu.trentorise.opendata.jackan.internal.org.apache.http.impl.client.CloseableHttpClient;
|
||||
import eu.trentorise.opendata.jackan.internal.org.apache.http.impl.client.HttpClientBuilder;
|
||||
import eu.trentorise.opendata.jackan.internal.org.apache.http.impl.client.LaxRedirectStrategy;
|
||||
import eu.trentorise.opendata.jackan.internal.org.apache.http.util.EntityUtils;
|
||||
|
||||
|
||||
/**
|
||||
* For managing the different interactions with social channels (posts and mails)
|
||||
* @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it)
|
||||
*/
|
||||
public class SocialCommunications {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(SocialCommunications.class);
|
||||
|
||||
// for discovering social networking service
|
||||
private static final String resource = "jersey-servlet";
|
||||
private static final String serviceName = "SocialNetworking";
|
||||
private static final String serviceClass = "Portal";
|
||||
|
||||
// social operations
|
||||
private static final String SOCIAL_SERVICE_APPLICATION_TOKEN = "/2/tokens/generate-application-token/";
|
||||
private static final String SOCIAL_SERVICE_WRITE_APPLICATION_POST = "/2/posts/write-post-app/";
|
||||
private static final String SOCIAL_SEND_EMAIL = "/2/messages/write-message/";
|
||||
private static final String MEDIATYPE_JSON = "application/json";
|
||||
|
||||
// for writing a post in the GRSF admin context
|
||||
private static final String APPLICATION_ID_CATALOGUE_MANAGER = "org.gcube.datacatalogue.GRSFNotifier";
|
||||
|
||||
// emails to be sent to editors and reviewers and post to be written into the grsf admin vre
|
||||
private static final String POST_MESSAGE = "Dear members,"
|
||||
+ "<br>The record 'PRODUCT_TITLE' has been just updated by USER_FULLNAME."
|
||||
+ "<br>You can inspect it here: PRODUCT_URL<br>";
|
||||
|
||||
private static final String EMAIL_MESSAGE_REVIEWER = "Dear GRSF Reviewer,"
|
||||
+ "<br>an update on the record named 'PRODUCT_TITLE' has been requested by USER_FULLNAME."
|
||||
+ "<br>It is available here LINK_RECORD.";
|
||||
|
||||
private static final String EMAIL_MESSAGE_EDITOR = "Dear USER_FULLNAME,"
|
||||
+ "<br>your request for the record 'PRODUCT_TITLE' has been accepted."
|
||||
+ "<br>It is available here LINK_RECORD.";
|
||||
|
||||
private static final String REVERT_LINK_PIECE = "<br>The request involves a merge operation. You can reject the merge by exploiting this link LINK in the following 24 hours.";
|
||||
|
||||
/**
|
||||
*
|
||||
* @param context
|
||||
* @return
|
||||
*/
|
||||
private static String getBaseUrlSocialService(String context){
|
||||
|
||||
if(context == null || context.isEmpty())
|
||||
throw new IllegalArgumentException("A valid context is needed to discover the service");
|
||||
|
||||
String oldContext = ScopeProvider.instance.get();
|
||||
ScopeProvider.instance.set(context);
|
||||
|
||||
String basePath = null;
|
||||
try{
|
||||
|
||||
SimpleQuery query = queryFor(GCoreEndpoint.class);
|
||||
query.addCondition(String.format("$resource/Profile/ServiceClass/text() eq '%s'",serviceClass));
|
||||
query.addCondition("$resource/Profile/DeploymentData/Status/text() eq 'ready'");
|
||||
query.addCondition(String.format("$resource/Profile/ServiceName/text() eq '%s'",serviceName));
|
||||
query.setResult("$resource/Profile/AccessPoint/RunningInstanceInterfaces//Endpoint[@EntryName/string() eq \""+resource+"\"]/text()");
|
||||
|
||||
DiscoveryClient<String> client = client();
|
||||
List<String> endpoints = client.submit(query);
|
||||
if (endpoints == null || endpoints.isEmpty())
|
||||
throw new Exception("Cannot retrieve the GCoreEndpoint serviceName: "+serviceName +", serviceClass: " +serviceClass +", in scope: "+context);
|
||||
|
||||
|
||||
basePath = endpoints.get(0);
|
||||
if(basePath==null)
|
||||
throw new Exception("Endpoint:"+resource+", is null for serviceName: "+serviceName +", serviceClass: " +serviceClass +", in scope: "+context);
|
||||
|
||||
}catch(Exception e){
|
||||
logger.error("Unable to retrieve such service endpoint information!", e);
|
||||
}finally{
|
||||
if(oldContext != null && !oldContext.equals(context))
|
||||
ScopeProvider.instance.set(oldContext);
|
||||
}
|
||||
logger.info("Found base path " + basePath + " for the service");
|
||||
return basePath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Notify the users about the required changes.
|
||||
* @param bean
|
||||
* @param url
|
||||
* @param username
|
||||
* @param fullName
|
||||
* @param hashtags
|
||||
* @param enablePostNotification
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static void writeProductPost(ManageProductBean bean, String username, String fullName, List<String> hashtags, boolean enablePostNotification){
|
||||
|
||||
// discover service endpoint for the social networking library
|
||||
String currentScope = ScopeProvider.instance.get();
|
||||
String tokenUser = SecurityTokenProvider.instance.get();
|
||||
|
||||
logger.info("Current scope for writeProductPost is " + currentScope + " and token is " + tokenUser.substring(0, 10) + "***************");
|
||||
String basePath = getBaseUrlSocialService(currentScope);
|
||||
|
||||
if(basePath == null){
|
||||
|
||||
logger.error("Unable to write a post because there is no social networking service available");
|
||||
|
||||
}else{
|
||||
|
||||
basePath = basePath.endsWith("/") ? basePath : basePath + "/";
|
||||
|
||||
try(CloseableHttpClient client = HttpClientBuilder.create().setRedirectStrategy(new LaxRedirectStrategy()).build();){
|
||||
|
||||
// ask token application
|
||||
HttpPost postRequest = new HttpPost(basePath + SOCIAL_SERVICE_APPLICATION_TOKEN + "?gcube-token=" + tokenUser);
|
||||
StringEntity input = new StringEntity("{\"app_id\":\"" + APPLICATION_ID_CATALOGUE_MANAGER + "\"}");
|
||||
input.setContentType(MEDIATYPE_JSON);
|
||||
postRequest.setEntity(input);
|
||||
HttpResponse response = client.execute(postRequest);
|
||||
|
||||
logger.debug("Url is " + basePath + SOCIAL_SERVICE_APPLICATION_TOKEN + "?gcube-token=" + tokenUser);
|
||||
|
||||
if (response.getStatusLine().getStatusCode() != 201) {
|
||||
throw new RuntimeException("Failed to retrieve application token : HTTP error code : "
|
||||
+ response.getStatusLine().getStatusCode());
|
||||
}else{
|
||||
|
||||
Map<String, Object> mapResponseGeneratedToken = getResponseEntityAsJSON(response);
|
||||
boolean successGeneratedToken = (boolean)mapResponseGeneratedToken.get("success");
|
||||
if(!successGeneratedToken){
|
||||
|
||||
throw new RuntimeException("Failed to generate the token for the application!"
|
||||
+ " Error message is " + mapResponseGeneratedToken.get("message"));
|
||||
|
||||
}else{
|
||||
|
||||
String applicationToken = (String)mapResponseGeneratedToken.get("result");
|
||||
|
||||
// replace
|
||||
String message = POST_MESSAGE.replace("PRODUCT_TITLE", bean.getGrsfName()).replace("PRODUCT_URL", bean.getRecordUrl()).replace("USER_FULLNAME", fullName);
|
||||
|
||||
if(hashtags != null && !hashtags.isEmpty())
|
||||
for (String hashtag : hashtags) {
|
||||
String modifiedHashtag = hashtag.replaceAll(" ", "_").replace("_+", "_"); // no empty spaces allowed
|
||||
if(modifiedHashtag.endsWith("_"))
|
||||
modifiedHashtag = modifiedHashtag.substring(0, modifiedHashtag.length() - 1);
|
||||
message += " #" + modifiedHashtag;
|
||||
}
|
||||
|
||||
logger.info("The post that is going to be written is -> " + message);
|
||||
postRequest = new HttpPost(basePath + SOCIAL_SERVICE_WRITE_APPLICATION_POST + "?gcube-token=" + applicationToken);
|
||||
JSONObject object = new JSONObject();
|
||||
object.put("text", message);
|
||||
object.put("enable_notification", enablePostNotification);
|
||||
input = new StringEntity(object.toJSONString());
|
||||
input.setContentType(MEDIATYPE_JSON);
|
||||
postRequest.setEntity(input);
|
||||
response = client.execute(postRequest);
|
||||
|
||||
Map<String, Object> mapResponseWritePost = getResponseEntityAsJSON(response);
|
||||
|
||||
if (response.getStatusLine().getStatusCode() != 201)
|
||||
throw new RuntimeException("Failed to write application post : HTTP error code : "
|
||||
+ response.getStatusLine().getStatusCode() + mapResponseWritePost.get("message"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}catch(Exception e){
|
||||
logger.error("Failed to create a post", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Send an email to the administrator as well as the
|
||||
* @param bean
|
||||
* @param catalogue
|
||||
* @param username
|
||||
* @param fullName
|
||||
* @param isMergeInvolved
|
||||
* @param httpSession
|
||||
* @throws Exceptio
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static void sendEmailAdministrators(
|
||||
ManageProductBean bean,
|
||||
DataCatalogue catalogue,
|
||||
String username,
|
||||
String fullName,
|
||||
long groupId,
|
||||
HttpServletRequest httpServletRequest,
|
||||
boolean isMergeInvolved) throws Exception {
|
||||
|
||||
// get the list of GRSF Reviewers to alert them as well
|
||||
RoleManager roleManager = new LiferayRoleManager();
|
||||
List<GCubeTeam> teamRoles = roleManager.listTeamsByGroup(groupId);
|
||||
List<String> 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()).getUsername());
|
||||
}
|
||||
|
||||
// if the user is a reviewer, then send the email just once
|
||||
reviewers.remove(username);
|
||||
|
||||
logger.info("List of " + Constants.GRSF_CATALOGUE_REVIEWER_ROLE + " is " + reviewers);
|
||||
|
||||
// build the url that allows to revert the operation
|
||||
Operation operation = Operation.MERGE;
|
||||
|
||||
// discover service endpoint for the social networking library
|
||||
String currentScope = ScopeProvider.instance.get();
|
||||
String tokenUser = SecurityTokenProvider.instance.get();
|
||||
|
||||
logger.info("Current scope for writeProductPost is " + currentScope + " and token is " + tokenUser.substring(0, 10) + "***************");
|
||||
String basePath = getBaseUrlSocialService(currentScope);
|
||||
|
||||
if(basePath == null){
|
||||
|
||||
logger.error("Unable to write a post because there is no social networking service available");
|
||||
|
||||
}else{
|
||||
|
||||
basePath = basePath.endsWith("/") ? basePath : basePath + "/";
|
||||
|
||||
try(CloseableHttpClient client = HttpClientBuilder.create().setRedirectStrategy(new LaxRedirectStrategy()).build();){
|
||||
|
||||
// ask token application
|
||||
HttpPost postRequest = new HttpPost(basePath + SOCIAL_SERVICE_APPLICATION_TOKEN + "?gcube-token=" + tokenUser);
|
||||
StringEntity input = new StringEntity("{\"app_id\":\"" + APPLICATION_ID_CATALOGUE_MANAGER + "\"}");
|
||||
input.setContentType(MEDIATYPE_JSON);
|
||||
postRequest.setEntity(input);
|
||||
HttpResponse response = client.execute(postRequest);
|
||||
|
||||
logger.debug("Url is " + basePath + SOCIAL_SERVICE_APPLICATION_TOKEN + "?gcube-token=" + tokenUser);
|
||||
|
||||
if (response.getStatusLine().getStatusCode() != 201) {
|
||||
throw new RuntimeException("Failed to retrieve application token : HTTP error code : "
|
||||
+ response.getStatusLine().getStatusCode());
|
||||
}else{
|
||||
|
||||
Map<String, Object> mapResponseGeneratedToken = getResponseEntityAsJSON(response);
|
||||
boolean successGeneratedToken = (boolean)mapResponseGeneratedToken.get("success");
|
||||
if(!successGeneratedToken){
|
||||
|
||||
throw new RuntimeException("Failed to generate the token for the application!"
|
||||
+ " Error message is " + mapResponseGeneratedToken.get("message"));
|
||||
|
||||
}else{
|
||||
|
||||
String applicationToken = (String)mapResponseGeneratedToken.get("result");
|
||||
|
||||
String revertUrl = getEncodedUrlManage(operation, username, System.currentTimeMillis(), bean.getKnowledgeBaseIdentifier(), httpServletRequest);
|
||||
|
||||
String messageToEditor = (EMAIL_MESSAGE_EDITOR +
|
||||
(isMergeInvolved? REVERT_LINK_PIECE : "")).replace("USER_FULLNAME", fullName).replace("PRODUCT_TITLE", bean.getGrsfName()).replace("LINK_RECORD", bean.getRecordUrl()).replace("LINK", revertUrl);
|
||||
String messageToReviewer = (EMAIL_MESSAGE_REVIEWER+
|
||||
(isMergeInvolved? REVERT_LINK_PIECE : "")).replace("USER_FULLNAME", fullName).replace("PRODUCT_TITLE", bean.getGrsfName()).replace("LINK_RECORD", bean.getRecordUrl()).replace("LINK", revertUrl);
|
||||
String subject = "Update request on GRSF Record";
|
||||
|
||||
// send email to the editor
|
||||
logger.info("The message that is going to be send to the editor is\n" + messageToEditor);
|
||||
postRequest = new HttpPost(basePath + SOCIAL_SEND_EMAIL + "?gcube-token=" + applicationToken);
|
||||
JSONObject reqMessage = new JSONObject();
|
||||
reqMessage.put("subject", subject);
|
||||
reqMessage.put("body", messageToEditor);
|
||||
JSONArray recipients = new JSONArray();
|
||||
JSONObject recipient = new JSONObject();
|
||||
recipient.put("id", username);
|
||||
recipients.add(recipient);
|
||||
reqMessage.put("recipients", recipients);
|
||||
input = new StringEntity(reqMessage.toJSONString());
|
||||
input.setContentType(MEDIATYPE_JSON);
|
||||
postRequest.setEntity(input);
|
||||
response = client.execute(postRequest);
|
||||
|
||||
Map<String, Object> mapResponseWritePost = getResponseEntityAsJSON(response);
|
||||
|
||||
if (response.getStatusLine().getStatusCode() != 201){
|
||||
logger.error("Failed to send message to editor : HTTP error code : "
|
||||
+ response.getStatusLine().getStatusCode() + mapResponseWritePost.get("message"));
|
||||
}
|
||||
|
||||
// send email to the reviewers
|
||||
logger.info("The message that is going to be send to the reviewers is\n" + messageToReviewer);
|
||||
postRequest = new HttpPost(basePath + SOCIAL_SEND_EMAIL + "?gcube-token=" + applicationToken);
|
||||
reqMessage = new JSONObject();
|
||||
reqMessage.put("subject", subject);
|
||||
reqMessage.put("body", messageToReviewer);
|
||||
recipients = new JSONArray();
|
||||
for(String reviewer: reviewers){
|
||||
JSONObject recip = new JSONObject();
|
||||
recip.put("id", reviewer);
|
||||
recipients.add(recip);
|
||||
}
|
||||
reqMessage.put("recipients", recipients);
|
||||
input = new StringEntity(reqMessage.toJSONString());
|
||||
input.setContentType(MEDIATYPE_JSON);
|
||||
postRequest.setEntity(input);
|
||||
response = client.execute(postRequest);
|
||||
mapResponseWritePost = getResponseEntityAsJSON(response);
|
||||
|
||||
if (response.getStatusLine().getStatusCode() != 201){
|
||||
logger.error("Failed to send message to editor : HTTP error code : "
|
||||
+ response.getStatusLine().getStatusCode() + mapResponseWritePost.get("message"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}catch(Exception e){
|
||||
logger.error("Failed to create a post", e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 = Utils.getCurrentClientUrl(httpServletRequest).split("\\?")[0]; // ignore other parameters
|
||||
RevertOperationUrl operationUrl = new RevertOperationUrl(clientUrl, administrator, timestamp, uuid, operation);
|
||||
String shortUrl = operationUrl.getShortUrl();
|
||||
return shortUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the json response to a map
|
||||
* @param response
|
||||
* @return
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
private static Map<String, Object> getResponseEntityAsJSON(HttpResponse response){
|
||||
|
||||
Map<String, Object> toReturn = null;
|
||||
HttpEntity entity = response.getEntity();
|
||||
|
||||
if (entity != null) {
|
||||
try {
|
||||
toReturn = new HashMap<String, Object>();
|
||||
String jsonString = EntityUtils.toString(response.getEntity());
|
||||
logger.debug("Response as string is " + jsonString);
|
||||
ObjectMapper objectMapper = new ObjectMapper();
|
||||
toReturn = objectMapper.readValue(jsonString, HashMap.class);
|
||||
logger.debug("Map is " + toReturn);
|
||||
}catch(Exception e){
|
||||
logger.error("Failed to read json object", e);
|
||||
}
|
||||
}
|
||||
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
}
|
|
@ -22,6 +22,7 @@ import javax.servlet.http.HttpSession;
|
|||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
|
||||
import org.gcube.common.authorization.library.provider.SecurityTokenProvider;
|
||||
import org.gcube.common.encryption.StringEncrypter;
|
||||
import org.gcube.common.portal.PortalContext;
|
||||
import org.gcube.common.resources.gcore.ServiceEndpoint;
|
||||
|
@ -34,10 +35,9 @@ import org.gcube.datacatalogue.ckanutillibrary.server.DataCatalogueRunningCluste
|
|||
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.server.manage.RevertOperationUrl.Operation;
|
||||
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;
|
||||
|
@ -177,7 +177,9 @@ public class Utils {
|
|||
}
|
||||
}
|
||||
logger.debug("Map is " + namespacesMap);
|
||||
httpSession.setAttribute(sessionKey, namespacesMap);
|
||||
|
||||
// put them into session for speeding up the operations
|
||||
httpSession.setAttribute(sessionKey, namespacesMap);
|
||||
return namespacesMap;
|
||||
} catch (Exception e) {
|
||||
logger.error("Error while trying to fetch applicationProfile profile from the infrastructure", e);
|
||||
|
@ -221,7 +223,7 @@ public class Utils {
|
|||
* @param extrasAsPairs
|
||||
* @return
|
||||
*/
|
||||
public static Map<String, List<String>> getExtras(List<CkanPair> extrasAsPairs){
|
||||
public static Map<String, List<String>> getExtrasAsHashMap(List<CkanPair> extrasAsPairs){
|
||||
|
||||
Map<String, List<String>> toReturn = new HashMap<String, List<String>>();
|
||||
|
||||
|
@ -242,52 +244,6 @@ public class Utils {
|
|||
return toReturn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Discover the service endpoint and return its url
|
||||
* @param context
|
||||
* @return the url of the service on success, null otherwise
|
||||
*/
|
||||
public static String discoverEndPoint(String context){
|
||||
|
||||
String oldContext = ScopeProvider.instance.get();
|
||||
ScopeProvider.instance.set(context);
|
||||
String toReturn = null;
|
||||
try{
|
||||
SimpleQuery query = queryFor(ServiceEndpoint.class);
|
||||
query.addCondition("$resource/Profile/Name/text() eq '"+ Constants.SERVICE_NAME +"'");
|
||||
query.addCondition("$resource/Profile/Category/text() eq '"+ Constants.SERVICE_CATEGORY +"'");
|
||||
DiscoveryClient<ServiceEndpoint> client = clientFor(ServiceEndpoint.class);
|
||||
List<ServiceEndpoint> resources = client.submit(query);
|
||||
|
||||
if (resources.size() == 0){
|
||||
logger.error("There is no Runtime Resource having name " + Constants.SERVICE_NAME +" and Category " + Constants.SERVICE_CATEGORY + " in this scope.");
|
||||
throw new Exception("There is no Runtime Resource having name " + Constants.SERVICE_NAME +" and Category " + Constants.SERVICE_CATEGORY + " in this scope.");
|
||||
}
|
||||
else {
|
||||
|
||||
for (ServiceEndpoint res : resources) {
|
||||
|
||||
Iterator<AccessPoint> accessPointIterator = res.profile().accessPoints().iterator();
|
||||
|
||||
while (accessPointIterator.hasNext()) {
|
||||
ServiceEndpoint.AccessPoint accessPoint = (ServiceEndpoint.AccessPoint) accessPointIterator
|
||||
.next();
|
||||
|
||||
// return the path
|
||||
toReturn = accessPoint.address();
|
||||
}
|
||||
}
|
||||
}
|
||||
}catch(Exception e){
|
||||
logger.error("Unable to retrieve such service endpoint information!", e);
|
||||
}finally{
|
||||
if(oldContext != null && !oldContext.equals(context))
|
||||
ScopeProvider.instance.set(oldContext);
|
||||
}
|
||||
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send an update for this bean
|
||||
* @param baseUrl
|
||||
|
@ -297,7 +253,7 @@ public class Utils {
|
|||
* @return true on success, false otherwise
|
||||
*/
|
||||
public static String updateRecord(String serviceUrl, ManageProductBean bean, DataCatalogue catalogue, String username,
|
||||
String fullName, HttpServletRequest httpServletRequest, long groupId) throws Exception{
|
||||
String fullName, HttpServletRequest httpServletRequest, long groupId, String context, String token) throws Exception{
|
||||
|
||||
if(serviceUrl == null)
|
||||
throw new IllegalArgumentException("GRSF Updater service url cannot be null");
|
||||
|
@ -312,14 +268,21 @@ public class Utils {
|
|||
updateStatusInvolvedRecords(bean, catalogue);
|
||||
|
||||
// send update to the knowledge base
|
||||
updateKB(httpClient, serviceUrl, bean, catalogue, username, fullName);
|
||||
GRSFUpdaterServiceClient.updateKB(httpClient, serviceUrl, bean, catalogue, username, fullName);
|
||||
|
||||
// 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);
|
||||
// manage interactions through a separated thread but set there security token and context
|
||||
new Thread(()->{
|
||||
|
||||
ScopeProvider.instance.set(context);
|
||||
SecurityTokenProvider.instance.set(token);
|
||||
|
||||
// send email to Editors and Reviewers
|
||||
SocialCommunications.sendEmailAdministrators(bean, catalogue, username, fullName, groupId, httpServletRequest, bean.isMergesInvolved());
|
||||
|
||||
// create a post about the operation
|
||||
createSocialPost(bean, catalogue, username, fullName);
|
||||
// create a post about the operation
|
||||
SocialCommunications.createSocialPost(bean, catalogue, username, fullName, hashtags);
|
||||
|
||||
}).start();
|
||||
|
||||
}catch(Exception e){
|
||||
logger.error("Unable to update this Item ", e);
|
||||
|
@ -343,7 +306,7 @@ public class Utils {
|
|||
for(SimilarGRSFRecord s: bean.getSimilarGrsfRecords()){
|
||||
if(s.isSuggestedMerge()){
|
||||
String productId = s.getKnowledgeBaseId();
|
||||
Map<String, List<String>> extrasMap = getExtras(catalogue.getDataset(productId, sysApi).getExtras());
|
||||
Map<String, List<String>> extrasMap = getExtrasAsHashMap(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);
|
||||
}
|
||||
|
@ -351,174 +314,12 @@ public class Utils {
|
|||
|
||||
// update the current status record
|
||||
String productId = bean.getKnowledgeBaseIdentifier();
|
||||
Map<String, List<String>> extrasMap = getExtras(catalogue.getDataset(productId, sysApi).getExtras());
|
||||
Map<String, List<String>> extrasMap = getExtrasAsHashMap(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
|
||||
|
@ -649,8 +450,9 @@ public class Utils {
|
|||
* @param url
|
||||
* @param clg
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static CkanDataset getDatasetFromUrl(String url, DataCatalogue clg, String apiKey){
|
||||
public static CkanDataset getDatasetFromUrl(String url, DataCatalogue clg, String apiKey) throws Exception{
|
||||
|
||||
if(url == null || url.isEmpty())
|
||||
return null;
|
||||
|
@ -667,7 +469,7 @@ public class Utils {
|
|||
return clg.getDataset(uuidFound, apiKey);
|
||||
}
|
||||
|
||||
return null;
|
||||
throw new Exception("No record exists with such url " + url);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -768,27 +570,31 @@ public class Utils {
|
|||
* @param json
|
||||
* @param sourceIdentifier
|
||||
* @param sourceDomain
|
||||
* @param grsfDomain
|
||||
* @return
|
||||
* @throws ParseException
|
||||
*/
|
||||
public static ConnectedBean connectedBeanRecordFromJson(String json, String sourceIdentifier, String sourceDomain,
|
||||
DataCatalogue clg) throws ParseException {
|
||||
public static ConnectedBean connectedBeanRecordFromUrl(
|
||||
String sourceIdentifier,
|
||||
String sourceDomain,
|
||||
String sourceUrl,
|
||||
String destUrl,
|
||||
DataCatalogue clg,
|
||||
String apiKey) throws ParseException {
|
||||
|
||||
if(json == null)
|
||||
if(destUrl == null)
|
||||
return null;
|
||||
|
||||
JSONParser parser = new JSONParser();
|
||||
JSONObject object = (JSONObject)parser.parse(json);
|
||||
|
||||
String uuidDest = (String)object.get(Constants.CONNECTED_RECORD_KNOWLEDGE_BASE_ID_JSON_KEY);
|
||||
String url = clg.getUrlFromDatasetIdOrName(uuidDest);
|
||||
String connectedBeanUuid = Utils.getDatasetKnowledgeBaseIdFromUrl(destUrl);
|
||||
CkanDataset destDataset = clg.getDataset(connectedBeanUuid, apiKey);
|
||||
return new ConnectedBean(
|
||||
sourceIdentifier,
|
||||
sourceDomain,
|
||||
(String)object.get(Constants.CONNECTED_RECORD_SHORT_NAME_JSON_KEY),
|
||||
(String)object.get(Constants.CONNECTED_RECORD_SEMANTIC_IDENTIFIER_JSON_KEY),
|
||||
uuidDest,
|
||||
url
|
||||
sourceUrl,
|
||||
connectedBeanUuid,
|
||||
destDataset.getTitle(),
|
||||
destUrl,
|
||||
destDataset.getExtrasAsHashMap().get(Constants.DOMAIN_CUSTOM_KEY)
|
||||
);
|
||||
|
||||
}
|
||||
|
@ -799,10 +605,8 @@ public class Utils {
|
|||
* @throws Exception
|
||||
*/
|
||||
public static String fetchSysAPI(String context) throws Exception{
|
||||
|
||||
DataCatalogueRunningCluster catalogueRunningInstance = new DataCatalogueRunningCluster(context);
|
||||
return catalogueRunningInstance.getSysAdminToken();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -12,10 +12,11 @@ public class ConnectedBean implements Serializable{
|
|||
private static final long serialVersionUID = -4863776727351488790L;
|
||||
private String sourceKnowledgeBaseId;
|
||||
private String sourceDomain; // i.e. Stock or Fishery
|
||||
private String destShortName;
|
||||
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 String sourceUrl;
|
||||
private String destKnowledgeBaseId; // the dest identifier of a Fishery or Stock (the link is from a Stock to a Fishery and vice versa)
|
||||
private String destName;
|
||||
private String destUrl;
|
||||
private String destDomain; // please note that this MUST be different from sourceDomain
|
||||
private boolean remove;
|
||||
private boolean connect;
|
||||
|
||||
|
@ -24,25 +25,26 @@ public class ConnectedBean implements Serializable{
|
|||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param sourceKnowledgeBaseId
|
||||
* @param sourceDomain
|
||||
* @param destShortName
|
||||
* @param destSemanticIdentifier
|
||||
* @param sourceUrl
|
||||
* @param destKnowledgeBaseId
|
||||
* @param url
|
||||
* @param destTitle
|
||||
* @param destUrl
|
||||
* @param remove
|
||||
* @param connect
|
||||
*/
|
||||
public ConnectedBean(String sourceKnowledgeBaseId, String sourceDomain,
|
||||
String destShortName, String destSemanticIdentifier,
|
||||
String destKnowledgeBaseId, String url) {
|
||||
String sourceUrl, String destKnowledgeBaseId, String destName,
|
||||
String destUrl, String destDomain) {
|
||||
super();
|
||||
this.sourceKnowledgeBaseId = sourceKnowledgeBaseId;
|
||||
this.sourceDomain = sourceDomain;
|
||||
this.destShortName = destShortName;
|
||||
this.destSemanticIdentifier = destSemanticIdentifier;
|
||||
this.sourceUrl = sourceUrl;
|
||||
this.destKnowledgeBaseId = destKnowledgeBaseId;
|
||||
this.url = url;
|
||||
|
||||
this.destName = destName;
|
||||
this.destUrl = destUrl;
|
||||
this.destDomain = destDomain;
|
||||
}
|
||||
|
||||
public boolean isConnect() {
|
||||
|
@ -53,21 +55,6 @@ public class ConnectedBean implements Serializable{
|
|||
this.connect = connect;
|
||||
}
|
||||
|
||||
public String getDestShortName() {
|
||||
return destShortName;
|
||||
}
|
||||
|
||||
public void setDestShortName(String destShortName) {
|
||||
this.destShortName = destShortName;
|
||||
}
|
||||
|
||||
public String getDestSemanticIdentifier() {
|
||||
return destSemanticIdentifier;
|
||||
}
|
||||
|
||||
public void setDestSemanticIdentifier(String destSemanticIdentifier) {
|
||||
this.destSemanticIdentifier = destSemanticIdentifier;
|
||||
}
|
||||
public String getSourceKnowledgeBaseId() {
|
||||
return sourceKnowledgeBaseId;
|
||||
}
|
||||
|
@ -99,20 +86,45 @@ public class ConnectedBean implements Serializable{
|
|||
this.remove = remove;
|
||||
}
|
||||
|
||||
public String getUrl() {
|
||||
return url;
|
||||
public String getSourceUrl() {
|
||||
return sourceUrl;
|
||||
}
|
||||
public void setUrl(String url) {
|
||||
this.url = url;
|
||||
|
||||
public void setSourceUrl(String sourceUrl) {
|
||||
this.sourceUrl = sourceUrl;
|
||||
}
|
||||
|
||||
public String getDestName() {
|
||||
return destName;
|
||||
}
|
||||
|
||||
public void setDestName(String destName) {
|
||||
this.destName = destName;
|
||||
}
|
||||
|
||||
public String getDestUrl() {
|
||||
return destUrl;
|
||||
}
|
||||
|
||||
public void setDestUrl(String destUrl) {
|
||||
this.destUrl = destUrl;
|
||||
}
|
||||
|
||||
public String getDestDomain() {
|
||||
return destDomain;
|
||||
}
|
||||
|
||||
public void setDestDomain(String destDomain) {
|
||||
this.destDomain = destDomain;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ConnectedBean [sourceKnowledgeBaseId=" + sourceKnowledgeBaseId
|
||||
+ ", sourceDomain=" + sourceDomain + ", destShortName="
|
||||
+ destShortName + ", destSemanticIdentifier="
|
||||
+ destSemanticIdentifier + ", destKnowledgeBaseId="
|
||||
+ destKnowledgeBaseId + ", url=" + url + ", remove=" + remove
|
||||
+ ", sourceDomain=" + sourceDomain + ", sourceUrl=" + sourceUrl
|
||||
+ ", destKnowledgeBaseId=" + destKnowledgeBaseId
|
||||
+ ", destName=" + destName + ", destUrl=" + destUrl
|
||||
+ ", destDomain=" + destDomain + ", remove=" + remove
|
||||
+ ", connect=" + connect + "]";
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package org.gcube.datacatalogue.grsf_manage_widget.shared;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
|
@ -14,13 +15,13 @@ public class ManageProductBean implements Serializable{
|
|||
|
||||
private static final long serialVersionUID = -4882608487467259326L;
|
||||
private String semanticIdentifier; // Stock id or Fishery id
|
||||
private String catalogueIdentifier; // catalogue id
|
||||
private String catalogueIdentifier; // Catalogue id
|
||||
private String knowledgeBaseIdentifier; // GRSF UUID
|
||||
private String grsfType; // Fishery or Stock type (e.g., Assessment_Unit, Marine Resource and so on)
|
||||
private String grsfDomain; // fishery/stock
|
||||
private String grsfName; // Fishery name or Stock name
|
||||
private String shortName; // it is editable ...
|
||||
private String shortNameUpdated;
|
||||
private String shortNameUpdated; // the updated one, if any
|
||||
private boolean traceabilityFlag; //from false to true etc
|
||||
private Status currentStatus;
|
||||
private Status newStatus;
|
||||
|
@ -28,20 +29,34 @@ public class ManageProductBean implements Serializable{
|
|||
private Map<String, String> extrasIfAvailable; // read from GRSFManageEntries resource
|
||||
private List<SourceRecord> sources; // sources for this record
|
||||
private List<SimilarGRSFRecord> similarGrsfRecords;
|
||||
private List<ConnectedBean> connectTo;
|
||||
private boolean mergesInvolved;
|
||||
private List<ConnectedBean> suggestedByKnowledgeBase;
|
||||
private List<ConnectedBean> suggestdByAdministrator = new ArrayList<ConnectedBean>(0);
|
||||
private List<ConnectedBean> currentConnections;
|
||||
private List<ConnectedBean> connections; // the one to used eventually
|
||||
private boolean mergesInvolved; // important: in this case an email must be sent to the editors/reviewers
|
||||
private String recordUrl; // this record url
|
||||
|
||||
public ManageProductBean() {
|
||||
super();
|
||||
}
|
||||
|
||||
public ManageProductBean(String semanticIdentifier,
|
||||
String catalogueIdentifier, String knowledgeBaseIdentifier,
|
||||
String grsfType, String grsfDomain, String grsfName,
|
||||
String shortName, boolean traceabilityFlag, Status currentStatus,
|
||||
Status newStatus, String annotation,
|
||||
Map<String, String> extrasIfAvailable, List<SourceRecord> sources,
|
||||
List<SimilarGRSFRecord> similarGrsfRecords, List<ConnectedBean> connectedBeans, boolean mergesInvolved) {
|
||||
public ManageProductBean(
|
||||
String semanticIdentifier,
|
||||
String catalogueIdentifier,
|
||||
String knowledgeBaseIdentifier,
|
||||
String grsfType,
|
||||
String grsfDomain,
|
||||
String grsfName,
|
||||
String shortName,
|
||||
boolean traceabilityFlag,
|
||||
Status currentStatus,
|
||||
String recordUrl,
|
||||
Map<String, String> extrasIfAvailable,
|
||||
List<SourceRecord> sources,
|
||||
List<SimilarGRSFRecord> similarGrsfRecords,
|
||||
List<ConnectedBean> currentConnections,
|
||||
List<ConnectedBean> suggestedByKnowledgeBase
|
||||
) {
|
||||
super();
|
||||
this.semanticIdentifier = semanticIdentifier;
|
||||
this.catalogueIdentifier = catalogueIdentifier;
|
||||
|
@ -53,13 +68,12 @@ public class ManageProductBean implements Serializable{
|
|||
this.shortNameUpdated = shortName;
|
||||
this.traceabilityFlag = traceabilityFlag;
|
||||
this.currentStatus = currentStatus;
|
||||
this.newStatus = newStatus;
|
||||
this.annotation = annotation;
|
||||
this.extrasIfAvailable = extrasIfAvailable;
|
||||
this.sources = sources;
|
||||
this.similarGrsfRecords = similarGrsfRecords;
|
||||
this.connectTo = connectedBeans;
|
||||
this.mergesInvolved = mergesInvolved;
|
||||
this.currentConnections = currentConnections;
|
||||
this.suggestedByKnowledgeBase = suggestedByKnowledgeBase;
|
||||
this.recordUrl = recordUrl;
|
||||
}
|
||||
|
||||
public String getSemanticIdentifier() {
|
||||
|
@ -184,12 +198,30 @@ public class ManageProductBean implements Serializable{
|
|||
this.shortNameUpdated = shortNameUpdated;
|
||||
}
|
||||
|
||||
public List<ConnectedBean> getConnectTo() {
|
||||
return connectTo;
|
||||
public List<ConnectedBean> getSuggestedByKnowledgeBase() {
|
||||
return suggestedByKnowledgeBase;
|
||||
}
|
||||
|
||||
public void setConnectTo(List<ConnectedBean> connectTo) {
|
||||
this.connectTo = connectTo;
|
||||
public void setSuggestedByKnowledgeBase(
|
||||
List<ConnectedBean> suggestedByKnowledgeBase) {
|
||||
this.suggestedByKnowledgeBase = suggestedByKnowledgeBase;
|
||||
}
|
||||
|
||||
public List<ConnectedBean> getSuggestdByAdministrator() {
|
||||
return suggestdByAdministrator;
|
||||
}
|
||||
|
||||
public void setSuggestdByAdministrator(
|
||||
List<ConnectedBean> suggestdByAdministrator) {
|
||||
this.suggestdByAdministrator = suggestdByAdministrator;
|
||||
}
|
||||
|
||||
public List<ConnectedBean> getCurrentConnections() {
|
||||
return currentConnections;
|
||||
}
|
||||
|
||||
public void setCurrentConnections(List<ConnectedBean> currentConnections) {
|
||||
this.currentConnections = currentConnections;
|
||||
}
|
||||
|
||||
public boolean isMergesInvolved() {
|
||||
|
@ -200,6 +232,22 @@ public class ManageProductBean implements Serializable{
|
|||
this.mergesInvolved = mergesInvolved;
|
||||
}
|
||||
|
||||
public String getRecordUrl() {
|
||||
return recordUrl;
|
||||
}
|
||||
|
||||
public void setRecordUrl(String recordUrl) {
|
||||
this.recordUrl = recordUrl;
|
||||
}
|
||||
|
||||
public List<ConnectedBean> getConnections() {
|
||||
return connections;
|
||||
}
|
||||
|
||||
public void setConnections(List<ConnectedBean> connections) {
|
||||
this.connections = connections;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ManageProductBean [semanticIdentifier=" + semanticIdentifier
|
||||
|
@ -212,7 +260,12 @@ public class ManageProductBean implements Serializable{
|
|||
+ currentStatus + ", newStatus=" + newStatus + ", annotation="
|
||||
+ annotation + ", extrasIfAvailable=" + extrasIfAvailable
|
||||
+ ", sources=" + sources + ", similarGrsfRecords="
|
||||
+ similarGrsfRecords + ", connectTo=" + connectTo
|
||||
+ ", mergesInvolved=" + mergesInvolved + "]";
|
||||
+ similarGrsfRecords + ", suggestedByKnowledgeBase="
|
||||
+ suggestedByKnowledgeBase + ", suggestdByAdministrator="
|
||||
+ suggestdByAdministrator + ", currentConnections="
|
||||
+ currentConnections + ", connections=" + connections
|
||||
+ ", mergesInvolved=" + mergesInvolved + ", recordUrl="
|
||||
+ recordUrl + "]";
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue