ignite-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From akuznet...@apache.org
Subject [21/21] ignite git commit: IGNITE-843 Implemented Web Console.
Date Tue, 17 May 2016 16:23:03 GMT
IGNITE-843 Implemented Web Console.


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/eb5ac0ae
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/eb5ac0ae
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/eb5ac0ae

Branch: refs/heads/ignite-1.6
Commit: eb5ac0ae5db711f75804842b7a39d3d6f80ffcd4
Parents: a284d05
Author: AKuznetsov <akuznetsov@gridgain.com>
Authored: Tue May 17 23:21:25 2016 +0700
Committer: AKuznetsov <akuznetsov@gridgain.com>
Committed: Tue May 17 23:21:29 2016 +0700

----------------------------------------------------------------------
 .../parser/dialect/DB2MetadataDialect.java      |    2 +-
 modules/web-agent/.gitignore                    |    2 +
 modules/web-agent/README.txt                    |   87 +
 .../web-agent/assembly/release-web-agent.xml    |   74 +
 modules/web-agent/bin/ignite-web-agent.bat      |   70 +
 modules/web-agent/bin/ignite-web-agent.sh       |   87 +
 modules/web-agent/demo/README.txt               |    4 +
 modules/web-agent/demo/db-init.sql              |  102 +
 modules/web-agent/jdbc-drivers/README.txt       |   10 +
 modules/web-agent/logs/README.txt               |    5 +
 modules/web-agent/pom.xml                       |  169 +
 .../console/agent/AgentConfiguration.java       |  255 ++
 .../ignite/console/agent/AgentLauncher.java     |  337 ++
 .../apache/ignite/console/agent/AgentUtils.java |  111 +
 .../console/agent/handlers/AbstractHandler.java |  110 +
 .../console/agent/handlers/DatabaseHandler.java |  298 ++
 .../console/agent/handlers/RestHandler.java     |  276 ++
 .../ignite/console/demo/AgentClusterDemo.java   |  614 ++++
 .../ignite/console/demo/AgentMetadataDemo.java  |   92 +
 .../apache/ignite/console/demo/model/Car.java   |  152 +
 .../ignite/console/demo/model/Country.java      |  152 +
 .../ignite/console/demo/model/Department.java   |  152 +
 .../ignite/console/demo/model/Employee.java     |  356 ++
 .../ignite/console/demo/model/Parking.java      |  152 +
 .../src/main/resources/log4j.properties         |   53 +
 modules/web-console/DEVNOTES.txt                |   28 +
 modules/web-console/README.txt                  |   36 +
 modules/web-console/licenses/apache-2.0.txt     |  202 ++
 modules/web-console/pom.xml                     |   69 +
 modules/web-console/src/main/js/.babelrc        |    3 +
 modules/web-console/src/main/js/.eslintrc       |  197 ++
 modules/web-console/src/main/js/.gitignore      |   11 +
 .../src/main/js/app/data/colors.json            |   22 +
 .../src/main/js/app/data/countries.json         |   94 +
 .../src/main/js/app/data/demo-info.json         |   14 +
 .../src/main/js/app/data/event-types.json       |  169 +
 .../src/main/js/app/data/getting-started.json   |  109 +
 .../src/main/js/app/data/java-classes.json      |   18 +
 .../src/main/js/app/data/java-keywords.json     |   55 +
 .../src/main/js/app/data/java-primitives.json   |    9 +
 .../src/main/js/app/decorator/select.js         |   77 +
 .../src/main/js/app/decorator/tooltip.js        |   56 +
 .../app/directives/bs-affix-update.directive.js |   34 +
 .../js/app/directives/centered/centered.css     |   37 +
 .../directives/centered/centered.directive.js   |   26 +
 .../hide-on-state-change.directive.js           |   31 +
 .../information/information.directive.js        |   30 +
 .../app/directives/information/information.jade |   20 +
 .../app/directives/information/information.scss |   56 +
 .../ui-ace-docker/ui-ace-docker.controller.js   |   33 +
 .../ui-ace-docker/ui-ace-docker.directive.js    |   46 +
 .../directives/ui-ace-docker/ui-ace-docker.jade |   31 +
 .../ui-ace-java/ui-ace-java.controller.js       |   32 +
 .../ui-ace-java/ui-ace-java.directive.js        |  133 +
 .../app/directives/ui-ace-java/ui-ace-java.jade |   22 +
 .../ui-ace-pojos/ui-ace-pojos.controller.js     |   95 +
 .../ui-ace-pojos/ui-ace-pojos.directive.js      |   46 +
 .../directives/ui-ace-pojos/ui-ace-pojos.jade   |   40 +
 .../ui-ace-pom/ui-ace-pom.controller.js         |   33 +
 .../ui-ace-pom/ui-ace-pom.directive.js          |   41 +
 .../app/directives/ui-ace-pom/ui-ace-pom.jade   |   17 +
 .../js/app/directives/ui-ace-tabs.directive.js  |   23 +
 .../ui-ace-xml/ui-ace-xml.controller.js         |   27 +
 .../ui-ace-xml/ui-ace-xml.directive.js          |  133 +
 .../app/directives/ui-ace-xml/ui-ace-xml.jade   |   17 +
 .../src/main/js/app/filters/byName.filter.js    |   23 +
 .../src/main/js/app/filters/hasPojo.filter.js   |   18 +
 .../src/main/js/app/helpers/jade/mixins.jade    |  587 ++++
 modules/web-console/src/main/js/app/index.js    |  241 ++
 .../src/main/js/app/modules/Demo/Demo.module.js |  165 +
 .../QueryNotebooks/QueryNotebooks.provider.js   |  115 +
 .../js/app/modules/Version/Version.provider.js  |   32 +
 .../src/main/js/app/modules/ace.module.js       |  269 ++
 .../js/app/modules/branding/branding.module.js  |   46 +
 .../app/modules/branding/branding.provider.js   |  111 +
 .../app/modules/branding/features.directive.js  |   35 +
 .../js/app/modules/branding/footer.directive.js |   34 +
 .../modules/branding/header-logo.directive.js   |   34 +
 .../js/app/modules/branding/header-logo.jade    |   18 +
 .../modules/branding/header-title.directive.js  |   35 +
 .../branding/powered-by-apache.directive.js     |   35 +
 .../app/modules/branding/powered-by-apache.jade |   18 +
 .../js/app/modules/branding/terms.directive.js  |   30 +
 .../configuration/EventGroups.provider.js       |   30 +
 .../modules/configuration/Sidebar.provider.js   |   39 +
 .../configuration/configuration.module.js       |   41 +
 .../configuration/generator/Docker.service.js   |   78 +
 .../configuration/generator/Java.service.js     |   21 +
 .../configuration/generator/Pom.service.js      |  214 ++
 .../configuration/generator/Xml.service.js      |   21 +
 .../modules/configuration/sidebar.directive.js  |   30 +
 .../modules/dialog/dialog-content.directive.js  |   31 +
 .../modules/dialog/dialog-title.directive.js    |   31 +
 .../js/app/modules/dialog/dialog.controller.js  |   40 +
 .../js/app/modules/dialog/dialog.directive.js   |   32 +
 .../js/app/modules/dialog/dialog.factory.js     |   32 +
 .../src/main/js/app/modules/dialog/dialog.jade  |   26 +
 .../main/js/app/modules/dialog/dialog.module.js |   32 +
 .../field/bs-select-placeholder.directive.js    |   46 +
 .../js/app/modules/form/field/down.directive.js |   43 +
 .../modules/form/field/dropdown.directive.js    |   84 +
 .../js/app/modules/form/field/dropdown.jade     |   61 +
 .../main/js/app/modules/form/field/field.css    |   23 +
 .../app/modules/form/field/field.directive.js   |   44 +
 .../main/js/app/modules/form/field/field.jade   |   27 +
 .../field/form-control-feedback.directive.js    |   40 +
 .../form/field/input/autofocus.directive.js     |   30 +
 .../form/field/input/checkbox.directive.js      |   67 +
 .../app/modules/form/field/input/checkbox.jade  |   30 +
 .../form/field/input/datalist.directive.js      |  123 +
 .../app/modules/form/field/input/datalist.jade  |   51 +
 .../form/field/input/number.directive.js        |   77 +
 .../js/app/modules/form/field/input/number.jade |   50 +
 .../js/app/modules/form/field/input/text.css    |   41 +
 .../modules/form/field/input/text.directive.js  |  124 +
 .../js/app/modules/form/field/input/text.jade   |   48 +
 .../app/modules/form/field/label.directive.js   |   47 +
 .../app/modules/form/field/tooltip.directive.js |   49 +
 .../js/app/modules/form/field/up.directive.js   |   44 +
 .../src/main/js/app/modules/form/form.module.js |  101 +
 .../js/app/modules/form/group/add.directive.js  |   40 +
 .../app/modules/form/group/group.directive.js   |   81 +
 .../main/js/app/modules/form/group/group.jade   |   21 +
 .../app/modules/form/group/table.directive.js   |   29 +
 .../main/js/app/modules/form/group/table.jade   |   17 +
 .../app/modules/form/group/tooltip.directive.js |   40 +
 .../app/modules/form/panel/chevron.directive.js |   53 +
 .../app/modules/form/panel/panel.directive.js   |   37 +
 .../app/modules/form/panel/revert.directive.js  |   53 +
 .../form/validator/ipaddress.directive.js       |   86 +
 .../validator/java-built-in-class.directive.js  |   31 +
 .../form/validator/java-identifier.directive.js |   31 +
 .../form/validator/java-keywords.directive.js   |   43 +
 .../validator/java-package-name.directive.js    |   31 +
 .../java-package-specified.directive.js         |   34 +
 .../form/validator/property-unique.directive.js |   47 +
 .../property-value-specified.directive.js       |   31 +
 .../modules/form/validator/unique.directive.js  |   49 +
 .../getting-started/GettingStarted.provider.js  |  112 +
 .../src/main/js/app/modules/loading/loading.css |   73 +
 .../js/app/modules/loading/loading.directive.js |   51 +
 .../main/js/app/modules/loading/loading.jade    |   23 +
 .../js/app/modules/loading/loading.module.js    |   26 +
 .../js/app/modules/loading/loading.service.js   |   48 +
 .../js/app/modules/navbar/Navbar.provider.js    |   28 +
 .../js/app/modules/navbar/Userbar.provider.js   |   28 +
 .../js/app/modules/navbar/navbar.directive.js   |   30 +
 .../main/js/app/modules/navbar/navbar.module.js |   33 +
 .../js/app/modules/navbar/userbar.directive.js  |   48 +
 .../src/main/js/app/modules/socket.module.js    |   41 +
 .../main/js/app/modules/states/admin.state.js   |   34 +
 .../app/modules/states/configuration.state.js   |  202 ++
 .../caches/concurrency.directive.js             |   27 +
 .../configuration/caches/concurrency.jade       |   65 +
 .../configuration/caches/general.directive.js   |   27 +
 .../states/configuration/caches/general.jade    |   65 +
 .../configuration/caches/memory.directive.js    |   27 +
 .../states/configuration/caches/memory.jade     |   88 +
 .../configuration/caches/query.directive.js     |   27 +
 .../states/configuration/caches/query.jade      |   93 +
 .../configuration/caches/rebalance.directive.js |   27 +
 .../states/configuration/caches/rebalance.jade  |   65 +
 .../caches/server-near-cache.directive.js       |   27 +
 .../configuration/caches/server-near-cache.jade |   45 +
 .../caches/statistics.directive.js              |   27 +
 .../states/configuration/caches/statistics.jade |   37 +
 .../configuration/caches/store.directive.js     |   27 +
 .../states/configuration/caches/store.jade      |  266 ++
 .../configuration/clusters/atomic.directive.js  |   27 +
 .../states/configuration/clusters/atomic.jade   |   53 +
 .../configuration/clusters/binary.directive.js  |   27 +
 .../states/configuration/clusters/binary.jade   |  100 +
 .../clusters/communication.directive.js         |   27 +
 .../configuration/clusters/communication.jade   |   90 +
 .../clusters/connector.directive.js             |   27 +
 .../configuration/clusters/connector.jade       |  103 +
 .../clusters/deployment.directive.js            |   27 +
 .../configuration/clusters/deployment.jade      |  112 +
 .../clusters/discovery.directive.js             |   27 +
 .../configuration/clusters/discovery.jade       |   81 +
 .../configuration/clusters/events.directive.js  |   27 +
 .../states/configuration/clusters/events.jade   |   37 +
 .../configuration/clusters/general.directive.js |   27 +
 .../states/configuration/clusters/general.jade  |   70 +
 .../general/discovery/cloud.directive.js        |   27 +
 .../clusters/general/discovery/cloud.jade       |  125 +
 .../general/discovery/google.directive.js       |   27 +
 .../clusters/general/discovery/google.jade      |   35 +
 .../general/discovery/jdbc.directive.js         |   27 +
 .../clusters/general/discovery/jdbc.jade        |   24 +
 .../general/discovery/multicast.directive.js    |   27 +
 .../clusters/general/discovery/multicast.jade   |  109 +
 .../clusters/general/discovery/s3.directive.js  |   27 +
 .../clusters/general/discovery/s3.jade          |   25 +
 .../general/discovery/shared.directive.js       |   27 +
 .../clusters/general/discovery/shared.jade      |   23 +
 .../clusters/general/discovery/vm.directive.js  |   27 +
 .../clusters/general/discovery/vm.jade          |   90 +
 .../general/discovery/zookeeper.directive.js    |   27 +
 .../clusters/general/discovery/zookeeper.jade   |   73 +
 .../bounded-exponential-backoff.directive.js    |   27 +
 .../bounded-exponential-backoff.jade            |   27 +
 .../zookeeper/retrypolicy/custom.directive.js   |   27 +
 .../discovery/zookeeper/retrypolicy/custom.jade |   22 +
 .../exponential-backoff.directive.js            |   27 +
 .../retrypolicy/exponential-backoff.jade        |   27 +
 .../zookeeper/retrypolicy/forever.directive.js  |   27 +
 .../zookeeper/retrypolicy/forever.jade          |   22 +
 .../zookeeper/retrypolicy/n-times.directive.js  |   27 +
 .../zookeeper/retrypolicy/n-times.jade          |   25 +
 .../zookeeper/retrypolicy/one-time.directive.js |   27 +
 .../zookeeper/retrypolicy/one-time.jade         |   23 +
 .../retrypolicy/until-elapsed.directive.js      |   27 +
 .../zookeeper/retrypolicy/until-elapsed.jade    |   25 +
 .../configuration/clusters/igfs.directive.js    |   27 +
 .../states/configuration/clusters/igfs.jade     |   37 +
 .../clusters/marshaller.directive.js            |   27 +
 .../configuration/clusters/marshaller.jade      |   69 +
 .../configuration/clusters/metrics.directive.js |   27 +
 .../states/configuration/clusters/metrics.jade  |   50 +
 .../configuration/clusters/ssl.directive.js     |   27 +
 .../states/configuration/clusters/ssl.jade      |  108 +
 .../configuration/clusters/swap.directive.js    |   27 +
 .../states/configuration/clusters/swap.jade     |   67 +
 .../configuration/clusters/thread.directive.js  |   27 +
 .../states/configuration/clusters/thread.jade   |   48 +
 .../configuration/clusters/time.directive.js    |   27 +
 .../states/configuration/clusters/time.jade     |   47 +
 .../clusters/transactions.directive.js          |   27 +
 .../configuration/clusters/transactions.jade    |   59 +
 .../configuration/domains/general.directive.js  |   27 +
 .../states/configuration/domains/general.jade   |   46 +
 .../configuration/domains/query.directive.js    |   27 +
 .../states/configuration/domains/query.jade     |  169 +
 .../configuration/domains/store.directive.js    |   27 +
 .../states/configuration/domains/store.jade     |  126 +
 .../states/configuration/igfs/dual.directive.js |   27 +
 .../modules/states/configuration/igfs/dual.jade |   42 +
 .../igfs/fragmentizer.directive.js              |   27 +
 .../states/configuration/igfs/fragmentizer.jade |   43 +
 .../configuration/igfs/general.directive.js     |   27 +
 .../states/configuration/igfs/general.jade      |   53 +
 .../states/configuration/igfs/ipc.directive.js  |   27 +
 .../modules/states/configuration/igfs/ipc.jade  |   57 +
 .../states/configuration/igfs/misc.directive.js |   27 +
 .../modules/states/configuration/igfs/misc.jade |  108 +
 .../configuration/igfs/secondary.directive.js   |   27 +
 .../states/configuration/igfs/secondary.jade    |   44 +
 .../configuration/preview-panel.directive.js    |  239 ++
 .../summary/summary-tabs.directive.js           |   50 +
 .../configuration/summary/summary.controller.js |  360 ++
 .../configuration/summary/summary.resource.js   |   40 +
 .../main/js/app/modules/states/logout.state.js  |   36 +
 .../js/app/modules/states/password.state.js     |   46 +
 .../main/js/app/modules/states/profile.state.js |   34 +
 .../main/js/app/modules/states/signin.state.js  |   52 +
 .../src/main/js/app/modules/states/sql.state.js |   46 +
 .../main/js/app/modules/user/Auth.service.js    |   73 +
 .../main/js/app/modules/user/User.service.js    |   65 +
 .../src/main/js/app/modules/user/user.module.js |   28 +
 .../js/app/services/AgentMonitor.service.js     |  337 ++
 .../main/js/app/services/ChartColors.service.js |   22 +
 .../main/js/app/services/Countries.service.js   |   31 +
 .../main/js/app/services/InetAddress.service.js |   53 +
 .../main/js/app/services/JavaTypes.service.js   |   84 +
 .../src/main/js/app/services/cleanup.service.js |   44 +
 .../src/main/js/app/services/confirm.service.js |   70 +
 .../src/main/js/build/system.config.js          |  415 +++
 .../src/main/js/controllers/admin-controller.js |   92 +
 .../main/js/controllers/caches-controller.js    |  493 +++
 .../main/js/controllers/clusters-controller.js  |  555 +++
 .../src/main/js/controllers/common-module.js    | 1759 ++++++++++
 .../main/js/controllers/domains-controller.js   | 1786 ++++++++++
 .../src/main/js/controllers/igfs-controller.js  |  441 +++
 .../main/js/controllers/profile-controller.js   |   84 +
 .../src/main/js/controllers/sql-controller.js   | 1568 +++++++++
 .../src/main/js/generator/generator-common.js   |  570 ++++
 .../src/main/js/generator/generator-java.js     | 3179 ++++++++++++++++++
 .../src/main/js/generator/generator-optional.js |   25 +
 .../main/js/generator/generator-properties.js   |  149 +
 .../src/main/js/generator/generator-readme.js   |   85 +
 .../src/main/js/generator/generator-xml.js      | 1769 ++++++++++
 .../src/main/js/gulpfile.babel.js/index.js      |   26 +
 .../src/main/js/gulpfile.babel.js/paths.js      |  101 +
 .../main/js/gulpfile.babel.js/tasks/build.js    |   21 +
 .../main/js/gulpfile.babel.js/tasks/bundle.js   |   76 +
 .../main/js/gulpfile.babel.js/tasks/clean.js    |   35 +
 .../main/js/gulpfile.babel.js/tasks/connect.js  |   47 +
 .../src/main/js/gulpfile.babel.js/tasks/copy.js |   57 +
 .../main/js/gulpfile.babel.js/tasks/eslint.js   |   43 +
 .../gulpfile.babel.js/tasks/ignite-modules.js   |   56 +
 .../src/main/js/gulpfile.babel.js/tasks/jade.js |   40 +
 .../src/main/js/gulpfile.babel.js/tasks/sass.js |   25 +
 .../main/js/gulpfile.babel.js/tasks/watch.js    |   39 +
 .../src/main/js/ignite_modules/README.txt       |    6 +
 .../src/main/js/ignite_modules/index.js         |   27 +
 modules/web-console/src/main/js/package.json    |  271 ++
 .../web-console/src/main/js/public/favicon.ico  |  Bin 0 -> 1150 bytes
 .../src/main/js/public/images/cache.png         |  Bin 0 -> 23700 bytes
 .../src/main/js/public/images/cluster.png       |  Bin 0 -> 29670 bytes
 .../src/main/js/public/images/docker.png        |  Bin 0 -> 521 bytes
 .../src/main/js/public/images/domains.png       |  Bin 0 -> 23828 bytes
 .../src/main/js/public/images/igfs.png          |  Bin 0 -> 14307 bytes
 .../src/main/js/public/images/ignite-logo.png   |  Bin 0 -> 1982 bytes
 .../main/js/public/images/ignite-logo@2x.png    |  Bin 0 -> 3325 bytes
 .../src/main/js/public/images/ignite-puzzle.png |  Bin 0 -> 71974 bytes
 .../src/main/js/public/images/java.png          |  Bin 0 -> 170 bytes
 .../src/main/js/public/images/pb-ignite.png     |  Bin 0 -> 3493 bytes
 .../src/main/js/public/images/pb-ignite@2x.png  |  Bin 0 -> 8558 bytes
 .../src/main/js/public/images/query-chart.png   |  Bin 0 -> 16637 bytes
 .../main/js/public/images/query-metadata.png    |  Bin 0 -> 32298 bytes
 .../src/main/js/public/images/query-table.png   |  Bin 0 -> 42253 bytes
 .../src/main/js/public/images/summary.png       |  Bin 0 -> 31997 bytes
 .../src/main/js/public/images/xml.png           |  Bin 0 -> 232 bytes
 .../public/stylesheets/_bootstrap-custom.scss   |   65 +
 .../stylesheets/_bootstrap-variables.scss       |  891 +++++
 .../stylesheets/_font-awesome-custom.scss       |   31 +
 .../src/main/js/public/stylesheets/style.scss   | 2128 ++++++++++++
 .../main/js/public/stylesheets/variables.scss   |   28 +
 modules/web-console/src/main/js/serve.js        |  116 +
 modules/web-console/src/main/js/serve/agent.js  |  601 ++++
 .../src/main/js/serve/agent_dists/README.txt    |    7 +
 modules/web-console/src/main/js/serve/app.js    |   42 +
 .../web-console/src/main/js/serve/browser.js    |  304 ++
 .../main/js/serve/config/settings.json.sample   |   26 +
 .../web-console/src/main/js/serve/configure.js  |   83 +
 .../web-console/src/main/js/serve/keys/test.crt |   13 +
 .../web-console/src/main/js/serve/keys/test.key |   18 +
 modules/web-console/src/main/js/serve/mail.js   |   75 +
 modules/web-console/src/main/js/serve/mongo.js  |  620 ++++
 .../src/main/js/serve/routes/admin.js           |  126 +
 .../src/main/js/serve/routes/agent.js           |   82 +
 .../src/main/js/serve/routes/caches.js          |  132 +
 .../src/main/js/serve/routes/clusters.js        |  146 +
 .../src/main/js/serve/routes/demo.js            |  135 +
 .../src/main/js/serve/routes/demo/caches.json   |   87 +
 .../src/main/js/serve/routes/demo/clusters.json |   50 +
 .../src/main/js/serve/routes/demo/domains.json  |  307 ++
 .../src/main/js/serve/routes/demo/igfss.json    |   10 +
 .../src/main/js/serve/routes/domains.js         |  195 ++
 .../src/main/js/serve/routes/igfs.js            |  122 +
 .../src/main/js/serve/routes/notebooks.js       |  121 +
 .../src/main/js/serve/routes/profile.js         |   95 +
 .../src/main/js/serve/routes/public.js          |  228 ++
 .../src/main/js/serve/routes/routes.js          |  103 +
 .../web-console/src/main/js/serve/settings.js   |   84 +
 modules/web-console/src/main/js/views/base.jade |   22 +
 .../src/main/js/views/configuration/caches.jade |   52 +
 .../main/js/views/configuration/clusters.jade   |   60 +
 .../js/views/configuration/domains-import.jade  |  196 ++
 .../main/js/views/configuration/domains.jade    |   66 +
 .../src/main/js/views/configuration/igfs.jade   |   51 +
 .../main/js/views/configuration/sidebar.jade    |   29 +
 .../summary-project-structure.jade              |   27 +
 .../js/views/configuration/summary-tabs.jade    |   25 +
 .../main/js/views/configuration/summary.jade    |  152 +
 .../src/main/js/views/includes/footer.jade      |   23 +
 .../src/main/js/views/includes/header.jade      |   48 +
 .../web-console/src/main/js/views/index.jade    |   66 +
 .../web-console/src/main/js/views/reset.jade    |   48 +
 .../src/main/js/views/settings/admin.jade       |   76 +
 .../src/main/js/views/settings/profile.jade     |   76 +
 .../web-console/src/main/js/views/signin.jade   |  159 +
 .../src/main/js/views/sql/cache-metadata.jade   |   40 +
 .../src/main/js/views/sql/chart-settings.jade   |   40 +
 .../src/main/js/views/sql/notebook-new.jade     |   31 +
 .../src/main/js/views/sql/paragraph-rate.jade   |   31 +
 .../web-console/src/main/js/views/sql/sql.jade  |  180 +
 .../main/js/views/templates/agent-download.jade |   48 +
 .../src/main/js/views/templates/alert.jade      |   21 +
 .../main/js/views/templates/batch-confirm.jade  |   32 +
 .../src/main/js/views/templates/clone.jade      |   31 +
 .../src/main/js/views/templates/confirm.jade    |   31 +
 .../src/main/js/views/templates/demo-info.jade  |   45 +
 .../src/main/js/views/templates/dropdown.jade   |   21 +
 .../js/views/templates/getting-started.jade     |   32 +
 .../src/main/js/views/templates/message.jade    |   26 +
 .../src/main/js/views/templates/pagination.jade |   32 +
 .../src/main/js/views/templates/select.jade     |   26 +
 .../js/views/templates/validation-error.jade    |   25 +
 modules/web-console/src/test/js/routes/agent.js |   94 +
 parent/pom.xml                                  |   12 +
 pom.xml                                         |    9 +
 383 files changed, 40336 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/eb5ac0ae/modules/schema-import-db/src/main/java/org/apache/ignite/schema/parser/dialect/DB2MetadataDialect.java
