package com.thinkbiganalytics.discovery.rest.controller;
/*-
* #%L
* thinkbig-schema-discovery-controller
* %%
* Copyright (C) 2017 ThinkBig Analytics
* %%
* 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.
* #L%
*/
import com.thinkbiganalytics.discovery.FileParserFactory;
import com.thinkbiganalytics.discovery.model.SchemaParserDescriptor;
import com.thinkbiganalytics.discovery.parser.FileSchemaParser;
import com.thinkbiganalytics.discovery.schema.Schema;
import com.thinkbiganalytics.discovery.util.TableSchemaType;
import com.thinkbiganalytics.json.ObjectMapperSerializer;
import com.thinkbiganalytics.policy.PolicyTransformException;
import com.thinkbiganalytics.rest.model.RestResponseStatus;
import org.glassfish.jersey.media.multipart.FormDataContentDisposition;
import org.glassfish.jersey.media.multipart.FormDataParam;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import java.util.ResourceBundle;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.InternalServerErrorException;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import io.swagger.annotations.SwaggerDefinition;
import io.swagger.annotations.Tag;
/**
* Provides schema discovery services which is able to generate a schema for file or database sources
*/
@Api(tags = "Feed Manager - Schema Discovery", produces = "application/json")
@Path("/v1/schema-discovery")
@SwaggerDefinition(tags = @Tag(name = "Feed Manager - Schema Discovery", description = "determine file schemas"))
public class SchemaDiscoveryRestController {
private static final Logger log = LoggerFactory.getLogger(SchemaDiscoveryRestController.class);
private static final ResourceBundle STRINGS = ResourceBundle.getBundle("com.thinkbiganalytics.discovery.rest.controller.DiscoveryMessages");
@POST
@Path("/hive/sample-file")
@Consumes(MediaType.MULTIPART_FORM_DATA)
@Produces(MediaType.APPLICATION_JSON)
@ApiOperation("Determines the schema of the provided file.")
@ApiResponses({
@ApiResponse(code = 200, message = "Returns the schema.", response = Schema.class),
@ApiResponse(code = 500, message = "The schema could not be determined.", response = RestResponseStatus.class)
})
public Response uploadFile(@FormDataParam("parser") String parserDescriptor,
@FormDataParam("file") InputStream fileInputStream,
@FormDataParam("file") FormDataContentDisposition fileMetaData) throws Exception {
Schema schema;
SchemaParserAnnotationTransformer transformer = new SchemaParserAnnotationTransformer();
try {
SchemaParserDescriptor descriptor = ObjectMapperSerializer.deserialize(parserDescriptor, SchemaParserDescriptor.class);
FileSchemaParser p = transformer.fromUiModel(descriptor);
// TODO: Detect charset
schema = p.parse(fileInputStream, Charset.defaultCharset(), TableSchemaType.HIVE);
} catch (IOException e) {
throw new WebApplicationException(e.getMessage());
} catch (PolicyTransformException e) {
log.warn("Failed to convert parser", e);
throw new InternalServerErrorException(STRINGS.getString("discovery.transformError"), e);
}
return Response.ok(schema).build();
}
@GET
@Path("/file-parsers")
@Produces(MediaType.APPLICATION_JSON)
@ApiOperation("Gets the available file parsers.")
@ApiResponses(
@ApiResponse(code = 200, message = "Returns the file parsers.", response = SchemaParserDescriptor.class, responseContainer = "List")
)
public Response getFileParsers() {
List<FileSchemaParser> parsers = FileParserFactory.instance().listSchemaParsers();
List<SchemaParserDescriptor> descriptors = new ArrayList<>();
SchemaParserAnnotationTransformer transformer = new SchemaParserAnnotationTransformer();
for (FileSchemaParser parser : parsers) {
SchemaParserDescriptor descriptor = transformer.toUIModel(parser);
descriptors.add(descriptor);
}
return Response.ok(descriptors).build();
}
}