Implemented zulip interaction

This commit is contained in:
Luca Frosini 2021-11-23 17:53:37 +01:00
parent d7c6257978
commit 0f3c5e38e0
8 changed files with 304 additions and 77 deletions

View File

@ -247,6 +247,13 @@ public abstract class CKAN {
int responseCode = httpURLConnection.getResponseCode(); int responseCode = httpURLConnection.getResponseCode();
if(responseCode >= Status.BAD_REQUEST.getStatusCode()) { if(responseCode >= Status.BAD_REQUEST.getStatusCode()) {
Status status = Status.fromStatusCode(responseCode); Status status = Status.fromStatusCode(responseCode);
switch (status) {
case NOT_FOUND:
throw new NotFoundException();
default:
break;
}
InputStream inputStream = httpURLConnection.getErrorStream(); InputStream inputStream = httpURLConnection.getErrorStream();
StringBuilder result = HTTPUtility.getStringBuilder(inputStream); StringBuilder result = HTTPUtility.getStringBuilder(inputStream);
logger.trace(result.toString()); logger.trace(result.toString());

View File

@ -256,6 +256,7 @@ public class CKANInstance {
public boolean isModerationEnabled() { public boolean isModerationEnabled() {
return true; return true;
// TODO
// return moderationEnabled; // return moderationEnabled;
} }

View File

@ -195,9 +195,37 @@ public class CKANPackage extends CKAN implements Moderated {
if(jsonNode.has(OWNER_ORG_KEY)) { if(jsonNode.has(OWNER_ORG_KEY)) {
((ObjectNode) jsonNode).remove(OWNER_ORG_KEY); ((ObjectNode) jsonNode).remove(OWNER_ORG_KEY);
} }
// Removing all Content Moderation Keys
if(jsonNode.has(EXTRAS_KEY)) {
ArrayNode extras = (ArrayNode) jsonNode.get(EXTRAS_KEY);
// It is not possible to remove the element of an array while iterating it.
// We need to create a new array only with valie elements;
ArrayNode newExtras = mapper.createArrayNode();
boolean foundOne = false;
for(int i=0; i<extras.size(); i++) {
JsonNode extra = extras.get(i);
if(extra.has(EXTRAS_KEY_KEY) &&
extra.get(EXTRAS_KEY_KEY)!=null &&
extra.get(EXTRAS_KEY_KEY).asText().startsWith(GCatConstants.SYSTEM_CM_PREFIX)) {
foundOne = true;
}else {
newExtras.add(extra.deepCopy());
}
}
if(foundOne) {
((ObjectNode) jsonNode).replace(EXTRAS_KEY, newExtras);
}
}
return jsonNode; return jsonNode;
} }
protected String getAsCleanedString(JsonNode node) {
JsonNode jsonNode = cleanResult(node);
return getAsString(jsonNode);
}
/** /**
* @param json The json to check * @param json The json to check
* @param allowPartialInfo used for patch method which provide only partial information (i.e. the info to patch) * @param allowPartialInfo used for patch method which provide only partial information (i.e. the info to patch)
@ -470,7 +498,7 @@ public class CKANPackage extends CKAN implements Moderated {
if(jsonNode.has(EXTRAS_KEY)) { if(jsonNode.has(EXTRAS_KEY)) {
extras = (ArrayNode) jsonNode.get(EXTRAS_KEY); extras = (ArrayNode) jsonNode.get(EXTRAS_KEY);
for(JsonNode extra : extras) { for(JsonNode extra : extras) {
if(extra.has(EXTRAS_KEY_KEY) && extra.get(EXTRAS_KEY_KEY).asText().compareTo(key) == 0) { if(extra.has(EXTRAS_KEY_KEY) && extra.get(EXTRAS_KEY_KEY)!=null && extra.get(EXTRAS_KEY_KEY).asText().compareTo(key) == 0) {
((ObjectNode) extra).put(EXTRAS_VALUE_KEY, value); ((ObjectNode) extra).put(EXTRAS_VALUE_KEY, value);
found = true; found = true;
break; break;
@ -490,6 +518,19 @@ public class CKANPackage extends CKAN implements Moderated {
return jsonNode; return jsonNode;
} }
protected JsonNode getExtraField(JsonNode jsonNode, String key) {
if(jsonNode.has(EXTRAS_KEY)) {
ArrayNode extras = (ArrayNode) jsonNode.get(EXTRAS_KEY);
for(JsonNode extra : extras) {
if(extra.has(EXTRAS_KEY_KEY) && extra.get(EXTRAS_KEY_KEY)!=null && extra.get(EXTRAS_KEY_KEY).asText().compareTo(key) == 0) {
return extra.get(EXTRAS_VALUE_KEY);
}
}
}
return null;
}
protected String addItemURLViaResolver(JsonNode jsonNode) { protected String addItemURLViaResolver(JsonNode jsonNode) {
// Adding Item URL via Resolver // Adding Item URL via Resolver
URIResolver uriResolver = new URIResolver(); URIResolver uriResolver = new URIResolver();
@ -546,7 +587,6 @@ public class CKANPackage extends CKAN implements Moderated {
protected void readItem() throws Exception { protected void readItem() throws Exception {
String ret = super.read(); String ret = super.read();
result = mapper.readTree(ret); result = mapper.readTree(ret);
result = cleanResult(result);
this.itemID = result.get(ID_KEY).asText(); this.itemID = result.get(ID_KEY).asText();
} }
@ -555,17 +595,13 @@ public class CKANPackage extends CKAN implements Moderated {
public String read() { public String read() {
try { try {
readItem(); readItem();
checkModerationRead(); checkModerationRead();
return getAsCleanedString(result);
return getAsString(result);
} catch(WebApplicationException e) { } catch(WebApplicationException e) {
throw e; throw e;
} catch(Exception e) { } catch(Exception e) {
throw new InternalServerErrorException(e); throw new InternalServerErrorException(e);
} }
} }
// see https://docs.ckan.org/en/latest/api/#ckan.logic.action.create.package_create // see https://docs.ckan.org/en/latest/api/#ckan.logic.action.create.package_create
@ -606,18 +642,17 @@ public class CKANPackage extends CKAN implements Moderated {
ArrayNode created = createResources(resourcesToBeCreated); ArrayNode created = createResources(resourcesToBeCreated);
((ObjectNode) result).replace(RESOURCES_KEY, created); ((ObjectNode) result).replace(RESOURCES_KEY, created);
// Actions performed after a package has been correctly created on ckan.
String title = result.get(TITLE_KEY).asText();
if(ckanInstance.getCurrentScopeBean().is(Type.VRE)) {
sendSocialPost(title, catalogueItemURL);
}
createZulipStream(); createZulipStream();
result = cleanResult(result); if(!isModerationEnabled()) {
if(ckanInstance.getCurrentScopeBean().is(Type.VRE)) {
// Actions performed after a package has been correctly created on ckan.
String title = result.get(TITLE_KEY).asText();
sendSocialPost(title, catalogueItemURL);
}
}
return getAsString(result); return getAsCleanedString(result);
} catch(WebApplicationException e) { } catch(WebApplicationException e) {
rollbackManagedResources(); rollbackManagedResources();
throw e; throw e;
@ -683,11 +718,9 @@ public class CKANPackage extends CKAN implements Moderated {
ckanResource.deleteFile(); ckanResource.deleteFile();
} }
result = cleanResult(result);
postItemUpdatedToStream(); postItemUpdatedToStream();
return getAsString(result); return getAsCleanedString(result);
} catch(WebApplicationException e) { } catch(WebApplicationException e) {
rollbackManagedResources(); rollbackManagedResources();
throw e; throw e;
@ -754,11 +787,9 @@ public class CKANPackage extends CKAN implements Moderated {
ckanResource.deleteFile(); ckanResource.deleteFile();
} }
result = cleanResult(result);
postItemUpdatedToStream(); postItemUpdatedToStream();
return getAsString(result); return getAsCleanedString(result);
} catch(WebApplicationException e) { } catch(WebApplicationException e) {
rollbackManagedResources(); rollbackManagedResources();
throw e; throw e;
@ -854,7 +885,6 @@ public class CKANPackage extends CKAN implements Moderated {
}catch (Exception e) { }catch (Exception e) {
new InternalServerErrorException(e); new InternalServerErrorException(e);
} }
result = cleanResult(result);
} }
return cmItemStatus; return cmItemStatus;
@ -1092,12 +1122,12 @@ public class CKANPackage extends CKAN implements Moderated {
CMItemVisibility cmItemVisibility = null; CMItemVisibility cmItemVisibility = null;
for(JsonNode extra : extras) { for(JsonNode extra : extras) {
if(extra.has(EXTRAS_KEY_KEY) && extra.get(EXTRAS_KEY_KEY).asText().compareTo(GCatConstants.SYSTEM_CM_ITEM_STATUS) == 0) { if(extra.has(EXTRAS_KEY_KEY) && extra.get(EXTRAS_KEY_KEY)!=null && extra.get(EXTRAS_KEY_KEY).asText().compareTo(GCatConstants.SYSTEM_CM_ITEM_STATUS) == 0) {
((ObjectNode) extra).put(EXTRAS_VALUE_KEY, CMItemStatus.APPROVED.getValue()); ((ObjectNode) extra).put(EXTRAS_VALUE_KEY, CMItemStatus.APPROVED.getValue());
approvedSet = true; approvedSet = true;
} }
if(extra.has(EXTRAS_KEY_KEY) && extra.get(EXTRAS_KEY_KEY).asText().compareTo(GCatConstants.SYSTEM_CM_ITEM_VISIBILITY) == 0) { if(extra.has(EXTRAS_KEY_KEY) && extra.get(EXTRAS_KEY_KEY)!=null && extra.get(EXTRAS_KEY_KEY).asText().compareTo(GCatConstants.SYSTEM_CM_ITEM_VISIBILITY) == 0) {
cmItemVisibility = CMItemVisibility.getCMItemStatusFromValue(extra.get(EXTRAS_VALUE_KEY).asText()); cmItemVisibility = CMItemVisibility.getCMItemStatusFromValue(extra.get(EXTRAS_VALUE_KEY).asText());
} }
} }
@ -1164,22 +1194,23 @@ public class CKANPackage extends CKAN implements Moderated {
setToApproved(result); setToApproved(result);
String ret = sendPostRequest(ITEM_PATCH, getAsString(result)); String ret = sendPostRequest(ITEM_PATCH, getAsString(result));
result = mapper.readTree(ret); result = mapper.readTree(ret);
result = cleanResult(result);
zulipStream.setItemCoordinates(itemID, name); zulipStream.setItemCoordinates(itemID, name);
zulipStream.postItemApproved(); zulipStream.postItemApproved(moderatorMessage);
if(moderatorMessage!=null && moderatorMessage.compareTo("")!=0) {
zulipStream.postMessageToStream(CMItemStatus.PENDING, moderatorMessage); if(ckanInstance.getCurrentScopeBean().is(Type.VRE)) {
// Actions performed after a package has been correctly created on ckan.
String title = result.get(TITLE_KEY).asText();
String catalogueItemURL = getExtraField(result, EXTRAS_ITEM_URL_KEY).asText();
sendSocialPost(title, catalogueItemURL);
} }
break; break;
default: default:
break; break;
} }
return getAsCleanedString(result);
return getAsString(result);
} }
throw new MethodNotSupportedException("The approve operation is available only in moderation mode"); throw new MethodNotSupportedException("The approve operation is available only in moderation mode");
}catch(WebApplicationException e) { }catch(WebApplicationException e) {
@ -1212,13 +1243,9 @@ public class CKANPackage extends CKAN implements Moderated {
setToRejected(result); setToRejected(result);
String ret = sendPostRequest(ITEM_PATCH, getAsString(result)); String ret = sendPostRequest(ITEM_PATCH, getAsString(result));
result = mapper.readTree(ret); result = mapper.readTree(ret);
result = cleanResult(result);
zulipStream.setItemCoordinates(itemID, name); zulipStream.setItemCoordinates(itemID, name);
zulipStream.postItemRejected(); zulipStream.postItemRejected(moderatorMessage);
if(moderatorMessage!=null && moderatorMessage.compareTo("")!=0) {
zulipStream.postMessageToStream(CMItemStatus.REJECTED, moderatorMessage);
}
break; break;
default: default:
@ -1227,7 +1254,7 @@ public class CKANPackage extends CKAN implements Moderated {
return getAsString(result); return getAsCleanedString(result);
} }
throw new MethodNotSupportedException("The reject operation is available only in moderation mode"); throw new MethodNotSupportedException("The reject operation is available only in moderation mode");
}catch(WebApplicationException e) { }catch(WebApplicationException e) {
@ -1255,10 +1282,10 @@ public class CKANPackage extends CKAN implements Moderated {
} }
} }
CMItemStatus cmItemStatus = getCMItemStatus(); CMItemStatus cmItemStatus = getCMItemStatus();
zulipStream.setItemCoordinates(itemID, name); zulipStream.setItemCoordinates(itemID, name);
zulipStream.postMessageToStream(cmItemStatus, message); zulipStream.postUserMessageToStream(cmItemStatus, message);
return;
} }
throw new MethodNotSupportedException("The message operation is available only in moderation mode"); throw new MethodNotSupportedException("The message operation is available only in moderation mode");
}catch(WebApplicationException e) { }catch(WebApplicationException e) {

View File

@ -0,0 +1,43 @@
package org.gcube.gcat.zulip;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
/**
* @author Luca Frosini (ISTI - CNR)
*/
public class ZulipAuth {
public static final String ZULIP_RC_FILENAME = "zuliprc";
public static final String EMAIL_KEY = "email";
public static final String KEY_KEY = "key";
public static final String SITE_KEY = "site";
protected final Properties properties;
public ZulipAuth(String username) {
properties = new Properties();
InputStream input = ZulipAuth.class.getClassLoader().getResourceAsStream(username+"_"+ZULIP_RC_FILENAME);
try {
// load the properties file
properties.load(input);
} catch(IOException e) {
throw new RuntimeException(e);
}
}
public String getEmail() {
return properties.getProperty(EMAIL_KEY);
}
public String getAPIKey() {
return properties.getProperty(KEY_KEY);
}
public String getSite() {
return properties.getProperty(SITE_KEY);
}
}

View File

@ -11,7 +11,10 @@ import org.gcube.com.fasterxml.jackson.databind.node.ArrayNode;
import org.gcube.com.fasterxml.jackson.databind.node.ObjectNode; import org.gcube.com.fasterxml.jackson.databind.node.ObjectNode;
import org.gcube.gcat.api.CMItemStatus; import org.gcube.gcat.api.CMItemStatus;
import org.gcube.gcat.persistence.ckan.CKANUser; import org.gcube.gcat.persistence.ckan.CKANUser;
import org.gcube.gcat.utils.Constants;
import org.gcube.gcat.utils.ContextUtility;
import org.gcube.gcat.zulip.ZulipResponse.Result; import org.gcube.gcat.zulip.ZulipResponse.Result;
import org.gcube.storagehub.ApplicationMode;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -28,7 +31,12 @@ public class ZulipStream {
private static final Logger logger = LoggerFactory.getLogger(ZulipStream.class); private static final Logger logger = LoggerFactory.getLogger(ZulipStream.class);
protected final ZulipRestExecutor gCatZulipRestExecutor; public static final String TOPICS_KEY = "topics";
public static final String NAME_KEY = "name";
public static final String MAX_ID_KEY = "max_id";
public static final String INITIAL_TOPIC_NAME = "hello";
protected ZulipRestExecutor gCatZulipRestExecutor;
protected ZulipRestExecutor userZulipRestExecutor; protected ZulipRestExecutor userZulipRestExecutor;
protected String itemID; protected String itemID;
@ -38,23 +46,31 @@ public class ZulipStream {
protected String streamDescription; protected String streamDescription;
protected CKANUser ckanUser; protected CKANUser ckanUser;
protected Set<String> moderators;
protected ObjectMapper objectMapper; protected ObjectMapper objectMapper;
protected ZulipRestExecutor getZulipRestExecutor() {
ZulipAuth zulipAuth = new ZulipAuth(ContextUtility.getUsername());
return new ZulipRestExecutor(zulipAuth.getEmail(), zulipAuth.getAPIKey(), zulipAuth.getSite());
}
public ZulipStream() { public ZulipStream() {
// TODO Get gcat email and API key from configuration
// TODO Get zulip URL from configuration
this.gCatZulipRestExecutor = new ZulipRestExecutor("gcat@d4science.com", "apikey", "https://zulip.example.com/");
this.objectMapper = new ObjectMapper(); this.objectMapper = new ObjectMapper();
this.moderators = new HashSet<>(); }
public ZulipRestExecutor getGCatZulipRestExecutor() {
if(gCatZulipRestExecutor==null) {
ApplicationMode applicationMode = new ApplicationMode(Constants.getCatalogueApplicationToken());
applicationMode.start();
gCatZulipRestExecutor = getZulipRestExecutor();
applicationMode.end();
}
return gCatZulipRestExecutor;
} }
public ZulipRestExecutor getUserZulipRestExecutor() { public ZulipRestExecutor getUserZulipRestExecutor() {
if(userZulipRestExecutor==null) { if(userZulipRestExecutor==null) {
// TODO get API key ?? userZulipRestExecutor = getZulipRestExecutor();
// TODO Get zulip URL from configuration
userZulipRestExecutor = new ZulipRestExecutor(ckanUser.getPortalUser().getEMail(), "apikey", "https://zulip.example.com/");
} }
return userZulipRestExecutor; return userZulipRestExecutor;
} }
@ -70,27 +86,29 @@ public class ZulipStream {
protected String getStreamName() { protected String getStreamName() {
if(streamName==null) { if(streamName==null) {
streamName = String.format("Item '{}' with id '{}' moderation", itemName, itemID); streamName = String.format("Item '%s' moderation", itemID);
} }
return streamName; return streamName;
} }
protected Integer getStreamID() throws Exception { protected Integer getStreamID() throws Exception {
GetStreamID getStreamID = new GetStreamID(getStreamName()); GetStreamID getStreamID = new GetStreamID(getStreamName());
ZulipResponse zulipResponse = executeZulipCall(getStreamID); ZulipResponse zulipResponse = executeZulipCall(gCatZulipRestExecutor, getStreamID);
JsonNode response = zulipResponse.getResponse(); JsonNode response = zulipResponse.getResponse();
return response.get("stream_id").asInt(); return response.get("stream_id").asInt();
} }
protected String getStreamDescription() { protected String getStreamDescription() {
if(streamDescription==null) { if(streamDescription==null) {
streamDescription = String.format("This stream is used to discuss about the moderation of the item '{}' with id '{}'", itemName, itemID); streamDescription = String.format("This stream is used to discuss about the moderation of the item '%s' with id '%s'", itemName, itemID);
} }
return streamDescription; return streamDescription;
} }
protected ZulipResponse executeZulipCall(ZulipRestAPICall call) throws Exception { protected ZulipResponse executeZulipCall(ZulipRestExecutor zulipRestExecutor, ZulipRestAPICall call) throws Exception {
String responseString = gCatZulipRestExecutor.executeCall(call); logger.trace("Going to execute {}", call);
String responseString = zulipRestExecutor.executeCall(call);
logger.trace("Response from {} is {}", call.getClass().getSimpleName(), responseString);
ZulipResponse zulipResponse = new ZulipResponse(responseString); ZulipResponse zulipResponse = new ZulipResponse(responseString);
if(zulipResponse.getResponseResult()==Result.error) { if(zulipResponse.getResponseResult()==Result.error) {
throw new InternalServerErrorException(zulipResponse.getResponseMessage()); throw new InternalServerErrorException(zulipResponse.getResponseMessage());
@ -98,6 +116,24 @@ public class ZulipStream {
return zulipResponse; return zulipResponse;
} }
protected void renameInitialHelloTopic() throws Exception {
// TODO check if it is possible
/*
Integer streamID = getStreamID();
GetAllTopicsOfAStream getAllTopicsOfAStream = new GetAllTopicsOfAStream(streamID.toString());
ZulipResponse zulipResponse = executeZulipCall(gCatZulipRestExecutor, getAllTopicsOfAStream);
JsonNode jsonNode = zulipResponse.getResponse();
ArrayNode arrayNode = (ArrayNode) jsonNode.get(TOPICS_KEY);
String initialTopicID = null;
for(JsonNode node : arrayNode) {
if(node.get(NAME_KEY).asText().compareTo(INITIAL_TOPIC_NAME)==0) {
initialTopicID = node.get(MAX_ID_KEY).asText();
}
}
*/
}
public void create() throws Exception { public void create() throws Exception {
ArrayNode streamsArrayNode = objectMapper.createArrayNode(); ArrayNode streamsArrayNode = objectMapper.createArrayNode();
ObjectNode streamobjectNode = objectMapper.createObjectNode(); ObjectNode streamobjectNode = objectMapper.createObjectNode();
@ -109,7 +145,12 @@ public class ZulipStream {
// Going to add the item creator // Going to add the item creator
String itemCreatorEmail = ckanUser.getPortalUser().getEMail(); String itemCreatorEmail = ckanUser.getPortalUser().getEMail();
principalsArrayNode.add(itemCreatorEmail); principalsArrayNode.add(itemCreatorEmail);
getGCatZulipRestExecutor();
principalsArrayNode.add(gCatZulipRestExecutor.httpController.getUserName());
// Going to add the catalogue moderators // Going to add the catalogue moderators
Set<String> moderators = getCatalogueModerators();
for(String moderator : moderators) { for(String moderator : moderators) {
principalsArrayNode.add(moderator); principalsArrayNode.add(moderator);
} }
@ -119,41 +160,62 @@ public class ZulipStream {
postCreateStream.setInvite_only(true); postCreateStream.setInvite_only(true);
postCreateStream.setAnnounce(false); postCreateStream.setAnnounce(false);
executeZulipCall(postCreateStream); executeZulipCall(gCatZulipRestExecutor, postCreateStream);
renameInitialHelloTopic();
postItemCreated(); postItemCreated();
} }
protected void postMessageToStream(ZulipRestExecutor zulipRestExecutor, CMItemStatus cmItemStatus, String message) { private Set<String> getCatalogueModerators() {
Set<String> moderators = new HashSet<>();
moderators.add("pasquale.pagano@isti.cnr.it");
moderators.add("leonardo.candela@isti.cnr.it");
return moderators;
}
protected void postMessageToStream(ZulipRestExecutor zulipRestExecutor, CMItemStatus cmItemStatus, String message) throws Exception {
PostMessage postMessage = new PostMessage(getStreamName(), cmItemStatus.getFancyValue(), message); PostMessage postMessage = new PostMessage(getStreamName(), cmItemStatus.getFancyValue(), message);
String response = zulipRestExecutor.executeCall(postMessage); logger.debug("Going to send the following message: {}", message);
logger.trace(response); executeZulipCall(zulipRestExecutor, postMessage);
} }
public void postMessageToStream(CMItemStatus cmItemStatus, String message) { public void postUserMessageToStream(CMItemStatus cmItemStatus, String message) throws Exception {
postMessageToStream(getUserZulipRestExecutor(), cmItemStatus, message); postMessageToStream(getUserZulipRestExecutor(), cmItemStatus, message);
} }
public void postItemCreated(){ private void postItemCreated() throws Exception{
String message = ""; String username = ckanUser.getPortalUser().getNameSurname();
postMessageToStream(gCatZulipRestExecutor, CMItemStatus.PENDING, message); CMItemStatus cmItemStatus = CMItemStatus.PENDING;
String message = String.format("@**%s** has created the item with name '%s' (id='%s'). The item is now in **%s** state and must be moderated.",
username, itemName, itemID, cmItemStatus.getFancyValue());
postMessageToStream(getGCatZulipRestExecutor(), cmItemStatus, message);
} }
public void postItemUpdated(){ public void postItemUpdated() throws Exception{
String message = ""; String username = ckanUser.getPortalUser().getNameSurname();
postMessageToStream(gCatZulipRestExecutor, CMItemStatus.PENDING, message); CMItemStatus cmItemStatus = CMItemStatus.PENDING;
String message = String.format("@**%s** has updated the item with name '%s' (id='%s'). The item is now in **%s** state and must be moderated.",
username, itemName, itemID, cmItemStatus.getFancyValue());
postMessageToStream(getGCatZulipRestExecutor(), cmItemStatus, message);
} }
public void postItemRejected() { public void postItemRejected(String userMessage) throws Exception {
String message = ""; String username = ckanUser.getPortalUser().getNameSurname();
postMessageToStream(gCatZulipRestExecutor, CMItemStatus.REJECTED, message); CMItemStatus cmItemStatus = CMItemStatus.REJECTED;
String message = String.format("@**%s** has **%s** the item with name '%s' (id='%s'). The author can delete the item or update it to try to meet moderators requests if any.",
username, cmItemStatus.getFancyValue(), itemName, itemID);
postMessageToStream(getGCatZulipRestExecutor(), cmItemStatus, message);
postUserMessageToStream(cmItemStatus, userMessage);
} }
public void postItemApproved(){ public void postItemApproved(String userMessage) throws Exception{
String message = ""; String username = ckanUser.getPortalUser().getNameSurname();
postMessageToStream(gCatZulipRestExecutor, CMItemStatus.PENDING, message); CMItemStatus cmItemStatus = CMItemStatus.APPROVED;
String message = String.format("@**%s** has **%s** the item with name '%s' (id='%s'). The item is now available in the catalogue.",
username, cmItemStatus.getFancyValue(), itemName, itemID);
postMessageToStream(getGCatZulipRestExecutor(), cmItemStatus, message);
postUserMessageToStream(cmItemStatus, userMessage);
} }
} }

View File

@ -31,7 +31,11 @@ public class ContextTest {
protected static Properties properties; protected static Properties properties;
protected static final String PROPERTIES_FILENAME = "token.properties"; protected static final String PROPERTIES_FILENAME = "token.properties";
public static final String DEFAULT_TEST_SCOPE_NAME; public static final String PARENT_DEFAULT_TEST_SCOPE;
public static final String DEFAULT_TEST_SCOPE;
public static final String ALTERNATIVE_TEST_SCOPE;
public static final String DEV_VRE;
static { static {
properties = new Properties(); properties = new Properties();
@ -45,7 +49,13 @@ public class ContextTest {
} }
//DEFAULT_TEST_SCOPE_NAME = "/pred4s/preprod/preVRE"; //DEFAULT_TEST_SCOPE_NAME = "/pred4s/preprod/preVRE";
DEFAULT_TEST_SCOPE_NAME = "/gcube/devsec/devVRE"; // DEFAULT_TEST_SCOPE_NAME = "/gcube/devsec/devVRE";
PARENT_DEFAULT_TEST_SCOPE = "/gcube";
DEFAULT_TEST_SCOPE = PARENT_DEFAULT_TEST_SCOPE + "/devsec";
ALTERNATIVE_TEST_SCOPE = DEFAULT_TEST_SCOPE + "/devVRE";
DEV_VRE = ALTERNATIVE_TEST_SCOPE;
} }
public static String getCurrentContextFullName() { public static String getCurrentContextFullName() {
@ -83,7 +93,7 @@ public class ContextTest {
@BeforeClass @BeforeClass
public static void beforeClass() throws Exception { public static void beforeClass() throws Exception {
setContextByName(DEFAULT_TEST_SCOPE_NAME); setContextByName(DEFAULT_TEST_SCOPE);
} }
@AfterClass @AfterClass

View File

@ -1,5 +1,7 @@
package org.gcube.gcat.persistence.ckan; package org.gcube.gcat.persistence.ckan;
import static org.gcube.common.authorization.client.Constants.authorizationService;
import java.io.StringWriter; import java.io.StringWriter;
import java.net.URI; import java.net.URI;
import java.util.ArrayList; import java.util.ArrayList;
@ -9,6 +11,7 @@ import java.util.Map;
import java.util.Set; import java.util.Set;
import javax.ws.rs.ForbiddenException; import javax.ws.rs.ForbiddenException;
import javax.ws.rs.NotFoundException;
import javax.ws.rs.core.MultivaluedHashMap; import javax.ws.rs.core.MultivaluedHashMap;
import javax.ws.rs.core.MultivaluedMap; import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.PathSegment; import javax.ws.rs.core.PathSegment;
@ -16,6 +19,7 @@ import javax.ws.rs.core.UriBuilder;
import javax.ws.rs.core.UriInfo; import javax.ws.rs.core.UriInfo;
import org.gcube.common.authorization.client.exceptions.ObjectNotFound; import org.gcube.common.authorization.client.exceptions.ObjectNotFound;
import org.gcube.common.authorization.library.provider.UserInfo;
import org.gcube.common.resources.gcore.GenericResource; import org.gcube.common.resources.gcore.GenericResource;
import org.gcube.common.resources.gcore.Resources; import org.gcube.common.resources.gcore.Resources;
import org.gcube.common.scope.impl.ScopeBean; import org.gcube.common.scope.impl.ScopeBean;
@ -562,4 +566,73 @@ public class CKANPackageTest extends ContextTest {
ckanPackage.update("{\"rating\": 0.0, \"license_title\": \"Academic Free License 3.0\", \"maintainer\": \"Kerekes Kata\", \"relationships_as_object\": [], \"private\": false, \"maintainer_email\": \"kerekeska@nebih.gov.hu\", \"num_tags\": 1, \"id\": \"7731b70f-47ff-4b74-b943-188215e82d07\", \"metadata_created\": \"2020-01-07T16:40:24.822719\", \"owner_org\": \"3571cca5-b0ae-4dc6-b791-434a8e062ce5\", \"metadata_modified\": \"2020-02-03T15:16:42.596068\", \"author\": \"Kerekes Kata\", \"author_email\": \"kerekeska@nebih.gov.hu\", \"state\": \"active\", \"version\": \"1\", \"license_id\": \"AFL-3.0\", \"type\": \"dataset\", \"resources\": [{\"cache_last_updated\": null, \"cache_url\": null, \"mimetype_inner\": null, \"hash\": \"\", \"description\": \"\", \"format\": \"JPEG\", \"url\": \"https://goo.gl/SnwAM7\", \"created\": \"2019-04-01T13:24:40.738838\", \"state\": \"active\", \"package_id\": \"7731b70f-47ff-4b74-b943-188215e82d07\", \"last_modified\": null, \"mimetype\": \"image/jpeg\", \"url_type\": null, \"position\": 0, \"revision_id\": \"06d61000-a0c1-4155-ad2d-78ede56d6bb5\", \"size\": null, \"datastore_active\": false, \"id\": \"1de8851d-1385-47ae-9c93-6040d170a9cc\", \"resource_type\": null, \"name\": \"th.jpeg\"}], \"num_resources\": 1, \"tags\": [{\"vocabulary_id\": null, \"state\": \"active\", \"display_name\": \"DEMETER\", \"id\": \"4e05058b-a006-4dbf-94f5-277a30318323\", \"name\": \"DEMETER\"}], \"groups\": [], \"creator_user_id\": \"7020f836-45f4-4ee8-9c65-e7504209644f\", \"relationships_as_subject\": [], \"name\": \"vre_picture\", \"isopen\": true, \"url\": \"\", \"notes\": \"This is a nice picture of a VRE ;)\", \"title\": \"VRE picture\", \"extras\": [{\"value\": \"https://data.d4science.org/ctlg/DEMETER_trial/vre_picture\", \"key\": \"Item URL\"}, {\"value\": \"ResearchObject\", \"key\": \"system:type\"}], \"license_url\": \"https://www.opensource.org/licenses/AFL-3.0\", \"ratings_count\": 0, \"organization\": {\"description\": \"\", \"title\": \"devVRE\", \"created\": \"2016-05-30T11:30:41.710079\", \"approval_status\": \"approved\", \"is_organization\": true, \"state\": \"active\", \"image_url\": \"\", \"revision_id\": \"7c8463df-ed3f-4d33-87d8-6c0bcbe30d5d\", \"type\": \"organization\", \"id\": \"3571cca5-b0ae-4dc6-b791-434a8e062ce5\", \"name\": \"devvre\"}, \"revision_id\": \"bdb6169a-6268-43d6-b7e1-265c0c9e1a1c\"}"); ckanPackage.update("{\"rating\": 0.0, \"license_title\": \"Academic Free License 3.0\", \"maintainer\": \"Kerekes Kata\", \"relationships_as_object\": [], \"private\": false, \"maintainer_email\": \"kerekeska@nebih.gov.hu\", \"num_tags\": 1, \"id\": \"7731b70f-47ff-4b74-b943-188215e82d07\", \"metadata_created\": \"2020-01-07T16:40:24.822719\", \"owner_org\": \"3571cca5-b0ae-4dc6-b791-434a8e062ce5\", \"metadata_modified\": \"2020-02-03T15:16:42.596068\", \"author\": \"Kerekes Kata\", \"author_email\": \"kerekeska@nebih.gov.hu\", \"state\": \"active\", \"version\": \"1\", \"license_id\": \"AFL-3.0\", \"type\": \"dataset\", \"resources\": [{\"cache_last_updated\": null, \"cache_url\": null, \"mimetype_inner\": null, \"hash\": \"\", \"description\": \"\", \"format\": \"JPEG\", \"url\": \"https://goo.gl/SnwAM7\", \"created\": \"2019-04-01T13:24:40.738838\", \"state\": \"active\", \"package_id\": \"7731b70f-47ff-4b74-b943-188215e82d07\", \"last_modified\": null, \"mimetype\": \"image/jpeg\", \"url_type\": null, \"position\": 0, \"revision_id\": \"06d61000-a0c1-4155-ad2d-78ede56d6bb5\", \"size\": null, \"datastore_active\": false, \"id\": \"1de8851d-1385-47ae-9c93-6040d170a9cc\", \"resource_type\": null, \"name\": \"th.jpeg\"}], \"num_resources\": 1, \"tags\": [{\"vocabulary_id\": null, \"state\": \"active\", \"display_name\": \"DEMETER\", \"id\": \"4e05058b-a006-4dbf-94f5-277a30318323\", \"name\": \"DEMETER\"}], \"groups\": [], \"creator_user_id\": \"7020f836-45f4-4ee8-9c65-e7504209644f\", \"relationships_as_subject\": [], \"name\": \"vre_picture\", \"isopen\": true, \"url\": \"\", \"notes\": \"This is a nice picture of a VRE ;)\", \"title\": \"VRE picture\", \"extras\": [{\"value\": \"https://data.d4science.org/ctlg/DEMETER_trial/vre_picture\", \"key\": \"Item URL\"}, {\"value\": \"ResearchObject\", \"key\": \"system:type\"}], \"license_url\": \"https://www.opensource.org/licenses/AFL-3.0\", \"ratings_count\": 0, \"organization\": {\"description\": \"\", \"title\": \"devVRE\", \"created\": \"2016-05-30T11:30:41.710079\", \"approval_status\": \"approved\", \"is_organization\": true, \"state\": \"active\", \"image_url\": \"\", \"revision_id\": \"7c8463df-ed3f-4d33-87d8-6c0bcbe30d5d\", \"type\": \"organization\", \"id\": \"3571cca5-b0ae-4dc6-b791-434a8e062ce5\", \"name\": \"devvre\"}, \"revision_id\": \"bdb6169a-6268-43d6-b7e1-265c0c9e1a1c\"}");
} }
@Test
public void generateLinoTokenModeration() throws Exception {
UserInfo userInfo = new UserInfo("leonardo.candela", new ArrayList<>());
String userToken = authorizationService().generateUserToken(userInfo, ALTERNATIVE_TEST_SCOPE);
logger.debug(userToken);
}
@Test
public void testModeration() throws Exception {
ContextTest.setContextByName(DEV_VRE);
CKANPackage ckanPackage = new CKANPackage();
ckanPackage.setName(ITEM_NAME_VALUE);
try {
ckanPackage.purge();
}catch (NotFoundException e) {
logger.trace("The item does not exist. This is correct");
}
ObjectMapper mapper = new ObjectMapper();
createPackage(mapper);
ContextTest.setContextByName("leonardo.candela_"+DEV_VRE);
ckanPackage = new CKANPackage();
ckanPackage.setName(ITEM_NAME_VALUE);
ckanPackage.message("Please add the notes.");
ContextTest.setContextByName(DEV_VRE);
ckanPackage = new CKANPackage();
ckanPackage.setName(ITEM_NAME_VALUE);
String readItem = ckanPackage.read();
JsonNode readItemObjectNode = mapper.readTree(readItem);
String updatedNotes = "A research of Luca Frosini made during the PhD";
((ObjectNode) readItemObjectNode).put(NOTES_KEY, updatedNotes);
ckanPackage.update(mapper.writeValueAsString(readItemObjectNode));
ckanPackage.message("I hope now it can be approved.");
ContextTest.setContextByName("leonardo.candela_"+DEV_VRE);
ckanPackage = new CKANPackage();
ckanPackage.setName(ITEM_NAME_VALUE);
ckanPackage.reject("You must specify the institution.");
ContextTest.setContextByName(DEV_VRE);
ckanPackage = new CKANPackage();
ckanPackage.setName(ITEM_NAME_VALUE);
readItem = ckanPackage.read();
readItemObjectNode = mapper.readTree(readItem);
updatedNotes = "A research of Luca Frosini at ISTI";
((ObjectNode) readItemObjectNode).put(NOTES_KEY, updatedNotes);
ckanPackage.update(mapper.writeValueAsString(readItemObjectNode));
ContextTest.setContextByName("pasquale.pagano_"+DEV_VRE);
ckanPackage = new CKANPackage();
ckanPackage.setName(ITEM_NAME_VALUE);
ckanPackage.approve("It seems fine now");
// ContextTest.setContextByName(DEV_VRE);
// ckanPackage = new CKANPackage();
// ckanPackage.setName(ITEM_NAME_VALUE);
// ckanPackage.purge();
}
} }

View File

@ -1,2 +1,6 @@
/*.gcubekey /*.gcubekey
/*.properties /*.properties
/gCat_zuliprc
/leonardo.candela_zuliprc
/luca.frosini_zuliprc
/pasquale.pagano_zuliprc