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.methodParameters=do not generate
|
||||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
|
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
|
||||||
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
|
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.lineNumber=generate
|
||||||
org.eclipse.jdt.core.compiler.debug.localVariable=generate
|
org.eclipse.jdt.core.compiler.debug.localVariable=generate
|
||||||
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
|
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
|
||||||
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
|
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
|
||||||
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
|
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
|
||||||
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
|
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="/" 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/java"/>
|
||||||
<wb-resource deploy-path="/WEB-INF/classes" source-path="/src/main/resources"/>
|
<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>
|
<dependency-type>uses</dependency-type>
|
||||||
</dependent-module>
|
</dependent-module>
|
||||||
<property name="context-root" value="grsf-manage-widget"/>
|
<property name="context-root" value="grsf-manage-widget"/>
|
||||||
|
|
|
@ -27,22 +27,21 @@ public interface GRSFManageWidgetService extends RemoteService {
|
||||||
*/
|
*/
|
||||||
String notifyProductUpdate(ManageProductBean bean) throws Exception;
|
String notifyProductUpdate(ManageProductBean bean) throws Exception;
|
||||||
|
|
||||||
/**
|
// /**
|
||||||
* Check that a record with such semantic identifier exists
|
// * Check that a record with such semantic identifier exists
|
||||||
* @param semanticIdentifier
|
// * @param semanticIdentifier
|
||||||
* @return true or false
|
// * @return true or false
|
||||||
*/
|
// */
|
||||||
boolean checkSemanticIdentifierExists(String semanticIdentifier) throws Exception;
|
// boolean checkSemanticIdentifierExists(String semanticIdentifier) throws Exception;
|
||||||
|
//
|
||||||
/**
|
// /**
|
||||||
* Check that a record with such semantic identifier exists in a given domain
|
// * Check that a record with such semantic identifier exists in a given domain
|
||||||
* @param semanticIdentifier
|
// * @param semanticIdentifier
|
||||||
* @param domain
|
// * @param domain
|
||||||
* @return
|
// * @return
|
||||||
* @throws Exception
|
// * @throws Exception
|
||||||
*/
|
// */
|
||||||
boolean checkSemanticIdentifierExistsInDomain(String semanticIdentifier, String domain) throws Exception;
|
// boolean checkSemanticIdentifierExistsInDomain(String semanticIdentifier, String domain) throws Exception;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Identifier of the record (UUID)
|
* Identifier of the record (UUID)
|
||||||
|
@ -61,4 +60,11 @@ public interface GRSFManageWidgetService extends RemoteService {
|
||||||
*/
|
*/
|
||||||
String checkIdentifierExistsInDomain(String id, String domain) throws Exception;
|
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 isAdminUser(AsyncCallback<Boolean> callback);
|
||||||
|
|
||||||
void checkSemanticIdentifierExists(String semanticIdentifier,
|
// void checkSemanticIdentifierExists(String semanticIdentifier,
|
||||||
AsyncCallback<Boolean> callback);
|
// AsyncCallback<Boolean> callback);
|
||||||
|
//
|
||||||
void checkSemanticIdentifierExistsInDomain(String semanticIdentifier,
|
// void checkSemanticIdentifierExistsInDomain(String semanticIdentifier,
|
||||||
String domain, AsyncCallback<Boolean> callback);
|
// String domain, AsyncCallback<Boolean> callback);
|
||||||
|
|
||||||
void checkIdentifierExists(String id,
|
void checkIdentifierExists(String id,
|
||||||
AsyncCallback<String> callback);
|
AsyncCallback<String> callback);
|
||||||
|
@ -33,4 +33,6 @@ public interface GRSFManageWidgetServiceAsync {
|
||||||
void checkIdentifierExistsInDomain(String id,
|
void checkIdentifierExistsInDomain(String id,
|
||||||
String domain, AsyncCallback<String> callback);
|
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.Map;
|
||||||
import java.util.UUID;
|
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.portal.PortalContext;
|
||||||
|
import org.gcube.common.scope.api.ScopeProvider;
|
||||||
import org.gcube.datacatalogue.ckanutillibrary.server.DataCatalogue;
|
import org.gcube.datacatalogue.ckanutillibrary.server.DataCatalogue;
|
||||||
import org.gcube.datacatalogue.ckanutillibrary.server.DataCatalogueFactory;
|
import org.gcube.datacatalogue.ckanutillibrary.server.DataCatalogueFactory;
|
||||||
import org.gcube.datacatalogue.ckanutillibrary.server.utils.UtilMethods;
|
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.RoleManager;
|
||||||
import org.gcube.vomanagement.usermanagement.impl.LiferayRoleManager;
|
import org.gcube.vomanagement.usermanagement.impl.LiferayRoleManager;
|
||||||
import org.gcube.vomanagement.usermanagement.model.GCubeTeam;
|
import org.gcube.vomanagement.usermanagement.model.GCubeTeam;
|
||||||
|
import org.gcube.vomanagement.usermanagement.model.GCubeUser;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import com.google.gwt.user.server.rpc.RemoteServiceServlet;
|
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.CkanDataset;
|
||||||
import eu.trentorise.opendata.jackan.model.CkanPair;
|
import eu.trentorise.opendata.jackan.model.CkanPair;
|
||||||
import eu.trentorise.opendata.jackan.model.CkanResource;
|
import eu.trentorise.opendata.jackan.model.CkanResource;
|
||||||
|
@ -52,7 +60,7 @@ public class GRSFNotificationService extends RemoteServiceServlet implements GRS
|
||||||
String currentScope = Utils.getCurrentContext(getThreadLocalRequest(), true);
|
String currentScope = Utils.getCurrentContext(getThreadLocalRequest(), true);
|
||||||
DataCatalogue instance = null;
|
DataCatalogue instance = null;
|
||||||
try{
|
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);
|
logger.debug("Discovering ckan utils library into scope " + scopeInWhichDiscover);
|
||||||
instance = DataCatalogueFactory.getFactory().getUtilsPerScope(scopeInWhichDiscover);
|
instance = DataCatalogueFactory.getFactory().getUtilsPerScope(scopeInWhichDiscover);
|
||||||
}catch(Exception e){
|
}catch(Exception e){
|
||||||
|
@ -65,17 +73,29 @@ public class GRSFNotificationService extends RemoteServiceServlet implements GRS
|
||||||
@Override
|
@Override
|
||||||
public ManageProductBean getProductBeanById(String productIdentifier) throws Exception {
|
public ManageProductBean getProductBeanById(String productIdentifier) throws Exception {
|
||||||
|
|
||||||
|
|
||||||
ManageProductBean toReturn = null;
|
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()){
|
if(!Utils.isIntoPortal()){
|
||||||
|
|
||||||
toReturn = new ManageProductBean();
|
toReturn = new ManageProductBean();
|
||||||
toReturn.setCatalogueIdentifier(UUID.randomUUID().toString());
|
toReturn.setCatalogueIdentifier(UUID.randomUUID().toString());
|
||||||
List<ConnectedBean> connectTo = new ArrayList<>();
|
List<ConnectedBean> connectTo = new ArrayList<>();
|
||||||
connectTo.add(new ConnectedBean("91f1e413-dc9f-3b4e-b1c5-0e8560177253","Stock",
|
connectTo.add(new ConnectedBean(
|
||||||
"aksldsam asd", "asdasjnk:fas", UUID.randomUUID().toString(), "http://data.d4science.org/ctlg/GRSF_Admin/91f1e413-dc9f-3b4e-b1c5-0e8560177253"));
|
"91f1e413-dc9f-3b4e-b1c5-0e8560177253",
|
||||||
toReturn.setConnectTo(connectTo);
|
"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.setGrsfDomain("Stock");
|
||||||
toReturn.setGrsfType("Assessment Unit");
|
toReturn.setGrsfType("Assessment Unit");
|
||||||
toReturn.setKnowledgeBaseIdentifier("91f1e413-dc9f-3b4e-b1c5-0e8560177253");
|
toReturn.setKnowledgeBaseIdentifier("91f1e413-dc9f-3b4e-b1c5-0e8560177253");
|
||||||
|
@ -105,52 +125,63 @@ public class GRSFNotificationService extends RemoteServiceServlet implements GRS
|
||||||
|
|
||||||
}else{
|
}else{
|
||||||
|
|
||||||
// retrieve scope per current portlet url
|
|
||||||
String scopePerCurrentUrl = Utils.getScopeFromClientUrl(getThreadLocalRequest());
|
String scopePerCurrentUrl = Utils.getScopeFromClientUrl(getThreadLocalRequest());
|
||||||
DataCatalogue catalogue = getCatalogue(scopePerCurrentUrl);
|
DataCatalogue catalogue = getCatalogue(scopePerCurrentUrl);
|
||||||
String username = Utils.getCurrentUser(getThreadLocalRequest()).getUsername();
|
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 ...
|
// it cannot be enabled in this case ...
|
||||||
if(record == null)
|
if(record == null)
|
||||||
throw new Exception("Unable to retrieve information for the selected record, sorry");
|
throw new Exception("Unable to retrieve information for the selected record, sorry");
|
||||||
else{
|
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)
|
// check it is a grsf record (Source records have a different System Type)
|
||||||
String systemType = record.getExtrasAsHashMap().get(Constants.SYSTEM_TYPE_CUSTOM_KEY);
|
Map<String, String> extrasAsMap = record.getExtrasAsHashMap();
|
||||||
if(systemType == null || systemType.isEmpty() || systemType.equals(Constants.SYSTEM_TYPE_FOR_SOURCES_VALUE))
|
|
||||||
throw new NoGRSFRecordException("This is not a GRSF Record");
|
|
||||||
|
|
||||||
// get extras as hashmap and pairs
|
// get extras as hashmap and pairs
|
||||||
List<CkanPair> extrasAsPairs = record.getExtras();
|
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
|
// fetch map for namespaces
|
||||||
Map<String, String> fieldsNamespacesMap = Utils.getFieldToFieldNameSpaceMapping(getThreadLocalRequest().getSession(),
|
Map<String, String> fieldsNamespacesMap =
|
||||||
record.getExtrasAsHashMap().get(Constants.DOMAIN_CUSTOM_KEY).contains(Product_Type.STOCK.getOrigName()) ? Constants.GENERIC_RESOURCE_NAME_MAP_KEY_NAMESPACES_STOCK
|
Utils.getFieldToFieldNameSpaceMapping(httpSession, isStock ?
|
||||||
: Constants.GENERIC_RESOURCE_NAME_MAP_KEY_NAMESPACES_FISHERY);
|
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);
|
Map<String, List<String>> extrasWithoutNamespaces = Utils.replaceFieldsKey(extrasAsPairs, fieldsNamespacesMap);
|
||||||
// get extras fields (wrt the mandatory ones) to show in the management panel TODO
|
// get extras fields (wrt the mandatory ones) to show in the management panel TODO
|
||||||
// Utils.getExtrasToShow();
|
// Utils.getExtrasToShow();
|
||||||
String catalogueIdentifier = record.getId();
|
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 uuidKB = extrasWithoutNamespaces.get(Constants.UUID_KB_CUSTOM_KEY).get(0);
|
||||||
String grsfDomain = extrasWithoutNamespaces.get(Constants.DOMAIN_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)
|
if(status == null || uuidKB == null)
|
||||||
throw new Exception("Some information is missing in this record: Status = " + status + ", knowledge base uuid = " + uuidKB +
|
throw new Exception("Some information is missing in this record: Status = " + status + ", knowledge base uuid = " + uuidKB +
|
||||||
", and grsf domain is = " + grsfDomain);
|
", 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 semanticId = extrasWithoutNamespaces.get(Constants.GRSF_SEMANTIC_IDENTIFIER_CUSTOM_KEY).get(0);
|
||||||
String shortName = extrasWithoutNamespaces.get(Constants.SHORT_NAME_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 grsfType = extrasWithoutNamespaces.get(Constants.GRSF_TYPE_CUSTOM_KEY).get(0);
|
||||||
String grsfName = extrasWithoutNamespaces.get(grsfDomain.contains(Product_Type.STOCK.getOrigName()) ?
|
String recordUrl = extrasWithoutNamespaces.get(Constants.ITEM_URL_FIELD).get(0);
|
||||||
Constants.STOCK_NAME_CUSTOM_KEY : Constants.FISHERY_NAME_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");
|
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))
|
// 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;
|
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) {
|
for (String similarGRSFRecord : similarGrsfRecordsAsStrings) {
|
||||||
if(similarGRSFRecord.equals(Constants.NO_SIMILAR_GRSF_RECORDS)) // stop here if there is a single element with this information
|
if(similarGRSFRecord.equals(Constants.NO_SIMILAR_GRSF_RECORDS)) // stop here if there is a single element with this information
|
||||||
break;
|
break;
|
||||||
|
|
||||||
similarRecords.add(Utils.similarGRSFRecordFromJson(similarGRSFRecord));
|
similarRecords.add(Utils.similarGRSFRecordFromJson(similarGRSFRecord));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.debug("SimilarGRSFRecords are " + similarRecords);
|
logger.debug("SimilarGRSFRecords are " + similarRecords);
|
||||||
|
|
||||||
// get connected records
|
// get connected records (and the proposed ones)
|
||||||
List<String> connectedBeansAsStrings = extrasWithoutNamespaces.containsKey(Constants.CONNECTED_CUSTOM_KEY) ? extrasWithoutNamespaces.get(Constants.CONNECTED_CUSTOM_KEY): null;
|
List<String> connectedBeanUrls =
|
||||||
|
extrasWithoutNamespaces.containsKey(Constants.CONNECTED_CUSTOM_KEY) ? extrasWithoutNamespaces.get(Constants.CONNECTED_CUSTOM_KEY): null;
|
||||||
|
|
||||||
List<ConnectedBean> connectedBeans = new ArrayList<ConnectedBean>(0);
|
List<ConnectedBean> connectedBeans = new ArrayList<ConnectedBean>(0);
|
||||||
if(connectedBeansAsStrings != null){
|
if(connectedBeanUrls != null){
|
||||||
for (String connectedBean : connectedBeansAsStrings) {
|
for (String connectedBean : connectedBeanUrls) {
|
||||||
if(connectedBean.equals(Constants.NO_CONNECTED_RECORDS)) // stop here if there is a single element with this information
|
if(connectedBean.equals(Constants.NO_CONNECTED_RECORDS)) // stop here if there is a single element with this information
|
||||||
break;
|
break;
|
||||||
connectedBeans.add(Utils.connectedBeanRecordFromJson(connectedBean, uuidKB, grsfDomain, catalogue));
|
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
|
// get the connections the knowledge base suggests
|
||||||
List<CkanResource> resources = record.getResources();
|
List<ConnectedBean> suggestedConnectionsByKnowledgeBase = new ArrayList<ConnectedBean>(0);
|
||||||
List<SourceRecord> sources = new ArrayList<SourceRecord>(3);
|
List<String> exploitedResourcesUrls = isStock ?
|
||||||
for (CkanResource ckanResource : resources) {
|
(extrasWithoutNamespaces.containsKey(Constants.EXPLOITING_FISHERY_JSON_KEY) ?
|
||||||
if(Sources.getListNames().contains(ckanResource.getName()))
|
extrasWithoutNamespaces.get(Constants.EXPLOITING_FISHERY_JSON_KEY) : null):
|
||||||
sources.add(new SourceRecord(ckanResource.getName(), ckanResource.getUrl()));
|
(extrasWithoutNamespaces.containsKey(Constants.RESOURCES_EXPLOITED_JSON_KEY) ? extrasWithoutNamespaces.get(Constants.RESOURCES_EXPLOITED_JSON_KEY) : null);
|
||||||
}
|
|
||||||
|
|
||||||
// set the values
|
if(exploitedResourcesUrls != null && !exploitedResourcesUrls.isEmpty()){
|
||||||
toReturn = new ManageProductBean(semanticId, catalogueIdentifier, uuidKB, grsfType,
|
for (String exploited : exploitedResourcesUrls) {
|
||||||
grsfDomain, grsfName, shortName, traceabilityFlag, Status.fromString(status), null,
|
ConnectedBean builtBean = Utils.connectedBeanRecordFromUrl(recordUrl, exploited, uuidKB, grsfDomain, catalogue, apiKey);
|
||||||
null, null, sources, similarRecords, connectedBeans, false);
|
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);
|
logger.info("Returning item bean " + toReturn);
|
||||||
|
httpSession.setAttribute(sessionProductKey, toReturn);
|
||||||
return toReturn;
|
return toReturn;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isAdminUser() {
|
public boolean isAdminUser() {
|
||||||
try{
|
try{
|
||||||
|
|
||||||
Boolean inSession = (Boolean)getThreadLocalRequest().getSession().getAttribute(Constants.GRSF_ADMIN_SESSION_KEY);
|
Boolean inSession = (Boolean)getThreadLocalRequest().getSession().getAttribute(Constants.GRSF_ADMIN_SESSION_KEY);
|
||||||
|
|
||||||
if(inSession != null)
|
if(inSession != null)
|
||||||
return inSession;
|
return inSession;
|
||||||
else{
|
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;
|
boolean toSetInSession = false;
|
||||||
for (GCubeTeam team : teamRoles) {
|
if(!Utils.isIntoPortal()){
|
||||||
if(team.getTeamName().equals(Constants.GRSF_CATALOGUE_EDITOR_ROLE) || team.getTeamName().equals(Constants.GRSF_CATALOGUE_REVIEWER_ROLE)){
|
toSetInSession = true;
|
||||||
logger.info("User " + username + " is allowed to modify GRSF records");
|
}else{
|
||||||
toSetInSession = true;
|
PortalContext pContext = PortalContext.getConfiguration();
|
||||||
break;
|
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);
|
getThreadLocalRequest().getSession().setAttribute(Constants.GRSF_ADMIN_SESSION_KEY, toSetInSession);
|
||||||
return toSetInSession;
|
return toSetInSession;
|
||||||
}
|
}
|
||||||
|
@ -251,42 +282,132 @@ public class GRSFNotificationService extends RemoteServiceServlet implements GRS
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean checkSemanticIdentifierExists(String semanticIdentifier)
|
public String notifyProductUpdate(ManageProductBean bean) throws Exception{
|
||||||
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
|
@Override
|
||||||
public boolean checkSemanticIdentifierExistsInDomain(String semanticIdentifier, String domain)
|
public void validateRevertOperation(String encryptedUrl) throws Exception {
|
||||||
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
|
if(!(isEditor | isReviewer))
|
||||||
List<CkanPair> extrasAsPairs = dataset.getExtras();
|
throw new Exception("You are not allowed to perform this operation!");
|
||||||
|
|
||||||
for (CkanPair ckanPair : extrasAsPairs) {
|
// decrypt the url
|
||||||
if(ckanPair.getKey().contains(Constants.DOMAIN_CUSTOM_KEY)){
|
RevertOperationUrl decryptedUrl = new RevertOperationUrl(encryptedUrl);
|
||||||
return ckanPair.getValue().equalsIgnoreCase(domain);
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private CkanDataset getDataset(String semanticIdentifier) throws Exception{
|
/**
|
||||||
|
* Check if the current user is a reviewer
|
||||||
String scopePerCurrentUrl = Utils.getScopeFromClientUrl(getThreadLocalRequest());
|
* @param username
|
||||||
DataCatalogue catalogue = getCatalogue(scopePerCurrentUrl);
|
* @param teamRoles
|
||||||
String username = Utils.getCurrentUser(getThreadLocalRequest()).getUsername();
|
* @return true if he/she is an reviewer, false otherwise
|
||||||
CkanDataset dataset = Utils.getRecordBySemanticIdentifier(semanticIdentifier, catalogue, catalogue.getApiKeyFromUsername(username));
|
*/
|
||||||
return dataset;
|
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
|
@Override
|
||||||
public String checkIdentifierExists(String id)
|
public String checkIdentifierExists(String id)
|
||||||
throws Exception {
|
throws Exception {
|
||||||
|
@ -295,8 +416,7 @@ public class GRSFNotificationService extends RemoteServiceServlet implements GRS
|
||||||
String username = Utils.getCurrentUser(getThreadLocalRequest()).getUsername();
|
String username = Utils.getCurrentUser(getThreadLocalRequest()).getUsername();
|
||||||
CkanDataset dataset = catalogue.getDataset(id, catalogue.getApiKeyFromUsername(username));
|
CkanDataset dataset = catalogue.getDataset(id, catalogue.getApiKeyFromUsername(username));
|
||||||
if(dataset == null)
|
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);
|
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();
|
String username = Utils.getCurrentUser(getThreadLocalRequest()).getUsername();
|
||||||
CkanDataset dataset = catalogue.getDataset(id, catalogue.getApiKeyFromUsername(username));
|
CkanDataset dataset = catalogue.getDataset(id, catalogue.getApiKeyFromUsername(username));
|
||||||
if(dataset == null)
|
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();
|
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
|
// @Override
|
||||||
public String notifyProductUpdate(ManageProductBean bean) throws Exception{
|
// 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");
|
// private CkanDataset getDataset(String semanticIdentifier) throws Exception{
|
||||||
try{
|
// String scopePerCurrentUrl = Utils.getScopeFromClientUrl(getThreadLocalRequest());
|
||||||
|
// DataCatalogue catalogue = getCatalogue(scopePerCurrentUrl);
|
||||||
String context = Utils.getScopeFromClientUrl(getThreadLocalRequest());
|
// String username = Utils.getCurrentUser(getThreadLocalRequest()).getUsername();
|
||||||
DataCatalogue catalogue = getCatalogue(context);
|
// CkanDataset dataset = Utils.getRecordBySemanticIdentifier(semanticIdentifier, catalogue, catalogue.getApiKeyFromUsername(username));
|
||||||
String administratorFullName = Utils.getCurrentUser(getThreadLocalRequest()).getFullname();
|
// return dataset;
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.URLDecoder;
|
||||||
import java.net.URLEncoder;
|
import java.net.URLEncoder;
|
||||||
|
@ -22,11 +22,16 @@ public class RevertOperationUrl {
|
||||||
public static final String TIMESTAMP_QUERY_PARAM = "t";
|
public static final String TIMESTAMP_QUERY_PARAM = "t";
|
||||||
public static final String UUID_QUERY_PARAM = "uuid";
|
public static final String UUID_QUERY_PARAM = "uuid";
|
||||||
public static final String OPERATION_REVERT_QUERY_PARAM = "operation_revert";
|
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 {
|
public enum Operation {
|
||||||
|
|
||||||
MERGE("merge"),
|
MERGE("merge");
|
||||||
DISSECT("dissect");
|
// DISSECT("dissect");
|
||||||
private String name;
|
private String name;
|
||||||
|
|
||||||
private Operation(String name) {
|
private Operation(String name) {
|
||||||
|
@ -45,7 +50,6 @@ public class RevertOperationUrl {
|
||||||
private long timestamp;
|
private long timestamp;
|
||||||
private String uuid;
|
private String uuid;
|
||||||
private Operation operation;
|
private Operation operation;
|
||||||
private Operation op;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param admin
|
* @param admin
|
||||||
|
@ -55,17 +59,20 @@ public class RevertOperationUrl {
|
||||||
* @param op
|
* @param op
|
||||||
*/
|
*/
|
||||||
public RevertOperationUrl(String baseUrl, String admin, long timestamp, String uuid,
|
public RevertOperationUrl(String baseUrl, String admin, long timestamp, String uuid,
|
||||||
Operation operation, Operation op) {
|
Operation operation) {
|
||||||
super();
|
super();
|
||||||
this.baseUrl = baseUrl;
|
this.baseUrl = baseUrl;
|
||||||
this.admin = admin;
|
this.admin = admin;
|
||||||
this.timestamp = timestamp;
|
this.timestamp = timestamp;
|
||||||
this.uuid = uuid;
|
this.uuid = uuid;
|
||||||
this.operation = operation;
|
this.operation = operation;
|
||||||
this.op = op;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build a crypted, encoded and shortened url
|
||||||
|
* @return
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
public String getShortUrl() 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;
|
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:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}catch(Exception e){
|
}catch(Exception e){
|
||||||
logger.error("Failed to parse url", e);
|
logger.error("Failed to parse url", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isTimestampValid() {
|
||||||
|
return TTL + this.timestamp < System.currentTimeMillis();
|
||||||
|
}
|
||||||
|
|
||||||
public String getBaseUrl() {
|
public String getBaseUrl() {
|
||||||
return baseUrl;
|
return baseUrl;
|
||||||
|
@ -188,58 +198,11 @@ public class RevertOperationUrl {
|
||||||
this.operation = operation;
|
this.operation = operation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public Operation getOp() {
|
|
||||||
return op;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void setOp(Operation op) {
|
|
||||||
this.op = op;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "RevertOperationUrl [baseUrl=" + baseUrl + ", admin=" + admin
|
return "RevertOperationUrl [baseUrl=" + baseUrl + ", admin=" + admin
|
||||||
+ ", timestamp=" + timestamp + ", uuid=" + uuid
|
+ ", 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.DocumentBuilder;
|
||||||
import javax.xml.parsers.DocumentBuilderFactory;
|
import javax.xml.parsers.DocumentBuilderFactory;
|
||||||
|
|
||||||
|
import org.gcube.common.authorization.library.provider.SecurityTokenProvider;
|
||||||
import org.gcube.common.encryption.StringEncrypter;
|
import org.gcube.common.encryption.StringEncrypter;
|
||||||
import org.gcube.common.portal.PortalContext;
|
import org.gcube.common.portal.PortalContext;
|
||||||
import org.gcube.common.resources.gcore.ServiceEndpoint;
|
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.ckanutillibrary.shared.ex.ApplicationProfileNotFoundException;
|
||||||
import org.gcube.datacatalogue.common.Constants;
|
import org.gcube.datacatalogue.common.Constants;
|
||||||
import org.gcube.datacatalogue.common.enums.Status;
|
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.ConnectedBean;
|
||||||
import org.gcube.datacatalogue.grsf_manage_widget.shared.ManageProductBean;
|
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.datacatalogue.grsf_manage_widget.shared.SimilarGRSFRecord;
|
||||||
import org.gcube.portlets.user.urlshortener.UrlShortener;
|
import org.gcube.portlets.user.urlshortener.UrlShortener;
|
||||||
import org.gcube.resources.discovery.client.api.DiscoveryClient;
|
import org.gcube.resources.discovery.client.api.DiscoveryClient;
|
||||||
|
@ -177,7 +177,9 @@ public class Utils {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
logger.debug("Map is " + namespacesMap);
|
logger.debug("Map is " + namespacesMap);
|
||||||
httpSession.setAttribute(sessionKey, namespacesMap);
|
|
||||||
|
// put them into session for speeding up the operations
|
||||||
|
httpSession.setAttribute(sessionKey, namespacesMap);
|
||||||
return namespacesMap;
|
return namespacesMap;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
logger.error("Error while trying to fetch applicationProfile profile from the infrastructure", e);
|
logger.error("Error while trying to fetch applicationProfile profile from the infrastructure", e);
|
||||||
|
@ -221,7 +223,7 @@ public class Utils {
|
||||||
* @param extrasAsPairs
|
* @param extrasAsPairs
|
||||||
* @return
|
* @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>>();
|
Map<String, List<String>> toReturn = new HashMap<String, List<String>>();
|
||||||
|
|
||||||
|
@ -242,52 +244,6 @@ public class Utils {
|
||||||
return toReturn;
|
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
|
* Send an update for this bean
|
||||||
* @param baseUrl
|
* @param baseUrl
|
||||||
|
@ -297,7 +253,7 @@ public class Utils {
|
||||||
* @return true on success, false otherwise
|
* @return true on success, false otherwise
|
||||||
*/
|
*/
|
||||||
public static String updateRecord(String serviceUrl, ManageProductBean bean, DataCatalogue catalogue, String username,
|
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)
|
if(serviceUrl == null)
|
||||||
throw new IllegalArgumentException("GRSF Updater service url cannot be null");
|
throw new IllegalArgumentException("GRSF Updater service url cannot be null");
|
||||||
|
@ -312,14 +268,21 @@ public class Utils {
|
||||||
updateStatusInvolvedRecords(bean, catalogue);
|
updateStatusInvolvedRecords(bean, catalogue);
|
||||||
|
|
||||||
// send update to the knowledge base
|
// 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
|
// manage interactions through a separated thread but set there security token and context
|
||||||
if(bean.isMergesInvolved() || bean.getNewStatus().equals(Status.Rejected))
|
new Thread(()->{
|
||||||
sendEmailAdministrators(bean, catalogue, username, fullName, groupId, httpServletRequest);
|
|
||||||
|
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
|
// create a post about the operation
|
||||||
createSocialPost(bean, catalogue, username, fullName);
|
SocialCommunications.createSocialPost(bean, catalogue, username, fullName, hashtags);
|
||||||
|
|
||||||
|
}).start();
|
||||||
|
|
||||||
}catch(Exception e){
|
}catch(Exception e){
|
||||||
logger.error("Unable to update this Item ", e);
|
logger.error("Unable to update this Item ", e);
|
||||||
|
@ -343,7 +306,7 @@ public class Utils {
|
||||||
for(SimilarGRSFRecord s: bean.getSimilarGrsfRecords()){
|
for(SimilarGRSFRecord s: bean.getSimilarGrsfRecords()){
|
||||||
if(s.isSuggestedMerge()){
|
if(s.isSuggestedMerge()){
|
||||||
String productId = s.getKnowledgeBaseId();
|
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()));
|
extrasMap.put(Constants.STATUS_OF_THE_GRSF_RECORD_CUSTOM_KEY, Arrays.asList(Status.To_be_Merged.getOrigName()));
|
||||||
catalogue.patchProductCustomFields(productId, sysApi, extrasMap);
|
catalogue.patchProductCustomFields(productId, sysApi, extrasMap);
|
||||||
}
|
}
|
||||||
|
@ -351,174 +314,12 @@ public class Utils {
|
||||||
|
|
||||||
// update the current status record
|
// update the current status record
|
||||||
String productId = bean.getKnowledgeBaseIdentifier();
|
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()));
|
extrasMap.put(Constants.STATUS_OF_THE_GRSF_RECORD_CUSTOM_KEY, Arrays.asList(Status.To_be_Merged.getOrigName()));
|
||||||
catalogue.patchProductCustomFields(productId, sysApi, extrasMap);
|
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
|
* Get the scope in which ckan information needs to be discovered from the url
|
||||||
* @param httpServletRequest
|
* @param httpServletRequest
|
||||||
|
@ -649,8 +450,9 @@ public class Utils {
|
||||||
* @param url
|
* @param url
|
||||||
* @param clg
|
* @param clg
|
||||||
* @return
|
* @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())
|
if(url == null || url.isEmpty())
|
||||||
return null;
|
return null;
|
||||||
|
@ -667,7 +469,7 @@ public class Utils {
|
||||||
return clg.getDataset(uuidFound, apiKey);
|
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 json
|
||||||
* @param sourceIdentifier
|
* @param sourceIdentifier
|
||||||
* @param sourceDomain
|
* @param sourceDomain
|
||||||
|
* @param grsfDomain
|
||||||
* @return
|
* @return
|
||||||
* @throws ParseException
|
* @throws ParseException
|
||||||
*/
|
*/
|
||||||
public static ConnectedBean connectedBeanRecordFromJson(String json, String sourceIdentifier, String sourceDomain,
|
public static ConnectedBean connectedBeanRecordFromUrl(
|
||||||
DataCatalogue clg) throws ParseException {
|
String sourceIdentifier,
|
||||||
|
String sourceDomain,
|
||||||
|
String sourceUrl,
|
||||||
|
String destUrl,
|
||||||
|
DataCatalogue clg,
|
||||||
|
String apiKey) throws ParseException {
|
||||||
|
|
||||||
if(json == null)
|
if(destUrl == null)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
JSONParser parser = new JSONParser();
|
String connectedBeanUuid = Utils.getDatasetKnowledgeBaseIdFromUrl(destUrl);
|
||||||
JSONObject object = (JSONObject)parser.parse(json);
|
CkanDataset destDataset = clg.getDataset(connectedBeanUuid, apiKey);
|
||||||
|
|
||||||
String uuidDest = (String)object.get(Constants.CONNECTED_RECORD_KNOWLEDGE_BASE_ID_JSON_KEY);
|
|
||||||
String url = clg.getUrlFromDatasetIdOrName(uuidDest);
|
|
||||||
return new ConnectedBean(
|
return new ConnectedBean(
|
||||||
sourceIdentifier,
|
sourceIdentifier,
|
||||||
sourceDomain,
|
sourceDomain,
|
||||||
(String)object.get(Constants.CONNECTED_RECORD_SHORT_NAME_JSON_KEY),
|
sourceUrl,
|
||||||
(String)object.get(Constants.CONNECTED_RECORD_SEMANTIC_IDENTIFIER_JSON_KEY),
|
connectedBeanUuid,
|
||||||
uuidDest,
|
destDataset.getTitle(),
|
||||||
url
|
destUrl,
|
||||||
|
destDataset.getExtrasAsHashMap().get(Constants.DOMAIN_CUSTOM_KEY)
|
||||||
);
|
);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -799,10 +605,8 @@ public class Utils {
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public static String fetchSysAPI(String context) throws Exception{
|
public static String fetchSysAPI(String context) throws Exception{
|
||||||
|
|
||||||
DataCatalogueRunningCluster catalogueRunningInstance = new DataCatalogueRunningCluster(context);
|
DataCatalogueRunningCluster catalogueRunningInstance = new DataCatalogueRunningCluster(context);
|
||||||
return catalogueRunningInstance.getSysAdminToken();
|
return catalogueRunningInstance.getSysAdminToken();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,10 +12,11 @@ public class ConnectedBean implements Serializable{
|
||||||
private static final long serialVersionUID = -4863776727351488790L;
|
private static final long serialVersionUID = -4863776727351488790L;
|
||||||
private String sourceKnowledgeBaseId;
|
private String sourceKnowledgeBaseId;
|
||||||
private String sourceDomain; // i.e. Stock or Fishery
|
private String sourceDomain; // i.e. Stock or Fishery
|
||||||
private String destShortName;
|
private String sourceUrl;
|
||||||
private String destSemanticIdentifier;
|
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 destKnowledgeBaseId; // the dest indentifier of a Fishery or Stock (the link is from a Stock to a Fishery and viceversa)
|
private String destName;
|
||||||
private String url;
|
private String destUrl;
|
||||||
|
private String destDomain; // please note that this MUST be different from sourceDomain
|
||||||
private boolean remove;
|
private boolean remove;
|
||||||
private boolean connect;
|
private boolean connect;
|
||||||
|
|
||||||
|
@ -24,25 +25,26 @@ public class ConnectedBean implements Serializable{
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @param sourceKnowledgeBaseId
|
* @param sourceKnowledgeBaseId
|
||||||
* @param sourceDomain
|
* @param sourceDomain
|
||||||
* @param destShortName
|
* @param sourceUrl
|
||||||
* @param destSemanticIdentifier
|
|
||||||
* @param destKnowledgeBaseId
|
* @param destKnowledgeBaseId
|
||||||
* @param url
|
* @param destTitle
|
||||||
|
* @param destUrl
|
||||||
|
* @param remove
|
||||||
|
* @param connect
|
||||||
*/
|
*/
|
||||||
public ConnectedBean(String sourceKnowledgeBaseId, String sourceDomain,
|
public ConnectedBean(String sourceKnowledgeBaseId, String sourceDomain,
|
||||||
String destShortName, String destSemanticIdentifier,
|
String sourceUrl, String destKnowledgeBaseId, String destName,
|
||||||
String destKnowledgeBaseId, String url) {
|
String destUrl, String destDomain) {
|
||||||
super();
|
super();
|
||||||
this.sourceKnowledgeBaseId = sourceKnowledgeBaseId;
|
this.sourceKnowledgeBaseId = sourceKnowledgeBaseId;
|
||||||
this.sourceDomain = sourceDomain;
|
this.sourceDomain = sourceDomain;
|
||||||
this.destShortName = destShortName;
|
this.sourceUrl = sourceUrl;
|
||||||
this.destSemanticIdentifier = destSemanticIdentifier;
|
|
||||||
this.destKnowledgeBaseId = destKnowledgeBaseId;
|
this.destKnowledgeBaseId = destKnowledgeBaseId;
|
||||||
this.url = url;
|
this.destName = destName;
|
||||||
|
this.destUrl = destUrl;
|
||||||
|
this.destDomain = destDomain;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isConnect() {
|
public boolean isConnect() {
|
||||||
|
@ -53,21 +55,6 @@ public class ConnectedBean implements Serializable{
|
||||||
this.connect = connect;
|
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() {
|
public String getSourceKnowledgeBaseId() {
|
||||||
return sourceKnowledgeBaseId;
|
return sourceKnowledgeBaseId;
|
||||||
}
|
}
|
||||||
|
@ -99,20 +86,45 @@ public class ConnectedBean implements Serializable{
|
||||||
this.remove = remove;
|
this.remove = remove;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getUrl() {
|
public String getSourceUrl() {
|
||||||
return url;
|
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
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "ConnectedBean [sourceKnowledgeBaseId=" + sourceKnowledgeBaseId
|
return "ConnectedBean [sourceKnowledgeBaseId=" + sourceKnowledgeBaseId
|
||||||
+ ", sourceDomain=" + sourceDomain + ", destShortName="
|
+ ", sourceDomain=" + sourceDomain + ", sourceUrl=" + sourceUrl
|
||||||
+ destShortName + ", destSemanticIdentifier="
|
+ ", destKnowledgeBaseId=" + destKnowledgeBaseId
|
||||||
+ destSemanticIdentifier + ", destKnowledgeBaseId="
|
+ ", destName=" + destName + ", destUrl=" + destUrl
|
||||||
+ destKnowledgeBaseId + ", url=" + url + ", remove=" + remove
|
+ ", destDomain=" + destDomain + ", remove=" + remove
|
||||||
+ ", connect=" + connect + "]";
|
+ ", connect=" + connect + "]";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package org.gcube.datacatalogue.grsf_manage_widget.shared;
|
package org.gcube.datacatalogue.grsf_manage_widget.shared;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
@ -14,13 +15,13 @@ public class ManageProductBean implements Serializable{
|
||||||
|
|
||||||
private static final long serialVersionUID = -4882608487467259326L;
|
private static final long serialVersionUID = -4882608487467259326L;
|
||||||
private String semanticIdentifier; // Stock id or Fishery id
|
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 knowledgeBaseIdentifier; // GRSF UUID
|
||||||
private String grsfType; // Fishery or Stock type (e.g., Assessment_Unit, Marine Resource and so on)
|
private String grsfType; // Fishery or Stock type (e.g., Assessment_Unit, Marine Resource and so on)
|
||||||
private String grsfDomain; // fishery/stock
|
private String grsfDomain; // fishery/stock
|
||||||
private String grsfName; // Fishery name or Stock name
|
private String grsfName; // Fishery name or Stock name
|
||||||
private String shortName; // it is editable ...
|
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 boolean traceabilityFlag; //from false to true etc
|
||||||
private Status currentStatus;
|
private Status currentStatus;
|
||||||
private Status newStatus;
|
private Status newStatus;
|
||||||
|
@ -28,20 +29,34 @@ public class ManageProductBean implements Serializable{
|
||||||
private Map<String, String> extrasIfAvailable; // read from GRSFManageEntries resource
|
private Map<String, String> extrasIfAvailable; // read from GRSFManageEntries resource
|
||||||
private List<SourceRecord> sources; // sources for this record
|
private List<SourceRecord> sources; // sources for this record
|
||||||
private List<SimilarGRSFRecord> similarGrsfRecords;
|
private List<SimilarGRSFRecord> similarGrsfRecords;
|
||||||
private List<ConnectedBean> connectTo;
|
private List<ConnectedBean> suggestedByKnowledgeBase;
|
||||||
private boolean mergesInvolved;
|
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() {
|
public ManageProductBean() {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ManageProductBean(String semanticIdentifier,
|
public ManageProductBean(
|
||||||
String catalogueIdentifier, String knowledgeBaseIdentifier,
|
String semanticIdentifier,
|
||||||
String grsfType, String grsfDomain, String grsfName,
|
String catalogueIdentifier,
|
||||||
String shortName, boolean traceabilityFlag, Status currentStatus,
|
String knowledgeBaseIdentifier,
|
||||||
Status newStatus, String annotation,
|
String grsfType,
|
||||||
Map<String, String> extrasIfAvailable, List<SourceRecord> sources,
|
String grsfDomain,
|
||||||
List<SimilarGRSFRecord> similarGrsfRecords, List<ConnectedBean> connectedBeans, boolean mergesInvolved) {
|
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();
|
super();
|
||||||
this.semanticIdentifier = semanticIdentifier;
|
this.semanticIdentifier = semanticIdentifier;
|
||||||
this.catalogueIdentifier = catalogueIdentifier;
|
this.catalogueIdentifier = catalogueIdentifier;
|
||||||
|
@ -53,13 +68,12 @@ public class ManageProductBean implements Serializable{
|
||||||
this.shortNameUpdated = shortName;
|
this.shortNameUpdated = shortName;
|
||||||
this.traceabilityFlag = traceabilityFlag;
|
this.traceabilityFlag = traceabilityFlag;
|
||||||
this.currentStatus = currentStatus;
|
this.currentStatus = currentStatus;
|
||||||
this.newStatus = newStatus;
|
|
||||||
this.annotation = annotation;
|
|
||||||
this.extrasIfAvailable = extrasIfAvailable;
|
this.extrasIfAvailable = extrasIfAvailable;
|
||||||
this.sources = sources;
|
this.sources = sources;
|
||||||
this.similarGrsfRecords = similarGrsfRecords;
|
this.similarGrsfRecords = similarGrsfRecords;
|
||||||
this.connectTo = connectedBeans;
|
this.currentConnections = currentConnections;
|
||||||
this.mergesInvolved = mergesInvolved;
|
this.suggestedByKnowledgeBase = suggestedByKnowledgeBase;
|
||||||
|
this.recordUrl = recordUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getSemanticIdentifier() {
|
public String getSemanticIdentifier() {
|
||||||
|
@ -184,12 +198,30 @@ public class ManageProductBean implements Serializable{
|
||||||
this.shortNameUpdated = shortNameUpdated;
|
this.shortNameUpdated = shortNameUpdated;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<ConnectedBean> getConnectTo() {
|
public List<ConnectedBean> getSuggestedByKnowledgeBase() {
|
||||||
return connectTo;
|
return suggestedByKnowledgeBase;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setConnectTo(List<ConnectedBean> connectTo) {
|
public void setSuggestedByKnowledgeBase(
|
||||||
this.connectTo = connectTo;
|
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() {
|
public boolean isMergesInvolved() {
|
||||||
|
@ -200,6 +232,22 @@ public class ManageProductBean implements Serializable{
|
||||||
this.mergesInvolved = mergesInvolved;
|
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
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "ManageProductBean [semanticIdentifier=" + semanticIdentifier
|
return "ManageProductBean [semanticIdentifier=" + semanticIdentifier
|
||||||
|
@ -212,7 +260,12 @@ public class ManageProductBean implements Serializable{
|
||||||
+ currentStatus + ", newStatus=" + newStatus + ", annotation="
|
+ currentStatus + ", newStatus=" + newStatus + ", annotation="
|
||||||
+ annotation + ", extrasIfAvailable=" + extrasIfAvailable
|
+ annotation + ", extrasIfAvailable=" + extrasIfAvailable
|
||||||
+ ", sources=" + sources + ", similarGrsfRecords="
|
+ ", sources=" + sources + ", similarGrsfRecords="
|
||||||
+ similarGrsfRecords + ", connectTo=" + connectTo
|
+ similarGrsfRecords + ", suggestedByKnowledgeBase="
|
||||||
+ ", mergesInvolved=" + mergesInvolved + "]";
|
+ suggestedByKnowledgeBase + ", suggestdByAdministrator="
|
||||||
|
+ suggestdByAdministrator + ", currentConnections="
|
||||||
|
+ currentConnections + ", connections=" + connections
|
||||||
|
+ ", mergesInvolved=" + mergesInvolved + ", recordUrl="
|
||||||
|
+ recordUrl + "]";
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue