/*
 * 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.coordinator.CoordinationConstants;
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 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(CoordinationConstants.YARN_EXECUTION_ENVIRONMENT_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());
    }
  }
}
