http://git-wip-us.apache.org/repos/asf/ignite/blob/12dfe9e8/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryArg.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryArg.java b/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryArg.java index 00587b4..1cb1f0d 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryArg.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryArg.java @@ -17,32 +17,44 @@ package org.apache.ignite.internal.visor.query; -import java.io.Serializable; +import java.io.IOException; +import java.io.ObjectInput; +import java.io.ObjectOutput; +import org.apache.ignite.internal.util.typedef.internal.S; +import org.apache.ignite.internal.util.typedef.internal.U; +import org.apache.ignite.internal.visor.VisorDataTransferObject; /** * Arguments for {@link VisorQueryTask}. */ -public class VisorQueryArg implements Serializable { +public class VisorQueryArg extends VisorDataTransferObject { /** */ private static final long serialVersionUID = 0L; /** Cache name for query. */ - private final String cacheName; + private String cacheName; /** Query text. */ - private final String qryTxt; + private String qryTxt; /** Distributed joins enabled flag. */ - private final boolean distributedJoins; + private boolean distributedJoins; /** Enforce join order flag. */ - private final boolean enforceJoinOrder; + private boolean enforceJoinOrder; /** Flag whether to execute query locally. */ - private final boolean loc; + private boolean loc; /** Result batch size. */ - private final int pageSize; + private int pageSize; + + /** + * Default constructor. + */ + public VisorQueryArg() { + // No-op. + } /** * @param cacheName Cache name for query. @@ -65,42 +77,67 @@ public class VisorQueryArg implements Serializable { /** * @return Cache name. */ - public String cacheName() { + public String getCacheName() { return cacheName; } /** * @return Query txt. */ - public String queryText() { + public String getQueryText() { return qryTxt; } /** * @return Distributed joins enabled flag. */ - public boolean distributedJoins() { + public boolean isDistributedJoins() { return distributedJoins; } /** * @return Enforce join order flag. */ - public boolean enforceJoinOrder() { + public boolean isEnforceJoinOrder() { return enforceJoinOrder; } /** * @return {@code true} if query should be executed locally. */ - public boolean local() { + public boolean isLocal() { return loc; } /** * @return Page size. */ - public int pageSize() { + public int getPageSize() { return pageSize; } + + /** {@inheritDoc} */ + @Override protected void writeExternalData(ObjectOutput out) throws IOException { + U.writeString(out, cacheName); + U.writeString(out, qryTxt); + out.writeBoolean(distributedJoins); + out.writeBoolean(enforceJoinOrder); + out.writeBoolean(loc); + out.writeInt(pageSize); + } + + /** {@inheritDoc} */ + @Override protected void readExternalData(byte protoVer, ObjectInput in) throws IOException, ClassNotFoundException { + cacheName = U.readString(in); + qryTxt = U.readString(in); + distributedJoins = in.readBoolean(); + enforceJoinOrder = in.readBoolean(); + loc = in.readBoolean(); + pageSize = in.readInt(); + } + + /** {@inheritDoc} */ + @Override public String toString() { + return S.toString(VisorQueryArg.class, this); + } }
http://git-wip-us.apache.org/repos/asf/ignite/blob/12dfe9e8/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryCancelTask.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryCancelTask.java b/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryCancelTask.java new file mode 100644 index 0000000..6b81dc4 --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryCancelTask.java @@ -0,0 +1,72 @@ +/* + * 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.visor.query; + +import java.util.Collections; +import java.util.List; +import org.apache.ignite.IgniteException; +import org.apache.ignite.compute.ComputeJobResult; +import org.apache.ignite.internal.processors.task.GridInternal; +import org.apache.ignite.internal.visor.VisorJob; +import org.apache.ignite.internal.visor.VisorOneNodeTask; +import org.jetbrains.annotations.Nullable; + +/** + * Task to cancel queries. + */ +@GridInternal +public class VisorQueryCancelTask extends VisorOneNodeTask<Long, Void> { + /** */ + private static final long serialVersionUID = 0L; + + /** {@inheritDoc} */ + @Override protected VisorCancelQueriesJob job(Long arg) { + return new VisorCancelQueriesJob(arg, debug); + } + + /** {@inheritDoc} */ + @Nullable @Override protected Void reduce0(List<ComputeJobResult> results) throws IgniteException { + return null; + } + + /** + * Job to cancel queries on node. + */ + private static class VisorCancelQueriesJob extends VisorJob<Long, Void> { + /** */ + private static final long serialVersionUID = 0L; + + /** + * Create job with specified argument. + * + * @param arg Job argument. + * @param debug Flag indicating whether debug information should be printed into node log. + */ + protected VisorCancelQueriesJob(@Nullable Long arg, boolean debug) { + super(arg, debug); + } + + /** {@inheritDoc} */ + @Override protected Void run(@Nullable Long queries) throws IgniteException { + ignite.context().query().cancelQueries(Collections.singleton(queries)); + + return null; + } + } + +} http://git-wip-us.apache.org/repos/asf/ignite/blob/12dfe9e8/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryCleanupTask.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryCleanupTask.java b/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryCleanupTask.java index c1f06ae..572cf3b 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryCleanupTask.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryCleanupTask.java @@ -65,10 +65,10 @@ public class VisorQueryCleanupTask extends VisorMultiNodeTask<Map<UUID, Collecti map.put(new VisorQueryCleanupJob(taskArg.get(node.id()), debug), node); if (map.isEmpty()) { - String notFoundNodes = ""; + StringBuilder notFoundNodes = new StringBuilder(); for (UUID nid : nodeIds) - notFoundNodes = notFoundNodes + (notFoundNodes.isEmpty() ? "" : ",") + U.id8(nid); + notFoundNodes.append((notFoundNodes.length() == 0) ? "" : ",").append(U.id8(nid)); throw new VisorClusterGroupEmptyException("Failed to clear query results. Nodes are not available: [" + notFoundNodes + "]"); @@ -123,4 +123,4 @@ public class VisorQueryCleanupTask extends VisorMultiNodeTask<Map<UUID, Collecti return S.toString(VisorQueryCleanupJob.class, this); } } -} \ No newline at end of file +} http://git-wip-us.apache.org/repos/asf/ignite/blob/12dfe9e8/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryConfiguration.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryConfiguration.java b/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryConfiguration.java new file mode 100644 index 0000000..92921b2 --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryConfiguration.java @@ -0,0 +1,142 @@ +/* + * 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.visor.query; + +import java.io.IOException; +import java.io.ObjectInput; +import java.io.ObjectOutput; +import java.util.List; +import org.apache.ignite.configuration.CacheConfiguration; +import org.apache.ignite.internal.util.typedef.internal.S; +import org.apache.ignite.internal.util.typedef.internal.U; +import org.apache.ignite.internal.visor.VisorDataTransferObject; + +import static org.apache.ignite.internal.visor.util.VisorTaskUtils.compactClasses; + +/** + * Data transfer object for cache query configuration data. + */ +public class VisorQueryConfiguration extends VisorDataTransferObject { + /** */ + private static final long serialVersionUID = 0L; + + /** */ + private List<String> sqlFuncClss; + + /** */ + private long longQryWarnTimeout; + + /** */ + private boolean sqlEscapeAll; + + /** */ + private List<String> indexedTypes; + + /** */ + private int sqlOnheapRowCacheSize; + + /** */ + private String sqlSchema; + + /** + * Default constructor. + */ + public VisorQueryConfiguration() { + // No-op. + } + + /** + * Create data transfer object with cache query configuration data. + * + * @param ccfg Cache configuration. + */ + public VisorQueryConfiguration(CacheConfiguration ccfg) { + sqlFuncClss = compactClasses(ccfg.getSqlFunctionClasses()); + longQryWarnTimeout = ccfg.getLongQueryWarningTimeout(); + sqlEscapeAll = ccfg.isSqlEscapeAll(); + indexedTypes = compactClasses(ccfg.getIndexedTypes()); + sqlSchema = ccfg.getSqlSchema(); + } + + /** + * @return Classes names with SQL functions. + */ + public List<String> getSqlFunctionClasses() { + return sqlFuncClss; + } + + /** + * @return Timeout in milliseconds after which long query warning will be printed. + */ + public long getLongQueryWarningTimeout() { + return longQryWarnTimeout; + } + + /** + * @return {@code true} if SQL engine generate SQL statements with escaped names. + */ + public boolean isSqlEscapeAll() { + return sqlEscapeAll; + } + + /** + * @return Array of key and value classes names to be indexed. + */ + public List<String> getIndexedTypes() { + return indexedTypes; + } + + /** + * @return Number of SQL rows which will be cached onheap to avoid deserialization on each SQL index access. + */ + public int getSqlOnheapRowCacheSize() { + return sqlOnheapRowCacheSize; + } + + /** + * @return Schema name, which is used by SQL engine for SQL statements generation. + */ + public String getSqlSchema() { + return sqlSchema; + } + + /** {@inheritDoc} */ + @Override protected void writeExternalData(ObjectOutput out) throws IOException { + U.writeCollection(out, sqlFuncClss); + out.writeLong(longQryWarnTimeout); + out.writeBoolean(sqlEscapeAll); + U.writeCollection(out, indexedTypes); + out.writeInt(sqlOnheapRowCacheSize); + U.writeString(out, sqlSchema); + } + + /** {@inheritDoc} */ + @Override protected void readExternalData(byte protoVer, ObjectInput in) throws IOException, ClassNotFoundException { + sqlFuncClss = U.readList(in); + longQryWarnTimeout = in.readLong(); + sqlEscapeAll = in.readBoolean(); + indexedTypes = U.readList(in); + sqlOnheapRowCacheSize = in.readInt(); + sqlSchema = U.readString(in); + } + + /** {@inheritDoc} */ + @Override public String toString() { + return S.toString(VisorQueryConfiguration.class, this); + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/12dfe9e8/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryDetailMetrics.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryDetailMetrics.java b/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryDetailMetrics.java new file mode 100644 index 0000000..b747845 --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryDetailMetrics.java @@ -0,0 +1,205 @@ +/* + * 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.visor.query; + +import java.io.IOException; +import java.io.ObjectInput; +import java.io.ObjectOutput; +import org.apache.ignite.cache.query.QueryDetailMetrics; +import org.apache.ignite.internal.util.typedef.internal.S; +import org.apache.ignite.internal.util.typedef.internal.U; +import org.apache.ignite.internal.visor.VisorDataTransferObject; + +/** + * Data transfer object for cache query detail metrics. + */ +public class VisorQueryDetailMetrics extends VisorDataTransferObject { + /** */ + private static final long serialVersionUID = 0L; + + /** Query type. */ + private String qryType; + + /** Textual query representation. */ + private String qry; + + /** Cache name. */ + private String cache; + + /** Number of executions. */ + private int execs; + + /** Number of completions executions. */ + private int completions; + + /** Number of failures. */ + private int failures; + + /** Minimum time of execution. */ + private long minTime; + + /** Maximum time of execution. */ + private long maxTime; + + /** Average time of execution. */ + private double avgTime; + + /** Sum of execution time of completions time. */ + private long totalTime; + + /** Sum of execution time of completions time. */ + private long lastStartTime; + + /** + * Default constructor + */ + public VisorQueryDetailMetrics() { + // No-op. + } + + /** + * @param m Cache query metrics. + */ + public VisorQueryDetailMetrics(QueryDetailMetrics m) { + qryType = m.queryType(); + qry = m.query(); + cache = m.cache(); + + execs = m.executions(); + completions = m.completions(); + failures = m.failures(); + + minTime = m.minimumTime(); + maxTime = m.maximumTime(); + avgTime = m.averageTime(); + totalTime = m.totalTime(); + lastStartTime = m.lastStartTime(); + } + + /** + * @return Query type + */ + public String getQueryType() { + return qryType; + } + + /** + * @return Query type + */ + public String getQuery() { + return qry; + } + + /** + * @return Cache name where query was executed. + */ + public String getCache() { + return cache; + } + + /** + * @return Number of executions. + */ + public int getExecutions() { + return execs; + } + + /** + * @return Number of completed executions. + */ + public int getCompletions() { + return completions; + } + + /** + * @return Total number of times a query execution failed. + */ + public int getFailures() { + return failures; + } + + /** + * @return Minimum execution time of query. + */ + public long getMinimumTime() { + return minTime; + } + + /** + * @return Maximum execution time of query. + */ + public long getMaximumTime() { + return maxTime; + } + + /** + * @return Average execution time of query. + */ + public double getAverageTime() { + return avgTime; + } + + /** + * @return Total time of all query executions. + */ + public long getTotalTime() { + return totalTime; + } + + /** + * @return Latest time query was stared. + */ + public long getLastStartTime() { + return lastStartTime; + } + + /** {@inheritDoc} */ + @Override protected void writeExternalData(ObjectOutput out) throws IOException { + U.writeString(out, qryType); + U.writeString(out, qry); + U.writeString(out, cache); + out.writeInt(execs); + out.writeInt(completions); + out.writeInt(failures); + out.writeLong(minTime); + out.writeLong(maxTime); + out.writeDouble(avgTime); + out.writeLong(totalTime); + out.writeLong(lastStartTime); + } + + /** {@inheritDoc} */ + @Override protected void readExternalData(byte protoVer, ObjectInput in) throws IOException, ClassNotFoundException { + qryType = U.readString(in); + qry = U.readString(in); + cache = U.readString(in); + execs = in.readInt(); + completions = in.readInt(); + failures = in.readInt(); + minTime = in.readLong(); + maxTime = in.readLong(); + avgTime = in.readDouble(); + totalTime = in.readLong(); + lastStartTime = in.readLong(); + } + + /** {@inheritDoc} */ + @Override public String toString() { + return S.toString(VisorQueryDetailMetrics.class, this); + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/12dfe9e8/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryDetailMetricsCollectorTask.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryDetailMetricsCollectorTask.java b/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryDetailMetricsCollectorTask.java new file mode 100644 index 0000000..7c1379f --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryDetailMetricsCollectorTask.java @@ -0,0 +1,146 @@ +/* + * 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.visor.query; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import org.apache.ignite.IgniteException; +import org.apache.ignite.cache.query.QueryDetailMetrics; +import org.apache.ignite.compute.ComputeJobResult; +import org.apache.ignite.configuration.IgniteConfiguration; +import org.apache.ignite.internal.processors.cache.GridCacheProcessor; +import org.apache.ignite.internal.processors.cache.IgniteInternalCache; +import org.apache.ignite.internal.processors.cache.query.GridCacheQueryDetailMetricsAdapter; +import org.apache.ignite.internal.processors.cache.query.GridCacheQueryDetailMetricsKey; +import org.apache.ignite.internal.processors.task.GridInternal; +import org.apache.ignite.internal.util.typedef.internal.S; +import org.apache.ignite.internal.visor.VisorJob; +import org.apache.ignite.internal.visor.VisorMultiNodeTask; +import org.jetbrains.annotations.Nullable; + +import static org.apache.ignite.internal.processors.cache.GridCacheUtils.isIgfsCache; +import static org.apache.ignite.internal.processors.cache.GridCacheUtils.isSystemCache; + +/** + * Task to collect cache query metrics. + */ +@GridInternal +public class VisorQueryDetailMetricsCollectorTask extends VisorMultiNodeTask<Long, Collection<VisorQueryDetailMetrics>, + Collection<? extends QueryDetailMetrics>> { + /** */ + private static final long serialVersionUID = 0L; + + /** {@inheritDoc} */ + @Override protected VisorCacheQueryDetailMetricsCollectorJob job(Long arg) { + return new VisorCacheQueryDetailMetricsCollectorJob(arg, debug); + } + + /** {@inheritDoc} */ + @Nullable @Override protected Collection<VisorQueryDetailMetrics> reduce0(List<ComputeJobResult> results) + throws IgniteException { + Map<GridCacheQueryDetailMetricsKey, GridCacheQueryDetailMetricsAdapter> taskRes = new HashMap<>(); + + for (ComputeJobResult res : results) { + if (res.getException() != null) + throw res.getException(); + + Collection<GridCacheQueryDetailMetricsAdapter> metrics = res.getData(); + + VisorCacheQueryDetailMetricsCollectorJob.aggregateMetrics(-1, taskRes, metrics); + } + + Collection<GridCacheQueryDetailMetricsAdapter> aggMetrics = taskRes.values(); + + Collection<VisorQueryDetailMetrics> res = new ArrayList<>(aggMetrics.size()); + + for (GridCacheQueryDetailMetricsAdapter m: aggMetrics) + res.add(new VisorQueryDetailMetrics(m)); + + return res; + } + + /** + * Job that will actually collect query metrics. + */ + private static class VisorCacheQueryDetailMetricsCollectorJob extends VisorJob<Long, Collection<? extends QueryDetailMetrics>> { + /** */ + private static final long serialVersionUID = 0L; + + /** + * Create job with specified argument. + * + * @param arg Last time when metrics were collected. + * @param debug Debug flag. + */ + protected VisorCacheQueryDetailMetricsCollectorJob(@Nullable Long arg, boolean debug) { + super(arg, debug); + } + + /** + * @param since Time when metrics were collected last time. + * @param res Response. + * @param metrics Metrics. + */ + private static void aggregateMetrics(long since, Map<GridCacheQueryDetailMetricsKey, + GridCacheQueryDetailMetricsAdapter> res, Collection<GridCacheQueryDetailMetricsAdapter> metrics) { + for (GridCacheQueryDetailMetricsAdapter m : metrics) { + if (m.lastStartTime() > since) { + GridCacheQueryDetailMetricsKey key = m.key(); + + GridCacheQueryDetailMetricsAdapter aggMetrics = res.get(key); + + res.put(key, aggMetrics == null ? m : aggMetrics.aggregate(m)); + } + } + } + + /** {@inheritDoc} */ + @Override protected Collection<? extends QueryDetailMetrics> run(@Nullable Long arg) throws IgniteException { + assert arg != null; + + IgniteConfiguration cfg = ignite.configuration(); + + GridCacheProcessor cacheProc = ignite.context().cache(); + + Collection<String> cacheNames = cacheProc.cacheNames(); + + Map<GridCacheQueryDetailMetricsKey, GridCacheQueryDetailMetricsAdapter> aggMetrics = new HashMap<>(); + + for (String cacheName : cacheNames) { + if (!isSystemCache(cacheName) && !isIgfsCache(cfg, cacheName)) { + IgniteInternalCache<Object, Object> cache = cacheProc.cache(cacheName); + + if (cache == null || !cache.context().started()) + continue; + + aggregateMetrics(arg, aggMetrics, cache.context().queries().detailMetrics()); + } + } + + return new ArrayList<>(aggMetrics.values()); + } + + /** {@inheritDoc} */ + @Override public String toString() { + return S.toString(VisorCacheQueryDetailMetricsCollectorJob.class, this); + } + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/12dfe9e8/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryEntity.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryEntity.java b/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryEntity.java new file mode 100644 index 0000000..9f4dfe7 --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryEntity.java @@ -0,0 +1,188 @@ +/* + * 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.visor.query; + +import java.io.IOException; +import java.io.ObjectInput; +import java.io.ObjectOutput; +import java.util.ArrayList; +import java.util.Collection; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import org.apache.ignite.cache.QueryEntity; +import org.apache.ignite.cache.QueryIndex; +import org.apache.ignite.internal.processors.igfs.IgfsUtils; +import org.apache.ignite.internal.util.typedef.F; +import org.apache.ignite.internal.util.typedef.internal.S; +import org.apache.ignite.internal.util.typedef.internal.U; +import org.apache.ignite.internal.visor.VisorDataTransferObject; + +/** + * Data transfer object for {@link QueryEntity}. + */ +public class VisorQueryEntity extends VisorDataTransferObject { + /** */ + private static final long serialVersionUID = 0L; + + /** Key class used to store key in cache. */ + private String keyType; + + /** Value class used to store value in cache. */ + private String valType; + + /** Fields to be queried, in addition to indexed fields. */ + private Map<String, String> qryFlds; + + /** Key fields. */ + private List<String> keyFields; + + /** Aliases. */ + private Map<String, String> aliases; + + /** Table name. */ + private String tblName; + + /** Fields to create group indexes for. */ + private List<VisorQueryIndex> grps; + + /** + * @param qryEntities Collection of query entities. + * @return Data transfer object for query entities. + */ + public static List<VisorQueryEntity> list(Collection<QueryEntity> qryEntities) { + List<VisorQueryEntity> entities = new ArrayList<>(); + + // Add query entries. + if (!F.isEmpty(qryEntities)) + for (QueryEntity qryEntity : qryEntities) + entities.add(new VisorQueryEntity(qryEntity)); + + return entities; + } + + /** + * Create data transfer object for given cache type metadata. + */ + public VisorQueryEntity() { + // No-op. + } + + /** + * Create data transfer object for given cache type metadata. + * + * @param q Actual cache query entities. + */ + private VisorQueryEntity(QueryEntity q) { + assert q != null; + + keyType = q.getKeyType(); + valType = q.getValueType(); + + keyFields = toList(q.getKeyFields()); + + LinkedHashMap<String, String> qryFields = q.getFields(); + + qryFlds = new LinkedHashMap<>(qryFields); + + aliases = U.copyMap(q.getAliases()); + + Collection<QueryIndex> qryIdxs = q.getIndexes(); + + grps = new ArrayList<>(qryIdxs.size()); + + for (QueryIndex qryIdx : qryIdxs) + grps.add(new VisorQueryIndex(qryIdx)); + } + + /** + * @return Key class used to store key in cache. + */ + public String getKeyType() { + return keyType; + } + + /** + * @return Value class used to store value in cache. + */ + public String getValueType() { + return valType; + } + + /** + * @return Key fields. + */ + public List<String> getKeyFields() { + return keyFields; + } + + /** + * @return Fields to be queried, in addition to indexed fields. + */ + public Map<String, String> getQueryFields() { + return qryFlds; + } + + /** + * @return Field aliases. + */ + public Map<String, String> getAliases() { + return aliases; + } + + /** + * @return Table name. + */ + public String getTableName() { + return tblName; + } + + /** + * @return Fields to create group indexes for. + */ + public List<VisorQueryIndex> getGroups() { + return grps; + } + + /** {@inheritDoc} */ + @Override protected void writeExternalData(ObjectOutput out) throws IOException { + U.writeString(out, keyType); + U.writeString(out, valType); + U.writeCollection(out, keyFields); + IgfsUtils.writeStringMap(out, qryFlds); + U.writeMap(out, aliases); + U.writeString(out, tblName); + U.writeCollection(out, grps); + } + + /** {@inheritDoc} */ + @Override protected void readExternalData(byte protoVer, ObjectInput in) throws IOException, ClassNotFoundException { + keyType = U.readString(in); + valType = U.readString(in); + keyFields = U.readList(in); + qryFlds = IgfsUtils.readStringMap(in); + aliases = U.readMap(in); + tblName = U.readString(in); + grps = U.readList(in); + } + + /** {@inheritDoc} */ + @Override public String toString() { + return S.toString(VisorQueryEntity.class, this); + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/12dfe9e8/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryField.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryField.java b/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryField.java index 18b0d71..ad84dda 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryField.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryField.java @@ -17,15 +17,18 @@ package org.apache.ignite.internal.visor.query; -import java.io.Serializable; -import org.apache.ignite.internal.LessNamingBean; +import java.io.IOException; +import java.io.ObjectInput; +import java.io.ObjectOutput; import org.apache.ignite.internal.util.typedef.F; import org.apache.ignite.internal.util.typedef.internal.S; +import org.apache.ignite.internal.util.typedef.internal.U; +import org.apache.ignite.internal.visor.VisorDataTransferObject; /** * Data transfer object for query field type description. */ -public class VisorQueryField implements Serializable, LessNamingBean { +public class VisorQueryField extends VisorDataTransferObject { /** */ private static final long serialVersionUID = 0L; @@ -42,6 +45,13 @@ public class VisorQueryField implements Serializable, LessNamingBean { private String fieldTypeName; /** + * Default constructor. + */ + public VisorQueryField() { + // No-op. + } + + /** * Create data transfer object with given parameters. * * @param schemaName Schema name. @@ -59,28 +69,28 @@ public class VisorQueryField implements Serializable, LessNamingBean { /** * @return Schema name. */ - public String schemaName() { + public String getSchemaName() { return schemaName; } /** * @return Type name. */ - public String typeName() { + public String getTypeName() { return typeName; } /** * @return Field name. */ - public String fieldName() { + public String getFieldName() { return fieldName; } /** * @return Field type name. */ - public String fieldTypeName() { + public String getFieldTypeName() { return fieldTypeName; } @@ -88,7 +98,7 @@ public class VisorQueryField implements Serializable, LessNamingBean { * @param schema If {@code true} then add schema name to full name. * @return Fully qualified field name with type name and schema name. */ - public String fullName(boolean schema) { + public String getFullName(boolean schema) { if (!F.isEmpty(typeName)) { if (schema && !F.isEmpty(schemaName)) return schemaName + "." + typeName + "." + fieldName; @@ -100,6 +110,22 @@ public class VisorQueryField implements Serializable, LessNamingBean { } /** {@inheritDoc} */ + @Override protected void writeExternalData(ObjectOutput out) throws IOException { + U.writeString(out, schemaName); + U.writeString(out, typeName); + U.writeString(out, fieldName); + U.writeString(out, fieldTypeName); + } + + /** {@inheritDoc} */ + @Override protected void readExternalData(byte protoVer, ObjectInput in) throws IOException, ClassNotFoundException { + schemaName = U.readString(in); + typeName = U.readString(in); + fieldName = U.readString(in); + fieldTypeName = U.readString(in); + } + + /** {@inheritDoc} */ @Override public String toString() { return S.toString(VisorQueryField.class, this); } http://git-wip-us.apache.org/repos/asf/ignite/blob/12dfe9e8/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryIndex.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryIndex.java b/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryIndex.java new file mode 100644 index 0000000..d9fa2a4 --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryIndex.java @@ -0,0 +1,105 @@ +/* + * 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.visor.query; + +import java.io.IOException; +import java.io.ObjectInput; +import java.io.ObjectOutput; +import java.util.List; +import org.apache.ignite.cache.QueryIndex; +import org.apache.ignite.cache.QueryIndexType; +import org.apache.ignite.internal.util.typedef.internal.S; +import org.apache.ignite.internal.util.typedef.internal.U; +import org.apache.ignite.internal.visor.VisorDataTransferObject; + +/** + * Data transfer object for {@link QueryIndex}. + */ +public class VisorQueryIndex extends VisorDataTransferObject { + /** */ + private static final long serialVersionUID = 0L; + + /** Name of index. */ + private String name; + + /** Type of index. */ + private QueryIndexType type; + + /** Fields to create group indexes for. */ + private List<VisorQueryIndexField> fields; + + /** + * Create data transfer object for given cache type metadata. + */ + public VisorQueryIndex() { + // No-op. + } + + /** + * Create data transfer object for given cache type metadata. + * + * @param idx Actual cache query entity index. + */ + public VisorQueryIndex(QueryIndex idx) { + assert idx != null; + + name = idx.getName(); + type = idx.getIndexType(); + fields = VisorQueryIndexField.list(idx); + } + + /** + * @return Name of index. + */ + public String getName() { + return name; + } + + /** + * @return Type of index. + */ + public QueryIndexType getType() { + return type; + } + + /** + * @return Fields to create group indexes for. + */ + public List<VisorQueryIndexField> getFields() { + return fields; + } + + /** {@inheritDoc} */ + @Override protected void writeExternalData(ObjectOutput out) throws IOException { + U.writeString(out, name); + U.writeEnum(out, type); + U.writeCollection(out, fields); + } + + /** {@inheritDoc} */ + @Override protected void readExternalData(byte protoVer, ObjectInput in) throws IOException, ClassNotFoundException { + name = U.readString(in); + type = QueryIndexType.fromOrdinal(in.readByte()); + fields = U.readList(in); + } + + /** {@inheritDoc} */ + @Override public String toString() { + return S.toString(VisorQueryIndex.class, this); + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/12dfe9e8/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryIndexField.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryIndexField.java b/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryIndexField.java new file mode 100644 index 0000000..fb32dd1 --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryIndexField.java @@ -0,0 +1,106 @@ +/* + * 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.visor.query; + +import java.io.IOException; +import java.io.ObjectInput; +import java.io.ObjectOutput; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import org.apache.ignite.cache.QueryEntity; +import org.apache.ignite.cache.QueryIndex; +import org.apache.ignite.internal.util.typedef.internal.S; +import org.apache.ignite.internal.util.typedef.internal.U; +import org.apache.ignite.internal.visor.VisorDataTransferObject; + +/** + * Data transfer object for {@link QueryEntity}. + */ +public class VisorQueryIndexField extends VisorDataTransferObject { + /** */ + private static final long serialVersionUID = 0L; + + /** Index field name. */ + private String fldName; + + /** Index field sort order. */ + private boolean fldSort; + + /** + * Create data transfer object for given cache type metadata. + */ + public VisorQueryIndexField() { + // No-op. + } + + /** + * Create data transfer object for given cache type metadata. + * + * @param fldName Index field name. + * @param fldSort Index field sort order. + */ + public VisorQueryIndexField(String fldName, boolean fldSort) { + this.fldName = fldName; + this.fldSort = fldSort; + } + + /** + * @param idx Query entity index. + * @return Data transfer object for query entity index fields. + */ + public static List<VisorQueryIndexField> list(QueryIndex idx) { + List<VisorQueryIndexField> res = new ArrayList<>(); + + for (Map.Entry<String, Boolean> field: idx.getFields().entrySet()) + res.add(new VisorQueryIndexField(field.getKey(), !field.getValue())); + + return res; + } + + /** + * @return Index field name. + */ + public String getFieldName() { + return fldName; + } + + /** + * @return Index field sort order. + */ + public boolean isFieldSort() { + return fldSort; + } + + /** {@inheritDoc} */ + @Override protected void writeExternalData(ObjectOutput out) throws IOException { + U.writeString(out, fldName); + out.writeBoolean(fldSort); + } + + /** {@inheritDoc} */ + @Override protected void readExternalData(byte protoVer, ObjectInput in) throws IOException, ClassNotFoundException { + fldName = U.readString(in); + fldSort = in.readBoolean(); + } + + /** {@inheritDoc} */ + @Override public String toString() { + return S.toString(VisorQueryIndexField.class, this); + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/12dfe9e8/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryJob.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryJob.java b/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryJob.java deleted file mode 100644 index 61ccac2..0000000 --- a/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryJob.java +++ /dev/null @@ -1,275 +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.visor.query; - -import java.sql.SQLException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Iterator; -import java.util.List; -import java.util.UUID; -import java.util.concurrent.ConcurrentMap; -import javax.cache.Cache; -import org.apache.ignite.IgniteCache; -import org.apache.ignite.cache.CachePeekMode; -import org.apache.ignite.cache.query.QueryCursor; -import org.apache.ignite.cache.query.ScanQuery; -import org.apache.ignite.cache.query.SqlFieldsQuery; -import org.apache.ignite.internal.processors.cache.GridCacheProcessor; -import org.apache.ignite.internal.processors.query.GridQueryFieldMetadata; -import org.apache.ignite.internal.processors.timeout.GridTimeoutObjectAdapter; -import org.apache.ignite.internal.util.typedef.internal.S; -import org.apache.ignite.internal.util.typedef.internal.U; -import org.apache.ignite.internal.visor.VisorJob; -import org.apache.ignite.internal.visor.util.VisorExceptionWrapper; -import org.apache.ignite.lang.IgniteBiPredicate; -import org.apache.ignite.lang.IgniteBiTuple; - -import static org.apache.ignite.internal.visor.query.VisorQueryUtils.RMV_DELAY; -import static org.apache.ignite.internal.visor.query.VisorQueryUtils.SCAN_CACHE_WITH_FILTER; -import static org.apache.ignite.internal.visor.query.VisorQueryUtils.SCAN_CACHE_WITH_FILTER_CASE_SENSITIVE; -import static org.apache.ignite.internal.visor.query.VisorQueryUtils.SCAN_COL_NAMES; -import static org.apache.ignite.internal.visor.query.VisorQueryUtils.SCAN_QRY_NAME; -import static org.apache.ignite.internal.visor.query.VisorQueryUtils.SCAN_NEAR_CACHE; -import static org.apache.ignite.internal.visor.query.VisorQueryUtils.SQL_QRY_NAME; -import static org.apache.ignite.internal.visor.query.VisorQueryUtils.fetchScanQueryRows; -import static org.apache.ignite.internal.visor.query.VisorQueryUtils.fetchSqlQueryRows; - -/** - * Job for execute SCAN or SQL query and get first page of results. - */ -public class VisorQueryJob extends VisorJob<VisorQueryArg, IgniteBiTuple<? extends VisorExceptionWrapper, VisorQueryResultEx>> { - /** */ - private static final long serialVersionUID = 0L; - - /** - * Create job with specified argument. - * - * @param arg Job argument. - * @param debug Debug flag. - */ - protected VisorQueryJob(VisorQueryArg arg, boolean debug) { - super(arg, debug); - } - - /** - * @param cacheName Cache name. - * @return Cache to execute query. - */ - protected IgniteCache<Object, Object> cache(String cacheName) { - GridCacheProcessor cacheProcessor = ignite.context().cache(); - - return cacheProcessor.jcache(cacheName); - } - - /** - * Execute scan query. - * - * @param c Cache to scan. - * @param arg Job argument with query parameters. - * @return Query cursor. - */ - private QueryCursor<Cache.Entry<Object, Object>> scan(IgniteCache<Object, Object> c, VisorQueryArg arg, - IgniteBiPredicate<Object, Object> filter) { - ScanQuery<Object, Object> qry = new ScanQuery<>(filter); - qry.setPageSize(arg.pageSize()); - qry.setLocal(arg.local()); - - return c.withKeepBinary().query(qry); - } - - /** - * Scan near cache. - * - * @param c Cache to scan near entries. - * @return Cache entries iterator wrapped with query cursor. - */ - private QueryCursor<Cache.Entry<Object, Object>> near(IgniteCache<Object, Object> c) { - return new VisorNearCacheCursor<>(c.localEntries(CachePeekMode.NEAR).iterator()); - } - - /** {@inheritDoc} */ - @Override protected IgniteBiTuple<? extends VisorExceptionWrapper, VisorQueryResultEx> run(final VisorQueryArg arg) { - try { - UUID nid = ignite.localNode().id(); - - String qryTxt = arg.queryText(); - - boolean scan = qryTxt == null; - - boolean scanWithFilter = qryTxt != null && qryTxt.startsWith(SCAN_CACHE_WITH_FILTER); - - boolean near = qryTxt != null && qryTxt.startsWith(SCAN_NEAR_CACHE); - - boolean scanAny = scan || scanWithFilter || near; - - // Generate query ID to store query cursor in node local storage. - String qryId = (scanAny ? SCAN_QRY_NAME : SQL_QRY_NAME) + "-" + UUID.randomUUID(); - - IgniteCache<Object, Object> c = cache(arg.cacheName()); - - if (scanAny) { - long start = U.currentTimeMillis(); - - IgniteBiPredicate<Object, Object> filter = null; - - if (scanWithFilter) { - boolean caseSensitive = qryTxt.startsWith(SCAN_CACHE_WITH_FILTER_CASE_SENSITIVE); - - String ptrn = qryTxt.substring(caseSensitive - ? SCAN_CACHE_WITH_FILTER_CASE_SENSITIVE.length() - : SCAN_CACHE_WITH_FILTER.length()); - - filter = new VisorQueryScanSubstringFilter(caseSensitive, ptrn); - } - - VisorQueryCursor<Cache.Entry<Object, Object>> cur = new VisorQueryCursor<>(near ? near(c) : scan(c, arg, filter)); - - List<Object[]> rows = fetchScanQueryRows(cur, arg.pageSize()); - - long duration = U.currentTimeMillis() - start; // Scan duration + fetch duration. - - boolean hasNext = cur.hasNext(); - - if (hasNext) { - ignite.cluster().<String, VisorQueryCursor>nodeLocalMap().put(qryId, cur); - - scheduleResultSetHolderRemoval(qryId); - } - else - cur.close(); - - return new IgniteBiTuple<>(null, new VisorQueryResultEx(nid, qryId, SCAN_COL_NAMES, rows, hasNext, - duration)); - } - else { - SqlFieldsQuery qry = new SqlFieldsQuery(arg.queryText()); - qry.setPageSize(arg.pageSize()); - qry.setDistributedJoins(arg.distributedJoins()); - qry.setEnforceJoinOrder(arg.enforceJoinOrder()); - qry.setLocal(arg.local()); - - long start = U.currentTimeMillis(); - - VisorQueryCursor<List<?>> cur = new VisorQueryCursor<>(c.withKeepBinary().query(qry)); - - Collection<GridQueryFieldMetadata> meta = cur.fieldsMeta(); - - if (meta == null) - return new IgniteBiTuple<>( - new VisorExceptionWrapper(new SQLException("Fail to execute query. No metadata available.")), null); - else { - List<VisorQueryField> names = new ArrayList<>(meta.size()); - - for (GridQueryFieldMetadata col : meta) - names.add(new VisorQueryField(col.schemaName(), col.typeName(), - col.fieldName(), col.fieldTypeName())); - - List<Object[]> rows = fetchSqlQueryRows(cur, arg.pageSize()); - - long duration = U.currentTimeMillis() - start; // Query duration + fetch duration. - - boolean hasNext = cur.hasNext(); - - if (hasNext) { - ignite.cluster().<String, VisorQueryCursor<List<?>>>nodeLocalMap().put(qryId, cur); - - scheduleResultSetHolderRemoval(qryId); - } - else - cur.close(); - - return new IgniteBiTuple<>(null, new VisorQueryResultEx(nid, qryId, names, rows, hasNext, duration)); - } - } - } - catch (Throwable e) { - return new IgniteBiTuple<>(new VisorExceptionWrapper(e), null); - } - } - - /** - * @param qryId Unique query result id. - */ - private void scheduleResultSetHolderRemoval(final String qryId) { - ignite.context().timeout().addTimeoutObject(new GridTimeoutObjectAdapter(RMV_DELAY) { - @Override public void onTimeout() { - ConcurrentMap<String, VisorQueryCursor> storage = ignite.cluster().nodeLocalMap(); - - VisorQueryCursor cur = storage.get(qryId); - - if (cur != null) { - // If cursor was accessed since last scheduling, set access flag to false and reschedule. - if (cur.accessed()) { - cur.accessed(false); - - scheduleResultSetHolderRemoval(qryId); - } - else { - // Remove stored cursor otherwise. - storage.remove(qryId); - - cur.close(); - } - } - } - }); - } - - /** {@inheritDoc} */ - @Override public String toString() { - return S.toString(VisorQueryJob.class, this); - } - - /** - * Wrapper for cache iterator to behave like {@link QueryCursor}. - */ - private static class VisorNearCacheCursor<T> implements QueryCursor<T> { - /** Wrapped iterator. */ - private final Iterator<T> it; - - /** - * Wrapping constructor. - * - * @param it Near cache iterator to wrap. - */ - private VisorNearCacheCursor(Iterator<T> it) { - this.it = it; - } - - /** {@inheritDoc} */ - @Override public List<T> getAll() { - List<T> all = new ArrayList<>(); - - while(it.hasNext()) - all.add(it.next()); - - return all; - } - - /** {@inheritDoc} */ - @Override public void close() { - // Nothing to close. - } - - /** {@inheritDoc} */ - @Override public Iterator<T> iterator() { - return it; - } - } -} http://git-wip-us.apache.org/repos/asf/ignite/blob/12dfe9e8/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryMetrics.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryMetrics.java b/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryMetrics.java new file mode 100644 index 0000000..f878ab6 --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryMetrics.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.visor.query; + +import java.io.IOException; +import java.io.ObjectInput; +import java.io.ObjectOutput; +import org.apache.ignite.cache.query.QueryMetrics; +import org.apache.ignite.internal.util.typedef.internal.S; +import org.apache.ignite.internal.visor.VisorDataTransferObject; + +/** + * Data transfer object for cache query metrics. + */ +public class VisorQueryMetrics extends VisorDataTransferObject { + /** */ + private static final long serialVersionUID = 0L; + + /** Minimum execution time of query. */ + private long minTime; + + /** Maximum execution time of query. */ + private long maxTime; + + /** Average execution time of query. */ + private double avgTime; + + /** Number of executions. */ + private int execs; + + /** Total number of times a query execution failed. */ + private int fails; + + /** + * Default constructor. + */ + public VisorQueryMetrics() { + // No-op. + } + + /** + * Create data transfer object for given cache metrics. + * @param m Cache query metrics. + */ + public VisorQueryMetrics(QueryMetrics m) { + minTime = m.minimumTime(); + maxTime = m.maximumTime(); + avgTime = m.averageTime(); + execs = m.executions(); + fails = m.fails(); + } + + /** + * @return Minimum execution time of query. + */ + public long getMinimumTime() { + return minTime; + } + + /** + * @return Maximum execution time of query. + */ + public long getMaximumTime() { + return maxTime; + } + + /** + * @return Average execution time of query. + */ + public double getAverageTime() { + return avgTime; + } + + /** + * @return Number of executions. + */ + public int getExecutions() { + return execs; + } + + /** + * @return Total number of times a query execution failed. + */ + public int getFailures() { + return fails; + } + + /** {@inheritDoc} */ + @Override protected void writeExternalData(ObjectOutput out) throws IOException { + out.writeLong(minTime); + out.writeLong(maxTime); + out.writeDouble(avgTime); + out.writeInt(execs); + out.writeInt(fails); + } + + /** {@inheritDoc} */ + @Override protected void readExternalData(byte protoVer, ObjectInput in) throws IOException, ClassNotFoundException { + minTime = in.readLong(); + maxTime = in.readLong(); + avgTime = in.readDouble(); + execs = in.readInt(); + fails = in.readInt(); + } + + /** {@inheritDoc} */ + @Override public String toString() { + return S.toString(VisorQueryMetrics.class, this); + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/12dfe9e8/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryNextPageTask.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryNextPageTask.java b/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryNextPageTask.java index 52a167d..4684c49 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryNextPageTask.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryNextPageTask.java @@ -26,25 +26,24 @@ import org.apache.ignite.internal.util.typedef.internal.S; import org.apache.ignite.internal.util.typedef.internal.U; import org.apache.ignite.internal.visor.VisorJob; import org.apache.ignite.internal.visor.VisorOneNodeTask; -import org.apache.ignite.lang.IgniteBiTuple; /** * Task for collecting next page previously executed SQL or SCAN query. */ @GridInternal -public class VisorQueryNextPageTask extends VisorOneNodeTask<IgniteBiTuple<String, Integer>, VisorQueryResult> { +public class VisorQueryNextPageTask extends VisorOneNodeTask<VisorQueryNextPageTaskArg, VisorQueryResult> { /** */ private static final long serialVersionUID = 0L; /** {@inheritDoc} */ - @Override protected VisorQueryNextPageJob job(IgniteBiTuple<String, Integer> arg) { + @Override protected VisorQueryNextPageJob job(VisorQueryNextPageTaskArg arg) { return new VisorQueryNextPageJob(arg, debug); } /** * Job for collecting next page previously executed SQL or SCAN query. */ - private static class VisorQueryNextPageJob extends VisorJob<IgniteBiTuple<String, Integer>, VisorQueryResult> { + private static class VisorQueryNextPageJob extends VisorJob<VisorQueryNextPageTaskArg, VisorQueryResult> { /** */ private static final long serialVersionUID = 0L; @@ -54,13 +53,13 @@ public class VisorQueryNextPageTask extends VisorOneNodeTask<IgniteBiTuple<Strin * @param arg Job argument. * @param debug Debug flag. */ - private VisorQueryNextPageJob(IgniteBiTuple<String, Integer> arg, boolean debug) { + private VisorQueryNextPageJob(VisorQueryNextPageTaskArg arg, boolean debug) { super(arg, debug); } /** {@inheritDoc} */ - @Override protected VisorQueryResult run(IgniteBiTuple<String, Integer> arg) { - return arg.get1().startsWith(VisorQueryUtils.SCAN_QRY_NAME) ? nextScanPage(arg) : nextSqlPage(arg); + @Override protected VisorQueryResult run(VisorQueryNextPageTaskArg arg) { + return arg.getQueryId().startsWith(VisorQueryUtils.SCAN_QRY_NAME) ? nextScanPage(arg) : nextSqlPage(arg); } /** @@ -69,19 +68,19 @@ public class VisorQueryNextPageTask extends VisorOneNodeTask<IgniteBiTuple<Strin * @param arg Query name and page size. * @return Query result with next page. */ - private VisorQueryResult nextSqlPage(IgniteBiTuple<String, Integer> arg) { + private VisorQueryResult nextSqlPage(VisorQueryNextPageTaskArg arg) { long start = U.currentTimeMillis(); ConcurrentMap<String, VisorQueryCursor<List<?>>> storage = ignite.cluster().nodeLocalMap(); - String qryId = arg.get1(); + String qryId = arg.getQueryId(); VisorQueryCursor<List<?>> cur = storage.get(qryId); if (cur == null) throw new IgniteException("SQL query results are expired."); - List<Object[]> nextRows = VisorQueryUtils.fetchSqlQueryRows(cur, arg.get2()); + List<Object[]> nextRows = VisorQueryUtils.fetchSqlQueryRows(cur, arg.getPageSize()); boolean hasMore = cur.hasNext(); @@ -93,7 +92,8 @@ public class VisorQueryNextPageTask extends VisorOneNodeTask<IgniteBiTuple<Strin cur.close(); } - return new VisorQueryResult(nextRows, hasMore, U.currentTimeMillis() - start); + return new VisorQueryResult(ignite.localNode().id(), qryId, null, nextRows, hasMore, + U.currentTimeMillis() - start); } /** @@ -102,19 +102,19 @@ public class VisorQueryNextPageTask extends VisorOneNodeTask<IgniteBiTuple<Strin * @param arg Query name and page size. * @return Next page with data. */ - private VisorQueryResult nextScanPage(IgniteBiTuple<String, Integer> arg) { + private VisorQueryResult nextScanPage(VisorQueryNextPageTaskArg arg) { long start = U.currentTimeMillis(); ConcurrentMap<String, VisorQueryCursor<Cache.Entry<Object, Object>>> storage = ignite.cluster().nodeLocalMap(); - String qryId = arg.get1(); + String qryId = arg.getQueryId(); VisorQueryCursor<Cache.Entry<Object, Object>> cur = storage.get(qryId); if (cur == null) throw new IgniteException("Scan query results are expired."); - List<Object[]> rows = VisorQueryUtils.fetchScanQueryRows(cur, arg.get2()); + List<Object[]> rows = VisorQueryUtils.fetchScanQueryRows(cur, arg.getPageSize()); boolean hasMore = cur.hasNext(); @@ -126,7 +126,8 @@ public class VisorQueryNextPageTask extends VisorOneNodeTask<IgniteBiTuple<Strin cur.close(); } - return new VisorQueryResult(rows, hasMore, U.currentTimeMillis() - start); + return new VisorQueryResult(ignite.localNode().id(), qryId, null, rows, hasMore, + U.currentTimeMillis() - start); } /** {@inheritDoc} */ @@ -134,4 +135,4 @@ public class VisorQueryNextPageTask extends VisorOneNodeTask<IgniteBiTuple<Strin return S.toString(VisorQueryNextPageJob.class, this); } } -} \ No newline at end of file +} http://git-wip-us.apache.org/repos/asf/ignite/blob/12dfe9e8/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryNextPageTaskArg.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryNextPageTaskArg.java b/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryNextPageTaskArg.java new file mode 100644 index 0000000..d0f62b9 --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryNextPageTaskArg.java @@ -0,0 +1,86 @@ +/* + * 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.visor.query; + +import java.io.IOException; +import java.io.ObjectInput; +import java.io.ObjectOutput; +import org.apache.ignite.internal.util.typedef.internal.S; +import org.apache.ignite.internal.util.typedef.internal.U; +import org.apache.ignite.internal.visor.VisorDataTransferObject; + +/** + * Arguments for {@link VisorQueryNextPageTask}. + */ +public class VisorQueryNextPageTaskArg extends VisorDataTransferObject { + /** */ + private static final long serialVersionUID = 0L; + + /** ID of query execution. */ + private String qryId; + + /** Number of rows to load. */ + private int pageSize; + + /** + * Default constructor. + */ + public VisorQueryNextPageTaskArg() { + // No-op. + } + + /** + * @param qryId ID of query execution. + * @param pageSize Number of rows to load. + */ + public VisorQueryNextPageTaskArg(String qryId, int pageSize) { + this.qryId = qryId; + this.pageSize = pageSize; + } + + /** + * @return ID of query execution. + */ + public String getQueryId() { + return qryId; + } + + /** + * @return Number of rows to load. + */ + public int getPageSize() { + return pageSize; + } + + /** {@inheritDoc} */ + @Override protected void writeExternalData(ObjectOutput out) throws IOException { + U.writeString(out, qryId); + out.writeInt(pageSize); + } + + /** {@inheritDoc} */ + @Override protected void readExternalData(byte protoVer, ObjectInput in) throws IOException, ClassNotFoundException { + qryId = U.readString(in); + pageSize = in.readInt(); + } + + /** {@inheritDoc} */ + @Override public String toString() { + return S.toString(VisorQueryNextPageTaskArg.class, this); + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/12dfe9e8/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryResetDetailMetricsTask.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryResetDetailMetricsTask.java b/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryResetDetailMetricsTask.java new file mode 100644 index 0000000..6d35e32 --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryResetDetailMetricsTask.java @@ -0,0 +1,71 @@ +/* + * 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.visor.query; + +import org.apache.ignite.IgniteCache; +import org.apache.ignite.internal.processors.task.GridInternal; +import org.apache.ignite.internal.util.typedef.internal.S; +import org.apache.ignite.internal.visor.VisorJob; +import org.apache.ignite.internal.visor.VisorOneNodeTask; + +/** + * Reset query detail metrics. + */ +@GridInternal +public class VisorQueryResetDetailMetricsTask extends VisorOneNodeTask<Void, Void> { + /** */ + private static final long serialVersionUID = 0L; + + /** {@inheritDoc} */ + @Override protected VisorCacheResetQueryDetailMetricsJob job(Void arg) { + return new VisorCacheResetQueryDetailMetricsJob(arg, debug); + } + + /** + * Job that reset query detail metrics. + */ + private static class VisorCacheResetQueryDetailMetricsJob extends VisorJob<Void, Void> { + /** */ + private static final long serialVersionUID = 0L; + + /** + * @param arg Task argument. + * @param debug Debug flag. + */ + private VisorCacheResetQueryDetailMetricsJob(Void arg, boolean debug) { + super(arg, debug); + } + + /** {@inheritDoc} */ + @Override protected Void run(Void arg) { + for (String cacheName : ignite.cacheNames()) { + IgniteCache cache = ignite.cache(cacheName); + + if (cache != null) + cache.resetQueryDetailMetrics(); + } + + return null; + } + + /** {@inheritDoc} */ + @Override public String toString() { + return S.toString(VisorCacheResetQueryDetailMetricsJob.class, this); + } + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/12dfe9e8/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryResetMetricsTask.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryResetMetricsTask.java b/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryResetMetricsTask.java new file mode 100644 index 0000000..3c5c668 --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryResetMetricsTask.java @@ -0,0 +1,69 @@ +/* + * 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.visor.query; + +import org.apache.ignite.IgniteCache; +import org.apache.ignite.internal.processors.task.GridInternal; +import org.apache.ignite.internal.util.typedef.internal.S; +import org.apache.ignite.internal.visor.VisorJob; +import org.apache.ignite.internal.visor.VisorOneNodeTask; + +/** + * Reset compute grid query metrics. + */ +@GridInternal +public class VisorQueryResetMetricsTask extends VisorOneNodeTask<String, Void> { + /** */ + private static final long serialVersionUID = 0L; + + /** {@inheritDoc} */ + @Override protected VisorQueryResetMetricsJob job(String arg) { + return new VisorQueryResetMetricsJob(arg, debug); + } + + /** + * Job that reset cache query metrics. + */ + private static class VisorQueryResetMetricsJob extends VisorJob<String, Void> { + /** */ + private static final long serialVersionUID = 0L; + + /** + * @param arg Cache name to reset query metrics for. + * @param debug Debug flag. + */ + private VisorQueryResetMetricsJob(String arg, boolean debug) { + super(arg, debug); + } + + /** {@inheritDoc} */ + @Override protected Void run(String cacheName) { + IgniteCache cache = ignite.cache(cacheName); + + if (cache != null) + cache.resetQueryMetrics(); + + return null; + } + + /** {@inheritDoc} */ + @Override public String toString() { + return S.toString(VisorQueryResetMetricsJob.class, this); + } + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/12dfe9e8/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryResult.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryResult.java b/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryResult.java index 21d1ed7..f7beae2 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryResult.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryResult.java @@ -17,62 +17,135 @@ package org.apache.ignite.internal.visor.query; -import java.io.Serializable; +import java.io.IOException; +import java.io.ObjectInput; +import java.io.ObjectOutput; +import java.util.Collection; import java.util.List; -import org.apache.ignite.internal.LessNamingBean; +import java.util.UUID; import org.apache.ignite.internal.util.typedef.internal.S; +import org.apache.ignite.internal.util.typedef.internal.U; +import org.apache.ignite.internal.visor.VisorDataTransferObject; /** * Result for cache query tasks. */ -public class VisorQueryResult implements Serializable, LessNamingBean { +public class VisorQueryResult extends VisorDataTransferObject { /** */ private static final long serialVersionUID = 0L; + /** Node where query executed. */ + private UUID resNodeId; + + /** Query ID to store in node local. */ + private String qryId; + + /** Query columns descriptors. */ + private List<VisorQueryField> cols; + /** Rows fetched from query. */ - private final List<Object[]> rows; + private List<Object[]> rows; /** Whether query has more rows to fetch. */ - private final boolean hasMore; + private boolean hasMore; /** Query duration */ - private final long duration; + private long duration; + + /** + * Default constructor. + */ + public VisorQueryResult() { + // No-op. + } /** - * Create task result with given parameters - * + * @param resNodeId Node where query executed. + * @param qryId Query ID for future extraction in nextPage() access. + * @param cols Columns descriptors. * @param rows Rows fetched from query. * @param hasMore Whether query has more rows to fetch. * @param duration Query duration. */ - public VisorQueryResult(List<Object[]> rows, boolean hasMore, long duration) { + public VisorQueryResult( + UUID resNodeId, + String qryId, + List<VisorQueryField> cols, + List<Object[]> rows, + boolean hasMore, + long duration + ) { + this.resNodeId = resNodeId; + this.qryId = qryId; + this.cols = cols; this.rows = rows; this.hasMore = hasMore; this.duration = duration; } /** + * @return Response node id. + */ + public UUID getResponseNodeId() { + return resNodeId; + } + + /** + * @return Query id. + */ + public String getQueryId() { + return qryId; + } + + /** + * @return Columns. + */ + public Collection<VisorQueryField> getColumns() { + return cols; + } + + /** * @return Rows fetched from query. */ - public List<Object[]> rows() { + public List<Object[]> getRows() { return rows; } /** * @return Whether query has more rows to fetch. */ - public boolean hasMore() { + public boolean isHasMore() { return hasMore; } /** * @return Duration of next page fetching. */ - public long duration() { + public long getDuration() { return duration; } /** {@inheritDoc} */ + @Override protected void writeExternalData(ObjectOutput out) throws IOException { + U.writeUuid(out, resNodeId); + U.writeString(out, qryId); + U.writeCollection(out, cols); + U.writeCollection(out, rows); + out.writeBoolean(hasMore); + out.writeLong(duration); + } + + /** {@inheritDoc} */ + @Override protected void readExternalData(byte protoVer, ObjectInput in) throws IOException, ClassNotFoundException { + resNodeId = U.readUuid(in); + qryId = U.readString(in); + cols = U.readList(in); + rows = U.readList(in); + hasMore = in.readBoolean(); + duration = in.readLong(); + } + + /** {@inheritDoc} */ @Override public String toString() { return S.toString(VisorQueryResult.class, this); } http://git-wip-us.apache.org/repos/asf/ignite/blob/12dfe9e8/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryResultEx.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryResultEx.java b/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryResultEx.java deleted file mode 100644 index 218cb36..0000000 --- a/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryResultEx.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.visor.query; - -import java.util.Collection; -import java.util.List; -import java.util.UUID; -import org.apache.ignite.internal.util.typedef.internal.S; - -/** - * Result for cache query tasks. - */ -public class VisorQueryResultEx extends VisorQueryResult { - /** */ - private static final long serialVersionUID = 0L; - - /** Node where query executed. */ - private final UUID resNodeId; - - /** Query ID to store in node local. */ - private final String qryId; - - /** Query columns descriptors. */ - private final Collection<VisorQueryField> cols; - - /** - * @param resNodeId Node where query executed. - * @param qryId Query ID for future extraction in nextPage() access. - * @param cols Columns descriptors. - * @param rows Rows fetched from query. - * @param hasMore Whether query has more rows to fetch. - * @param duration Query duration. - */ - public VisorQueryResultEx( - UUID resNodeId, - String qryId, - Collection<VisorQueryField> cols, - List<Object[]> rows, - boolean hasMore, - long duration - ) { - super(rows, hasMore, duration); - - this.resNodeId = resNodeId; - this.qryId = qryId; - this.cols = cols; - } - - /** - * @return Response node id. - */ - public UUID responseNodeId() { - return resNodeId; - } - - /** - * @return Query id. - */ - public String queryId() { - return qryId; - } - - /** - * @return Columns. - */ - public Collection<VisorQueryField> columns() { - return cols; - } - - /** {@inheritDoc} */ - @Override public String toString() { - return S.toString(VisorQueryResultEx.class, this); - } -} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ignite/blob/12dfe9e8/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryScanRegexFilter.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryScanRegexFilter.java b/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryScanRegexFilter.java new file mode 100644 index 0000000..fa4a596 --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryScanRegexFilter.java @@ -0,0 +1,59 @@ +/* + * 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.visor.query; + +import java.util.regex.Pattern; +import org.apache.ignite.binary.BinaryObject; +import org.apache.ignite.lang.IgniteBiPredicate; + +/** + * Filter scan results by specified substring in string presentation of key or value. + */ +public class VisorQueryScanRegexFilter implements IgniteBiPredicate<Object, Object> { + /** */ + private static final long serialVersionUID = 0L; + + /** Regex pattern to search data. */ + private final Pattern ptrn; + + /** + * Create filter instance. + * + * @param caseSensitive Case sensitive flag. + * @param regex Regex search flag. + * @param ptrn String to search in string presentation of key or value. + */ + public VisorQueryScanRegexFilter(boolean caseSensitive, boolean regex, String ptrn) { + int flags = caseSensitive ? 0 : Pattern.CASE_INSENSITIVE; + + this.ptrn = Pattern.compile(regex ? ptrn : ".*?" + Pattern.quote(ptrn) + ".*?", flags); + } + /** + * Check that key or value contains specified string. + * + * @param key Key object. + * @param val Value object. + * @return {@code true} when string presentation of key or value contain specified string. + */ + @Override public boolean apply(Object key, Object val) { + String k = key instanceof BinaryObject ? VisorQueryUtils.binaryToString((BinaryObject)key) : key.toString(); + String v = val instanceof BinaryObject ? VisorQueryUtils.binaryToString((BinaryObject)val) : val.toString(); + + return ptrn.matcher(k).find() || ptrn.matcher(v).find(); + } +}
