IGNITE-2447: Renamed ODBC classes to follow naming convention.
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/9baf2668 Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/9baf2668 Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/9baf2668 Branch: refs/heads/ignite-1786 Commit: 9baf2668e00ed879e7f777d0b21d58aa81c900c3 Parents: a622561 Author: isapego <[email protected]> Authored: Mon Jan 25 18:17:07 2016 +0300 Committer: isapego <[email protected]> Committed: Mon Jan 25 18:17:07 2016 +0300 ---------------------------------------------------------------------- .../ignite/internal/GridKernalContext.java | 4 +- .../ignite/internal/GridKernalContextImpl.java | 10 +- .../apache/ignite/internal/IgniteKernal.java | 4 +- .../processors/odbc/GridOdbcColumnMeta.java | 125 ------- .../processors/odbc/GridOdbcCommandHandler.java | 337 ------------------ .../processors/odbc/GridOdbcProcessor.java | 160 --------- .../odbc/GridOdbcProtocolHandler.java | 40 --- .../processors/odbc/GridOdbcTableMeta.java | 89 ----- .../processors/odbc/OdbcColumnMeta.java | 125 +++++++ .../processors/odbc/OdbcCommandHandler.java | 337 ++++++++++++++++++ .../internal/processors/odbc/OdbcProcessor.java | 160 +++++++++ .../processors/odbc/OdbcProtocolHandler.java | 40 +++ .../internal/processors/odbc/OdbcTableMeta.java | 89 +++++ .../odbc/protocol/GridOdbcParser.java | 345 ------------------- .../odbc/protocol/GridTcpOdbcNioListener.java | 102 ------ .../odbc/protocol/GridTcpOdbcServer.java | 191 ---------- .../processors/odbc/protocol/OdbcParser.java | 345 +++++++++++++++++++ .../odbc/protocol/OdbcTcpNioListener.java | 102 ++++++ .../processors/odbc/protocol/OdbcTcpServer.java | 191 ++++++++++ .../odbc/request/GridOdbcRequest.java | 61 ---- .../odbc/request/OdbcQueryCloseRequest.java | 47 +++ .../odbc/request/OdbcQueryExecuteRequest.java | 85 +++++ .../odbc/request/OdbcQueryFetchRequest.java | 66 ++++ .../request/OdbcQueryGetColumnsMetaRequest.java | 84 +++++ .../request/OdbcQueryGetTablesMetaRequest.java | 105 ++++++ .../processors/odbc/request/OdbcRequest.java | 61 ++++ .../odbc/request/QueryCloseRequest.java | 47 --- .../odbc/request/QueryExecuteRequest.java | 85 ----- .../odbc/request/QueryFetchRequest.java | 66 ---- .../request/QueryGetColumnsMetaRequest.java | 84 ----- .../odbc/request/QueryGetTablesMetaRequest.java | 105 ------ .../odbc/response/GridOdbcResponse.java | 107 ------ .../odbc/response/OdbcQueryCloseResult.java | 39 +++ .../odbc/response/OdbcQueryExecuteResult.java | 55 +++ .../odbc/response/OdbcQueryFetchResult.java | 75 ++++ .../response/OdbcQueryGetColumnsMetaResult.java | 43 +++ .../response/OdbcQueryGetTablesMetaResult.java | 43 +++ .../processors/odbc/response/OdbcResponse.java | 107 ++++++ .../odbc/response/QueryCloseResult.java | 39 --- .../odbc/response/QueryExecuteResult.java | 55 --- .../odbc/response/QueryFetchResult.java | 75 ---- .../response/QueryGetColumnsMetaResult.java | 43 --- .../odbc/response/QueryGetTablesMetaResult.java | 43 --- 43 files changed, 2208 insertions(+), 2208 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ignite/blob/9baf2668/modules/core/src/main/java/org/apache/ignite/internal/GridKernalContext.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/GridKernalContext.java b/modules/core/src/main/java/org/apache/ignite/internal/GridKernalContext.java index e563478..b95d595 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/GridKernalContext.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/GridKernalContext.java @@ -48,7 +48,7 @@ import org.apache.ignite.internal.processors.igfs.IgfsHelper; import org.apache.ignite.internal.processors.igfs.IgfsProcessorAdapter; import org.apache.ignite.internal.processors.job.GridJobProcessor; import org.apache.ignite.internal.processors.jobmetrics.GridJobMetricsProcessor; -import org.apache.ignite.internal.processors.odbc.GridOdbcProcessor; +import org.apache.ignite.internal.processors.odbc.OdbcProcessor; import org.apache.ignite.internal.processors.offheap.GridOffHeapProcessor; import org.apache.ignite.internal.processors.platform.PlatformProcessor; import org.apache.ignite.internal.processors.plugin.IgnitePluginProcessor; @@ -316,7 +316,7 @@ public interface GridKernalContext extends Iterable<GridComponent> { * * @return ODBC processor. */ - public GridOdbcProcessor odbc(); + public OdbcProcessor odbc(); /** * @return Plugin processor. http://git-wip-us.apache.org/repos/asf/ignite/blob/9baf2668/modules/core/src/main/java/org/apache/ignite/internal/GridKernalContextImpl.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/GridKernalContextImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/GridKernalContextImpl.java index 81088b4..753dbe8 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/GridKernalContextImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/GridKernalContextImpl.java @@ -65,7 +65,7 @@ import org.apache.ignite.internal.processors.igfs.IgfsProcessorAdapter; import org.apache.ignite.internal.processors.job.GridJobProcessor; import org.apache.ignite.internal.processors.jobmetrics.GridJobMetricsProcessor; import org.apache.ignite.internal.processors.nodevalidation.DiscoveryNodeValidationProcessor; -import org.apache.ignite.internal.processors.odbc.GridOdbcProcessor; +import org.apache.ignite.internal.processors.odbc.OdbcProcessor; import org.apache.ignite.internal.processors.offheap.GridOffHeapProcessor; import org.apache.ignite.internal.processors.platform.PlatformProcessor; import org.apache.ignite.internal.processors.plugin.IgnitePluginProcessor; @@ -161,7 +161,7 @@ public class GridKernalContextImpl implements GridKernalContext, Externalizable /** */ @GridToStringInclude - private GridOdbcProcessor odbcProc; + private OdbcProcessor odbcProc; /** */ @GridToStringInclude @@ -511,8 +511,8 @@ public class GridKernalContextImpl implements GridKernalContext, Externalizable pluginProc = (IgnitePluginProcessor)comp; else if (comp instanceof GridQueryProcessor) qryProc = (GridQueryProcessor)comp; - else if (comp instanceof GridOdbcProcessor) - odbcProc = (GridOdbcProcessor)comp; + else if (comp instanceof OdbcProcessor) + odbcProc = (OdbcProcessor)comp; else if (comp instanceof DataStructuresProcessor) dataStructuresProc = (DataStructuresProcessor)comp; else if (comp instanceof ClusterProcessor) @@ -756,7 +756,7 @@ public class GridKernalContextImpl implements GridKernalContext, Externalizable } /** {@inheritDoc} */ - @Override public GridOdbcProcessor odbc() { + @Override public OdbcProcessor odbc() { return odbcProc; } http://git-wip-us.apache.org/repos/asf/ignite/blob/9baf2668/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java b/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java index 22afe01..cd27995 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java @@ -117,7 +117,7 @@ import org.apache.ignite.internal.processors.job.GridJobProcessor; import org.apache.ignite.internal.processors.jobmetrics.GridJobMetricsProcessor; import org.apache.ignite.internal.processors.nodevalidation.DiscoveryNodeValidationProcessor; import org.apache.ignite.internal.processors.nodevalidation.OsDiscoveryNodeValidationProcessor; -import org.apache.ignite.internal.processors.odbc.GridOdbcProcessor; +import org.apache.ignite.internal.processors.odbc.OdbcProcessor; import org.apache.ignite.internal.processors.offheap.GridOffHeapProcessor; import org.apache.ignite.internal.processors.platform.PlatformNoopProcessor; import org.apache.ignite.internal.processors.platform.PlatformProcessor; @@ -850,7 +850,7 @@ public class IgniteKernal implements IgniteEx, IgniteMXBean, Externalizable { startProcessor(createComponent(IgniteCacheObjectProcessor.class, ctx)); startProcessor(new GridCacheProcessor(ctx)); startProcessor(new GridQueryProcessor(ctx)); - startProcessor(new GridOdbcProcessor(ctx)); + startProcessor(new OdbcProcessor(ctx)); startProcessor(new GridTaskSessionProcessor(ctx)); startProcessor(new GridJobProcessor(ctx)); startProcessor(new GridTaskProcessor(ctx)); http://git-wip-us.apache.org/repos/asf/ignite/blob/9baf2668/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/GridOdbcColumnMeta.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/GridOdbcColumnMeta.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/GridOdbcColumnMeta.java deleted file mode 100644 index 03a5dd8..0000000 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/GridOdbcColumnMeta.java +++ /dev/null @@ -1,125 +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.ignite.internal.processors.odbc; - -import org.apache.ignite.internal.binary.BinaryClassDescriptor; -import org.apache.ignite.internal.binary.BinaryContext; -import org.apache.ignite.internal.binary.BinaryRawWriterEx; -import org.apache.ignite.internal.processors.query.GridQueryFieldMetadata; - -import java.io.IOException; - -import static org.apache.ignite.internal.binary.GridBinaryMarshaller.UNREGISTERED_TYPE_ID; - -/** - * ODBC column-related metadata. - */ -public class GridOdbcColumnMeta { - /** Cache name. */ - private String schemaName; - - /** Table name. */ - private String tableName; - - /** Column name. */ - private String columnName; - - /** Data type. */ - private Class<?> dataType; - - /** - * Add quotation marks at the beginning and end of the string. - * @param str Input string. - * @return String surrounded with quotation marks. - */ - private String AddQuotationMarksIfNeeded(String str) { - if (!str.startsWith("\"") && !str.isEmpty()) - return "\"" + str + "\""; - - return str; - } - - /** - * @param schemaName Cache name. - * @param tableName Table name. - * @param columnName Column name. - * @param dataType Data type. - */ - public GridOdbcColumnMeta(String schemaName, String tableName, String columnName, Class<?> dataType) { - this.schemaName = AddQuotationMarksIfNeeded(schemaName); - this.tableName = tableName; - this.columnName = columnName; - this.dataType = dataType; - } - - /** - * @param info Field metadata. - */ - public GridOdbcColumnMeta(GridQueryFieldMetadata info) { - this.schemaName = AddQuotationMarksIfNeeded(info.schemaName()); - this.tableName = info.typeName(); - this.columnName = info.fieldName(); - - try { - this.dataType = Class.forName(info.fieldTypeName()); - } - catch (Exception ignored) { - this.dataType = Object.class; - } - } - - @Override - public boolean equals(Object o) - { - if (!(o instanceof GridOdbcColumnMeta)) - return false; - - GridOdbcColumnMeta another = (GridOdbcColumnMeta)o; - - return schemaName.equals(another.schemaName) && - tableName.equals(another.tableName) && - columnName.equals(another.columnName) && - dataType.equals(another.dataType); - } - - /** - * Write in a binary format. - * @param writer Binary writer. - * @param ctx Portable context. - * @throws IOException - */ - public void writeBinary(BinaryRawWriterEx writer, BinaryContext ctx) throws IOException { - writer.writeString(schemaName); - writer.writeString(tableName); - writer.writeString(columnName); - writer.writeString(dataType.getName()); - - byte typeId; - - BinaryClassDescriptor desc = ctx.descriptorForClass(dataType, false); - - if (desc == null) - throw new IOException("Object is not portable: [class=" + dataType + ']'); - - if (desc.registered()) - typeId = (byte)desc.typeId(); - else - typeId = (byte)UNREGISTERED_TYPE_ID; - - writer.writeByte(typeId); - } -} http://git-wip-us.apache.org/repos/asf/ignite/blob/9baf2668/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/GridOdbcCommandHandler.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/GridOdbcCommandHandler.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/GridOdbcCommandHandler.java deleted file mode 100644 index 2b19880..0000000 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/GridOdbcCommandHandler.java +++ /dev/null @@ -1,337 +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.ignite.internal.processors.odbc; - -import org.apache.ignite.IgniteCache; -import org.apache.ignite.IgniteLogger; -import org.apache.ignite.cache.query.QueryCursor; -import org.apache.ignite.cache.query.SqlFieldsQuery; -import org.apache.ignite.internal.GridKernalContext; -import org.apache.ignite.internal.processors.cache.QueryCursorImpl; -import org.apache.ignite.internal.processors.odbc.request.*; -import org.apache.ignite.internal.processors.odbc.response.*; -import org.apache.ignite.internal.processors.query.GridQueryFieldMetadata; -import org.apache.ignite.internal.processors.query.GridQueryTypeDescriptor; -import org.apache.ignite.lang.IgniteBiTuple; - -import java.util.*; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.atomic.AtomicLong; - -import static org.apache.ignite.internal.processors.odbc.request.GridOdbcRequest.*; - -/** - * SQL query handler. - */ -public class GridOdbcCommandHandler { - /** Kernal context. */ - protected final GridKernalContext ctx; - - /** Log. */ - protected final IgniteLogger log; - - /** Query ID sequence. */ - private static final AtomicLong qryIdGen = new AtomicLong(); - - /** Current queries cursors. */ - private final ConcurrentHashMap<Long, IgniteBiTuple<QueryCursor, Iterator>> qryCurs = new ConcurrentHashMap<>(); - - /** - * @param ctx Context. - */ - public GridOdbcCommandHandler(GridKernalContext ctx) { - this.ctx = ctx; - - log = ctx.log(getClass()); - } - - /** - * @param req Request. - * @return Response. - */ - public GridOdbcResponse handle(GridOdbcRequest req) { - assert req != null; - - switch (req.command()) { - case EXECUTE_SQL_QUERY: { - return executeQuery((QueryExecuteRequest)req, qryCurs); - } - - case FETCH_SQL_QUERY: { - return fetchQuery((QueryFetchRequest)req, qryCurs); - } - - case CLOSE_SQL_QUERY: { - return closeQuery((QueryCloseRequest)req, qryCurs); - } - - case GET_COLUMNS_META: { - return getColumnsMeta((QueryGetColumnsMetaRequest) req); - } - - case GET_TABLES_META: { - return getTablesMeta((QueryGetTablesMetaRequest) req); - } - } - - return null; - } - - /** - * @param qryCurs Query cursors. - * @param cur Current cursor. - * @param req Sql fetch request. - * @param qryId Query id. - * @return Query result with items. - */ - private static QueryFetchResult createQueryResult( - ConcurrentHashMap<Long, IgniteBiTuple<QueryCursor, Iterator>> qryCurs, - Iterator cur, QueryFetchRequest req, Long qryId) { - QueryFetchResult res = new QueryFetchResult(qryId); - - List<Object> items = new ArrayList<>(); - - for (int i = 0; i < req.pageSize() && cur.hasNext(); ++i) - items.add(cur.next()); - - res.setItems(items); - - res.setLast(!cur.hasNext()); - - return res; - } - - /** - * @param meta Internal query field metadata. - * @return Rest query field metadata. - */ - private static Collection<GridOdbcColumnMeta> convertMetadata(Collection<GridQueryFieldMetadata> meta) { - List<GridOdbcColumnMeta> res = new ArrayList<>(); - - if (meta != null) { - for (GridQueryFieldMetadata info : meta) - res.add(new GridOdbcColumnMeta(info)); - } - - return res; - } - - /** - * Checks whether string matches SQL pattern. - * - * @param str String. - * @param ptrn Pattern. - * @return Whether string matches pattern. - */ - private boolean matches(String str, String ptrn) { - return str != null && (ptrn == null || ptrn.isEmpty() || - str.toUpperCase().matches(ptrn.toUpperCase().replace("%", ".*").replace("_", "."))); - } - - /** - * Remove quotation marks at the beginning and end of the string if present. - * @param str Input string. - * @return String without leading and trailing quotation marks. - */ - private String RemoveQuotationMarksIfNeeded(String str) { - if (str.startsWith("\"") && str.endsWith("\"")) - return str.substring(1, str.length() - 1); - - return str; - } - - /** - * @param req Execute query request. - * @param qryCurs Queries cursors. - * @return Response. - */ - private GridOdbcResponse executeQuery(QueryExecuteRequest req, - ConcurrentHashMap<Long, IgniteBiTuple<QueryCursor, Iterator>> qryCurs) { - long qryId = qryIdGen.getAndIncrement(); - - try { - SqlFieldsQuery qry = new SqlFieldsQuery(req.sqlQuery()); - - qry.setArgs(req.arguments()); - - IgniteCache<Object, Object> cache = ctx.grid().cache(req.cacheName()); - - if (cache == null) - return new GridOdbcResponse(GridOdbcResponse.STATUS_FAILED, - "Failed to find cache with name: " + req.cacheName()); - - QueryCursor qryCur = cache.query(qry); - - Iterator cur = qryCur.iterator(); - - qryCurs.put(qryId, new IgniteBiTuple<>(qryCur, cur)); - - List<GridQueryFieldMetadata> fieldsMeta = ((QueryCursorImpl) qryCur).fieldsMeta(); - - System.out.println("Field meta: " + fieldsMeta); - - QueryExecuteResult res = new QueryExecuteResult(qryId, convertMetadata(fieldsMeta)); - - return new GridOdbcResponse(res); - } - catch (Exception e) { - qryCurs.remove(qryId); - - return new GridOdbcResponse(GridOdbcResponse.STATUS_FAILED, e.getMessage()); - } - } - - /** - * @param req Execute query request. - * @param qryCurs Queries cursors. - * @return Response. - */ - private GridOdbcResponse closeQuery(QueryCloseRequest req, - ConcurrentHashMap<Long, IgniteBiTuple<QueryCursor, Iterator>> qryCurs) { - try { - QueryCursor cur = qryCurs.get(req.queryId()).get1(); - - if (cur == null) - return new GridOdbcResponse(GridOdbcResponse.STATUS_FAILED, - "Failed to find query with ID: " + req.queryId()); - - cur.close(); - - qryCurs.remove(req.queryId()); - - QueryCloseResult res = new QueryCloseResult(req.queryId()); - - return new GridOdbcResponse(res); - } - catch (Exception e) { - qryCurs.remove(req.queryId()); - - return new GridOdbcResponse(GridOdbcResponse.STATUS_FAILED, e.getMessage()); - } - } - - /** - * @param req Execute query request. - * @param qryCurs Queries cursors. - * @return Response. - */ - private GridOdbcResponse fetchQuery(QueryFetchRequest req, - ConcurrentHashMap<Long, IgniteBiTuple<QueryCursor, Iterator>> qryCurs) { - try { - Iterator cur = qryCurs.get(req.queryId()).get2(); - - if (cur == null) - return new GridOdbcResponse(GridOdbcResponse.STATUS_FAILED, - "Failed to find query with ID: " + req.queryId()); - - QueryFetchResult res = createQueryResult(qryCurs, cur, req, req.queryId()); - - return new GridOdbcResponse(res); - } - catch (Exception e) { - qryCurs.remove(req.queryId()); - - return new GridOdbcResponse(GridOdbcResponse.STATUS_FAILED, e.getMessage()); - } - } - - /** - * @param req Get columns metadata request. - * @return Response. - */ - private GridOdbcResponse getColumnsMeta(QueryGetColumnsMetaRequest req) { - try { - List<GridOdbcColumnMeta> meta = new ArrayList<>(); - - String cacheName; - String tableName; - - if (req.tableName().contains(".")) { - // Parsing two-part table name. - String[] parts = req.tableName().split("\\."); - - cacheName = RemoveQuotationMarksIfNeeded(parts[0]); - - tableName = parts[1]; - } - else { - cacheName = RemoveQuotationMarksIfNeeded(req.cacheName()); - - tableName = req.tableName(); - } - - Collection<GridQueryTypeDescriptor> tablesMeta = ctx.query().types(cacheName); - - for (GridQueryTypeDescriptor table : tablesMeta) { - if (!matches(table.name(), tableName)) - continue; - - for (Map.Entry<String, Class<?>> field : table.fields().entrySet()) { - if (!matches(field.getKey(), req.columnName())) - continue; - - GridOdbcColumnMeta columnMeta = new GridOdbcColumnMeta(req.cacheName(), - table.name(), field.getKey(), field.getValue()); - - if (!meta.contains(columnMeta)) - meta.add(columnMeta); - } - } - QueryGetColumnsMetaResult res = new QueryGetColumnsMetaResult(meta); - - return new GridOdbcResponse(res); - } - catch (Exception e) { - return new GridOdbcResponse(GridOdbcResponse.STATUS_FAILED, e.getMessage()); - } - } - - /** - * @param req Get tables metadata request. - * @return Response. - */ - private GridOdbcResponse getTablesMeta(QueryGetTablesMetaRequest req) { - try { - List<GridOdbcTableMeta> meta = new ArrayList<>(); - - String realSchema = RemoveQuotationMarksIfNeeded(req.schema()); - - Collection<GridQueryTypeDescriptor> tablesMeta = ctx.query().types(realSchema); - - for (GridQueryTypeDescriptor table : tablesMeta) { - if (!matches(table.name(), req.table())) - continue; - - if (!matches("TABLE", req.tableType())) - continue; - - GridOdbcTableMeta tableMeta = new GridOdbcTableMeta(req.catalog(), req.schema(), - table.name(), "TABLE"); - - if (!meta.contains(tableMeta)) - meta.add(tableMeta); - } - - QueryGetTablesMetaResult res = new QueryGetTablesMetaResult(meta); - - return new GridOdbcResponse(res); - } - catch (Exception e) { - return new GridOdbcResponse(GridOdbcResponse.STATUS_FAILED, e.getMessage()); - } - } -} http://git-wip-us.apache.org/repos/asf/ignite/blob/9baf2668/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/GridOdbcProcessor.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/GridOdbcProcessor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/GridOdbcProcessor.java deleted file mode 100644 index a78b032..0000000 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/GridOdbcProcessor.java +++ /dev/null @@ -1,160 +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.ignite.internal.processors.odbc; - -import org.apache.ignite.IgniteCheckedException; -import org.apache.ignite.internal.GridKernalContext; -import org.apache.ignite.internal.IgniteInternalFuture; -import org.apache.ignite.internal.binary.BinaryMarshaller; -import org.apache.ignite.internal.processors.GridProcessorAdapter; -import org.apache.ignite.internal.processors.odbc.protocol.GridTcpOdbcServer; -import org.apache.ignite.internal.processors.odbc.request.GridOdbcRequest; -import org.apache.ignite.internal.processors.odbc.response.GridOdbcResponse; -import org.apache.ignite.internal.util.GridSpinReadWriteLock; -import org.apache.ignite.internal.util.future.GridFinishedFuture; -import org.apache.ignite.marshaller.Marshaller; - -/** - * ODBC processor. - */ -public class GridOdbcProcessor extends GridProcessorAdapter { - /** OBCD TCP Server. */ - private GridTcpOdbcServer srv; - - /** Busy lock. */ - private final GridSpinReadWriteLock busyLock = new GridSpinReadWriteLock(); - - /** Command handler. */ - private GridOdbcCommandHandler handler; - - /** Protocol handler. */ - private final GridOdbcProtocolHandler protoHnd = new GridOdbcProtocolHandler() { - @Override public GridOdbcResponse handle(GridOdbcRequest req) throws IgniteCheckedException { - return handle0(req); - } - - @Override public IgniteInternalFuture<GridOdbcResponse> handleAsync(GridOdbcRequest req) { - return new GridFinishedFuture<>( - new IgniteCheckedException("Failed to handle request (asynchronous handling is not implemented).")); - } - }; - - /** - * @param req Request. - * @return Response. - */ - private GridOdbcResponse handle0(final GridOdbcRequest req) throws IgniteCheckedException { - if (!busyLock.tryReadLock()) - throw new IgniteCheckedException("Failed to handle request (received request while stopping grid)."); - - GridOdbcResponse rsp = null; - - try { - rsp = handleRequest(req); - } - finally { - busyLock.readUnlock(); - } - - return rsp; - } - - /** - * @param req Request. - * @return Future. - */ - private GridOdbcResponse handleRequest(final GridOdbcRequest req) throws IgniteCheckedException { - if (log.isDebugEnabled()) - log.debug("Received request from client: " + req); - - GridOdbcResponse rsp; - - try { - rsp = handler == null ? null : handler.handle(req); - - if (rsp == null) - throw new IgniteCheckedException("Failed to find registered handler for command: " + req.command()); - } - catch (Exception e) { - if (log.isDebugEnabled()) - log.debug("Failed to handle request [req=" + req + ", e=" + e + "]"); - - rsp = new GridOdbcResponse(GridOdbcResponse.STATUS_FAILED, e.getMessage()); - } - - return rsp; - } - - /** - * @param ctx Kernal context. - */ - public GridOdbcProcessor(GridKernalContext ctx) { - super(ctx); - - srv = new GridTcpOdbcServer(ctx); - } - - /** {@inheritDoc} */ - @Override public void start() throws IgniteCheckedException { - if (isOdbcEnabled()) { - - Marshaller marsh = ctx.config().getMarshaller(); - - if (marsh != null && !(marsh instanceof BinaryMarshaller)) - throw new IgniteCheckedException("Failed to start processor " + - "(ODBC may only be used with BinaryMarshaller)."); - - // Register handler. - handler = new GridOdbcCommandHandler(ctx); - - srv.start(protoHnd); - } - } - - /** {@inheritDoc} */ - @Override public void stop(boolean cancel) throws IgniteCheckedException { - if (isOdbcEnabled()) { - srv.stop(); - } - } - - /** {@inheritDoc} */ - @Override public void onKernalStart() throws IgniteCheckedException { - if (isOdbcEnabled()) { - - if (log.isDebugEnabled()) - log.debug("ODBC processor started."); - } - } - - /** {@inheritDoc} */ - @Override public void onKernalStop(boolean cancel) { - if (isOdbcEnabled()) { - busyLock.writeLock(); - - if (log.isDebugEnabled()) - log.debug("ODBC processor stopped."); - } - } - - /** - * @return Whether or not ODBC is enabled. - */ - public boolean isOdbcEnabled() { - return ctx.config().getOdbcConfiguration() != null; - } -} http://git-wip-us.apache.org/repos/asf/ignite/blob/9baf2668/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/GridOdbcProtocolHandler.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/GridOdbcProtocolHandler.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/GridOdbcProtocolHandler.java deleted file mode 100644 index 033f067..0000000 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/GridOdbcProtocolHandler.java +++ /dev/null @@ -1,40 +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.ignite.internal.processors.odbc; - -import org.apache.ignite.IgniteCheckedException; -import org.apache.ignite.internal.IgniteInternalFuture; -import org.apache.ignite.internal.processors.odbc.request.GridOdbcRequest; -import org.apache.ignite.internal.processors.odbc.response.GridOdbcResponse; - -/** - * ODBC command protocol handler. - */ -public interface GridOdbcProtocolHandler { - /** - * @param req Request. - * @return Response. - * @throws IgniteCheckedException In case of error. - */ - public GridOdbcResponse handle(GridOdbcRequest req) throws IgniteCheckedException; - - /** - * @param req Request. - * @return Future. - */ - public IgniteInternalFuture<GridOdbcResponse> handleAsync(GridOdbcRequest req); -} http://git-wip-us.apache.org/repos/asf/ignite/blob/9baf2668/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/GridOdbcTableMeta.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/GridOdbcTableMeta.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/GridOdbcTableMeta.java deleted file mode 100644 index 1dd11b8..0000000 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/GridOdbcTableMeta.java +++ /dev/null @@ -1,89 +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.ignite.internal.processors.odbc; - -import org.apache.ignite.internal.binary.BinaryRawWriterEx; - -import java.io.IOException; - -/** - * ODBC table-related metadata. - */ -public class GridOdbcTableMeta { - /** Catalog name. */ - private String catalog; - - /** Schema name. */ - private String schema; - - /** Table name. */ - private String table; - - /** Table type. */ - private String tableType; - - /** - * Add quotation marks at the beginning and end of the string. - * @param str Input string. - * @return String surrounded with quotation marks. - */ - private String AddQuotationMarksIfNeeded(String str) { - if (!str.startsWith("\"") && !str.isEmpty()) - return "\"" + str + "\""; - - return str; - } - - /** - * @param catalog Catalog name. - * @param schema Schema name. - * @param table Table name. - * @param tableType Table type. - */ - public GridOdbcTableMeta(String catalog, String schema, String table, String tableType) { - this.catalog = catalog; - this.schema = AddQuotationMarksIfNeeded(schema); - this.table = table; - this.tableType = tableType; - } - - @Override - public boolean equals(Object o) - { - if (!(o instanceof GridOdbcTableMeta)) - return false; - - GridOdbcTableMeta another = (GridOdbcTableMeta)o; - - return catalog.equals(another.catalog) && - schema.equals(another.schema) && - table.equals(another.table) && - tableType.equals(another.tableType); - } - - /** - * Write in a binary format. - * @param writer Binary writer. - * @throws IOException - */ - public void writeBinary(BinaryRawWriterEx writer) throws IOException { - writer.writeString(catalog); - writer.writeString(schema); - writer.writeString(table); - writer.writeString(tableType); - } -} http://git-wip-us.apache.org/repos/asf/ignite/blob/9baf2668/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/OdbcColumnMeta.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/OdbcColumnMeta.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/OdbcColumnMeta.java new file mode 100644 index 0000000..0c2eed2 --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/OdbcColumnMeta.java @@ -0,0 +1,125 @@ +/* + * 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.ignite.internal.processors.odbc; + +import org.apache.ignite.internal.binary.BinaryClassDescriptor; +import org.apache.ignite.internal.binary.BinaryContext; +import org.apache.ignite.internal.binary.BinaryRawWriterEx; +import org.apache.ignite.internal.processors.query.GridQueryFieldMetadata; + +import java.io.IOException; + +import static org.apache.ignite.internal.binary.GridBinaryMarshaller.UNREGISTERED_TYPE_ID; + +/** + * ODBC column-related metadata. + */ +public class OdbcColumnMeta { + /** Cache name. */ + private String schemaName; + + /** Table name. */ + private String tableName; + + /** Column name. */ + private String columnName; + + /** Data type. */ + private Class<?> dataType; + + /** + * Add quotation marks at the beginning and end of the string. + * @param str Input string. + * @return String surrounded with quotation marks. + */ + private String AddQuotationMarksIfNeeded(String str) { + if (!str.startsWith("\"") && !str.isEmpty()) + return "\"" + str + "\""; + + return str; + } + + /** + * @param schemaName Cache name. + * @param tableName Table name. + * @param columnName Column name. + * @param dataType Data type. + */ + public OdbcColumnMeta(String schemaName, String tableName, String columnName, Class<?> dataType) { + this.schemaName = AddQuotationMarksIfNeeded(schemaName); + this.tableName = tableName; + this.columnName = columnName; + this.dataType = dataType; + } + + /** + * @param info Field metadata. + */ + public OdbcColumnMeta(GridQueryFieldMetadata info) { + this.schemaName = AddQuotationMarksIfNeeded(info.schemaName()); + this.tableName = info.typeName(); + this.columnName = info.fieldName(); + + try { + this.dataType = Class.forName(info.fieldTypeName()); + } + catch (Exception ignored) { + this.dataType = Object.class; + } + } + + @Override + public boolean equals(Object o) + { + if (!(o instanceof OdbcColumnMeta)) + return false; + + OdbcColumnMeta another = (OdbcColumnMeta)o; + + return schemaName.equals(another.schemaName) && + tableName.equals(another.tableName) && + columnName.equals(another.columnName) && + dataType.equals(another.dataType); + } + + /** + * Write in a binary format. + * @param writer Binary writer. + * @param ctx Portable context. + * @throws IOException + */ + public void writeBinary(BinaryRawWriterEx writer, BinaryContext ctx) throws IOException { + writer.writeString(schemaName); + writer.writeString(tableName); + writer.writeString(columnName); + writer.writeString(dataType.getName()); + + byte typeId; + + BinaryClassDescriptor desc = ctx.descriptorForClass(dataType, false); + + if (desc == null) + throw new IOException("Object is not portable: [class=" + dataType + ']'); + + if (desc.registered()) + typeId = (byte)desc.typeId(); + else + typeId = (byte)UNREGISTERED_TYPE_ID; + + writer.writeByte(typeId); + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/9baf2668/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/OdbcCommandHandler.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/OdbcCommandHandler.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/OdbcCommandHandler.java new file mode 100644 index 0000000..d8a05f7 --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/OdbcCommandHandler.java @@ -0,0 +1,337 @@ +/* + * 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.ignite.internal.processors.odbc; + +import org.apache.ignite.IgniteCache; +import org.apache.ignite.IgniteLogger; +import org.apache.ignite.cache.query.QueryCursor; +import org.apache.ignite.cache.query.SqlFieldsQuery; +import org.apache.ignite.internal.GridKernalContext; +import org.apache.ignite.internal.processors.cache.QueryCursorImpl; +import org.apache.ignite.internal.processors.odbc.request.*; +import org.apache.ignite.internal.processors.odbc.response.*; +import org.apache.ignite.internal.processors.query.GridQueryFieldMetadata; +import org.apache.ignite.internal.processors.query.GridQueryTypeDescriptor; +import org.apache.ignite.lang.IgniteBiTuple; + +import java.util.*; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.atomic.AtomicLong; + +import static org.apache.ignite.internal.processors.odbc.request.OdbcRequest.*; + +/** + * SQL query handler. + */ +public class OdbcCommandHandler { + /** Kernal context. */ + protected final GridKernalContext ctx; + + /** Log. */ + protected final IgniteLogger log; + + /** Query ID sequence. */ + private static final AtomicLong qryIdGen = new AtomicLong(); + + /** Current queries cursors. */ + private final ConcurrentHashMap<Long, IgniteBiTuple<QueryCursor, Iterator>> qryCurs = new ConcurrentHashMap<>(); + + /** + * @param ctx Context. + */ + public OdbcCommandHandler(GridKernalContext ctx) { + this.ctx = ctx; + + log = ctx.log(getClass()); + } + + /** + * @param req Request. + * @return Response. + */ + public OdbcResponse handle(OdbcRequest req) { + assert req != null; + + switch (req.command()) { + case EXECUTE_SQL_QUERY: { + return executeQuery((OdbcQueryExecuteRequest)req, qryCurs); + } + + case FETCH_SQL_QUERY: { + return fetchQuery((OdbcQueryFetchRequest)req, qryCurs); + } + + case CLOSE_SQL_QUERY: { + return closeQuery((OdbcQueryCloseRequest)req, qryCurs); + } + + case GET_COLUMNS_META: { + return getColumnsMeta((OdbcQueryGetColumnsMetaRequest) req); + } + + case GET_TABLES_META: { + return getTablesMeta((OdbcQueryGetTablesMetaRequest) req); + } + } + + return null; + } + + /** + * @param qryCurs Query cursors. + * @param cur Current cursor. + * @param req Sql fetch request. + * @param qryId Query id. + * @return Query result with items. + */ + private static OdbcQueryFetchResult createQueryResult( + ConcurrentHashMap<Long, IgniteBiTuple<QueryCursor, Iterator>> qryCurs, + Iterator cur, OdbcQueryFetchRequest req, Long qryId) { + OdbcQueryFetchResult res = new OdbcQueryFetchResult(qryId); + + List<Object> items = new ArrayList<>(); + + for (int i = 0; i < req.pageSize() && cur.hasNext(); ++i) + items.add(cur.next()); + + res.setItems(items); + + res.setLast(!cur.hasNext()); + + return res; + } + + /** + * @param meta Internal query field metadata. + * @return Rest query field metadata. + */ + private static Collection<OdbcColumnMeta> convertMetadata(Collection<GridQueryFieldMetadata> meta) { + List<OdbcColumnMeta> res = new ArrayList<>(); + + if (meta != null) { + for (GridQueryFieldMetadata info : meta) + res.add(new OdbcColumnMeta(info)); + } + + return res; + } + + /** + * Checks whether string matches SQL pattern. + * + * @param str String. + * @param ptrn Pattern. + * @return Whether string matches pattern. + */ + private boolean matches(String str, String ptrn) { + return str != null && (ptrn == null || ptrn.isEmpty() || + str.toUpperCase().matches(ptrn.toUpperCase().replace("%", ".*").replace("_", "."))); + } + + /** + * Remove quotation marks at the beginning and end of the string if present. + * @param str Input string. + * @return String without leading and trailing quotation marks. + */ + private String RemoveQuotationMarksIfNeeded(String str) { + if (str.startsWith("\"") && str.endsWith("\"")) + return str.substring(1, str.length() - 1); + + return str; + } + + /** + * @param req Execute query request. + * @param qryCurs Queries cursors. + * @return Response. + */ + private OdbcResponse executeQuery(OdbcQueryExecuteRequest req, + ConcurrentHashMap<Long, IgniteBiTuple<QueryCursor, Iterator>> qryCurs) { + long qryId = qryIdGen.getAndIncrement(); + + try { + SqlFieldsQuery qry = new SqlFieldsQuery(req.sqlQuery()); + + qry.setArgs(req.arguments()); + + IgniteCache<Object, Object> cache = ctx.grid().cache(req.cacheName()); + + if (cache == null) + return new OdbcResponse(OdbcResponse.STATUS_FAILED, + "Failed to find cache with name: " + req.cacheName()); + + QueryCursor qryCur = cache.query(qry); + + Iterator cur = qryCur.iterator(); + + qryCurs.put(qryId, new IgniteBiTuple<>(qryCur, cur)); + + List<GridQueryFieldMetadata> fieldsMeta = ((QueryCursorImpl) qryCur).fieldsMeta(); + + System.out.println("Field meta: " + fieldsMeta); + + OdbcQueryExecuteResult res = new OdbcQueryExecuteResult(qryId, convertMetadata(fieldsMeta)); + + return new OdbcResponse(res); + } + catch (Exception e) { + qryCurs.remove(qryId); + + return new OdbcResponse(OdbcResponse.STATUS_FAILED, e.getMessage()); + } + } + + /** + * @param req Execute query request. + * @param qryCurs Queries cursors. + * @return Response. + */ + private OdbcResponse closeQuery(OdbcQueryCloseRequest req, + ConcurrentHashMap<Long, IgniteBiTuple<QueryCursor, Iterator>> qryCurs) { + try { + QueryCursor cur = qryCurs.get(req.queryId()).get1(); + + if (cur == null) + return new OdbcResponse(OdbcResponse.STATUS_FAILED, + "Failed to find query with ID: " + req.queryId()); + + cur.close(); + + qryCurs.remove(req.queryId()); + + OdbcQueryCloseResult res = new OdbcQueryCloseResult(req.queryId()); + + return new OdbcResponse(res); + } + catch (Exception e) { + qryCurs.remove(req.queryId()); + + return new OdbcResponse(OdbcResponse.STATUS_FAILED, e.getMessage()); + } + } + + /** + * @param req Execute query request. + * @param qryCurs Queries cursors. + * @return Response. + */ + private OdbcResponse fetchQuery(OdbcQueryFetchRequest req, + ConcurrentHashMap<Long, IgniteBiTuple<QueryCursor, Iterator>> qryCurs) { + try { + Iterator cur = qryCurs.get(req.queryId()).get2(); + + if (cur == null) + return new OdbcResponse(OdbcResponse.STATUS_FAILED, + "Failed to find query with ID: " + req.queryId()); + + OdbcQueryFetchResult res = createQueryResult(qryCurs, cur, req, req.queryId()); + + return new OdbcResponse(res); + } + catch (Exception e) { + qryCurs.remove(req.queryId()); + + return new OdbcResponse(OdbcResponse.STATUS_FAILED, e.getMessage()); + } + } + + /** + * @param req Get columns metadata request. + * @return Response. + */ + private OdbcResponse getColumnsMeta(OdbcQueryGetColumnsMetaRequest req) { + try { + List<OdbcColumnMeta> meta = new ArrayList<>(); + + String cacheName; + String tableName; + + if (req.tableName().contains(".")) { + // Parsing two-part table name. + String[] parts = req.tableName().split("\\."); + + cacheName = RemoveQuotationMarksIfNeeded(parts[0]); + + tableName = parts[1]; + } + else { + cacheName = RemoveQuotationMarksIfNeeded(req.cacheName()); + + tableName = req.tableName(); + } + + Collection<GridQueryTypeDescriptor> tablesMeta = ctx.query().types(cacheName); + + for (GridQueryTypeDescriptor table : tablesMeta) { + if (!matches(table.name(), tableName)) + continue; + + for (Map.Entry<String, Class<?>> field : table.fields().entrySet()) { + if (!matches(field.getKey(), req.columnName())) + continue; + + OdbcColumnMeta columnMeta = new OdbcColumnMeta(req.cacheName(), + table.name(), field.getKey(), field.getValue()); + + if (!meta.contains(columnMeta)) + meta.add(columnMeta); + } + } + OdbcQueryGetColumnsMetaResult res = new OdbcQueryGetColumnsMetaResult(meta); + + return new OdbcResponse(res); + } + catch (Exception e) { + return new OdbcResponse(OdbcResponse.STATUS_FAILED, e.getMessage()); + } + } + + /** + * @param req Get tables metadata request. + * @return Response. + */ + private OdbcResponse getTablesMeta(OdbcQueryGetTablesMetaRequest req) { + try { + List<OdbcTableMeta> meta = new ArrayList<>(); + + String realSchema = RemoveQuotationMarksIfNeeded(req.schema()); + + Collection<GridQueryTypeDescriptor> tablesMeta = ctx.query().types(realSchema); + + for (GridQueryTypeDescriptor table : tablesMeta) { + if (!matches(table.name(), req.table())) + continue; + + if (!matches("TABLE", req.tableType())) + continue; + + OdbcTableMeta tableMeta = new OdbcTableMeta(req.catalog(), req.schema(), + table.name(), "TABLE"); + + if (!meta.contains(tableMeta)) + meta.add(tableMeta); + } + + OdbcQueryGetTablesMetaResult res = new OdbcQueryGetTablesMetaResult(meta); + + return new OdbcResponse(res); + } + catch (Exception e) { + return new OdbcResponse(OdbcResponse.STATUS_FAILED, e.getMessage()); + } + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/9baf2668/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/OdbcProcessor.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/OdbcProcessor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/OdbcProcessor.java new file mode 100644 index 0000000..a3f0b94 --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/OdbcProcessor.java @@ -0,0 +1,160 @@ +/* + * 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.ignite.internal.processors.odbc; + +import org.apache.ignite.IgniteCheckedException; +import org.apache.ignite.internal.GridKernalContext; +import org.apache.ignite.internal.IgniteInternalFuture; +import org.apache.ignite.internal.binary.BinaryMarshaller; +import org.apache.ignite.internal.processors.GridProcessorAdapter; +import org.apache.ignite.internal.processors.odbc.protocol.OdbcTcpServer; +import org.apache.ignite.internal.processors.odbc.request.OdbcRequest; +import org.apache.ignite.internal.processors.odbc.response.OdbcResponse; +import org.apache.ignite.internal.util.GridSpinReadWriteLock; +import org.apache.ignite.internal.util.future.GridFinishedFuture; +import org.apache.ignite.marshaller.Marshaller; + +/** + * ODBC processor. + */ +public class OdbcProcessor extends GridProcessorAdapter { + /** OBCD TCP Server. */ + private OdbcTcpServer srv; + + /** Busy lock. */ + private final GridSpinReadWriteLock busyLock = new GridSpinReadWriteLock(); + + /** Command handler. */ + private OdbcCommandHandler handler; + + /** Protocol handler. */ + private final OdbcProtocolHandler protoHnd = new OdbcProtocolHandler() { + @Override public OdbcResponse handle(OdbcRequest req) throws IgniteCheckedException { + return handle0(req); + } + + @Override public IgniteInternalFuture<OdbcResponse> handleAsync(OdbcRequest req) { + return new GridFinishedFuture<>( + new IgniteCheckedException("Failed to handle request (asynchronous handling is not implemented).")); + } + }; + + /** + * @param req Request. + * @return Response. + */ + private OdbcResponse handle0(final OdbcRequest req) throws IgniteCheckedException { + if (!busyLock.tryReadLock()) + throw new IgniteCheckedException("Failed to handle request (received request while stopping grid)."); + + OdbcResponse rsp = null; + + try { + rsp = handleRequest(req); + } + finally { + busyLock.readUnlock(); + } + + return rsp; + } + + /** + * @param req Request. + * @return Future. + */ + private OdbcResponse handleRequest(final OdbcRequest req) throws IgniteCheckedException { + if (log.isDebugEnabled()) + log.debug("Received request from client: " + req); + + OdbcResponse rsp; + + try { + rsp = handler == null ? null : handler.handle(req); + + if (rsp == null) + throw new IgniteCheckedException("Failed to find registered handler for command: " + req.command()); + } + catch (Exception e) { + if (log.isDebugEnabled()) + log.debug("Failed to handle request [req=" + req + ", e=" + e + "]"); + + rsp = new OdbcResponse(OdbcResponse.STATUS_FAILED, e.getMessage()); + } + + return rsp; + } + + /** + * @param ctx Kernal context. + */ + public OdbcProcessor(GridKernalContext ctx) { + super(ctx); + + srv = new OdbcTcpServer(ctx); + } + + /** {@inheritDoc} */ + @Override public void start() throws IgniteCheckedException { + if (isOdbcEnabled()) { + + Marshaller marsh = ctx.config().getMarshaller(); + + if (marsh != null && !(marsh instanceof BinaryMarshaller)) + throw new IgniteCheckedException("Failed to start processor " + + "(ODBC may only be used with BinaryMarshaller)."); + + // Register handler. + handler = new OdbcCommandHandler(ctx); + + srv.start(protoHnd); + } + } + + /** {@inheritDoc} */ + @Override public void stop(boolean cancel) throws IgniteCheckedException { + if (isOdbcEnabled()) { + srv.stop(); + } + } + + /** {@inheritDoc} */ + @Override public void onKernalStart() throws IgniteCheckedException { + if (isOdbcEnabled()) { + + if (log.isDebugEnabled()) + log.debug("ODBC processor started."); + } + } + + /** {@inheritDoc} */ + @Override public void onKernalStop(boolean cancel) { + if (isOdbcEnabled()) { + busyLock.writeLock(); + + if (log.isDebugEnabled()) + log.debug("ODBC processor stopped."); + } + } + + /** + * @return Whether or not ODBC is enabled. + */ + public boolean isOdbcEnabled() { + return ctx.config().getOdbcConfiguration() != null; + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/9baf2668/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/OdbcProtocolHandler.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/OdbcProtocolHandler.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/OdbcProtocolHandler.java new file mode 100644 index 0000000..9af002d --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/OdbcProtocolHandler.java @@ -0,0 +1,40 @@ +/* + * 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.ignite.internal.processors.odbc; + +import org.apache.ignite.IgniteCheckedException; +import org.apache.ignite.internal.IgniteInternalFuture; +import org.apache.ignite.internal.processors.odbc.request.OdbcRequest; +import org.apache.ignite.internal.processors.odbc.response.OdbcResponse; + +/** + * ODBC command protocol handler. + */ +public interface OdbcProtocolHandler { + /** + * @param req Request. + * @return Response. + * @throws IgniteCheckedException In case of error. + */ + public OdbcResponse handle(OdbcRequest req) throws IgniteCheckedException; + + /** + * @param req Request. + * @return Future. + */ + public IgniteInternalFuture<OdbcResponse> handleAsync(OdbcRequest req); +} http://git-wip-us.apache.org/repos/asf/ignite/blob/9baf2668/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/OdbcTableMeta.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/OdbcTableMeta.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/OdbcTableMeta.java new file mode 100644 index 0000000..b1eea71 --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/OdbcTableMeta.java @@ -0,0 +1,89 @@ +/* + * 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.ignite.internal.processors.odbc; + +import org.apache.ignite.internal.binary.BinaryRawWriterEx; + +import java.io.IOException; + +/** + * ODBC table-related metadata. + */ +public class OdbcTableMeta { + /** Catalog name. */ + private String catalog; + + /** Schema name. */ + private String schema; + + /** Table name. */ + private String table; + + /** Table type. */ + private String tableType; + + /** + * Add quotation marks at the beginning and end of the string. + * @param str Input string. + * @return String surrounded with quotation marks. + */ + private String AddQuotationMarksIfNeeded(String str) { + if (!str.startsWith("\"") && !str.isEmpty()) + return "\"" + str + "\""; + + return str; + } + + /** + * @param catalog Catalog name. + * @param schema Schema name. + * @param table Table name. + * @param tableType Table type. + */ + public OdbcTableMeta(String catalog, String schema, String table, String tableType) { + this.catalog = catalog; + this.schema = AddQuotationMarksIfNeeded(schema); + this.table = table; + this.tableType = tableType; + } + + @Override + public boolean equals(Object o) + { + if (!(o instanceof OdbcTableMeta)) + return false; + + OdbcTableMeta another = (OdbcTableMeta)o; + + return catalog.equals(another.catalog) && + schema.equals(another.schema) && + table.equals(another.table) && + tableType.equals(another.tableType); + } + + /** + * Write in a binary format. + * @param writer Binary writer. + * @throws IOException + */ + public void writeBinary(BinaryRawWriterEx writer) throws IOException { + writer.writeString(catalog); + writer.writeString(schema); + writer.writeString(table); + writer.writeString(tableType); + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/9baf2668/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/protocol/GridOdbcParser.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/protocol/GridOdbcParser.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/protocol/GridOdbcParser.java deleted file mode 100644 index 3cd2fad..0000000 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/protocol/GridOdbcParser.java +++ /dev/null @@ -1,345 +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.ignite.internal.processors.odbc.protocol; - -import org.apache.ignite.IgniteCheckedException; -import org.apache.ignite.internal.GridKernalContext; -import org.apache.ignite.internal.binary.*; -import org.apache.ignite.internal.binary.streams.BinaryHeapInputStream; -import org.apache.ignite.internal.binary.streams.BinaryHeapOutputStream; -import org.apache.ignite.internal.binary.streams.BinaryInputStream; -import org.apache.ignite.internal.processors.cache.binary.CacheObjectBinaryProcessorImpl; -import org.apache.ignite.internal.processors.odbc.GridOdbcColumnMeta; -import org.apache.ignite.internal.processors.odbc.GridOdbcTableMeta; -import org.apache.ignite.internal.processors.odbc.request.*; -import org.apache.ignite.internal.processors.odbc.response.*; -import org.apache.ignite.internal.util.nio.GridNioParser; -import org.apache.ignite.internal.util.nio.GridNioSession; -import org.jetbrains.annotations.Nullable; - -import java.io.IOException; -import java.nio.ByteBuffer; -import java.util.Collection; - - -/** - * ODBC protocol parser. - */ -public class GridOdbcParser implements GridNioParser { - /** Initial output stream capacity. */ - private static final int INIT_CAP = 1024; - - /** Length in bytes of the remaining message part. */ - int leftToReceive = 0; - - /** Already received bytes of current message. */ - ByteBuffer currentMessage = null; - - /** Context. */ - protected final GridKernalContext ctx; - - /** Marshaller. */ - private final GridBinaryMarshaller marsh; - - GridOdbcParser(GridKernalContext context) { - ctx = context; - - CacheObjectBinaryProcessorImpl cacheObjProc = (CacheObjectBinaryProcessorImpl)ctx.cacheObjects(); - - marsh = cacheObjProc.marshaller(); - } - - /** - * Process data chunk and try to construct new message using stored and freshly received data. - * @param buf Fresh data buffer. - * @return Instance of the {@link BinaryReaderExImpl} positioned to read from the beginning of the message on - * success and null otherwise. - */ - private BinaryRawReaderEx tryConstructMessage(ByteBuffer buf) { - if (leftToReceive != 0) { - // Still receiving message - int toConsume = Math.min(leftToReceive, buf.remaining()); - - currentMessage.put(buf.array(), buf.arrayOffset(), toConsume); - leftToReceive -= toConsume; - - buf.position(buf.position() + toConsume); - - if (leftToReceive != 0) - return null; - - BinaryInputStream stream = new BinaryHeapInputStream(currentMessage.array()); - - BinaryReaderExImpl reader = new BinaryReaderExImpl(null, stream, null); - - currentMessage = null; - - return reader; - } - - // Receiving new message - // Getting message length. It's in the first four bytes of the message. - BinaryInputStream stream = new BinaryHeapInputStream(buf.array()); - - BinaryReaderExImpl reader = new BinaryReaderExImpl(null, stream, null); - - int messageLen = reader.readInt(); - buf.getInt(); - - int remaining = buf.remaining(); - - if (messageLen > remaining) { - leftToReceive = messageLen - remaining; - - currentMessage = ByteBuffer.allocate(messageLen); - currentMessage.put(buf); - - return null; - } - - buf.position(buf.position() + messageLen); - - return reader; - } - - /** {@inheritDoc} */ - @Nullable @Override public GridOdbcRequest decode(GridNioSession ses, ByteBuffer buf) throws IOException, - IgniteCheckedException { - BinaryRawReaderEx messageReader = tryConstructMessage(buf); - - return messageReader == null ? null : readRequest(ses, messageReader); - } - - /** {@inheritDoc} */ - @Override public ByteBuffer encode(GridNioSession ses, Object msg) throws IOException, IgniteCheckedException { - assert msg != null; - assert msg instanceof GridOdbcResponse; - - System.out.println("Encoding query processing result"); - - BinaryRawWriterEx writer = marsh.writer(new BinaryHeapOutputStream(INIT_CAP)); - - // Reserving space for the message length. - int msgLenPos = writer.reserveInt(); - - writeResponse(ses, writer, (GridOdbcResponse)msg); - - int msgLenWithHdr = writer.out().position() - msgLenPos; - - int msgLen = msgLenWithHdr - 4; - - writer.writeInt(msgLenPos, msgLen); - - ByteBuffer buf = ByteBuffer.allocate(msgLenWithHdr); - - buf.put(writer.out().array(), msgLenPos, msgLenWithHdr); - - buf.flip(); - - return buf; - } - - /** - * Read ODBC request from the raw data using provided {@link BinaryReaderExImpl} instance. - * @param ses Current session. - * @param reader Reader positioned to read the request. - * @return Instance of the {@link GridOdbcRequest}. - * @throws IOException if the type of the request is unknown to the parser. - */ - private GridOdbcRequest readRequest(GridNioSession ses, BinaryRawReaderEx reader) throws IOException { - GridOdbcRequest res; - - byte cmd = reader.readByte(); - - switch (cmd) { - case GridOdbcRequest.EXECUTE_SQL_QUERY: { - String cache = reader.readString(); - String sql = reader.readString(); - int argsNum = reader.readInt(); - - System.out.println("Message EXECUTE_SQL_QUERY:"); - System.out.println("cache: " + cache); - System.out.println("query: " + sql); - System.out.println("argsNum: " + argsNum); - - Object[] params = new Object[argsNum]; - - for (int i = 0; i < argsNum; ++i) - params[i] = reader.readObjectDetached(); - - res = new QueryExecuteRequest(cache, sql, params); - break; - } - - case GridOdbcRequest.FETCH_SQL_QUERY: { - long queryId = reader.readLong(); - int pageSize = reader.readInt(); - - System.out.println("Message FETCH_SQL_QUERY:"); - System.out.println("queryId: " + queryId); - System.out.println("pageSize: " + pageSize); - - res = new QueryFetchRequest(queryId, pageSize); - break; - } - - case GridOdbcRequest.CLOSE_SQL_QUERY: { - long queryId = reader.readLong(); - - System.out.println("Message CLOSE_SQL_QUERY:"); - System.out.println("queryId: " + queryId); - - res = new QueryCloseRequest(queryId); - break; - } - - case GridOdbcRequest.GET_COLUMNS_META: { - String cache = reader.readString(); - String table = reader.readString(); - String column = reader.readString(); - - System.out.println("Message GET_COLUMNS_META:"); - System.out.println("cache: " + cache); - System.out.println("table: " + table); - System.out.println("column: " + column); - - res = new QueryGetColumnsMetaRequest(cache, table, column); - break; - } - - case GridOdbcRequest.GET_TABLES_META: { - String catalog = reader.readString(); - String schema = reader.readString(); - String table = reader.readString(); - String tableType = reader.readString(); - - System.out.println("Message GET_COLUMNS_META:"); - System.out.println("catalog: " + catalog); - System.out.println("schema: " + schema); - System.out.println("table: " + table); - System.out.println("tableType: " + tableType); - - res = new QueryGetTablesMetaRequest(catalog, schema, table, tableType); - break; - } - - default: - throw new IOException("Failed to parse incoming packet (unknown command type) [ses=" + ses + - ", cmd=[" + Byte.toString(cmd) + ']'); - } - - return res; - } - - /** - * Write ODBC response using provided {@link BinaryRawWriterEx} instance. - * @param ses Current session. - * @param writer Writer. - * @param rsp ODBC response that should be written. - * @throws IOException if the type of the response is unknown to the parser. - */ - private void writeResponse(GridNioSession ses, BinaryRawWriterEx writer, GridOdbcResponse rsp) throws IOException { - // Writing status - writer.writeByte((byte)rsp.getSuccessStatus()); - - if (rsp.getSuccessStatus() != GridOdbcResponse.STATUS_SUCCESS) { - writer.writeString(rsp.getError()); - - return; - } - - Object res0 = rsp.getResponse(); - - if (res0 instanceof QueryExecuteResult) { - QueryExecuteResult res = (QueryExecuteResult) res0; - - System.out.println("Resulting query ID: " + res.getQueryId()); - - writer.writeLong(res.getQueryId()); - - Collection<GridOdbcColumnMeta> metas = res.getColumnsMetadata(); - - assert metas != null; - - writer.writeInt(metas.size()); - - for (GridOdbcColumnMeta meta : metas) - meta.writeBinary(writer, marsh.context()); - - } else if (res0 instanceof QueryFetchResult) { - QueryFetchResult res = (QueryFetchResult) res0; - - System.out.println("Resulting query ID: " + res.getQueryId()); - - writer.writeLong(res.getQueryId()); - - Collection<?> items0 = res.getItems(); - - assert items0 != null; - - Collection<Collection<Object>> items = (Collection<Collection<Object>>)items0; - - writer.writeBoolean(res.getLast()); - - writer.writeInt(items.size()); - - for (Collection<Object> row : items) { - if (row != null) { - writer.writeInt(row.size()); - - for (Object obj : row) { - if (obj != null) - writer.writeObjectDetached(obj); - } - } - } - } else if (res0 instanceof QueryCloseResult) { - QueryCloseResult res = (QueryCloseResult) res0; - - System.out.println("Resulting query ID: " + res.getQueryId()); - - writer.writeLong(res.getQueryId()); - - } else if (res0 instanceof QueryGetColumnsMetaResult) { - QueryGetColumnsMetaResult res = (QueryGetColumnsMetaResult) res0; - - Collection<GridOdbcColumnMeta> columnsMeta = res.getMeta(); - - assert columnsMeta != null; - - writer.writeInt(columnsMeta.size()); - - for (GridOdbcColumnMeta columnMeta : columnsMeta) - columnMeta.writeBinary(writer, marsh.context()); - - } else if (res0 instanceof QueryGetTablesMetaResult) { - QueryGetTablesMetaResult res = (QueryGetTablesMetaResult) res0; - - Collection<GridOdbcTableMeta> tablesMeta = res.getMeta(); - - assert tablesMeta != null; - - writer.writeInt(tablesMeta.size()); - - for (GridOdbcTableMeta tableMeta : tablesMeta) - tableMeta.writeBinary(writer); - - } else { - throw new IOException("Failed to serialize response packet (unknown response type) [ses=" + ses + "]"); - } - } -} http://git-wip-us.apache.org/repos/asf/ignite/blob/9baf2668/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/protocol/GridTcpOdbcNioListener.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/protocol/GridTcpOdbcNioListener.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/protocol/GridTcpOdbcNioListener.java deleted file mode 100644 index c53c2c0..0000000 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/protocol/GridTcpOdbcNioListener.java +++ /dev/null @@ -1,102 +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.ignite.internal.processors.odbc.protocol; - -import org.apache.ignite.IgniteCheckedException; -import org.apache.ignite.IgniteLogger; -import org.apache.ignite.internal.GridKernalContext; -import org.apache.ignite.internal.processors.odbc.GridOdbcProtocolHandler; -import org.apache.ignite.internal.processors.odbc.request.GridOdbcRequest; -import org.apache.ignite.internal.processors.odbc.response.GridOdbcResponse; -import org.apache.ignite.internal.util.nio.GridNioFuture; -import org.apache.ignite.internal.util.nio.GridNioServerListenerAdapter; -import org.apache.ignite.internal.util.nio.GridNioSession; -import org.apache.ignite.internal.util.typedef.internal.U; -import org.jetbrains.annotations.Nullable; - -/** - * Listener for ODBC driver connection. - */ -public class GridTcpOdbcNioListener extends GridNioServerListenerAdapter<GridOdbcRequest> { - /** Server. */ - private GridTcpOdbcServer srv; - - /** Logger. */ - protected final IgniteLogger log; - - /** Context. */ - protected final GridKernalContext ctx; - - /** Protocol handler. */ - private GridOdbcProtocolHandler hnd; - - GridTcpOdbcNioListener(IgniteLogger log, GridTcpOdbcServer srv, GridKernalContext ctx, GridOdbcProtocolHandler hnd) { - this.log = log; - this.srv = srv; - this.ctx = ctx; - this.hnd = hnd; - } - - @Override - public void onConnected(GridNioSession ses) { - System.out.println("Driver connected"); - } - - @Override - public void onDisconnected(GridNioSession ses, @Nullable Exception e) { - System.out.println("Driver disconnected"); - - if (e != null) { - if (e instanceof RuntimeException) - U.error(log, "Failed to process request from remote client: " + ses, e); - else - U.warn(log, "Closed client session due to exception [ses=" + ses + ", msg=" + e.getMessage() + ']'); - } - } - - @Override - public void onMessage(GridNioSession ses, GridOdbcRequest msg) { - assert msg != null; - - System.out.println("Query: " + msg.command()); - - GridOdbcResponse res; - - try { - res = hnd.handle(msg); - } - catch (IgniteCheckedException e) { - U.error(log, "Failed to process client request: " + msg, e); - - res = new GridOdbcResponse(GridOdbcResponse.STATUS_FAILED, - "Failed to process client request: " + e.getMessage()); - } - - System.out.println("Resulting success status: " + res.getSuccessStatus()); - - GridNioFuture<?> sf = ses.send(res); - - // Check if send failed. - if (sf.isDone()) { - try { - sf.get(); - } catch (Exception e) { - U.error(log, "Failed to process client request [ses=" + ses + ", msg=" + msg + ']', e); - } - } - } -}
