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/01/15 12:04:03 UTC
[2/6] ignite git commit: IGNITE-843 WIP
http://git-wip-us.apache.org/repos/asf/ignite/blob/54a24746/modules/control-center-agent/src/main/java/org/apache/ignite/agent/demo/model/Employee.java
----------------------------------------------------------------------
diff --git a/modules/control-center-agent/src/main/java/org/apache/ignite/agent/demo/model/Employee.java b/modules/control-center-agent/src/main/java/org/apache/ignite/agent/demo/model/Employee.java
deleted file mode 100644
index 9238845..0000000
--- a/modules/control-center-agent/src/main/java/org/apache/ignite/agent/demo/model/Employee.java
+++ /dev/null
@@ -1,358 +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.agent.demo.model;
-
-import java.io.Serializable;
-
-/**
- * Employee definition.
- *
- * Code generated by Apache Ignite Schema Import utility: 08/24/2015.
- */
-public class Employee implements Serializable {
- /** */
- private static final long serialVersionUID = 0L;
-
- /** Value for employeeId. */
- private int employeeId;
-
- /** 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 java.sql.Date hireDate;
-
- /** Value for job. */
- private String job;
-
- /** Value for salary. */
- private Double salary;
-
- /** Value for managerId. */
- private Integer managerId;
-
- /** Value for departmentId. */
- private Integer departmentId;
-
- /**
- * Empty constructor.
- */
- public Employee() {
- // No-op.
- }
-
- /**
- * Full constructor.
- */
- public Employee(
- int employeeId,
- String firstName,
- String lastName,
- String email,
- String phoneNumber,
- java.sql.Date hireDate,
- String job,
- Double salary,
- Integer managerId,
- Integer departmentId
- ) {
- this.employeeId = employeeId;
- this.firstName = firstName;
- this.lastName = lastName;
- this.email = email;
- this.phoneNumber = phoneNumber;
- this.hireDate = hireDate;
- this.job = job;
- this.salary = salary;
- this.managerId = managerId;
- this.departmentId = departmentId;
- }
-
- /**
- * Gets employeeId.
- *
- * @return Value for employeeId.
- */
- public int getEmployeeId() {
- return employeeId;
- }
-
- /**
- * Sets employeeId.
- *
- * @param employeeId New value for employeeId.
- */
- public void setEmployeeId(int employeeId) {
- this.employeeId = employeeId;
- }
-
- /**
- * 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 java.sql.Date getHireDate() {
- return hireDate;
- }
-
- /**
- * Sets hireDate.
- *
- * @param hireDate New value for hireDate.
- */
- public void setHireDate(java.sql.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;
- }
-
- /**
- * 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 departmentId.
- *
- * @return Value for departmentId.
- */
- public Integer getDepartmentId() {
- return departmentId;
- }
-
- /**
- * Sets departmentId.
- *
- * @param departmentId New value for departmentId.
- */
- public void setDepartmentId(Integer departmentId) {
- this.departmentId = departmentId;
- }
-
- /** {@inheritDoc} */
- @Override public boolean equals(Object o) {
- if (this == o)
- return true;
-
- if (!(o instanceof Employee))
- return false;
-
- Employee that = (Employee)o;
-
- if (employeeId != that.employeeId)
- 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;
-
- if (managerId != null ? !managerId.equals(that.managerId) : that.managerId != null)
- return false;
-
- if (departmentId != null ? !departmentId.equals(that.departmentId) : that.departmentId != null)
- return false;
-
- return true;
- }
-
- /** {@inheritDoc} */
- @Override public int hashCode() {
- int res = employeeId;
-
- 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);
-
- res = 31 * res + (managerId != null ? managerId.hashCode() : 0);
-
- res = 31 * res + (departmentId != null ? departmentId.hashCode() : 0);
-
- return res;
- }
-
- /** {@inheritDoc} */
- @Override public String toString() {
- return "Employee [employeeId=" + employeeId +
- ", firstName=" + firstName +
- ", lastName=" + lastName +
- ", email=" + email +
- ", phoneNumber=" + phoneNumber +
- ", hireDate=" + hireDate +
- ", job=" + job +
- ", salary=" + salary +
- ", managerId=" + managerId +
- ", departmentId=" + departmentId +
- "]";
- }
-}
-
http://git-wip-us.apache.org/repos/asf/ignite/blob/54a24746/modules/control-center-agent/src/main/java/org/apache/ignite/agent/demo/model/EmployeeKey.java
----------------------------------------------------------------------
diff --git a/modules/control-center-agent/src/main/java/org/apache/ignite/agent/demo/model/EmployeeKey.java b/modules/control-center-agent/src/main/java/org/apache/ignite/agent/demo/model/EmployeeKey.java
deleted file mode 100644
index 6a9f4c0..0000000
--- a/modules/control-center-agent/src/main/java/org/apache/ignite/agent/demo/model/EmployeeKey.java
+++ /dev/null
@@ -1,97 +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.agent.demo.model;
-
-import java.io.Serializable;
-
-/**
- * EmployeeKey definition.
- *
- * Code generated by Apache Ignite Schema Import utility: 08/24/2015.
- */
-public class EmployeeKey implements Serializable {
- /** */
- private static final long serialVersionUID = 0L;
-
- /** Value for employeeId. */
- private int employeeId;
-
- /**
- * Empty constructor.
- */
- public EmployeeKey() {
- // No-op.
- }
-
- /**
- * Full constructor.
- */
- public EmployeeKey(
- int employeeId
- ) {
- this.employeeId = employeeId;
- }
-
- /**
- * Gets employeeId.
- *
- * @return Value for employeeId.
- */
- public int getEmployeeId() {
- return employeeId;
- }
-
- /**
- * Sets employeeId.
- *
- * @param employeeId New value for employeeId.
- */
- public void setEmployeeId(int employeeId) {
- this.employeeId = employeeId;
- }
-
- /** {@inheritDoc} */
- @Override public boolean equals(Object o) {
- if (this == o)
- return true;
-
- if (!(o instanceof EmployeeKey))
- return false;
-
- EmployeeKey that = (EmployeeKey)o;
-
- if (employeeId != that.employeeId)
- return false;
-
- return true;
- }
-
- /** {@inheritDoc} */
- @Override public int hashCode() {
- int res = employeeId;
-
- return res;
- }
-
- /** {@inheritDoc} */
- @Override public String toString() {
- return "EmployeeKey [employeeId=" + employeeId +
- "]";
- }
-}
-
http://git-wip-us.apache.org/repos/asf/ignite/blob/54a24746/modules/control-center-agent/src/main/java/org/apache/ignite/agent/demo/model/Parking.java
----------------------------------------------------------------------
diff --git a/modules/control-center-agent/src/main/java/org/apache/ignite/agent/demo/model/Parking.java b/modules/control-center-agent/src/main/java/org/apache/ignite/agent/demo/model/Parking.java
deleted file mode 100644
index 7613760..0000000
--- a/modules/control-center-agent/src/main/java/org/apache/ignite/agent/demo/model/Parking.java
+++ /dev/null
@@ -1,126 +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.agent.demo.model;
-
-import java.io.Serializable;
-
-/**
- * Parking definition.
- *
- * Code generated by Apache Ignite Schema Import utility: 08/24/2015.
- */
-public class Parking implements Serializable {
- /** */
- private static final long serialVersionUID = 0L;
-
- /** Value for parkingId. */
- private int parkingId;
-
- /** Value for parkingName. */
- private String parkingName;
-
- /**
- * Empty constructor.
- */
- public Parking() {
- // No-op.
- }
-
- /**
- * Full constructor.
- */
- public Parking(
- int parkingId,
- String parkingName
- ) {
- this.parkingId = parkingId;
- this.parkingName = parkingName;
- }
-
- /**
- * 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 parkingName.
- *
- * @return Value for parkingName.
- */
- public String getParkingName() {
- return parkingName;
- }
-
- /**
- * Sets parkingName.
- *
- * @param parkingName New value for parkingName.
- */
- public void setParkingName(String parkingName) {
- this.parkingName = parkingName;
- }
-
- /** {@inheritDoc} */
- @Override public boolean equals(Object o) {
- if (this == o)
- return true;
-
- if (!(o instanceof Parking))
- return false;
-
- Parking that = (Parking)o;
-
- if (parkingId != that.parkingId)
- return false;
-
- if (parkingName != null ? !parkingName.equals(that.parkingName) : that.parkingName != null)
- return false;
-
- return true;
- }
-
- /** {@inheritDoc} */
- @Override public int hashCode() {
- int res = parkingId;
-
- res = 31 * res + (parkingName != null ? parkingName.hashCode() : 0);
-
- return res;
- }
-
- /** {@inheritDoc} */
- @Override public String toString() {
- return "Parking [parkingId=" + parkingId +
- ", parkingName=" + parkingName +
- "]";
- }
-}
-
http://git-wip-us.apache.org/repos/asf/ignite/blob/54a24746/modules/control-center-agent/src/main/java/org/apache/ignite/agent/demo/model/ParkingKey.java
----------------------------------------------------------------------
diff --git a/modules/control-center-agent/src/main/java/org/apache/ignite/agent/demo/model/ParkingKey.java b/modules/control-center-agent/src/main/java/org/apache/ignite/agent/demo/model/ParkingKey.java
deleted file mode 100644
index a68e8e5..0000000
--- a/modules/control-center-agent/src/main/java/org/apache/ignite/agent/demo/model/ParkingKey.java
+++ /dev/null
@@ -1,97 +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.agent.demo.model;
-
-import java.io.Serializable;
-
-/**
- * ParkingKey definition.
- *
- * Code generated by Apache Ignite Schema Import utility: 08/24/2015.
- */
-public class ParkingKey implements Serializable {
- /** */
- private static final long serialVersionUID = 0L;
-
- /** Value for parkingId. */
- private int parkingId;
-
- /**
- * Empty constructor.
- */
- public ParkingKey() {
- // No-op.
- }
-
- /**
- * Full constructor.
- */
- public ParkingKey(
- int parkingId
- ) {
- this.parkingId = parkingId;
- }
-
- /**
- * 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;
- }
-
- /** {@inheritDoc} */
- @Override public boolean equals(Object o) {
- if (this == o)
- return true;
-
- if (!(o instanceof ParkingKey))
- return false;
-
- ParkingKey that = (ParkingKey)o;
-
- if (parkingId != that.parkingId)
- return false;
-
- return true;
- }
-
- /** {@inheritDoc} */
- @Override public int hashCode() {
- int res = parkingId;
-
- return res;
- }
-
- /** {@inheritDoc} */
- @Override public String toString() {
- return "ParkingKey [parkingId=" + parkingId +
- "]";
- }
-}
-
http://git-wip-us.apache.org/repos/asf/ignite/blob/54a24746/modules/control-center-agent/src/main/java/org/apache/ignite/agent/handlers/DatabaseMetadataExtractor.java
----------------------------------------------------------------------
diff --git a/modules/control-center-agent/src/main/java/org/apache/ignite/agent/handlers/DatabaseMetadataExtractor.java b/modules/control-center-agent/src/main/java/org/apache/ignite/agent/handlers/DatabaseMetadataExtractor.java
deleted file mode 100644
index 0498656..0000000
--- a/modules/control-center-agent/src/main/java/org/apache/ignite/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.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.agent.AgentConfiguration;
-import org.apache.ignite.agent.remote.Remote;
-import org.apache.ignite.agent.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.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/54a24746/modules/control-center-agent/src/main/java/org/apache/ignite/agent/handlers/RestExecutor.java
----------------------------------------------------------------------
diff --git a/modules/control-center-agent/src/main/java/org/apache/ignite/agent/handlers/RestExecutor.java b/modules/control-center-agent/src/main/java/org/apache/ignite/agent/handlers/RestExecutor.java
deleted file mode 100644
index 99b5626..0000000
--- a/modules/control-center-agent/src/main/java/org/apache/ignite/agent/handlers/RestExecutor.java
+++ /dev/null
@@ -1,195 +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.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.agent.AgentConfiguration;
-import org.apache.ignite.agent.remote.Remote;
-import org.apache.ignite.agent.demo.AgentSqlDemo;
-import org.apache.log4j.Logger;
-
-import static org.apache.ignite.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 path Path.
- * @param mtd Method.
- * @param params Params.
- * @param headers Headers.
- * @param body Body.
- */
- @Remote
- public RestResult executeRest(String path, Map<String, String> params, String mtd, Map<String, String> headers,
- String body) throws IOException, URISyntaxException {
- log.debug("Start execute REST command [url=/" + path + ", method=" + mtd +
- ", parameters=" + params + "]");
-
- URIBuilder builder = new URIBuilder(cfg.nodeUri());
-
- if (builder.getPort() == -1)
- builder.setPort(DFLT_NODE_PORT);
-
- if (path != null) {
- if (!path.startsWith("/") && !cfg.nodeUri().endsWith("/"))
- path = '/' + path;
-
- builder.setPath(path);
- }
-
- 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 new RestResult(resp.getStatusLine().getStatusCode(), new String(out.toByteArray(), charset));
- }
- catch (ConnectException e) {
- log.debug("Failed connect to node and execute REST command [uri=" + builder.build() + "]");
-
- return new RestResult(404, "Failed connect to node and execute REST command.");
- }
- }
-
- /**
- * Enable test-drive SQL.
- */
- @Remote
- public boolean startDemoSQL() {
- return AgentSqlDemo.testDrive(cfg);
- }
-
- /**
- * Request result.
- */
- public static class RestResult {
- /** Status code. */
- private int code;
-
- /** Message. */
- private String message;
-
- /**
- * @param code Code.
- * @param msg Message.
- */
- public RestResult(int code, String msg) {
- this.code = code;
- message = msg;
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/ignite/blob/54a24746/modules/control-center-agent/src/main/java/org/apache/ignite/agent/remote/Remote.java
----------------------------------------------------------------------
diff --git a/modules/control-center-agent/src/main/java/org/apache/ignite/agent/remote/Remote.java b/modules/control-center-agent/src/main/java/org/apache/ignite/agent/remote/Remote.java
deleted file mode 100644
index 8fe49bd..0000000
--- a/modules/control-center-agent/src/main/java/org/apache/ignite/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.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/54a24746/modules/control-center-agent/src/main/java/org/apache/ignite/agent/remote/RemoteHandler.java
----------------------------------------------------------------------
diff --git a/modules/control-center-agent/src/main/java/org/apache/ignite/agent/remote/RemoteHandler.java b/modules/control-center-agent/src/main/java/org/apache/ignite/agent/remote/RemoteHandler.java
deleted file mode 100644
index e15280f..0000000
--- a/modules/control-center-agent/src/main/java/org/apache/ignite/agent/remote/RemoteHandler.java
+++ /dev/null
@@ -1,252 +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.agent.remote;
-
-import com.google.gson.Gson;
-import com.google.gson.JsonArray;
-import com.google.gson.JsonElement;
-import com.google.gson.JsonNull;
-import com.google.gson.JsonObject;
-import com.google.gson.JsonPrimitive;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.lang.reflect.Type;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import org.apache.http.auth.AuthenticationException;
-import org.apache.log4j.Logger;
-
-/**
- * Allow to execute methods remotely from NodeJS server by web-socket command.
- */
-public class RemoteHandler implements AutoCloseable {
- /** */
- public static final Gson GSON = new Gson();
-
- /** */
- public static final Object[] EMPTY_OBJECTS = new Object[0];
-
- /** */
- private static final Logger log = Logger.getLogger(RemoteHandler.class.getName());
-
- /** */
- private static final String INTERNAL_EXCEPTION_TYPE = "org.apache.ignite.agent.AgentException";
-
- /** */
- private final WebSocketSender snd;
-
- /** */
- private final Map<String, MethodDescriptor> mtds = new HashMap<>();
-
- /** */
- private final ExecutorService executorSrvc = Executors.newFixedThreadPool(Runtime.getRuntime()
- .availableProcessors());
-
- /**
- * @param snd Session.
- * @param hnds Handlers.
- */
- private RemoteHandler(WebSocketSender snd, Object ... hnds) {
- this.snd = snd;
-
- for (Object hnd : hnds) {
- for (Method method : hnd.getClass().getMethods()) {
- Remote remoteAnn = method.getAnnotation(Remote.class);
-
- if (remoteAnn != null) {
- MethodDescriptor old = mtds.put(method.getName(), new MethodDescriptor(method, hnd,
- remoteAnn.async()));
-
- if (old != null)
- throw new IllegalArgumentException("Duplicated method: " + method.getName());
- }
- }
- }
- }
-
- /**
- * @param hnds Handler.
- * @param snd Sender.
- */
- public static RemoteHandler wrap(WebSocketSender snd, Object ... hnds) {
- return new RemoteHandler(snd, hnds);
- }
-
- /**
- * @param req Request.
- */
- public void onMessage(JsonObject req) {
- JsonPrimitive reqIdJson = req.getAsJsonPrimitive("reqId");
-
- final Long reqId = reqIdJson == null ? null : reqIdJson.getAsLong();
-
- String mtdName = req.getAsJsonPrimitive("mtdName").getAsString();
-
- final MethodDescriptor desc = mtds.get(mtdName);
-
- if (desc == null) {
- sendException(reqId, INTERNAL_EXCEPTION_TYPE, "Unknown method: " + mtdName);
-
- return;
- }
-
- Type[] paramTypes = desc.mtd.getGenericParameterTypes();
-
- JsonArray argsJson = req.getAsJsonArray("args");
-
- final Object[] args;
-
- if (paramTypes.length > 0) {
- args = new Object[paramTypes.length];
-
- if (argsJson == null || argsJson.size() != paramTypes.length) {
- sendException(reqId, INTERNAL_EXCEPTION_TYPE, "Inconsistent parameters");
-
- return;
- }
-
- for (int i = 0; i < paramTypes.length; i++)
- args[i] = GSON.fromJson(argsJson.get(i), paramTypes[i]);
- }
- else {
- args = EMPTY_OBJECTS;
-
- if (argsJson != null && argsJson.size() > 0) {
- sendException(reqId, INTERNAL_EXCEPTION_TYPE, "Inconsistent parameters");
-
- return;
- }
- }
-
- Runnable run = new Runnable() {
- @Override public void run() {
- final Object res;
-
- try {
- res = desc.mtd.invoke(desc.hnd, args);
- }
- catch (Throwable e) {
- if (e instanceof AuthenticationException) {
- close();
-
- return;
- }
-
- if (e instanceof InvocationTargetException)
- e = ((InvocationTargetException)e).getTargetException();
-
- if (reqId != null)
- sendException(reqId, e.getClass().getName(), e.getMessage());
- else
- log.error("Exception on execute remote method.", e);
-
- return;
- }
-
- sendResponse(reqId, res, desc.returnType);
- }
- };
-
- if (desc.async)
- executorSrvc.submit(run);
- else
- run.run();
- }
-
- /**
- * @param reqId Request id.
- * @param exType Exception class name.
- * @param exMsg Exception message.
- */
- protected void sendException(Long reqId, String exType, String exMsg) {
- if (reqId == null)
- return;
-
- JsonObject res = new JsonObject();
-
- res.addProperty("type", "CallRes");
- res.addProperty("reqId", reqId);
-
- JsonObject exJson = new JsonObject();
- exJson.addProperty("type", exType);
- exJson.addProperty("message", exMsg);
-
- res.add("ex", exJson);
-
- snd.send(res);
- }
-
- /**
- * @param reqId Request id.
- * @param res Result.
- * @param type Type.
- */
- private void sendResponse(Long reqId, Object res, Type type) {
- if (reqId == null)
- return;
-
- JsonObject resp = new JsonObject();
-
- resp.addProperty("type", "CallRes");
-
- resp.addProperty("reqId", reqId);
-
- JsonElement resJson = type == void.class ? JsonNull.INSTANCE : GSON.toJsonTree(res, type);
-
- resp.add("res", resJson);
-
- snd.send(resp);
- }
-
- /** {@inheritDoc} */
- @Override public void close() {
- executorSrvc.shutdown();
- }
-
- /**
- *
- */
- private static class MethodDescriptor {
- /** */
- private final Method mtd;
-
- /** */
- private final Object hnd;
-
- /** */
- private final Type returnType;
-
- /** */
- private final boolean async;
-
- /**
- * @param mtd Method.
- * @param hnd Handler.
- * @param async Async.
- */
- MethodDescriptor(Method mtd, Object hnd, boolean async) {
- this.mtd = mtd;
- this.hnd = hnd;
- this.async = async;
-
- returnType = mtd.getGenericReturnType();
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/ignite/blob/54a24746/modules/control-center-agent/src/main/java/org/apache/ignite/agent/remote/WebSocketSender.java
----------------------------------------------------------------------
diff --git a/modules/control-center-agent/src/main/java/org/apache/ignite/agent/remote/WebSocketSender.java b/modules/control-center-agent/src/main/java/org/apache/ignite/agent/remote/WebSocketSender.java
deleted file mode 100644
index 655ff85..0000000
--- a/modules/control-center-agent/src/main/java/org/apache/ignite/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.agent.remote;
-
-import com.google.gson.JsonObject;
-
-/**
- * Sender for messages to web-socket.
- */
-public interface WebSocketSender {
- /**
- * Send message.
- * @param msg Message.
- * @return {@code true} if message sent successfully.
- */
- public boolean send(String msg);
-
- /**
- * Send message.
- * @param msg Message.
- * @return {@code true} if message sent successfully.
- */
- public boolean send(JsonObject msg);
-}
http://git-wip-us.apache.org/repos/asf/ignite/blob/54a24746/modules/control-center-agent/src/main/java/org/apache/ignite/console/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
new file mode 100644
index 0000000..6259cca
--- /dev/null
+++ b/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/AgentConfiguration.java
@@ -0,0 +1,255 @@
+/*
+ * 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.beust.jcommander.Parameter;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.net.URL;
+import java.util.Properties;
+
+/**
+ * Agent configuration.
+ */
+public class AgentConfiguration {
+ /** Default server port. */
+ public static final int DFLT_SERVER_PORT = 3001;
+
+ /** Default Ignite node HTTP port. */
+ public static final int DFLT_NODE_PORT = 8080;
+
+ /** Default path to agent property file. */
+ public static final String DFLT_CFG_PATH = "default.properties";
+
+ /** Default server URI. */
+ private static final String DFLT_SERVER_URI = "wss://localhost:3001";
+
+ /** Default Ignite node HTTP URI. */
+ private static final String DFLT_NODE_URI = "http://localhost:8080";
+
+ /** */
+ @Parameter(names = {"-t", "--token"}, description = "User's security token used to establish connection to Ignite Console.")
+ private String tok;
+
+ /** */
+ @Parameter(names = {"-s", "--server-uri"}, description = "URI for connect to Ignite Console via web-socket protocol" +
+ " " +
+ " Default value: " + DFLT_SERVER_URI)
+ private String srvUri;
+
+ /** */
+ @Parameter(names = {"-n", "--node-uri"}, description = "URI for connect to Ignite node REST server" +
+ " " +
+ " Default value: " + DFLT_NODE_URI)
+ private String nodeUri;
+
+ /** URI for connect to Ignite demo node REST server */
+ private String demoNodeUri;
+
+ /** */
+ @Parameter(names = {"-c", "--config"}, description = "Path to agent property file" +
+ " " +
+ " Default value: " + DFLT_CFG_PATH)
+ private String cfgPath;
+
+ /** */
+ @Parameter(names = {"-d", "--driver-folder"}, description = "Path to folder with JDBC drivers" +
+ " " +
+ " Default value: ./jdbc-drivers")
+ private String driversFolder;
+
+ /** */
+ @Parameter(names = { "-h", "--help" }, help = true, description = "Print this help message")
+ private Boolean help;
+
+ /**
+ * @return Token.
+ */
+ public String token() {
+ return tok;
+ }
+
+ /**
+ * @param tok Token.
+ */
+ public void token(String tok) {
+ this.tok = tok;
+ }
+
+ /**
+ * @return Server URI.
+ */
+ public String serverUri() {
+ return srvUri;
+ }
+
+ /**
+ * @param srvUri URI.
+ */
+ public void serverUri(String srvUri) {
+ this.srvUri = srvUri;
+ }
+
+ /**
+ * @return Node URI.
+ */
+ public String nodeUri() {
+ return nodeUri;
+ }
+
+ /**
+ * @param nodeUri Node URI.
+ */
+ public void nodeUri(String nodeUri) {
+ this.nodeUri = nodeUri;
+ }
+
+ /**
+ * @return Demo node URI.
+ */
+ public String demoNodeUri() {
+ return demoNodeUri;
+ }
+
+ /**
+ * @param demoNodeUri Demo node URI.
+ */
+ public void demoNodeUri(String demoNodeUri) {
+ this.demoNodeUri = demoNodeUri;
+ }
+
+ /**
+ * @return Configuration path.
+ */
+ public String configPath() {
+ return cfgPath == null ? DFLT_CFG_PATH : cfgPath;
+ }
+
+ /**
+ * @return Configured drivers folder.
+ */
+ public String driversFolder() {
+ return driversFolder;
+ }
+
+ /**
+ * @param driversFolder Driver folder.
+ */
+ public void driversFolder(String driversFolder) {
+ this.driversFolder = driversFolder;
+ }
+
+ /**
+ * @return {@code true} If agent options usage should be printed.
+ */
+ public Boolean help() {
+ return help != null ? help : false;
+ }
+
+ /**
+ * @param cfgUrl URL.
+ */
+ public void load(URL cfgUrl) throws IOException {
+ Properties props = new Properties();
+
+ try (Reader reader = new InputStreamReader(cfgUrl.openStream())) {
+ props.load(reader);
+ }
+
+ String val = (String)props.remove("token");
+
+ if (val != null)
+ token(val);
+
+ val = (String)props.remove("server-uri");
+
+ if (val != null)
+ serverUri(val);
+
+ val = (String)props.remove("node-uri");
+
+ if (val != null)
+ nodeUri(val);
+
+ val = (String)props.remove("driver-folder");
+
+ if (val != null)
+ driversFolder(val);
+ }
+
+ /**
+ * @param cmd Command.
+ */
+ public void merge(AgentConfiguration cmd) {
+ if (tok == null)
+ token(cmd.token());
+
+ if (srvUri == null)
+ serverUri(cmd.serverUri());
+
+ if (srvUri == null)
+ serverUri(DFLT_SERVER_URI);
+
+ if (nodeUri == null)
+ nodeUri(cmd.nodeUri());
+
+ if (nodeUri == null)
+ nodeUri(DFLT_NODE_URI);
+
+ if (driversFolder == null)
+ driversFolder(cmd.driversFolder());
+ }
+
+ /** {@inheritDoc} */
+ @Override public String toString() {
+ StringBuilder sb = new StringBuilder();
+
+ if (tok != null && tok.length() > 0) {
+ sb.append("User's security token : ");
+
+ if (tok.length() > 4) {
+ 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('\n');
+ }
+
+ sb.append("URI to Ignite node REST server: ").append(nodeUri == null ? DFLT_NODE_URI : nodeUri).append('\n');
+ sb.append("URI to Ignite Console server : ").append(srvUri == null ? DFLT_SERVER_URI : srvUri).append('\n');
+ sb.append("Path to agent property file : ").append(configPath()).append('\n');
+
+ String drvFld = driversFolder();
+
+ if (drvFld == null) {
+ File agentHome = AgentUtils.getAgentHome();
+
+ if (agentHome != null)
+ drvFld = new File(agentHome, "jdbc-drivers").getPath();
+ }
+
+ sb.append("Path to JDBC drivers folder : ").append(drvFld);
+
+ return sb.toString();
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/54a24746/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
new file mode 100644
index 0000000..ed08d78
--- /dev/null
+++ b/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/AgentLauncher.java
@@ -0,0 +1,164 @@
+/*
+ * 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.beust.jcommander.JCommander;
+import java.io.File;
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.Arrays;
+
+import com.beust.jcommander.ParameterException;
+import org.apache.ignite.console.agent.handlers.RestExecutor;
+import org.apache.log4j.Logger;
+import org.eclipse.jetty.util.ssl.SslContextFactory;
+import org.eclipse.jetty.websocket.client.WebSocketClient;
+
+import static org.apache.ignite.console.agent.AgentConfiguration.DFLT_SERVER_PORT;
+
+/**
+ * Control Center Agent launcher.
+ */
+public class AgentLauncher {
+ /** */
+ private static final Logger log = Logger.getLogger(AgentLauncher.class.getName());
+
+ /** */
+ private static final int RECONNECT_INTERVAL = 3000;
+
+ /**
+ * @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();
+
+ JCommander jCommander = new JCommander(cfg);
+
+ String osName = System.getProperty("os.name").toLowerCase();
+
+ jCommander.setProgramName("ignite-web-agent." + (osName.contains("win") ? "bat" : "sh"));
+
+ try {
+ jCommander.parse(args);
+ }
+ catch (ParameterException pe) {
+ log.error("Failed to parse command line parameters: " + Arrays.toString(args), pe);
+
+ jCommander.usage();
+
+ return;
+ }
+
+ String prop = cfg.configPath();
+
+ AgentConfiguration propCfg = new AgentConfiguration();
+
+ try {
+ File f = AgentUtils.resolvePath(prop);
+
+ if (f == null)
+ 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);
+ }
+
+ cfg.merge(propCfg);
+
+ if (cfg.help()) {
+ jCommander.usage();
+
+ return;
+ }
+
+ System.out.println();
+ System.out.println("Agent configuration:");
+ System.out.println(cfg);
+ System.out.println();
+
+ if (cfg.token() == null) {
+ String webHost;
+
+ try {
+ webHost = new URI(cfg.serverUri()).getHost();
+ }
+ catch (URISyntaxException e) {
+ log.error("Failed to parse Ignite Web Console uri", e);
+
+ return;
+ }
+
+ System.out.println("Security token is required to establish connection to the web console.");
+ System.out.println(String.format("It is available on the Profile page: https://%s/profile", webHost));
+
+ System.out.print("Enter security token: ");
+
+ cfg.token(System.console().readLine().trim());
+ }
+
+ RestExecutor restExecutor = new RestExecutor(cfg);
+
+ restExecutor.start();
+
+ try {
+ SslContextFactory sslCtxFactory = new SslContextFactory();
+
+ // Workaround for use self-signed certificate:
+ if (Boolean.getBoolean("trust.all"))
+ sslCtxFactory.setTrustAll(true);
+
+ WebSocketClient client = new WebSocketClient(sslCtxFactory);
+
+ client.setMaxIdleTimeout(Long.MAX_VALUE);
+
+ client.start();
+
+ try {
+ while (!Thread.interrupted()) {
+ AgentSocket agentSock = new AgentSocket(cfg, restExecutor);
+
+ log.info("Connecting to: " + cfg.serverUri());
+
+ URI uri = URI.create(cfg.serverUri());
+
+ if (uri.getPort() == -1)
+ uri = URI.create(cfg.serverUri() + ":" + DFLT_SERVER_PORT);
+
+ client.connect(agentSock, uri);
+
+ agentSock.waitForClose();
+
+ Thread.sleep(RECONNECT_INTERVAL);
+ }
+ }
+ finally {
+ client.stop();
+ }
+ }
+ finally {
+ restExecutor.stop();
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/54a24746/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
new file mode 100644
index 0000000..80816fa
--- /dev/null
+++ b/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/AgentSocket.java
@@ -0,0 +1,189 @@
+/*
+ * 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.warn(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());
+
+ 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/54a24746/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
new file mode 100644
index 0000000..349eea1
--- /dev/null
+++ b/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/AgentUtils.java
@@ -0,0 +1,115 @@
+/*
+ * 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 org.apache.log4j.Logger;
+
+import java.io.File;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.security.ProtectionDomain;
+
+/**
+ * Utility methods.
+ */
+public class AgentUtils {
+ /** */
+ private static final Logger log = Logger.getLogger(AgentUtils.class.getName());
+
+ /**
+ * Default constructor.
+ */
+ private AgentUtils() {
+ // No-op.
+ }
+
+ /**
+ * @param path Path to normalize.
+ * @return Normalized file path.
+ */
+ public static String normalizePath(String path) {
+ return path != null ? path.replace('\\', '/') : null;
+ }
+
+ /**
+ * @return App folder.
+ */
+ public static File getAgentHome() {
+ try {
+ ProtectionDomain domain = AgentLauncher.class.getProtectionDomain();
+
+ // Should not happen, but to make sure our code is not broken.
+ if (domain == null || domain.getCodeSource() == null || domain.getCodeSource().getLocation() == null) {
+ log.warn("Failed to resolve agent jar location!");
+
+ return null;
+ }
+
+ // Resolve path to class-file.
+ URI classesUri = domain.getCodeSource().getLocation().toURI();
+
+ boolean win = System.getProperty("os.name").toLowerCase().contains("win");
+
+ // Overcome UNC path problem on Windows (http://www.tomergabel.com/JavaMishandlesUNCPathsOnWindows.aspx)
+ if (win && classesUri.getAuthority() != null)
+ classesUri = new URI(classesUri.toString().replace("file://", "file:/"));
+
+ return new File(classesUri).getParentFile();
+ }
+ catch (URISyntaxException | SecurityException ignored) {
+ log.warn("Failed to resolve agent jar location!");
+
+ return null;
+ }
+ }
+
+ /**
+ * Gets file associated with path.
+ * <p>
+ * First check if path is relative to agent home.
+ * If not, check if path is absolute.
+ * If all checks fail, then {@code null} is returned.
+ * <p>
+ *
+ * @param path Path to resolve.
+ * @return Resolved path as file, or {@code null} if path cannot be resolved.
+ */
+ public static File resolvePath(String path) {
+ assert path != null;
+
+ File home = getAgentHome();
+
+ if (home != null) {
+ File file = new File(home, normalizePath(path));
+
+ if (file.exists())
+ return file;
+ }
+
+ /*
+ * 2. Check given path as absolute.
+ */
+
+ File file = new File(path);
+
+ if (file.exists())
+ return file;
+
+ return null;
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/54a24746/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
new file mode 100644
index 0000000..48d5236
--- /dev/null
+++ b/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/handlers/DatabaseMetadataExtractor.java
@@ -0,0 +1,205 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.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/54a24746/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
new file mode 100644
index 0000000..ee6742a
--- /dev/null
+++ b/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/handlers/RestExecutor.java
@@ -0,0 +1,195 @@
+/*
+ * 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 + "]");
+
+ URIBuilder builder = new URIBuilder(demo ? cfg.demoNodeUri() : 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 new RestResult(resp.getStatusLine().getStatusCode(), new String(out.toByteArray(), charset));
+ }
+ catch (ConnectException e) {
+ log.debug("Failed connect to node and execute REST command [uri=" + builder.build() + "]");
+
+ return new RestResult(404, "Failed connect to node and execute REST command.");
+ }
+ }
+
+ /**
+ * Enable test-drive SQL.
+ */
+ @Remote
+ public boolean startDemoSQL() {
+ return AgentSqlDemo.testDrive(cfg);
+ }
+
+ /**
+ * Request result.
+ */
+ public static class RestResult {
+ /** Status code. */
+ private int code;
+
+ /** Message. */
+ private String message;
+
+ /**
+ * @param code Code.
+ * @param msg Message.
+ */
+ public RestResult(int code, String msg) {
+ this.code = code;
+ message = msg;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/54a24746/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
new file mode 100644
index 0000000..71b2bc0
--- /dev/null
+++ b/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/remote/Remote.java
@@ -0,0 +1,37 @@
+/*
+ * 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;
+}