/*
 * 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());
    }
  }
}
