Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DRILL-8162: Add OpenAPI Specification documentation for Drill's REST API #2489

Merged
merged 6 commits into from
Mar 11, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
22 changes: 20 additions & 2 deletions exec/java-exec/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -650,6 +650,24 @@
<version>${testcontainers.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.github.rdblue</groupId>
<artifactId>brotli-codec</artifactId>
<version>0.1.1</version>
<!-- brotli-codec bundles natives for linux and darwin, amd64 only so
we don't ship it so as not to break startup on windows or arm -->
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.swagger.core.v3</groupId>
<artifactId>swagger-jaxrs2</artifactId>
<version>${swagger.version}</version>
</dependency>
<dependency>
<groupId>io.swagger.core.v3</groupId>
<artifactId>swagger-jaxrs2-servlet-initializer-v2</artifactId>
<version>${swagger.version}</version>
</dependency>
</dependencies>

<profiles>
Expand Down Expand Up @@ -863,7 +881,8 @@
<execution>
<id>generate-fmpp</id>
<phase>generate-sources</phase>
<goals><goal>generate</goal></goals>
<goals>
<goal>generate</goal></goals>
<configuration>
<config>${project.build.directory}/codegen/config.fmpp</config>
<output>${project.build.directory}/generated-sources</output>
Expand Down Expand Up @@ -980,5 +999,4 @@
</build>



</project>
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@
import com.fasterxml.jackson.jaxrs.base.JsonMappingExceptionMapper;
import com.fasterxml.jackson.jaxrs.base.JsonParseExceptionMapper;
import com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider;
import io.swagger.v3.oas.annotations.OpenAPIDefinition;
import io.swagger.v3.oas.annotations.info.Contact;
import io.swagger.v3.oas.annotations.info.Info;
import io.swagger.v3.oas.annotations.info.License;
import org.apache.drill.shaded.guava.com.google.common.base.Strings;
import freemarker.cache.ClassTemplateLoader;
import freemarker.cache.FileTemplateLoader;
Expand All @@ -31,6 +35,7 @@
import freemarker.template.Configuration;
import io.netty.util.concurrent.DefaultPromise;
import io.netty.util.concurrent.Promise;
import io.swagger.v3.jaxrs2.integration.resources.OpenApiResource;
import io.netty.util.concurrent.EventExecutor;
import org.apache.drill.common.config.DrillConfig;
import org.apache.drill.exec.ExecConstants;
Expand Down Expand Up @@ -73,6 +78,10 @@
import java.util.ArrayList;
import java.util.List;

@OpenAPIDefinition(info = @Info(title = "Apache Drill REST API", description = "OpenAPI Specification",
license = @License(name = "Apache Software Foundation (ASF)", url = "http://www.apache" + ".org/licenses/LICENSE-2.0"),
contact = @Contact(name = "Apache Drill", url = "https://drill.apache.org/")))

public class DrillRestServer extends ResourceConfig {
static final Logger logger = LoggerFactory.getLogger(DrillRestServer.class);

Expand All @@ -93,7 +102,7 @@ public DrillRestServer(final WorkManager workManager, final ServletContext servl
property(ServerProperties.METAINF_SERVICES_LOOKUP_DISABLE, true);

final boolean isAuthEnabled =
workManager.getContext().getConfig().getBoolean(ExecConstants.USER_AUTHENTICATION_ENABLED);
workManager.getContext().getConfig().getBoolean(ExecConstants.USER_AUTHENTICATION_ENABLED);

if (isAuthEnabled) {
register(LogInLogOutResources.class);
Expand All @@ -103,7 +112,7 @@ public DrillRestServer(final WorkManager workManager, final ServletContext servl

//disable moxy so it doesn't conflict with jackson.
final String disableMoxy = PropertiesHelper.getPropertyNameForRuntime(CommonProperties.MOXY_JSON_FEATURE_DISABLE,
getConfiguration().getRuntimeType());
getConfiguration().getRuntimeType());
property(disableMoxy, true);

register(JsonParseExceptionMapper.class);
Expand Down Expand Up @@ -140,6 +149,8 @@ protected void configure() {
}
}
});

register(OpenApiResource.class);
}

