Repository: ignite Updated Branches: refs/heads/ignite-3199-1 73f8e2701 -> 5ebe43edd
http://git-wip-us.apache.org/repos/asf/ignite/blob/6af6560a/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/handlers/RestHandler.java ---------------------------------------------------------------------- diff --git a/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/handlers/RestHandler.java b/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/handlers/RestHandler.java new file mode 100644 index 0000000..1b4b565 --- /dev/null +++ b/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/handlers/RestHandler.java @@ -0,0 +1,276 @@ +/* + * 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.handlers; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.net.ConnectException; +import java.net.URISyntaxException; +import java.nio.charset.Charset; +import java.util.List; +import java.util.Map; +import org.apache.commons.codec.Charsets; +import org.apache.http.Header; +import org.apache.http.NameValuePair; +import org.apache.http.client.entity.UrlEncodedFormEntity; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.client.methods.HttpRequestBase; +import org.apache.http.client.utils.URIBuilder; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClientBuilder; +import org.apache.ignite.console.agent.AgentConfiguration; +import org.apache.ignite.console.demo.AgentClusterDemo; +import org.apache.log4j.Logger; + +import static org.apache.ignite.console.agent.AgentConfiguration.DFLT_NODE_PORT; + +/** + * API to translate REST requests to Ignite cluster. + */ +public class RestHandler extends AbstractHandler { + /** */ + private static final Logger log = Logger.getLogger(RestHandler.class.getName()); + + /** */ + private final AgentConfiguration cfg; + + /** */ + private CloseableHttpClient httpClient; + + /** + * @param cfg Config. + */ + public RestHandler(AgentConfiguration cfg) { + this.cfg = cfg; + } + + /** + * Start HTTP client for communication with node via REST. + */ + public void start() { + httpClient = HttpClientBuilder.create().build(); + } + + /** + * Stop HTTP client. + */ + public void stop() { + if (httpClient != null) { + try { + httpClient.close(); + } + catch (IOException ignore) { + // No-op. + } + } + } + + /** {@inheritDoc} */ + @SuppressWarnings("unchecked") + @Override public Object execute(Map<String, Object> args) throws Exception { + if (log.isDebugEnabled()) + log.debug("Start parse REST command args: " + args); + + String uri = null; + + if (args.containsKey("uri")) + uri = args.get("uri").toString(); + + Map<String, Object> params = null; + + if (args.containsKey("params")) + params = (Map<String, Object>)args.get("params"); + + if (!args.containsKey("demo")) + throw new IllegalArgumentException("Missing demo flag in arguments: " + args); + + boolean demo = (boolean)args.get("demo"); + + if (!args.containsKey("method")) + throw new IllegalArgumentException("Missing method in arguments: " + args); + + String mtd = args.get("method").toString(); + + Map<String, Object> headers = null; + + if (args.containsKey("headers")) + headers = (Map<String, Object>)args.get("headers"); + + String body = null; + + if (args.containsKey("body")) + body = args.get("body").toString(); + + return executeRest(uri, params, demo, mtd, headers, body); + } + + /** + * @param uri Url. + * @param params Params. + * @param demo Use demo node. + * @param mtd Method. + * @param headers Headers. + * @param body Body. + */ + protected RestResult executeRest(String uri, Map<String, Object> params, boolean demo, + String mtd, Map<String, Object> headers, String body) throws IOException, URISyntaxException { + if (log.isDebugEnabled()) + log.debug("Start execute REST command [method=" + mtd + ", uri=/" + (uri == null ? "" : uri) + + ", parameters=" + params + "]"); + + final URIBuilder builder; + + if (demo) { + // try start demo if needed. + AgentClusterDemo.testDrive(cfg); + + // null if demo node not started yet. + if (cfg.demoNodeUri() == null) + return RestResult.fail("Demo node is not started yet.", 404); + + builder = new URIBuilder(cfg.demoNodeUri()); + } + else + builder = new URIBuilder(cfg.nodeUri()); + + if (builder.getPort() == -1) + builder.setPort(DFLT_NODE_PORT); + + if (uri != null) { + if (!uri.startsWith("/") && !cfg.nodeUri().endsWith("/")) + uri = '/' + uri; + + builder.setPath(uri); + } + + if (params != null) { + for (Map.Entry<String, Object> entry : params.entrySet()) { + if (entry.getValue() != null) + builder.addParameter(entry.getKey(), entry.getValue().toString()); + } + } + + HttpRequestBase httpReq = null; + + try { + if ("GET".equalsIgnoreCase(mtd)) + httpReq = new HttpGet(builder.build()); + else if ("POST".equalsIgnoreCase(mtd)) { + HttpPost post; + + if (body == null) { + List<NameValuePair> nvps = builder.getQueryParams(); + + builder.clearParameters(); + + post = new HttpPost(builder.build()); + + if (!nvps.isEmpty()) + post.setEntity(new UrlEncodedFormEntity(nvps)); + } + else { + post = new HttpPost(builder.build()); + + post.setEntity(new StringEntity(body)); + } + + httpReq = post; + } + else + throw new IOException("Unknown HTTP-method: " + mtd); + + if (headers != null) { + for (Map.Entry<String, Object> entry : headers.entrySet()) + httpReq.addHeader(entry.getKey(), entry.getValue() == null ? null : entry.getValue().toString()); + } + + try (CloseableHttpResponse resp = httpClient.execute(httpReq)) { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + + resp.getEntity().writeTo(out); + + Charset charset = Charsets.UTF_8; + + Header encodingHdr = resp.getEntity().getContentEncoding(); + + if (encodingHdr != null) { + String encoding = encodingHdr.getValue(); + + charset = Charsets.toCharset(encoding); + } + + return RestResult.success(resp.getStatusLine().getStatusCode(), new String(out.toByteArray(), charset)); + } + catch (ConnectException e) { + log.info("Failed connect to node and execute REST command [uri=" + builder.build() + "]"); + + return RestResult.fail("Failed connect to node and execute REST command.", 404); + } + } + finally { + if (httpReq != null) + httpReq.reset(); + } + } + + /** + * Request result. + */ + public static class RestResult { + /** The field contains description of error if server could not handle the request. */ + public final String error; + + /** REST http code. */ + public final int code; + + /** The field contains result of command. */ + public final String data; + + /** + * @param error The field contains description of error if server could not handle the request. + * @param resCode REST http code. + * @param res The field contains result of command. + */ + private RestResult(String error, int resCode, String res) { + this.error = error; + this.code = resCode; + this.data = res; + } + + /** + * @param error The field contains description of error if server could not handle the request. + * @param restCode REST http code. + * @return Request result. + */ + public static RestResult fail(String error, int restCode) { + return new RestResult(error, restCode, null); + } + + /** + * @param code REST http code. + * @param data The field contains result of command. + * @return Request result. + */ + public static RestResult success(int code, String data) { + return new RestResult(null, code, data); + } + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/6af6560a/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/demo/AgentClusterDemo.java ---------------------------------------------------------------------- diff --git a/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/demo/AgentClusterDemo.java b/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/demo/AgentClusterDemo.java new file mode 100644 index 0000000..09189b5 --- /dev/null +++ b/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/demo/AgentClusterDemo.java @@ -0,0 +1,641 @@ +/* + * 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.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.Random; +import java.util.Set; +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.cache.CacheAtomicityMode; +import org.apache.ignite.cache.QueryEntity; +import org.apache.ignite.cache.QueryIndex; +import org.apache.ignite.cache.QueryIndexType; +import org.apache.ignite.cache.affinity.rendezvous.RendezvousAffinityFunction; +import org.apache.ignite.configuration.CacheConfiguration; +import org.apache.ignite.configuration.IgniteConfiguration; +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.internal.IgniteEx; +import org.apache.ignite.internal.util.typedef.F; +import org.apache.ignite.logger.log4j.Log4JLogger; +import org.apache.ignite.spi.communication.tcp.TcpCommunicationSpi; +import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi; +import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder; +import org.apache.ignite.spi.swapspace.file.FileSwapSpaceSpi; +import org.apache.ignite.transactions.Transaction; +import org.apache.log4j.Logger; + +import static org.apache.ignite.IgniteSystemProperties.IGNITE_ATOMIC_CACHE_DELETE_HISTORY_SIZE; +import static org.apache.ignite.IgniteSystemProperties.IGNITE_PERFORMANCE_SUGGESTIONS_DISABLED; +import static org.apache.ignite.IgniteSystemProperties.IGNITE_UPDATE_NOTIFIER; +import static org.apache.ignite.IgniteSystemProperties.IGNITE_JETTY_PORT; +import static org.apache.ignite.IgniteSystemProperties.IGNITE_NO_ASCII; +import static org.apache.ignite.events.EventType.EVTS_DISCOVERY; +import static org.apache.ignite.internal.IgniteNodeAttributes.ATTR_REST_JETTY_ADDRS; +import static org.apache.ignite.internal.IgniteNodeAttributes.ATTR_REST_JETTY_PORT; +import static org.apache.ignite.transactions.TransactionConcurrency.PESSIMISTIC; +import static org.apache.ignite.transactions.TransactionIsolation.REPEATABLE_READ; + +/** + * Demo for cluster features like SQL and Monitoring. + * + * Cache will be created and populated with data to query. + */ +public class AgentClusterDemo { + /** */ + private static final Logger log = Logger.getLogger(AgentClusterDemo.class.getName()); + + /** */ + private static final AtomicBoolean initLatch = new AtomicBoolean(); + + /** */ + private static final int NODE_CNT = 3; + + /** */ + 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 Set<String> DEMO_CACHES = new HashSet<>(Arrays.asList(COUNTRY_CACHE_NAME, + DEPARTMENT_CACHE_NAME, EMPLOYEE_CACHE_NAME, PARKING_CACHE_NAME, CAR_CACHE_NAME)); + + /** */ + 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); + + /** + * Create base cache configuration. + * + * @param name cache name. + * @return Cache configuration with basic properties set. + */ + private static <K, V> CacheConfiguration<K, V> cacheConfiguration(String name) { + CacheConfiguration<K, V> ccfg = new CacheConfiguration<>(name); + + ccfg.setAffinity(new RendezvousAffinityFunction(false, 32)); + ccfg.setStartSize(100); + ccfg.setStatisticsEnabled(true); + + return ccfg; + } + + /** + * Configure cacheCountry. + */ + private static <K, V> CacheConfiguration<K, V> cacheCountry() { + CacheConfiguration<K, V> ccfg = cacheConfiguration(COUNTRY_CACHE_NAME); + + // Configure cacheCountry types. + Collection<QueryEntity> qryEntities = new ArrayList<>(); + + // COUNTRY. + QueryEntity type = new QueryEntity(); + + qryEntities.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); + + ccfg.setQueryEntities(qryEntities); + + return ccfg; + } + + /** + * Configure cacheEmployee. + */ + private static <K, V> CacheConfiguration<K, V> cacheDepartment() { + CacheConfiguration<K, V> ccfg = cacheConfiguration(DEPARTMENT_CACHE_NAME); + + // Configure cacheDepartment types. + Collection<QueryEntity> qryEntities = new ArrayList<>(); + + // DEPARTMENT. + QueryEntity type = new QueryEntity(); + + qryEntities.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); + + ccfg.setQueryEntities(qryEntities); + + return ccfg; + } + + /** + * Configure cacheEmployee. + */ + private static <K, V> CacheConfiguration<K, V> cacheEmployee() { + CacheConfiguration<K, V> ccfg = cacheConfiguration(EMPLOYEE_CACHE_NAME); + + ccfg.setAtomicityMode(CacheAtomicityMode.TRANSACTIONAL); + ccfg.setBackups(1); + + // Configure cacheEmployee types. + Collection<QueryEntity> qryEntities = new ArrayList<>(); + + // EMPLOYEE. + QueryEntity type = new QueryEntity(); + + qryEntities.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<>(); + + QueryIndex idx = new QueryIndex(); + + idx.setName("EMP_NAMES"); + idx.setIndexType(QueryIndexType.SORTED); + LinkedHashMap<String, Boolean> indFlds = new LinkedHashMap<>(); + + indFlds.put("firstName", Boolean.FALSE); + indFlds.put("lastName", Boolean.FALSE); + + idx.setFields(indFlds); + + indexes.add(idx); + indexes.add(new QueryIndex("salary", QueryIndexType.SORTED, false, "EMP_SALARY")); + + type.setIndexes(indexes); + + ccfg.setQueryEntities(qryEntities); + + return ccfg; + } + + /** + * Configure cacheEmployee. + */ + private static <K, V> CacheConfiguration<K, V> cacheParking() { + CacheConfiguration<K, V> ccfg = cacheConfiguration(PARKING_CACHE_NAME); + + // Configure cacheParking types. + Collection<QueryEntity> qryEntities = new ArrayList<>(); + + // PARKING. + QueryEntity type = new QueryEntity(); + + qryEntities.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); + + ccfg.setQueryEntities(qryEntities); + + return ccfg; + } + + /** + * Configure cacheEmployee. + */ + private static <K, V> CacheConfiguration<K, V> cacheCar() { + CacheConfiguration<K, V> ccfg = cacheConfiguration(CAR_CACHE_NAME); + + // Configure cacheCar types. + Collection<QueryEntity> qryEntities = new ArrayList<>(); + + // CAR. + QueryEntity type = new QueryEntity(); + + qryEntities.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); + + ccfg.setQueryEntities(qryEntities); + + return ccfg; + } + + /** + * Configure node. + * @param gridIdx Grid name index. + * @param client If {@code true} then start client node. + * @return IgniteConfiguration + */ + private static IgniteConfiguration igniteConfiguration(int gridIdx, boolean client) { + IgniteConfiguration cfg = new IgniteConfiguration(); + + cfg.setGridName((client ? "demo-server-" : "demo-client-") + gridIdx); + cfg.setLocalHost("127.0.0.1"); + cfg.setIncludeEventTypes(EVTS_DISCOVERY); + + TcpDiscoveryVmIpFinder ipFinder = new TcpDiscoveryVmIpFinder(); + + ipFinder.setAddresses(Collections.singletonList("127.0.0.1:60900.." + (60900 + NODE_CNT - 1))); + + // Configure discovery SPI. + TcpDiscoverySpi discoSpi = new TcpDiscoverySpi(); + + discoSpi.setLocalPort(60900); + discoSpi.setIpFinder(ipFinder); + + cfg.setDiscoverySpi(discoSpi); + + TcpCommunicationSpi commSpi = new TcpCommunicationSpi(); + + commSpi.setSharedMemoryPort(-1); + commSpi.setLocalPort(60800); + + cfg.setCommunicationSpi(commSpi); + cfg.setGridLogger(new Log4JLogger(log)); + cfg.setMetricsLogFrequency(0); + cfg.getConnectorConfiguration().setPort(60700); + + if (client) + cfg.setClientMode(true); + + cfg.setCacheConfiguration(cacheCountry(), cacheDepartment(), cacheEmployee(), cacheParking(), cacheCar()); + + cfg.setSwapSpaceSpi(new FileSwapSpaceSpi()); + + return cfg; + } + + /** + * @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) { + if (log.isDebugEnabled()) + log.debug("DEMO: Start employees population with data..."); + + IgniteCache<Integer, Country> cacheCountry = ignite.cache(COUNTRY_CACHE_NAME); + + for (int i = 0, n = 1; i < CNTR_CNT; i++, n++) + 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 = 1; i < DEP_CNT; i++, n++) { + 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 = 1; i < EMPL_CNT; i++, n++) { + 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))); + } + + if (log.isDebugEnabled()) + log.debug("DEMO: Finished employees population."); + } + + /** + * @param ignite Ignite. + */ + private static void populateCacheCar(Ignite ignite) { + if (log.isDebugEnabled()) + log.debug("DEMO: Start cars population..."); + + IgniteCache<Integer, Parking> cacheParking = ignite.cache(PARKING_CACHE_NAME); + + for (int i = 0, n = 1; i < PARK_CNT; i++, n++) + cacheParking.put(i, new Parking(i, "Parking #" + n, n * 10)); + + IgniteCache<Integer, Car> cacheCar = ignite.cache(CAR_CACHE_NAME); + + for (int i = 0, n = 1; i < CAR_CNT; i++, n++) + cacheCar.put(i, new Car(i, rnd.nextInt(PARK_CNT), "Car #" + n)); + + if (log.isDebugEnabled()) + log.debug("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 { + for (String cacheName : ignite.cacheNames()) { + if (!DEMO_CACHES.contains(cacheName)) { + IgniteCache<Integer, String> otherCache = ignite.cache(cacheName); + + if (otherCache != null) { + for (int i = 0, n = 1; i < cnt; i++, n++) { + Integer key = rnd.nextInt(1000); + + String val = otherCache.get(key); + + if (val == null) + otherCache.put(key, "other-" + key); + else if (rnd.nextInt(100) < 30) + otherCache.remove(key); + } + } + } + } + + IgniteCache<Integer, Employee> cacheEmployee = ignite.cache(EMPLOYEE_CACHE_NAME); + + if (cacheEmployee != null) + try(Transaction tx = ignite.transactions().txStart(PESSIMISTIC, REPEATABLE_READ)) { + for (int i = 0, n = 1; i < cnt; i++, n++) { + 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)); + + cacheEmployee.get(rnd.nextInt(EMPL_CNT)); + } + + if (rnd.nextInt(100) > 20) + tx.commit(); + } + } + 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 nodes for demo..."); + + System.setProperty(IGNITE_ATOMIC_CACHE_DELETE_HISTORY_SIZE, "1"); + System.setProperty(IGNITE_PERFORMANCE_SUGGESTIONS_DISABLED, "true"); + System.setProperty(IGNITE_UPDATE_NOTIFIER, "false"); + + System.setProperty(IGNITE_JETTY_PORT, "60800"); + System.setProperty(IGNITE_NO_ASCII, "true"); + + try { + IgniteEx ignite = (IgniteEx)Ignition.start(igniteConfiguration(0, false)); + + final AtomicInteger cnt = new AtomicInteger(0); + + final ScheduledExecutorService execSrv = Executors.newSingleThreadScheduledExecutor(); + + execSrv.scheduleAtFixedRate(new Runnable() { + @Override public void run() { + int idx = cnt.incrementAndGet(); + + try { + Ignition.start(igniteConfiguration(idx, idx == NODE_CNT)); + } + catch (Throwable e) { + log.error("DEMO: Failed to start embedded node: " + e.getMessage()); + } + finally { + if (idx == NODE_CNT) + execSrv.shutdown(); + } + } + }, 10, 10, TimeUnit.SECONDS); + + if (log.isDebugEnabled()) + log.debug("DEMO: Started embedded nodes with indexed enabled caches..."); + + Collection<String> jettyAddrs = ignite.localNode().attribute(ATTR_REST_JETTY_ADDRS); + + String host = jettyAddrs == null ? null : jettyAddrs.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 nodes for sql and monitoring demo successfully started"); + + startLoad(ignite, 20); + } + catch (Exception e) { + log.error("DEMO: Failed to start embedded node for sql and monitoring demo!", e); + + return false; + } + } + + return true; + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/6af6560a/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/demo/AgentMetadataDemo.java ---------------------------------------------------------------------- diff --git a/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/demo/AgentMetadataDemo.java b/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/demo/AgentMetadataDemo.java new file mode 100644 index 0000000..4683dd8 --- /dev/null +++ b/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/demo/AgentMetadataDemo.java @@ -0,0 +1,92 @@ +/* + * 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.FileNotFoundException; +import java.io.FileReader; +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.SQLException; +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 Connection testDrive() throws SQLException { + 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"); + + //noinspection ConstantConditions + 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 (SQLException e) { + log.error("DEMO: Failed to start test drive for metadata!", e); + + throw e; + } + catch (FileNotFoundException | NullPointerException e) { + log.error("DEMO: Failed to find demo database init script file: demo/db-init.sql"); + + throw new SQLException("Failed to start demo for metadata", e); + } + } + + return DriverManager.getConnection("jdbc:h2:mem:demo-db;DB_CLOSE_DELAY=-1", "sa", ""); + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/6af6560a/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/demo/model/Car.java ---------------------------------------------------------------------- diff --git a/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/demo/model/Car.java b/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/demo/model/Car.java new file mode 100644 index 0000000..f351efc --- /dev/null +++ b/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/demo/model/Car.java @@ -0,0 +1,152 @@ +/* + * 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.model; + +import java.io.Serializable; + +/** + * Car definition. + */ +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 + + ']'; + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/6af6560a/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/demo/model/Country.java ---------------------------------------------------------------------- diff --git a/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/demo/model/Country.java b/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/demo/model/Country.java new file mode 100644 index 0000000..348928b --- /dev/null +++ b/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/demo/model/Country.java @@ -0,0 +1,152 @@ +/* + * 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.model; + +import java.io.Serializable; + +/** + * Country definition. + */ +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 + + ']'; + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/6af6560a/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/demo/model/Department.java ---------------------------------------------------------------------- diff --git a/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/demo/model/Department.java b/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/demo/model/Department.java new file mode 100644 index 0000000..1c2f3b2 --- /dev/null +++ b/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/demo/model/Department.java @@ -0,0 +1,152 @@ +/* + * 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.model; + +import java.io.Serializable; + +/** + * Department definition. + */ +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 + + ']'; + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/6af6560a/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/demo/model/Employee.java ---------------------------------------------------------------------- diff --git a/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/demo/model/Employee.java b/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/demo/model/Employee.java new file mode 100644 index 0000000..a3e7eba --- /dev/null +++ b/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/demo/model/Employee.java @@ -0,0 +1,356 @@ +/* + * 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.model; + +import java.io.Serializable; +import java.sql.Date; + +/** + * Employee definition. + */ +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 + + ']'; + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/6af6560a/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/demo/model/Parking.java ---------------------------------------------------------------------- diff --git a/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/demo/model/Parking.java b/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/demo/model/Parking.java new file mode 100644 index 0000000..d55ae81 --- /dev/null +++ b/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/demo/model/Parking.java @@ -0,0 +1,152 @@ +/* + * 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.model; + +import java.io.Serializable; + +/** + * Parking definition. + */ +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 + + ']'; + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/6af6560a/modules/web-console/web-agent/src/main/resources/log4j.properties ---------------------------------------------------------------------- diff --git a/modules/web-console/web-agent/src/main/resources/log4j.properties b/modules/web-console/web-agent/src/main/resources/log4j.properties new file mode 100644 index 0000000..3b7767c --- /dev/null +++ b/modules/web-console/web-agent/src/main/resources/log4j.properties @@ -0,0 +1,53 @@ +# 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. + +log4j.rootLogger=INFO,console_err,file + +log4j.logger.org.apache.http=WARN +log4j.logger.org.apache.ignite.spi.checkpoint.noop.NoopCheckpointSpi=OFF +log4j.logger.org.apache.ignite.spi.swapspace.noop.NoopSwapSpaceSpi=OFF +log4j.logger.org.apache.ignite.internal.managers.collision.GridCollisionManager=ERROR +log4j.logger.org.apache.commons.beanutils=WARN +log4j.logger.sun.net.www.protocol.http=WARN + +# Configure console appender. +log4j.appender.console_err=org.apache.log4j.ConsoleAppender +log4j.appender.console_err.Threshold=WARN +log4j.appender.console_err.layout=org.apache.log4j.PatternLayout +log4j.appender.console_err.layout.ConversionPattern=[%d{ABSOLUTE}][%-5p][%t][%c{1}] %m%n + +# Configure console appender. +log4j.appender.console=org.apache.log4j.ConsoleAppender +log4j.appender.console.layout=org.apache.log4j.PatternLayout +log4j.appender.console.layout.ConversionPattern=[%d{ABSOLUTE}][%-5p][%t][%c{1}] %m%n +log4j.appender.console.filter.a=org.apache.log4j.varia.LevelMatchFilter +log4j.appender.console.filter.a.LevelToMatch=INFO +log4j.appender.console.filter.a.AcceptOnMatch=true +log4j.appender.console.filter.b=org.apache.log4j.varia.LevelMatchFilter +log4j.appender.console.filter.b.LevelToMatch=ERROR +log4j.appender.console.filter.b.AcceptOnMatch=false +log4j.appender.console.filter.c=org.apache.log4j.varia.LevelMatchFilter +log4j.appender.console.filter.c.LevelToMatch=WARN +log4j.appender.console.filter.c.AcceptOnMatch=false + +log4j.category.org.apache.ignite.console=INFO,console + +# Direct log messages to a log file +log4j.appender.file=org.apache.log4j.RollingFileAppender +log4j.appender.file.File=logs/ignite-web-agent.log +log4j.appender.file.MaxFileSize=10MB +log4j.appender.file.MaxBackupIndex=10 +log4j.appender.file.layout=org.apache.log4j.PatternLayout +log4j.appender.file.layout.ConversionPattern=[%d{ABSOLUTE}][%-5p][%t][%c{1}] %m%n http://git-wip-us.apache.org/repos/asf/ignite/blob/6af6560a/pom.xml ---------------------------------------------------------------------- diff --git a/pom.xml b/pom.xml index 2c7bad1..070b5c8 100644 --- a/pom.xml +++ b/pom.xml @@ -798,8 +798,8 @@ <profile> <id>web-console</id> <modules> - <module>modules/web-agent</module> <module>modules/web-console</module> + <module>modules/web-console/web-agent</module> <module>modules/schema-import-db</module> </modules> </profile>
