package com.linkedin.pinot.controller.api.restlet.resources;

import com.linkedin.pinot.common.data.Schema;
import java.io.File;
import java.io.IOException;

import com.linkedin.pinot.common.metrics.ControllerMeter;
import com.linkedin.pinot.controller.api.ControllerRestApplication;
import org.apache.commons.io.FileUtils;
import org.restlet.data.MediaType;
import org.restlet.data.Status;
import org.restlet.representation.Representation;
import org.restlet.representation.StringRepresentation;
import org.restlet.resource.Get;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.linkedin.pinot.common.config.AbstractTableConfig;
import com.linkedin.pinot.common.utils.CommonConstants.Helix.TableType;
import com.linkedin.pinot.common.restlet.swagger.HttpVerb;
import com.linkedin.pinot.common.restlet.swagger.Parameter;
import com.linkedin.pinot.common.restlet.swagger.Paths;
import com.linkedin.pinot.common.restlet.swagger.Summary;
import com.linkedin.pinot.common.restlet.swagger.Tags;


public class PinotTableSchema extends BasePinotControllerRestletResource {

  private static final Logger LOGGER = LoggerFactory.getLogger(PinotTableSchema.class);
  private final File baseDataDir;
  private final File tempDir;

  public PinotTableSchema() throws IOException {
    baseDataDir = new File(_controllerConf.getDataDir());
    if (!baseDataDir.exists()) {
      FileUtils.forceMkdir(baseDataDir);
    }
    tempDir = new File(baseDataDir, "schemasTemp");
    if (!tempDir.exists()) {
      FileUtils.forceMkdir(tempDir);
    }
  }

  @Override
  @Get
  public Representation get() {
    final String tableName = (String) getRequest().getAttributes().get("tableName");

    return getTableSchema(tableName);
  }

  @HttpVerb("get")
  @Summary("Gets schema for a table")
  @Tags({"schema", "table"})
  @Paths({
      "/tables/{tableName}/schema",
      "/tables/{tableName}/schema/"
  })
  private Representation getTableSchema(
      @Parameter(name = "tableName", in = "path", description = "Table name for which to get the schema", required = true)
      String tableName) {
    if (_pinotHelixResourceManager.hasRealtimeTable(tableName)) {
      try {
        AbstractTableConfig config = _pinotHelixResourceManager.getTableConfig(tableName, TableType.REALTIME);
        return new StringRepresentation(_pinotHelixResourceManager.getSchema(config.getValidationConfig().getSchemaName()).getJSONSchema()
            .toString());
      } catch (Exception e) {
        LOGGER.error("Caught exception while fetching schema for a realtime table : {} ", tableName, e);
        ControllerRestApplication.getControllerMetrics().addMeteredGlobalValue(ControllerMeter.CONTROLLER_TABLE_SCHEMA_GET_ERROR, 1L);
        setStatus(Status.SERVER_ERROR_INTERNAL);
        return PinotSegmentUploadRestletResource.exceptionToStringRepresentation(e);
      }
    } else {
      AbstractTableConfig config;
      try {
        config = _pinotHelixResourceManager.getTableConfig(tableName, TableType.OFFLINE);
        String schemaName = config.getValidationConfig().getSchemaName();
        Schema schema = _pinotHelixResourceManager.getSchema(schemaName);
        if (schema == null) {
          setStatus(Status.CLIENT_ERROR_NOT_FOUND);
          StringRepresentation repr = new StringRepresentation("{\"error\": \"Schema " + schemaName + " not found\"");
          repr.setMediaType(MediaType.APPLICATION_JSON);
          return repr;
        }
        return new StringRepresentation(schema.getJSONSchema().toString());
      } catch (Exception e) {
        LOGGER.error("Caught exception while fetching schema for a offline table : {} ", tableName, e);
        ControllerRestApplication.getControllerMetrics().addMeteredGlobalValue(ControllerMeter.CONTROLLER_TABLE_SCHEMA_GET_ERROR, 1L);
        setStatus(Status.SERVER_ERROR_INTERNAL);
        return PinotSegmentUploadRestletResource.exceptionToStringRepresentation(e);
      }
    }
  }
}

@@ -66,217 +66,44 @@
 ort 
-com.linkedin.pinot.common.data.Schema;%0Aimport java.io.File;%0Aimport java.io.IOException;%0A%0Aimport com.linkedin.pinot.common.metrics.ControllerMeter;%0Aimport com.linkedin.pinot.controller.api.ControllerRestApplica
+java.io.File;%0Aimport java.io.IOExcep
 tion
@@ -407,17 +407,16 @@
 actory;%0A
-%0A
 import c
@@ -505,45 +505,77 @@
 mon.
-utils.CommonConstants.Helix.TableType
+data.Schema;%0Aimport com.linkedin.pinot.common.metrics.ControllerMeter
 ;%0Aim
@@ -860,16 +860,156 @@
 r.Tags;%0A
+import com.linkedin.pinot.common.utils.CommonConstants.Helix.TableType;%0Aimport com.linkedin.pinot.controller.api.ControllerRestApplication;%0A
 %0A%0Apublic
@@ -3103,16 +3103,100 @@
 schema =
+ null;%0A        if (schemaName != null && !schemaName.isEmpty()) %7B%0A          schema =
  _pinotH
@@ -3234,24 +3234,34 @@
 chemaName);%0A
+        %7D%0A
         if (

Fix Exception when getting a schema for offline table (#806)