Repository: ignite Updated Branches: refs/heads/ignite-843-rc2 f6629cab8 -> d603a53a8
http://git-wip-us.apache.org/repos/asf/ignite/blob/54a24746/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/remote/RemoteHandler.java ---------------------------------------------------------------------- diff --git a/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/remote/RemoteHandler.java b/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/remote/RemoteHandler.java new file mode 100644 index 0000000..4eda313 --- /dev/null +++ b/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/remote/RemoteHandler.java @@ -0,0 +1,252 @@ +/* + * 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.console.agent.remote; + +import com.google.gson.Gson; +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonNull; +import com.google.gson.JsonObject; +import com.google.gson.JsonPrimitive; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Type; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import org.apache.http.auth.AuthenticationException; +import org.apache.log4j.Logger; + +/** + * Allow to execute methods remotely from NodeJS server by web-socket command. + */ +public class RemoteHandler implements AutoCloseable { + /** */ + public static final Gson GSON = new Gson(); + + /** */ + public static final Object[] EMPTY_OBJECTS = new Object[0]; + + /** */ + private static final Logger log = Logger.getLogger(RemoteHandler.class.getName()); + + /** */ + private static final String INTERNAL_EXCEPTION_TYPE = "org.apache.ignite.agent.AgentException"; + + /** */ + private final WebSocketSender snd; + + /** */ + private final Map<String, MethodDescriptor> mtds = new HashMap<>(); + + /** */ + private final ExecutorService executorSrvc = Executors.newFixedThreadPool(Runtime.getRuntime() + .availableProcessors()); + + /** + * @param snd Session. + * @param hnds Handlers. + */ + private RemoteHandler(WebSocketSender snd, Object ... hnds) { + this.snd = snd; + + for (Object hnd : hnds) { + for (Method method : hnd.getClass().getMethods()) { + Remote remoteAnn = method.getAnnotation(Remote.class); + + if (remoteAnn != null) { + MethodDescriptor old = mtds.put(method.getName(), new MethodDescriptor(method, hnd, + remoteAnn.async())); + + if (old != null) + throw new IllegalArgumentException("Duplicated method: " + method.getName()); + } + } + } + } + + /** + * @param hnds Handler. + * @param snd Sender. + */ + public static RemoteHandler wrap(WebSocketSender snd, Object ... hnds) { + return new RemoteHandler(snd, hnds); + } + + /** + * @param req Request. + */ + public void onMessage(JsonObject req) { + JsonPrimitive reqIdJson = req.getAsJsonPrimitive("reqId"); + + final Long reqId = reqIdJson == null ? null : reqIdJson.getAsLong(); + + String mtdName = req.getAsJsonPrimitive("mtdName").getAsString(); + + final MethodDescriptor desc = mtds.get(mtdName); + + if (desc == null) { + sendException(reqId, INTERNAL_EXCEPTION_TYPE, "Unknown method: " + mtdName); + + return; + } + + Type[] paramTypes = desc.mtd.getGenericParameterTypes(); + + JsonArray argsJson = req.getAsJsonArray("args"); + + final Object[] args; + + if (paramTypes.length > 0) { + args = new Object[paramTypes.length]; + + if (argsJson == null || argsJson.size() != paramTypes.length) { + sendException(reqId, INTERNAL_EXCEPTION_TYPE, "Inconsistent parameters"); + + return; + } + + for (int i = 0; i < paramTypes.length; i++) + args[i] = GSON.fromJson(argsJson.get(i), paramTypes[i]); + } + else { + args = EMPTY_OBJECTS; + + if (argsJson != null && argsJson.size() > 0) { + sendException(reqId, INTERNAL_EXCEPTION_TYPE, "Inconsistent parameters"); + + return; + } + } + + Runnable run = new Runnable() { + @Override public void run() { + final Object res; + + try { + res = desc.mtd.invoke(desc.hnd, args); + } + catch (Throwable e) { + if (e instanceof AuthenticationException) { + close(); + + return; + } + + if (e instanceof InvocationTargetException) + e = ((InvocationTargetException)e).getTargetException(); + + if (reqId != null) + sendException(reqId, e.getClass().getName(), e.getMessage()); + else + log.error("Exception on execute remote method.", e); + + return; + } + + sendResponse(reqId, res, desc.returnType); + } + }; + + if (desc.async) + executorSrvc.submit(run); + else + run.run(); + } + + /** + * @param reqId Request id. + * @param exType Exception class name. + * @param exMsg Exception message. + */ + protected void sendException(Long reqId, String exType, String exMsg) { + if (reqId == null) + return; + + JsonObject res = new JsonObject(); + + res.addProperty("type", "CallRes"); + res.addProperty("reqId", reqId); + + JsonObject exJson = new JsonObject(); + exJson.addProperty("type", exType); + exJson.addProperty("message", exMsg); + + res.add("ex", exJson); + + snd.send(res); + } + + /** + * @param reqId Request id. + * @param res Result. + * @param type Type. + */ + private void sendResponse(Long reqId, Object res, Type type) { + if (reqId == null) + return; + + JsonObject resp = new JsonObject(); + + resp.addProperty("type", "CallRes"); + + resp.addProperty("reqId", reqId); + + JsonElement resJson = type == void.class ? JsonNull.INSTANCE : GSON.toJsonTree(res, type); + + resp.add("res", resJson); + + snd.send(resp); + } + + /** {@inheritDoc} */ + @Override public void close() { + executorSrvc.shutdown(); + } + + /** + * + */ + private static class MethodDescriptor { + /** */ + private final Method mtd; + + /** */ + private final Object hnd; + + /** */ + private final Type returnType; + + /** */ + private final boolean async; + + /** + * @param mtd Method. + * @param hnd Handler. + * @param async Async. + */ + MethodDescriptor(Method mtd, Object hnd, boolean async) { + this.mtd = mtd; + this.hnd = hnd; + this.async = async; + + returnType = mtd.getGenericReturnType(); + } + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/54a24746/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/remote/WebSocketSender.java ---------------------------------------------------------------------- diff --git a/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/remote/WebSocketSender.java b/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/remote/WebSocketSender.java new file mode 100644 index 0000000..cceb86b --- /dev/null +++ b/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/remote/WebSocketSender.java @@ -0,0 +1,39 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.ignite.console.agent.remote; + +import com.google.gson.JsonObject; + +/** + * Sender for messages to web-socket. + */ +public interface WebSocketSender { + /** + * Send message. + * @param msg Message. + * @return {@code true} if message sent successfully. + */ + public boolean send(String msg); + + /** + * Send message. + * @param msg Message. + * @return {@code true} if message sent successfully. + */ + public boolean send(JsonObject msg); +} http://git-wip-us.apache.org/repos/asf/ignite/blob/54a24746/modules/control-center-agent/src/main/java/org/apache/ignite/console/demo/AgentMetadataDemo.java ---------------------------------------------------------------------- diff --git a/modules/control-center-agent/src/main/java/org/apache/ignite/console/demo/AgentMetadataDemo.java b/modules/control-center-agent/src/main/java/org/apache/ignite/console/demo/AgentMetadataDemo.java new file mode 100644 index 0000000..5d33f29 --- /dev/null +++ b/modules/control-center-agent/src/main/java/org/apache/ignite/console/demo/AgentMetadataDemo.java @@ -0,0 +1,88 @@ +/* + * 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.console.demo; + +import java.io.File; +import java.io.FileReader; +import java.sql.Connection; +import java.sql.DriverManager; +import java.util.concurrent.atomic.AtomicBoolean; + +import org.apache.log4j.Logger; +import org.h2.tools.RunScript; +import org.h2.tools.Server; + +import static org.apache.ignite.console.agent.AgentUtils.resolvePath; + +/** + * Demo for metadata load from database. + * + * H2 database will be started and several tables will be created. + */ +public class AgentMetadataDemo { + /** */ + private static final Logger log = Logger.getLogger(AgentMetadataDemo.class.getName()); + + /** */ + private static final AtomicBoolean initLatch = new AtomicBoolean(); + + /** + * @param jdbcUrl Connection url. + * @return true if url is used for test-drive. + */ + public static boolean isTestDriveUrl(String jdbcUrl) { + return "jdbc:h2:mem:demo-db".equals(jdbcUrl); + } + + /** + * Start H2 database and populate it with several tables. + */ + public static void testDrive() { + if (initLatch.compareAndSet(false, true)) { + log.info("DEMO: Prepare in-memory H2 database..."); + + try { + Connection conn = DriverManager.getConnection("jdbc:h2:mem:demo-db;DB_CLOSE_DELAY=-1", "sa", ""); + + File sqlScript = resolvePath("demo/db-init.sql"); + + if (sqlScript == null) { + log.error("DEMO: Failed to find demo database init script file: demo/db-init.sql"); + log.error("DEMO: Failed to start demo for metadata"); + + return; + } + + RunScript.execute(conn, new FileReader(sqlScript)); + + log.info("DEMO: Sample tables created."); + + conn.close(); + + Server.createTcpServer("-tcpDaemon").start(); + + log.info("DEMO: TcpServer stared."); + + log.info("DEMO: JDBC URL for test drive metadata load: jdbc:h2:mem:demo-db"); + } + catch (Exception e) { + log.error("DEMO: Failed to start test drive for metadata!", e); + } + } + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/54a24746/modules/control-center-agent/src/main/java/org/apache/ignite/console/demo/AgentSqlDemo.java ---------------------------------------------------------------------- diff --git a/modules/control-center-agent/src/main/java/org/apache/ignite/console/demo/AgentSqlDemo.java b/modules/control-center-agent/src/main/java/org/apache/ignite/console/demo/AgentSqlDemo.java new file mode 100644 index 0000000..1e63232 --- /dev/null +++ b/modules/control-center-agent/src/main/java/org/apache/ignite/console/demo/AgentSqlDemo.java @@ -0,0 +1,551 @@ +/* + * 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.console.demo; + +import java.net.InetSocketAddress; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.Random; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ScheduledThreadPoolExecutor; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicInteger; +import org.apache.ignite.Ignite; +import org.apache.ignite.IgniteCache; +import org.apache.ignite.Ignition; +import org.apache.ignite.console.agent.AgentConfiguration; +import org.apache.ignite.console.demo.model.Car; +import org.apache.ignite.console.demo.model.Country; +import org.apache.ignite.console.demo.model.Department; +import org.apache.ignite.console.demo.model.Employee; +import org.apache.ignite.console.demo.model.Parking; +import org.apache.ignite.cache.QueryEntity; +import org.apache.ignite.cache.QueryIndex; +import org.apache.ignite.cache.QueryIndexType; +import org.apache.ignite.configuration.CacheConfiguration; +import org.apache.ignite.configuration.IgniteConfiguration; +import org.apache.ignite.internal.IgniteEx; +import org.apache.ignite.internal.util.typedef.F; +import org.apache.ignite.logger.NullLogger; +import org.apache.ignite.spi.IgniteSpiException; +import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi; +import org.apache.ignite.spi.discovery.tcp.ipfinder.TcpDiscoveryIpFinderAdapter; +import org.apache.log4j.Logger; + +import static org.apache.ignite.IgniteSystemProperties.IGNITE_JETTY_PORT; +import static org.apache.ignite.internal.IgniteNodeAttributes.ATTR_REST_JETTY_ADDRS; +import static org.apache.ignite.internal.IgniteNodeAttributes.ATTR_REST_JETTY_PORT; + +/** + * Demo for SQL. + * + * Cache will be created and populated with data to query. + */ +public class AgentSqlDemo { + /** */ + private static final Logger log = Logger.getLogger(AgentMetadataDemo.class.getName()); + + /** */ + private static final AtomicBoolean initLatch = new AtomicBoolean(); + + /** */ + private static final String COUNTRY_CACHE_NAME = "CountryCache"; + /** */ + private static final String DEPARTMENT_CACHE_NAME = "DepartmentCache"; + /** */ + private static final String EMPLOYEE_CACHE_NAME = "EmployeeCache"; + /** */ + private static final String PARKING_CACHE_NAME = "ParkingCache"; + /** */ + private static final String CAR_CACHE_NAME = "CarCache"; + + /** */ + private static final Random rnd = new Random(); + + /** Countries count. */ + private static final int CNTR_CNT = 10; + + /** Departments count */ + private static final int DEP_CNT = 100; + + /** Employees count. */ + private static final int EMPL_CNT = 1000; + + /** Countries count. */ + private static final int CAR_CNT = 100; + + /** Departments count */ + private static final int PARK_CNT = 10; + + /** Counter for threads in pool. */ + private static final AtomicInteger THREAD_CNT = new AtomicInteger(0); + + /** + * Configure cacheCountry. + */ + private static <K, V> CacheConfiguration<K, V> cacheCountry() { + CacheConfiguration<K, V> ccfg = new CacheConfiguration<>(COUNTRY_CACHE_NAME); + + // Configure cacheCountry types. + Collection<QueryEntity> queryEntities = new ArrayList<>(); + + // COUNTRY. + QueryEntity type = new QueryEntity(); + + queryEntities.add(type); + + type.setKeyType(Integer.class.getName()); + type.setValueType(Country.class.getName()); + + // Query fields for COUNTRY. + LinkedHashMap<String, String> qryFlds = new LinkedHashMap<>(); + + qryFlds.put("id", "java.lang.Integer"); + qryFlds.put("name", "java.lang.String"); + qryFlds.put("population", "java.lang.Integer"); + + type.setFields(qryFlds); + + // Indexes for COUNTRY. + type.setIndexes(Collections.singletonList(new QueryIndex("id", QueryIndexType.SORTED, false, "PRIMARY_KEY_6"))); + + ccfg.setQueryEntities(queryEntities); + + return ccfg; + } + + /** + * Configure cacheEmployee. + */ + private static <K, V> CacheConfiguration<K, V> cacheDepartment() { + CacheConfiguration<K, V> ccfg = new CacheConfiguration<>(DEPARTMENT_CACHE_NAME); + + // Configure cacheDepartment types. + Collection<QueryEntity> queryEntities = new ArrayList<>(); + + // DEPARTMENT. + QueryEntity type = new QueryEntity(); + + queryEntities.add(type); + + type.setKeyType(Integer.class.getName()); + type.setValueType(Department.class.getName()); + + // Query fields for DEPARTMENT. + LinkedHashMap<String, String> qryFlds = new LinkedHashMap<>(); + + qryFlds.put("id", "java.lang.Integer"); + qryFlds.put("countryId", "java.lang.Integer"); + qryFlds.put("name", "java.lang.String"); + + type.setFields(qryFlds); + + // Indexes for DEPARTMENT. + type.setIndexes(Collections.singletonList(new QueryIndex("id", QueryIndexType.SORTED, false, "PRIMARY_KEY_4"))); + + ccfg.setQueryEntities(queryEntities); + + return ccfg; + } + + /** + * Configure cacheEmployee. + */ + private static <K, V> CacheConfiguration<K, V> cacheEmployee() { + CacheConfiguration<K, V> ccfg = new CacheConfiguration<>(EMPLOYEE_CACHE_NAME); + + // Configure cacheEmployee types. + Collection<QueryEntity> queryEntities = new ArrayList<>(); + + // EMPLOYEE. + QueryEntity type = new QueryEntity(); + + queryEntities.add(type); + + type.setKeyType(Integer.class.getName()); + type.setValueType(Employee.class.getName()); + + // Query fields for EMPLOYEE. + LinkedHashMap<String, String> qryFlds = new LinkedHashMap<>(); + + qryFlds.put("id", "java.lang.Integer"); + qryFlds.put("departmentId", "java.lang.Integer"); + qryFlds.put("managerId", "java.lang.Integer"); + qryFlds.put("firstName", "java.lang.String"); + qryFlds.put("lastName", "java.lang.String"); + qryFlds.put("email", "java.lang.String"); + qryFlds.put("phoneNumber", "java.lang.String"); + qryFlds.put("hireDate", "java.sql.Date"); + qryFlds.put("job", "java.lang.String"); + qryFlds.put("salary", "java.lang.Double"); + + type.setFields(qryFlds); + + // Indexes for EMPLOYEE. + Collection<QueryIndex> indexes = new ArrayList<>(); + + indexes.add(new QueryIndex("id", QueryIndexType.SORTED, false, "PRIMARY_KEY_7")); + + QueryIndex index = new QueryIndex(); + + index.setName("EMP_NAMES"); + index.setIndexType(QueryIndexType.SORTED); + LinkedHashMap<String, Boolean> indFlds = new LinkedHashMap<>(); + + indFlds.put("firstName", false); + indFlds.put("lastName", false); + + index.setFields(indFlds); + + indexes.add(index); + indexes.add(new QueryIndex("salary", QueryIndexType.SORTED, false, "EMP_SALARY")); + + type.setIndexes(indexes); + + ccfg.setQueryEntities(queryEntities); + + return ccfg; + } + + /** + * Configure cacheEmployee. + */ + private static <K, V> CacheConfiguration<K, V> cacheParking() { + CacheConfiguration<K, V> ccfg = new CacheConfiguration<>(PARKING_CACHE_NAME); + + // Configure cacheParking types. + Collection<QueryEntity> queryEntities = new ArrayList<>(); + + // PARKING. + QueryEntity type = new QueryEntity(); + + queryEntities.add(type); + + type.setKeyType(Integer.class.getName()); + type.setValueType(Parking.class.getName()); + + // Query fields for PARKING. + LinkedHashMap<String, String> qryFlds = new LinkedHashMap<>(); + + qryFlds.put("id", "java.lang.Integer"); + qryFlds.put("name", "java.lang.String"); + qryFlds.put("capacity", "java.lang.Integer");; + + type.setFields(qryFlds); + + // Indexes for PARKING. + type.setIndexes(Collections.singletonList(new QueryIndex("id", QueryIndexType.SORTED, false, "PRIMARY_KEY_F"))); + + ccfg.setQueryEntities(queryEntities); + + return ccfg; + } + + /** + * Configure cacheEmployee. + */ + private static <K, V> CacheConfiguration<K, V> cacheCar() { + CacheConfiguration<K, V> ccfg = new CacheConfiguration<>(CAR_CACHE_NAME); + + // Configure cacheCar types. + Collection<QueryEntity> queryEntities = new ArrayList<>(); + + // CAR. + QueryEntity type = new QueryEntity(); + + queryEntities.add(type); + + type.setKeyType(Integer.class.getName()); + type.setValueType(Car.class.getName()); + + // Query fields for CAR. + LinkedHashMap<String, String> qryFlds = new LinkedHashMap<>(); + + qryFlds.put("id", "java.lang.Integer"); + qryFlds.put("parkingId", "java.lang.Integer"); + qryFlds.put("name", "java.lang.String"); + + type.setFields(qryFlds); + + // Indexes for CAR. + type.setIndexes(Collections.singletonList(new QueryIndex("id", QueryIndexType.SORTED, false, "PRIMARY_KEY_1"))); + + ccfg.setQueryEntities(queryEntities); + + return ccfg; + } + + /** + * @param val Value to round. + * @param places Numbers after point. + * @return Rounded value; + */ + private static double round(double val, int places) { + if (places < 0) + throw new IllegalArgumentException(); + + long factor = (long) Math.pow(10, places); + + val *= factor; + + long tmp = Math.round(val); + + return (double) tmp / factor; + } + + /** + * @param ignite Ignite. + * @param range Time range in milliseconds. + */ + private static void populateCacheEmployee(Ignite ignite, long range) { + log.trace("DEMO: Start employees population with data..."); + + IgniteCache<Integer, Country> cacheCountry = ignite.cache(COUNTRY_CACHE_NAME); + + for (int i = 0, n = i + 1; i < CNTR_CNT; i++) + cacheCountry.put(i, new Country(i, "Country #" + n, n * 10000000)); + + IgniteCache<Integer, Department> cacheDepartment = ignite.cache(DEPARTMENT_CACHE_NAME); + + IgniteCache<Integer, Employee> cacheEmployee = ignite.cache(EMPLOYEE_CACHE_NAME); + + for (int i = 0, n = i + 1; i < DEP_CNT; i++) { + cacheDepartment.put(i, new Department(n, rnd.nextInt(CNTR_CNT), "Department #" + n)); + + double r = rnd.nextDouble(); + + cacheEmployee.put(i, new Employee(i, rnd.nextInt(DEP_CNT), null, "First name manager #" + n, + "Last name manager #" + n, "Email manager #" + n, "Phone number manager #" + n, + new java.sql.Date((long)(r * range)), "Job manager #" + n, 1000 + round(r * 4000, 2))); + } + + for (int i = 0, n = i + 1; i < EMPL_CNT; i++) { + Integer depId = rnd.nextInt(DEP_CNT); + + double r = rnd.nextDouble(); + + cacheEmployee.put(i, new Employee(i, depId, depId, "First name employee #" + n, + "Last name employee #" + n, "Email employee #" + n, "Phone number employee #" + n, + new java.sql.Date((long)(r * range)), "Job employee #" + n, 500 + round(r * 2000, 2))); + } + + log.trace("DEMO: Finished employees population."); + } + + /** + * @param ignite Ignite. + */ + private static void populateCacheCar(Ignite ignite) { + log.trace("DEMO: Start cars population..."); + + IgniteCache<Integer, Parking> cacheParking = ignite.cache(PARKING_CACHE_NAME); + + for (int i = 0, n = i + 1; i < PARK_CNT; i++) + cacheParking.put(i, new Parking(i, "Parking #" + n, n * 10)); + + IgniteCache<Integer, Car> cacheCar = ignite.cache(CAR_CACHE_NAME); + + for (int i = 0, n = i + 1; i < CAR_CNT; i++) + cacheCar.put(i, new Car(i, rnd.nextInt(PARK_CNT), "Car #" + n)); + + log.trace("DEMO: Finished cars population."); + } + + /** + * Creates a thread pool that can schedule commands to run after a given delay, or to execute periodically. + * + * @param corePoolSize Number of threads to keep in the pool, even if they are idle. + * @param threadName Part of thread name that would be used by thread factory. + * @return Newly created scheduled thread pool. + */ + private static ScheduledExecutorService newScheduledThreadPool(int corePoolSize, final String threadName) { + ScheduledExecutorService srvc = Executors.newScheduledThreadPool(corePoolSize, new ThreadFactory() { + @Override public Thread newThread(Runnable r) { + Thread thread = new Thread(r, String.format("%s-%d", threadName, THREAD_CNT.getAndIncrement())); + + thread.setDaemon(true); + + return thread; + } + }); + + ScheduledThreadPoolExecutor executor = (ScheduledThreadPoolExecutor) srvc; + + // Setting up shutdown policy. + executor.setExecuteExistingDelayedTasksAfterShutdownPolicy(false); + executor.setContinueExistingPeriodicTasksAfterShutdownPolicy(false); + + return srvc; + } + + /** + * Starts read and write from cache in background. + * + * @param ignite Ignite. + * @param cnt - maximum count read/write key + */ + private static void startLoad(final Ignite ignite, final int cnt) { + final long diff = new java.util.Date().getTime(); + + populateCacheEmployee(ignite, diff); + + populateCacheCar(ignite); + + ScheduledExecutorService cachePool = newScheduledThreadPool(2, "demo-sql-load-cache-tasks"); + + cachePool.scheduleWithFixedDelay(new Runnable() { + @Override public void run() { + try { + IgniteCache<Integer, Employee> cacheEmployee = ignite.cache(EMPLOYEE_CACHE_NAME); + + if (cacheEmployee != null) + for (int i = 0, n = i + 1; i < cnt; i++) { + Integer id = rnd.nextInt(EMPL_CNT); + + Integer depId = rnd.nextInt(DEP_CNT); + + double r = rnd.nextDouble(); + + cacheEmployee.put(id, new Employee(id, depId, depId, "First name employee #" + n, + "Last name employee #" + n, "Email employee #" + n, "Phone number employee #" + n, + new java.sql.Date((long)(r * diff)), "Job employee #" + n, 500 + round(r * 2000, 2))); + + if (rnd.nextBoolean()) + cacheEmployee.remove(rnd.nextInt(EMPL_CNT)); + } + } + catch (IllegalStateException ignored) { + // No-op. + } + catch (Throwable e) { + if (!e.getMessage().contains("cache is stopped")) + ignite.log().error("Cache write task execution error", e); + } + } + }, 10, 3, TimeUnit.SECONDS); + + cachePool.scheduleWithFixedDelay(new Runnable() { + @Override public void run() { + try { + IgniteCache<Integer, Car> cache = ignite.cache(CAR_CACHE_NAME); + + if (cache != null) + for (int i = 0; i < cnt; i++) { + Integer carId = rnd.nextInt(CAR_CNT); + + cache.put(carId, new Car(carId, rnd.nextInt(PARK_CNT), "Car #" + (i + 1))); + + if (rnd.nextBoolean()) + cache.remove(rnd.nextInt(CAR_CNT)); + } + } + catch (IllegalStateException ignored) { + // No-op. + } + catch (Throwable e) { + if (!e.getMessage().contains("cache is stopped")) + ignite.log().error("Cache write task execution error", e); + } + } + }, 10, 3, TimeUnit.SECONDS); + } + + /** + * Start ignite node with cacheEmployee and populate it with data. + */ + public static boolean testDrive(AgentConfiguration acfg) { + if (initLatch.compareAndSet(false, true)) { + log.info("DEMO: Starting embedded node for sql test-drive..."); + + try { + IgniteConfiguration cfg = new IgniteConfiguration(); + + cfg.setLocalHost("127.0.0.1"); + + cfg.setMetricsLogFrequency(0); + + cfg.setGridLogger(new NullLogger()); + + // Configure discovery SPI. + TcpDiscoverySpi discoSpi = new TcpDiscoverySpi(); + + discoSpi.setLocalPort(60900); + + discoSpi.setIpFinder(new TcpDiscoveryIpFinderAdapter() { + { + setShared(true); + } + + /** {@inheritDoc} */ + @Override public Collection<InetSocketAddress> getRegisteredAddresses() throws IgniteSpiException { + return Collections.emptyList(); + } + + /** {@inheritDoc} */ + @Override public void registerAddresses(Collection<InetSocketAddress> addrs) throws IgniteSpiException { + // No-op. + } + + /** {@inheritDoc} */ + @Override public void unregisterAddresses(Collection<InetSocketAddress> addrs) throws IgniteSpiException { + // No-op. + } + }); + + cfg.setDiscoverySpi(discoSpi); + + cfg.setCacheConfiguration(cacheCountry(), cacheDepartment(), cacheEmployee(), cacheParking(), cacheCar()); + + System.setProperty(IGNITE_JETTY_PORT, "60800"); + + log.trace("DEMO: Start embedded node with indexed enabled caches..."); + + IgniteEx ignite = (IgniteEx)Ignition.start(cfg); + + String host = ((Collection<String>) + ignite.localNode().attribute(ATTR_REST_JETTY_ADDRS)).iterator().next(); + + Integer port = ignite.localNode().attribute(ATTR_REST_JETTY_PORT); + + if (F.isEmpty(host) || port == null) { + log.error("DEMO: Failed to start embedded node with rest!"); + + return false; + } + + acfg.demoNodeUri(String.format("http://%s:%d", host, port)); + + log.info("DEMO: Embedded node for sql test-drive successfully started"); + + startLoad(ignite, 20); + } + catch (Exception e) { + log.error("DEMO: Failed to start embedded node for sql test-drive!", e); + + return false; + } + } + + return true; + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/54a24746/modules/control-center-agent/src/main/java/org/apache/ignite/console/demo/model/Car.java ---------------------------------------------------------------------- diff --git a/modules/control-center-agent/src/main/java/org/apache/ignite/console/demo/model/Car.java b/modules/control-center-agent/src/main/java/org/apache/ignite/console/demo/model/Car.java new file mode 100755 index 0000000..16b1120 --- /dev/null +++ b/modules/control-center-agent/src/main/java/org/apache/ignite/console/demo/model/Car.java @@ -0,0 +1,137 @@ +package org.apache.ignite.console.demo.model; + +import java.io.Serializable; + +/** + * Car definition. + * + * This configuration was generated by Ignite Web Console (01/14/2016 13:46) + */ +public class Car implements Serializable { + /** */ + private static final long serialVersionUID = 0L; + + /** Value for id. */ + private int id; + + /** Value for parkingId. */ + private int parkingId; + + /** Value for name. */ + private String name; + + /** + * Empty constructor. + */ + public Car() { + // No-op. + } + + /** + * Full constructor. + */ + public Car( + int id, + int parkingId, + String name + ) { + this.id = id; + this.parkingId = parkingId; + this.name = name; + } + + /** + * Gets id. + * + * @return Value for id. + */ + public int getId() { + return id; + } + + /** + * Sets id. + * + * @param id New value for id. + */ + public void setId(int id) { + this.id = id; + } + + /** + * Gets parkingId. + * + * @return Value for parkingId. + */ + public int getParkingId() { + return parkingId; + } + + /** + * Sets parkingId. + * + * @param parkingId New value for parkingId. + */ + public void setParkingId(int parkingId) { + this.parkingId = parkingId; + } + + /** + * Gets name. + * + * @return Value for name. + */ + public String getName() { + return name; + } + + /** + * Sets name. + * + * @param name New value for name. + */ + public void setName(String name) { + this.name = name; + } + + /** {@inheritDoc} */ + @Override public boolean equals(Object o) { + if (this == o) + return true; + + if (!(o instanceof Car)) + return false; + + Car that = (Car)o; + + if (id != that.id) + return false; + + if (parkingId != that.parkingId) + return false; + + if (name != null ? !name.equals(that.name) : that.name != null) + return false; + + return true; + } + + /** {@inheritDoc} */ + @Override public int hashCode() { + int res = id; + + res = 31 * res + parkingId; + + res = 31 * res + (name != null ? name.hashCode() : 0); + + return res; + } + + /** {@inheritDoc} */ + @Override public String toString() { + return "Car [id=" + id + + ", parkingId=" + parkingId + + ", name=" + name + + ']'; + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ignite/blob/54a24746/modules/control-center-agent/src/main/java/org/apache/ignite/console/demo/model/Country.java ---------------------------------------------------------------------- diff --git a/modules/control-center-agent/src/main/java/org/apache/ignite/console/demo/model/Country.java b/modules/control-center-agent/src/main/java/org/apache/ignite/console/demo/model/Country.java new file mode 100755 index 0000000..1817224 --- /dev/null +++ b/modules/control-center-agent/src/main/java/org/apache/ignite/console/demo/model/Country.java @@ -0,0 +1,137 @@ +package org.apache.ignite.console.demo.model; + +import java.io.Serializable; + +/** + * Country definition. + * + * This configuration was generated by Ignite Web Console (01/14/2016 13:46) + */ +public class Country implements Serializable { + /** */ + private static final long serialVersionUID = 0L; + + /** Value for id. */ + private int id; + + /** Value for name. */ + private String name; + + /** Value for population. */ + private int population; + + /** + * Empty constructor. + */ + public Country() { + // No-op. + } + + /** + * Full constructor. + */ + public Country( + int id, + String name, + int population + ) { + this.id = id; + this.name = name; + this.population = population; + } + + /** + * Gets id. + * + * @return Value for id. + */ + public int getId() { + return id; + } + + /** + * Sets id. + * + * @param id New value for id. + */ + public void setId(int id) { + this.id = id; + } + + /** + * Gets name. + * + * @return Value for name. + */ + public String getName() { + return name; + } + + /** + * Sets name. + * + * @param name New value for name. + */ + public void setName(String name) { + this.name = name; + } + + /** + * Gets population. + * + * @return Value for population. + */ + public int getPopulation() { + return population; + } + + /** + * Sets population. + * + * @param population New value for population. + */ + public void setPopulation(int population) { + this.population = population; + } + + /** {@inheritDoc} */ + @Override public boolean equals(Object o) { + if (this == o) + return true; + + if (!(o instanceof Country)) + return false; + + Country that = (Country)o; + + if (id != that.id) + return false; + + if (name != null ? !name.equals(that.name) : that.name != null) + return false; + + if (population != that.population) + return false; + + return true; + } + + /** {@inheritDoc} */ + @Override public int hashCode() { + int res = id; + + res = 31 * res + (name != null ? name.hashCode() : 0); + + res = 31 * res + population; + + return res; + } + + /** {@inheritDoc} */ + @Override public String toString() { + return "Country [id=" + id + + ", name=" + name + + ", population=" + population + + ']'; + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ignite/blob/54a24746/modules/control-center-agent/src/main/java/org/apache/ignite/console/demo/model/Department.java ---------------------------------------------------------------------- diff --git a/modules/control-center-agent/src/main/java/org/apache/ignite/console/demo/model/Department.java b/modules/control-center-agent/src/main/java/org/apache/ignite/console/demo/model/Department.java new file mode 100755 index 0000000..3f90147 --- /dev/null +++ b/modules/control-center-agent/src/main/java/org/apache/ignite/console/demo/model/Department.java @@ -0,0 +1,137 @@ +package org.apache.ignite.console.demo.model; + +import java.io.Serializable; + +/** + * Department definition. + * + * This configuration was generated by Ignite Web Console (01/14/2016 13:46) + */ +public class Department implements Serializable { + /** */ + private static final long serialVersionUID = 0L; + + /** Value for id. */ + private int id; + + /** Value for countryId. */ + private int countryId; + + /** Value for name. */ + private String name; + + /** + * Empty constructor. + */ + public Department() { + // No-op. + } + + /** + * Full constructor. + */ + public Department( + int id, + int countryId, + String name + ) { + this.id = id; + this.countryId = countryId; + this.name = name; + } + + /** + * Gets id. + * + * @return Value for id. + */ + public int getId() { + return id; + } + + /** + * Sets id. + * + * @param id New value for id. + */ + public void setId(int id) { + this.id = id; + } + + /** + * Gets countryId. + * + * @return Value for countryId. + */ + public int getCountryId() { + return countryId; + } + + /** + * Sets countryId. + * + * @param countryId New value for countryId. + */ + public void setCountryId(int countryId) { + this.countryId = countryId; + } + + /** + * Gets name. + * + * @return Value for name. + */ + public String getName() { + return name; + } + + /** + * Sets name. + * + * @param name New value for name. + */ + public void setName(String name) { + this.name = name; + } + + /** {@inheritDoc} */ + @Override public boolean equals(Object o) { + if (this == o) + return true; + + if (!(o instanceof Department)) + return false; + + Department that = (Department)o; + + if (id != that.id) + return false; + + if (countryId != that.countryId) + return false; + + if (name != null ? !name.equals(that.name) : that.name != null) + return false; + + return true; + } + + /** {@inheritDoc} */ + @Override public int hashCode() { + int res = id; + + res = 31 * res + countryId; + + res = 31 * res + (name != null ? name.hashCode() : 0); + + return res; + } + + /** {@inheritDoc} */ + @Override public String toString() { + return "Department [id=" + id + + ", countryId=" + countryId + + ", name=" + name + + ']'; + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ignite/blob/54a24746/modules/control-center-agent/src/main/java/org/apache/ignite/console/demo/model/Employee.java ---------------------------------------------------------------------- diff --git a/modules/control-center-agent/src/main/java/org/apache/ignite/console/demo/model/Employee.java b/modules/control-center-agent/src/main/java/org/apache/ignite/console/demo/model/Employee.java new file mode 100755 index 0000000..f1f0b3f --- /dev/null +++ b/modules/control-center-agent/src/main/java/org/apache/ignite/console/demo/model/Employee.java @@ -0,0 +1,341 @@ +package org.apache.ignite.console.demo.model; + +import java.io.Serializable; +import java.sql.Date; + +/** + * Employee definition. + * + * This configuration was generated by Ignite Web Console (01/14/2016 13:46) + */ +public class Employee implements Serializable { + /** */ + private static final long serialVersionUID = 0L; + + /** Value for id. */ + private int id; + + /** Value for departmentId. */ + private int departmentId; + + /** Value for managerId. */ + private Integer managerId; + + /** Value for firstName. */ + private String firstName; + + /** Value for lastName. */ + private String lastName; + + /** Value for email. */ + private String email; + + /** Value for phoneNumber. */ + private String phoneNumber; + + /** Value for hireDate. */ + private Date hireDate; + + /** Value for job. */ + private String job; + + /** Value for salary. */ + private Double salary; + + /** + * Empty constructor. + */ + public Employee() { + // No-op. + } + + /** + * Full constructor. + */ + public Employee( + int id, + int departmentId, + Integer managerId, + String firstName, + String lastName, + String email, + String phoneNumber, + Date hireDate, + String job, + Double salary + ) { + this.id = id; + this.departmentId = departmentId; + this.managerId = managerId; + this.firstName = firstName; + this.lastName = lastName; + this.email = email; + this.phoneNumber = phoneNumber; + this.hireDate = hireDate; + this.job = job; + this.salary = salary; + } + + /** + * Gets id. + * + * @return Value for id. + */ + public int getId() { + return id; + } + + /** + * Sets id. + * + * @param id New value for id. + */ + public void setId(int id) { + this.id = id; + } + + /** + * Gets departmentId. + * + * @return Value for departmentId. + */ + public int getDepartmentId() { + return departmentId; + } + + /** + * Sets departmentId. + * + * @param departmentId New value for departmentId. + */ + public void setDepartmentId(int departmentId) { + this.departmentId = departmentId; + } + + /** + * Gets managerId. + * + * @return Value for managerId. + */ + public Integer getManagerId() { + return managerId; + } + + /** + * Sets managerId. + * + * @param managerId New value for managerId. + */ + public void setManagerId(Integer managerId) { + this.managerId = managerId; + } + + /** + * Gets firstName. + * + * @return Value for firstName. + */ + public String getFirstName() { + return firstName; + } + + /** + * Sets firstName. + * + * @param firstName New value for firstName. + */ + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + /** + * Gets lastName. + * + * @return Value for lastName. + */ + public String getLastName() { + return lastName; + } + + /** + * Sets lastName. + * + * @param lastName New value for lastName. + */ + public void setLastName(String lastName) { + this.lastName = lastName; + } + + /** + * Gets email. + * + * @return Value for email. + */ + public String getEmail() { + return email; + } + + /** + * Sets email. + * + * @param email New value for email. + */ + public void setEmail(String email) { + this.email = email; + } + + /** + * Gets phoneNumber. + * + * @return Value for phoneNumber. + */ + public String getPhoneNumber() { + return phoneNumber; + } + + /** + * Sets phoneNumber. + * + * @param phoneNumber New value for phoneNumber. + */ + public void setPhoneNumber(String phoneNumber) { + this.phoneNumber = phoneNumber; + } + + /** + * Gets hireDate. + * + * @return Value for hireDate. + */ + public Date getHireDate() { + return hireDate; + } + + /** + * Sets hireDate. + * + * @param hireDate New value for hireDate. + */ + public void setHireDate(Date hireDate) { + this.hireDate = hireDate; + } + + /** + * Gets job. + * + * @return Value for job. + */ + public String getJob() { + return job; + } + + /** + * Sets job. + * + * @param job New value for job. + */ + public void setJob(String job) { + this.job = job; + } + + /** + * Gets salary. + * + * @return Value for salary. + */ + public Double getSalary() { + return salary; + } + + /** + * Sets salary. + * + * @param salary New value for salary. + */ + public void setSalary(Double salary) { + this.salary = salary; + } + + /** {@inheritDoc} */ + @Override public boolean equals(Object o) { + if (this == o) + return true; + + if (!(o instanceof Employee)) + return false; + + Employee that = (Employee)o; + + if (id != that.id) + return false; + + if (departmentId != that.departmentId) + return false; + + if (managerId != null ? !managerId.equals(that.managerId) : that.managerId != null) + return false; + + if (firstName != null ? !firstName.equals(that.firstName) : that.firstName != null) + return false; + + if (lastName != null ? !lastName.equals(that.lastName) : that.lastName != null) + return false; + + if (email != null ? !email.equals(that.email) : that.email != null) + return false; + + if (phoneNumber != null ? !phoneNumber.equals(that.phoneNumber) : that.phoneNumber != null) + return false; + + if (hireDate != null ? !hireDate.equals(that.hireDate) : that.hireDate != null) + return false; + + if (job != null ? !job.equals(that.job) : that.job != null) + return false; + + if (salary != null ? !salary.equals(that.salary) : that.salary != null) + return false; + + return true; + } + + /** {@inheritDoc} */ + @Override public int hashCode() { + int res = id; + + res = 31 * res + departmentId; + + res = 31 * res + (managerId != null ? managerId.hashCode() : 0); + + res = 31 * res + (firstName != null ? firstName.hashCode() : 0); + + res = 31 * res + (lastName != null ? lastName.hashCode() : 0); + + res = 31 * res + (email != null ? email.hashCode() : 0); + + res = 31 * res + (phoneNumber != null ? phoneNumber.hashCode() : 0); + + res = 31 * res + (hireDate != null ? hireDate.hashCode() : 0); + + res = 31 * res + (job != null ? job.hashCode() : 0); + + res = 31 * res + (salary != null ? salary.hashCode() : 0); + + return res; + } + + /** {@inheritDoc} */ + @Override public String toString() { + return "Employee [id=" + id + + ", departmentId=" + departmentId + + ", managerId=" + managerId + + ", firstName=" + firstName + + ", lastName=" + lastName + + ", email=" + email + + ", phoneNumber=" + phoneNumber + + ", hireDate=" + hireDate + + ", job=" + job + + ", salary=" + salary + + ']'; + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ignite/blob/54a24746/modules/control-center-agent/src/main/java/org/apache/ignite/console/demo/model/Parking.java ---------------------------------------------------------------------- diff --git a/modules/control-center-agent/src/main/java/org/apache/ignite/console/demo/model/Parking.java b/modules/control-center-agent/src/main/java/org/apache/ignite/console/demo/model/Parking.java new file mode 100755 index 0000000..e6539fa --- /dev/null +++ b/modules/control-center-agent/src/main/java/org/apache/ignite/console/demo/model/Parking.java @@ -0,0 +1,137 @@ +package org.apache.ignite.console.demo.model; + +import java.io.Serializable; + +/** + * Parking definition. + * + * This configuration was generated by Ignite Web Console (01/14/2016 13:46) + */ +public class Parking implements Serializable { + /** */ + private static final long serialVersionUID = 0L; + + /** Value for id. */ + private int id; + + /** Value for name. */ + private String name; + + /** Value for capacity. */ + private int capacity; + + /** + * Empty constructor. + */ + public Parking() { + // No-op. + } + + /** + * Full constructor. + */ + public Parking( + int id, + String name, + int capacity + ) { + this.id = id; + this.name = name; + this.capacity = capacity; + } + + /** + * Gets id. + * + * @return Value for id. + */ + public int getId() { + return id; + } + + /** + * Sets id. + * + * @param id New value for id. + */ + public void setId(int id) { + this.id = id; + } + + /** + * Gets name. + * + * @return Value for name. + */ + public String getName() { + return name; + } + + /** + * Sets name. + * + * @param name New value for name. + */ + public void setName(String name) { + this.name = name; + } + + /** + * Gets capacity. + * + * @return Value for capacity. + */ + public int getCapacity() { + return capacity; + } + + /** + * Sets capacity. + * + * @param capacity New value for capacity. + */ + public void setCapacity(int capacity) { + this.capacity = capacity; + } + + /** {@inheritDoc} */ + @Override public boolean equals(Object o) { + if (this == o) + return true; + + if (!(o instanceof Parking)) + return false; + + Parking that = (Parking)o; + + if (id != that.id) + return false; + + if (name != null ? !name.equals(that.name) : that.name != null) + return false; + + if (capacity != that.capacity) + return false; + + return true; + } + + /** {@inheritDoc} */ + @Override public int hashCode() { + int res = id; + + res = 31 * res + (name != null ? name.hashCode() : 0); + + res = 31 * res + capacity; + + return res; + } + + /** {@inheritDoc} */ + @Override public String toString() { + return "Parking [id=" + id + + ", name=" + name + + ", capacity=" + capacity + + ']'; + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ignite/blob/54a24746/modules/control-center-web/src/main/js/agents/agent-manager.js ---------------------------------------------------------------------- diff --git a/modules/control-center-web/src/main/js/agents/agent-manager.js b/modules/control-center-web/src/main/js/agents/agent-manager.js index 6205198..9f631b9 100644 --- a/modules/control-center-web/src/main/js/agents/agent-manager.js +++ b/modules/control-center-web/src/main/js/agents/agent-manager.js @@ -113,14 +113,15 @@ function Client(ws, manager) { } /** - * @param {String} path + * @param {String} uri * @param {Object} params + * @param {Boolean} demo * @param {String} [method] * @param {Object} [headers] * @param {String} [body] * @param {Function} [cb] Callback. Take 3 arguments: {String} error, {number} httpCode, {string} response. */ -Client.prototype.executeRest = function(path, params, method, headers, body, cb) { +Client.prototype.executeRest = function(uri, params, demo, method, headers, body, cb) { if (typeof(params) != 'object') throw '"params" argument must be an object'; @@ -143,7 +144,7 @@ Client.prototype.executeRest = function(path, params, method, headers, body, cb) var newArgs = argsToArray(arguments); - newArgs[5] = function(ex, res) { + newArgs[6] = function(ex, res) { if (ex) cb(ex.message); else @@ -250,7 +251,9 @@ Client.prototype._rmtAuthMessage = function(msg) { self._manager._addClient(account._id, self); - self._ignite = new apacheIgnite.Ignite(new AgentServer(self)); + self._cluster = new apacheIgnite.Ignite(new AgentServer(self)); + + self._demo = new apacheIgnite.Ignite(new AgentServer(self, true)); } }); }; @@ -271,8 +274,8 @@ Client.prototype._rmtCallRes = function(msg) { /** * @returns {Ignite} */ -Client.prototype.ignite = function() { - return this._ignite; +Client.prototype.ignite = function(demo) { + return demo ? this._demo : this._cluster; }; function removeFromArray(arr, val) { http://git-wip-us.apache.org/repos/asf/ignite/blob/54a24746/modules/control-center-web/src/main/js/agents/agent-server.js ---------------------------------------------------------------------- diff --git a/modules/control-center-web/src/main/js/agents/agent-server.js b/modules/control-center-web/src/main/js/agents/agent-server.js index 76bdeb4..ae5a87c 100644 --- a/modules/control-center-web/src/main/js/agents/agent-server.js +++ b/modules/control-center-web/src/main/js/agents/agent-server.js @@ -22,10 +22,12 @@ var _ = require('lodash'); * * @constructor * @this {AgentServer} - * @param {Client} client connected client + * @param {Client} client Connected client + * @param {Boolean} demo Use demo node for request */ -function AgentServer(client) { +function AgentServer(client, demo) { this._client = client; + this._demo = !!demo; } /** @@ -56,9 +58,10 @@ AgentServer.prototype.runCommand = function(cmd, callback) { headers = {'JSONObject': 'application/json'}; } - this._client.executeRest("ignite", params, method, headers, body, function(error, code, message) { + this._client.executeRest("ignite", params, this._demo, method, headers, body, function(error, code, message) { if (error) { callback(error); + return } @@ -71,22 +74,16 @@ AgentServer.prototype.runCommand = function(cmd, callback) { return; } - var igniteResponse; - try { - igniteResponse = JSON.parse(message); + var igniteResponse = JSON.parse(message); + + if (igniteResponse.successStatus) + callback.call(null, igniteResponse.error, null); + else + callback.call(null, null, igniteResponse.response); } catch (e) { callback.call(null, e, null); - - return; - } - - if (igniteResponse.successStatus) { - callback.call(null, igniteResponse.error, null) - } - else { - callback.call(null, null, igniteResponse.response); } }); }; http://git-wip-us.apache.org/repos/asf/ignite/blob/54a24746/modules/control-center-web/src/main/js/app/index.js ---------------------------------------------------------------------- diff --git a/modules/control-center-web/src/main/js/app/index.js b/modules/control-center-web/src/main/js/app/index.js index a552939..6fcaad5 100644 --- a/modules/control-center-web/src/main/js/app/index.js +++ b/modules/control-center-web/src/main/js/app/index.js @@ -59,6 +59,7 @@ import './modules/User/index'; import './modules/Auth/index'; import './modules/Form/index'; import './modules/JavaTypes/index'; +import './modules/QueryNotebooks/index'; import './modules/states/login/index'; import './modules/states/logout/index'; @@ -102,6 +103,7 @@ angular 'ignite-console.User', 'ignite-console.Form', 'ignite-console.JavaTypes', + 'ignite-console.QueryNotebooks', // States. 'ignite-console.states.login', 'ignite-console.states.logout', http://git-wip-us.apache.org/repos/asf/ignite/blob/54a24746/modules/control-center-web/src/main/js/app/modules/QueryNotebooks/index.js ---------------------------------------------------------------------- diff --git a/modules/control-center-web/src/main/js/app/modules/QueryNotebooks/index.js b/modules/control-center-web/src/main/js/app/modules/QueryNotebooks/index.js new file mode 100644 index 0000000..702b107 --- /dev/null +++ b/modules/control-center-web/src/main/js/app/modules/QueryNotebooks/index.js @@ -0,0 +1,111 @@ +/* + * 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. + */ + +import angular from 'angular'; + +angular + .module('ignite-console.QueryNotebooks', [ + + ]) + .provider('QueryNotebooks', function() { + const _demoNotebook = { + name: 'SQL demo', + paragraphs: [ + { + name: 'Simple query', + cacheName: 'CarCache', + pageSize: 50, + query: 'SELECT * FROM Car', + result: 'table', + queryArgs: { + type: 'QUERY', + query: 'SELECT * FROM Car', + pageSize: 50, + cacheName: 'CarCache' + }, + rate: { + value: 1, + unit: 60000, + installed: false + } + }, + { + name: 'Query with aggregates', + cacheName: 'CarCache', + pageSize: 50, + query: 'SELECT * FROM Car', + result: 'table', + queryArgs: { + type: 'QUERY', + query: 'SELECT * FROM Car', + pageSize: 50, + cacheName: 'CarCache' + }, + rate: { + value: 1, + unit: 60000, + installed: false + } + }, + { + name: 'Query with refresh rate', + cacheName: 'CarCache', + pageSize: 50, + query: 'SELECT * FROM Car', + result: 'table', + queryArgs: { + type: 'QUERY', + query: 'SELECT * FROM Car', + pageSize: 50, + cacheName: 'CarCache' + }, + rate: { + value: 1, + unit: 60000, + installed: false + } + } + ], + expandedParagraphs: [0, 1, 2] + }; + + this.$get = ['$q', '$http', ($q, $http) => { + return { + read(demo, noteId) { + if (demo) { + return $http.post('/api/v1/agent/demo/sql/start') + .then(() => { + return angular.copy(_demoNotebook); + }); + } + + return $http.post('/api/v1/notebooks/get', {noteId}) + .then(({data}) => { + return data; + }); + }, + save(demo, notebook) { + if (demo) + return $http.post('/api/v1/notebooks/save', notebook); + + return $q.when(); + }, + remove(demo, nodeId) { + } + }; + }]; + }); http://git-wip-us.apache.org/repos/asf/ignite/blob/54a24746/modules/control-center-web/src/main/js/app/modules/states/configuration/index.js ---------------------------------------------------------------------- diff --git a/modules/control-center-web/src/main/js/app/modules/states/configuration/index.js b/modules/control-center-web/src/main/js/app/modules/states/configuration/index.js index 0700950..90558d4 100644 --- a/modules/control-center-web/src/main/js/app/modules/states/configuration/index.js +++ b/modules/control-center-web/src/main/js/app/modules/states/configuration/index.js @@ -41,7 +41,7 @@ angular }, resolve: { $title: () => { - return 'Create and Configure Ignite Clusters'; + return 'Configure Clusters - Ignite Console'; } } }) @@ -53,7 +53,7 @@ angular }, resolve: { $title: () => { - return 'Create and Configure Ignite Caches'; + return 'Configure Caches - Ignite Console'; } } }) @@ -65,7 +65,7 @@ angular }, resolve: { $title: () => { - return 'Create and Configure Cache Type Metadata'; + return 'Configure Cache Type Metadata - Ignite Console'; } } }) @@ -77,7 +77,7 @@ angular }, resolve: { $title: () => { - return 'Create and Configure IGFS'; + return 'Configure IGFS - Ignite Console'; } } }) @@ -91,7 +91,7 @@ angular }, resolve: { $title: () => { - return 'Configurations Summary'; + return 'Configurations Summary - Ignite Console'; } } }); http://git-wip-us.apache.org/repos/asf/ignite/blob/54a24746/modules/control-center-web/src/main/js/app/modules/states/login/index.js ---------------------------------------------------------------------- diff --git a/modules/control-center-web/src/main/js/app/modules/states/login/index.js b/modules/control-center-web/src/main/js/app/modules/states/login/index.js index 316aecd..008ffb7 100644 --- a/modules/control-center-web/src/main/js/app/modules/states/login/index.js +++ b/modules/control-center-web/src/main/js/app/modules/states/login/index.js @@ -28,7 +28,12 @@ angular $stateProvider .state('login', { url: '/login', - templateUrl: '/login.html' + templateUrl: '/login.html', + resolve: { + $title: () => { + return 'Sign In - Ignite Console'; + } + } }); }]) .run(['$rootScope', '$state', 'Auth', 'igniteTerms', function($root, $state, Auth, igniteTerms) { http://git-wip-us.apache.org/repos/asf/ignite/blob/54a24746/modules/control-center-web/src/main/js/app/modules/states/sql/index.js ---------------------------------------------------------------------- diff --git a/modules/control-center-web/src/main/js/app/modules/states/sql/index.js b/modules/control-center-web/src/main/js/app/modules/states/sql/index.js index 852724b..672d829 100644 --- a/modules/control-center-web/src/main/js/app/modules/states/sql/index.js +++ b/modules/control-center-web/src/main/js/app/modules/states/sql/index.js @@ -25,14 +25,31 @@ angular // set up the states $stateProvider .state('base.sql', { - url: '/sql/{id}', + url: '/sql', + abstract: true, + template: '<ui-view></ui-view>' + }) + .state('base.sql.notebook', { + url: '/notebook/{noteId}', templateUrl: '/sql/sql.html', data: { loading: 'Loading notebook screen...' }, resolve: { $title: () => { - return 'SQL notebook'; + return 'Query notebook'; + } + } + }) + .state('base.sql.demo', { + url: '/demo', + templateUrl: '/sql/sql.html', + data: { + loading: 'Enable SQL demo...' + }, + resolve: { + $title: () => { + return 'SQL demo'; } } }); http://git-wip-us.apache.org/repos/asf/ignite/blob/54a24746/modules/control-center-web/src/main/js/controllers/common-module.js ---------------------------------------------------------------------- diff --git a/modules/control-center-web/src/main/js/controllers/common-module.js b/modules/control-center-web/src/main/js/controllers/common-module.js index cafca42..e995175 100644 --- a/modules/control-center-web/src/main/js/controllers/common-module.js +++ b/modules/control-center-web/src/main/js/controllers/common-module.js @@ -2143,10 +2143,10 @@ consoleModule.service('$agentDownload', [ * @param attr * @param mtr */ - startTopologyListening: function (success, attr, mtr) { + startTopologyListening: function (success, demo, attr, mtr) { _agentDownloadModal.check = { url: '/api/v1/agent/topology', - params: {attr: !!attr, mtr: !!mtr}, + params: {demo: !!demo, attr: !!attr, mtr: !!mtr}, cb: success }; @@ -2196,16 +2196,15 @@ consoleModule.controller('notebooks', ['$scope', '$modal', '$state', '$http', '$ $scope.$root.rebuildDropdown = function() { $scope.notebookDropdown = [ - {text: 'Create new notebook', click: 'inputNotebookName()'} + {text: 'Create new notebook', click: 'inputNotebookName()'}, + {divider: true}, + {text: 'SQL demo', sref: 'base.sql.demo'} ]; - if ($scope.$root.notebooks.length > 0) - $scope.notebookDropdown.push({divider: true}); - _.forEach($scope.$root.notebooks, function (notebook) { $scope.notebookDropdown.push({ text: notebook.name, - href: '/sql/' + notebook._id + sref: 'base.sql.notebook({noteId:"' + notebook._id + '"})' }); }); }; http://git-wip-us.apache.org/repos/asf/ignite/blob/54a24746/modules/control-center-web/src/main/js/controllers/sql-controller.js ---------------------------------------------------------------------- diff --git a/modules/control-center-web/src/main/js/controllers/sql-controller.js b/modules/control-center-web/src/main/js/controllers/sql-controller.js index c3a029e..69fbc85 100644 --- a/modules/control-center-web/src/main/js/controllers/sql-controller.js +++ b/modules/control-center-web/src/main/js/controllers/sql-controller.js @@ -17,7 +17,7 @@ // Controller for SQL notebook screen. consoleModule.controller('sqlController', function ($http, $timeout, $interval, $scope, $animate, $location, $anchorScroll, $state, - $modal, $popover, $loading, $common, $confirm, $agentDownload, uiGridExporterConstants) { + $modal, $popover, $loading, $common, $confirm, $agentDownload, QueryNotebooks, uiGridExporterConstants) { $scope.joinTip = $common.joinTip; @@ -56,10 +56,16 @@ consoleModule.controller('sqlController', function ($http, $timeout, $interval, } }; + var _demo = $state.includes('**.sql.demo'); + var _mask = function (cacheName) { return _.isEmpty(cacheName) ? '<default>' : cacheName; }; + var _handleException = function(errMsg) { + $common.showError(errMsg); + }; + // Time line X axis descriptor. var TIME_LINE = {value: -1, type: 'java.sql.Date', label: 'TIME_LINE'}; @@ -245,52 +251,47 @@ consoleModule.controller('sqlController', function ($http, $timeout, $interval, $state.go('/configuration/clusters'); }; - var loadNotebook = function () { - $loading.start('loading'); + var loadNotebook = function (notebook) { + $scope.notebook = notebook; - $http.post('/api/v1/notebooks/get', {noteId: $state.params.id}) - .success(function (notebook) { - $scope.notebook = notebook; + $scope.notebook_name = notebook.name; - $scope.notebook_name = notebook.name; + if (!$scope.notebook.expandedParagraphs) + $scope.notebook.expandedParagraphs = []; - if (!$scope.notebook.expandedParagraphs) - $scope.notebook.expandedParagraphs = []; + if (!$scope.notebook.paragraphs) + $scope.notebook.paragraphs = []; - if (!$scope.notebook.paragraphs) - $scope.notebook.paragraphs = []; + _.forEach(notebook.paragraphs, function (paragraph) { + paragraph.id = 'paragraph-' + paragraphId++; - _.forEach(notebook.paragraphs, function (paragraph) { - paragraph.id = 'paragraph-' + paragraphId++; + enhanceParagraph(paragraph); + }); - enhanceParagraph(paragraph); - }); + if (!notebook.paragraphs || notebook.paragraphs.length == 0) + $scope.addParagraph(); + else + $scope.rebuildScrollParagraphs(); - if (!notebook.paragraphs || notebook.paragraphs.length == 0) - $scope.addParagraph(); - else - $scope.rebuildScrollParagraphs(); + $agentDownload.startTopologyListening(getTopology, _demo); + }; - $agentDownload.startTopologyListening(getTopology); - }) - .error(function () { - $scope.notebook = undefined; - }) - .finally(function () { - $scope.loaded = true; + $loading.start('loading'); - $loading.finish('loading'); - }); - }; + QueryNotebooks.read(_demo, $state.params.noteId) + .then(loadNotebook) + .catch(function(err) { + $scope.notebook = undefined; + }) + .finally(function() { + $scope.loaded = true; - loadNotebook(); + $loading.finish('loading'); + }); - var _saveNotebook = function (f) { - $http.post('/api/v1/notebooks/save', $scope.notebook) - .success(f || function() {}) - .error(function (errMsg) { - $common.showError(errMsg); - }); + var _saveNotebook = function (cb) { + QueryNotebooks.save(_demo, $scope.notebook) + .catch(_handleException); }; $scope.renameNotebook = function (name) { @@ -300,19 +301,21 @@ consoleModule.controller('sqlController', function ($http, $timeout, $interval, if ($scope.notebook.name != name) { $scope.notebook.name = name; - _saveNotebook(function () { - var idx = _.findIndex($scope.$root.notebooks, function (item) { - return item._id == $scope.notebook._id; - }); + QueryNotebooks.save(_demo, $scope.notebook) + .then(function() { + var idx = _.findIndex($scope.$root.notebooks, function (item) { + return item._id == $scope.notebook._id; + }); - if (idx >= 0) { - $scope.$root.notebooks[idx].name = name; + if (idx >= 0) { + $scope.$root.notebooks[idx].name = name; - $scope.$root.rebuildDropdown(); - } + $scope.$root.rebuildDropdown(); + } - $scope.notebook.edit = false; - }); + $scope.notebook.edit = false; + }) + .catch(_handleException); } else $scope.notebook.edit = false @@ -353,7 +356,9 @@ consoleModule.controller('sqlController', function ($http, $timeout, $interval, $scope.rebuildScrollParagraphs(); - _saveNotebook(function () { paragraph.edit = false; }); + QueryNotebooks.save(_demo, $scope.notebook) + .then(function () { paragraph.edit = false; }) + .catch(_handleException); } else paragraph.edit = false @@ -365,7 +370,6 @@ consoleModule.controller('sqlController', function ($http, $timeout, $interval, var paragraph = { id: 'paragraph-' + paragraphId++, name: 'Query' + (sz ==0 ? '' : sz), - editor: true, query: '', pageSize: $scope.pageSizes[0], timeLineSpan: $scope.timeLineSpans[0], @@ -431,7 +435,8 @@ consoleModule.controller('sqlController', function ($http, $timeout, $interval, $scope.rebuildScrollParagraphs(); - _saveNotebook(); + QueryNotebooks.save(_demo, $scope.notebook) + .catch(_handleException); }); }; @@ -683,7 +688,8 @@ consoleModule.controller('sqlController', function ($http, $timeout, $interval, }; $scope.execute = function (paragraph) { - _saveNotebook(); + QueryNotebooks.save(_demo, $scope.notebook) + .catch(_handleException); paragraph.prevQuery = paragraph.queryArgs ? paragraph.queryArgs.query : paragraph.query; @@ -692,6 +698,7 @@ consoleModule.controller('sqlController', function ($http, $timeout, $interval, _tryCloseQueryResult(paragraph.queryId); paragraph.queryArgs = { + demo: _demo, type: "QUERY", query: paragraph.query, pageSize: paragraph.pageSize, @@ -720,7 +727,8 @@ consoleModule.controller('sqlController', function ($http, $timeout, $interval, }; $scope.explain = function (paragraph) { - _saveNotebook(); + QueryNotebooks.save(_demo, $scope.notebook) + .catch(_handleException); _cancelRefresh(paragraph); @@ -729,6 +737,7 @@ consoleModule.controller('sqlController', function ($http, $timeout, $interval, _tryCloseQueryResult(paragraph.queryId); paragraph.queryArgs = { + demo: _demo, type: "EXPLAIN", query: 'EXPLAIN ' + paragraph.query, pageSize: paragraph.pageSize, @@ -747,7 +756,8 @@ consoleModule.controller('sqlController', function ($http, $timeout, $interval, }; $scope.scan = function (paragraph) { - _saveNotebook(); + QueryNotebooks.save(_demo, $scope.notebook) + .catch(_handleException); _cancelRefresh(paragraph); @@ -756,6 +766,7 @@ consoleModule.controller('sqlController', function ($http, $timeout, $interval, _tryCloseQueryResult(paragraph.queryId); paragraph.queryArgs = { + demo: _demo, type: "SCAN", pageSize: paragraph.pageSize, cacheName: paragraph.cacheName || undefined @@ -775,7 +786,7 @@ consoleModule.controller('sqlController', function ($http, $timeout, $interval, $scope.nextPage = function(paragraph) { _showLoading(paragraph, true); - $http.post('/api/v1/agent/query/fetch', {queryId: paragraph.queryId, pageSize: paragraph.pageSize, cacheName: paragraph.queryArgs.cacheName}) + $http.post('/api/v1/agent/query/fetch', {demo: _demo, queryId: paragraph.queryId, pageSize: paragraph.pageSize, cacheName: paragraph.queryArgs.cacheName}) .success(function (res) { paragraph.page++; @@ -862,7 +873,7 @@ consoleModule.controller('sqlController', function ($http, $timeout, $interval, }; $scope.exportCsvAll = function(paragraph) { - $http.post('/api/v1/agent/query/getAll', {query: paragraph.query, cacheName: paragraph.cacheName}) + $http.post('/api/v1/agent/query/getAll', {demo: _demo, query: paragraph.query, cacheName: paragraph.cacheName}) .success(function (item) { _export(paragraph.name + '-all.csv', item.meta, item.rows); }) @@ -1463,7 +1474,7 @@ consoleModule.controller('sqlController', function ($http, $timeout, $interval, $scope.metadata = []; - $http.post('/api/v1/agent/cache/metadata') + $http.post('/api/v1/agent/cache/metadata', {demo: _demo}) .success(function (metadata) { $scope.metadata = _.sortBy(metadata, _.filter(metadata, function (meta) { var cacheName = _mask(meta.cacheName); http://git-wip-us.apache.org/repos/asf/ignite/blob/54a24746/modules/control-center-web/src/main/js/gulpfile.js/tasks/copy.js ---------------------------------------------------------------------- diff --git a/modules/control-center-web/src/main/js/gulpfile.js/tasks/copy.js b/modules/control-center-web/src/main/js/gulpfile.js/tasks/copy.js index 0f05f32..c1dbb21 100644 --- a/modules/control-center-web/src/main/js/gulpfile.js/tasks/copy.js +++ b/modules/control-center-web/src/main/js/gulpfile.js/tasks/copy.js @@ -40,7 +40,7 @@ var legacyPaths = [ './helpers/*.js', './helpers/**/*.js', './public/**/*.png', - './public/*.png' + './public/*.ico' ]; var igniteModulePaths = [ http://git-wip-us.apache.org/repos/asf/ignite/blob/54a24746/modules/control-center-web/src/main/js/routes/agent.js ---------------------------------------------------------------------- diff --git a/modules/control-center-web/src/main/js/routes/agent.js b/modules/control-center-web/src/main/js/routes/agent.js index 12f8f01..9229a3f 100644 --- a/modules/control-center-web/src/main/js/routes/agent.js +++ b/modules/control-center-web/src/main/js/routes/agent.js @@ -67,7 +67,7 @@ router.get('/download/zip', function (req, res) { zip.file(agentFld + '/default.properties', prop.join('\n')); - var buffer = zip.generate({type:"nodebuffer", platform: "UNIX"}); + var buffer = zip.generate({type: 'nodebuffer', platform: 'UNIX'}); // Set the archive name. res.attachment(agentZip); @@ -81,7 +81,7 @@ router.post('/topology', function (req, res) { var client = _client(req, res); if (client) { - client.ignite().cluster(req.body.attr, req.body.mtr).then( + client.ignite(req.body.demo).cluster(req.body.attr, req.body.mtr).then( function (clusters) { res.json(clusters); }, @@ -105,7 +105,7 @@ router.post('/query', function (req, res) { qry.setPageSize(req.body.pageSize); // Get query cursor. - client.ignite().cache(req.body.cacheName).query(qry).nextPage().then(function (cursor) { + client.ignite(req.body.demo).cache(req.body.cacheName).query(qry).nextPage().then(function (cursor) { res.json({meta: cursor.fieldsMetadata(), rows: cursor.page(), queryId: cursor.queryId()}); }, function (err) { res.status(500).send(err); @@ -125,7 +125,7 @@ router.post('/query/getAll', function (req, res) { qry.setPageSize(1024); // Get query cursor. - var cursor = client.ignite().cache(req.body.cacheName).query(qry); + var cursor = client.ignite(req.body.demo).cache(req.body.cacheName).query(qry); cursor.getAll().then(function (rows) { res.json({meta: cursor.fieldsMetadata(), rows: rows}); @@ -147,7 +147,7 @@ router.post('/scan', function (req, res) { qry.setPageSize(req.body.pageSize); // Get query cursor. - client.ignite().cache(req.body.cacheName).query(qry).nextPage().then(function (cursor) { + client.ignite(req.body.demo).cache(req.body.cacheName).query(qry).nextPage().then(function (cursor) { res.json({meta: cursor.fieldsMetadata(), rows: cursor.page(), queryId: cursor.queryId()}); }, function (err) { res.status(500).send(err); @@ -160,7 +160,7 @@ router.post('/query/fetch', function (req, res) { var client = _client(req, res); if (client) { - var cache = client.ignite().cache(req.body.cacheName); + var cache = client.ignite(req.body.demo).cache(req.body.cacheName); var cmd = cache._createCommand('qryfetch').addParam('qryId', req.body.queryId). addParam('pageSize', req.body.pageSize); @@ -178,7 +178,7 @@ router.post('/query/close', function (req, res) { var client = _client(req, res); if (client) { - var cache = client.ignite().cache(req.body.cacheName); + var cache = client.ignite(req.body.demo).cache(req.body.cacheName); var cmd = cache._createCommand('qrycls').addParam('qryId', req.body.queryId); @@ -195,7 +195,7 @@ router.post('/cache/metadata', function (req, res) { var client = _client(req, res); if (client) { - client.ignite().cache(req.body.cacheName).metadata().then(function (caches) { + client.ignite(req.body.demo).cache(req.body.cacheName).metadata().then(function (caches) { var types = []; for (var meta of caches) { @@ -275,9 +275,12 @@ router.post('/demo/sql/start', function (req, res) { if (client) { client.startDemoSQL(function (err, enabled) { if (err) - return res.status(500).send(err); + return res.status(500).send(err.message); + + if (!enabled) + return res.status(500).send('Failed to start SQL demo'); - res.status(200).send(enabled); + res.sendStatus(200); }); } }); http://git-wip-us.apache.org/repos/asf/ignite/blob/54a24746/modules/control-center-web/src/main/js/routes/notebooks.js ---------------------------------------------------------------------- diff --git a/modules/control-center-web/src/main/js/routes/notebooks.js b/modules/control-center-web/src/main/js/routes/notebooks.js index 6dd02c2..93defd4 100644 --- a/modules/control-center-web/src/main/js/routes/notebooks.js +++ b/modules/control-center-web/src/main/js/routes/notebooks.js @@ -68,8 +68,8 @@ router.post('/get', function (req, res) { // Get all metadata for spaces. db.Notebook.findOne({space: {$in: space_ids}, _id: req.body.noteId}).exec(function (err, notebook) { - if (err || notebook == null) - return res.sendStatus(500); + if (err) + return res.status(500).send(err.message); res.json(notebook); }); http://git-wip-us.apache.org/repos/asf/ignite/blob/54a24746/modules/control-center-web/src/main/js/views/templates/agent-download.jade ---------------------------------------------------------------------- diff --git a/modules/control-center-web/src/main/js/views/templates/agent-download.jade b/modules/control-center-web/src/main/js/views/templates/agent-download.jade index 8ece589..d2a1442 100644 --- a/modules/control-center-web/src/main/js/views/templates/agent-download.jade +++ b/modules/control-center-web/src/main/js/views/templates/agent-download.jade @@ -51,5 +51,4 @@ | in agent folder for more information .modal-footer button.btn.btn-default(ng-click='back()') {{::backText}} - button.btn.btn-primary(ng-if='nodeFailedConnection' ng-click='startDemoSQL()') Start demo button.btn.btn-primary(ng-if='!nodeFailedConnection' ng-click='downloadAgent()') Download zip
