package org.gcube.gcat.moderation.thread.zulip; import java.util.Set; import javax.ws.rs.InternalServerErrorException; import org.gcube.com.fasterxml.jackson.databind.JsonNode; import org.gcube.com.fasterxml.jackson.databind.node.ArrayNode; import org.gcube.com.fasterxml.jackson.databind.node.ObjectNode; import org.gcube.common.authorization.utils.manager.SecretManager; import org.gcube.common.authorization.utils.manager.SecretManagerProvider; import org.gcube.common.authorization.utils.secret.Secret; import org.gcube.gcat.api.moderation.CMItemStatus; import org.gcube.gcat.api.moderation.Moderated; import org.gcube.gcat.moderation.thread.ModerationThread; import org.gcube.gcat.moderation.thread.zulip.ZulipResponse.Result; import org.gcube.gcat.social.SocialUsers; import org.gcube.gcat.utils.Constants; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import io.taliox.zulip.ZulipRestExecutor; import io.taliox.zulip.calls.ZulipRestAPICall; import io.taliox.zulip.calls.messages.PostMessage; import io.taliox.zulip.calls.streams.GetStreamID; import io.taliox.zulip.calls.streams.PostCreateStream; /** * @author Luca Frosini (ISTI - CNR) */ public class ZulipStream extends ModerationThread { private static final Logger logger = LoggerFactory.getLogger(ZulipStream.class); 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 String streamName; protected String streamDescription; public ZulipStream() { super(); } protected ZulipRestExecutor getZulipRestExecutor() { ZulipAuth zulipAuth = new ZulipAuth(SecretManagerProvider.instance.get().getUser().getUsername()); return new ZulipRestExecutor(zulipAuth.getEmail(), zulipAuth.getAPIKey(), zulipAuth.getSite()); } public ZulipRestExecutor getGCatZulipRestExecutor() throws Exception { if(gCatZulipRestExecutor==null) { SecretManager secretManager = SecretManagerProvider.instance.get(); Secret secret = Constants.getCatalogueSecret(); secretManager.startSession(secret); gCatZulipRestExecutor = getZulipRestExecutor(); secretManager.endSession(); } return gCatZulipRestExecutor; } public ZulipRestExecutor getUserZulipRestExecutor() { if(userZulipRestExecutor==null) { userZulipRestExecutor = getZulipRestExecutor(); } return userZulipRestExecutor; } protected String getStreamName() { if(streamName==null) { streamName = String.format("Item '%s' moderation", itemID); } return streamName; } protected Integer getStreamID() throws Exception { GetStreamID getStreamID = new GetStreamID(getStreamName()); ZulipResponse zulipResponse = executeZulipCall(gCatZulipRestExecutor, getStreamID); JsonNode response = zulipResponse.getResponse(); return response.get("stream_id").asInt(); } protected String getStreamDescription() { if(streamDescription==null) { streamDescription = String.format("This stream is used to discuss about the moderation of the item '%s' with id '%s'", itemName, itemID); } return streamDescription; } protected ZulipResponse executeZulipCall(ZulipRestExecutor zulipRestExecutor, ZulipRestAPICall call) throws Exception { 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); if(zulipResponse.getResponseResult()==Result.error) { throw new InternalServerErrorException(zulipResponse.getResponseMessage()); } return zulipResponse; } @Override protected void createModerationThread() throws Exception { ArrayNode streamsArrayNode = objectMapper.createArrayNode(); ObjectNode streamobjectNode = objectMapper.createObjectNode(); streamobjectNode.put("name", getStreamName()); streamobjectNode.put("description", getStreamDescription()); streamsArrayNode.add(streamobjectNode); ArrayNode principalsArrayNode = objectMapper.createArrayNode(); // Going to add the item creator String itemCreatorEmail = ckanUser.getEMail(); principalsArrayNode.add(itemCreatorEmail); getGCatZulipRestExecutor(); principalsArrayNode.add(gCatZulipRestExecutor.httpController.getUserName()); // Going to add the catalogue moderators Set moderators = SocialUsers.getUsernamesByRole(Moderated.CATALOGUE_MODERATOR); for(String moderator : moderators) { principalsArrayNode.add(moderator); } PostCreateStream postCreateStream = new PostCreateStream(streamsArrayNode.toString()); postCreateStream.setPrincipals(principalsArrayNode.toString()); postCreateStream.setInvite_only(true); postCreateStream.setAnnounce(false); executeZulipCall(gCatZulipRestExecutor, postCreateStream); } protected void postMessageToStream(ZulipRestExecutor zulipRestExecutor, String message) throws Exception { PostMessage postMessage = new PostMessage(getStreamName(), cmItemStatus.getFancyValue(), message); logger.debug("Going to send the following message: {}", message); executeZulipCall(zulipRestExecutor, postMessage); } @Override protected void postMessage(String message) throws Exception { postMessageToStream(getGCatZulipRestExecutor(), message); } @Override public void postUserMessage(CMItemStatus cmItemStatus, String message) throws Exception { this.cmItemStatus = cmItemStatus; postMessageToStream(getUserZulipRestExecutor(), message); } }