http://git-wip-us.apache.org/repos/asf/ignite/blob/ec3819f7/examples/pom.xml ---------------------------------------------------------------------- diff --cc examples/pom.xml index 54dc2ea,5b8c36a..a5d7ee2 --- a/examples/pom.xml +++ b/examples/pom.xml @@@ -57,21 -51,7 +57,21 @@@ <dependency> <groupId>org.apache.ignite</groupId> + <artifactId>ignite-rest-http</artifactId> + <version>${project.version}</version> + </dependency> + + <dependency> + <groupId>org.apache.ignite</groupId> + <artifactId>ignite-nodejs</artifactId> + <version>${project.version}</version> + <type>test-jar</type> + <scope>test</scope> + </dependency> + + <dependency> + <groupId>org.apache.ignite</groupId> - <artifactId>ignite-spring</artifactId> + <artifactId>ignite-log4j</artifactId> <version>${project.version}</version> </dependency>
http://git-wip-us.apache.org/repos/asf/ignite/blob/ec3819f7/examples/src/main/java/org/apache/ignite/examples/computegrid/ComputeTaskMapExample.java ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ignite/blob/ec3819f7/modules/clients/src/test/java/org/apache/ignite/internal/processors/rest/JettyRestProcessorAbstractSelfTest.java ---------------------------------------------------------------------- diff --cc modules/clients/src/test/java/org/apache/ignite/internal/processors/rest/JettyRestProcessorAbstractSelfTest.java index aa838bb,4b1d47c..959ff1a --- a/modules/clients/src/test/java/org/apache/ignite/internal/processors/rest/JettyRestProcessorAbstractSelfTest.java +++ b/modules/clients/src/test/java/org/apache/ignite/internal/processors/rest/JettyRestProcessorAbstractSelfTest.java @@@ -17,28 -17,43 +17,47 @@@ package org.apache.ignite.internal.processors.rest; - import net.sf.json.*; - import org.apache.ignite.*; - import org.apache.ignite.cache.*; - import org.apache.ignite.cache.query.*; - import org.apache.ignite.cache.query.annotations.*; - import org.apache.ignite.cluster.*; - import org.apache.ignite.configuration.*; - import org.apache.ignite.internal.processors.json.*; - import org.apache.ignite.internal.processors.rest.handlers.*; - import org.apache.ignite.internal.util.typedef.*; - import org.apache.ignite.lang.*; - import org.apache.ignite.testframework.*; + import java.io.InputStream; + import java.io.InputStreamReader; + import java.io.LineNumberReader; + import java.io.Serializable; + import java.net.URL; + import java.net.URLConnection; + import java.net.URLEncoder; + import java.util.Collection; + import java.util.HashMap; + import java.util.Iterator; + import java.util.List; + import java.util.Map; + import java.util.UUID; + import java.util.concurrent.ConcurrentHashMap; + import java.util.regex.Pattern; + import net.sf.json.JSONNull; + import net.sf.json.JSONObject; + import org.apache.ignite.IgniteCache; + import org.apache.ignite.cache.CacheMode; + import org.apache.ignite.cache.CachePeekMode; + import org.apache.ignite.cache.query.SqlQuery; + import org.apache.ignite.cache.query.annotations.QuerySqlField; + import org.apache.ignite.cluster.ClusterNode; + import org.apache.ignite.configuration.CacheConfiguration; + import org.apache.ignite.internal.processors.cache.IgniteCacheProxy; + import org.apache.ignite.internal.processors.cache.query.GridCacheSqlIndexMetadata; + import org.apache.ignite.internal.processors.cache.query.GridCacheSqlMetadata; + import org.apache.ignite.internal.processors.rest.handlers.GridRestCommandHandler; + import org.apache.ignite.internal.util.typedef.F; + import org.apache.ignite.internal.util.typedef.internal.U; + import org.apache.ignite.internal.util.typedef.P1; + import org.apache.ignite.lang.IgniteBiPredicate; + import org.apache.ignite.lang.IgnitePredicate; + import org.apache.ignite.testframework.GridTestUtils; -import static org.apache.ignite.IgniteSystemProperties.IGNITE_JETTY_PORT; +import java.io.*; +import java.net.*; - import java.nio.charset.*; +import java.util.*; +import java.util.concurrent.*; +import java.util.regex.*; - import static org.apache.ignite.IgniteSystemProperties.*; - /** * Tests for Jetty REST protocol. */ @@@ -1344,28 -1262,28 +1541,50 @@@ public abstract class JettyRestProcesso /** * @throws Exception If failed. */ + public void testIncorrectFilterQueryScan() throws Exception { + Map<String, String> params = new HashMap<>(); + params.put("cmd", GridRestCommand.EXECUTE_SCAN_QUERY.key()); + params.put("pageSize", "10"); + params.put("cacheName", "person"); + params.put("className", ScanFilter.class.getName() + 1); + + String ret = content(params); + + assertNotNull(ret); + assertTrue(!ret.isEmpty()); + + JSONObject json = JSONObject.fromObject(ret); + + String err = (String)json.get("error"); + + assertTrue(err.contains("Failed to find target class")); + } + + /** + * @throws Exception If failed. + */ + public void testIncorrectQueryScan() throws Exception { + Map<String, String> params = new HashMap<>(); + params.put("cmd", GridRestCommand.EXECUTE_SCAN_QUERY.key()); + params.put("pageSize", "10"); + params.put("cacheName", "person"); + params.put("classname", ScanFilter.class.getName() + 1); + + String ret = content(params); + + assertNotNull(ret); + assertTrue(!ret.isEmpty()); + + JSONObject json = JSONObject.fromObject(ret); + + String err = (String)json.get("error"); + + assertTrue(err.contains("Failed to find target class")); + } + + /** + * @throws Exception If failed. + */ public void testQuery() throws Exception { grid(0).cache(null).put("1", "1"); grid(0).cache(null).put("2", "2"); @@@ -1519,183 -1437,44 +1738,220 @@@ assertFalse(queryCursorFound()); } + /** + * @throws Exception If failed. + */ + public void testQueryDelay() throws Exception { + String qry = "salary > ? and salary <= ?"; + + Map<String, String> params = new HashMap<>(); + params.put("cmd", GridRestCommand.EXECUTE_SQL_QUERY.key()); + params.put("type", "Person"); + params.put("pageSize", "1"); + params.put("cacheName", "person"); + params.put("qry", URLEncoder.encode(qry)); + params.put("arg1", "1000"); + params.put("arg2", "2000"); + + String ret = null; + + for (int i = 0; i < 10; ++i) + ret = content(params); + + assertNotNull(ret); + assertTrue(!ret.isEmpty()); + + JSONObject json = JSONObject.fromObject(ret); + + List items = (List)((Map)json.get("response")).get("items"); + + assertEquals(1, items.size()); + + assertTrue(queryCursorFound()); + + U.sleep(10000); + + assertFalse(queryCursorFound()); + } + + protected abstract String signature() throws Exception; + + /** + * @throws Exception If failed. + */ + public void testRunScriptPost() throws Exception { + String f = "function(param){return param;}"; + String ret = makePostRequest(F.asMap("cmd", GridRestCommand.RUN_SCRIPT.key(), "func", URLEncoder.encode(f)), "{\"arg\":\"hello\"}"); + + assertNotNull(ret); + assertTrue(!ret.isEmpty()); + + jsonEquals(ret, stringPattern("hello", true)); + } + + /** + * @throws Exception If failed. + */ + public void testRunScript() throws Exception { + String f = "function(param){return param;}"; + String ret = content(F.asMap("cmd", GridRestCommand.RUN_SCRIPT.key(), "func", + URLEncoder.encode(f), "arg", "hello")); + + assertNotNull(ret); + assertTrue(!ret.isEmpty()); + + jsonEquals(ret, stringPattern("hello", true)); + } + + /** + * @throws Exception If failed. + */ + public void testRunAffinityScriptPost() throws Exception { + ClusterNode node = grid(0).affinity(null).mapKeyToNode(new IgniteJsonString("key0")); + + Ignite ignite = null; + + for (int i = 0; i < GRID_CNT; ++i) { + if (grid(i).localNode().equals(node)) + ignite = grid(i); + } + + assertNotNull(ignite); + + String f = "function(expName){"+ + "if (expName !== \"hello\") {" + + "throw \"Not correct arg.\"" + + "}" + + "return ignite.name();}"; + + String ret = makePostRequest(F.asMap("cmd", GridRestCommand.AFFINITY_RUN_SCRIPT.key(), + "func", URLEncoder.encode(f)), + "{\"arg\":\"" + "hello" + "\",\"key\":\"key0\"}"); + + assertNotNull(ret); + assertTrue(!ret.isEmpty()); + + jsonEquals(ret, stringPattern(ignite.name(), true)); + } + + /** + * @throws Exception If failed. + */ + public void testRunAffinityScript() throws Exception { + ClusterNode node = grid(0).affinity(null).mapKeyToNode("key0"); + + Ignite ignite = null; + + for (int i = 0; i < GRID_CNT; ++i) { + if (grid(i).localNode().equals(node)) + ignite = grid(i); + } + + assertNotNull(ignite); + + String f = "function(expName){"+ + "if (expName !== \"hello\") {" + + "throw \"Not correct arg.\"" + + "}" + + "return ignite.name();}"; + + String ret = content(F.asMap("cmd", GridRestCommand.AFFINITY_RUN_SCRIPT.key(), + "func", URLEncoder.encode(f), "key", "key0", "arg", "hello")); + + assertNotNull(ret); + assertTrue(!ret.isEmpty()); + + jsonEquals(ret, stringPattern(ignite.name(), true)); + } + + /** + * @throws Exception If failed. + */ + public void testMapReduceScriptPost() throws Exception { + String map = "function(nodes, arg) {" + + "var words = arg.split(\" \");" + + "for (var i = 0; i < words.length; i++) {" + + "var f = function(word) {" + + "return word.length;" + + "};" + + "emit(f, words[i], nodes[i % nodes.length]);" + + "}"+ + "};"; + + String reduce = "function(results) {"+ + "var sum = 0;"+ + "for (var i = 0; i < results.size(); ++i) {"+ + "sum += results.get(i).intValue();"+ + "}" + + "return sum;" + + "};"; + + String ret = makePostRequest(F.asMap("cmd", GridRestCommand.EXECUTE_MAP_REDUCE_SCRIPT.key(), + "map", URLEncoder.encode(map), + "reduce", URLEncoder.encode(reduce)), "{\"arg\": \"Hello world!\"}"); + + assertNotNull(ret); + assertTrue(!ret.isEmpty()); + + jsonEquals(ret, integerPattern(11, true)); + } + + /** + * @throws Exception If failed. + */ + public void testMapReduceScript() throws Exception { + String map = "function(nodes, arg) {" + + "var words = arg.split(\" \");" + + "for (var i = 0; i < words.length; i++) {" + + "var f = function(word) {" + + "return word.length;" + + "};" + + "emit(f, words[i], nodes[i % nodes.length]);" + + "}"+ + "};"; + + String reduce = "function(results) {"+ + "var sum = 0;"+ + "for (var i = 0; i < results.size(); ++i) {"+ + "sum += results.get(i).intValue();"+ + "}" + + "return sum;" + + "};"; + + String ret = content(F.asMap("cmd", GridRestCommand.EXECUTE_MAP_REDUCE_SCRIPT.key(), + "map", URLEncoder.encode(map), + "reduce", URLEncoder.encode(reduce), + "arg", URLEncoder.encode("Hello world!"))); + + assertNotNull(ret); + assertTrue(!ret.isEmpty()); + + jsonEquals(ret, integerPattern(11, true)); + } + + /** + * @throws Exception If failed. + */ + public void testQueryArgsPost() throws Exception { + String qry = "salary > ? and salary <= ?"; + + String ret = makePostRequest(F.asMap("cmd", GridRestCommand.EXECUTE_SQL_QUERY.key(), + "type", "Person", "pageSize", "10", "cacheName", "person", + "qry", URLEncoder.encode(qry)), "{\"arg\": [1000, 2000]}"); + + assertNotNull(ret); + assertTrue(!ret.isEmpty()); + + JSONObject json = JSONObject.fromObject(ret); + + List items = (List)((Map)json.get("response")).get("items"); + + assertEquals(2, items.size()); + + assertFalse(queryCursorFound()); + } + /** * @return True if any query cursor is available. */ http://git-wip-us.apache.org/repos/asf/ignite/blob/ec3819f7/modules/core/src/main/java/org/apache/ignite/internal/GridKernalContext.java ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ignite/blob/ec3819f7/modules/core/src/main/java/org/apache/ignite/internal/GridKernalContextImpl.java ---------------------------------------------------------------------- diff --cc modules/core/src/main/java/org/apache/ignite/internal/GridKernalContextImpl.java index 36b263c,22fd96c..b2d5033 --- a/modules/core/src/main/java/org/apache/ignite/internal/GridKernalContextImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/GridKernalContextImpl.java @@@ -495,10 -510,8 +518,12 @@@ public class GridKernalContextImpl impl dataStructuresProc = (DataStructuresProcessor)comp; else if (comp instanceof ClusterProcessor) cluster = (ClusterProcessor)comp; + else if (comp instanceof PlatformProcessor) + platformProc = (PlatformProcessor)comp; + else if (comp instanceof IgniteScriptingProcessor) + scriptProc = (IgniteScriptingProcessor)comp; + else if (comp instanceof IgniteJsonProcessor) + json = (IgniteJsonProcessor)comp; else if (!(comp instanceof DiscoveryNodeValidationProcessor)) assert (comp instanceof GridPluginComponent) : "Unknown manager class: " + comp.getClass(); http://git-wip-us.apache.org/repos/asf/ignite/blob/ec3819f7/modules/core/src/main/java/org/apache/ignite/internal/IgniteComponentType.java ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ignite/blob/ec3819f7/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java ---------------------------------------------------------------------- diff --cc modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java index ab088b8,14b5816..987b4cb --- a/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java @@@ -791,7 -899,7 +900,8 @@@ public class IgniteKernal implements Ig IgniteComponentType.HADOOP.createIfInClassPath(ctx, cfg.getHadoopConfiguration() != null))); startProcessor(new GridServiceProcessor(ctx)); startProcessor(new DataStructuresProcessor(ctx)); + startProcessor(createComponent(PlatformProcessor.class, ctx)); + startProcessor((GridProcessor)IgniteComponentType.JSON.createIfInClassPath(ctx, false)); // Start plugins. for (PluginProvider provider : ctx.plugins().allProviders()) { http://git-wip-us.apache.org/repos/asf/ignite/blob/ec3819f7/modules/core/src/main/java/org/apache/ignite/internal/processors/cacheobject/IgniteCacheObjectProcessorImpl.java ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ignite/blob/ec3819f7/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java ---------------------------------------------------------------------- diff --cc modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java index 9384a03,4808e96..de65b1a --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java @@@ -131,34 -210,76 +213,83 @@@ public class GridQueryProcessor extend TypeDescriptor desc = new TypeDescriptor(); - Class<?> valCls = U.classForName(meta.getValueType(), null); + // Key and value classes still can be available if they are primitive or JDK part. + // We need that to set correct types for _key and _val columns. + Class<?> keyCls = U.classForName(qryEntity.getKeyType(), null); + Class<?> valCls = U.classForName(qryEntity.getValueType(), null); + + // If local node has the classes and they are externalizable, we must use reflection properties. + boolean keyMustDeserialize = mustDeserializeBinary(keyCls); + boolean valMustDeserialize = mustDeserializeBinary(valCls); + + boolean keyOrValMustDeserialize = keyMustDeserialize || valMustDeserialize; + + if (keyCls == null) + keyCls = Object.class; + + String simpleValType = valCls == null ? typeName(qryEntity.getValueType()) : typeName(valCls); - desc.name(valCls != null ? typeName(valCls) : meta.getValueType()); + desc.name(simpleValType); - desc.valueClass(valCls != null ? valCls : Object.class); - desc.keyClass( - meta.getKeyType() == null ? - Object.class : - U.classForName(meta.getKeyType(), Object.class)); + if (binaryEnabled && !keyOrValMustDeserialize) { + // Safe to check null. + if (SQL_TYPES.contains(valCls)) + desc.valueClass(valCls); + else + desc.valueClass(Object.class); + + if (SQL_TYPES.contains(keyCls)) + desc.keyClass(keyCls); + else + desc.keyClass(Object.class); + } + else { + if (keyCls == null) + throw new IgniteCheckedException("Failed to find key class in the node classpath " + + "(use default marshaller to enable binary objects): " + qryEntity.getKeyType()); + + if (valCls == null) + throw new IgniteCheckedException("Failed to find value class in the node classpath " + + "(use default marshaller to enable binary objects) : " + qryEntity.getValueType()); + + desc.valueClass(valCls); + desc.keyClass(keyCls); + } + + if (binaryEnabled && keyOrValMustDeserialize) { + if (mustDeserializeClss == null) + mustDeserializeClss = new ArrayList<>(); + + if (keyMustDeserialize) + mustDeserializeClss.add(keyCls); + + if (valMustDeserialize) + mustDeserializeClss.add(valCls); + } TypeId typeId; + TypeId altTypeId = null; - if (valCls == null || ctx.cacheObjects().isPortableEnabled()) { - processPortableMeta(meta, desc); + if (valCls == null || (binaryEnabled && !keyOrValMustDeserialize)) { + processBinaryMeta(qryEntity, desc); - typeId = new TypeId(ccfg.getName(), ctx.cacheObjects().typeId(meta.getValueType())); + typeId = new TypeId(ccfg.getName(), ctx.cacheObjects().typeId(qryEntity.getValueType())); + + if (valCls != null) + altTypeId = new TypeId(ccfg.getName(), valCls); } + else if (ctx.json().jsonType(desc.keyClass()) || ctx.json().jsonType(desc.valueClass())) { + processJsonMeta(meta, desc); + + typeId = new TypeId(ccfg.getName(), valCls); + + jsonTypeId = typeId; + } else { - processClassMeta(meta, desc); + processClassMeta(qryEntity, desc, coCtx); typeId = new TypeId(ccfg.getName(), valCls); + altTypeId = new TypeId(ccfg.getName(), ctx.cacheObjects().typeId(qryEntity.getValueType())); } addTypeByName(ccfg, desc); @@@ -465,48 -657,39 +667,48 @@@ if (coctx == null) coctx = cacheObjectContext(space); - Class<?> valCls = null; - - TypeId id; - - boolean binaryVal = ctx.cacheObjects().isBinaryObject(val); + TypeDescriptor desc; - if (binaryVal) { - int typeId = ctx.cacheObjects().typeId(val); + if (ctx.json().jsonObject(val) && jsonTypeId != null) { + desc = types.get(jsonTypeId); - id = new TypeId(space, typeId); + assert desc != null && desc.registered() : desc; } else { - valCls = val.value(coctx, false).getClass(); + Class<?> valCls = null; - id = new TypeId(space, valCls); - } + TypeId id; - boolean portableVal = ctx.cacheObjects().isPortableObject(val); - TypeDescriptor desc = types.get(id); ++ boolean binaryVal = ctx.cacheObjects().isBinaryObject(val); - if (portableVal) { - if (desc == null || !desc.registered()) - return; ++ if (binaryVal) { + int typeId = ctx.cacheObjects().typeId(val); - if (!binaryVal && !desc.valueClass().isAssignableFrom(valCls)) - throw new IgniteCheckedException("Failed to update index due to class name conflict" + - "(multiple classes with same simple name are stored in the same cache) " + - "[expCls=" + desc.valueClass().getName() + ", actualCls=" + valCls.getName() + ']'); + id = new TypeId(space, typeId); + } - else { ++ else { + valCls = val.value(coctx, false).getClass(); + + id = new TypeId(space, valCls); + } + + desc = types.get(id); - if (!ctx.cacheObjects().isBinaryObject(key)) { - Class<?> keyCls = key.value(coctx, false).getClass(); + if (desc == null || !desc.registered()) + return; - if (!portableVal && !desc.valueClass().isAssignableFrom(valCls)) - if (!desc.keyClass().isAssignableFrom(keyCls)) - throw new IgniteCheckedException("Failed to update index, incorrect key class [expCls=" + - desc.keyClass().getName() + ", actualCls=" + keyCls.getName() + "]"); ++ if (!binaryVal && !desc.valueClass().isAssignableFrom(valCls)) + throw new IgniteCheckedException("Failed to update index due to class name conflict" + + "(multiple classes with same simple name are stored in the same cache) " + + "[expCls=" + desc.valueClass().getName() + ", actualCls=" + valCls.getName() + ']'); + - if (!ctx.cacheObjects().isPortableObject(key)) { ++ if (!ctx.cacheObjects().isBinaryObject(key)) { + Class<?> keyCls = key.value(coctx, false).getClass(); + + if (!desc.keyClass().isAssignableFrom(keyCls)) + throw new IgniteCheckedException("Failed to update index, incorrect key class [expCls=" + + desc.keyClass().getName() + ", actualCls=" + keyCls.getName() + "]"); + } } idx.store(space, desc, key, val, ver, expirationTime); @@@ -1255,101 -1470,9 +1489,101 @@@ } /** - * Processes declarative metadata for binary object. + * Processes declarative metadata for json object. + * + * @param meta Declared metadata. + * @param d Type descriptor. + * @throws IgniteCheckedException If failed. + */ + private void processJsonMeta(CacheTypeMetadata meta, TypeDescriptor d) + throws IgniteCheckedException { + for (Map.Entry<String, Class<?>> entry : meta.getAscendingFields().entrySet()) { + JsonProperty prop = buildJsonProperty(entry.getKey(), entry.getValue()); + + d.addProperty(prop, false); + + String idxName = prop.name() + "_idx"; + + d.addIndex(idxName, idx.isGeometryClass(prop.type()) ? GEO_SPATIAL : SORTED); + + d.addFieldToIndex(idxName, prop.name(), 0, false); + } + + for (Map.Entry<String, Class<?>> entry : meta.getDescendingFields().entrySet()) { + JsonProperty prop = buildJsonProperty(entry.getKey(), entry.getValue()); + + d.addProperty(prop, false); + + String idxName = prop.name() + "_idx"; + + d.addIndex(idxName, idx.isGeometryClass(prop.type()) ? GEO_SPATIAL : SORTED); + + d.addFieldToIndex(idxName, prop.name(), 0, true); + } + + for (String txtIdx : meta.getTextFields()) { + JsonProperty prop = buildJsonProperty(txtIdx, String.class); + + d.addProperty(prop, false); + + d.addFieldToTextIndex(prop.name()); + } + + Map<String, LinkedHashMap<String, IgniteBiTuple<Class<?>, Boolean>>> grps = meta.getGroups(); + + if (grps != null) { + for (Map.Entry<String, LinkedHashMap<String, IgniteBiTuple<Class<?>, Boolean>>> entry : grps.entrySet()) { + String idxName = entry.getKey(); + + LinkedHashMap<String, IgniteBiTuple<Class<?>, Boolean>> idxFields = entry.getValue(); + + int order = 0; + + for (Map.Entry<String, IgniteBiTuple<Class<?>, Boolean>> idxField : idxFields.entrySet()) { + JsonProperty prop = buildJsonProperty(idxField.getKey(), idxField.getValue().get1()); + + d.addProperty(prop, false); + + Boolean descending = idxField.getValue().get2(); + + d.addFieldToIndex(idxName, prop.name(), order, descending != null && descending); + + order++; + } + } + } + + for (Map.Entry<String, Class<?>> entry : meta.getQueryFields().entrySet()) { + JsonProperty prop = buildJsonProperty(entry.getKey(), entry.getValue()); + + if (!d.props.containsKey(prop.name())) + d.addProperty(prop, false); + } + } + + /** + * Builds portable object property. + * + * @param pathStr String representing path to the property. May contains dots '.' to identify + * nested fields. + * @param resType Result type. + * @return Portable property. + */ + private JsonProperty buildJsonProperty(String pathStr, Class<?> resType) { + String[] path = pathStr.split("\\."); + + JsonProperty res = null; + + for (String prop : path) + res = new JsonProperty(prop, res, resType); + + return res; + } + + /** + * Processes declarative metadata for portable object. * - * @param meta Declared metadata. + * @param qryEntity Declared metadata. * @param d Type descriptor. * @throws IgniteCheckedException If failed. */ @@@ -1737,85 -1921,7 +2032,85 @@@ /** * */ + private class JsonProperty extends Property { + /** Property name. */ + private String propName; + + /** Parent property. */ + private JsonProperty parent; + + /** Result class. */ + private Class<?> type; + + /** */ + private volatile int isKeyProp; + + /** + * Constructor. + * + * @param propName Property name. + * @param parent Parent property. + * @param type Result type. + */ + private JsonProperty(String propName, JsonProperty parent, Class<?> type) { + this.propName = propName; + this.parent = parent; + this.type = type; + } + + /** {@inheritDoc} */ + @Override public Object value(Object key, Object val) throws IgniteCheckedException { + Object obj; + + if (parent != null) { + obj = parent.value(key, val); + + if (obj == null) + return null; + + if (!ctx.json().jsonObject(obj)) + throw new IgniteCheckedException("Non-json object received as a result of property extraction " + + "[parent=" + parent + ", propName=" + propName + ", obj=" + obj + ']'); + } + else { + int isKeyProp0 = isKeyProp; + + if (isKeyProp0 == 0) { + // Key is allowed to be a non-portable object here. + // We check key before value consistently with ClassProperty. + if (ctx.json().jsonObject(key) && ctx.json().hasField(key, propName)) + isKeyProp = isKeyProp0 = 1; + else if (ctx.json().hasField(val, propName)) + isKeyProp = isKeyProp0 = -1; + else { + U.warn(log, "Neither key nor value have property " + + "[propName=" + propName + ", key=" + key + ", val=" + val + "]"); + + return null; + } + } + + obj = isKeyProp0 == 1 ? key : val; + } + + return ctx.json().field(obj, propName); + } + + /** {@inheritDoc} */ + @Override public String name() { + return propName; + } + + /** {@inheritDoc} */ + @Override public Class<?> type() { + return type; + } + } + + /** + * + */ - private class PortableProperty extends Property { + private class BinaryProperty extends GridQueryProperty { /** Property name. */ private String propName; http://git-wip-us.apache.org/repos/asf/ignite/blob/ec3819f7/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/GridRestCommand.java ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ignite/blob/ec3819f7/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/GridRestProcessor.java ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ignite/blob/ec3819f7/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/version/GridVersionNameCommandHandler.java ---------------------------------------------------------------------- diff --cc modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/version/GridVersionNameCommandHandler.java index c22b838,0000000..6c87259 mode 100644,000000..100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/version/GridVersionNameCommandHandler.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/version/GridVersionNameCommandHandler.java @@@ -1,67 -1,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.processors.rest.handlers.version; + - import org.apache.ignite.internal.*; - import org.apache.ignite.internal.processors.rest.*; - import org.apache.ignite.internal.processors.rest.handlers.*; - import org.apache.ignite.internal.processors.rest.request.*; - import org.apache.ignite.internal.util.future.*; - import org.apache.ignite.internal.util.typedef.internal.*; ++import java.util.Collection; ++import org.apache.ignite.internal.GridKernalContext; ++import org.apache.ignite.internal.IgniteInternalFuture; ++import org.apache.ignite.internal.processors.rest.GridRestCommand; ++import org.apache.ignite.internal.processors.rest.GridRestResponse; ++import org.apache.ignite.internal.processors.rest.handlers.GridRestCommandHandlerAdapter; ++import org.apache.ignite.internal.processors.rest.request.GridRestRequest; ++import org.apache.ignite.internal.util.future.GridFinishedFuture; ++import org.apache.ignite.internal.util.typedef.internal.U; + - import java.util.*; - - import static org.apache.ignite.internal.IgniteVersionUtils.*; - import static org.apache.ignite.internal.processors.rest.GridRestCommand.*; ++import static org.apache.ignite.internal.IgniteVersionUtils.VER_STR; ++import static org.apache.ignite.internal.processors.rest.GridRestCommand.NAME; ++import static org.apache.ignite.internal.processors.rest.GridRestCommand.VERSION; + +/** + * Handler for {@link GridRestCommand#VERSION} and {@link GridRestCommand#NAME} command. + */ +public class GridVersionNameCommandHandler extends GridRestCommandHandlerAdapter { + /** Supported commands. */ + private static final Collection<GridRestCommand> SUPPORTED_COMMANDS = U.sealList(VERSION, NAME); + + /** + * @param ctx Context. + */ + public GridVersionNameCommandHandler(GridKernalContext ctx) { + super(ctx); + } + + /** {@inheritDoc} */ + @Override public Collection<GridRestCommand> supportedCommands() { + return SUPPORTED_COMMANDS; + } + + /** {@inheritDoc} */ + @Override public IgniteInternalFuture<GridRestResponse> handleAsync(GridRestRequest req) { + assert req != null; + + assert SUPPORTED_COMMANDS.contains(req.command()); + + switch (req.command()){ + case VERSION: + return new GridFinishedFuture<>(new GridRestResponse(VER_STR)); + + case NAME: + return new GridFinishedFuture<>(new GridRestResponse(ctx.gridName())); + } + + return new GridFinishedFuture<>(); + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/ec3819f7/modules/core/src/main/java/org/apache/ignite/internal/util/GridJavaProcess.java ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ignite/blob/ec3819f7/modules/rest-http/pom.xml ---------------------------------------------------------------------- diff --cc modules/rest-http/pom.xml index 1af413b,4523d3b..84372a9 --- a/modules/rest-http/pom.xml +++ b/modules/rest-http/pom.xml @@@ -47,15 -49,9 +55,15 @@@ </dependency> <dependency> + <groupId>org.apache.ignite</groupId> + <artifactId>ignite-json</artifactId> + <version>${project.version}</version> + </dependency> + + <dependency> <groupId>org.apache.tomcat</groupId> <artifactId>tomcat-servlet-api</artifactId> - <version>8.0.23</version> + <version>${tomcat.version}</version> </dependency> <dependency> http://git-wip-us.apache.org/repos/asf/ignite/blob/ec3819f7/modules/rest-http/src/main/java/org/apache/ignite/internal/processors/rest/protocols/http/jetty/GridJettyRestHandler.java ---------------------------------------------------------------------- diff --cc modules/rest-http/src/main/java/org/apache/ignite/internal/processors/rest/protocols/http/jetty/GridJettyRestHandler.java index 17467ca,5f2c4ba..95a385a --- a/modules/rest-http/src/main/java/org/apache/ignite/internal/processors/rest/protocols/http/jetty/GridJettyRestHandler.java +++ b/modules/rest-http/src/main/java/org/apache/ignite/internal/processors/rest/protocols/http/jetty/GridJettyRestHandler.java @@@ -17,31 -17,55 +17,56 @@@ package org.apache.ignite.internal.processors.rest.protocols.http.jetty; - import net.sf.json.*; - import net.sf.json.processors.*; - import org.apache.ignite.*; - import org.apache.ignite.internal.*; - import org.apache.ignite.internal.processors.rest.*; - import org.apache.ignite.internal.processors.rest.client.message.*; - import org.apache.ignite.internal.processors.rest.request.*; - import org.apache.ignite.internal.processors.rest.request.RestQueryRequest.*; - import org.apache.ignite.internal.util.typedef.*; - import org.apache.ignite.internal.util.typedef.internal.*; - import org.apache.ignite.lang.*; - import org.apache.ignite.plugin.security.*; - import org.eclipse.jetty.server.*; - import org.eclipse.jetty.server.handler.*; - import org.glassfish.json.*; - import org.jetbrains.annotations.*; - - import javax.servlet.*; - import javax.servlet.http.*; - import java.io.*; - import java.net.*; - import java.util.*; - - import static org.apache.ignite.internal.processors.rest.GridRestCommand.*; - import static org.apache.ignite.internal.processors.rest.GridRestResponse.*; + import java.io.BufferedInputStream; + import java.io.ByteArrayOutputStream; + import java.io.IOException; + import java.io.InputStream; + import java.io.InputStreamReader; + import java.io.LineNumberReader; + import java.net.InetSocketAddress; + import java.util.Collections; + import java.util.Iterator; + import java.util.LinkedList; + import java.util.List; + import java.util.Map; + import java.util.UUID; + import javax.servlet.ServletException; + import javax.servlet.ServletRequest; + import javax.servlet.http.HttpServletRequest; + import javax.servlet.http.HttpServletResponse; + import net.sf.json.JSON; + import net.sf.json.JSONException; + import net.sf.json.JSONSerializer; + import net.sf.json.JsonConfig; + import net.sf.json.processors.JsonValueProcessor; + import org.apache.ignite.IgniteCheckedException; + import org.apache.ignite.IgniteLogger; ++import org.apache.ignite.internal.GridKernalContext; + import org.apache.ignite.internal.processors.rest.GridRestCommand; + import org.apache.ignite.internal.processors.rest.GridRestProtocolHandler; + import org.apache.ignite.internal.processors.rest.GridRestResponse; + import org.apache.ignite.internal.processors.rest.client.message.GridClientTaskResultBean; + import org.apache.ignite.internal.processors.rest.request.DataStructuresRequest; + import org.apache.ignite.internal.processors.rest.request.GridRestCacheRequest; + import org.apache.ignite.internal.processors.rest.request.GridRestLogRequest; + import org.apache.ignite.internal.processors.rest.request.GridRestRequest; + import org.apache.ignite.internal.processors.rest.request.GridRestTaskRequest; + import org.apache.ignite.internal.processors.rest.request.GridRestTopologyRequest; + import org.apache.ignite.internal.processors.rest.request.RestQueryRequest; + import org.apache.ignite.internal.util.typedef.F; + import org.apache.ignite.internal.util.typedef.internal.U; + import org.apache.ignite.lang.IgniteClosure; + import org.apache.ignite.plugin.security.SecurityCredentials; + import org.eclipse.jetty.server.Request; + import org.eclipse.jetty.server.handler.AbstractHandler; + import org.jetbrains.annotations.Nullable; + + import static org.apache.ignite.internal.processors.rest.GridRestCommand.CACHE_CONTAINS_KEYS; + import static org.apache.ignite.internal.processors.rest.GridRestCommand.CACHE_GET_ALL; + import static org.apache.ignite.internal.processors.rest.GridRestCommand.CACHE_PUT_ALL; + import static org.apache.ignite.internal.processors.rest.GridRestCommand.CACHE_REMOVE_ALL; + import static org.apache.ignite.internal.processors.rest.GridRestCommand.EXECUTE_SQL_QUERY; + import static org.apache.ignite.internal.processors.rest.GridRestResponse.STATUS_FAILED; /** * Jetty REST handler. The following URL format is supported: @@@ -61,22 -85,15 +86,22 @@@ public class GridJettyRestHandler exten /** Logger. */ private final IgniteLogger log; + + /** Authentication checker. */ + private final IgniteClosure<String, Boolean> authChecker; ++ /** Request handlers. */ private GridRestProtocolHandler hnd; + /** Default page. */ private volatile String dfltPage; + /** Favicon. */ private volatile byte[] favicon; - /** Authentication checker. */ - private final IgniteClosure<String, Boolean> authChecker; - + /** Grid context. */ + GridKernalContext ctx; + /** * Creates new HTTP requests handler. * @@@ -642,15 -565,9 +736,15 @@@ case EXECUTE_SQL_FIELDS_QUERY: { RestQueryRequest restReq0 = new RestQueryRequest(); - restReq0.sqlQuery((String) params.get("qry")); + restReq0.sqlQuery((String)params.get("qry")); - restReq0.arguments(values("arg", params).toArray()); + if (req.getHeader("Content-Type") != null && req.getHeader("Content-Type").contains("json")) { + Map o = parseRequest(req); + List args = (List) ctx.scripting().toScriptObject(o.get("arg")); + restReq0.arguments(args.toArray()); + } + else + restReq0.arguments(values("arg", params).toArray()); restReq0.typeName((String) params.get("type")); http://git-wip-us.apache.org/repos/asf/ignite/blob/ec3819f7/modules/rest-http/src/main/java/org/apache/ignite/internal/processors/rest/protocols/http/jetty/GridJettyRestProtocol.java ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ignite/blob/ec3819f7/parent/pom.xml ---------------------------------------------------------------------- diff --cc parent/pom.xml index 2c9ad8b,b7b417b..1a6d0d0 --- a/parent/pom.xml +++ b/parent/pom.xml @@@ -704,7 -847,10 +847,11 @@@ <exclude>dev-tools/.gradle/**/*</exclude> <exclude>dev-tools/gradle/wrapper/**/*</exclude> <exclude>dev-tools/gradlew</exclude> + <exclude>src/main/js/package.json</exclude> + <exclude>src/test/binaries/repo/org/apache/ignite/binary/test2/1.1/test2-1.1.pom</exclude> + <exclude>src/test/binaries/repo/org/apache/ignite/binary/test2/maven-metadata-local.xml</exclude> + <exclude>src/test/binaries/repo/org/apache/ignite/binary/test1/1.1/test1-1.1.pom</exclude> + <exclude>src/test/binaries/repo/org/apache/ignite/binary/test1/maven-metadata-local.xml</exclude> <!--shmem--> <exclude>ipc/shmem/**/Makefile.in</exclude><!--auto generated files--> <exclude>ipc/shmem/**/Makefile</exclude><!--auto generated files--> http://git-wip-us.apache.org/repos/asf/ignite/blob/ec3819f7/pom.xml ---------------------------------------------------------------------- diff --cc pom.xml index 0b9ac0a,3457c30..325985b --- a/pom.xml +++ b/pom.xml @@@ -72,10 -72,17 +72,19 @@@ <module>modules/gce</module> <module>modules/cloud</module> <module>modules/mesos</module> + <module>modules/nodejs</module> <module>modules/kafka</module> + <module>modules/flume</module> <module>modules/yarn</module> + <module>modules/jms11</module> + <module>modules/twitter</module> + <module>modules/mqtt</module> + <module>modules/zookeeper</module> + <module>modules/camel</module> + <module>modules/osgi-paxlogging</module> + <module>modules/osgi-karaf</module> + <module>modules/osgi</module> + <module>modules/json</module> </modules> <profiles> @@@ -738,31 -761,138 +763,165 @@@ </profile> <profile> + <id>ignite-npm</id> + <build> + <plugins> + <plugin> + <groupId>org.codehaus.mojo</groupId> + <artifactId>exec-maven-plugin</artifactId> + <executions> + <execution> + <phase>compile</phase> + <goals> + <goal>exec</goal> + </goals> + </execution> + </executions> + <configuration> + <executable>npm</executable> + <arguments> + <argument>publish</argument> + <argument>modules/nodejs/src/main/js</argument> + </arguments> + </configuration> + </plugin> + </plugins> + </build> + </profile> ++ ++ <profile> + <id>update-versions</id> + <!-- updates dotnet & cpp versions --> + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-antrun-plugin</artifactId> + <version>1.7</version> + <executions> + <execution> + <id>update-versions</id> + <goals> + <goal>run</goal> + </goals> + <phase>validate</phase> + <configuration> + <target> + <script language="javascript"> + function setClientVersion(ggVer, clientVer) { + var p = project.getProperty(ggVer); + + var digitVer = /\d+\.\d+\.\d+/.exec(p); + + if (digitVer != null) + { + // Date of the last major release + var startDate = new Date(2015,1,1); + + // Number of hours since the last major release + var buildNum = Math.round((new Date() - startDate)/(3600*1000)); + var ver = digitVer[0] + "." + buildNum; + + project.setProperty(clientVer, ver); + } + else + project.setProperty(clientVer, p); + } + + function fix(dest, source) { + project.setProperty(dest, project.getProperty(source).replace("-SNAPSHOT", + "")); + } + + fix('ignite.version.fixed', 'project.version'); + fix('new.ignite.version.fixed', 'new.ignite.version'); + setClientVersion('ignite.version.fixed', 'old.client.version'); + setClientVersion('new.ignite.version.fixed', 'new.client.version'); + </script> + + <echo message="Update ignite.version in dotnet client" /> + <echo message="${new.client.version}" /> + + <replaceregexp byline="true" encoding="UTF-8"> + <regexp pattern="(\[assembly:\s*Assembly\w*Version\w*\(")\d+\.\d+\.\d+(\.\d+)?("\)\])" /> + <substitution expression="\1${new.client.version}\3" /> + <fileset dir="${basedir}/"> + <include name="**/AssemblyInfo.cs" /> + <include name="**/AssemblyInfo.cpp" /> + </fileset> + </replaceregexp> + + <replaceregexp byline="true" encoding="UTF-8"> + <regexp pattern="(\[assembly:\s*AssemblyInformationalVersion\w*\(").*?("\)\])" /> + <substitution expression="\1${new.ignite.version.fixed}\2" /> + <fileset dir="${basedir}/"> + <include name="**/AssemblyInfo.cs" /> + <include name="**/AssemblyInfo.cpp" /> + </fileset> + </replaceregexp> + + <echo message="Update ignite.version in cpp client" /> + <replaceregexp byline="true" encoding="UTF-8"> + <regexp pattern="(AC_INIT.+\[)\d+\.\d+\.\d+.*?(\].+)" /> + <substitution expression="\1${new.client.version}\2" /> + <fileset dir="${basedir}/"> + <include name="**/configure.ac" /> + </fileset> + </replaceregexp> + + <replaceregexp byline="true" encoding="UTF-8"> + <regexp pattern="(define GG_VERSION_STR_WIN ")\d+\.\d+\.\d+(\.\d+)?(")" /> + <substitution expression="\1${new.client.version}\3" /> + <fileset dir="${basedir}/"> + <include name="**/resource.h" /> + </fileset> + </replaceregexp> + + <replaceregexp byline="true" encoding="UTF-16"> + <regexp pattern="(Version", ")\d+\.\d+\.\d+\.\d+(")" /> + <substitution expression="\1${new.client.version}\2" /> + <fileset dir="${basedir}/"> + <include name="**/Resource.rc" /> + </fileset> + </replaceregexp> + + <script language="javascript"> + function setBinVersion(clientVer, binVer) { + var p = project.getProperty(clientVer).replace(".", ","); + + if (p.split(',').length == 3) + project.setProperty(binVer, p + ',0'); + else + project.setProperty(binVer, p); + } + + setBinVersion('old.client.version', 'old.bin.version'); + setBinVersion('new.client.version', 'new.bin.version'); + </script> + + <replaceregexp byline="true" encoding="UTF-8"> + <regexp pattern="(define GG_VERSION_BIN_WIN )\d,\d,\d,\d" /> + <substitution expression="\1${new.bin.version}" /> + <fileset dir="${basedir}/"> + <include name="**/resource.h" /> + </fileset> + </replaceregexp> + + <replaceregexp byline="true" encoding="UTF-16"> + <regexp pattern="(VERSION )\d,\d,\d,\d" /> + <substitution expression="\1${new.bin.version}" /> + <fileset dir="${basedir}/"> + <include name="**/Resource.rc" /> + </fileset> + </replaceregexp> + </target> + </configuration> + </execution> + </executions> + </plugin> + </plugins> + </build> + </profile> </profiles> <build>