----------------------------------------------------------------------
diff --git a/modules/schema-import-db/src/main/java/org/apache/ignite/schema/parser/dialect/DB2MetadataDialect.java b/modules/schema-import-db/src/main/java/org/apache/ignite/schema/parser/dialect/DB2MetadataDialect.java
index b191ec3..d277e4b 100644
--- a/modules/schema-import-db/src/main/java/org/apache/ignite/schema/parser/dialect/DB2MetadataDialect.java
+++ b/modules/schema-import-db/src/main/java/org/apache/ignite/schema/parser/dialect/DB2MetadataDialect.java
@@ -30,4 +30,4 @@ public class DB2MetadataDialect extends JdbcMetadataDialect {
         return new HashSet<>(Arrays.asList("SYSIBM", "SYSCAT", "SYSSTAT", "SYSTOOLS", "SYSFUN", "SYSIBMADM",
             "SYSIBMINTERNAL", "SYSIBMTS", "SYSPROC", "SYSPUBLIC"));
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/eb5ac0ae/modules/web-agent/.gitignore
----------------------------------------------------------------------
diff --git a/modules/web-agent/.gitignore b/modules/web-agent/.gitignore
new file mode 100644
index 0000000..57dd45e
--- /dev/null
+++ b/modules/web-agent/.gitignore
@@ -0,0 +1,2 @@
+logs/*.log.*
+jdbc-drivers/*.jar

http://git-wip-us.apache.org/repos/asf/ignite/blob/eb5ac0ae/modules/web-agent/README.txt
----------------------------------------------------------------------
diff --git a/modules/web-agent/README.txt b/modules/web-agent/README.txt
new file mode 100644
index 0000000..0d8d4ac
--- /dev/null
+++ b/modules/web-agent/README.txt
@@ -0,0 +1,87 @@
+Ignite Web Agent
+======================================
+Ignite Web Agent is a java standalone application that allow to connect Ignite Grid to Ignite Web Console.
+Ignite Web Agent communicates with grid nodes via REST interface and connects to Ignite Web Console via web-socket.
+
+Two main functions of Ignite Web Agent:
+ 1. Proxy between Ignite Web Console and Ignite Grid to execute SQL statements and collect metrics for monitoring.
+   You may need to specify URI for connect to Ignite REST server via "-n" option.
+
+ 2. Proxy between Ignite Web Console and user RDBMS to collect database metadata for later CacheTypeMetadata configuration.
+   You may need to copy JDBC driver into "./jdbc-drivers" subfolder or specify path via "-d" option.
+
+Usage example:
+  ignite-web-agent.sh
+
+Configuration file:
+  Should be a file with simple line-oriented format as described here: http://docs.oracle.com/javase/7/docs/api/java/util/Properties.html#load(java.io.Reader)
+
+  Available entries names:
+    token
+    server-uri
+    node-uri
+    driver-folder
+
+  Example configuration file:
+    token=1a2b3c4d5f
+    serverURI=http://console.example.com:3001
+
+Security token:
+  1) By default token will be included into downloaded agent zip.
+  2) You can get/change token in your profile.
+
+Ignite Web agent requirements:
+  1) Ignite node should be started with REST server (move ignite-rest-http folder from lib/optional/ to lib/).
+  2) Pass Ignite node REST server URI to agent.
+
+Options:
+  -h, --help
+     Print this help message
+  -c, --config
+     Path to configuration file
+  -d, --driver-folder
+     Path to folder with JDBC drivers, default value: ./jdbc-drivers
+  -n, --node-uri
+     URI for connect to Ignite REST server, default value:
+     http://localhost:8080
+  -s, --server-uri
+     URI for connect to Ignite Web Console via web-socket protocol, default
+     value: http://localhost:3001
+  -t, --token
+     User's security token
+
+How to build:
+  To build from sources run following command in Ignite project root folder:
+  mvn clean package -pl :ignite-web-agent -am -P web-console -DskipTests=true
+
+Demo of Ignite Web Agent:
+ In order to simplify evaluation demo mode was implemented. To start demo, you need to to click button "Start demo".
+ New tab will be open with prepared demo data.
+
+ 1) Demo for import domain model from database.
+   In this mode an in-memory H2 database will be started.
+   How to evaluate:
+     1.1) Go to Ignite Web Console "Domain model" screen.
+     1.2) Click "Import from database". You should see modal with demo description.
+     1.3) Click "Next" button. You should see list of available schemas.
+     1.4) Click "Next" button. You should see list of available tables.
+     1.5) Click "Next" button. You should see import options.
+     1.6) Select some of them and click "Save".
+
+   2) Demo for SQL.
+     How to evaluate:
+     In this mode internal Ignite node will be started. Cache created and populated with data.
+       2.1) Click "SQL" in Ignite Web Console top menu.
+       2.2) "Demo" notebook with preconfigured queries will be opened.
+       2.3) You can also execute any SQL queries for tables: "Country, Department, Employee", "Parking, Car".
+
+ For example:
+   2.4) Enter SQL statement:
+           SELECT p.name, count(*) AS cnt
+           FROM "ParkingCache".Parking p
+           INNER JOIN "CarCache".Car c
+             ON (p.id) = (c.parkingId)
+           GROUP BY P.NAME
+   2.5) Click "Execute" button. You should get some data in table.
+   2.6) Click charts buttons to see auto generated charts.
+

http://git-wip-us.apache.org/repos/asf/ignite/blob/eb5ac0ae/modules/web-agent/assembly/release-web-agent.xml
----------------------------------------------------------------------
diff --git a/modules/web-agent/assembly/release-web-agent.xml b/modules/web-agent/assembly/release-web-agent.xml
new file mode 100644
index 0000000..eb7da95
--- /dev/null
+++ b/modules/web-agent/assembly/release-web-agent.xml
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+  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.
+-->
+
+<assembly xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+          xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3"
+          xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3 http://maven.apache.org/xsd/assembly-1.1.3.xsd">
+    <id>release-ignite-web-agent</id>
+
+    <formats>
+        <format>zip</format>
+    </formats>
+
+    <fileSets>
+        <fileSet>
+            <directory>${basedir}</directory>
+            <outputDirectory>/</outputDirectory>
+            <includes>
+                <include>jdbc-drivers/README*</include>
+                <include>demo/README*</include>
+                <include>demo/*.sql</include>
+                <include>README*</include>
+                <include>LICENSE*</include>
+                <include>NOTICE*</include>
+            </includes>
+        </fileSet>
+        <fileSet>
+            <directory>${basedir}/bin</directory>
+            <outputDirectory>/</outputDirectory>
+            <filtered>true</filtered>
+            <includes>
+                <include>**/*.bat</include>
+            </includes>
+        </fileSet>
+        <fileSet>
+            <directory>${basedir}/bin</directory>
+            <outputDirectory>/</outputDirectory>
+            <filtered>true</filtered>
+            <fileMode>0755</fileMode>
+            <includes>
+                <include>**/*.sh</include>
+            </includes>
+        </fileSet>
+        <fileSet>
+            <directory>${basedir}/logs</directory>
+            <outputDirectory>/logs</outputDirectory>
+            <includes>
+                <include>README*</include>
+            </includes>
+        </fileSet>
+        <fileSet>
+            <directory>${project.build.directory}</directory>
+            <outputDirectory>/</outputDirectory>
+            <includes>
+                <include>ignite-web-agent-${project.version}.jar</include>
+            </includes>
+        </fileSet>
+    </fileSets>
+</assembly>

http://git-wip-us.apache.org/repos/asf/ignite/blob/eb5ac0ae/modules/web-agent/bin/ignite-web-agent.bat
----------------------------------------------------------------------
diff --git a/modules/web-agent/bin/ignite-web-agent.bat b/modules/web-agent/bin/ignite-web-agent.bat
new file mode 100644
index 0000000..5b3f24c
--- /dev/null
+++ b/modules/web-agent/bin/ignite-web-agent.bat
@@ -0,0 +1,70 @@
+::
+:: 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.
+::
+
+@echo off
+Setlocal EnableDelayedExpansion
+
+if "%OS%" == "Windows_NT"  setlocal
+
+:: Check JAVA_HOME.
+if defined JAVA_HOME  goto checkJdk
+    echo %0, ERROR:
+    echo JAVA_HOME environment variable is not found.
+    echo Please point JAVA_HOME variable to location of JDK 1.7 or JDK 1.8.
+    echo You can also download latest JDK at http://java.com/download.
+goto error_finish
+
+:checkJdk
+:: Check that JDK is where it should be.
+if exist "%JAVA_HOME%\bin\java.exe" goto checkJdkVersion
+    echo %0, ERROR:
+    echo JAVA is not found in JAVA_HOME=%JAVA_HOME%.
+    echo Please point JAVA_HOME variable to installation of JDK 1.7 or JDK 1.8.
+    echo You can also download latest JDK at http://java.com/download.
+goto error_finish
+
+:checkJdkVersion
+"%JAVA_HOME%\bin\java.exe" -version 2>&1 | findstr "1\.[78]\." > nul
+if %ERRORLEVEL% equ 0 goto run_java
+    echo %0, ERROR:
+    echo The version of JAVA installed in %JAVA_HOME% is incorrect.
+    echo Please point JAVA_HOME variable to installation of JDK 1.7 or JDK 1.8.
+    echo You can also download latest JDK at http://java.com/download.
+goto error_finish
+
+:run_java
+
+::
+:: JVM options. See http://java.sun.com/javase/technologies/hotspot/vmoptions.jsp for more details.
+::
+:: ADD YOUR/CHANGE ADDITIONAL OPTIONS HERE
+::
+if "%JVM_OPTS%" == "" set JVM_OPTS=-Xms1g -Xmx1g -server -XX:+AggressiveOpts -XX:MaxPermSize=256m
+
+"%JAVA_HOME%\bin\java.exe" %JVM_OPTS% -cp ignite-web-agent-${version}.jar org.apache.ignite.console.agent.AgentLauncher  %*
+
+set JAVA_ERRORLEVEL=%ERRORLEVEL%
+
+:: errorlevel 130 if aborted with Ctrl+c
+if %JAVA_ERRORLEVEL%==130 goto eof
+
+:error_finish
+
+if not "%NO_PAUSE%" == "1" pause
+
+goto :eof
+

http://git-wip-us.apache.org/repos/asf/ignite/blob/eb5ac0ae/modules/web-agent/bin/ignite-web-agent.sh
----------------------------------------------------------------------
diff --git a/modules/web-agent/bin/ignite-web-agent.sh b/modules/web-agent/bin/ignite-web-agent.sh
new file mode 100644
index 0000000..6d0a1b5
--- /dev/null
+++ b/modules/web-agent/bin/ignite-web-agent.sh
@@ -0,0 +1,87 @@
+#!/bin/bash
+#
+# 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.
+#
+
+# Check JAVA_HOME.
+if [ "$JAVA_HOME" = "" ]; then
+    JAVA=`type -p java`
+    RETCODE=$?
+
+    if [ $RETCODE -ne 0 ]; then
+        echo $0", ERROR:"
+        echo "JAVA_HOME environment variable is not found."
+        echo "Please point JAVA_HOME variable to location of JDK 1.7 or JDK 1.8."
+        echo "You can also download latest JDK at http://java.com/download"
+
+        exit 1
+    fi
+
+    JAVA_HOME=
+else
+    JAVA=${JAVA_HOME}/bin/java
+fi
+
+#
+# Check JDK.
+#
+if [ ! -e "$JAVA" ]; then
+    echo $0", ERROR:"
+    echo "JAVA is not found in JAVA_HOME=$JAVA_HOME."
+    echo "Please point JAVA_HOME variable to installation of JDK 1.7 or JDK 1.8."
+    echo "You can also download latest JDK at http://java.com/download"
+
+    exit 1
+fi
+
+JAVA_VER=`"$JAVA" -version 2>&1 | egrep "1\.[78]\."`
+
+if [ "$JAVA_VER" == "" ]; then
+    echo $0", ERROR:"
+    echo "The version of JAVA installed in JAVA_HOME=$JAVA_HOME is incorrect."
+    echo "Please point JAVA_HOME variable to installation of JDK 1.7 or JDK 1.8."
+    echo "You can also download latest JDK at http://java.com/download"
+
+    exit 1
+fi
+
+SOURCE="${BASH_SOURCE[0]}"
+
+DIR="$( dirname "$SOURCE" )"
+
+while [ -h "$SOURCE" ]
+    do
+        SOURCE="$(readlink "$SOURCE")"
+
+        [[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE"
+
+        DIR="$( cd -P "$( dirname "$SOURCE"  )" && pwd )"
+    done
+
+DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
+
+cd $DIR
+
+#
+# JVM options. See http://java.sun.com/javase/technologies/hotspot/vmoptions.jsp for more details.
+#
+# ADD YOUR/CHANGE ADDITIONAL OPTIONS HERE
+#
+if [ -z "$JVM_OPTS" ] ; then
+    JVM_OPTS="-Xms1g -Xmx1g -server -XX:+AggressiveOpts -XX:MaxPermSize=256m"
+fi
+
+"$JAVA" ${JVM_OPTS} -cp ignite-web-agent-${version}.jar org.apache.ignite.console.agent.AgentLauncher "$@"

http://git-wip-us.apache.org/repos/asf/ignite/blob/eb5ac0ae/modules/web-agent/demo/README.txt
----------------------------------------------------------------------
diff --git a/modules/web-agent/demo/README.txt b/modules/web-agent/demo/README.txt
new file mode 100644
index 0000000..17e5074
--- /dev/null
+++ b/modules/web-agent/demo/README.txt
@@ -0,0 +1,4 @@
+Ignite Web Agent
+======================================
+
+This is folder for demo files.

http://git-wip-us.apache.org/repos/asf/ignite/blob/eb5ac0ae/modules/web-agent/demo/db-init.sql
----------------------------------------------------------------------
diff --git a/modules/web-agent/demo/db-init.sql b/modules/web-agent/demo/db-init.sql
new file mode 100644
index 0000000..0688ea0
--- /dev/null
+++ b/modules/web-agent/demo/db-init.sql
@@ -0,0 +1,102 @@
+--
+--  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.
+--
+
+CREATE TABLE COUNTRY (
+    ID         INTEGER NOT NULL PRIMARY KEY,
+    NAME       VARCHAR(50),
+    POPULATION INTEGER NOT NULL
+);
+
+CREATE TABLE DEPARTMENT (
+    ID         INTEGER NOT NULL PRIMARY KEY,
+    COUNTRY_ID INTEGER NOT NULL,
+    NAME       VARCHAR(50) NOT NULL
+);
+
+CREATE TABLE EMPLOYEE (
+    ID            INTEGER NOT NULL PRIMARY KEY,
+    DEPARTMENT_ID INTEGER NOT NULL,
+    MANAGER_ID    INTEGER,
+    FIRST_NAME    VARCHAR(50) NOT NULL,
+    LAST_NAME     VARCHAR(50) NOT NULL,
+    EMAIL         VARCHAR(50) NOT NULL,
+    PHONE_NUMBER  VARCHAR(50),
+    HIRE_DATE     DATE        NOT NULL,
+    JOB           VARCHAR(50) NOT NULL,
+    SALARY        DOUBLE
+);
+
+CREATE INDEX EMP_SALARY ON EMPLOYEE (SALARY ASC);
+CREATE INDEX EMP_NAMES ON EMPLOYEE (FIRST_NAME ASC, LAST_NAME ASC);
+
+CREATE SCHEMA CARS;
+
+CREATE TABLE CARS.PARKING (
+    ID       INTEGER     NOT NULL PRIMARY KEY,
+    NAME     VARCHAR(50) NOT NULL,
+    CAPACITY INTEGER NOT NULL
+);
+
+CREATE TABLE CARS.CAR (
+    ID         INTEGER NOT NULL PRIMARY KEY,
+    PARKING_ID INTEGER NOT NULL,
+    NAME       VARCHAR(50) NOT NULL
+);
+
+INSERT INTO COUNTRY(ID, NAME, POPULATION) VALUES(0, 'Country #1', 10000000);
+INSERT INTO COUNTRY(ID, NAME, POPULATION) VALUES(1, 'Country #2', 20000000);
+INSERT INTO COUNTRY(ID, NAME, POPULATION) VALUES(2, 'Country #3', 30000000);
+
+INSERT INTO DEPARTMENT(ID, COUNTRY_ID, NAME) VALUES(0, 0, 'Department #1');
+INSERT INTO DEPARTMENT(ID, COUNTRY_ID, NAME) VALUES(1, 0, 'Department #2');
+INSERT INTO DEPARTMENT(ID, COUNTRY_ID, NAME) VALUES(2, 2, 'Department #3');
+INSERT INTO DEPARTMENT(ID, COUNTRY_ID, NAME) VALUES(3, 1, 'Department #4');
+INSERT INTO DEPARTMENT(ID, COUNTRY_ID, NAME) VALUES(4, 1, 'Department #5');
+INSERT INTO DEPARTMENT(ID, COUNTRY_ID, NAME) VALUES(5, 1, 'Department #6');
+
+INSERT INTO EMPLOYEE(ID, DEPARTMENT_ID, FIRST_NAME, LAST_NAME, EMAIL, PHONE_NUMBER, HIRE_DATE, JOB, SALARY) VALUES(0, 0, 'First name manager #1', 'Last name manager #1', 'Email manager #1', 'Phone number manager #1', '2014-01-01', 'Job manager #1', 1100.00);
+INSERT INTO EMPLOYEE(ID, DEPARTMENT_ID, FIRST_NAME, LAST_NAME, EMAIL, PHONE_NUMBER, HIRE_DATE, JOB, SALARY) VALUES(1, 1, 'First name manager #2', 'Last name manager #2', 'Email manager #2', 'Phone number manager #2', '2014-01-01', 'Job manager #2', 2100.00);
+INSERT INTO EMPLOYEE(ID, DEPARTMENT_ID, FIRST_NAME, LAST_NAME, EMAIL, PHONE_NUMBER, HIRE_DATE, JOB, SALARY) VALUES(2, 2, 'First name manager #3', 'Last name manager #3', 'Email manager #3', 'Phone number manager #3', '2014-01-01', 'Job manager #3', 3100.00);
+INSERT INTO EMPLOYEE(ID, DEPARTMENT_ID, FIRST_NAME, LAST_NAME, EMAIL, PHONE_NUMBER, HIRE_DATE, JOB, SALARY) VALUES(3, 3, 'First name manager #4', 'Last name manager #4', 'Email manager #4', 'Phone number manager #4', '2014-01-01', 'Job manager #4', 1500.00);
+INSERT INTO EMPLOYEE(ID, DEPARTMENT_ID, FIRST_NAME, LAST_NAME, EMAIL, PHONE_NUMBER, HIRE_DATE, JOB, SALARY) VALUES(4, 4, 'First name manager #5', 'Last name manager #5', 'Email manager #5', 'Phone number manager #5', '2014-01-01', 'Job manager #5', 1700.00);
+INSERT INTO EMPLOYEE(ID, DEPARTMENT_ID, FIRST_NAME, LAST_NAME, EMAIL, PHONE_NUMBER, HIRE_DATE, JOB, SALARY) VALUES(5, 5, 'First name manager #6', 'Last name manager #6', 'Email manager #6', 'Phone number manager #6', '2014-01-01', 'Job manager #6', 1300.00);
+
+INSERT INTO EMPLOYEE(ID, DEPARTMENT_ID, MANAGER_ID, FIRST_NAME, LAST_NAME, EMAIL, PHONE_NUMBER, HIRE_DATE, JOB, SALARY) VALUES(101, 0, 0, 'First name employee #1', 'Last name employee #1', 'Email employee #1', 'Phone number employee #1', '2014-01-01', 'Job employee #1', 600.00);
+INSERT INTO EMPLOYEE(ID, DEPARTMENT_ID, MANAGER_ID, FIRST_NAME, LAST_NAME, EMAIL, PHONE_NUMBER, HIRE_DATE, JOB, SALARY) VALUES(102, 0, 0, 'First name employee #2', 'Last name employee #2', 'Email employee #2', 'Phone number employee #2', '2014-01-01', 'Job employee #2', 1600.00);
+INSERT INTO EMPLOYEE(ID, DEPARTMENT_ID, MANAGER_ID, FIRST_NAME, LAST_NAME, EMAIL, PHONE_NUMBER, HIRE_DATE, JOB, SALARY) VALUES(103, 1, 1, 'First name employee #3', 'Last name employee #3', 'Email employee #3', 'Phone number employee #3', '2014-01-01', 'Job employee #3', 2600.00);
+INSERT INTO EMPLOYEE(ID, DEPARTMENT_ID, MANAGER_ID, FIRST_NAME, LAST_NAME, EMAIL, PHONE_NUMBER, HIRE_DATE, JOB, SALARY) VALUES(104, 2, 2, 'First name employee #4', 'Last name employee #4', 'Email employee #4', 'Phone number employee #4', '2014-01-01', 'Job employee #4', 1000.00);
+INSERT INTO EMPLOYEE(ID, DEPARTMENT_ID, MANAGER_ID, FIRST_NAME, LAST_NAME, EMAIL, PHONE_NUMBER, HIRE_DATE, JOB, SALARY) VALUES(105, 2, 2, 'First name employee #5', 'Last name employee #5', 'Email employee #5', 'Phone number employee #5', '2014-01-01', 'Job employee #5', 1200.00);
+INSERT INTO EMPLOYEE(ID, DEPARTMENT_ID, MANAGER_ID, FIRST_NAME, LAST_NAME, EMAIL, PHONE_NUMBER, HIRE_DATE, JOB, SALARY) VALUES(106, 2, 2, 'First name employee #6', 'Last name employee #6', 'Email employee #6', 'Phone number employee #6', '2014-01-01', 'Job employee #6', 800.00);
+INSERT INTO EMPLOYEE(ID, DEPARTMENT_ID, MANAGER_ID, FIRST_NAME, LAST_NAME, EMAIL, PHONE_NUMBER, HIRE_DATE, JOB, SALARY) VALUES(107, 3, 3, 'First name employee #7', 'Last name employee #7', 'Email employee #7', 'Phone number employee #7', '2014-01-01', 'Job employee #7', 1400.00);
+INSERT INTO EMPLOYEE(ID, DEPARTMENT_ID, MANAGER_ID, FIRST_NAME, LAST_NAME, EMAIL, PHONE_NUMBER, HIRE_DATE, JOB, SALARY) VALUES(108, 4, 4, 'First name employee #8', 'Last name employee #8', 'Email employee #8', 'Phone number employee #8', '2014-01-01', 'Job employee #8', 800.00);
+INSERT INTO EMPLOYEE(ID, DEPARTMENT_ID, MANAGER_ID, FIRST_NAME, LAST_NAME, EMAIL, PHONE_NUMBER, HIRE_DATE, JOB, SALARY) VALUES(109, 4, 4, 'First name employee #9', 'Last name employee #9', 'Email employee #9', 'Phone number employee #9', '2014-01-01', 'Job employee #9', 1490.00);
+INSERT INTO EMPLOYEE(ID, DEPARTMENT_ID, MANAGER_ID, FIRST_NAME, LAST_NAME, EMAIL, PHONE_NUMBER, HIRE_DATE, JOB, SALARY) VALUES(110, 4, 4, 'First name employee #10', 'Last name employee #12', 'Email employee #10', 'Phone number employee #10', '2014-01-01', 'Job employee #10', 1600.00);
+INSERT INTO EMPLOYEE(ID, DEPARTMENT_ID, MANAGER_ID, FIRST_NAME, LAST_NAME, EMAIL, PHONE_NUMBER, HIRE_DATE, JOB, SALARY) VALUES(111, 5, 5, 'First name employee #11', 'Last name employee #11', 'Email employee #11', 'Phone number employee #11', '2014-01-01', 'Job employee #11', 400.00);
+
+INSERT INTO CARS.PARKING(ID, NAME, CAPACITY) VALUES(0, 'Parking #1', 10);
+INSERT INTO CARS.PARKING(ID, NAME, CAPACITY) VALUES(1, 'Parking #2', 20);
+INSERT INTO CARS.PARKING(ID, NAME, CAPACITY) VALUES(2, 'Parking #3', 30);
+
+INSERT INTO CARS.CAR(ID, PARKING_ID, NAME) VALUES(0, 0, 'Car #1');
+INSERT INTO CARS.CAR(ID, PARKING_ID, NAME) VALUES(1, 0, 'Car #2');
+INSERT INTO CARS.CAR(ID, PARKING_ID, NAME) VALUES(2, 0, 'Car #3');
+INSERT INTO CARS.CAR(ID, PARKING_ID, NAME) VALUES(3, 1, 'Car #4');
+INSERT INTO CARS.CAR(ID, PARKING_ID, NAME) VALUES(4, 1, 'Car #5');
+INSERT INTO CARS.CAR(ID, PARKING_ID, NAME) VALUES(5, 2, 'Car #6');
+INSERT INTO CARS.CAR(ID, PARKING_ID, NAME) VALUES(6, 2, 'Car #7');
+INSERT INTO CARS.CAR(ID, PARKING_ID, NAME) VALUES(7, 2, 'Car #8');
+INSERT INTO CARS.CAR(ID, PARKING_ID, NAME) VALUES(8, 2, 'Car #9');

http://git-wip-us.apache.org/repos/asf/ignite/blob/eb5ac0ae/modules/web-agent/jdbc-drivers/README.txt
----------------------------------------------------------------------
diff --git a/modules/web-agent/jdbc-drivers/README.txt b/modules/web-agent/jdbc-drivers/README.txt
new file mode 100644
index 0000000..cad43b7
--- /dev/null
+++ b/modules/web-agent/jdbc-drivers/README.txt
@@ -0,0 +1,10 @@
+Ignite Web Agent
+======================================
+
+If you are are planning to load cache type metadata from your existing databases
+you need to copy JDBC drivers in this folder.
+
+This is default folder for JDBC drivers.
+
+Also, you could specify custom folder using option: "-d CUSTOM_PATH_TO_FOLDER_WITH_JDBC_DRIVERS".
+

http://git-wip-us.apache.org/repos/asf/ignite/blob/eb5ac0ae/modules/web-agent/logs/README.txt
----------------------------------------------------------------------
diff --git a/modules/web-agent/logs/README.txt b/modules/web-agent/logs/README.txt
new file mode 100644
index 0000000..3a220eb
--- /dev/null
+++ b/modules/web-agent/logs/README.txt
@@ -0,0 +1,5 @@
+Ignite Web Agent
+======================================
+
+This is folder for agent logs.
+

http://git-wip-us.apache.org/repos/asf/ignite/blob/eb5ac0ae/modules/web-agent/pom.xml
----------------------------------------------------------------------
diff --git a/modules/web-agent/pom.xml b/modules/web-agent/pom.xml
new file mode 100644
index 0000000..afca554
--- /dev/null
+++ b/modules/web-agent/pom.xml
@@ -0,0 +1,169 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+  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.
+-->
+
+<!--
+    POM file.
+-->
+<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.apache.ignite</groupId>
+        <artifactId>ignite-parent</artifactId>
+        <version>1</version>
+        <relativePath>../../parent</relativePath>
+    </parent>
+
+    <artifactId>ignite-web-agent</artifactId>
+    <version>1.6.0-SNAPSHOT</version>
+
+    <properties>
+        <maven.build.timestamp.format>yyMMddHHmmss</maven.build.timestamp.format>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>io.socket</groupId>
+            <artifactId>socket.io-client</artifactId>
+            <version>0.7.0</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.fasterxml.jackson.datatype</groupId>
+            <artifactId>jackson-datatype-json-org</artifactId>
+            <version>2.7.1</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.beust</groupId>
+            <artifactId>jcommander</artifactId>
+            <version>1.48</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.httpcomponents</groupId>
+            <artifactId>httpclient</artifactId>
+            <version>${httpclient.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.ignite</groupId>
+            <artifactId>ignite-schema-import-db</artifactId>
+            <version>${project.version}</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.gridgain</groupId>
+                    <artifactId>ignite-shmem</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.ignite</groupId>
+            <artifactId>ignite-indexing</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.ignite</groupId>
+            <artifactId>ignite-rest-http</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.ignite</groupId>
+            <artifactId>ignite-log4j</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <finalName>ignite-web-agent-${project.version}</finalName>
+
+        <plugins>
+            <plugin>
+                <artifactId>maven-jar-plugin</artifactId>
+                <version>2.5</version>
+
+                <configuration>
+                    <archive>
+                        <manifest>
+                            <mainClass>org.apache.ignite.console.agent.AgentLauncher</mainClass>
+                        </manifest>
+                        <manifestEntries>
+                            <Build-Time>${maven.build.timestamp}</Build-Time>
+                        </manifestEntries>
+                    </archive>
+                </configuration>
+            </plugin>
+
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-shade-plugin</artifactId>
+                <version>2.4</version>
+
+                <executions>
+                    <execution>
+                        <phase>package</phase>
+                        <goals>
+                            <goal>shade</goal>
+                        </goals>
+
+                        <configuration>
+                            <createDependencyReducedPom>false</createDependencyReducedPom>
+                            <filters>
+                                <filter>
+                                    <artifact>*:*</artifact>
+                                    <excludes>
+                                        <exclude>META-INF/maven/**</exclude>
+                                    </excludes>
+                                </filter>
+                            </filters>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-assembly-plugin</artifactId>
+                <version>2.4</version>
+                <inherited>false</inherited>
+
+                <executions>
+                    <execution>
+                        <id>release-web-agent</id>
+                        <phase>package</phase>
+                        <goals>
+                            <goal>single</goal>
+                        </goals>
+                        <configuration>
+                            <descriptors>
+                                <descriptor>assembly/release-web-agent.xml</descriptor>
+                            </descriptors>
+                            <finalName>ignite-web-agent-${project.version}</finalName>
+                            <outputDirectory>target</outputDirectory>
+                            <appendAssemblyId>false</appendAssemblyId>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+</project>

http://git-wip-us.apache.org/repos/asf/ignite/blob/eb5ac0ae/modules/web-agent/src/main/java/org/apache/ignite/console/agent/AgentConfiguration.java
----------------------------------------------------------------------
diff --git a/modules/web-agent/src/main/java/org/apache/ignite/console/agent/AgentConfiguration.java b/modules/web-agent/src/main/java/org/apache/ignite/console/agent/AgentConfiguration.java
new file mode 100644
index 0000000..ffd30a5
--- /dev/null
+++ b/modules/web-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 = "http://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 : Boolean.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/eb5ac0ae/modules/web-agent/src/main/java/org/apache/ignite/console/agent/AgentLauncher.java
----------------------------------------------------------------------
diff --git a/modules/web-agent/src/main/java/org/apache/ignite/console/agent/AgentLauncher.java b/modules/web-agent/src/main/java/org/apache/ignite/console/agent/AgentLauncher.java
new file mode 100644
index 0000000..4b99a92
--- /dev/null
+++ b/modules/web-agent/src/main/java/org/apache/ignite/console/agent/AgentLauncher.java
@@ -0,0 +1,337 @@
+/*
+ * 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 com.beust.jcommander.ParameterException;
+import io.socket.client.Ack;
+import io.socket.client.IO;
+import io.socket.client.Socket;
+import io.socket.emitter.Emitter;
+import java.io.File;
+import java.io.IOException;
+import java.net.ConnectException;
+import java.net.SocketException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.util.Arrays;
+import java.util.concurrent.CountDownLatch;
+import java.util.jar.Attributes;
+import java.util.jar.Manifest;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLHandshakeException;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.X509TrustManager;
+import org.apache.ignite.console.agent.handlers.DatabaseHandler;
+import org.apache.ignite.console.agent.handlers.RestHandler;
+import org.apache.ignite.internal.util.typedef.X;
+import org.apache.log4j.Logger;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import static io.socket.client.Socket.EVENT_CONNECT;
+import static io.socket.client.Socket.EVENT_CONNECTING;
+import static io.socket.client.Socket.EVENT_CONNECT_ERROR;
+import static io.socket.client.Socket.EVENT_DISCONNECT;
+import static io.socket.client.Socket.EVENT_ERROR;
+import static io.socket.client.Socket.EVENT_RECONNECTING;
+import static org.apache.ignite.console.agent.AgentConfiguration.DFLT_SERVER_PORT;
+
+/**
+ * Control Center Agent launcher.
+ */
+public class AgentLauncher {
+    /** */
+    private static final Logger log = Logger.getLogger(AgentLauncher.class.getName());
+
+    /** */
+    private static final String EVENT_NODE_REST = "node:rest";
+
+    /** */
+    private static final String EVENT_SCHEMA_IMPORT_DRIVERS = "schemaImport:drivers";
+
+    /** */
+    private static final String EVENT_SCHEMA_IMPORT_SCHEMAS = "schemaImport:schemas";
+
+    /** */
+    private static final String EVENT_SCHEMA_IMPORT_METADATA = "schemaImport:metadata";
+
+    /** */
+    private static final String EVENT_AGENT_CLOSE = "agent:close";
+
+    /** */
+    private static final int RECONNECT_INTERVAL = 3000;
+
+    /**
+     * Create a trust manager that trusts all certificates It is not using a particular keyStore
+     */
+    private static TrustManager[] getTrustManagers() {
+        return new TrustManager[] {
+            new X509TrustManager() {
+                public java.security.cert.X509Certificate[] getAcceptedIssuers() {
+                    return null;
+                }
+
+                public void checkClientTrusted(
+                    java.security.cert.X509Certificate[] certs, String authType) {
+                }
+
+                public void checkServerTrusted(
+                    java.security.cert.X509Certificate[] certs, String authType) {
+                }
+            }};
+    }
+
+    /**
+     * On error listener.
+     */
+    private static final Emitter.Listener onError = new Emitter.Listener() {
+        @SuppressWarnings("ThrowableResultOfMethodCallIgnored")
+        @Override public void call(Object... args) {
+            Throwable e = (Throwable)args[0];
+
+            ConnectException ce = X.cause(e, ConnectException.class);
+
+            if (ce != null)
+                log.error("Failed to receive response from server (connection refused).");
+            else {
+                Exception ignore = X.cause(e, SSLHandshakeException.class);
+
+                if (ignore != null) {
+                    log.error("Failed to establish SSL connection to server, due to errors with SSL handshake.");
+                    log.error("Add to environment variable JVM_OPTS parameter \"-Dtrust.all=true\" to skip certificate validation in case of using self-signed certificate.");
+
+                    System.exit(1);
+                }
+
+                ignore = X.cause(e, IOException.class);
+
+                if (ignore != null && "404".equals(ignore.getMessage())) {
+                    log.error("Failed to receive response from server (connection refused).");
+
+                    return;
+                }
+
+                log.error("Connection error.", e);
+            }
+        }
+    };
+
+    /**
+     * On disconnect listener.
+     */
+    private static final Emitter.Listener onDisconnect = new Emitter.Listener() {
+        @Override public void call(Object... args) {
+            log.error(String.format("Connection closed: %s.", args[0]));
+        }
+    };
+
+    /**
+     * @param args Args.
+     */
+    @SuppressWarnings("BusyWait")
+    public static void main(String[] args) throws Exception {
+        log.info("Starting Apache Ignite Web Console Agent...");
+
+        final 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());
+        }
+
+        final RestHandler restHnd = new RestHandler(cfg);
+
+        try {
+            restHnd.start();
+
+            URI uri = URI.create(cfg.serverUri());
+
+            if (uri.getPort() == -1)
+                uri = URI.create(cfg.serverUri() + ':' + DFLT_SERVER_PORT);
+
+            IO.Options opts = new IO.Options();
+
+            opts.reconnectionDelay = RECONNECT_INTERVAL;
+
+            // Workaround for use self-signed certificate
+            if (Boolean.getBoolean("trust.all")) {
+                SSLContext ctx = SSLContext.getInstance("TLS");
+
+                // Create an SSLContext that uses our TrustManager
+                ctx.init(null, getTrustManagers(), null);
+
+                opts.sslContext = ctx;
+            }
+
+            final Socket client = IO.socket(uri, opts);
+
+            try {
+                Emitter.Listener onConnecting = new Emitter.Listener() {
+                    @Override public void call(Object... args) {
+                        log.info("Connecting to: " + cfg.serverUri());
+                    }
+                };
+
+                Emitter.Listener onConnect = new Emitter.Listener() {
+                    @Override public void call(Object... args) {
+                        log.info("Connection established.");
+
+                        JSONObject authMsg = new JSONObject();
+
+                        try {
+                            authMsg.put("token", cfg.token());
+
+                            String clsName = AgentLauncher.class.getSimpleName() + ".class";
+
+                            String clsPath = AgentLauncher.class.getResource(clsName).toString();
+
+                            if (clsPath.startsWith("jar")) {
+                                String manifestPath = clsPath.substring(0, clsPath.lastIndexOf('!') + 1) +
+                                    "/META-INF/MANIFEST.MF";
+
+                                Manifest manifest = new Manifest(new URL(manifestPath).openStream());
+
+                                Attributes attr = manifest.getMainAttributes();
+
+                                authMsg.put("ver", attr.getValue("Implementation-Version"));
+                                authMsg.put("bt", attr.getValue("Build-Time"));
+                            }
+
+                            client.emit("agent:auth", authMsg, new Ack() {
+                                @Override public void call(Object... args) {
+                                    // Authentication failed if response contains args.
+                                    if (args != null && args.length > 0) {
+                                        onDisconnect.call("Authentication failed: " + args[0]);
+
+                                        System.exit(1);
+                                    }
+
+                                    log.info("Authentication success.");
+                                }
+                            });
+                        }
+                        catch (JSONException | IOException e) {
+                            log.error("Failed to construct authentication message", e);
+
+                            client.close();
+                        }
+                    }
+                };
+
+                DatabaseHandler dbHnd = new DatabaseHandler(cfg);
+
+                final CountDownLatch latch = new CountDownLatch(1);
+
+                client
+                    .on(EVENT_CONNECTING, onConnecting)
+                    .on(EVENT_CONNECT, onConnect)
+                    .on(EVENT_CONNECT_ERROR, onError)
+                    .on(EVENT_RECONNECTING, onConnecting)
+                    .on(EVENT_NODE_REST, restHnd)
+                    .on(EVENT_SCHEMA_IMPORT_DRIVERS, dbHnd.availableDriversListener())
+                    .on(EVENT_SCHEMA_IMPORT_SCHEMAS, dbHnd.schemasListener())
+                    .on(EVENT_SCHEMA_IMPORT_METADATA, dbHnd.metadataListener())
+                    .on(EVENT_ERROR, onError)
+                    .on(EVENT_DISCONNECT, onDisconnect)
+                    .on(EVENT_AGENT_CLOSE, new Emitter.Listener() {
+                        @Override public void call(Object... args) {
+                            onDisconnect.call(args);
+
+                            client.off();
+
+                            latch.countDown();
+                        }
+                    });
+
+                client.connect();
+
+                latch.await();
+            }
+            finally {
+                client.close();
+            }
+        }
+        finally {
+            restHnd.stop();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/eb5ac0ae/modules/web-agent/src/main/java/org/apache/ignite/console/agent/AgentUtils.java
----------------------------------------------------------------------
diff --git a/modules/web-agent/src/main/java/org/apache/ignite/console/agent/AgentUtils.java b/modules/web-agent/src/main/java/org/apache/ignite/console/agent/AgentUtils.java
new file mode 100644
index 0000000..50a849a
--- /dev/null
+++ b/modules/web-agent/src/main/java/org/apache/ignite/console/agent/AgentUtils.java
@@ -0,0 +1,111 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.console.agent;
+
+import java.io.File;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.security.ProtectionDomain;
+import org.apache.log4j.Logger;
+
+/**
+ * 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/eb5ac0ae/modules/web-agent/src/main/java/org/apache/ignite/console/agent/handlers/AbstractHandler.java
----------------------------------------------------------------------
diff --git a/modules/web-agent/src/main/java/org/apache/ignite/console/agent/handlers/AbstractHandler.java b/modules/web-agent/src/main/java/org/apache/ignite/console/agent/handlers/AbstractHandler.java
new file mode 100644
index 0000000..7e4e320
--- /dev/null
+++ b/modules/web-agent/src/main/java/org/apache/ignite/console/agent/handlers/AbstractHandler.java
@@ -0,0 +1,110 @@
+/*
+ * 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 com.fasterxml.jackson.annotation.JsonAutoDetect;
+import com.fasterxml.jackson.annotation.PropertyAccessor;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.datatype.jsonorg.JsonOrgModule;
+import io.socket.client.Ack;
+import io.socket.emitter.Emitter;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Map;
+import org.json.JSONArray;
+import org.json.JSONObject;
+
+/**
+ * Base class for web socket handlers.
+ */
+abstract class AbstractHandler implements Emitter.Listener {
+    /** JSON object mapper. */
+    private static final ObjectMapper mapper = new ObjectMapper();
+
+    static {
+        JsonOrgModule module = new JsonOrgModule();
+
+        mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.NONE);
+        mapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY);
+
+        mapper.registerModule(module);
+    }
+
+    /**
+     * @param obj Object.
+     * @return {@link JSONObject} or {@link JSONArray}.
+     */
+    private Object toJSON(Object obj) {
+        if (obj instanceof Iterable)
+            return mapper.convertValue(obj, JSONArray.class);
+
+        return mapper.convertValue(obj, JSONObject.class);
+    }
+
+    /** {@inheritDoc} */
+    @SuppressWarnings("unchecked")
+    @Override public final void call(Object... args) {
+        Ack cb = null;
+
+        try {
+            if (args == null || args.length == 0)
+                throw new IllegalArgumentException("Missing arguments.");
+
+            if (args.length > 2)
+                throw new IllegalArgumentException("Wrong arguments count, must be <= 2: " + Arrays.toString(args));
+
+            JSONObject lsnrArgs = null;
+
+            if (args.length == 1) {
+                if (args[0] instanceof JSONObject)
+                    lsnrArgs = (JSONObject)args[0];
+                else if (args[0] instanceof Ack)
+                    cb = (Ack)args[0];
+                else
+                    throw new IllegalArgumentException("Wrong type of argument, must be JSONObject or Ack: " + args[0]);
+            }
+            else {
+                if (args[0] != null && !(args[0] instanceof JSONObject))
+                    throw new IllegalArgumentException("Wrong type of argument, must be JSONObject: " + args[0]);
+
+                if (!(args[1] instanceof Ack))
+                    throw new IllegalArgumentException("Wrong type of argument, must be Ack: " + args[1]);
+
+                lsnrArgs = (JSONObject)args[0];
+
+                cb = (Ack)args[1];
+            }
+
+            Object res = execute(lsnrArgs == null ? Collections.emptyMap() : mapper.convertValue(lsnrArgs, Map.class));
+
+            if (cb != null)
+                cb.call(null, toJSON(res));
+        }
+        catch (Exception e) {
+            if (cb != null)
+                cb.call(e, null);
+        }
+    }
+
+    /**
+     * Execute command with specified arguments.
+     *
+     * @param args Map with method args.
+     */
+    public abstract Object execute(Map<String, Object> args) throws Exception;
+}


Mime
View raw message