diff --git a/CHANGELOG.md b/CHANGELOG.md index ee9b6ef..d9ea252 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm - Migrated to ServiceClass corresponding to Maven groupId - Added Enunciate to automatically create REST APIs documentation [#23096] - Fixed offset behaviuor in item listing [#22999] - +- Moderation message are sent using gcube messaging system via Social Service [#23117] ## [v2.1.0] @@ -26,7 +26,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm ## [v2.0.0] [r5.2.0] - 2021-05-04 - Fixed retrieving of filename from content-disposition http header used to persist a resource [#21216] -- Fixed author and maintainer name and email [#21059] [#21189] +- Fixed author and maintainer name and email [#21059][#21189] - Improved check on controlled vocabulary to match corner cases [#20742] - Added PATCH method on Item collection [#19768] - Switched JSON management to gcube-jackson [#19735] diff --git a/src/main/java/org/gcube/gcat/moderation/thread/ModerationThread.java b/src/main/java/org/gcube/gcat/moderation/thread/ModerationThread.java index 3018e02..ef3f621 100644 --- a/src/main/java/org/gcube/gcat/moderation/thread/ModerationThread.java +++ b/src/main/java/org/gcube/gcat/moderation/thread/ModerationThread.java @@ -12,8 +12,11 @@ public abstract class ModerationThread { protected String itemID; protected String itemName; + protected String itemTitle; protected String itemURL; + protected boolean itemAuthor; + protected CKANUser ckanUser; protected ObjectMapper objectMapper; @@ -24,14 +27,24 @@ public abstract class ModerationThread { public ModerationThread() { this.objectMapper = new ObjectMapper(); + itemAuthor = false; } - public void setItemCoordinates(String itemID, String itemName, String itemURL) { + public void setItemCoordinates(String itemID, String itemName, String itemTitle, String itemURL) { this.itemID = itemID; this.itemName = itemName; + this.itemTitle = itemTitle; this.itemURL = itemURL; } + public boolean isItemAuthor() { + return itemAuthor; + } + + public void setItemAuthor(boolean itemAuthor) { + this.itemAuthor = itemAuthor; + } + public void setCKANUser(CKANUser ckanUser) { this.ckanUser = ckanUser; } @@ -58,9 +71,7 @@ public abstract class ModerationThread { createModerationThread(); String fullName = ckanUser.getNameSurname(); CMItemStatus cmItemStatus = CMItemStatus.PENDING; -// String message = String.format("@**%s** created the item with name '%s' (id='%s'). The item is now in **%s** state and must be moderated.", -// username, itemName, itemID, cmItemStatus.getFancyValue()); - String message = String.format("%s created the item with name '%s' (id='%s'). The item is now in %s state and must be moderated.", + String message = String.format("@**%s** created the item with name '%s' (id='%s'). The item is now in **%s** state and must be moderated.", fullName, itemName, itemID, cmItemStatus.getFancyValue()); postMessage(cmItemStatus, message); } @@ -68,19 +79,15 @@ public abstract class ModerationThread { public void postItemUpdated() throws Exception { String fullName = ckanUser.getNameSurname(); CMItemStatus cmItemStatus = CMItemStatus.PENDING; -// String message = String.format("@**%s** updated the item with name '%s' (id='%s'). The item is now in **%s** state and must be moderated.", -// username, itemName, itemID, cmItemStatus.getFancyValue()); - String message = String.format("%s updated the item with name '%s' (id='%s'). The item is now in %s state and must be moderated.", - fullName, itemName, itemID, cmItemStatus.getFancyValue(), itemURL); + String message = String.format("@**%s** updated the item with name '%s' (id='%s'). The item is now in **%s** state and must be moderated.", + fullName, itemName, itemID, cmItemStatus.getFancyValue()); postMessage(cmItemStatus, message); } public void postItemRejected(String userMessage) throws Exception { String fullName = ckanUser.getNameSurname(); CMItemStatus cmItemStatus = CMItemStatus.REJECTED; -// String message = String.format("@**%s** **%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,); - String message = String.format("%s %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.", + String message = String.format("@**%s** **%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.", fullName, cmItemStatus.getFancyValue(), itemName, itemID); postMessage(cmItemStatus, message); postUserMessage(cmItemStatus, userMessage); @@ -89,9 +96,7 @@ public abstract class ModerationThread { public void postItemApproved(String userMessage) throws Exception{ String fullName = ckanUser.getNameSurname(); CMItemStatus cmItemStatus = CMItemStatus.APPROVED; -// String message = String.format("@**%s** **%s** the item with name '%s' (id='%s'). The item is now available in the catalogue. The item is available at %s", -// username, cmItemStatus.getFancyValue(), itemName, itemID, itemURL); - String message = String.format("%s %s the item with name '%s' (id='%s'). The item is now available in the catalogue. The item is available at %s", + String message = String.format("@**%s** **%s** the item with name '%s' (id='%s'). The item is now available in the catalogue. The item is available at %s", fullName, cmItemStatus.getFancyValue(), itemName, itemID, itemURL); postMessage(cmItemStatus, message); postUserMessage(cmItemStatus, userMessage); diff --git a/src/main/java/org/gcube/gcat/moderation/thread/social/SocialMessageModerationThread.java b/src/main/java/org/gcube/gcat/moderation/thread/social/SocialMessageModerationThread.java index 8234e9c..44b3e99 100644 --- a/src/main/java/org/gcube/gcat/moderation/thread/social/SocialMessageModerationThread.java +++ b/src/main/java/org/gcube/gcat/moderation/thread/social/SocialMessageModerationThread.java @@ -23,13 +23,124 @@ public class SocialMessageModerationThread extends ModerationThread { private static final Logger logger = LoggerFactory.getLogger(SocialMessageModerationThread.class); + protected StringBuffer getMainItemInfo(CMItemStatus cmItemStatus) { + StringBuffer stringBuffer = new StringBuffer(); + stringBuffer.append("Status: "); + stringBuffer.append(cmItemStatus.getFancyValue()); + stringBuffer.append("\n"); + stringBuffer.append("Title: "); + stringBuffer.append(itemTitle); + stringBuffer.append("\n"); + stringBuffer.append("Name: "); + stringBuffer.append(itemName); + stringBuffer.append("\n"); + stringBuffer.append("ID: "); + stringBuffer.append(itemID); + stringBuffer.append("\n"); + stringBuffer.append("URL: "); + stringBuffer.append(itemURL); + stringBuffer.append("\n\n"); + return stringBuffer; + } + + public void postItemCreated() throws Exception{ + String fullName = ckanUser.getNameSurname(); + CMItemStatus cmItemStatus = CMItemStatus.PENDING; + StringBuffer stringBuffer = getMainItemInfo(cmItemStatus); + + stringBuffer.append("Message:\n"); + stringBuffer.append(fullName); + stringBuffer.append(" created '"); + stringBuffer.append(itemTitle); + stringBuffer.append("'. It is now in "); + stringBuffer.append(cmItemStatus.getFancyValue()); + stringBuffer.append(" state and must be moderated."); + + postMessage(cmItemStatus, stringBuffer.toString()); + + } + + public void postItemUpdated() throws Exception { + String fullName = ckanUser.getNameSurname(); + CMItemStatus cmItemStatus = CMItemStatus.PENDING; + StringBuffer stringBuffer = getMainItemInfo(cmItemStatus); + + stringBuffer.append("Message:\n"); + stringBuffer.append(fullName); + stringBuffer.append(" updated '"); + stringBuffer.append(itemTitle); + stringBuffer.append("'. It is now in "); + stringBuffer.append(cmItemStatus.getFancyValue()); + stringBuffer.append(" state and must be moderated."); + + postMessage(cmItemStatus, stringBuffer.toString()); + } + + protected StringBuffer addUserWithRole(String fullName, String role, StringBuffer stringBuffer) { + stringBuffer.append(fullName); + stringBuffer.append(" ["); + stringBuffer.append(role); + stringBuffer.append("] "); + return stringBuffer; + } + + public void postItemRejected(String userMessage) throws Exception { + String fullName = ckanUser.getNameSurname(); + CMItemStatus cmItemStatus = CMItemStatus.REJECTED; + + StringBuffer stringBuffer = getMainItemInfo(cmItemStatus); + + stringBuffer.append("Message:\n"); + stringBuffer = addUserWithRole(fullName, Moderated.CATALOGUE_MODERATOR, stringBuffer); + stringBuffer.append("rejected '"); + stringBuffer.append(itemTitle); + stringBuffer.append("'."); + stringBuffer.append(" The author can delete or update it."); + + if(userMessage!=null && userMessage.length()>0) { + stringBuffer.append("\n\n"); + stringBuffer = addUserWithRole(fullName, Moderated.CATALOGUE_MODERATOR, stringBuffer); + stringBuffer.append("added the following comment:\n"); + stringBuffer.append(userMessage); + } + + postMessage(cmItemStatus, stringBuffer.toString()); + } + + public void postItemApproved(String userMessage) throws Exception{ + String fullName = ckanUser.getNameSurname(); + CMItemStatus cmItemStatus = CMItemStatus.APPROVED; + + StringBuffer stringBuffer = getMainItemInfo(cmItemStatus); + + stringBuffer.append("Message:\n"); + stringBuffer = addUserWithRole(fullName, Moderated.CATALOGUE_MODERATOR, stringBuffer); + stringBuffer.append("approved the '"); + stringBuffer.append(itemTitle); + stringBuffer.append("'."); + stringBuffer.append(" It is now available in the catalogue at "); + stringBuffer.append(itemURL); + + if(userMessage!=null && userMessage.length()>0) { + stringBuffer.append("\n\n"); + stringBuffer = addUserWithRole(fullName, Moderated.CATALOGUE_MODERATOR, stringBuffer); + stringBuffer.append("added the following comment:\n"); + stringBuffer.append(userMessage); + } + + postMessage(cmItemStatus, stringBuffer.toString()); + } + + protected String getSubject(CMItemStatus cmItemStatus) { StringWriter stringWriter = new StringWriter(); + stringWriter.append("[Catalogue Service] "); + stringWriter.append(itemTitle); + stringWriter.append(" (name:"); stringWriter.append(itemName); - stringWriter.append(" (id:"); + stringWriter.append(" - id:"); stringWriter.append(itemID); - stringWriter.append(") - status:"); - stringWriter.append(cmItemStatus.getFancyValue()); + stringWriter.append(")"); return stringWriter.toString(); } @@ -59,10 +170,22 @@ public class SocialMessageModerationThread extends ModerationThread { @Override public void postUserMessage(CMItemStatus cmItemStatus, String userMessage) throws Exception { - Message message = getMessage(cmItemStatus, userMessage); - String itemAuthor = ckanUser.getEMail(); - message.addUser(itemAuthor); - sendMessage(message); + String fullName = ckanUser.getNameSurname(); + StringBuffer stringBuffer = getMainItemInfo(cmItemStatus); + stringBuffer = addUserWithRole(fullName, isItemAuthor() ? "Author" : Moderated.CATALOGUE_MODERATOR, stringBuffer); + stringBuffer.append("sent the following comment:\n"); + stringBuffer.append(userMessage); + Message message = getMessage(cmItemStatus, stringBuffer.toString()); + SecretManager secretManager = SecretManagerProvider.instance.get(); + String username = secretManager.getUser().getUsername(); + message.addUser(username); + Secret secret = Constants.getCatalogueSecret(); + secretManager.startSession(secret); + try { + sendMessage(message); + }finally { + secretManager.endSession(); + } } protected void sendMessage(Message message) throws Exception { diff --git a/src/main/java/org/gcube/gcat/persistence/ckan/CKAN.java b/src/main/java/org/gcube/gcat/persistence/ckan/CKAN.java index e5edcb2..8190dc8 100644 --- a/src/main/java/org/gcube/gcat/persistence/ckan/CKAN.java +++ b/src/main/java/org/gcube/gcat/persistence/ckan/CKAN.java @@ -35,6 +35,7 @@ public abstract class CKAN { private static final Logger logger = LoggerFactory.getLogger(CKAN.class); protected static final String ID_KEY = "id"; + protected static final String TITLE_KEY = "title"; protected static final String NAME_KEY = "name"; protected static final String ERROR_KEY = "error"; diff --git a/src/main/java/org/gcube/gcat/persistence/ckan/CKANPackage.java b/src/main/java/org/gcube/gcat/persistence/ckan/CKANPackage.java index 661e6ea..b19b124 100644 --- a/src/main/java/org/gcube/gcat/persistence/ckan/CKANPackage.java +++ b/src/main/java/org/gcube/gcat/persistence/ckan/CKANPackage.java @@ -118,6 +118,7 @@ public class CKANPackage extends CKAN implements Moderated { protected final List managedResources; protected String itemID; + protected String itemTitle; protected String itemURL; protected final CKANUser ckanUser; @@ -383,6 +384,8 @@ public class CKANPackage extends CKAN implements Moderated { this.name = null; this.result = null; this.itemID = null; + this.itemURL = null; + this.itemTitle = null; } /** @@ -669,7 +672,7 @@ public class CKANPackage extends CKAN implements Moderated { return itemURL; } - protected void sendSocialPost(String title) { + protected void sendSocialPost() { try { boolean makePost = false; try { @@ -686,8 +689,8 @@ public class CKANPackage extends CKAN implements Moderated { SocialPost socialPost = new SocialPost(); socialPost.setItemID(itemID); socialPost.setItemURL(itemURL); + socialPost.setItemTitle(itemTitle); socialPost.setTags(arrayNode); - socialPost.setItemTitle(title); Boolean notification = null; try { @@ -714,15 +717,21 @@ public class CKANPackage extends CKAN implements Moderated { return result.get(AUTHOR_EMAIL_KEY).asText().compareTo(ckanUser.getEMail())==0; } + protected void parseResult() { + if(this.itemID == null) { + this.itemID = result.get(ID_KEY).asText(); + } + this.itemTitle = result.get(TITLE_KEY).asText(); + this.itemURL = getExtraField(result, EXTRAS_ITEM_URL_KEY).asText(); + } + + protected void readItem() throws Exception { if(this.result == null) { String ret = super.read(); this.result = mapper.readTree(ret); } - if(this.itemID == null) { - this.itemID = result.get(ID_KEY).asText(); - } - itemURL = getExtraField(result, EXTRAS_ITEM_URL_KEY).asText(); + parseResult(); } @@ -772,7 +781,7 @@ public class CKANPackage extends CKAN implements Moderated { super.create(getAsString(jsonNode)); - this.itemID = result.get(ID_KEY).asText(); + parseResult(); ArrayNode created = createResources(resourcesToBeCreated); ((ObjectNode) result).replace(RESOURCES_KEY, created); @@ -781,8 +790,7 @@ public class CKANPackage extends CKAN implements Moderated { if(!isModerationEnabled()) { if(configuration.getScopeBean().is(Type.VRE)) { // Actions performed after a package has been correctly created on ckan. - String title = result.get(TITLE_KEY).asText(); - sendSocialPost(title); + sendSocialPost(); } } @@ -922,6 +930,8 @@ public class CKANPackage extends CKAN implements Moderated { sendPostRequest(ITEM_PATCH, getAsString(jsonNode)); + parseResult(); + for(String resourceId : originalResources.keySet()) { CKANResource ckanResource = originalResources.get(resourceId); ckanResource.deleteFile(); @@ -1293,7 +1303,7 @@ public class CKANPackage extends CKAN implements Moderated { private void postItemCreated() throws Exception { try { if(isModerationEnabled()) { - moderationThread.setItemCoordinates(itemID, name, itemURL); + moderationThread.setItemCoordinates(itemID, name, itemTitle, itemURL); moderationThread.postItemCreated(); } } catch(WebApplicationException e) { @@ -1306,7 +1316,7 @@ public class CKANPackage extends CKAN implements Moderated { private void postItemUpdated() { try { if(isModerationEnabled()) { - moderationThread.setItemCoordinates(itemID, name, itemURL); + moderationThread.setItemCoordinates(itemID, name, itemTitle, itemURL); moderationThread.postItemUpdated(); } } catch(WebApplicationException e) { @@ -1338,14 +1348,13 @@ public class CKANPackage extends CKAN implements Moderated { String ret = sendPostRequest(ITEM_UPDATE, getAsString(result)); result = mapper.readTree(ret); - itemURL = getExtraField(result, EXTRAS_ITEM_URL_KEY).asText(); - moderationThread.setItemCoordinates(itemID, name, itemURL); + parseResult(); + moderationThread.setItemCoordinates(itemID, name, itemTitle, itemURL); moderationThread.postItemApproved(moderatorMessage); if(configuration.getScopeBean().is(Type.VRE)) { // Actions performed after a package has been correctly created on ckan. - String title = result.get(TITLE_KEY).asText(); - sendSocialPost(title); + sendSocialPost(); } break; @@ -1385,8 +1394,8 @@ public class CKANPackage extends CKAN implements Moderated { setToRejected(result); String ret = sendPostRequest(ITEM_PATCH, getAsString(result)); result = mapper.readTree(ret); - - moderationThread.setItemCoordinates(itemID, name, itemURL); + parseResult(); + moderationThread.setItemCoordinates(itemID, name, itemTitle, itemURL); moderationThread.postItemRejected(moderatorMessage); break; @@ -1418,11 +1427,13 @@ public class CKANPackage extends CKAN implements Moderated { // Users that are not if(!isItemCreator()) { throw new NotAllowedException("Only item creator and " + Moderated.CATALOGUE_MODERATOR + "s are entitled to partecipate to the moderation discussion thread."); + }else { + moderationThread.setItemAuthor(true); } } CMItemStatus cmItemStatus = getCMItemStatus(); - moderationThread.setItemCoordinates(itemID, name, itemURL); + moderationThread.setItemCoordinates(itemID, name, itemTitle, itemURL); moderationThread.postUserMessage(cmItemStatus, message); return; } diff --git a/src/test/java/org/gcube/gcat/moderation/ModerationThreadTest.java b/src/test/java/org/gcube/gcat/moderation/ModerationThreadTest.java index efcc105..c8f064c 100644 --- a/src/test/java/org/gcube/gcat/moderation/ModerationThreadTest.java +++ b/src/test/java/org/gcube/gcat/moderation/ModerationThreadTest.java @@ -13,10 +13,10 @@ import org.junit.Test; public class ModerationThreadTest extends ContextTest { @Test - @JsonIgnore + // @JsonIgnore public void test() throws Exception { ModerationThread moderationThread = ModerationThread.getDefaultInstance(); - moderationThread.setItemCoordinates("my_first_restful_transaction_model", "RESTful Transaction Model", "https://data.dev.d4science.org/ctlg/devVRE/my_first_restful_transaction_model"); + moderationThread.setItemCoordinates("e31a6ba8-66ef-47b8-b61f-99a1366b4a69", "my_first_restful_transaction_model", "RESTful Transaction Model", "https://data.dev.d4science.org/ctlg/devVRE/my_first_restful_transaction_model"); CKANUser ckanUser = new CKANUser(); ckanUser.setName(CKANUser.getCKANUsername()); ckanUser.read(); @@ -25,7 +25,8 @@ public class ModerationThreadTest extends ContextTest { moderationThread.postItemUpdated(); moderationThread.postItemRejected("Non mi garba"); moderationThread.postItemApproved("Ora mi garba"); - moderationThread.postUserMessage(CMItemStatus.APPROVED, "Well Done"); + moderationThread.setItemAuthor(true); + moderationThread.postUserMessage(CMItemStatus.APPROVED, "Grazie"); Thread.sleep(1000); }