/**
* Copyright (C) 2014-2016 LinkedIn Corp. (pinot-core@linkedin.com)
*
* 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.
*/
package com.linkedin.pinot.server.starter.helix;
import com.linkedin.pinot.server.starter.ServerInstance;
import io.swagger.jaxrs.config.BeanConfig;
import java.io.IOException;
import java.net.URI;
import java.net.URL;
import java.net.URLClassLoader;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerResponseContext;
import javax.ws.rs.container.ContainerResponseFilter;
import org.glassfish.grizzly.http.server.CLStaticHttpHandler;
import org.glassfish.grizzly.http.server.HttpServer;
import org.glassfish.hk2.utilities.binding.AbstractBinder;
import org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpServerFactory;
import org.glassfish.jersey.jackson.JacksonFeature;
import org.glassfish.jersey.server.ResourceConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class AdminApiApplication extends ResourceConfig {
private static final Logger LOGGER = LoggerFactory.getLogger(AdminApiApplication.class);
private final ServerInstance serverInstance;
private URI baseUri;
private boolean started = false;
private HttpServer httpServer;
public static final String RESOURCE_PACKAGE = "com.linkedin.pinot.server.api.resources";
public AdminApiApplication(ServerInstance instance) {
this.serverInstance = instance;
packages(RESOURCE_PACKAGE);
register(new AbstractBinder() {
@Override
protected void configure() {
bind(serverInstance).to(ServerInstance.class);
}
});
register(JacksonFeature.class);
registerClasses(io.swagger.jaxrs.listing.ApiListingResource.class);
registerClasses(io.swagger.jaxrs.listing.SwaggerSerializers.class);
register(new ContainerResponseFilter() {
@Override
public void filter(ContainerRequestContext containerRequestContext,
ContainerResponseContext containerResponseContext)
throws IOException {
containerResponseContext.getHeaders().add("Access-Control-Allow-Origin", "*");
}
});
}
public boolean start(int httpPort) {
if (httpPort <= 0 ) {
LOGGER.warn("Invalid admin API port: {}. Not starting admin service", httpPort);
return false;
}
baseUri = URI.create("http://0.0.0.0:" + Integer.toString(httpPort) + "/");
httpServer = GrizzlyHttpServerFactory.createHttpServer(baseUri, this);
setupSwagger(httpServer);
started = true;
return true;
}
public URI getBaseUri() {
return baseUri;
}
private void setupSwagger(HttpServer httpServer) {
BeanConfig beanConfig = new BeanConfig();
beanConfig.setTitle("Pinot Server API");
beanConfig.setDescription("APIs for accessing Pinot server information");
beanConfig.setContact("https://github.com/linkedin/pinot");
beanConfig.setVersion("1.0");
beanConfig.setSchemes(new String[]{"http"});
beanConfig.setBasePath(baseUri.getPath());
beanConfig.setResourcePackage(RESOURCE_PACKAGE);
beanConfig.setScan(true);
CLStaticHttpHandler staticHttpHandler = new CLStaticHttpHandler(AdminApiApplication.class.getClassLoader(), "/api/");
// map both /api and /help to swagger docs. /api because it looks nice. /help for backward compatibility
httpServer.getServerConfiguration().addHttpHandler(staticHttpHandler, "/api");
httpServer.getServerConfiguration().addHttpHandler(staticHttpHandler, "/help");
URL swaggerDistLocation = AdminApiApplication.class.getClassLoader()
.getResource("META-INF/resources/webjars/swagger-ui/2.2.2/");
CLStaticHttpHandler swaggerDist = new CLStaticHttpHandler(
new URLClassLoader(new URL[] {swaggerDistLocation}));
httpServer.getServerConfiguration().addHttpHandler(swaggerDist, "/swaggerui-dist/");
}
public void stop(){
if (!started) {
return;
}
httpServer.shutdownNow();
}
}