/**
Expand Down Expand Up @@ -189,19 +200,19 @@ public WebUserConnection provide() {

// User is logged in, get/set the WebSessionResources attribute
WebSessionResources webSessionResources =
(WebSessionResources) session.getAttribute(WebSessionResources.class.getSimpleName());
(WebSessionResources) session.getAttribute(WebSessionResources.class.getSimpleName());

if (webSessionResources == null) {
// User is login in for the first time
final DrillbitContext drillbitContext = workManager.getContext();
final DrillConfig config = drillbitContext.getConfig();
final UserSession drillUserSession = UserSession.Builder.newBuilder()
.withCredentials(UserBitShared.UserCredentials.newBuilder()
.setUserName(sessionUserPrincipal.getName())
.build())
.withOptionManager(drillbitContext.getOptionManager())
.setSupportComplexTypes(config.getBoolean(ExecConstants.CLIENT_SUPPORT_COMPLEX_TYPES))
.build();
.withCredentials(UserBitShared.UserCredentials.newBuilder()
.setUserName(sessionUserPrincipal.getName())
.build())
.withOptionManager(drillbitContext.getOptionManager())
.setSupportComplexTypes(config.getBoolean(ExecConstants.CLIENT_SUPPORT_COMPLEX_TYPES))
.build();

// Only try getting remote address in first login since it's a costly operation.
SocketAddress remoteAddress = null;
Expand All @@ -217,9 +228,9 @@ public WebUserConnection provide() {
// Create per session BufferAllocator and set it in session
final String sessionAllocatorName = String.format("WebServer:AuthUserSession:%s", session.getId());
final BufferAllocator sessionAllocator = workManager.getContext().getAllocator().newChildAllocator(
sessionAllocatorName,
config.getLong(ExecConstants.HTTP_SESSION_MEMORY_RESERVATION),
config.getLong(ExecConstants.HTTP_SESSION_MEMORY_MAXIMUM));
sessionAllocatorName,
config.getLong(ExecConstants.HTTP_SESSION_MEMORY_RESERVATION),
config.getLong(ExecConstants.HTTP_SESSION_MEMORY_MAXIMUM));

// Create a future which is needed by Foreman only. Foreman uses this future to add a close
// listener to known about channel close event from underlying layer. We use this future to notify Foreman
Expand Down Expand Up @@ -258,20 +269,20 @@ public WebUserConnection provide() {

// Create an allocator here for each request
final BufferAllocator sessionAllocator = drillbitContext.getAllocator()
.newChildAllocator("WebServer:AnonUserSession",
config.getLong(ExecConstants.HTTP_SESSION_MEMORY_RESERVATION),
config.getLong(ExecConstants.HTTP_SESSION_MEMORY_MAXIMUM));
.newChildAllocator("WebServer:AnonUserSession",
config.getLong(ExecConstants.HTTP_SESSION_MEMORY_RESERVATION),
config.getLong(ExecConstants.HTTP_SESSION_MEMORY_MAXIMUM));

final Principal sessionUserPrincipal = createSessionUserPrincipal(config, request);

// Create new UserSession for each request from non-authenticated user
final UserSession drillUserSession = UserSession.Builder.newBuilder()
.withCredentials(UserBitShared.UserCredentials.newBuilder()
.setUserName(sessionUserPrincipal.getName())
.build())
.withOptionManager(drillbitContext.getOptionManager())
.setSupportComplexTypes(drillbitContext.getConfig().getBoolean(ExecConstants.CLIENT_SUPPORT_COMPLEX_TYPES))
.build();
.withCredentials(UserBitShared.UserCredentials.newBuilder()
.setUserName(sessionUserPrincipal.getName())
.build())
.withOptionManager(drillbitContext.getOptionManager())
.setSupportComplexTypes(drillbitContext.getConfig().getBoolean(ExecConstants.CLIENT_SUPPORT_COMPLEX_TYPES))
.build();

// Try to get the remote Address but set it to null in case of failure.
SocketAddress remoteAddress = null;
Expand All @@ -291,7 +302,7 @@ public WebUserConnection provide() {
final Promise<Void> closeFuture = new DefaultPromise(executor);

final WebSessionResources webSessionResources = new WebSessionResources(sessionAllocator, remoteAddress,
drillUserSession, closeFuture);
drillUserSession, closeFuture);

// Create a AnonWenUserConnection for this request
return new AnonWebUserConnection(webSessionResources);
Expand Down