You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by an...@apache.org on 2016/03/28 10:47:49 UTC
[09/50] [abbrv] ignite git commit: IGNITE-2597 Refactored to
websockets.
IGNITE-2597 Refactored to websockets.
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/706317f3
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/706317f3
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/706317f3
Branch: refs/heads/ignite-2875
Commit: 706317f3d12989883a1c199797a74a49670f94aa
Parents: 2cf28fe
Author: Andrey <an...@gridgain.com>
Authored: Fri Mar 18 15:48:01 2016 +0700
Committer: Andrey <an...@gridgain.com>
Committed: Fri Mar 18 15:48:01 2016 +0700
----------------------------------------------------------------------
.../assembly/release-control-center-agent.xml | 7 -
modules/control-center-agent/pom.xml | 45 +-
.../console/agent/AgentConfiguration.java | 31 +-
.../ignite/console/agent/AgentLauncher.java | 235 ++++++++--
.../ignite/console/agent/AgentSocket.java | 190 --------
.../apache/ignite/console/agent/AgentUtils.java | 8 +-
.../console/agent/handlers/AbstractHandler.java | 102 +++++
.../console/agent/handlers/DatabaseHandler.java | 298 +++++++++++++
.../handlers/DatabaseMetadataExtractor.java | 205 ---------
.../console/agent/handlers/RestExecutor.java | 225 ----------
.../console/agent/handlers/RestHandler.java | 274 ++++++++++++
.../ignite/console/agent/remote/Remote.java | 37 --
.../console/agent/remote/RemoteHandler.java | 246 -----------
.../console/agent/remote/WebSocketSender.java | 39 --
.../ignite/console/demo/AgentMetadataDemo.java | 24 +-
.../ignite/console/demo/AgentSqlDemo.java | 101 +++--
.../control-center-web/src/main/js/.eslintrc | 1 +
.../control-center-web/src/main/js/.gitignore | 5 +-
.../src/main/js/app/data/colors.json | 22 +
.../src/main/js/app/decorator/select.js | 55 ++-
.../control-center-web/src/main/js/app/index.js | 37 +-
.../js/app/services/AgentMonitor.service.js | 286 ++++++++++++
.../main/js/app/services/ChartColors.service.js | 22 +
.../main/js/app/services/Countries.service.js | 23 +
.../app/services/Countries/Countries.service.js | 23 -
.../src/main/js/app/services/cleanup.service.js | 62 +++
.../js/app/services/cleanup/cleanup.service.js | 62 ---
.../control-center-web/src/main/js/config.js | 22 +-
.../src/main/js/controllers/common-module.js | 201 +--------
.../main/js/controllers/domains-controller.js | 146 +++----
.../src/main/js/controllers/sql-controller.js | 434 ++++++++++---------
.../src/main/js/gulpfile.js/tasks/bundle.js | 12 +-
.../main/js/gulpfile.js/tasks/inject-plugins.js | 3 +-
.../control-center-web/src/main/js/package.json | 39 +-
modules/control-center-web/src/main/js/serve.js | 28 +-
.../src/main/js/serve/agent.js | 354 +++++++++------
.../src/main/js/serve/agent_dists/README.txt | 7 +
.../control-center-web/src/main/js/serve/app.js | 17 +-
.../src/main/js/serve/config/default.json | 26 --
.../main/js/serve/config/settings.json.sample | 26 ++
.../src/main/js/serve/configure.js | 72 +--
.../control-center-web/src/main/js/serve/io.js | 242 +++++++++++
.../src/main/js/serve/mail.js | 5 +-
.../src/main/js/serve/routes/agent.js | 307 ++-----------
.../src/main/js/serve/routes/profile.js | 15 +-
.../src/main/js/serve/routes/public.js | 64 ++-
.../src/main/js/serve/settings.js | 11 +-
.../src/main/js/views/includes/controls.jade | 2 +-
.../main/js/views/templates/agent-download.jade | 11 +-
.../src/main/js/views/templates/select.jade | 4 +-
.../src/test/js/routes/agent.js | 10 +-
51 files changed, 2462 insertions(+), 2261 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/706317f3/modules/control-center-agent/assembly/release-control-center-agent.xml
----------------------------------------------------------------------
diff --git a/modules/control-center-agent/assembly/release-control-center-agent.xml b/modules/control-center-agent/assembly/release-control-center-agent.xml
index 90a9415..eb7da95 100644
--- a/modules/control-center-agent/assembly/release-control-center-agent.xml
+++ b/modules/control-center-agent/assembly/release-control-center-agent.xml
@@ -28,13 +28,6 @@
<fileSets>
<fileSet>
- <directory>${basedir}/../indexing/target/libs</directory>
- <outputDirectory>/jdbc-drivers</outputDirectory>
- <includes>
- <include>**/h2-*.jar</include>
- </includes>
- </fileSet>
- <fileSet>
<directory>${basedir}</directory>
<outputDirectory>/</outputDirectory>
<includes>
http://git-wip-us.apache.org/repos/asf/ignite/blob/706317f3/modules/control-center-agent/pom.xml
----------------------------------------------------------------------
diff --git a/modules/control-center-agent/pom.xml b/modules/control-center-agent/pom.xml
index 2fe8844..9bee2a2 100644
--- a/modules/control-center-agent/pom.xml
+++ b/modules/control-center-agent/pom.xml
@@ -34,26 +34,20 @@
<version>1.5.0.final-SNAPSHOT</version>
<properties>
- <jetty.version>9.2.12.v20150709</jetty.version>
+ <maven.build.timestamp.format>yyMMddHHmmss</maven.build.timestamp.format>
</properties>
<dependencies>
<dependency>
- <groupId>org.apache.ignite</groupId>
- <artifactId>ignite-schema-import-db</artifactId>
- <version>${project.version}</version>
- </dependency>
-
- <dependency>
- <groupId>org.eclipse.jetty.websocket</groupId>
- <artifactId>websocket-client</artifactId>
- <version>${jetty.version}</version>
+ <groupId>io.socket</groupId>
+ <artifactId>socket.io-client</artifactId>
+ <version>0.7.0</version>
</dependency>
<dependency>
- <groupId>com.google.code.gson</groupId>
- <artifactId>gson</artifactId>
- <version>2.4</version>
+ <groupId>com.fasterxml.jackson.datatype</groupId>
+ <artifactId>jackson-datatype-json-org</artifactId>
+ <version>2.7.1</version>
</dependency>
<dependency>
@@ -65,7 +59,19 @@
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
- <version>4.5</version>
+ <version>${httpclient.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.ignite</groupId>
+ <artifactId>ignite-schema-import-db</artifactId>
+ <version>${project.version}</version>
+ <exclusions>
+ <exclusion>
+ <groupId>org.gridgain</groupId>
+ <artifactId>ignite-shmem</artifactId>
+ </exclusion>
+ </exclusions>
</dependency>
<dependency>
@@ -100,6 +106,9 @@
<manifest>
<mainClass>org.apache.ignite.console.agent.AgentLauncher</mainClass>
</manifest>
+ <manifestEntries>
+ <Build-Time>${maven.build.timestamp}</Build-Time>
+ </manifestEntries>
</archive>
</configuration>
</plugin>
@@ -118,6 +127,14 @@
<configuration>
<createDependencyReducedPom>false</createDependencyReducedPom>
+ <filters>
+ <filter>
+ <artifact>*:*</artifact>
+ <excludes>
+ <exclude>META-INF/maven/**</exclude>
+ </excludes>
+ </filter>
+ </filters>
</configuration>
</execution>
</executions>
http://git-wip-us.apache.org/repos/asf/ignite/blob/706317f3/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/AgentConfiguration.java
----------------------------------------------------------------------
diff --git a/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/AgentConfiguration.java b/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/AgentConfiguration.java
index 7a0faa9..ffd30a5 100644
--- a/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/AgentConfiguration.java
+++ b/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/AgentConfiguration.java
@@ -39,7 +39,7 @@ public class AgentConfiguration {
public static final String DFLT_CFG_PATH = "default.properties";
/** Default server URI. */
- private static final String DFLT_SERVER_URI = "wss://localhost:3001";
+ private static final String DFLT_SERVER_URI = "http://localhost:3001";
/** Default Ignite node HTTP URI. */
private static final String DFLT_NODE_URI = "http://localhost:8080";
@@ -75,9 +75,6 @@ public class AgentConfiguration {
" Default value: ./jdbc-drivers")
private String driversFolder;
- /** Release date. */
- private long relDate;
-
/** */
@Parameter(names = { "-h", "--help" }, help = true, description = "Print this help message")
private Boolean help;
@@ -160,17 +157,10 @@ public class AgentConfiguration {
}
/**
- * @return Release date.
- */
- public long relDate() {
- return relDate;
- }
-
- /**
* @return {@code true} If agent options usage should be printed.
*/
public Boolean help() {
- return help != null ? help : false;
+ return help != null ? help : Boolean.FALSE;
}
/**
@@ -202,17 +192,6 @@ public class AgentConfiguration {
if (val != null)
driversFolder(val);
-
- val = (String)props.remove("rel-date");
-
- if (val != null) {
- try {
- this.relDate = Long.parseLong(val);
- }
- catch (NumberFormatException ignored) {
- // No-op.
- }
- }
}
/**
@@ -236,8 +215,6 @@ public class AgentConfiguration {
if (driversFolder == null)
driversFolder(cmd.driversFolder());
-
- relDate = cmd.relDate();
}
/** {@inheritDoc} */
@@ -248,12 +225,12 @@ public class AgentConfiguration {
sb.append("User's security token : ");
if (tok.length() > 4) {
- sb.append(new String(new char[tok.length() - 4]).replace("\0", "*"));
+ sb.append(new String(new char[tok.length() - 4]).replace('\0', '*'));
sb.append(tok.substring(tok.length() - 4));
}
else
- sb.append(new String(new char[tok.length()]).replace("\0", "*"));
+ sb.append(new String(new char[tok.length()]).replace('\0', '*'));
sb.append('\n');
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/706317f3/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/AgentLauncher.java
----------------------------------------------------------------------
diff --git a/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/AgentLauncher.java b/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/AgentLauncher.java
index ed08d78..cb4bd46 100644
--- a/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/AgentLauncher.java
+++ b/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/AgentLauncher.java
@@ -18,18 +18,39 @@
package org.apache.ignite.console.agent;
import com.beust.jcommander.JCommander;
+import com.beust.jcommander.ParameterException;
+import io.socket.client.Ack;
+import io.socket.client.IO;
+import io.socket.client.Socket;
+import io.socket.emitter.Emitter;
import java.io.File;
import java.io.IOException;
+import java.net.ConnectException;
+import java.net.SocketException;
import java.net.URI;
import java.net.URISyntaxException;
+import java.net.URL;
import java.util.Arrays;
-
-import com.beust.jcommander.ParameterException;
-import org.apache.ignite.console.agent.handlers.RestExecutor;
+import java.util.concurrent.CountDownLatch;
+import java.util.jar.Attributes;
+import java.util.jar.Manifest;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLHandshakeException;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.X509TrustManager;
+import org.apache.ignite.console.agent.handlers.DatabaseHandler;
+import org.apache.ignite.console.agent.handlers.RestHandler;
+import org.apache.ignite.internal.util.typedef.X;
import org.apache.log4j.Logger;
-import org.eclipse.jetty.util.ssl.SslContextFactory;
-import org.eclipse.jetty.websocket.client.WebSocketClient;
-
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import static io.socket.client.Socket.EVENT_CONNECT;
+import static io.socket.client.Socket.EVENT_CONNECTING;
+import static io.socket.client.Socket.EVENT_CONNECT_ERROR;
+import static io.socket.client.Socket.EVENT_DISCONNECT;
+import static io.socket.client.Socket.EVENT_ERROR;
+import static io.socket.client.Socket.EVENT_RECONNECTING;
import static org.apache.ignite.console.agent.AgentConfiguration.DFLT_SERVER_PORT;
/**
@@ -40,16 +61,95 @@ public class AgentLauncher {
private static final Logger log = Logger.getLogger(AgentLauncher.class.getName());
/** */
+ private static final String EVENT_NODE_REST = "node:rest";
+
+ /** */
+ private static final String EVENT_SCHEMA_IMPORT_DRIVERS = "schemaImport:drivers";
+
+ /** */
+ private static final String EVENT_SCHEMA_IMPORT_SCHEMAS = "schemaImport:schemas";
+
+ /** */
+ private static final String EVENT_SCHEMA_IMPORT_METADATA = "schemaImport:metadata";
+
+ /** */
+ private static final String EVENT_AGENT_CLOSE = "agent:close";
+
+ /** */
private static final int RECONNECT_INTERVAL = 3000;
/**
+ * Create a trust manager that trusts all certificates It is not using a particular keyStore
+ */
+ private static TrustManager[] getTrustManagers() {
+ return new TrustManager[] {
+ new X509TrustManager() {
+ public java.security.cert.X509Certificate[] getAcceptedIssuers() {
+ return null;
+ }
+
+ public void checkClientTrusted(
+ java.security.cert.X509Certificate[] certs, String authType) {
+ }
+
+ public void checkServerTrusted(
+ java.security.cert.X509Certificate[] certs, String authType) {
+ }
+ }};
+ }
+
+ /**
+ * On error listener.
+ */
+ private static final Emitter.Listener onError = new Emitter.Listener() {
+ @SuppressWarnings("ThrowableResultOfMethodCallIgnored")
+ @Override public void call(Object... args) {
+ Throwable e = (Throwable)args[0];
+
+ ConnectException ce = X.cause(e, ConnectException.class);
+
+ if (ce != null)
+ log.warn(ce.getMessage());
+ else {
+ Exception ignore = X.cause(e, SSLHandshakeException.class);
+
+ if (ignore != null) {
+ log.error("Failed to establish SSL connection to server, due to errors with SSL handshake.");
+ log.error("Add to environment variable JVM_OPTS parameter \"-Dtrust.all=true\" to skip certificate validation in case of using self-signed certificate.");
+
+ System.exit(1);
+ }
+
+ ignore = X.cause(e, SocketException.class);
+
+ if (ignore != null) {
+ log.error("Failed to receive response from server (connection refused).");
+
+ return;
+ }
+
+ log.error("Connection error.", e);
+ }
+ }
+ };
+
+ /**
+ * On disconnect listener.
+ */
+ private static final Emitter.Listener onDisconnect = new Emitter.Listener() {
+ @Override public void call(Object... args) {
+ log.error(String.format("Connection closed: %s.", args[0]));
+ }
+ };
+
+ /**
* @param args Args.
*/
@SuppressWarnings("BusyWait")
public static void main(String[] args) throws Exception {
log.info("Starting Apache Ignite Web Console Agent...");
- AgentConfiguration cfg = new AgentConfiguration();
+ final AgentConfiguration cfg = new AgentConfiguration();
JCommander jCommander = new JCommander(cfg);
@@ -76,13 +176,13 @@ public class AgentLauncher {
File f = AgentUtils.resolvePath(prop);
if (f == null)
- log.warn("Failed to find agent property file: '" + prop + "'");
+ log.warn("Failed to find agent property file: " + prop);
else
propCfg.load(f.toURI().toURL());
}
catch (IOException ignore) {
if (!AgentConfiguration.DFLT_CFG_PATH.equals(prop))
- log.warn("Failed to load agent property file: '" + prop + "'", ignore);
+ log.warn("Failed to load agent property file: " + prop, ignore);
}
cfg.merge(propCfg);
@@ -118,47 +218,120 @@ public class AgentLauncher {
cfg.token(System.console().readLine().trim());
}
- RestExecutor restExecutor = new RestExecutor(cfg);
-
- restExecutor.start();
+ final RestHandler restHnd = new RestHandler(cfg);
try {
- SslContextFactory sslCtxFactory = new SslContextFactory();
+ restHnd.start();
+
+ URI uri = URI.create(cfg.serverUri());
- // Workaround for use self-signed certificate:
- if (Boolean.getBoolean("trust.all"))
- sslCtxFactory.setTrustAll(true);
+ if (uri.getPort() == -1)
+ uri = URI.create(cfg.serverUri() + ':' + DFLT_SERVER_PORT);
- WebSocketClient client = new WebSocketClient(sslCtxFactory);
+ IO.Options opts = new IO.Options();
- client.setMaxIdleTimeout(Long.MAX_VALUE);
+ opts.reconnectionDelay = RECONNECT_INTERVAL;
+
+ // Workaround for use self-signed certificate
+ if (Boolean.getBoolean("trust.all")) {
+ SSLContext ctx = SSLContext.getInstance("TLS");
+
+ // Create an SSLContext that uses our TrustManager
+ ctx.init(null, getTrustManagers(), null);
+
+ opts.sslContext = ctx;
+ }
- client.start();
+ final Socket client = IO.socket(uri, opts);
try {
- while (!Thread.interrupted()) {
- AgentSocket agentSock = new AgentSocket(cfg, restExecutor);
+ Emitter.Listener onConnecting = new Emitter.Listener() {
+ @Override public void call(Object... args) {
+ log.info("Connecting to: " + cfg.serverUri());
+ }
+ };
- log.info("Connecting to: " + cfg.serverUri());
+ Emitter.Listener onConnect = new Emitter.Listener() {
+ @Override public void call(Object... args) {
+ log.info("Connection established.");
- URI uri = URI.create(cfg.serverUri());
+ JSONObject authMsg = new JSONObject();
- if (uri.getPort() == -1)
- uri = URI.create(cfg.serverUri() + ":" + DFLT_SERVER_PORT);
+ try {
+ authMsg.put("token", cfg.token());
- client.connect(agentSock, uri);
+ String clsName = AgentLauncher.class.getSimpleName() + ".class";
- agentSock.waitForClose();
+ String clsPath = AgentLauncher.class.getResource(clsName).toString();
- Thread.sleep(RECONNECT_INTERVAL);
- }
+ if (clsPath.startsWith("jar")) {
+ String manifestPath = clsPath.substring(0, clsPath.lastIndexOf('!') + 1) +
+ "/META-INF/MANIFEST.MF";
+
+ Manifest manifest = new Manifest(new URL(manifestPath).openStream());
+
+ Attributes attr = manifest.getMainAttributes();
+
+ authMsg.put("ver", attr.getValue("Implementation-Version"));
+ authMsg.put("bt", attr.getValue("Build-Time"));
+ }
+
+ client.emit("agent:auth", authMsg, new Ack() {
+ @Override public void call(Object... args) {
+ // Authentication failed if response contains args.
+ if (args != null && args.length > 0) {
+ onDisconnect.call("Authentication failed: " + args[0]);
+
+ System.exit(1);
+ }
+
+ log.info("Authentication success.");
+ }
+ });
+ }
+ catch (JSONException | IOException e) {
+ log.error("Failed to construct authentication message", e);
+
+ client.close();
+ }
+ }
+ };
+
+ DatabaseHandler dbHnd = new DatabaseHandler(cfg);
+
+ final CountDownLatch latch = new CountDownLatch(1);
+
+ client
+ .on(EVENT_CONNECTING, onConnecting)
+ .on(EVENT_CONNECT, onConnect)
+ .on(EVENT_CONNECT_ERROR, onError)
+ .on(EVENT_RECONNECTING, onConnecting)
+ .on(EVENT_NODE_REST, restHnd)
+ .on(EVENT_SCHEMA_IMPORT_DRIVERS, dbHnd.availableDriversListener())
+ .on(EVENT_SCHEMA_IMPORT_SCHEMAS, dbHnd.schemasListener())
+ .on(EVENT_SCHEMA_IMPORT_METADATA, dbHnd.metadataListener())
+ .on(EVENT_ERROR, onError)
+ .on(EVENT_DISCONNECT, onDisconnect)
+ .on(EVENT_AGENT_CLOSE, new Emitter.Listener() {
+ @Override public void call(Object... args) {
+ onDisconnect.call(args);
+
+ client.off();
+
+ latch.countDown();
+ }
+ });
+
+ client.connect();
+
+ latch.await();
}
finally {
- client.stop();
+ client.close();
}
}
finally {
- restExecutor.stop();
+ restHnd.stop();
}
}
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/706317f3/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/AgentSocket.java
----------------------------------------------------------------------
diff --git a/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/AgentSocket.java b/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/AgentSocket.java
deleted file mode 100644
index ae6da07..0000000
--- a/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/AgentSocket.java
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.console.agent;
-
-import com.google.gson.Gson;
-import com.google.gson.JsonElement;
-import com.google.gson.JsonObject;
-import com.google.gson.JsonParser;
-import java.io.IOException;
-import java.net.ConnectException;
-import java.util.concurrent.CountDownLatch;
-import javax.net.ssl.SSLHandshakeException;
-import org.apache.ignite.console.agent.handlers.DatabaseMetadataExtractor;
-import org.apache.ignite.console.agent.handlers.RestExecutor;
-import org.apache.ignite.console.agent.remote.Remote;
-import org.apache.ignite.console.agent.remote.RemoteHandler;
-import org.apache.ignite.console.agent.remote.WebSocketSender;
-import org.apache.log4j.Logger;
-import org.eclipse.jetty.websocket.api.Session;
-import org.eclipse.jetty.websocket.api.annotations.OnWebSocketClose;
-import org.eclipse.jetty.websocket.api.annotations.OnWebSocketConnect;
-import org.eclipse.jetty.websocket.api.annotations.OnWebSocketError;
-import org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage;
-import org.eclipse.jetty.websocket.api.annotations.WebSocket;
-
-/**
- * Handler for web-socket connection.
- */
-@WebSocket
-public class AgentSocket implements WebSocketSender {
- /** */
- public static final Gson GSON = new Gson();
-
- /** */
- public static final JsonParser PARSER = new JsonParser();
-
- /** */
- private static final Logger log = Logger.getLogger(AgentSocket.class.getName());
-
- /** */
- private final CountDownLatch closeLatch = new CountDownLatch(1);
-
- /** */
- private final AgentConfiguration cfg;
-
- /** */
- private final RestExecutor restExecutor;
-
- /** */
- private RemoteHandler remote;
-
- /** */
- private Session ses;
-
- /**
- * @param cfg Config.
- */
- public AgentSocket(AgentConfiguration cfg, RestExecutor restExecutor) {
- this.cfg = cfg;
- this.restExecutor = restExecutor;
- }
-
- /**
- * @param statusCode Status code.
- * @param reason Reason.
- */
- @OnWebSocketClose
- public void onClose(int statusCode, String reason) {
- log.error(String.format("Connection closed: %d - %s.", statusCode, reason));
-
- if (remote != null)
- remote.close();
-
- closeLatch.countDown();
- }
-
- /**
- * @param ses Session.
- */
- @OnWebSocketConnect
- public void onConnect(Session ses) {
- log.info("Connection established.");
-
- this.ses = ses;
-
- remote = RemoteHandler.wrap(this, this, restExecutor, new DatabaseMetadataExtractor(cfg));
-
- JsonObject authMsg = new JsonObject();
-
- authMsg.addProperty("type", "AuthMessage");
- authMsg.addProperty("token", cfg.token());
- authMsg.addProperty("relDate", cfg.relDate());
-
- send(authMsg);
- }
-
- /**
- * @param msg Message.
- * @return Whether or not message was sent.
- */
- @Override public boolean send(JsonObject msg) {
- return send(GSON.toJson(msg));
- }
-
- /**
- * @param msg Message.
- * @return Whether or not message was sent.
- */
- @Override public boolean send(String msg) {
- try {
- ses.getRemote().sendString(msg);
-
- return true;
- }
- catch (IOException ignored) {
- log.error("Failed to send message to Control Center.");
-
- return false;
- }
- }
-
- /**
- * @param ses Session.
- * @param error Error.
- */
- @OnWebSocketError
- public void onError(Session ses, Throwable error) {
- if (error instanceof ConnectException)
- log.warn(error.getMessage());
- else if (error instanceof SSLHandshakeException) {
- log.error("Failed to establish SSL connection to Ignite Console. Start agent with " +
- "\"-Dtrust.all=true\" to skip certificate validation in case of using self-signed certificate.", error);
-
- System.exit(1);
- }
- else
- log.error("Connection error.", error);
-
- if (remote != null)
- remote.close();
-
- closeLatch.countDown();
- }
-
- /**
- * @param msg Message.
- */
- @OnWebSocketMessage
- public void onMessage(String msg) {
- JsonElement jsonElement = PARSER.parse(msg);
-
- remote.onMessage((JsonObject)jsonElement);
- }
-
- /**
- * @param errorMsg Authentication failed message or {@code null} if authentication success.
- */
- @Remote
- public void authResult(String errorMsg) {
- if (errorMsg != null) {
- onClose(401, "Authentication failed: " + errorMsg);
-
- System.exit(1);
- }
-
- log.info("Authentication success.");
- }
-
- /**
- * Await socket close.
- */
- public void waitForClose() throws InterruptedException {
- closeLatch.await();
- }
-}
http://git-wip-us.apache.org/repos/asf/ignite/blob/706317f3/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/AgentUtils.java
----------------------------------------------------------------------
diff --git a/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/AgentUtils.java b/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/AgentUtils.java
index 349eea1..50a849a 100644
--- a/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/AgentUtils.java
+++ b/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/AgentUtils.java
@@ -17,12 +17,11 @@
package org.apache.ignite.console.agent;
-import org.apache.log4j.Logger;
-
import java.io.File;
import java.net.URI;
import java.net.URISyntaxException;
import java.security.ProtectionDomain;
+import org.apache.log4j.Logger;
/**
* Utility methods.
@@ -101,10 +100,7 @@ public class AgentUtils {
return file;
}
- /*
- * 2. Check given path as absolute.
- */
-
+ // 2. Check given path as absolute.
File file = new File(path);
if (file.exists())
http://git-wip-us.apache.org/repos/asf/ignite/blob/706317f3/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/handlers/AbstractHandler.java
----------------------------------------------------------------------
diff --git a/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/handlers/AbstractHandler.java b/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/handlers/AbstractHandler.java
new file mode 100644
index 0000000..aa38dd7
--- /dev/null
+++ b/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/handlers/AbstractHandler.java
@@ -0,0 +1,102 @@
+/* @java.file.header */
+
+/* _________ _____ __________________ _____
+ * __ ____/___________(_)______ /__ ____/______ ____(_)_______
+ * _ / __ __ ___/__ / _ __ / _ / __ _ __ `/__ / __ __ \
+ * / /_/ / _ / _ / / /_/ / / /_/ / / /_/ / _ / _ / / /
+ * \____/ /_/ /_/ \_,__/ \____/ \__,_/ /_/ /_/ /_/
+ */
+
+package org.apache.ignite.console.agent.handlers;
+
+import com.fasterxml.jackson.annotation.JsonAutoDetect;
+import com.fasterxml.jackson.annotation.PropertyAccessor;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.datatype.jsonorg.JsonOrgModule;
+import io.socket.client.Ack;
+import io.socket.emitter.Emitter;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Map;
+import org.json.JSONArray;
+import org.json.JSONObject;
+
+/**
+ * Base class for web socket handlers.
+ */
+abstract class AbstractHandler implements Emitter.Listener {
+ /** JSON object mapper. */
+ private static final ObjectMapper mapper = new ObjectMapper();
+
+ static {
+ JsonOrgModule module = new JsonOrgModule();
+
+ mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.NONE);
+ mapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY);
+
+ mapper.registerModule(module);
+ }
+
+ /**
+ * @param obj Object.
+ * @return {@link JSONObject} or {@link JSONArray}.
+ */
+ private Object toJSON(Object obj) {
+ if (obj instanceof Iterable)
+ return mapper.convertValue(obj, JSONArray.class);
+
+ return mapper.convertValue(obj, JSONObject.class);
+ }
+
+ /** {@inheritDoc} */
+ @SuppressWarnings("unchecked")
+ @Override public final void call(Object... args) {
+ Ack cb = null;
+
+ try {
+ if (args == null || args.length == 0)
+ throw new IllegalArgumentException("Missing arguments.");
+
+ if (args.length > 2)
+ throw new IllegalArgumentException("Wrong arguments count, must be <= 2: " + Arrays.toString(args));
+
+ JSONObject lsnrArgs = null;
+
+ if (args.length == 1) {
+ if (args[0] instanceof JSONObject)
+ lsnrArgs = (JSONObject)args[0];
+ else if (args[0] instanceof Ack)
+ cb = (Ack)args[0];
+ else
+ throw new IllegalArgumentException("Wrong type of argument, must be JSONObject or Ack: " + args[0]);
+ }
+ else {
+ if (args[0] != null && !(args[0] instanceof JSONObject))
+ throw new IllegalArgumentException("Wrong type of argument, must be JSONObject: " + args[0]);
+
+ if (!(args[1] instanceof Ack))
+ throw new IllegalArgumentException("Wrong type of argument, must be Ack: " + args[1]);
+
+ lsnrArgs = (JSONObject)args[0];
+
+ cb = (Ack)args[1];
+ }
+
+ Object res = execute(lsnrArgs == null ? Collections.emptyMap() : mapper.convertValue(lsnrArgs, Map.class));
+
+ if (cb != null)
+ cb.call(null, toJSON(res));
+ }
+ catch (Exception e) {
+ if (cb != null)
+ cb.call(e, null);
+ }
+ }
+
+ /**
+ * Execute command with specified arguments.
+ *
+ * @param args Map with method args.
+ */
+ public abstract Object execute(Map<String, Object> args) throws Exception;
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/706317f3/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/handlers/DatabaseHandler.java
----------------------------------------------------------------------
diff --git a/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/handlers/DatabaseHandler.java b/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/handlers/DatabaseHandler.java
new file mode 100644
index 0000000..02146d9
--- /dev/null
+++ b/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/handlers/DatabaseHandler.java
@@ -0,0 +1,298 @@
+/*
+ * 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 io.socket.emitter.Emitter;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FilenameFilter;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.net.URL;
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import org.apache.ignite.console.agent.AgentConfiguration;
+import org.apache.ignite.console.demo.AgentMetadataDemo;
+import org.apache.ignite.schema.parser.DbMetadataReader;
+import org.apache.ignite.schema.parser.DbTable;
+import org.apache.log4j.Logger;
+
+import static org.apache.ignite.console.agent.AgentUtils.resolvePath;
+
+/**
+ * API to extract database metadata.
+ */
+public class DatabaseHandler {
+ /** */
+ private static final Logger log = Logger.getLogger(DatabaseHandler.class.getName());
+
+ /** */
+ private final File driversFolder;
+
+ /**
+ * @param cfg Config.
+ */
+ public DatabaseHandler(AgentConfiguration cfg) {
+ driversFolder = resolvePath(cfg.driversFolder() == null ? "jdbc-drivers" : cfg.driversFolder());
+ }
+
+ /**
+ * @param jdbcDriverJarPath JDBC driver JAR path.
+ * @param jdbcDriverCls JDBC driver class.
+ * @param jdbcUrl JDBC URL.
+ * @param jdbcInfo Properties to connect to database.
+ * @return Connection to database.
+ * @throws SQLException
+ */
+ private Connection connect(String jdbcDriverJarPath, String jdbcDriverCls, String jdbcUrl,
+ Properties jdbcInfo) throws SQLException {
+ if (AgentMetadataDemo.isTestDriveUrl(jdbcUrl))
+ return AgentMetadataDemo.testDrive();
+
+ if (!new File(jdbcDriverJarPath).isAbsolute() && driversFolder != null)
+ jdbcDriverJarPath = new File(driversFolder, jdbcDriverJarPath).getPath();
+
+ return DbMetadataReader.getInstance().connect(jdbcDriverJarPath, jdbcDriverCls, jdbcUrl, jdbcInfo);
+ }
+
+ /**
+ * @param jdbcDriverJarPath JDBC driver JAR path.
+ * @param jdbcDriverCls JDBC driver class.
+ * @param jdbcUrl JDBC URL.
+ * @param jdbcInfo Properties to connect to database.
+ * @return Collection of schema names.
+ * @throws SQLException
+ */
+ protected Collection<String> schemas(String jdbcDriverJarPath, String jdbcDriverCls, String jdbcUrl,
+ Properties jdbcInfo) throws SQLException {
+ if (log.isDebugEnabled())
+ log.debug("Start collecting database schemas [drvJar=" + jdbcDriverJarPath +
+ ", drvCls=" + jdbcDriverCls + ", jdbcUrl=" + jdbcUrl + "]");
+
+ try (Connection conn = connect(jdbcDriverJarPath, jdbcDriverCls, jdbcUrl, jdbcInfo)) {
+ Collection<String> schemas = DbMetadataReader.getInstance().schemas(conn);
+
+ if (log.isDebugEnabled())
+ log.debug("Finished collection of schemas [jdbcUrl=" + jdbcUrl + ", count=" + schemas.size() + "]");
+
+ return schemas;
+ }
+ catch (Throwable e) {
+ log.error("Failed to collect schemas", e);
+
+ throw new SQLException("Failed to collect schemas", e);
+ }
+ }
+
+ /**
+ * Listener for schema names.
+ *
+ * @return Collection of schema names.
+ */
+ public Emitter.Listener schemasListener() {
+ return new AbstractHandler() {
+ @Override public Object execute(Map<String, Object> args) throws Exception {
+ String driverPath = null;
+
+ if (args.containsKey("driverPath"))
+ driverPath = args.get("driverPath").toString();
+
+ if (!args.containsKey("driverClass"))
+ throw new IllegalArgumentException("Missing driverClass in arguments: " + args);
+
+ String driverCls = args.get("driverClass").toString();
+
+ if (!args.containsKey("url"))
+ throw new IllegalArgumentException("Missing url in arguments: " + args);
+
+ String url = args.get("url").toString();
+
+ if (!args.containsKey("info"))
+ throw new IllegalArgumentException("Missing info in arguments: " + args);
+
+ Properties info = new Properties();
+
+ info.putAll((Map)args.get("info"));
+
+ return schemas(driverPath, driverCls, url, info);
+ }
+ };
+ }
+
+ /**
+ * @param jdbcDriverJarPath JDBC driver JAR path.
+ * @param jdbcDriverCls JDBC driver class.
+ * @param jdbcUrl JDBC URL.
+ * @param jdbcInfo Properties to connect to database.
+ * @param schemas List of schema names to process.
+ * @param tblsOnly If {@code true} then only tables will be processed otherwise views also will be processed.
+ * @return Collection of tables.
+ */
+ protected Collection<DbTable> metadata(String jdbcDriverJarPath, String jdbcDriverCls, String jdbcUrl,
+ Properties jdbcInfo, List<String> schemas, boolean tblsOnly) throws SQLException {
+ if (log.isDebugEnabled())
+ log.debug("Start collecting database metadata [drvJar=" + jdbcDriverJarPath +
+ ", drvCls=" + jdbcDriverCls + ", jdbcUrl=" + jdbcUrl + "]");
+
+ try (Connection conn = connect(jdbcDriverJarPath, jdbcDriverCls, jdbcUrl, jdbcInfo)) {
+ Collection<DbTable> metadata = DbMetadataReader.getInstance().metadata(conn, schemas, tblsOnly);
+
+ if (log.isDebugEnabled())
+ log.debug("Finished collection of metadata [jdbcUrl=" + jdbcUrl + ", count=" + metadata.size() + "]");
+
+ return metadata;
+ }
+ catch (Throwable e) {
+ log.error("Failed to collect metadata", e);
+
+ throw new SQLException("Failed to collect metadata", e);
+ }
+ }
+
+ /**
+ * Listener for tables.
+ *
+ * @return Collection of tables.
+ */
+ public Emitter.Listener metadataListener() {
+ return new AbstractHandler() {
+ @SuppressWarnings("unchecked")
+ @Override public Object execute(Map<String, Object> args) throws Exception {
+ String driverPath = null;
+
+ if (args.containsKey("driverPath"))
+ driverPath = args.get("driverPath").toString();
+
+ if (!args.containsKey("driverClass"))
+ throw new IllegalArgumentException("Missing driverClass in arguments: " + args);
+
+ String driverCls = args.get("driverClass").toString();
+
+ if (!args.containsKey("url"))
+ throw new IllegalArgumentException("Missing url in arguments: " + args);
+
+ String url = args.get("url").toString();
+
+ if (!args.containsKey("info"))
+ throw new IllegalArgumentException("Missing info in arguments: " + args);
+
+ Properties info = new Properties();
+
+ info.putAll((Map)args.get("info"));
+
+ if (!args.containsKey("schemas"))
+ throw new IllegalArgumentException("Missing schemas in arguments: " + args);
+
+ List<String> schemas = (List<String>)args.get("schemas");
+
+ if (!args.containsKey("tablesOnly"))
+ throw new IllegalArgumentException("Missing tablesOnly in arguments: " + args);
+
+ boolean tblsOnly = (boolean)args.get("tablesOnly");
+
+ return metadata(driverPath, driverCls, url, info, schemas, tblsOnly);
+ }
+ };
+ }
+
+ /**
+ * Listener for drivers.
+ *
+ * @return Drivers in drivers folder
+ * @see AgentConfiguration#driversFolder
+ */
+ public Emitter.Listener availableDriversListener() {
+ return new AbstractHandler() {
+ @Override public Object execute(Map<String, Object> args) throws Exception {
+ if (driversFolder == null) {
+ log.info("JDBC drivers folder not specified, returning empty list");
+
+ return Collections.emptyList();
+ }
+
+ if (log.isDebugEnabled())
+ log.debug("Collecting JDBC drivers in folder: " + driversFolder.getPath());
+
+ File[] list = driversFolder.listFiles(new FilenameFilter() {
+ @Override public boolean accept(File dir, String name) {
+ return name.endsWith(".jar");
+ }
+ });
+
+ if (list == null) {
+ log.info("JDBC drivers folder has no files, returning empty list");
+
+ return Collections.emptyList();
+ }
+
+ List<JdbcDriver> res = new ArrayList<>();
+
+ for (File file : list) {
+ try {
+ boolean win = System.getProperty("os.name").contains("win");
+
+ URL url = new URL("jar", null,
+ "file:" + (win ? "/" : "") + file.getPath() + "!/META-INF/services/java.sql.Driver");
+
+ try (BufferedReader reader = new BufferedReader(new InputStreamReader(url.openStream()))) {
+ String jdbcDriverCls = reader.readLine();
+
+ res.add(new JdbcDriver(file.getName(), jdbcDriverCls));
+
+ if (log.isDebugEnabled())
+ log.debug("Found: [driver=" + file + ", class=" + jdbcDriverCls + "]");
+ }
+ }
+ catch (IOException e) {
+ res.add(new JdbcDriver(file.getName(), null));
+
+ log.info("Found: [driver=" + file + "]");
+ log.info("Failed to detect driver class: " + e.getMessage());
+ }
+ }
+
+ return res;
+ }
+ };
+ }
+
+ /**
+ * Wrapper class for later to be transformed to JSON and send to Web Console.
+ */
+ private static class JdbcDriver {
+ /** */
+ public final String jdbcDriverJar;
+ /** */
+ public final String jdbcDriverCls;
+
+ /**
+ * @param jdbcDriverJar File name of driver jar file.
+ * @param jdbcDriverCls Optional JDBC driver class.
+ */
+ public JdbcDriver(String jdbcDriverJar, String jdbcDriverCls) {
+ this.jdbcDriverJar = jdbcDriverJar;
+ this.jdbcDriverCls = jdbcDriverCls;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/706317f3/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/handlers/DatabaseMetadataExtractor.java
----------------------------------------------------------------------
diff --git a/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/handlers/DatabaseMetadataExtractor.java b/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/handlers/DatabaseMetadataExtractor.java
deleted file mode 100644
index 48d5236..0000000
--- a/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/handlers/DatabaseMetadataExtractor.java
+++ /dev/null
@@ -1,205 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.console.agent.handlers;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FilenameFilter;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.net.URL;
-import java.sql.Connection;
-import java.sql.SQLException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-import java.util.Properties;
-import org.apache.ignite.console.agent.AgentConfiguration;
-import org.apache.ignite.console.agent.remote.Remote;
-import org.apache.ignite.console.demo.AgentMetadataDemo;
-import org.apache.ignite.schema.parser.DbMetadataReader;
-import org.apache.ignite.schema.parser.DbTable;
-import org.apache.log4j.Logger;
-
-import static org.apache.ignite.console.agent.AgentUtils.resolvePath;
-
-/**
- * Remote API to extract database metadata.
- */
-public class DatabaseMetadataExtractor {
- /** */
- private static final Logger log = Logger.getLogger(DatabaseMetadataExtractor.class.getName());
-
- /** */
- private final File driversFolder;
-
- /**
- * @param cfg Config.
- */
- public DatabaseMetadataExtractor(AgentConfiguration cfg) {
- driversFolder = resolvePath(cfg.driversFolder() == null ? "jdbc-drivers" : cfg.driversFolder());
- }
-
- /**
- * @param jdbcDriverJarPath JDBC driver JAR path.
- * @param jdbcDriverCls JDBC driver class.
- * @param jdbcUrl JDBC URL.
- * @param jdbcInfo Properties to connect to database.
- * @return Connection to database.
- * @throws SQLException
- */
- private Connection connect(String jdbcDriverJarPath, String jdbcDriverCls, String jdbcUrl, Properties jdbcInfo) throws SQLException {
- if (!new File(jdbcDriverJarPath).isAbsolute() && driversFolder != null)
- jdbcDriverJarPath = new File(driversFolder, jdbcDriverJarPath).getPath();
-
- if (AgentMetadataDemo.isTestDriveUrl(jdbcUrl))
- AgentMetadataDemo.testDrive();
-
- return DbMetadataReader.getInstance().connect(jdbcDriverJarPath, jdbcDriverCls, jdbcUrl, jdbcInfo);
- }
-
- /**
- * @param jdbcDriverJarPath JDBC driver JAR path.
- * @param jdbcDriverCls JDBC driver class.
- * @param jdbcUrl JDBC URL.
- * @param jdbcInfo Properties to connect to database.
- * @return Collection of schema names.
- * @throws SQLException
- */
- @Remote
- public Collection<String> schemas(String jdbcDriverJarPath, String jdbcDriverCls, String jdbcUrl,
- Properties jdbcInfo) throws SQLException {
- log.debug("Start collecting database schemas [driver jar=" + jdbcDriverJarPath +
- ", driver class=" + jdbcDriverCls + ", url=" + jdbcUrl + "]");
-
- try (Connection conn = connect(jdbcDriverJarPath, jdbcDriverCls, jdbcUrl, jdbcInfo)) {
- Collection<String> schemas = DbMetadataReader.getInstance().schemas(conn);
-
- log.debug("Finished collection of schemas [url=" + jdbcUrl + ", count="+ schemas.size() +"]");
-
- return schemas;
- }
- catch (Throwable e) {
- log.error("Failed to collect schemas", e);
-
- throw new SQLException("Failed to collect schemas", e);
- }
- }
-
- /**
- * @param jdbcDriverJarPath JDBC driver JAR path.
- * @param jdbcDriverCls JDBC driver class.
- * @param jdbcUrl JDBC URL.
- * @param jdbcInfo Properties to connect to database.
- * @param schemas List of schema names to process.
- * @param tblsOnly If {@code true} then only tables will be processed otherwise views also will be processed.
- * @return Collection of tables.
- */
- @Remote
- public Collection<DbTable> metadata(String jdbcDriverJarPath, String jdbcDriverCls, String jdbcUrl,
- Properties jdbcInfo, List<String> schemas, boolean tblsOnly) throws SQLException {
- log.debug("Start collecting database metadata [driver jar=" + jdbcDriverJarPath +
- ", driver class=" + jdbcDriverCls + ", url=" + jdbcUrl + "]");
-
- try (Connection conn = connect(jdbcDriverJarPath, jdbcDriverCls, jdbcUrl, jdbcInfo)) {
- Collection<DbTable> metadata = DbMetadataReader.getInstance().metadata(conn, schemas, tblsOnly);
-
- log.debug("Finished collection of metadata [url=" + jdbcUrl + ", count="+ metadata.size() +"]");
-
- return metadata;
- }
- catch (Throwable e) {
- log.error("Failed to collect metadata", e);
-
- throw new SQLException("Failed to collect metadata", e);
- }
- }
-
- /**
- * @return Drivers in drivers folder
- * @see AgentConfiguration#driversFolder
- */
- @Remote
- public List<JdbcDriver> availableDrivers() {
- if (driversFolder == null) {
- log.info("JDBC drivers folder not specified, returning empty list");
-
- return Collections.emptyList();
- }
-
- log.debug("Collecting JDBC drivers in folder: " + driversFolder.getPath());
-
- File[] list = driversFolder.listFiles(new FilenameFilter() {
- @Override public boolean accept(File dir, String name) {
- return name.endsWith(".jar");
- }
- });
-
- if (list == null) {
- log.info("JDBC drivers folder has no files, returning empty list");
-
- return Collections.emptyList();
- }
-
- List<JdbcDriver> res = new ArrayList<>();
-
- for (File file : list) {
- try {
- boolean win = System.getProperty("os.name").contains("win");
-
- URL url = new URL("jar", null, "file:" + (win ? "/" : "") + file.getPath() + "!/META-INF/services/java.sql.Driver");
-
- try (BufferedReader reader = new BufferedReader(new InputStreamReader(url.openStream()))) {
- String jdbcDriverCls = reader.readLine();
-
- res.add(new JdbcDriver(file.getName(), jdbcDriverCls));
-
- log.debug("Found: [driver=" + file + ", class=" + jdbcDriverCls + "]");
- }
- }
- catch (IOException e) {
- res.add(new JdbcDriver(file.getName(), null));
-
- log.info("Found: [driver=" + file + "]");
- log.info("Failed to detect driver class: " + e.getMessage());
- }
- }
-
- return res;
- }
-
- /**
- * Wrapper class for later to be transformed to JSON and send to Web Console.
- */
- private static class JdbcDriver {
- /** */
- private final String jdbcDriverJar;
- /** */
- private final String jdbcDriverClass;
-
- /**
- * @param jdbcDriverJar File name of driver jar file.
- * @param jdbcDriverClass Optional JDBC driver class.
- */
- public JdbcDriver(String jdbcDriverJar, String jdbcDriverClass) {
- this.jdbcDriverJar = jdbcDriverJar;
- this.jdbcDriverClass = jdbcDriverClass;
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/ignite/blob/706317f3/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/handlers/RestExecutor.java
----------------------------------------------------------------------
diff --git a/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/handlers/RestExecutor.java b/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/handlers/RestExecutor.java
deleted file mode 100644
index 3eb869b..0000000
--- a/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/handlers/RestExecutor.java
+++ /dev/null
@@ -1,225 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.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.agent.remote.Remote;
-import org.apache.ignite.console.demo.AgentSqlDemo;
-import org.apache.log4j.Logger;
-
-import static org.apache.ignite.console.agent.AgentConfiguration.DFLT_NODE_PORT;
-
-/**
- * Executor for REST requests.
- */
-public class RestExecutor {
- /** */
- private static final Logger log = Logger.getLogger(RestExecutor.class.getName());
-
- /** */
- private final AgentConfiguration cfg;
-
- /** */
- private CloseableHttpClient httpClient;
-
- /**
- * @param cfg Config.
- */
- public RestExecutor(AgentConfiguration cfg) {
- this.cfg = cfg;
- }
-
- /**
- *
- */
- public void start() {
- httpClient = HttpClientBuilder.create().build();
- }
-
- /**
- *
- */
- public void stop() throws IOException {
- if (httpClient != null)
- httpClient.close();
- }
-
- /**
- * @param uri Url.
- * @param params Params.
- * @param demo Use demo node.
- * @param mtd Method.
- * @param headers Headers.
- * @param body Body.
- */
- @Remote
- public RestResult executeRest(String uri, Map<String, String> params, boolean demo,
- String mtd, Map<String, String> headers, String body) throws IOException, URISyntaxException {
- log.debug("Start execute REST command [method=" + mtd + ", uri=/" + uri + ", parameters=" + params + "]");
-
- final URIBuilder builder;
-
- if (demo) {
- // try start demo if needed.
- AgentSqlDemo.testDrive(cfg);
-
- // null if demo node not started yet.
- if (cfg.demoNodeUri() == null)
- return RestResult.fail(404, "Demo node is not started yet.");
-
- 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, String> entry : params.entrySet())
- builder.addParameter(entry.getKey(), entry.getValue());
- }
-
- HttpRequestBase httpReq;
-
- 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, String> entry : headers.entrySet())
- httpReq.addHeader(entry.getKey(), entry.getValue());
- }
-
- 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(404, "Failed connect to node and execute REST command.");
- }
- }
-
- /**
- * Request result.
- */
- public static class RestResult {
- /** REST http code. */
- private int restCode;
-
- /** The field contains description of error if server could not handle the request. */
- private String error;
-
- /** The field contains result of command. */
- private String response;
-
- /**
- * @param restCode REST http code.
- * @param error The field contains description of error if server could not handle the request.
- * @param response The field contains result of command.
- */
- private RestResult(int restCode, String error, String response) {
- this.restCode = restCode;
- this.error = error;
- this.response = response;
- }
-
- /**
- * @param restCode REST http code.
- * @param error The field contains description of error if server could not handle the request.
-
- * @return Request result.
- */
- public static RestResult fail(int restCode, String error) {
- return new RestResult(restCode, error, null);
- }
-
- /**
- * @param restCode REST http code.
- * @param response The field contains result of command.
-
- * @return Request result.
- */
- public static RestResult success(int restCode, String response) {
- return new RestResult(restCode, null, response);
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/ignite/blob/706317f3/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/handlers/RestHandler.java
----------------------------------------------------------------------
diff --git a/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/handlers/RestHandler.java b/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/handlers/RestHandler.java
new file mode 100644
index 0000000..2f476cf
--- /dev/null
+++ b/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/handlers/RestHandler.java
@@ -0,0 +1,274 @@
+/*
+ * 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.AgentSqlDemo;
+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.
+ AgentSqlDemo.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())
+ builder.addParameter(entry.getKey(), entry.getValue() == null ? null : 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/706317f3/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/remote/Remote.java
----------------------------------------------------------------------
diff --git a/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/remote/Remote.java b/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/remote/Remote.java
deleted file mode 100644
index 71b2bc0..0000000
--- a/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/remote/Remote.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.console.agent.remote;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- * Use this annotation to associate methods with remote NodeJS server commands.
- */
-@Target(ElementType.METHOD)
-@Retention(RetentionPolicy.RUNTIME)
-public @interface Remote {
- /**
- * Whether or not method should be executed synchronously.
- *
- * @return {@code true} if method will be executed in separated thread otherwise if method will be executed in handler thread.
- */
- boolean async() default true;
-}
http://git-wip-us.apache.org/repos/asf/ignite/blob/706317f3/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
deleted file mode 100644
index 11e35e3..0000000
--- a/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/remote/RemoteHandler.java
+++ /dev/null
@@ -1,246 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.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 java.util.concurrent.RejectedExecutionException;
-
-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 ann = method.getAnnotation(Remote.class);
-
- if (ann != null) {
- MethodDescriptor old = mtds.put(method.getName(), new MethodDescriptor(method, hnd, ann.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 method = req.getAsJsonPrimitive("method").getAsString();
-
- final MethodDescriptor desc = mtds.get(method);
-
- if (desc == null) {
- sendException(reqId, INTERNAL_EXCEPTION_TYPE, "Unknown method: " + method);
-
- 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 count");
-
- return;
- }
-
- for (int i = 0; i < paramTypes.length; i++)
- args[i] = GSON.fromJson(argsJson.get(i), paramTypes[i]);
- }
- else
- args = EMPTY_OBJECTS;
-
- 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) {
- try {
- executorSrvc.submit(run);
- }
- catch (RejectedExecutionException ignore) {
- // No-op.
- }
- }
- 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);
- res.addProperty("error", exType + ": " + exMsg);
-
- 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("response", 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/706317f3/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
deleted file mode 100644
index cceb86b..0000000
--- a/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/remote/WebSocketSender.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.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/706317f3/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
index 5d33f29..4683dd8 100644
--- 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
@@ -18,11 +18,12 @@
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;
@@ -52,7 +53,7 @@ public class AgentMetadataDemo {
/**
* Start H2 database and populate it with several tables.
*/
- public static void testDrive() {
+ public static Connection testDrive() throws SQLException {
if (initLatch.compareAndSet(false, true)) {
log.info("DEMO: Prepare in-memory H2 database...");
@@ -61,13 +62,7 @@ public class AgentMetadataDemo {
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;
- }
-
+ //noinspection ConstantConditions
RunScript.execute(conn, new FileReader(sqlScript));
log.info("DEMO: Sample tables created.");
@@ -80,9 +75,18 @@ public class AgentMetadataDemo {
log.info("DEMO: JDBC URL for test drive metadata load: jdbc:h2:mem:demo-db");
}
- catch (Exception e) {
+ 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", "");
}
}