info.pancancer.arch3.reportbot.SlackReportBot.java Source code

Java tutorial

Introduction

Here is the source code for info.pancancer.arch3.reportbot.SlackReportBot.java

Source

/*
 *     Consonance - workflow software for multiple clouds
 *     Copyright (C) 2016 OICR
 *
 *     This program is free software: you can redistribute it and/or modify
 *     it under the terms of the GNU General Public License as published by
 *     the Free Software Foundation, either version 3 of the License, or
 *     (at your option) any later version.
 *
 *     This program is distributed in the hope that it will be useful,
 *     but WITHOUT ANY WARRANTY; without even the implied warranty of
 *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *     GNU General Public License for more details.
 *
 *     You should have received a copy of the GNU General Public License
 *     along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 */
package info.pancancer.arch3.reportbot;

import com.ullink.slack.simpleslackapi.SlackSession;
import com.ullink.slack.simpleslackapi.events.SlackMessagePosted;
import com.ullink.slack.simpleslackapi.impl.SlackSessionFactory;
import com.ullink.slack.simpleslackapi.listeners.SlackMessagePostedListener;
import info.pancancer.arch3.Base;
import info.pancancer.arch3.persistence.PostgreSQL;
import info.pancancer.arch3.reporting.ReportAPI;
import info.pancancer.arch3.reporting.ReportAPIFactory;
import info.pancancer.arch3.reporting.SlackRenderer;
import info.pancancer.arch3.utils.Constants;
import info.pancancer.arch3.utils.Utilities;
import io.cloudbindle.youxia.util.Log;
import java.io.IOException;
import java.util.Locale;
import org.apache.commons.configuration.HierarchicalINIConfiguration;

/**
 * This responds to Slack events and translates them into reporting calls.
 *
 * @author dyuen
 */
public class SlackReportBot extends Base {

    public static final int SLEEP_IN_MILLISECONDS = 5000;

    public static void main(String[] argv) throws Exception {
        SlackReportBot bot = new SlackReportBot(argv);
        bot.doWork();
    }

    public SlackReportBot(String[] argv) throws IOException {
        super();
        parseOptions(argv);
    }

    public void doWork() throws Exception {

        final HierarchicalINIConfiguration settings = Utilities.parseConfig(configFile);
        final PostgreSQL db = new PostgreSQL(settings);

        final SlackSession session = SlackSessionFactory
                .createWebSocketSlackSession(settings.getString(Constants.REPORT_TOKEN));
        session.addMessagePostedListener(new SlackMessagePostedListener() {
            @Override
            public void onEvent(SlackMessagePosted event, SlackSession session) {
                Log.debug(event.toString());
                String namespace = settings.getString(Constants.REPORT_NAMESPACE).toUpperCase(Locale.CANADA);
                if (event.getSender().getUserName().equalsIgnoreCase(namespace)) {
                    return;
                }
                // note that this ignores case
                String message = event.getMessageContent().toUpperCase(Locale.CANADA);

                boolean validMessage = false;
                // remove the '@' if necessary
                String dmIdentifer = "<@" + session.sessionPersona().getId() + ">";
                if (message.startsWith(dmIdentifer)) {
                    message = message.replaceFirst(dmIdentifer, "").trim();
                    // trim automatically inserted colon in some chat clients
                    if (message.startsWith(":")) {
                        message = message.replaceFirst(":", "").trim();
                    }
                    validMessage = true;
                }
                // remove plain user name if needed
                if (message.startsWith(namespace)) {
                    validMessage = true;
                    message = message.replaceFirst(namespace, "").trim();
                    Log.info("message was *" + message + "* ");
                    // remove extra colon that the Mac client adds
                    if (message.startsWith(":")) {
                        message = message.substring(1).trim();
                    }
                }

                if (validMessage) {
                    ReportAPI reportAPI = ReportAPIFactory.makeReportAPI(settings, db);
                    SlackRenderer renderer = new SlackRenderer(reportAPI);
                    SlackRenderer.FormattedMessage result = renderer.convertToResult(message);
                    if (result.attachment != null) {
                        result.attachment.addMarkdownIn("text");
                    }
                    session.sendMessage(session.findChannelById(event.getChannel().getId()), result.message,
                            result.attachment);
                }
            }
        });

        int retries = 0;
        boolean retry = false;
        do {
            try {
                session.connect();
                do {
                    Thread.sleep(SLEEP_IN_MILLISECONDS);
                } while (options.has(this.endlessSpec));
            } catch (Exception e) {
                Log.error("SlackBot connection issue", e);
                long waitTime = Math.min(getWaitTimeExp(retries), TEN_MINUTES_IN_MILLISECONDS);
                System.out.print(waitTime + "\n");
                // Wait for the result.
                Thread.sleep(waitTime);
            }
        } while (options.has(this.endlessSpec));
    }

    /*
     * Returns the next wait interval, in milliseconds, using an exponential backoff algorithm. Taken from AWS.
     */
    public static long getWaitTimeExp(int retryCount) {
        final long convertToMilliseconds = 100L;
        long waitTime = ((long) Math.pow(2, retryCount) * convertToMilliseconds);
        return waitTime;
    }
}