org.basinmc.irc.bridge.github.TeamCityHandler.java Source code

Java tutorial

Introduction

Here is the source code for org.basinmc.irc.bridge.github.TeamCityHandler.java

Source

/*
 * Copyright 2016 Johannes Donath <johannesd@torchmind.com>
 * and other copyright owners as documented in the project's IP log.
 *
 * Licensed 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 org.basinmc.irc.bridge.github;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectReader;

import org.basinmc.irc.bridge.Bridge;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.handler.AbstractHandler;
import org.pircbotx.Colors;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.io.InputStream;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Handles build server events from TeamCity using the TCWebHooks plugin.
 *
 * @author <a href="mailto:johannesd@torchmind.com">Johannes Donath</a>
 */
public class TeamCityHandler extends AbstractHandler {
    private static final Logger logger = LoggerFactory.getLogger(TeamCityHandler.class);
    public static final String MESSAGE_START = "[" + Colors.DARK_BLUE + "%s" + Colors.BLACK
            + "] Build has started on " + Colors.DARK_GREEN + "%s" + Colors.DARK_GREEN + " - " + Colors.RED + "%s";
    public static final String MESSAGE_SUCCESS = "[" + Colors.DARK_BLUE + "%s" + Colors.BLACK
            + "] Build has finished " + Colors.GREEN + "successfully" + Colors.BLACK + " - " + Colors.RED + "%s";
    public static final String MESSAGE_FAILURE = "[" + Colors.DARK_BLUE + "%s" + Colors.BLACK + "] Build has "
            + Colors.RED + "failed" + Colors.BLACK + " to complete - " + Colors.RED + "%s";

    private static final ObjectReader reader = (new ObjectMapper()).findAndRegisterModules().reader();
    private final Bridge bridge;
    private final String serverAddress;

    public TeamCityHandler(@Nonnull Bridge bridge, @Nullable String serverAddress) {
        this.bridge = bridge;
        this.serverAddress = serverAddress;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void handle(@Nonnull String target, @Nonnull Request baseRequest, @Nonnull HttpServletRequest request,
            @Nonnull HttpServletResponse response) throws IOException, ServletException {
        if (!target.startsWith("/build")) {
            return;
        }

        if (this.serverAddress != null && !this.serverAddress.isEmpty()
                && !this.serverAddress.equals(request.getRemoteAddr())) {
            logger.info("Access denied to build webhook from " + request.getRemoteAddr());

            response.sendError(HttpServletResponse.SC_FORBIDDEN);
            baseRequest.setHandled(true);
            return;
        }

        JsonNode data;

        try (InputStream inputStream = request.getInputStream()) {
            data = reader.readTree(inputStream).get("build");
        }

        switch (target) {
        default:
            return;
        case "/build/started":
            this.bridge.sendMessage(String.format(MESSAGE_START, data.get("buildFullName").asText(),
                    data.get("agentName").asText(), data.get("buildStatusUrl").asText()));
            break;
        case "/build/success":
            this.bridge.sendMessage(String.format(MESSAGE_SUCCESS, data.get("buildFullName").asText(),
                    data.get("buildStatusUrl").asText()));
            break;
        case "/build/failure":
            this.bridge.sendMessage(String.format(MESSAGE_FAILURE, data.get("buildFullName").asText(),
                    data.get("buildStatusUrl").asText()));
            break;
        }

        logger.info("Handled build webhook from " + request.getRemoteAddr());
        response.setStatus(HttpServletResponse.SC_NO_CONTENT);
        baseRequest.setHandled(true);
    }
}