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

PHOENIX-6074 Let PQS Act As An Admin Tool Rest Endpoint #48

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions phoenix-queryserver-it/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -105,12 +105,12 @@
<artifactId>phoenix-client</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.phoenix</groupId>
<artifactId>phoenix-core</artifactId>
<scope>test</scope>
<classifier>tests</classifier>
</dependency>
<!-- <dependency>-->
<!-- <groupId>org.apache.phoenix</groupId>-->
<!-- <artifactId>phoenix-core</artifactId>-->
<!-- <scope>test</scope>-->
<!-- <classifier>tests</classifier>-->
<!-- </dependency>-->
<dependency>
<groupId>org.apache.phoenix</groupId>
<artifactId>phoenix-queryserver-orchestrator</artifactId>
Expand Down
4 changes: 4 additions & 0 deletions phoenix-queryserver/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,10 @@
</dependency>

<!-- for tests -->
<dependency>
<groupId>org.apache.phoenix</groupId>
<artifactId>phoenix-core</artifactId>
</dependency>
<dependency>
<groupId>org.apache.phoenix</groupId>
<artifactId>phoenix-client</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,10 @@ public class QueryServerOptions {
public static final String DEFAULT_CLIENT_JARS_REPO = "";
public static final String DEFAULT_CLIENT_JARS_CONTEXT = "/maven";

// Admin rest defaults
public static final boolean DEFAULT_ADMIN_REST_ENABLED = false;
public static final String DEFAULT_ADMIN_REST_CONTEXT = "/admin";

// Common defaults
public static final String DEFAULT_EXTRA_JDBC_ARGUMENTS = "";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,4 +89,7 @@ public class QueryServerProperties {
public static final String CLIENT_JARS_ENABLED_ATTRIB = "phoenix.queryserver.client.jars.enabled";
public static final String CLIENT_JARS_REPO_ATTRIB = "phoenix.queryserver.client.jars.repo";
public static final String CLIENT_JARS_CONTEXT_ATTRIB = "phoenix.queryserver.client.jars.context";

public static final String ADMIN_REST_ENABLED = "phoenix.queryserver.admin.rest.enabled";
public static final String ADMIN_REST_CONTEXT_ATTRIB = "phoenix.queryserver.admin.rest.context";
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import org.apache.hadoop.conf.Configuration;
import org.apache.phoenix.queryserver.QueryServerOptions;
import org.apache.phoenix.queryserver.QueryServerProperties;
import org.apache.phoenix.queryserver.server.customizers.AdminServerCustomizer;
import org.apache.phoenix.queryserver.server.customizers.HostedClientJarsServerCustomizer;
import org.eclipse.jetty.server.Server;
import org.slf4j.Logger;
Expand Down Expand Up @@ -71,6 +72,13 @@ public List<ServerCustomizer<Server>> createServerCustomizers(Configuration conf
LOG.warn("Empty value provided for {}, ignoring", QueryServerProperties.CLIENT_JARS_REPO_ATTRIB);
}
}
// if (conf.getBoolean(QueryServerProperties.ADMIN_REST_ENABLED, QueryServerOptions.DEFAULT_ADMIN_REST_ENABLED)) {
String contextPath = conf.get(QueryServerProperties.ADMIN_REST_CONTEXT_ATTRIB,
QueryServerOptions.DEFAULT_ADMIN_REST_CONTEXT);
LOG.info("Creating admin HTTP endpoint {}", contextPath);
AdminServerCustomizer customizer = new AdminServerCustomizer(contextPath);
customizers.add(customizer);
// }
return Collections.unmodifiableList(customizers);
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
* 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.phoenix.queryserver.server.admin;

/**
*
*/
public enum AdminCommand {
IndexTool, IndexScrutiny
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/*
* 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.phoenix.queryserver.server.admin;

import java.util.Map;

import org.apache.htrace.fasterxml.jackson.annotation.JsonProperty;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dont' use the HTrace jackson package.


/**
*
*/
public class AdminCommandRequest {
@JsonProperty(required = true)
private AdminCommand command;
private Map<String, String> parameters;

public AdminCommandRequest() {

}

public AdminCommandRequest(AdminCommand command, Map<String, String> parameters) {
this.command = command;
this.parameters = parameters;
}

public AdminCommand getCommand() {
return command;
}

public void setCommand(AdminCommand command) {
this.command = command;
}

public Map<String, String> getParameters() {
return parameters;
}

public void setParameters(Map<String, String> parameters) {
this.parameters = parameters;
}

public String[] getParametersAsInputArgs() {
String[] args = parameters != null ? new String[parameters.size()] : new String[0];
if (parameters != null) {
int index = 0;
for (String key : parameters.keySet()) {
args[index++] = "-" + key + " " + parameters.get(key);
}
}
return args;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/*
* 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.phoenix.queryserver.server.admin;


import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.util.Tool;
import org.apache.hadoop.util.ToolRunner;
import org.apache.htrace.fasterxml.jackson.databind.ObjectMapper;
import org.apache.phoenix.mapreduce.index.IndexScrutinyTool;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.handler.AbstractHandler;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import org.apache.phoenix.mapreduce.index.IndexTool;
/**
*
*/
public class AdminServerHandler extends AbstractHandler {
@Override
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
if ("POST".equalsIgnoreCase(baseRequest.getMethod())) {
response.setContentType("application/json");
try {
AdminCommandRequest adminCommand = parseRequest(baseRequest.getInputStream());
response.setStatus(HttpServletResponse.SC_OK);
Tool tool = null;
switch (adminCommand.getCommand()) {
case IndexTool:
tool = new IndexTool();
break;
case IndexScrutiny:
tool = new IndexScrutinyTool();
break;
default:
throw new IllegalArgumentException("Unsupported tool: " + adminCommand.getCommand());
}
int runStatus = ToolRunner.run(tool, adminCommand.getParametersAsInputArgs());
} catch (Exception e) {

}
response.getWriter().println("<h1>Hello OneHandler</h1>");
response.flushBuffer();
}

}

private AdminCommandRequest parseRequest(InputStream inputStream) throws IOException {
ObjectMapper mapper = new ObjectMapper();
return mapper.readValue(inputStream, AdminCommandRequest.class);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* 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.phoenix.queryserver.server.customizers;
import org.apache.phoenix.queryserver.server.admin.AdminServerHandler;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.handler.ContextHandler;

/**
*
*/
public class AdminServerCustomizer extends ContextCustomizer {

public AdminServerCustomizer(String contextPath) {
super(contextPath);
}

@Override
protected Handler createHandler(String contextPath) {
ContextHandler ctx = new ContextHandler(contextPath);
ctx.setAllowNullPathInfo(true);
ctx.setHandler(new AdminServerHandler());
return ctx;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/*
* 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.phoenix.queryserver.server.customizers;

import org.apache.calcite.avatica.server.ServerCustomizer;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.server.handler.HandlerList;
import org.eclipse.jetty.server.handler.ResourceHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.util.Arrays;

/**
* A context based customizer
*/
public abstract class ContextCustomizer implements ServerCustomizer<Server> {
private static final Logger LOG = LoggerFactory.getLogger(ContextCustomizer.class);

private final String contextPath;

/**
* @param contextPath The HTTP path which the repository will be hosted at
*/
protected ContextCustomizer(String contextPath) {
this.contextPath = contextPath;
}

@Override
public void customize(Server server) {
Handler[] handlers = server.getHandlers();
if (handlers.length != 1) {
LOG.warn("Observed handlers on server {}", Arrays.toString(handlers));
throw new IllegalStateException("Expected to find one handler");
}
HandlerList list = (HandlerList) handlers[0];
Handler[] realHandlers = list.getChildHandlers();
Handler[] newHandlers = new Handler[realHandlers.length + 1];
newHandlers[0] = createHandler(contextPath);
System.arraycopy(realHandlers, 0, newHandlers, 1, realHandlers.length);
server.setHandler(new HandlerList(newHandlers));
}

protected abstract Handler createHandler(String contextPath);
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,42 +32,28 @@
/**
* Hosts a Maven repository from local filesystem over HTTP from within PQS.
*/
public class HostedClientJarsServerCustomizer implements ServerCustomizer<Server> {
public class HostedClientJarsServerCustomizer extends ContextCustomizer {
private static final Logger LOG = LoggerFactory.getLogger(HostedClientJarsServerCustomizer.class);

private final File repoRoot;
private final String contextPath;

/**
* @param localMavenRepoRoot The path to the Phoenix-built maven repository on the local filesystem
* @param contextPath The HTTP path which the repository will be hosted at
*/
public HostedClientJarsServerCustomizer(File localMavenRepoRoot, String contextPath) {
super(contextPath);
this.repoRoot = localMavenRepoRoot;
this.contextPath = contextPath;
}

@Override
public void customize(Server server) {
Handler[] handlers = server.getHandlers();
if (handlers.length != 1) {
LOG.warn("Observed handlers on server {}", Arrays.toString(handlers));
throw new IllegalStateException("Expected to find one handler");
}
HandlerList list = (HandlerList) handlers[0];

protected Handler createHandler(String contextPath) {
ContextHandler ctx = new ContextHandler(contextPath);
ResourceHandler resource = new ResourceHandler();
resource.setDirAllowed(true);
resource.setDirectoriesListed(false);
resource.setResourceBase(repoRoot.getAbsolutePath());
ctx.setHandler(resource);

Handler[] realHandlers = list.getChildHandlers();

Handler[] newHandlers = new Handler[realHandlers.length + 1];
newHandlers[0] = ctx;
System.arraycopy(realHandlers, 0, newHandlers, 1, realHandlers.length);
server.setHandler(new HandlerList(newHandlers));
return ctx;
}
}
Loading