All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.fabric8.hubot.HubotNotifier Maven / Gradle / Ivy

There is a newer version: 3.0.12
Show newest version
/**
 *  Copyright 2005-2016 Red Hat, Inc.
 *
 *  Red Hat licenses this file to you under the Apache License, version
 *  2.0 (the "License"); you may not use this file except in compliance
 *  with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
 *  implied.  See the License for the specific language governing
 *  permissions and limitations under the License.
 */
package io.fabric8.hubot;

import io.fabric8.annotations.Protocol;
import io.fabric8.annotations.ServiceName;
import io.fabric8.utils.Strings;
import org.apache.cxf.jaxrs.client.JAXRSClientFactory;
import org.apache.cxf.jaxrs.client.WebClient;
import org.apache.deltaspike.core.api.config.ConfigProperty;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.enterprise.inject.Instance;
import javax.inject.Inject;
import java.util.List;

import static io.fabric8.utils.cxf.WebClients.configureUserAndPassword;
import static io.fabric8.utils.cxf.WebClients.createProviders;
import static io.fabric8.utils.cxf.WebClients.disableSslChecks;

/**
 * A service for notifying a message to the Hubot chat bot
 */
public class HubotNotifier {
    public static final String HUBOT_SERVICE_NAME = "hubot";
    public static final String DEFAULT_ROOM_EXPRESSION = "#fabric8_${namespace}";

    private static final transient Logger LOG = LoggerFactory.getLogger(HubotNotifier.class);

    @Inject
    @Protocol("http")
    @ServiceName(HUBOT_SERVICE_NAME)
    private Instance hubotUrlHolder;

    private final String username;
    private final String password;
    private final String roomExpression;
    private HubotRestApi api;
    private LoggingHubotRestApi logMessages = new LoggingHubotRestApi();
    private String hubotUrl;
    private boolean initalised;

    @Inject
    public HubotNotifier(@ConfigProperty(name = "HUBOT_USERNAME") String username,
                         @ConfigProperty(name = "HUBOT_PASSWORD") String password,
                         @ConfigProperty(name = "HUBOT_BUILD_ROOM", defaultValue = DEFAULT_ROOM_EXPRESSION) String roomExpression) {

        this.username = username;
        this.password = password;
        this.roomExpression = roomExpression;
    }

    public HubotNotifier(String hubotUrl, String username, String password, String roomExpression) {
        this.hubotUrl = hubotUrl;
        this.username = username;
        this.password = password;
        this.roomExpression = roomExpression;
    }

    public String getHubotUrl() {
        if (!initalised) {
            initalised = true;
            if (hubotUrl == null && hubotUrlHolder != null) {
                hubotUrl = hubotUrlHolder.get();
            }
            if (Strings.isNotBlank(hubotUrl)) {
                LOG.info("Starting HubotNotifier using address: " + hubotUrl);
            } else {
                LOG.warn("No kubernetes service found for " + HUBOT_SERVICE_NAME + " so chat messages just going to logs instead");
            }
        }
        return hubotUrl;
    }

    /**
     * Sends a message to a given room in the chat bot
     *
     * @param room the name of the room usually using IRC style starting with #
     * @param message the notification message to send which can include links or refer to people via @somenick
     */
    public void notifyRoom(String room, String message) {
        logMessages.notify(room, message);
        try {
            getHubotRestApi().notify(room, message);
        } catch (Throwable e) {
            LOG.error("Failed to notify hubot room: " + room + " with message: " + message + ". Reason: " + e);
        }
    }

    /**
     * Notifies the room for the given namespace and build config name with the given message.
     *
     * By default this maps to a single logical room; which could be global or typically parameterised with
     * the namespace and/or buildConfig.
     *
     * @param namespace the kubernetes namespace for the build
     * @param buildConfig the name of the build configuration
     * @param message the notification message
     */
    public void notifyBuild(String namespace, String buildConfig, String message) {
        String room = roomExpression.replace("${namespace}", namespace).replace("${buildConfig}", buildConfig);
        notifyRoom(room, message);
    }


    protected HubotRestApi getHubotRestApi() {
        if (api == null) {
            String url = getHubotUrl();
            if (Strings.isNotBlank(url)) {
                api = createWebClient(HubotRestApi.class, url);
            } else {
                api = new NoopHubotRestApi();
            }
        }
        return api;
    }

    /**
     * Creates a JAXRS web client for the given JAXRS client
     */
    protected  T createWebClient(Class clientType, String hubotUrl) {
        List providers = createProviders();
        WebClient webClient = WebClient.create(hubotUrl, providers);
        disableSslChecks(webClient);
        configureUserAndPassword(webClient, username, password);
        return JAXRSClientFactory.fromClient(webClient, clientType);
    }


}