You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@calcite.apache.org by el...@apache.org on 2017/04/01 20:36:00 UTC
[11/37] calcite git commit: [CALCITE-1717] Remove avatica from the
tree
http://git-wip-us.apache.org/repos/asf/calcite/blob/5289d343/avatica/server/src/main/java/org/apache/calcite/avatica/jdbc/JdbcResultSet.java
----------------------------------------------------------------------
diff --git a/avatica/server/src/main/java/org/apache/calcite/avatica/jdbc/JdbcResultSet.java b/avatica/server/src/main/java/org/apache/calcite/avatica/jdbc/JdbcResultSet.java
deleted file mode 100644
index 17b33f8..0000000
--- a/avatica/server/src/main/java/org/apache/calcite/avatica/jdbc/JdbcResultSet.java
+++ /dev/null
@@ -1,215 +0,0 @@
-/*
- * 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.calcite.avatica.jdbc;
-
-import org.apache.calcite.avatica.AvaticaStatement;
-import org.apache.calcite.avatica.Meta;
-import org.apache.calcite.avatica.util.DateTimeUtils;
-
-import java.sql.Array;
-import java.sql.Date;
-import java.sql.ResultSet;
-import java.sql.ResultSetMetaData;
-import java.sql.SQLException;
-import java.sql.Struct;
-import java.sql.Time;
-import java.sql.Timestamp;
-import java.sql.Types;
-import java.util.ArrayList;
-import java.util.Calendar;
-import java.util.List;
-import java.util.TreeMap;
-
-/** Implementation of {@link org.apache.calcite.avatica.Meta.MetaResultSet}
- * upon a JDBC {@link java.sql.ResultSet}.
- *
- * @see org.apache.calcite.avatica.jdbc.JdbcMeta */
-class JdbcResultSet extends Meta.MetaResultSet {
- protected JdbcResultSet(String connectionId, int statementId,
- boolean ownStatement, Meta.Signature signature, Meta.Frame firstFrame) {
- this(connectionId, statementId, ownStatement, signature, firstFrame, -1L);
- }
-
- protected JdbcResultSet(String connectionId, int statementId,
- boolean ownStatement, Meta.Signature signature, Meta.Frame firstFrame,
- long updateCount) {
- super(connectionId, statementId, ownStatement, signature, firstFrame, updateCount);
- }
-
- /** Creates a result set. */
- public static JdbcResultSet create(String connectionId, int statementId,
- ResultSet resultSet) {
- // -1 still limits to 100 but -2 does not limit to any number
- return create(connectionId, statementId, resultSet,
- JdbcMeta.UNLIMITED_COUNT);
- }
-
- /** Creates a result set with maxRowCount.
- *
- * <p>If {@code maxRowCount} is -2 ({@link JdbcMeta#UNLIMITED_COUNT}),
- * returns an unlimited number of rows in a single frame; any other
- * negative value (typically -1) returns an unlimited number of rows
- * in frames of the default frame size. */
- public static JdbcResultSet create(String connectionId, int statementId,
- ResultSet resultSet, int maxRowCount) {
- try {
- Meta.Signature sig = JdbcMeta.signature(resultSet.getMetaData());
- return create(connectionId, statementId, resultSet, maxRowCount, sig);
- } catch (SQLException e) {
- throw new RuntimeException(e);
- }
- }
-
- public static JdbcResultSet create(String connectionId, int statementId,
- ResultSet resultSet, int maxRowCount, Meta.Signature signature) {
- try {
- final Calendar calendar = DateTimeUtils.calendar();
- final int fetchRowCount;
- if (maxRowCount == JdbcMeta.UNLIMITED_COUNT) {
- fetchRowCount = -1;
- } else if (maxRowCount < 0L) {
- fetchRowCount = AvaticaStatement.DEFAULT_FETCH_SIZE;
- } else if (maxRowCount > AvaticaStatement.DEFAULT_FETCH_SIZE) {
- fetchRowCount = AvaticaStatement.DEFAULT_FETCH_SIZE;
- } else {
- fetchRowCount = maxRowCount;
- }
- final Meta.Frame firstFrame = frame(null, resultSet, 0, fetchRowCount, calendar);
- if (firstFrame.done) {
- resultSet.close();
- }
- return new JdbcResultSet(connectionId, statementId, true, signature,
- firstFrame);
- } catch (SQLException e) {
- throw new RuntimeException(e);
- }
- }
-
- /** Creates a empty result set with empty frame */
- public static JdbcResultSet empty(String connectionId, int statementId,
- Meta.Signature signature) {
- return new JdbcResultSet(connectionId, statementId, true, signature,
- Meta.Frame.EMPTY);
- }
-
- /** Creates a result set that only has an update count. */
- public static JdbcResultSet count(String connectionId, int statementId,
- int updateCount) {
- return new JdbcResultSet(connectionId, statementId, true, null, null, updateCount);
- }
-
- /** Creates a frame containing a given number or unlimited number of rows
- * from a result set. */
- static Meta.Frame frame(StatementInfo info, ResultSet resultSet, long offset,
- int fetchMaxRowCount, Calendar calendar) throws SQLException {
- final ResultSetMetaData metaData = resultSet.getMetaData();
- final int columnCount = metaData.getColumnCount();
- final int[] types = new int[columnCount];
- for (int i = 0; i < types.length; i++) {
- types[i] = metaData.getColumnType(i + 1);
- }
- final List<Object> rows = new ArrayList<>();
- // Meta prepare/prepareAndExecute 0 return 0 row and done
- boolean done = fetchMaxRowCount == 0;
- for (int i = 0; fetchMaxRowCount < 0 || i < fetchMaxRowCount; i++) {
- final boolean hasRow;
- if (null != info) {
- hasRow = info.next();
- } else {
- hasRow = resultSet.next();
- }
- if (!hasRow) {
- done = true;
- resultSet.close();
- break;
- }
- Object[] columns = new Object[columnCount];
- for (int j = 0; j < columnCount; j++) {
- columns[j] = getValue(resultSet, types[j], j, calendar);
- }
- rows.add(columns);
- }
- return new Meta.Frame(offset, done, rows);
- }
-
- private static Object getValue(ResultSet resultSet, int type, int j,
- Calendar calendar) throws SQLException {
- switch (type) {
- case Types.BIGINT:
- final long aLong = resultSet.getLong(j + 1);
- return aLong == 0 && resultSet.wasNull() ? null : aLong;
- case Types.INTEGER:
- final int anInt = resultSet.getInt(j + 1);
- return anInt == 0 && resultSet.wasNull() ? null : anInt;
- case Types.SMALLINT:
- final short aShort = resultSet.getShort(j + 1);
- return aShort == 0 && resultSet.wasNull() ? null : aShort;
- case Types.TINYINT:
- final byte aByte = resultSet.getByte(j + 1);
- return aByte == 0 && resultSet.wasNull() ? null : aByte;
- case Types.DOUBLE:
- case Types.FLOAT:
- final double aDouble = resultSet.getDouble(j + 1);
- return aDouble == 0D && resultSet.wasNull() ? null : aDouble;
- case Types.REAL:
- final float aFloat = resultSet.getFloat(j + 1);
- return aFloat == 0D && resultSet.wasNull() ? null : aFloat;
- case Types.DATE:
- final Date aDate = resultSet.getDate(j + 1, calendar);
- return aDate == null
- ? null
- : (int) (aDate.getTime() / DateTimeUtils.MILLIS_PER_DAY);
- case Types.TIME:
- final Time aTime = resultSet.getTime(j + 1, calendar);
- return aTime == null
- ? null
- : (int) (aTime.getTime() % DateTimeUtils.MILLIS_PER_DAY);
- case Types.TIMESTAMP:
- final Timestamp aTimestamp = resultSet.getTimestamp(j + 1, calendar);
- return aTimestamp == null ? null : aTimestamp.getTime();
- case Types.ARRAY:
- final Array array = resultSet.getArray(j + 1);
- if (null == array) {
- return null;
- }
- ResultSet arrayValues = array.getResultSet();
- TreeMap<Integer, Object> map = new TreeMap<>();
- while (arrayValues.next()) {
- // column 1 is the index in the array, column 2 is the value.
- // Recurse on `getValue` to unwrap nested types correctly.
- // `j` is zero-indexed and incremented for us, thus we have `1` being used twice.
- map.put(arrayValues.getInt(1), getValue(arrayValues, array.getBaseType(), 1, calendar));
- }
- // If the result set is not in the same order as the actual Array, TreeMap fixes that.
- // Need to make a concrete list to ensure Jackson serialization.
- //return new ListLike<Object>(new ArrayList<>(map.values()), ListLikeType.ARRAY);
- return new ArrayList<>(map.values());
- case Types.STRUCT:
- Struct struct = resultSet.getObject(j + 1, Struct.class);
- Object[] attrs = struct.getAttributes();
- List<Object> list = new ArrayList<>(attrs.length);
- for (Object o : attrs) {
- list.add(o);
- }
- return list;
- default:
- return resultSet.getObject(j + 1);
- }
- }
-}
-
-// End JdbcResultSet.java
http://git-wip-us.apache.org/repos/asf/calcite/blob/5289d343/avatica/server/src/main/java/org/apache/calcite/avatica/jdbc/StatementInfo.java
----------------------------------------------------------------------
diff --git a/avatica/server/src/main/java/org/apache/calcite/avatica/jdbc/StatementInfo.java b/avatica/server/src/main/java/org/apache/calcite/avatica/jdbc/StatementInfo.java
deleted file mode 100644
index c4f8e21..0000000
--- a/avatica/server/src/main/java/org/apache/calcite/avatica/jdbc/StatementInfo.java
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * 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.calcite.avatica.jdbc;
-
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.SQLFeatureNotSupportedException;
-import java.sql.Statement;
-
-/**
- * All we know about a statement. Encapsulates a {@link ResultSet}.
- */
-public class StatementInfo {
- private volatile Boolean relativeSupported = null;
-
- final Statement statement; // sometimes a PreparedStatement
- private ResultSet resultSet;
- private long position = 0;
-
- // True when setResultSet(ResultSet) is called to let us determine the difference between
- // a null ResultSet (from an update) from the lack of a ResultSet.
- private boolean resultsInitialized = false;
-
- public StatementInfo(Statement statement) {
- // May be null when coming from a DatabaseMetaData call
- this.statement = statement;
- }
-
- // Visible for testing
- void setPosition(long position) {
- this.position = position;
- }
-
- // Visible for testing
- long getPosition() {
- return this.position;
- }
-
- /**
- * Set a ResultSet on this object.
- *
- * @param resultSet The current ResultSet
- */
- public void setResultSet(ResultSet resultSet) {
- resultsInitialized = true;
- this.resultSet = resultSet;
- }
-
- /**
- * @return The {@link ResultSet} for this Statement, may be null.
- */
- public ResultSet getResultSet() {
- return this.resultSet;
- }
-
- /**
- * @return True if {@link #setResultSet(ResultSet)} was ever invoked.
- */
- public boolean isResultSetInitialized() {
- return resultsInitialized;
- }
-
- /**
- * @see ResultSet#next()
- */
- public boolean next() throws SQLException {
- return _next(resultSet);
- }
-
- boolean _next(ResultSet results) throws SQLException {
- boolean ret = results.next();
- position++;
- return ret;
- }
-
- /**
- * Consumes <code>offset - position</code> elements from the {@link ResultSet}.
- *
- * @param offset The offset to advance to
- * @return True if the resultSet was advanced to the current point, false if insufficient rows
- * were present to advance to the requested offset.
- */
- public boolean advanceResultSetToOffset(ResultSet results, long offset) throws SQLException {
- if (offset < 0 || offset < position) {
- throw new IllegalArgumentException("Offset should be "
- + " non-negative and not less than the current position. " + offset + ", " + position);
- }
- if (position >= offset) {
- return true;
- }
-
- if (null == relativeSupported) {
- Boolean moreResults = null;
- synchronized (this) {
- if (null == relativeSupported) {
- try {
- moreResults = advanceByRelative(results, offset);
- relativeSupported = true;
- } catch (SQLFeatureNotSupportedException e) {
- relativeSupported = false;
- }
- }
- }
-
- if (null != moreResults) {
- // We figured out whether or not relative is supported.
- // Make sure we actually do the necessary work.
- if (!relativeSupported) {
- // We avoided calling advanceByNext in the synchronized block earlier.
- moreResults = advanceByNext(results, offset);
- }
-
- return moreResults;
- }
-
- // Another thread updated the RELATIVE_SUPPORTED before we did, fall through.
- }
-
- if (relativeSupported) {
- return advanceByRelative(results, offset);
- } else {
- return advanceByNext(results, offset);
- }
- }
-
- private boolean advanceByRelative(ResultSet results, long offset) throws SQLException {
- long diff = offset - position;
- while (diff > Integer.MAX_VALUE) {
- if (!results.relative(Integer.MAX_VALUE)) {
- // Avoid updating position until relative succeeds.
- position += Integer.MAX_VALUE;
- return false;
- }
- // Avoid updating position until relative succeeds.
- position += Integer.MAX_VALUE;
- diff -= Integer.MAX_VALUE;
- }
- boolean ret = results.relative((int) diff);
- // Make sure we only update the position after successfully calling relative(int).
- position += diff;
- return ret;
- }
-
- private boolean advanceByNext(ResultSet results, long offset) throws SQLException {
- while (position < offset) {
- // Advance while maintaining `position`
- if (!_next(results)) {
- return false;
- }
- }
-
- return true;
- }
-}
-
-// End StatementInfo.java
http://git-wip-us.apache.org/repos/asf/calcite/blob/5289d343/avatica/server/src/main/java/org/apache/calcite/avatica/jdbc/package-info.java
----------------------------------------------------------------------
diff --git a/avatica/server/src/main/java/org/apache/calcite/avatica/jdbc/package-info.java b/avatica/server/src/main/java/org/apache/calcite/avatica/jdbc/package-info.java
deleted file mode 100644
index 8b8fb76..0000000
--- a/avatica/server/src/main/java/org/apache/calcite/avatica/jdbc/package-info.java
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * 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.
- */
-
-/** Implements an Avatica provider on top of an existing JDBC data source. */
-package org.apache.calcite.avatica.jdbc;
-
-
-// End package-info.java
http://git-wip-us.apache.org/repos/asf/calcite/blob/5289d343/avatica/server/src/main/java/org/apache/calcite/avatica/server/AbstractAvaticaHandler.java
----------------------------------------------------------------------
diff --git a/avatica/server/src/main/java/org/apache/calcite/avatica/server/AbstractAvaticaHandler.java b/avatica/server/src/main/java/org/apache/calcite/avatica/server/AbstractAvaticaHandler.java
deleted file mode 100644
index 3a7ccf3..0000000
--- a/avatica/server/src/main/java/org/apache/calcite/avatica/server/AbstractAvaticaHandler.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * 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.calcite.avatica.server;
-
-import org.apache.calcite.avatica.AvaticaSeverity;
-import org.apache.calcite.avatica.remote.AuthenticationType;
-import org.apache.calcite.avatica.remote.Service.ErrorResponse;
-
-import org.eclipse.jetty.server.handler.AbstractHandler;
-
-import java.io.IOException;
-import java.net.HttpURLConnection;
-import java.util.Collections;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-/**
- * Base-class for Avatica implemented Jetty Handlers.
- */
-public abstract class AbstractAvaticaHandler extends AbstractHandler
- implements MetricsAwareAvaticaHandler {
-
- private static final ErrorResponse UNAUTHORIZED_ERROR = new ErrorResponse(
- Collections.<String>emptyList(), "User is not authenticated",
- ErrorResponse.UNAUTHORIZED_ERROR_CODE, ErrorResponse.UNAUTHORIZED_SQL_STATE,
- AvaticaSeverity.ERROR, null);
-
- /**
- * Determines if a request is permitted to be executed. The server may require authentication
- * and the login mechanism might have failed. This check verifies that only authenticated
- * users are permitted through when the server is requiring authentication. When a user
- * is disallowed, a status code and response will be automatically written to the provided
- * <code>response</code> and the caller should return immediately.
- *
- * @param serverConfig The server's configuration
- * @param request The user's request
- * @param response The response to the user's request
- * @return True if request can proceed, false otherwise.
- */
- public boolean isUserPermitted(AvaticaServerConfiguration serverConfig,
- HttpServletRequest request, HttpServletResponse response) throws IOException {
- // Make sure that we drop any unauthenticated users out first.
- if (null != serverConfig) {
- if (AuthenticationType.SPNEGO == serverConfig.getAuthenticationType()) {
- String remoteUser = request.getRemoteUser();
- if (null == remoteUser) {
- response.setStatus(HttpURLConnection.HTTP_UNAUTHORIZED);
- response.getOutputStream().write(UNAUTHORIZED_ERROR.serialize().toByteArray());
- return false;
- }
- }
- }
-
- return true;
- }
-}
-
-// End AbstractAvaticaHandler.java
http://git-wip-us.apache.org/repos/asf/calcite/blob/5289d343/avatica/server/src/main/java/org/apache/calcite/avatica/server/AvaticaHandler.java
----------------------------------------------------------------------
diff --git a/avatica/server/src/main/java/org/apache/calcite/avatica/server/AvaticaHandler.java b/avatica/server/src/main/java/org/apache/calcite/avatica/server/AvaticaHandler.java
deleted file mode 100644
index 42b13c9..0000000
--- a/avatica/server/src/main/java/org/apache/calcite/avatica/server/AvaticaHandler.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * 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.calcite.avatica.server;
-
-import org.apache.calcite.avatica.remote.Service.RpcMetadataResponse;
-
-import org.eclipse.jetty.server.Handler;
-
-/**
- * A custom interface that extends the Jetty interface to enable extra control within Avatica.
- */
-public interface AvaticaHandler extends Handler {
-
- void setServerRpcMetadata(RpcMetadataResponse metadata);
-
-}
-
-// End AvaticaHandler.java
http://git-wip-us.apache.org/repos/asf/calcite/blob/5289d343/avatica/server/src/main/java/org/apache/calcite/avatica/server/AvaticaJsonHandler.java
----------------------------------------------------------------------
diff --git a/avatica/server/src/main/java/org/apache/calcite/avatica/server/AvaticaJsonHandler.java b/avatica/server/src/main/java/org/apache/calcite/avatica/server/AvaticaJsonHandler.java
deleted file mode 100644
index b639183..0000000
--- a/avatica/server/src/main/java/org/apache/calcite/avatica/server/AvaticaJsonHandler.java
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * 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.calcite.avatica.server;
-
-import org.apache.calcite.avatica.AvaticaUtils;
-import org.apache.calcite.avatica.metrics.MetricsSystem;
-import org.apache.calcite.avatica.metrics.Timer;
-import org.apache.calcite.avatica.metrics.Timer.Context;
-import org.apache.calcite.avatica.metrics.noop.NoopMetricsSystem;
-import org.apache.calcite.avatica.remote.Handler.HandlerResponse;
-import org.apache.calcite.avatica.remote.JsonHandler;
-import org.apache.calcite.avatica.remote.Service;
-import org.apache.calcite.avatica.remote.Service.RpcMetadataResponse;
-import org.apache.calcite.avatica.util.UnsynchronizedBuffer;
-
-import org.eclipse.jetty.server.Request;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.io.IOException;
-import java.util.Objects;
-import java.util.concurrent.Callable;
-
-import javax.servlet.ServletException;
-import javax.servlet.ServletInputStream;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import static org.apache.calcite.avatica.remote.MetricsHelper.concat;
-
-/**
- * Jetty handler that executes Avatica JSON request-responses.
- */
-public class AvaticaJsonHandler extends AbstractAvaticaHandler {
- private static final Logger LOG = LoggerFactory.getLogger(AvaticaJsonHandler.class);
-
- final Service service;
- final JsonHandler jsonHandler;
-
- final MetricsSystem metrics;
- final Timer requestTimer;
-
- final ThreadLocal<UnsynchronizedBuffer> threadLocalBuffer;
-
- final AvaticaServerConfiguration serverConfig;
-
- public AvaticaJsonHandler(Service service) {
- this(service, NoopMetricsSystem.getInstance(), null);
- }
-
- public AvaticaJsonHandler(Service service, MetricsSystem metrics) {
- this(service, metrics, null);
- }
-
- public AvaticaJsonHandler(Service service, MetricsSystem metrics,
- AvaticaServerConfiguration serverConfig) {
- this.service = Objects.requireNonNull(service);
- this.metrics = Objects.requireNonNull(metrics);
- // Avatica doesn't have a Guava dependency
- this.jsonHandler = new JsonHandler(service, this.metrics);
-
- // Metrics
- this.requestTimer = this.metrics.getTimer(
- concat(AvaticaJsonHandler.class, MetricsAwareAvaticaHandler.REQUEST_TIMER_NAME));
-
- this.threadLocalBuffer = new ThreadLocal<UnsynchronizedBuffer>() {
- @Override public UnsynchronizedBuffer initialValue() {
- return new UnsynchronizedBuffer();
- }
- };
-
- this.serverConfig = serverConfig;
- }
-
- public void handle(String target, Request baseRequest,
- HttpServletRequest request, HttpServletResponse response)
- throws IOException, ServletException {
- try (final Context ctx = requestTimer.start()) {
- if (!isUserPermitted(serverConfig, request, response)) {
- LOG.debug("HTTP request from {} is unauthenticated and authentication is required",
- request.getRemoteAddr());
- return;
- }
-
- response.setContentType("application/json;charset=utf-8");
- response.setStatus(HttpServletResponse.SC_OK);
- if (request.getMethod().equals("POST")) {
- // First look for a request in the header, then look in the body.
- // The latter allows very large requests without hitting HTTP 413.
- String rawRequest = request.getHeader("request");
- if (rawRequest == null) {
- // Avoid a new buffer creation for every HTTP request
- final UnsynchronizedBuffer buffer = threadLocalBuffer.get();
- try (ServletInputStream inputStream = request.getInputStream()) {
- rawRequest = AvaticaUtils.readFully(inputStream, buffer);
- } finally {
- // Reset the offset into the buffer after we're done
- buffer.reset();
- }
- }
- final String jsonRequest =
- new String(rawRequest.getBytes("ISO-8859-1"), "UTF-8");
- LOG.trace("request: {}", jsonRequest);
-
- HandlerResponse<String> jsonResponse;
- try {
- if (null != serverConfig && serverConfig.supportsImpersonation()) {
- jsonResponse = serverConfig.doAsRemoteUser(request.getRemoteUser(),
- request.getRemoteAddr(), new Callable<HandlerResponse<String>>() {
- @Override public HandlerResponse<String> call() {
- return jsonHandler.apply(jsonRequest);
- }
- });
- } else {
- jsonResponse = jsonHandler.apply(jsonRequest);
- }
- } catch (Exception e) {
- LOG.debug("Error invoking request from {}", baseRequest.getRemoteAddr(), e);
- jsonResponse = jsonHandler.convertToErrorResponse(e);
- }
-
- LOG.trace("response: {}", jsonResponse);
- baseRequest.setHandled(true);
- // Set the status code and write out the response.
- response.setStatus(jsonResponse.getStatusCode());
- response.getWriter().println(jsonResponse.getResponse());
- }
- }
- }
-
- @Override public void setServerRpcMetadata(RpcMetadataResponse metadata) {
- // Set the metadata for the normal service calls
- service.setRpcMetadata(metadata);
- // Also add it to the handler to include with exceptions
- jsonHandler.setRpcMetadata(metadata);
- }
-
- @Override public MetricsSystem getMetrics() {
- return metrics;
- }
-}
-
-// End AvaticaJsonHandler.java
http://git-wip-us.apache.org/repos/asf/calcite/blob/5289d343/avatica/server/src/main/java/org/apache/calcite/avatica/server/AvaticaProtobufHandler.java
----------------------------------------------------------------------
diff --git a/avatica/server/src/main/java/org/apache/calcite/avatica/server/AvaticaProtobufHandler.java b/avatica/server/src/main/java/org/apache/calcite/avatica/server/AvaticaProtobufHandler.java
deleted file mode 100644
index f8723f1..0000000
--- a/avatica/server/src/main/java/org/apache/calcite/avatica/server/AvaticaProtobufHandler.java
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- * 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.calcite.avatica.server;
-
-import org.apache.calcite.avatica.AvaticaUtils;
-import org.apache.calcite.avatica.metrics.MetricsSystem;
-import org.apache.calcite.avatica.metrics.Timer;
-import org.apache.calcite.avatica.metrics.Timer.Context;
-import org.apache.calcite.avatica.metrics.noop.NoopMetricsSystem;
-import org.apache.calcite.avatica.remote.Handler.HandlerResponse;
-import org.apache.calcite.avatica.remote.MetricsHelper;
-import org.apache.calcite.avatica.remote.ProtobufHandler;
-import org.apache.calcite.avatica.remote.ProtobufTranslation;
-import org.apache.calcite.avatica.remote.ProtobufTranslationImpl;
-import org.apache.calcite.avatica.remote.Service;
-import org.apache.calcite.avatica.remote.Service.RpcMetadataResponse;
-import org.apache.calcite.avatica.util.UnsynchronizedBuffer;
-
-import org.eclipse.jetty.server.Request;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.io.IOException;
-import java.util.Objects;
-import java.util.concurrent.Callable;
-
-import javax.servlet.ServletException;
-import javax.servlet.ServletInputStream;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-/**
- * Jetty handler that executes Avatica JSON request-responses.
- */
-public class AvaticaProtobufHandler extends AbstractAvaticaHandler {
- private static final Logger LOG = LoggerFactory.getLogger(AvaticaJsonHandler.class);
-
- private final Service service;
- private final ProtobufHandler pbHandler;
- private final ProtobufTranslation protobufTranslation;
- private final MetricsSystem metrics;
- private final Timer requestTimer;
- private final AvaticaServerConfiguration serverConfig;
-
- final ThreadLocal<UnsynchronizedBuffer> threadLocalBuffer;
-
- public AvaticaProtobufHandler(Service service) {
- this(service, NoopMetricsSystem.getInstance());
- }
-
- public AvaticaProtobufHandler(Service service, MetricsSystem metrics) {
- this(service, metrics, null);
- }
-
- public AvaticaProtobufHandler(Service service, MetricsSystem metrics,
- AvaticaServerConfiguration serverConfig) {
- this.service = Objects.requireNonNull(service);
- this.metrics = Objects.requireNonNull(metrics);
-
- this.requestTimer = this.metrics.getTimer(
- MetricsHelper.concat(AvaticaProtobufHandler.class,
- MetricsAwareAvaticaHandler.REQUEST_TIMER_NAME));
-
- this.protobufTranslation = new ProtobufTranslationImpl();
- this.pbHandler = new ProtobufHandler(service, protobufTranslation, metrics);
-
- this.threadLocalBuffer = new ThreadLocal<UnsynchronizedBuffer>() {
- @Override public UnsynchronizedBuffer initialValue() {
- return new UnsynchronizedBuffer();
- }
- };
-
- this.serverConfig = serverConfig;
- }
-
- public void handle(String target, Request baseRequest,
- HttpServletRequest request, HttpServletResponse response)
- throws IOException, ServletException {
- try (final Context ctx = this.requestTimer.start()) {
- // Check if the user is OK to proceed.
- if (!isUserPermitted(serverConfig, request, response)) {
- LOG.debug("HTTP request from {} is unauthenticated and authentication is required",
- request.getRemoteAddr());
- return;
- }
-
- response.setContentType("application/octet-stream;charset=utf-8");
- response.setStatus(HttpServletResponse.SC_OK);
- if (request.getMethod().equals("POST")) {
- final byte[] requestBytes;
- // Avoid a new buffer creation for every HTTP request
- final UnsynchronizedBuffer buffer = threadLocalBuffer.get();
- try (ServletInputStream inputStream = request.getInputStream()) {
- requestBytes = AvaticaUtils.readFullyToBytes(inputStream, buffer);
- } finally {
- buffer.reset();
- }
-
- HandlerResponse<byte[]> handlerResponse;
- try {
- if (null != serverConfig && serverConfig.supportsImpersonation()) {
- // Invoke the ProtobufHandler inside as doAs for the remote user.
- handlerResponse = serverConfig.doAsRemoteUser(request.getRemoteUser(),
- request.getRemoteAddr(), new Callable<HandlerResponse<byte[]>>() {
- @Override public HandlerResponse<byte[]> call() {
- return pbHandler.apply(requestBytes);
- }
- });
- } else {
- handlerResponse = pbHandler.apply(requestBytes);
- }
- } catch (Exception e) {
- LOG.debug("Error invoking request from {}", baseRequest.getRemoteAddr(), e);
- // Catch at the highest level of exceptions
- handlerResponse = pbHandler.convertToErrorResponse(e);
- }
-
- baseRequest.setHandled(true);
- response.setStatus(handlerResponse.getStatusCode());
- response.getOutputStream().write(handlerResponse.getResponse());
- }
- }
- }
-
- @Override public void setServerRpcMetadata(RpcMetadataResponse metadata) {
- // Set the metadata for the normal service calls
- service.setRpcMetadata(metadata);
- // Also add it to the handler to include with exceptions
- pbHandler.setRpcMetadata(metadata);
- }
-
- @Override public MetricsSystem getMetrics() {
- return this.metrics;
- }
-
-}
-
-// End AvaticaProtobufHandler.java
http://git-wip-us.apache.org/repos/asf/calcite/blob/5289d343/avatica/server/src/main/java/org/apache/calcite/avatica/server/AvaticaServerConfiguration.java
----------------------------------------------------------------------
diff --git a/avatica/server/src/main/java/org/apache/calcite/avatica/server/AvaticaServerConfiguration.java b/avatica/server/src/main/java/org/apache/calcite/avatica/server/AvaticaServerConfiguration.java
deleted file mode 100644
index dd843a4..0000000
--- a/avatica/server/src/main/java/org/apache/calcite/avatica/server/AvaticaServerConfiguration.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * 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.calcite.avatica.server;
-
-import org.apache.calcite.avatica.remote.AuthenticationType;
-
-import java.util.concurrent.Callable;
-
-/**
- * A generic configuration interface that users can implement to configure the {@link HttpServer}.
- */
-public interface AvaticaServerConfiguration {
-
- /**
- * Returns the type of authentication the {@link HttpServer} should use.
- * @return An enum corresponding to an authentication mechanism
- */
- AuthenticationType getAuthenticationType();
-
- /**
- * Returns the Kerberos realm to use for the server's login. Only relevant when
- * {@link #getAuthenticationType()} returns {@link AuthenticationType#SPNEGO}.
- *
- * @return The Kerberos realm for the server login, or null if not applicable.
- */
- String getKerberosRealm();
-
- /**
- * Returns the Kerberos principal that the Avatica server should log in as.
- *
- * @return A Kerberos principal, or null if not applicable.
- */
- String getKerberosPrincipal();
-
- /**
- * Returns the array of allowed roles for login. Only applicable when
- * {@link #getAuthenticationType()} returns {@link AuthenticationType#BASIC} or
- * {@link AuthenticationType#DIGEST}.
- *
- * @return An array of allowed login roles, or null.
- */
- String[] getAllowedRoles();
-
- /**
- * Returns the name of the realm to use in coordination with the properties files specified
- * by {@link #getHashLoginServiceProperties()}. Only applicable when
- * {@link #getAuthenticationType()} returns {@link AuthenticationType#BASIC} or
- * {@link AuthenticationType#DIGEST}.
- *
- * @return A realm for the HashLoginService, or null.
- */
- String getHashLoginServiceRealm();
-
- /**
- * Returns the path to a properties file that contains users and realms. Only applicable when
- * {@link #getAuthenticationType()} returns {@link AuthenticationType#BASIC} or
- * {@link AuthenticationType#DIGEST}.
- *
- * @return A realm for the HashLoginService, or null.
- */
- String getHashLoginServiceProperties();
-
- /**
- * Returns true if the Avatica server should run user requests at that remote user. Otherwise,
- * all requests are run as the Avatica server user (which is the default).
- *
- * @return True if impersonation is enabled, false otherwise.
- */
- boolean supportsImpersonation();
-
- /**
- * Invokes the given <code>action</code> as the <code>remoteUserName</code>. This will only be
- * invoked if {@link #supportsImpersonation()} returns <code>true</code>.
- *
- * @param remoteUserName The remote user making a request to the Avatica server.
- * @param remoteAddress The address the remote user is making the request from.
- * @return The result from the Callable.
- */
- <T> T doAsRemoteUser(String remoteUserName, String remoteAddress, Callable<T> action)
- throws Exception;
-}
-
-// End AvaticaServerConfiguration.java
http://git-wip-us.apache.org/repos/asf/calcite/blob/5289d343/avatica/server/src/main/java/org/apache/calcite/avatica/server/DelegatingAvaticaHandler.java
----------------------------------------------------------------------
diff --git a/avatica/server/src/main/java/org/apache/calcite/avatica/server/DelegatingAvaticaHandler.java b/avatica/server/src/main/java/org/apache/calcite/avatica/server/DelegatingAvaticaHandler.java
deleted file mode 100644
index fff176d..0000000
--- a/avatica/server/src/main/java/org/apache/calcite/avatica/server/DelegatingAvaticaHandler.java
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * 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.calcite.avatica.server;
-
-import org.apache.calcite.avatica.remote.Service.RpcMetadataResponse;
-
-import org.eclipse.jetty.server.Handler;
-import org.eclipse.jetty.server.Request;
-import org.eclipse.jetty.server.Server;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.io.IOException;
-import java.util.Objects;
-
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-/**
- * An AvaticaHandler implementation that delegates to a provided Jetty Handler instance.
- *
- * <p>This implementation provides a no-op implementation for
- * {@link #setServerRpcMetadata(org.apache.calcite.avatica.remote.Service.RpcMetadataResponse)}.
- *
- * <p>Does not implement {@link MetricsAwareAvaticaHandler} as this implementation is only presented
- * for backwards compatibility.
- */
-public class DelegatingAvaticaHandler implements AvaticaHandler {
- private static final Logger LOG = LoggerFactory.getLogger(DelegatingAvaticaHandler.class);
-
- private final Handler handler;
-
- public DelegatingAvaticaHandler(Handler handler) {
- this.handler = Objects.requireNonNull(handler);
- }
-
- @Override public void handle(String target, Request baseRequest, HttpServletRequest request,
- HttpServletResponse response) throws IOException, ServletException {
- handler.handle(target, baseRequest, request, response);
- }
-
- @Override public void setServer(Server server) {
- handler.setServer(server);
- }
-
- @Override public Server getServer() {
- return handler.getServer();
- }
-
- @Override public void destroy() {
- handler.destroy();
- }
-
- @Override public void start() throws Exception {
- handler.start();
- }
-
- @Override public void stop() throws Exception {
- handler.stop();
- }
-
- @Override public boolean isRunning() {
- return handler.isRunning();
- }
-
- @Override public boolean isStarted() {
- return handler.isStarted();
- }
-
- @Override public boolean isStarting() {
- return handler.isStarting();
- }
-
- @Override public boolean isStopping() {
- return handler.isStopping();
- }
-
- @Override public boolean isStopped() {
- return handler.isStopped();
- }
-
- @Override public boolean isFailed() {
- return handler.isFailed();
- }
-
- @Override public void addLifeCycleListener(Listener listener) {
- handler.addLifeCycleListener(listener);
- }
-
- @Override public void removeLifeCycleListener(Listener listener) {
- handler.removeLifeCycleListener(listener);
- }
-
- @Override public void setServerRpcMetadata(RpcMetadataResponse metadata) {
- LOG.warn("Setting RpcMetadata is not implemented for DelegatingAvaticaHandler");
- }
-
-}
-
-// End DelegatingAvaticaHandler.java
http://git-wip-us.apache.org/repos/asf/calcite/blob/5289d343/avatica/server/src/main/java/org/apache/calcite/avatica/server/DoAsRemoteUserCallback.java
----------------------------------------------------------------------
diff --git a/avatica/server/src/main/java/org/apache/calcite/avatica/server/DoAsRemoteUserCallback.java b/avatica/server/src/main/java/org/apache/calcite/avatica/server/DoAsRemoteUserCallback.java
deleted file mode 100644
index c2be80f..0000000
--- a/avatica/server/src/main/java/org/apache/calcite/avatica/server/DoAsRemoteUserCallback.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * 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.calcite.avatica.server;
-
-import java.util.concurrent.Callable;
-
-/**
- * A callback which the server can invoke to allow implementations to control additional logic
- * about whether or not a client from a specific host should be run.
- * <p>For example, complex logic could be supplied to control whether clientA from host1 is
- * permitted to execute queries. This logic is deferred upon the user to implement.
- */
-public interface DoAsRemoteUserCallback {
-
- /**
- * Invokes the given <code>action</code> as the <code>remoteUserName</code>.
- *
- * @param remoteUserName The remote user making a request to the Avatica server.
- * @param remoteAddress The address the remote user is making the request from.
- * @param action The operation the Avatica server wants to run as <code>remoteUserName</code>.
- * @return The result from the Callable.
- */
- <T> T doAsRemoteUser(String remoteUserName, String remoteAddress, Callable<T> action)
- throws Exception;
-
-}
-
-// End DoAsRemoteUserCallback.java
http://git-wip-us.apache.org/repos/asf/calcite/blob/5289d343/avatica/server/src/main/java/org/apache/calcite/avatica/server/HandlerFactory.java
----------------------------------------------------------------------
diff --git a/avatica/server/src/main/java/org/apache/calcite/avatica/server/HandlerFactory.java b/avatica/server/src/main/java/org/apache/calcite/avatica/server/HandlerFactory.java
deleted file mode 100644
index 6c70d1b..0000000
--- a/avatica/server/src/main/java/org/apache/calcite/avatica/server/HandlerFactory.java
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * 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.calcite.avatica.server;
-
-import org.apache.calcite.avatica.metrics.MetricsSystem;
-import org.apache.calcite.avatica.metrics.MetricsSystemConfiguration;
-import org.apache.calcite.avatica.metrics.MetricsSystemFactory;
-import org.apache.calcite.avatica.metrics.MetricsSystemLoader;
-import org.apache.calcite.avatica.metrics.noop.NoopMetricsSystem;
-import org.apache.calcite.avatica.metrics.noop.NoopMetricsSystemConfiguration;
-import org.apache.calcite.avatica.remote.Driver;
-import org.apache.calcite.avatica.remote.Service;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.ServiceLoader;
-
-/**
- * Factory that instantiates the desired implementation, typically differing on the method
- * used to serialize messages, for use in the Avatica server.
- */
-public class HandlerFactory {
- private static final Logger LOG = LoggerFactory.getLogger(HandlerFactory.class);
-
- /**
- * Constructs the desired implementation for the given serialization method with metrics.
- *
- * @param service The underlying {@link Service}.
- * @param serialization The desired message serialization.
- * @return The {@link AvaticaHandler}.
- */
- public AvaticaHandler getHandler(Service service, Driver.Serialization serialization) {
- return getHandler(service, serialization, NoopMetricsSystemConfiguration.getInstance());
- }
-
- /**
- * Constructs the desired implementation for the given serialization method and server
- * configuration with metrics.
- *
- * @param service The underlying {@link Service}.
- * @param serialization The desired message serialization.
- * @param serverConfig Avatica server configuration or null.
- * @return The {@link AvaticaHandler}.
- */
- public AvaticaHandler getHandler(Service service, Driver.Serialization serialization,
- AvaticaServerConfiguration serverConfig) {
- return getHandler(service, serialization, NoopMetricsSystemConfiguration.getInstance(),
- serverConfig);
- }
-
- /**
- * Constructs the desired implementation for the given serialization method with metrics.
- *
- * @param service The underlying {@link Service}.
- * @param serialization The desired message serialization.
- * @param metricsConfig Configuration for the {@link MetricsSystem}.
- * @return The {@link AvaticaHandler}.
- */
- public AvaticaHandler getHandler(Service service, Driver.Serialization serialization,
- MetricsSystemConfiguration<?> metricsConfig) {
- return getHandler(service, serialization, metricsConfig, null);
- }
-
- /**
- * Constructs the desired implementation for the given serialization method and server
- * configuration with metrics.
- *
- * @param service The underlying {@link Service}
- * @param serialization The serializatio mechanism to use
- * @param metricsConfig Configuration for the {@link MetricsSystem}.
- * @param serverConfig Avatica server configuration or null
- * @return An {@link AvaticaHandler}
- */
- public AvaticaHandler getHandler(Service service, Driver.Serialization serialization,
- MetricsSystemConfiguration<?> metricsConfig, AvaticaServerConfiguration serverConfig) {
- if (null == metricsConfig) {
- metricsConfig = NoopMetricsSystemConfiguration.getInstance();
- }
- MetricsSystem metrics = MetricsSystemLoader.load(metricsConfig);
-
- switch (serialization) {
- case JSON:
- return new AvaticaJsonHandler(service, metrics, serverConfig);
- case PROTOBUF:
- return new AvaticaProtobufHandler(service, metrics, serverConfig);
- default:
- throw new IllegalArgumentException("Unknown Avatica handler for " + serialization.name());
- }
- }
-
- /**
- * Load a {@link MetricsSystem} using ServiceLoader to create a {@link MetricsSystemFactory}.
- *
- * @param config State to pass to the factory for initialization.
- * @return A {@link MetricsSystem} instance.
- */
- MetricsSystem loadMetricsSystem(MetricsSystemConfiguration<?> config) {
- ServiceLoader<MetricsSystemFactory> loader = ServiceLoader.load(MetricsSystemFactory.class);
- List<MetricsSystemFactory> availableFactories = new ArrayList<>();
- for (MetricsSystemFactory factory : loader) {
- availableFactories.add(factory);
- }
-
- if (1 == availableFactories.size()) {
- // One and only one instance -- what we want
- MetricsSystemFactory factory = availableFactories.get(0);
- LOG.info("Loaded MetricsSystem {}", factory.getClass());
- return factory.create(config);
- } else if (availableFactories.isEmpty()) {
- // None-provided default to no metrics
- LOG.info("No metrics implementation available on classpath. Using No-op implementation");
- return NoopMetricsSystem.getInstance();
- } else {
- // Tell the user they're doing something wrong, and choose the first impl.
- StringBuilder sb = new StringBuilder();
- for (MetricsSystemFactory factory : availableFactories) {
- if (sb.length() > 0) {
- sb.append(", ");
- }
- sb.append(factory.getClass());
- }
- LOG.warn("Found multiple MetricsSystemFactory implementations: {}."
- + " Using No-op implementation", sb);
- return NoopMetricsSystem.getInstance();
- }
- }
-}
-
-// End HandlerFactory.java
http://git-wip-us.apache.org/repos/asf/calcite/blob/5289d343/avatica/server/src/main/java/org/apache/calcite/avatica/server/HttpServer.java
----------------------------------------------------------------------
diff --git a/avatica/server/src/main/java/org/apache/calcite/avatica/server/HttpServer.java b/avatica/server/src/main/java/org/apache/calcite/avatica/server/HttpServer.java
deleted file mode 100644
index 4c871f0..0000000
--- a/avatica/server/src/main/java/org/apache/calcite/avatica/server/HttpServer.java
+++ /dev/null
@@ -1,826 +0,0 @@
-/*
- * 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.calcite.avatica.server;
-
-import org.apache.calcite.avatica.metrics.MetricsSystemConfiguration;
-import org.apache.calcite.avatica.remote.AuthenticationType;
-import org.apache.calcite.avatica.remote.Driver.Serialization;
-import org.apache.calcite.avatica.remote.Service;
-import org.apache.calcite.avatica.remote.Service.RpcMetadataResponse;
-
-import org.eclipse.jetty.security.Authenticator;
-import org.eclipse.jetty.security.ConstraintMapping;
-import org.eclipse.jetty.security.ConstraintSecurityHandler;
-import org.eclipse.jetty.security.HashLoginService;
-import org.eclipse.jetty.security.LoginService;
-import org.eclipse.jetty.security.authentication.BasicAuthenticator;
-import org.eclipse.jetty.security.authentication.DigestAuthenticator;
-import org.eclipse.jetty.security.authentication.SpnegoAuthenticator;
-import org.eclipse.jetty.server.Connector;
-import org.eclipse.jetty.server.Handler;
-import org.eclipse.jetty.server.Server;
-import org.eclipse.jetty.server.ServerConnector;
-import org.eclipse.jetty.server.handler.DefaultHandler;
-import org.eclipse.jetty.server.handler.HandlerList;
-import org.eclipse.jetty.util.security.Constraint;
-import org.eclipse.jetty.util.ssl.SslContextFactory;
-import org.eclipse.jetty.util.thread.QueuedThreadPool;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.io.File;
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-import java.security.Principal;
-import java.security.PrivilegedAction;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Set;
-import java.util.concurrent.Callable;
-
-import javax.security.auth.Subject;
-import javax.security.auth.kerberos.KerberosPrincipal;
-import javax.security.auth.login.AppConfigurationEntry;
-import javax.security.auth.login.LoginContext;
-import javax.security.auth.login.LoginException;
-
-/**
- * Avatica HTTP server.
- *
- * <p>If you need to change the server's configuration, override the
- * {@link #configureConnector(ServerConnector, int)} method in a derived class.
- */
-public class HttpServer {
- private static final Logger LOG = LoggerFactory.getLogger(HttpServer.class);
-
- private Server server;
- private int port = -1;
- private final AvaticaHandler handler;
- private final AvaticaServerConfiguration config;
- private final Subject subject;
- private final SslContextFactory sslFactory;
-
- @Deprecated
- public HttpServer(Handler handler) {
- this(wrapJettyHandler(handler));
- }
-
- /**
- * Constructs an {@link HttpServer} which binds to an ephemeral port.
- * @param handler The Handler to run
- */
- public HttpServer(AvaticaHandler handler) {
- this(0, handler);
- }
-
- @Deprecated
- public HttpServer(int port, Handler handler) {
- this(port, wrapJettyHandler(handler));
- }
-
- /**
- * Constructs an {@link HttpServer} with no additional configuration.
- * @param port The listen port
- * @param handler The Handler to run
- */
- public HttpServer(int port, AvaticaHandler handler) {
- this(port, handler, null);
- }
-
- /**
- * Constructs an {@link HttpServer}.
- * @param port The listen port
- * @param handler The Handler to run
- * @param config Optional configuration for the server
- */
- public HttpServer(int port, AvaticaHandler handler, AvaticaServerConfiguration config) {
- this(port, handler, config, null);
- }
-
- /**
- * Constructs an {@link HttpServer}.
- * @param port The listen port
- * @param handler The Handler to run
- * @param config Optional configuration for the server
- * @param subject The javax.security Subject for the server, or null
- */
- public HttpServer(int port, AvaticaHandler handler, AvaticaServerConfiguration config,
- Subject subject) {
- this(port, handler, config, subject, null);
- }
-
- /**
- * Constructs an {@link HttpServer}.
- * @param port The listen port
- * @param handler The Handler to run
- * @param config Optional configuration for the server
- * @param subject The javax.security Subject for the server, or null
- * @param sslFactory A configured SslContextFactory, or null
- */
- public HttpServer(int port, AvaticaHandler handler, AvaticaServerConfiguration config,
- Subject subject, SslContextFactory sslFactory) {
- this.port = port;
- this.handler = handler;
- this.config = config;
- this.subject = subject;
- this.sslFactory = sslFactory;
- }
-
- static AvaticaHandler wrapJettyHandler(Handler handler) {
- if (handler instanceof AvaticaHandler) {
- return (AvaticaHandler) handler;
- }
- // Backwards compatibility, noop's the AvaticaHandler interface
- return new DelegatingAvaticaHandler(handler);
- }
-
- public void start() {
- if (null != subject) {
- // Run the start in the privileged block (as the kerberos-identified user)
- Subject.doAs(subject, new PrivilegedAction<Void>() {
- @Override public Void run() {
- internalStart();
- return null;
- }
- });
- } else {
- internalStart();
- }
- }
-
- protected void internalStart() {
- if (server != null) {
- throw new RuntimeException("Server is already started");
- }
-
- final QueuedThreadPool threadPool = new QueuedThreadPool();
- threadPool.setDaemon(true);
- server = new Server(threadPool);
- server.manage(threadPool);
-
- final ServerConnector connector = configureConnector(getConnector(), port);
- ConstraintSecurityHandler securityHandler = null;
-
- if (null != this.config) {
- switch (config.getAuthenticationType()) {
- case SPNEGO:
- // Get the Handler for SPNEGO authentication
- securityHandler = configureSpnego(server, connector, this.config);
- break;
- case BASIC:
- securityHandler = configureBasicAuthentication(server, connector, config);
- break;
- case DIGEST:
- securityHandler = configureDigestAuthentication(server, connector, config);
- break;
- default:
- // Pass
- break;
- }
- }
-
- server.setConnectors(new Connector[] { connector });
-
- // Default to using the handler that was passed in
- final HandlerList handlerList = new HandlerList();
- Handler avaticaHandler = handler;
-
- // Wrap the provided handler for security if we made one
- if (null != securityHandler) {
- securityHandler.setHandler(handler);
- avaticaHandler = securityHandler;
- }
-
- handlerList.setHandlers(new Handler[] {avaticaHandler, new DefaultHandler()});
-
- server.setHandler(handlerList);
- try {
- server.start();
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
- port = connector.getLocalPort();
-
- LOG.info("Service listening on port {}.", getPort());
-
- // Set the information about the address for this server
- try {
- this.handler.setServerRpcMetadata(createRpcServerMetadata(connector));
- } catch (UnknownHostException e) {
- // Failed to do the DNS lookup, bail out.
- throw new RuntimeException(e);
- }
- }
-
- private ServerConnector getConnector() {
- if (null == sslFactory) {
- return new ServerConnector(server);
- }
- return new ServerConnector(server, sslFactory);
- }
-
- private RpcMetadataResponse createRpcServerMetadata(ServerConnector connector) throws
- UnknownHostException {
- String host = connector.getHost();
- if (null == host) {
- // "null" means binding to all interfaces, we need to pick one so the client gets a real
- // address and not "0.0.0.0" or similar.
- host = InetAddress.getLocalHost().getHostName();
- }
-
- final int port = connector.getLocalPort();
-
- return new RpcMetadataResponse(
- String.format(Locale.ROOT, "%s:%d", host, port));
- }
-
- /**
- * Configures the <code>connector</code> given the <code>config</code> for using SPNEGO.
- *
- * @param connector The connector to configure
- * @param config The configuration
- */
- protected ConstraintSecurityHandler configureSpnego(Server server, ServerConnector connector,
- AvaticaServerConfiguration config) {
- final String realm = Objects.requireNonNull(config.getKerberosRealm());
- final String principal = Objects.requireNonNull(config.getKerberosPrincipal());
-
- // A customization of SpnegoLoginService to explicitly set the server's principal, otherwise
- // we would have to require a custom file to set the server's principal.
- PropertyBasedSpnegoLoginService spnegoLoginService =
- new PropertyBasedSpnegoLoginService(realm, principal);
-
- // Roles are "realms" for Kerberos/SPNEGO
- final String[] allowedRealms = getAllowedRealms(realm, config);
-
- return configureCommonAuthentication(server, connector, config, Constraint.__SPNEGO_AUTH,
- allowedRealms, new SpnegoAuthenticator(), realm, spnegoLoginService);
- }
-
- protected String[] getAllowedRealms(String serverRealm, AvaticaServerConfiguration config) {
- // Roles are "realms" for Kerberos/SPNEGO
- String[] allowedRealms = new String[] {serverRealm};
- // By default, only the server's realm is allowed, but other realms can also be allowed.
- if (null != config.getAllowedRoles()) {
- allowedRealms = new String[config.getAllowedRoles().length + 1];
- allowedRealms[0] = serverRealm;
- System.arraycopy(config.getAllowedRoles(), 0, allowedRealms, 1,
- config.getAllowedRoles().length);
- }
- return allowedRealms;
- }
-
- protected ConstraintSecurityHandler configureBasicAuthentication(Server server,
- ServerConnector connector, AvaticaServerConfiguration config) {
- final String[] allowedRoles = config.getAllowedRoles();
- final String realm = config.getHashLoginServiceRealm();
- final String loginServiceProperties = config.getHashLoginServiceProperties();
-
- HashLoginService loginService = new HashLoginService(realm, loginServiceProperties);
- server.addBean(loginService);
-
- return configureCommonAuthentication(server, connector, config, Constraint.__BASIC_AUTH,
- allowedRoles, new BasicAuthenticator(), null, loginService);
- }
-
- protected ConstraintSecurityHandler configureDigestAuthentication(Server server,
- ServerConnector connector, AvaticaServerConfiguration config) {
- final String[] allowedRoles = config.getAllowedRoles();
- final String realm = config.getHashLoginServiceRealm();
- final String loginServiceProperties = config.getHashLoginServiceProperties();
-
- HashLoginService loginService = new HashLoginService(realm, loginServiceProperties);
- server.addBean(loginService);
-
- return configureCommonAuthentication(server, connector, config, Constraint.__DIGEST_AUTH,
- allowedRoles, new DigestAuthenticator(), null, loginService);
- }
-
- protected ConstraintSecurityHandler configureCommonAuthentication(Server server,
- ServerConnector connector, AvaticaServerConfiguration config, String constraintName,
- String[] allowedRoles, Authenticator authenticator, String realm,
- LoginService loginService) {
-
- Constraint constraint = new Constraint();
- constraint.setName(constraintName);
- constraint.setRoles(allowedRoles);
- // This is telling Jetty to not allow unauthenticated requests through (very important!)
- constraint.setAuthenticate(true);
-
- ConstraintMapping cm = new ConstraintMapping();
- cm.setConstraint(constraint);
- cm.setPathSpec("/*");
-
- ConstraintSecurityHandler sh = new ConstraintSecurityHandler();
- sh.setAuthenticator(authenticator);
- sh.setLoginService(loginService);
- sh.setConstraintMappings(new ConstraintMapping[]{cm});
- sh.setRealmName(realm);
-
- return sh;
- }
-
- /**
- * Configures the server connector.
- *
- * <p>The default configuration sets a timeout of 1 minute and disables
- * TCP linger time.
- *
- * <p>To change the configuration, override this method in a derived class.
- * The overriding method must call its super method.
- *
- * @param connector connector to be configured
- * @param port port number handed over in constructor
- */
- protected ServerConnector configureConnector(ServerConnector connector, int port) {
- connector.setIdleTimeout(60 * 1000);
- connector.setSoLingerTime(-1);
- connector.setPort(port);
- return connector;
- }
-
- protected AvaticaServerConfiguration getConfig() {
- return this.config;
- }
-
- public void stop() {
- if (server == null) {
- throw new RuntimeException("Server is already stopped");
- }
-
- LOG.info("Service terminating.");
- try {
- final Server server1 = server;
- port = -1;
- server = null;
- server1.stop();
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
- }
-
- public void join() throws InterruptedException {
- server.join();
- }
-
- public int getPort() {
- return port;
- }
-
- /**
- * Builder class for creating instances of {@link HttpServer}.
- */
- public static class Builder {
- private int port;
-
- private Service service;
- private Serialization serialization;
- private AvaticaHandler handler = null;
-
- private MetricsSystemConfiguration<?> metricsConfig;
-
- private AuthenticationType authenticationType = AuthenticationType.NONE;
-
- private String kerberosPrincipal;
- private String kerberosRealm;
- private File keytab;
-
- private DoAsRemoteUserCallback remoteUserCallback;
-
- private String loginServiceRealm;
- private String loginServiceProperties;
- private String[] loginServiceAllowedRoles;
-
- private boolean usingTLS = false;
- private File keystore;
- private String keystorePassword;
- private File truststore;
- private String truststorePassword;
-
- public Builder() {}
-
- public Builder withPort(int port) {
- this.port = port;
- return this;
- }
-
- /**
- * Sets the {@link Service} and {@link Serialization} information necessary to construct
- * the appropriate {@link AvaticaHandler}.
- *
- * @param service The Avatica service
- * @param serialization The serialization method
- * @return <code>this</code>
- */
- public Builder withHandler(Service service, Serialization serialization) {
- this.service = Objects.requireNonNull(service);
- this.serialization = Objects.requireNonNull(serialization);
- return this;
- }
-
- /**
- * Sets an {@link AvaticaHandler} directly on the builder. Most users will not want to use
- * this method and should instead use {@link #withHandler(Service, Serialization)}.
- *
- * @param handler The handler
- * @return <code>this</code>
- */
- public Builder withHandler(AvaticaHandler handler) {
- this.handler = Objects.requireNonNull(handler);
- return this;
- }
-
- /**
- * Sets the given configuration to enable metrics collection in the server.
- *
- * @param metricsConfig Configuration object for metrics.
- * @return <code>this</code>
- */
- public Builder withMetricsConfiguration(MetricsSystemConfiguration<?> metricsConfig) {
- this.metricsConfig = Objects.requireNonNull(metricsConfig);
- return this;
- }
-
- /**
- * Configures the server to use SPNEGO authentication. This method requires that the
- * <code>principal</code> contains the Kerberos realm. Invoking this method overrides any
- * previous call which configures authentication.
- *
- * @param principal A kerberos principal with the realm required.
- * @return <code>this</code>
- */
- public Builder withSpnego(String principal) {
- return withSpnego(principal, (String[]) null);
- }
-
- /**
- * Configures the server to use SPNEGO authentication. This method requires that the
- * <code>principal</code> contains the Kerberos realm. Invoking this method overrides any
- * previous call which configures authentication. Invoking this method overrides any previous
- * call which configures authentication. By default, only principals from the server's realm are
- * permitted, but additional realms can be allowed using <code>additionalAllowedRealms</code>.
- *
- * @param principal A kerberos principal with the realm required.
- * @param additionalAllowedRealms Any additional realms, other than the server's realm, which
- * should be allowed to authenticate against the server. Can be null.
- * @return <code>this</code>
- */
- public Builder withSpnego(String principal, String[] additionalAllowedRealms) {
- int index = Objects.requireNonNull(principal).lastIndexOf('@');
- if (-1 == index) {
- throw new IllegalArgumentException("Could not find '@' symbol in '" + principal
- + "' to parse the Kerberos realm from the principal");
- }
- final String realm = principal.substring(index + 1);
- return withSpnego(principal, realm, additionalAllowedRealms);
- }
-
- /**
- * Configures the server to use SPNEGO authentication. It is required that callers are logged
- * in via Kerberos already or have provided the necessary configuration to automatically log
- * in via JAAS (using the <code>java.security.auth.login.config</code> system property) before
- * starting the {@link HttpServer}. Invoking this method overrides any previous call which
- * configures authentication.
- *
- * @param principal The kerberos principal
- * @param realm The kerberos realm
- * @return <code>this</code>
- */
- public Builder withSpnego(String principal, String realm) {
- return this.withSpnego(principal, realm, null);
- }
-
- /**
- * Configures the server to use SPNEGO authentication. It is required that callers are logged
- * in via Kerberos already or have provided the necessary configuration to automatically log
- * in via JAAS (using the <code>java.security.auth.login.config</code> system property) before
- * starting the {@link HttpServer}. Invoking this method overrides any previous call which
- * configures authentication. By default, only principals from the server's realm are permitted,
- * but additional realms can be allowed using <code>additionalAllowedRealms</code>.
- *
- * @param principal The kerberos principal
- * @param realm The kerberos realm
- * @param additionalAllowedRealms Any additional realms, other than the server's realm, which
- * should be allowed to authenticate against the server. Can be null.
- * @return <code>this</code>
- */
- public Builder withSpnego(String principal, String realm, String[] additionalAllowedRealms) {
- this.authenticationType = AuthenticationType.SPNEGO;
- this.kerberosPrincipal = Objects.requireNonNull(principal);
- this.kerberosRealm = Objects.requireNonNull(realm);
- this.loginServiceAllowedRoles = additionalAllowedRealms;
- return this;
- }
-
- /**
- * Sets a keytab to be used to perform a Kerberos login automatically (without the use of JAAS).
- *
- * @param keytab A KeyTab file for the server's login.
- * @return <code>this</code>
- */
- public Builder withAutomaticLogin(File keytab) {
- this.keytab = Objects.requireNonNull(keytab);
- return this;
- }
-
- /**
- * Sets a callback implementation to defer the logic on how to run an action as a given user and
- * if the action should be permitted for that user.
- *
- * @param remoteUserCallback User-provided implementation of the callback
- * @return <code>this</code>
- */
- public Builder withImpersonation(DoAsRemoteUserCallback remoteUserCallback) {
- this.remoteUserCallback = Objects.requireNonNull(remoteUserCallback);
- return this;
- }
-
- /**
- * Configures the server to use HTTP Basic authentication. The <code>properties</code> must
- * be in a form consumable by Jetty. Invoking this method overrides any previous call which
- * configures authentication. This authentication is supplementary to the JDBC-provided user
- * authentication interfaces and should only be used when those interfaces are not used.
- *
- * @param properties Location of a properties file parseable by Jetty which contains users and
- * passwords.
- * @param allowedRoles An array of allowed roles in the properties file
- * @return <code>this</code>
- */
- public Builder withBasicAuthentication(String properties, String[] allowedRoles) {
- return withAuthentication(AuthenticationType.BASIC, properties, allowedRoles);
- }
-
- /**
- * Configures the server to use HTTP Digest authentication. The <code>properties</code> must
- * be in a form consumable by Jetty. Invoking this method overrides any previous call which
- * configures authentication. This authentication is supplementary to the JDBC-provided user
- * authentication interfaces and should only be used when those interfaces are not used.
- *
- * @param properties Location of a properties file parseable by Jetty which contains users and
- * passwords.
- * @param allowedRoles An array of allowed roles in the properties file
- * @return <code>this</code>
- */
- public Builder withDigestAuthentication(String properties, String[] allowedRoles) {
- return withAuthentication(AuthenticationType.DIGEST, properties, allowedRoles);
- }
-
- private Builder withAuthentication(AuthenticationType authType, String properties,
- String[] allowedRoles) {
- this.loginServiceRealm = "Avatica";
- this.authenticationType = authType;
- this.loginServiceProperties = Objects.requireNonNull(properties);
- this.loginServiceAllowedRoles = Objects.requireNonNull(allowedRoles);
- return this;
- }
-
- /**
- * Configures the server to use TLS for wire encryption.
- *
- * @param keystore The server's keystore
- * @param keystorePassword The keystore's password
- * @param truststore The truststore containing the key used to generate the server's key
- * @param truststorePassword The truststore's password
- * @return <code>this</code>
- */
- public Builder withTLS(File keystore, String keystorePassword, File truststore,
- String truststorePassword) {
- this.usingTLS = true;
- this.keystore = Objects.requireNonNull(keystore);
- this.keystorePassword = Objects.requireNonNull(keystorePassword);
- this.truststore = Objects.requireNonNull(truststore);
- this.truststorePassword = Objects.requireNonNull(truststorePassword);
- return this;
- }
-
- /**
- * Builds the HttpServer instance from <code>this</code>.
- * @return An HttpServer.
- */
- public HttpServer build() {
- final AvaticaServerConfiguration serverConfig;
- final Subject subject;
- switch (authenticationType) {
- case NONE:
- serverConfig = null;
- subject = null;
- break;
- case BASIC:
- case DIGEST:
- // Build the configuration for BASIC or DIGEST authentication.
- serverConfig = buildUserAuthenticationConfiguration(this);
- subject = null;
- break;
- case SPNEGO:
- if (usingTLS) {
- throw new IllegalArgumentException("TLS has not been tested wtih SPNEGO");
- }
- if (null != keytab) {
- LOG.debug("Performing Kerberos login with {} as {}", keytab, kerberosPrincipal);
- subject = loginViaKerberos(this);
- } else {
- LOG.debug("Not performing Kerberos login");
- subject = null;
- }
- serverConfig = buildSpnegoConfiguration(this);
- break;
- default:
- throw new IllegalArgumentException("Unhandled AuthenticationType");
- }
-
- AvaticaHandler handler = buildHandler(this, serverConfig);
- SslContextFactory sslFactory = null;
- if (usingTLS) {
- sslFactory = new SslContextFactory();
- sslFactory.setKeyStorePath(this.keystore.getAbsolutePath());
- sslFactory.setKeyStorePassword(keystorePassword);
- sslFactory.setTrustStorePath(truststore.getAbsolutePath());
- sslFactory.setTrustStorePassword(truststorePassword);
- }
-
- return new HttpServer(port, handler, serverConfig, subject, sslFactory);
- }
-
- /**
- * Creates the appropriate {@link AvaticaHandler}.
- *
- * @param b The {@link Builder}.
- * @param config The Avatica server configuration
- * @return An {@link AvaticaHandler}.
- */
- private AvaticaHandler buildHandler(Builder b, AvaticaServerConfiguration config) {
- // The user provided a handler explicitly.
- if (null != b.handler) {
- return b.handler;
- }
-
- // Normal case, we create the handler for the user.
- HandlerFactory factory = new HandlerFactory();
- return factory.getHandler(b.service, b.serialization, b.metricsConfig, config);
- }
-
- /**
- * Builds an {@link AvaticaServerConfiguration} implementation for SPNEGO-based authentication.
- * @param b The {@link Builder}.
- * @return A configuration instance.
- */
- private AvaticaServerConfiguration buildSpnegoConfiguration(Builder b) {
- final String principal = b.kerberosPrincipal;
- final String realm = b.kerberosRealm;
- final String[] additionalAllowedRealms = b.loginServiceAllowedRoles;
- final DoAsRemoteUserCallback callback = b.remoteUserCallback;
- return new AvaticaServerConfiguration() {
-
- @Override public AuthenticationType getAuthenticationType() {
- return AuthenticationType.SPNEGO;
- }
-
- @Override public String getKerberosRealm() {
- return realm;
- }
-
- @Override public String getKerberosPrincipal() {
- return principal;
- }
-
- @Override public boolean supportsImpersonation() {
- return null != callback;
- }
-
- @Override public <T> T doAsRemoteUser(String remoteUserName, String remoteAddress,
- Callable<T> action) throws Exception {
- return callback.doAsRemoteUser(remoteUserName, remoteAddress, action);
- }
-
- @Override public String[] getAllowedRoles() {
- return additionalAllowedRealms;
- }
-
- @Override public String getHashLoginServiceRealm() {
- return null;
- }
-
- @Override public String getHashLoginServiceProperties() {
- return null;
- }
- };
- }
-
- private AvaticaServerConfiguration buildUserAuthenticationConfiguration(Builder b) {
- final AuthenticationType authType = b.authenticationType;
- final String[] allowedRoles = b.loginServiceAllowedRoles;
- final String realm = b.loginServiceRealm;
- final String properties = b.loginServiceProperties;
-
- return new AvaticaServerConfiguration() {
- @Override public AuthenticationType getAuthenticationType() {
- return authType;
- }
-
- @Override public String[] getAllowedRoles() {
- return allowedRoles;
- }
-
- @Override public String getHashLoginServiceRealm() {
- return realm;
- }
-
- @Override public String getHashLoginServiceProperties() {
- return properties;
- }
-
- // Unused
-
- @Override public String getKerberosRealm() {
- return null;
- }
-
- @Override public String getKerberosPrincipal() {
- return null;
- }
-
- @Override public boolean supportsImpersonation() {
- return false;
- }
-
- @Override public <T> T doAsRemoteUser(String remoteUserName, String remoteAddress,
- Callable<T> action) throws Exception {
- return null;
- }
- };
- }
-
- private Subject loginViaKerberos(Builder b) {
- Set<Principal> principals = new HashSet<Principal>();
- principals.add(new KerberosPrincipal(b.kerberosPrincipal));
-
- Subject subject = new Subject(false, principals, new HashSet<Object>(),
- new HashSet<Object>());
-
- KeytabJaasConf conf = new KeytabJaasConf(b.kerberosPrincipal, b.keytab.toString());
- String confName = "NotUsed";
- try {
- LoginContext loginContext = new LoginContext(confName, subject, null, conf);
- loginContext.login();
- return loginContext.getSubject();
- } catch (LoginException e) {
- throw new RuntimeException(e);
- }
- }
-
- /**
- * Javax Configuration class which always returns a configuration for our keytab-based
- * login.
- */
- private static class KeytabJaasConf extends javax.security.auth.login.Configuration {
- private final String principal;
- private final String keytab;
-
- private KeytabJaasConf(String principal, String keytab) {
- this.principal = principal;
- this.keytab = keytab;
- }
-
- @Override public AppConfigurationEntry[] getAppConfigurationEntry(String name) {
- Map<String, String> options = new HashMap<String, String>();
- options.put("storeKey", "true");
- options.put("principal", principal);
- options.put("keyTab", keytab);
- options.put("doNotPrompt", "true");
- options.put("useKeyTab", "true");
- options.put("isInitiator", "false");
- options.put("debug",
- System.getProperty("sun.security.krb5.debug", "false")
- .toLowerCase(Locale.ROOT));
-
- return new AppConfigurationEntry[] {new AppConfigurationEntry(getKrb5LoginModuleName(),
- AppConfigurationEntry.LoginModuleControlFlag.REQUIRED, options)};
- }
- }
-
- private static String getKrb5LoginModuleName() {
- return System.getProperty("java.vendor").contains("IBM")
- ? "com.ibm.security.auth.module.Krb5LoginModule"
- : "com.sun.security.auth.module.Krb5LoginModule";
- }
- }
-}
-
-// End HttpServer.java
http://git-wip-us.apache.org/repos/asf/calcite/blob/5289d343/avatica/server/src/main/java/org/apache/calcite/avatica/server/Main.java
----------------------------------------------------------------------
diff --git a/avatica/server/src/main/java/org/apache/calcite/avatica/server/Main.java b/avatica/server/src/main/java/org/apache/calcite/avatica/server/Main.java
deleted file mode 100644
index f2d546b..0000000
--- a/avatica/server/src/main/java/org/apache/calcite/avatica/server/Main.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * 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.calcite.avatica.server;
-
-import org.apache.calcite.avatica.Meta;
-import org.apache.calcite.avatica.remote.LocalService;
-import org.apache.calcite.avatica.remote.Service;
-
-import org.eclipse.jetty.server.handler.AbstractHandler;
-
-import java.lang.reflect.InvocationTargetException;
-import java.util.Arrays;
-
-/**
- * Jetty handler that executes Avatica JSON request-responses.
- */
-public class Main {
- private Main() {}
-
- public static void main(String[] args) throws InterruptedException, ClassNotFoundException,
- IllegalAccessException, InstantiationException, NoSuchMethodException,
- InvocationTargetException {
- HttpServer server = start(args);
- server.join();
- }
-
- /**
- * Factory that instantiates Jetty Handlers
- */
- public interface HandlerFactory {
- AbstractHandler createHandler(Service service);
- }
-
- private static final HandlerFactory JSON_HANDLER_FACTORY = new HandlerFactory() {
- public AbstractHandler createHandler(Service service) {
- return new AvaticaJsonHandler(service);
- }
- };
-
- /**
- * Creates and starts an {@link HttpServer} using JSON POJO serialization of requests/responses.
- *
- * <p>Arguments are as follows:
- * <ul>
- * <li>args[0]: the {@link org.apache.calcite.avatica.Meta.Factory} class
- * name
- * <li>args[1+]: arguments passed along to
- * {@link org.apache.calcite.avatica.Meta.Factory#create(java.util.List)}
- * </ul>
- *
- * @param args Command-line arguments
- */
- public static HttpServer start(String[] args) throws ClassNotFoundException,
- InstantiationException, IllegalAccessException, NoSuchMethodException,
- InvocationTargetException {
- return start(args, 8765, JSON_HANDLER_FACTORY);
- }
-
- /**
- * Creates and starts an {@link HttpServer} using the given factory to create the Handler.
- *
- * <p>Arguments are as follows:
- * <ul>
- * <li>args[0]: the {@link org.apache.calcite.avatica.Meta.Factory} class
- * name
- * <li>args[1+]: arguments passed along to
- * {@link org.apache.calcite.avatica.Meta.Factory#create(java.util.List)}
- * </ul>
- *
- * @param args Command-line arguments
- * @param port Server port to bind
- * @param handlerFactory Factory to create the handler used by the server
- */
- public static HttpServer start(String[] args, int port, HandlerFactory handlerFactory)
- throws ClassNotFoundException, InstantiationException, IllegalAccessException,
- NoSuchMethodException, InvocationTargetException {
- String factoryClassName = args[0];
- @SuppressWarnings("unchecked") Class<Meta.Factory> factoryClass =
- (Class<Meta.Factory>) Class.forName(factoryClassName);
- Meta.Factory factory = factoryClass.getConstructor().newInstance();
- Meta meta = factory.create(Arrays.asList(args).subList(1, args.length));
- Service service = new LocalService(meta);
- HttpServer server = new HttpServer(port,
- HttpServer.wrapJettyHandler(handlerFactory.createHandler(service)));
- server.start();
- return server;
- }
-}
-
-// End Main.java