org.apache.samza.webapp.YarnContainerHeartbeatServlet.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.samza.webapp.YarnContainerHeartbeatServlet.java

Source

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF 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 org.apache.samza.webapp;

import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.hadoop.yarn.api.records.ContainerId;
import org.apache.samza.container.ContainerHeartbeatResponse;
import org.apache.samza.job.yarn.SamzaAppMasterMetrics;
import org.apache.samza.job.yarn.YarnAppState;
import org.apache.samza.job.yarn.YarnContainer;
import org.apache.samza.metrics.Counter;
import org.apache.samza.metrics.ReadableMetricsRegistry;
import org.codehaus.jackson.map.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Responds to heartbeat requests from the containers with a {@link ContainerHeartbeatResponse}.
 * The heartbeat request contains the <code> executionContainerId </code>
 * which in YARN's case is the YARN container Id.
 * This servlet validates the container Id against the list
 * of running containers maintained in the {@link YarnAppState}.
 * The returned {@link ContainerHeartbeatResponse#isAlive()} is
 * <code> true </code> iff. the container Id exists in {@link YarnAppState#runningProcessors}.
 */
public class YarnContainerHeartbeatServlet extends HttpServlet {

    private static final String YARN_CONTAINER_ID = "executionContainerId";
    private static final Logger LOG = LoggerFactory.getLogger(YarnContainerHeartbeatServlet.class);
    private static final String APPLICATION_JSON = "application/json";
    private static final String GROUP = SamzaAppMasterMetrics.class.getName();
    private final Counter heartbeatsExpiredCount;

    private YarnAppState yarnAppState;
    private ObjectMapper mapper;

    public YarnContainerHeartbeatServlet(YarnAppState yarnAppState, ReadableMetricsRegistry registry) {
        this.yarnAppState = yarnAppState;
        this.mapper = new ObjectMapper();
        this.heartbeatsExpiredCount = registry.newCounter(GROUP, "heartbeats-expired");
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ContainerId yarnContainerId;
        PrintWriter printWriter = resp.getWriter();
        String containerIdParam = req.getParameter(YARN_CONTAINER_ID);
        ContainerHeartbeatResponse response;
        resp.setContentType(APPLICATION_JSON);
        boolean alive = false;
        try {
            yarnContainerId = ContainerId.fromString(containerIdParam);
            for (YarnContainer yarnContainer : yarnAppState.runningProcessors.values()) {
                if (yarnContainer.id().compareTo(yarnContainerId) == 0) {
                    alive = true;
                    break;
                }
            }
            if (!alive) {
                heartbeatsExpiredCount.inc();
            }
            response = new ContainerHeartbeatResponse(alive);
            printWriter.write(mapper.writeValueAsString(response));
        } catch (IllegalArgumentException e) {
            LOG.error("Container ID {} passed is invalid", containerIdParam);
            resp.sendError(HttpServletResponse.SC_BAD_REQUEST, e.getMessage());
        }
    }
}