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; +}
