You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by an...@apache.org on 2015/07/30 11:37:02 UTC

[18/28] incubator-ignite git commit: # ignite-843 Rename

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/control-center-web/src/main/js/controllers/models/clusters.json
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/controllers/models/clusters.json b/modules/control-center-web/src/main/js/controllers/models/clusters.json
new file mode 100644
index 0000000..36d0dd8
--- /dev/null
+++ b/modules/control-center-web/src/main/js/controllers/models/clusters.json
@@ -0,0 +1,909 @@
+{
+  "screenTip": {
+    "workflowTitle": "Use clusters view to:",
+    "workflowContent": [
+      "<ul>",
+      "  <li>Configure clusters.</li>",
+      "  <li>Associate clusters with caches.</li>",
+      "</ul>"
+    ],
+    "whatsNextTitle": "What's next:",
+    "whatsNextContent": [
+      "<ul>",
+      "  <li>Configure cache type metadata.</li>",
+      "  <li>Configure caches.</li>",
+      "  <li>Generate XML and java code on Summary view.</li>",
+      "</ul>"
+    ]
+  },
+  "templateTip": [
+    "Use following template to add a new cluster:",
+    "<ul>",
+    "  <li>multicast - cluster with multicast discovery.</li>",
+    "  <li>local - cluster with static ips discovery and pre-configured list of IP addresses.</li>",
+    "</ul>"
+  ],
+  "general": [
+    {
+      "label": "Name",
+      "type": "text",
+      "model": "name",
+      "required": true,
+      "placeholder": "Input name",
+      "id": "defaultFocusId"
+    },
+    {
+      "label": "Caches",
+      "type": "dropdown-multiple",
+      "model": "caches",
+      "placeholder": "Choose caches",
+      "items": "caches",
+      "tip": [
+        "Select caches to start in cluster or add a new cache."
+      ],
+      "addLink": {
+        "label": "Add cache(s)",
+        "ref": "/configuration/caches"
+      }
+    },
+    {
+      "label": "Discovery",
+      "type": "dropdown-details",
+      "path": "discovery",
+      "model": "kind",
+      "required": true,
+      "placeholder": "Choose discovery",
+      "items": "discoveries",
+      "tip": [
+        "Discovery allows to discover remote nodes in grid."
+      ],
+      "details": {
+        "Vm": {
+          "expanded": true,
+          "fields": [
+            {
+              "type": "table-simple",
+              "path": "discovery.Vm",
+              "model": "addresses",
+              "editIdx": -1,
+              "reordering": true,
+              "ipaddress": true,
+              "placeholder": "IP address:port",
+              "focusNewItemId": "newIpAddress",
+              "focusCurItemId": "curIpAddress",
+              "addTip": "Add new address.",
+              "removeTip": "Remove address.",
+              "tip": [
+                "Addresses may be represented as follows:",
+                "<ul>",
+                "  <li>IP address (e.g. 127.0.0.1, 9.9.9.9, etc);</li>",
+                "  <li>IP address and port (e.g. 127.0.0.1:47500, 9.9.9.9:47501, etc);</li>",
+                "  <li>IP address and port range (e.g. 127.0.0.1:47500..47510, 9.9.9.9:47501..47504, etc);</li>",
+                "  <li>Hostname (e.g. host1.com, host2, etc);</li>",
+                "  <li>Hostname and port (e.g. host1.com:47500, host2:47502, etc).</li>",
+                "  <li>Hostname and port range (e.g. host1.com:47500..47510, host2:47502..47508, etc).</li>",
+                "</ul>",
+                "If port is 0 or not provided then default port will be used (depends on discovery SPI configuration).",
+                "If port range is provided (e.g. host:port1..port2) the following should be considered:",
+                "<ul>",
+                "  <li>port1 < port2 should be true;</li>",
+                "  <li>Both port1 and port2 should be greater than 0.</li>",
+                "</ul>"
+              ]
+            }
+          ]
+        },
+        "Multicast": {
+          "expanded": false,
+          "fields": [
+            {
+              "label": "IP address",
+              "type": "text",
+              "path": "discovery.Multicast",
+              "model": "multicastGroup",
+              "placeholder": "228.1.2.4",
+              "tip": [
+                "IP address of multicast group."
+              ]
+            },
+            {
+              "label": "Port number",
+              "type": "number",
+              "path": "discovery.Multicast",
+              "model": "multicastPort",
+              "max": 65535,
+              "placeholder": 47400,
+              "tip": [
+                "Port number which multicast messages are sent to."
+              ]
+            },
+            {
+              "label": "Waits for reply",
+              "type": "number",
+              "path": "discovery.Multicast",
+              "model": "responseWaitTime",
+              "placeholder": 500,
+              "tip": [
+                "Time in milliseconds IP finder waits for reply to multicast address request."
+              ]
+            },
+            {
+              "label": "Attempts count",
+              "type": "number",
+              "path": "discovery.Multicast",
+              "model": "addressRequestAttempts",
+              "placeholder": 2,
+              "tip": [
+                "Number of attempts to send multicast address request.",
+                "IP finder re-sends request only in case if no reply for previous request is received."
+              ]
+            },
+            {
+              "label": "Local address",
+              "type": "text",
+              "path": "discovery.Multicast",
+              "model": "localAddress",
+              "tip": [
+                "Local host address used by this IP finder.",
+                "If provided address is non-loopback then multicast socket is bound to this interface.",
+                "If local address is not set or is any local address then IP finder creates multicast sockets for all found non-loopback addresses."
+              ]
+            }
+          ]
+        },
+        "S3": {
+          "expanded": true,
+          "fields": [
+            {
+              "label": "Bucket name",
+              "type": "text",
+              "required": true,
+              "path": "discovery.S3",
+              "model": "bucketName",
+              "tip": [
+                "Bucket name for IP finder."
+              ]
+            },
+            {
+              "label": "Note, AWS credentials will be generated as stubs.",
+              "type": "label"
+            }
+          ]
+        },
+        "Cloud": {
+          "expanded": true,
+          "fields": [
+            {
+              "label": "Credential",
+              "type": "text",
+              "path": "discovery.Cloud",
+              "model": "credential",
+              "tip": [
+                "Credential that is used during authentication on the cloud.",
+                "Depending on a cloud platform it can be a password or access key."
+              ]
+            },
+            {
+              "label": "Path to credential",
+              "type": "text",
+              "path": "discovery.Cloud",
+              "model": "credentialPath",
+              "tip": [
+                "Path to a credential that is used during authentication on the cloud.",
+                "Access key or private key should be stored in a plain or PEM file without a passphrase."
+              ]
+            },
+            {
+              "label": "Identity",
+              "type": "text",
+              "required": true,
+              "path": "discovery.Cloud",
+              "model": "identity",
+              "tip": [
+                "Identity that is used as a user name during a connection to the cloud.",
+                "Depending on a cloud platform it can be an email address, user name, etc."
+              ]
+            },
+            {
+              "label": "Provider",
+              "type": "text",
+              "required": true,
+              "path": "discovery.Cloud",
+              "model": "provider",
+              "tip": [
+                "Cloud provider to use."
+              ]
+            },
+            {
+              "label": "Regions",
+              "type": "table-simple",
+              "path": "discovery.Cloud",
+              "model": "regions",
+              "editIdx": -1,
+              "focusNewItemId": "newRegion",
+              "focusCurItemId": "curRegion",
+              "addTip": "Add new region.",
+              "removeTip": "Remove region.",
+              "tableTip": [
+                "List of regions where VMs are located.",
+                "If the regions are not set then every region, that a cloud provider has, will be investigated. This could lead to significant performance degradation.",
+                "Note, that some cloud providers, like Google Compute Engine, doesn't have a notion of a region. For such providers a call to this method is redundant."
+              ],
+              "tip": [
+                "Region where VMs are located."
+              ]
+            },
+            {
+              "label": "Zones",
+              "type": "table-simple",
+              "path": "discovery.Cloud",
+              "model": "zones",
+              "editIdx": -1,
+              "focusNewItemId": "newZone",
+              "focusCurItemId": "curZone",
+              "addTip": "Add new zone.",
+              "removeTip": "Remove zone.",
+              "tableTip": [
+                "List of zones where VMs are located.",
+                "If the zones are not set then every zone from regions, set by {@link #setRegions(Collection)}}, will be taken into account.",
+                "Note, that some cloud providers, like Rackspace, doesn't have a notion of a zone. For such providers a call to this method is redundant."
+              ],
+              "tip": [
+                "Zone where VMs are located."
+              ]
+            }
+          ]
+        },
+        "GoogleStorage": {
+          "expanded": true,
+          "fields": [
+            {
+              "label": "Project name",
+              "type": "text",
+              "required": true,
+              "path": "discovery.GoogleStorage",
+              "model": "projectName",
+              "tip": [
+                "Google Cloud Platforms project name.",
+                "Usually this is an auto generated project number (ex. 208709979073) that can be found in 'Overview' section of Google Developer Console."
+              ]
+            },
+            {
+              "label": "Bucket name",
+              "type": "text",
+              "required": true,
+              "path": "discovery.GoogleStorage",
+              "model": "bucketName",
+              "tip": [
+                "Google Cloud Storage bucket name.",
+                "If the bucket doesn't exist Ignite will automatically create it.",
+                "However the name must be unique across whole Google Cloud Storage and Service Account Id must be authorized to perform this operation."
+              ]
+            },
+            {
+              "label": "Private key path",
+              "type": "text",
+              "required": true,
+              "path": "discovery.GoogleStorage",
+              "model": "serviceAccountP12FilePath",
+              "tip": [
+                "Full path to the private key in PKCS12 format of the Service Account."
+              ]
+            },
+            {
+              "label": "Account id",
+              "type": "text",
+              "required": true,
+              "path": "discovery.GoogleStorage",
+              "model": "accountId",
+              "tip": [
+                "Service account ID (typically an e-mail address)."
+              ]
+            }
+          ]
+        },
+        "Jdbc": {
+          "expanded": true,
+          "fields": [
+            {
+              "label": "DB schema should be initialized by Ignite",
+              "type": "check",
+              "path": "discovery.Jdbc",
+              "model": "initSchema",
+              "tip": [
+                "Flag indicating whether DB schema should be initialized by Ignite or was explicitly created by user."
+              ]
+            }
+          ]
+        },
+        "SharedFs": {
+          "expanded": false,
+          "fields": [
+            {
+              "label": "File path",
+              "type": "text",
+              "path": "discovery.SharedFs",
+              "model": "path",
+              "placeholder": "disco/tcp"
+            }
+          ]
+        }
+      }
+    }
+  ],
+  "advanced": [
+    {
+      "label": "Atomics configuration",
+      "tip": [
+        "Configuration for atomic data structures.",
+        "Atomics are distributed across the cluster, essentially enabling performing atomic operations (such as increment-and-get or compare-and-set) with the same globally-visible value."
+      ],
+      "fields": [
+        {
+          "label": "Backups",
+          "type": "number",
+          "path": "atomicConfiguration",
+          "model": "backups",
+          "placeholder": 0,
+          "tip": [
+            "Number of backup nodes."
+          ]
+        },
+        {
+          "label": "Cache mode",
+          "type": "dropdown",
+          "path": "atomicConfiguration",
+          "model": "cacheMode",
+          "placeholder": "PARTITIONED",
+          "items": "cacheModes",
+          "tip": [
+            "Cache modes:",
+            "<ul>",
+            "  <li>Partitioned - in this mode the overall key set will be divided into partitions and all partitions will be split equally between participating nodes.</li>",
+            "  <li>Replicated - in this mode all the keys are distributed to all participating nodes.</li>",
+            "  <li>Local - in this mode caches residing on different grid nodes will not know about each other.</li>",
+            "</ul>"
+          ]
+        },
+        {
+          "label": "Sequence reserve",
+          "type": "number",
+          "path": "atomicConfiguration",
+          "model": "atomicSequenceReserveSize",
+          "placeholder": 1000,
+          "tip": [
+            "Default number of sequence values reserved for IgniteAtomicSequence instances.",
+            "After a certain number has been reserved, consequent increments of sequence will happen locally, without communication with other nodes, until the next reservation has to be made."
+          ]
+        }
+      ]
+    },
+    {
+      "label": "Communication",
+      "tip": [
+        "Cluster communication network properties."
+      ],
+      "fields": [
+        {
+          "label": "Timeout",
+          "type": "number",
+          "model": "networkTimeout",
+          "placeholder": 5000,
+          "tip": [
+            "Maximum timeout in milliseconds for network requests."
+          ]
+        },
+        {
+          "label": "Send retry delay",
+          "type": "number",
+          "model": "networkSendRetryDelay",
+          "placeholder": 1000,
+          "tip": [
+            "Interval in milliseconds between message send retries."
+          ]
+        },
+        {
+          "label": "Send retry count",
+          "type": "number",
+          "model": "networkSendRetryCount",
+          "placeholder": 3,
+          "tip": [
+            "Message send retries count."
+          ]
+        },
+        {
+          "label": "Segment check frequency",
+          "type": "number",
+          "model": "segmentCheckFrequency",
+          "placeholder": 10000,
+          "tip": [
+            "Network segment check frequency in milliseconds.",
+            "If 0, periodic segment check is disabled and segment is checked only on topology changes (if segmentation resolvers are configured)."
+          ]
+        },
+        {
+          "label": "Wait for segment on start",
+          "type": "check",
+          "model": "waitForSegmentOnStart",
+          "tip": [
+            "Wait for segment on start flag.",
+            "<ul>",
+            "  <li>If enabled, node should wait for correct segment on start.</li>",
+            "  <li>If node detects that segment is incorrect on startup and enabled, node waits until segment becomes correct.</li>",
+            "  <li>If segment is incorrect on startup and disabled, exception is thrown.</li>",
+            "</ul>"
+          ]
+        },
+        {
+          "label": "Discovery startup delay",
+          "type": "number",
+          "model": "discoveryStartupDelay",
+          "placeholder": 600000,
+          "tip": [
+            "This value is used to expire messages from waiting list whenever node discovery discrepancies happen."
+          ]
+        }
+      ]
+    },
+    {
+      "label": "Deployment",
+      "tip": [
+        "Task and resources deployment in cluster."
+      ],
+      "fields": [
+        {
+          "label": "Mode",
+          "type": "dropdown",
+          "model": "deploymentMode",
+          "placeholder": "SHARED",
+          "items": "deploymentModes",
+          "tip": [
+            "Task classes and resources sharing mode."
+          ]
+        }
+      ]
+    },
+    {
+      "label": "Events",
+      "tip": [
+        " Grid events are used for notification about what happens within the grid."
+      ],
+      "fields": [
+        {
+          "label": "Include type",
+          "type": "dropdown-multiple",
+          "model": "includeEventTypes",
+          "placeholder": "Choose recorded event types",
+          "items": "events",
+          "tip": [
+            "Array of event types, which will be recorded by GridEventStorageManager#record(Event).",
+            "Note, that either the include event types or the exclude event types can be established."
+          ]
+        }
+      ]
+    },
+    {
+      "label": "Marshaller",
+      "tip": [
+        "Marshaller allows to marshal or unmarshal objects in grid.",
+        "It provides serialization/deserialization mechanism for all instances that are sent across networks or are otherwise serialized."
+      ],
+      "fields": [
+        {
+          "label": "Marshaller",
+          "type": "dropdown-details",
+          "path": "marshaller",
+          "model": "kind",
+          "placeholder": "Choose marshaller",
+          "items": "marshallers",
+          "tip": [
+            "Instance of marshaller to use in grid. If not provided, OptimizedMarshaller will be used on Java HotSpot VM, and JdkMarshaller will be used on other VMs."
+          ],
+          "details": {
+            "OptimizedMarshaller": {
+              "expanded": false,
+              "fields": [
+                {
+                  "label": "Streams pool size",
+                  "type": "number",
+                  "path": "marshaller.OptimizedMarshaller",
+                  "model": "poolSize",
+                  "placeholder": 0,
+                  "tip": [
+                    "Specifies size of cached object streams used by marshaller.",
+                    "Object streams are cached for performance reason to avoid costly recreation for every serialization routine.",
+                    "If 0 (default), pool is not used and each thread has its own cached object stream which it keeps reusing.",
+                    "Since each stream has an internal buffer, creating a stream for each thread can lead to high memory consumption if many large messages are marshalled or unmarshalled concurrently.",
+                    "Consider using pool in this case. This will limit number of streams that can be created and, therefore, decrease memory consumption.",
+                    "NOTE: Using streams pool can decrease performance since streams will be shared between different threads which will lead to more frequent context switching."
+                  ]
+                },
+                {
+                  "label": "Require serializable",
+                  "type": "check",
+                  "path": "marshaller.OptimizedMarshaller",
+                  "model": "requireSerializable",
+                  "tip": [
+                    "Whether marshaller should require Serializable interface or not."
+                  ]
+                }
+              ]
+            }
+          }
+        },
+        {
+          "label": "Marshal local jobs",
+          "type": "check",
+          "model": "marshalLocalJobs",
+          "placeholder": "false",
+          "tip": [
+            "If this flag is enabled, jobs mapped to local node will be marshalled as if it was remote node."
+          ]
+        },
+        {
+          "label": "Keep alive time",
+          "type": "number",
+          "model": "marshallerCacheKeepAliveTime",
+          "placeholder": 10000,
+          "tip": [
+            "Keep alive time of thread pool that is in charge of processing marshaller messages."
+          ]
+        },
+        {
+          "label": "Pool size",
+          "type": "number",
+          "model": "marshallerCacheThreadPoolSize",
+          "placeholder": "max(8, availableProcessors) * 2",
+          "tip": [
+            "Default size of thread pool that is in charge of processing marshaller messages."
+          ]
+        }
+      ]
+    },
+    {
+      "label": "Metrics",
+      "tip": [
+        "Cluster runtime metrics settings."
+      ],
+      "fields": [
+        {
+          "label": "Elapsed time",
+          "type": "number",
+          "model": "metricsExpireTime",
+          "placeholder": "Long.MAX_VALUE",
+          "min": 1,
+          "tip": [
+            "Time in milliseconds after which a certain metric value is considered expired."
+          ]
+        },
+        {
+          "label": "History size",
+          "type": "number",
+          "model": "metricsHistorySize",
+          "placeholder": 10000,
+          "min": 1,
+          "tip": [
+            "Number of metrics kept in history to compute totals and averages."
+          ]
+        },
+        {
+          "label": "Log frequency",
+          "type": "number",
+          "model": "metricsLogFrequency",
+          "placeholder": 60000,
+          "tip": [
+            "Frequency of metrics log print out. To disable set to 0"
+          ]
+        },
+        {
+          "label": "Update frequency",
+          "type": "number",
+          "model": "metricsUpdateFrequency",
+          "placeholder": 60000,
+          "tip": [
+            "Job metrics update frequency in milliseconds.",
+            "<ul>",
+            "  <li>If set to -1 job metrics are never updated.</li>",
+            "  <li>If set to 0 job metrics are updated on each job start and finish.</li>",
+            "  <li>Positive value defines the actual update frequency.</li>",
+            "</ul>"
+          ]
+        }
+      ]
+    },
+    {
+      "label": "Peer Class Loading",
+      "tip": [
+        "Cluster peer class loading settings."
+      ],
+      "fields": [
+        {
+          "label": "Enable peer class loading",
+          "type": "check",
+          "model": "peerClassLoadingEnabled",
+          "tip": [
+            "Enables/disables peer class loading."
+          ]
+        },
+        {
+          "label": "Local class path exclude",
+          "type": "text",
+          "model": "peerClassLoadingLocalClassPathExclude",
+          "placeholder": "[]",
+          "tip": [
+            "List of packages separated by comma from the system classpath that need to be peer-to-peer loaded from task originating node.",
+            "'*' is supported at the end of the package name which means that all sub-packages and their classes are included like in Java package import clause."
+          ]
+        },
+        {
+          "label": "Missed resources cache size",
+          "type": "number",
+          "model": "peerClassLoadingMissedResourcesCacheSize",
+          "placeholder": 100,
+          "tip": [
+            "If size greater than 0, missed resources will be cached and next resource request ignored.",
+            "If size is 0, then request for the resource will be sent to the remote node every time this resource is requested."
+          ]
+        },
+        {
+          "label": "Pool size",
+          "type": "number",
+          "model": "peerClassLoadingThreadPoolSize",
+          "placeholder": "availableProcessors",
+          "tip": [
+            "Thread pool size to use for peer class loading."
+          ]
+        }
+      ]
+    },
+    {
+      "label": "Swap",
+      "tip": [
+        "Settings for overflow data to disk if it cannot fit in memory."
+      ],
+      "fields": [
+        {
+          "label": "Swap space SPI",
+          "type": "dropdown-details",
+          "path": "swapSpaceSpi",
+          "model": "kind",
+          "items": "swapSpaceSpis",
+          "placeholder": "Choose swap SPI",
+          "tip": [
+            "Provides a mechanism in grid for storing data on disk.",
+            "Ignite cache uses swap space to overflow data to disk if it cannot fit in memory."
+          ],
+          "details": {
+            "FileSwapSpaceSpi": {
+              "fields": [
+                {
+                  "label": "Base directory",
+                  "type": "text",
+                  "path": "swapSpaceSpi.FileSwapSpaceSpi",
+                  "model": "baseDirectory",
+                  "placeholder": "swapspace",
+                  "tip": [
+                    "Base directory where to write files."
+                  ]
+                },
+                {
+                  "label": "Read stripe size",
+                  "type": "number",
+                  "path": "swapSpaceSpi.FileSwapSpaceSpi",
+                  "model": "readStripesNumber",
+                  "placeholder": "available CPU cores",
+                  "tip": [
+                    "Read stripe size defines number of file channels to be used concurrently."
+                  ]
+                },
+                {
+                  "label": "Maximum sparsity",
+                  "type": "number",
+                  "path": "swapSpaceSpi.FileSwapSpaceSpi",
+                  "model": "maximumSparsity",
+                  "placeholder": 0.5,
+                  "tip": [
+                    "This property defines maximum acceptable wasted file space to whole file size ratio.",
+                    "When this ratio becomes higher than specified number compacting thread starts working."
+                  ]
+                },
+                {
+                  "label": "Max write queue size",
+                  "type": "number",
+                  "path": "swapSpaceSpi.FileSwapSpaceSpi",
+                  "model": "maxWriteQueueSize",
+                  "placeholder": "1024 * 1024",
+                  "tip": [
+                    "Max write queue size in bytes.",
+                    "If there are more values are waiting for being written to disk then specified size, SPI will block on store operation."
+                  ]
+                },
+                {
+                  "label": "Write buffer size",
+                  "type": "number",
+                  "path": "swapSpaceSpi.FileSwapSpaceSpi",
+                  "model": "writeBufferSize",
+                  "placeholder": "Available CPU cores",
+                  "tip": [
+                    "Write buffer size in bytes.",
+                    "Write to disk occurs only when this buffer is full."
+                  ]
+                }
+              ]
+            }
+          }
+        }
+      ]
+    },
+    {
+      "label": "Time configuration",
+      "tip": [
+        "Time settings for CLOCK write ordering mode."
+      ],
+      "fields": [
+        {
+          "label": "Samples size",
+          "type": "number",
+          "model": "clockSyncSamples",
+          "placeholder": 8,
+          "tip": [
+            "Number of samples used to synchronize clocks between different nodes.",
+            "Clock synchronization is used for cache version assignment in CLOCK order mode."
+          ]
+        },
+        {
+          "label": "Frequency",
+          "type": "number",
+          "model": "clockSyncFrequency",
+          "placeholder": 120000,
+          "tip": [
+            "Frequency at which clock is synchronized between nodes, in milliseconds.",
+            "Clock synchronization is used for cache version assignment in CLOCK order mode."
+          ]
+        },
+        {
+          "label": "Port base",
+          "type": "number",
+          "model": "timeServerPortBase",
+          "max": 65535,
+          "placeholder": 31100,
+          "tip": [
+            "Time server provides clock synchronization between nodes.",
+            "Base UPD port number for grid time server. Time server will be started on one of free ports in range."
+          ]
+        },
+        {
+          "label": "Port range",
+          "type": "number",
+          "model": "timeServerPortRange",
+          "placeholder": 100,
+          "tip": [
+            "Time server port range."
+          ]
+        }
+      ]
+    },
+    {
+      "label": "Thread pools size",
+      "tip": [
+        "Settings for node thread pools."
+      ],
+      "fields": [
+        {
+          "label": "Public",
+          "type": "number",
+          "model": "publicThreadPoolSize",
+          "placeholder": "max(8, availableProcessors) * 2",
+          "tip": [
+            "Thread pool that is in charge of processing ComputeJob, GridJobs and user messages sent to node."
+          ]
+        },
+        {
+          "label": "System",
+          "type": "number",
+          "model": "systemThreadPoolSize",
+          "placeholder": "max(8, availableProcessors) * 2",
+          "tip": [
+            "Thread pool that is in charge of processing internal system messages."
+          ]
+        },
+        {
+          "label": "Management",
+          "type": "number",
+          "model": "managementThreadPoolSize",
+          "placeholder": 4,
+          "tip": [
+            "Thread pool that is in charge of processing internal and Visor ComputeJob, GridJobs."
+          ]
+        },
+        {
+          "label": "IGFS",
+          "type": "number",
+          "model": "igfsThreadPoolSize",
+          "placeholder": "availableProcessors",
+          "tip": [
+            "Thread pool that is in charge of processing outgoing IGFS messages."
+          ]
+        }
+      ]
+    },
+    {
+      "label": "Transactions",
+      "tip": [
+        "Settings for transactions."
+      ],
+      "fields": [
+        {
+          "label": "Concurrency",
+          "type": "dropdown",
+          "path": "transactionConfiguration",
+          "model": "defaultTxConcurrency",
+          "placeholder": "PESSIMISTIC",
+          "items": "transactionConcurrency",
+          "tip": [
+            "Cache transaction concurrency to use when one is not explicitly specified."
+          ]
+        },
+        {
+          "label": "Isolation",
+          "type": "dropdown",
+          "path": "transactionConfiguration",
+          "model": "transactionIsolation",
+          "placeholder": "REPEATABLE_READ",
+          "items": "transactionIsolation",
+          "tip": [
+            "Default transaction isolation."
+          ]
+        },
+        {
+          "label": "Default timeout",
+          "type": "number",
+          "path": "transactionConfiguration",
+          "model": "defaultTxTimeout",
+          "placeholder": 0,
+          "tip": [
+            "Default transaction timeout."
+          ]
+        },
+        {
+          "label": "Pessimistic log cleanup delay",
+          "type": "number",
+          "path": "transactionConfiguration",
+          "model": "pessimisticTxLogLinger",
+          "placeholder": 10000,
+          "tip": [
+            "Delay, in milliseconds, after which pessimistic recovery entries will be cleaned up for failed node."
+          ]
+        },
+        {
+          "label": "Pessimistic log size",
+          "type": "number",
+          "path": "transactionConfiguration",
+          "model": "pessimisticTxLogSize",
+          "placeholder": 0,
+          "tip": [
+            "Size of pessimistic transactions log stored on node in order to recover transaction commit if originating node has left grid before it has sent all messages to transaction nodes."
+          ]
+        },
+        {
+          "label": "Manager lookup",
+          "type": "text",
+          "model": "txManagerLookupClassName",
+          "tip": [
+            "Class name of transaction manager finder for integration for JEE app servers."
+          ]
+        },
+        {
+          "label": "Enable serializable cache transactions",
+          "type": "check",
+          "path": "transactionConfiguration",
+          "model": "txSerializableEnabled",
+          "tip": [
+            "Flag to enable/disable isolation level for cache transactions.",
+            "Serializable level does carry certain overhead and if not used, should be disabled."
+          ]
+        }
+      ]
+    }
+  ]
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/control-center-web/src/main/js/controllers/models/metadata.json
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/controllers/models/metadata.json b/modules/control-center-web/src/main/js/controllers/models/metadata.json
new file mode 100644
index 0000000..a9b60de
--- /dev/null
+++ b/modules/control-center-web/src/main/js/controllers/models/metadata.json
@@ -0,0 +1,252 @@
+{
+  "screenTip": {
+    "workflowTitle": "Use metadata view to:",
+    "workflowContent": [
+      "<ul>",
+      "  <li>Manually configure metadata for queries and persistence.</li>",
+      "Or",
+      "  <li>Automatically configure metadata from database schema.</li>",
+      "</ul>"
+    ],
+    "whatsNextTitle": "What's next:",
+    "whatsNextContent": [
+      "<ul>",
+      "  <li>Associate caches with metadata.</li>",
+      "  <li>Generate XML and java code on Summary view.</li>",
+      "</ul>"
+    ]
+  },
+  "templateTip": [
+    "Use following template for metadata:",
+    "<ul>",
+    "  <li>query - Create cache type metadata to use with queries only.</li>",
+    "  <li>store - Create cache type metadata to use with JDBC POJO store only.</li>",
+    "  <li>both - Create cache type metadata to use with query and store.</li>",
+    "</ul>"
+  ],
+  "metadataManual": [
+    {
+      "label": "Name",
+      "type": "text",
+      "model": "name",
+      "required": true,
+      "placeholder": "Input name",
+      "id": "defaultFocusId"
+    },
+    {
+      "label": "Metadata for",
+      "type": "dropdown",
+      "model": "kind",
+      "items": "kinds",
+      "tip": [
+        "Use following template for metadata:",
+        "<ul>",
+        "  <li>query - Create cache type metadata to use with queries only.</li>",
+        "  <li>store - Create cache type metadata to use with JDBC POJO store only.</li>",
+        "  <li>both - Create cache type metadata to use with query and store.</li>",
+        "</ul>"
+      ]
+    },
+    {
+      "label": "Database schema",
+      "type": "text",
+      "model": "databaseSchema",
+      "hide": "backupItem.kind != 'both' && backupItem.kind == 'query'",
+      "placeholder": "Input DB schema name",
+      "tip": [
+        "Schema name in database."
+      ]
+    },
+    {
+      "label": "Database table",
+      "type": "text",
+      "model": "databaseTable",
+      "hide": "backupItem.kind != 'both' && backupItem.kind == 'query'",
+      "placeholder": "Input DB table name",
+      "tip": [
+        "Table name in database."
+      ]
+    },
+    {
+      "label": "Key type",
+      "type": "withJavaBuildInTypes",
+      "model": "keyType",
+      "required": true,
+      "placeholder": "Full class name for Key",
+      "tip": [
+        "Key class used to store key in cache."
+      ]
+    },
+    {
+      "label": "Value type",
+      "type": "text",
+      "model": "valueType",
+      "required": true,
+      "placeholder": "Full class name for Value",
+      "tip": [
+        "Value class used to store value in cache."
+      ]
+    },
+    {
+      "label": "Key fields",
+      "type": "dbFields",
+      "model": "keyFields",
+      "keyName": "name",
+      "valueName": "className",
+      "hide": "backupItem.kind != 'both' && backupItem.kind == 'query'",
+      "addTip": "Add key field.",
+      "removeTip": "Remove key field.",
+      "tip": [
+        "Collection of key fields descriptions for CacheJdbcPojoStore."
+      ]
+    },
+    {
+      "label": "Value fields",
+      "type": "dbFields",
+      "model": "valueFields",
+      "keyName": "name",
+      "valueName": "className",
+      "hide": "backupItem.kind != 'both' && backupItem.kind == 'query'",
+      "addTip": "Add value field.",
+      "removeTip": "Remove value field.",
+      "tip": [
+        "Collection of value fields descriptions for CacheJdbcPojoStore.."
+      ]
+    },
+    {
+      "label": "Query fields",
+      "type": "queryFields",
+      "model": "queryFields",
+      "keyName": "name",
+      "valueName": "className",
+      "hide": "backupItem.kind != 'both' && backupItem.kind != 'query'",
+      "focusNewItemId": "newQryField",
+      "focusCurItemId": "curQryField",
+      "addTip": "Add field to query.",
+      "removeTip": "Remove field.",
+      "tip": [
+        "Collection of name-to-type mappings to be queried, in addition to indexed fields."
+      ]
+    },
+    {
+      "label": "Ascending fields",
+      "type": "queryFields",
+      "model": "ascendingFields",
+      "keyName": "name",
+      "valueName": "className",
+      "hide": "backupItem.kind != 'both' && backupItem.kind != 'query'",
+      "focusNewItemId": "newAscField",
+      "focusCurItemId": "curAscField",
+      "addTip": "Add field to index in ascending order.",
+      "removeTip": "Remove field.",
+      "tip": [
+        "Collection of name-to-type mappings to index in ascending order."
+      ]
+    },
+    {
+      "label": "Descending fields",
+      "type": "queryFields",
+      "model": "descendingFields",
+      "keyName": "name",
+      "valueName": "className",
+      "hide": "backupItem.kind != 'both' && backupItem.kind != 'query'",
+      "focusNewItemId": "newDescField",
+      "focusCurItemId": "curDescField",
+      "addTip": "Add field to index in descending order.",
+      "removeTip": "Remove field.",
+      "tip": [
+        "Collection of name-to-type mappings to index in descending order."
+      ]
+    },
+    {
+      "label": "Text fields",
+      "type": "table-simple",
+      "model": "textFields",
+      "hide": "backupItem.kind != 'both' && backupItem.kind != 'query'",
+      "placeholder": "Field name",
+      "focusNewItemId": "newTextField",
+      "focusCurItemId": "curTextField",
+      "addTip": "Add field to index as text.",
+      "removeTip": "Remove field.",
+      "tableTip": [
+        "Fields to index as text."
+      ],
+      "tip": [
+        "Field to index as text."
+      ]
+    },
+    {
+      "label": "Groups",
+      "type": "queryGroups",
+      "model": "groups",
+      "hide": "backupItem.kind != 'both' && backupItem.kind != 'query'",
+      "addTip": "Add new group.",
+      "removeTip": "Remove group.",
+      "addItemTip": "Add new field to group.",
+      "removeItemTip": "Remove field from group.",
+      "tip": [
+        "Collection of group indexes."
+      ]
+    }
+  ],
+  "metadataDb": [
+    {
+      "label": "Name",
+      "type": "text",
+      "model": "name"
+    },
+    {
+      "label": "Database type",
+      "type": "dropdown",
+      "model": "rdbms",
+      "placeholder": "Choose database",
+      "items": "databases",
+      "tip": [
+        "Select database type to connect for loading tables metadata."
+      ]
+    },
+    {
+      "label": "Database name",
+      "type": "text",
+      "model": "dbName",
+      "tip": [
+        "Database name to connect for loading tables metadata."
+      ]
+    },
+    {
+      "label": "Host",
+      "type": "text",
+      "model": "host",
+      "placeholder": "IP address or host",
+      "tip": [
+        "IP address or host name where database server deployed."
+      ]
+    },
+    {
+      "label": "Port",
+      "type": "number",
+      "model": "port",
+      "max": 65535,
+      "tip": [
+        "Port number for connecting to database."
+      ]
+    },
+    {
+      "label": "User",
+      "type": "text",
+      "model": "user",
+      "tip": [
+        "User name for connecting to database."
+      ]
+    },
+    {
+      "label": "Password",
+      "type": "password",
+      "model": "password",
+      "tip": [
+        "Password for connecting to database.",
+        "Note, password would not be saved."
+      ]
+    }
+  ]
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/control-center-web/src/main/js/controllers/models/sql.json
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/controllers/models/sql.json b/modules/control-center-web/src/main/js/controllers/models/sql.json
new file mode 100644
index 0000000..bcb03e0
--- /dev/null
+++ b/modules/control-center-web/src/main/js/controllers/models/sql.json
@@ -0,0 +1,5 @@
+{
+  "screenTip": [
+    "Select cache and execute SQL queries."
+  ]
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/control-center-web/src/main/js/controllers/models/summary.json
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/controllers/models/summary.json b/modules/control-center-web/src/main/js/controllers/models/summary.json
new file mode 100644
index 0000000..29edb3d
--- /dev/null
+++ b/modules/control-center-web/src/main/js/controllers/models/summary.json
@@ -0,0 +1,163 @@
+{
+  "screenTip": {
+    "workflowTitle": "Use summary view to:",
+    "workflowContent": [
+      "<ul>",
+      "  <li>See XML and java code for server nodes configurations.</li>",
+      "  <li>See XML and java code for client nodes configurations.</li>",
+      "</ul>"
+    ],
+    "whatsNextTitle": "What's next:",
+    "whatsNextContent": [
+      "<ul>",
+      "  <li>Download XML or java code configuration.</li>",
+      "  <li>Start Ignite cluster with downloaded configuration.</li>",
+      "</ul>"
+    ]
+  },
+  "clientFields": [
+    {
+      "label": "Near cache start size",
+      "type": "number",
+      "path": "nearConfiguration",
+      "model": "nearStartSize",
+      "placeholder": 375000,
+      "tip": [
+        "Initial cache size for near cache which will be used to pre-create internal hash table after start."
+      ]
+    },
+    {
+      "label": "Near cache eviction policy",
+      "type": "dropdown-details",
+      "path": "nearConfiguration.nearEvictionPolicy",
+      "model": "kind",
+      "placeholder": "Choose eviction policy",
+      "items": "evictionPolicies",
+      "tip": [
+        "Cache expiration policy."
+      ],
+      "details": {
+        "LRU": {
+          "expanded": false,
+          "fields": [
+            {
+              "label": "Batch size",
+              "type": "number",
+              "path": "nearConfiguration.nearEvictionPolicy.LRU",
+              "model": "batchSize",
+              "placeholder": 1,
+              "tip": [
+                "Number of entries to remove on shrink."
+              ]
+            },
+            {
+              "label": "Max memory size",
+              "type": "number",
+              "path": "nearConfiguration.nearEvictionPolicy.LRU",
+              "model": "maxMemorySize",
+              "placeholder": 0,
+              "tip": [
+                "Maximum allowed cache size in bytes."
+              ]
+            },
+            {
+              "label": "Max size",
+              "type": "number",
+              "path": "nearConfiguration.nearEvictionPolicy.LRU",
+              "model": "maxSize",
+              "placeholder": 100000,
+              "tip": [
+                "Maximum allowed size of cache before entry will start getting evicted."
+              ]
+            }
+          ]
+        },
+        "RND": {
+          "expanded": false,
+          "fields": [
+            {
+              "label": "Max size",
+              "type": "number",
+              "path": "nearConfiguration.nearEvictionPolicy.RND",
+              "model": "maxSize",
+              "placeholder": 100000,
+              "tip": [
+                "Maximum allowed size of cache before entry will start getting evicted."
+              ]
+            }
+          ]
+        },
+        "FIFO": {
+          "expanded": false,
+          "fields": [
+            {
+              "label": "Batch size",
+              "type": "number",
+              "path": "nearConfiguration.nearEvictionPolicy.FIFO",
+              "model": "batchSize",
+              "placeholder": 1,
+              "tip": [
+                "Number of entries to remove on shrink."
+              ]
+            },
+            {
+              "label": "Max memory size",
+              "type": "number",
+              "path": "nearConfiguration.nearEvictionPolicy.FIFO",
+              "model": "maxMemorySize",
+              "placeholder": 0,
+              "tip": [
+                "Maximum allowed cache size in bytes."
+              ]
+            },
+            {
+              "label": "Max size",
+              "type": "number",
+              "path": "nearConfiguration.nearEvictionPolicy.FIFO",
+              "model": "maxSize",
+              "placeholder": 100000,
+              "tip": [
+                "Maximum allowed size of cache before entry will start getting evicted."
+              ]
+            }
+          ]
+        },
+        "SORTED": {
+          "expanded": false,
+          "fields": [
+            {
+              "label": "Batch size",
+              "type": "number",
+              "path": "nearConfiguration.nearEvictionPolicy.SORTED",
+              "model": "batchSize",
+              "placeholder": 1,
+              "tip": [
+                "Number of entries to remove on shrink."
+              ]
+            },
+            {
+              "label": "Max memory size",
+              "type": "number",
+              "path": "nearConfiguration.nearEvictionPolicy.SORTED",
+              "model": "maxMemorySize",
+              "placeholder": 0,
+              "tip": [
+                "Maximum allowed cache size in bytes."
+              ]
+            },
+            {
+              "label": "Max size",
+              "type": "number",
+              "path": "nearConfiguration.nearEvictionPolicy.SORTED",
+              "model": "maxSize",
+              "placeholder": 100000,
+              "tip": [
+                "Maximum allowed size of cache before entry will start getting evicted."
+              ]
+            }
+          ]
+        }
+      }
+    }
+  ]
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/control-center-web/src/main/js/controllers/profile-controller.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/controllers/profile-controller.js b/modules/control-center-web/src/main/js/controllers/profile-controller.js
new file mode 100644
index 0000000..a67df63
--- /dev/null
+++ b/modules/control-center-web/src/main/js/controllers/profile-controller.js
@@ -0,0 +1,51 @@
+/*
+ * 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.
+ */
+
+controlCenterModule.controller('profileController', ['$scope', '$http', '$common', function ($scope, $http, $common) {
+    $scope.profileUser = angular.copy($scope.user);
+
+    $scope.saveUser = function () {
+        var profile = $scope.profileUser;
+
+        if (profile) {
+            var userName = profile.username;
+            var changeUsername = userName != $scope.user.username;
+
+            var email = profile.email;
+            var changeEmail = email != $scope.user.email;
+
+            if (changeUsername || changeEmail || profile.changePassword) {
+                $http.post('/profile/saveUser', {
+                    _id: profile._id,
+                    userName: changeUsername ? userName : undefined,
+                    email: changeEmail ? email : undefined,
+                    newPassword: profile.changePassword ? profile.newPassword : undefined
+                }).success(function (user) {
+                    $common.showInfo('Profile saved.');
+
+                    if (changeUsername)
+                        $scope.user.username = userName;
+
+                    if (changeEmail)
+                        $scope.user.email = email;
+                }).error(function (err) {
+                    $common.showError('Failed to save profile: ' + $common.errorMessage(err));
+                });
+            }
+        }
+    };
+}]);
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/control-center-web/src/main/js/controllers/sql-controller.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/controllers/sql-controller.js b/modules/control-center-web/src/main/js/controllers/sql-controller.js
new file mode 100644
index 0000000..12772c6
--- /dev/null
+++ b/modules/control-center-web/src/main/js/controllers/sql-controller.js
@@ -0,0 +1,84 @@
+/*
+ * 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.
+ */
+
+var demoResults = [
+    {
+        id: 256,
+        firstName: 'Ivan',
+        lastName: 'Ivanov'
+    },
+    {
+        id: 384,
+        firstName: 'Sergey',
+        lastName: 'Petrov'
+    },
+    {
+        id: 923,
+        firstName: 'Andrey',
+        lastName: 'Sidorov'
+    }
+];
+
+var demoCaches = [{_id: '1', name: 'Users', mode: 'LOCAL'}, {_id: '2', name: 'Organizations', mode: 'REPLICATED'}, {_id: '3', name: 'Cities', mode: 'PARTITIONED'}];
+
+
+
+controlCenterModule.controller('sqlController', ['$scope', '$http', '$common', function ($scope, $http, $common) {
+    $scope.joinTip = $common.joinTip;
+
+    $scope.pageSizes = [50, 100, 200, 400, 800, 1000];
+
+    $scope.tabs = [
+        {
+            query: "SELECT u.id, u.firstName, u.lastName FROM User u WHERE u.name LIKE 'aaaa'",
+            cols: Object.keys(demoResults[0]),
+            page: 1,
+            hasMore: true,
+            total: 0,
+            rows: demoResults
+        },
+        {query: "SELECT * FROM Organization"}
+    ];
+
+    $scope.addTab = function() {
+        console.log('addTab');
+
+        $scope.tabs.push({query: "SELECT "});
+    };
+
+    $scope.removeTab = function(idx) {
+        console.log('removeTab');
+
+        $scope.tabs.splice(idx, 1);
+    };
+
+    $scope.modes = [
+        {value: 'PARTITIONED', label: 'PARTITIONED'},
+        {value: 'REPLICATED', label: 'REPLICATED'},
+        {value: 'LOCAL', label: 'LOCAL'}
+    ];
+
+    $http.get('/models/sql.json')
+        .success(function (data) {
+            $scope.screenTip = data.screenTip;
+        })
+        .error(function (errMsg) {
+            $common.showError(errMsg);
+        });
+
+    $scope.caches = demoCaches;
+}]);

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/control-center-web/src/main/js/controllers/summary-controller.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/controllers/summary-controller.js b/modules/control-center-web/src/main/js/controllers/summary-controller.js
new file mode 100644
index 0000000..531dc83
--- /dev/null
+++ b/modules/control-center-web/src/main/js/controllers/summary-controller.js
@@ -0,0 +1,170 @@
+/*
+ * 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.
+ */
+
+controlCenterModule.controller('summaryController', ['$scope', '$http', '$common', function ($scope, $http, $common) {
+    $scope.joinTip = $common.joinTip;
+    $scope.getModel = $common.getModel;
+
+    $scope.javaClassItems = [
+        {label: 'snippet', value: false},
+        {label: 'factory class', value: true}
+    ];
+
+    $scope.evictionPolicies = [
+        {value: 'LRU', label: 'LRU'},
+        {value: 'RND', label: 'Random'},
+        {value: 'FIFO', label: 'FIFO'},
+        {value: 'SORTED', label: 'Sorted'},
+        {value: undefined, label: 'Not set'}
+    ];
+
+    $scope.oss = ['debian:8', 'ubuntu:14.10'];
+
+    $scope.configServer = {javaClassServer: false, os: undefined};
+    $scope.backupItem = {javaClassClient: false};
+
+    $http.get('/models/summary.json')
+        .success(function (data) {
+            $scope.screenTip = data.screenTip;
+            $scope.clientFields = data.clientFields;
+        })
+        .error(function (errMsg) {
+            $common.showError(errMsg);
+        });
+
+    $scope.clusters = [];
+
+    $scope.aceInit = function (editor) {
+        editor.setReadOnly(true);
+        editor.setOption("highlightActiveLine", false);
+
+        var renderer = editor.renderer;
+
+        renderer.setHighlightGutterLine(false);
+        renderer.setShowPrintMargin(false);
+        renderer.setOption('fontSize', '14px');
+
+        editor.setTheme('ace/theme/chrome');
+    };
+
+    $scope.reloadServer = function () {
+        $scope.javaServer = $scope.configServer.javaClassServer ? $scope.configServer.javaClass : $scope.configServer.javaSnippet;
+
+        if ($scope.configServer.docker) {
+            var os = $scope.configServer.os ? $scope.configServer.os : $scope.oss[0];
+
+            $scope.dockerServer = $scope.configServer.docker.replace(new RegExp('\%OS\%', 'g'), os);
+        }
+    };
+
+    $scope.selectItem = function (cluster) {
+        if (!cluster)
+            return;
+
+        $scope.selectedItem = cluster;
+
+        $scope.$watch('javaClassServer', $scope.reloadServer);
+        $scope.$watch('os', $scope.reloadServer);
+
+        $scope.generateServer(cluster);
+
+        $scope.reloadServer();
+
+        $scope.$watch('configServer', function () {
+            $scope.reloadServer();
+        }, true);
+
+        $scope.$watch('backupItem', function () {
+            $scope.generateClient();
+        }, true);
+    };
+
+    $scope.generateServer = function (cluster) {
+        $http.post('summary/generator', {_id: cluster._id})
+            .success(function (data) {
+                $scope.xmlServer = data.xmlServer;
+
+                $scope.configServer.javaClass = data.javaClassServer;
+                $scope.configServer.javaSnippet = data.javaSnippetServer;
+                $scope.configServer.docker = data.docker;
+            }).error(function (errMsg) {
+                $common.showError('Failed to generate config: ' + errMsg);
+            });
+    };
+
+    $scope.generateClient = function () {
+        $http.post('summary/generator', {
+            _id: $scope.selectedItem._id, javaClass: $scope.backupItem.javaClassClient,
+            clientNearConfiguration: $scope.backupItem.nearConfiguration
+        })
+            .success(function (data) {
+                $scope.xmlClient = data.xmlClient;
+                $scope.javaClient = data.javaClient;
+            }).error(function (errMsg) {
+                $common.showError('Failed to generate config: ' + errMsg);
+            });
+    };
+
+    $scope.download = function () {
+        $http.post('summary/download', {_id: $scope.selectedItem._id, javaClass: $scope.javaClass, os: $scope.os})
+            .success(function (data) {
+                var file = document.createElement('a');
+
+                file.setAttribute('href', 'data:application/octet-stream;charset=utf-8,' + data);
+                file.setAttribute('download', $scope.selectedItem.name + '-configuration.zip');
+
+                file.style.display = 'none';
+
+                document.body.appendChild(file);
+
+                file.click();
+
+                document.body.removeChild(file);
+            })
+            .error(function (errMsg) {
+                $common.showError('Failed to generate zip: ' + errMsg);
+            });
+    };
+
+    $http.post('clusters/list').success(function (data) {
+        $scope.clusters = data.clusters;
+
+        if ($scope.clusters.length > 0) {
+            var restoredId = sessionStorage.summarySelectedId;
+
+            var selectIdx = 0;
+
+            if (restoredId) {
+                var idx = _.findIndex($scope.clusters, function (cluster) {
+                    return cluster._id == restoredId;
+                });
+
+                if (idx >= 0)
+                    selectIdx = idx;
+                else
+                    delete sessionStorage.summarySelectedId;
+            }
+
+            $scope.selectItem($scope.clusters[selectIdx]);
+
+            $scope.$watch('selectedItem', function (val) {
+                if (val)
+                    sessionStorage.summarySelectedId = val._id;
+            }, true);
+        }
+    });
+}]);

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/control-center-web/src/main/js/db.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/db.js b/modules/control-center-web/src/main/js/db.js
new file mode 100644
index 0000000..5232e24
--- /dev/null
+++ b/modules/control-center-web/src/main/js/db.js
@@ -0,0 +1,370 @@
+/*
+ * 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.
+ */
+
+var config = require('./helpers/configuration-loader.js');
+
+// Mongoose for mongodb.
+var mongoose = require('mongoose'),
+    Schema = mongoose.Schema,
+    ObjectId = mongoose.Schema.Types.ObjectId,
+    passportLocalMongoose = require('passport-local-mongoose');
+
+var deepPopulate = require('mongoose-deep-populate');
+
+// Connect to mongoDB database.
+mongoose.connect(config.get('mongoDB:url'), {server: {poolSize: 4}});
+
+// Define account model.
+var AccountSchema = new Schema({
+    username: String,
+    email: String,
+    lastLogin: Date,
+    admin: Boolean
+});
+
+AccountSchema.plugin(passportLocalMongoose, {usernameField: 'email', limitAttempts: true, lastLoginField: 'lastLogin',
+    usernameLowerCase: true});
+
+AccountSchema.set('toJSON', {
+    transform: function(doc, ret) {
+        return {
+            _id: ret._id,
+            email: ret.email,
+            username: ret.username,
+            admin: ret.admin,
+            lastLogin: ret.lastLogin
+        };
+    }
+});
+
+exports.Account = mongoose.model('Account', AccountSchema);
+
+// Define space model.
+exports.Space = mongoose.model('Space', new Schema({
+    name: String,
+    owner: {type: ObjectId, ref: 'Account'},
+    usedBy: [{
+        permission: {type: String, enum: ['VIEW', 'FULL']},
+        account: {type: ObjectId, ref: 'Account'}
+    }]
+}));
+
+// Define cache type metadata model.
+var CacheTypeMetadataSchema = new Schema({
+    space: {type: ObjectId, ref: 'Space'},
+    name: String,
+    kind: {type: String, enum: ['query', 'store', 'both']},
+    databaseSchema: String,
+    databaseTable: String,
+    keyType: String,
+    valueType: String,
+    keyFields: [{databaseName: String, databaseType: String, javaName: String, javaType: String}],
+    valueFields: [{databaseName: String, databaseType: String, javaName: String, javaType: String}],
+    queryFields: [{name: String, className: String}],
+    ascendingFields: [{name: String, className: String}],
+    descendingFields:  [{name: String, className: String}],
+    textFields: [String],
+    groups: [{name: String, fields: [{name: String, className: String, direction: Boolean}]}]
+});
+
+exports.CacheTypeMetadata = mongoose.model('CacheTypeMetadata', CacheTypeMetadataSchema);
+
+// Define cache model.
+var CacheSchema = new Schema({
+    space: {type: ObjectId, ref: 'Space'},
+    name: String,
+    mode: {type: String, enum: ['PARTITIONED', 'REPLICATED', 'LOCAL']},
+    atomicityMode: {type: String, enum: ['ATOMIC', 'TRANSACTIONAL']},
+
+    backups: Number,
+    memoryMode: {type: String, enum: ['ONHEAP_TIERED', 'OFFHEAP_TIERED', 'OFFHEAP_VALUES']},
+    offHeapMaxMemory: Number,
+    startSize: Number,
+    swapEnabled: Boolean,
+
+    evictionPolicy: {
+        kind: {type: String, enum: ['LRU', 'RND', 'FIFO', 'Sorted']},
+        LRU: {
+            batchSize: Number,
+            maxMemorySize: Number,
+            maxSize: Number
+        },
+        RND: {
+            maxSize: Number
+        },
+        FIFO: {
+            batchSize: Number,
+            maxMemorySize: Number,
+            maxSize: Number
+        },
+        SORTED: {
+            batchSize: Number,
+            maxMemorySize: Number,
+            maxSize: Number
+        }
+    },
+
+    rebalanceMode: {type: String, enum: ['SYNC', 'ASYNC', 'NONE']},
+    rebalanceThreadPoolSize: Number,
+    rebalanceBatchSize: Number,
+    rebalanceOrder: Number,
+    rebalanceDelay: Number,
+    rebalanceTimeout: Number,
+    rebalanceThrottle: Number,
+
+    storeMetadata: [{type: ObjectId, ref: 'CacheTypeMetadata'}],
+    cacheStoreFactory: {
+        kind: {
+            type: String,
+            enum: ['CacheJdbcPojoStoreFactory', 'CacheJdbcBlobStoreFactory', 'CacheHibernateBlobStoreFactory']
+        },
+        CacheJdbcPojoStoreFactory: {
+            dataSourceBean: String,
+            dialect: {
+                type: String,
+                enum: ['Oracle', 'DB2', 'SQLServer', 'MySQL', 'PosgreSQL', 'H2']
+            }
+        },
+        CacheJdbcBlobStoreFactory: {
+            user: String,
+            dataSourceBean: String,
+            initSchema: Boolean,
+            createTableQuery: String,
+            loadQuery: String,
+            insertQuery: String,
+            updateQuery: String,
+            deleteQuery: String
+        },
+        CacheHibernateBlobStoreFactory: {
+            hibernateProperties: [String]
+        }
+    },
+    loadPreviousValue: Boolean,
+    readThrough: Boolean,
+    writeThrough: Boolean,
+
+    writeBehindEnabled: Boolean,
+    writeBehindBatchSize: Number,
+    writeBehindFlushSize: Number,
+    writeBehindFlushFrequency: Number,
+    writeBehindFlushThreadCount: Number,
+
+    invalidate: Boolean,
+    defaultLockTimeout: Number,
+    transactionManagerLookupClassName: String,
+
+    sqlEscapeAll: Boolean,
+    sqlOnheapRowCacheSize: Number,
+    longQueryWarningTimeout: Number,
+    queryMetadata: [{type: ObjectId, ref: 'CacheTypeMetadata'}],
+    indexedTypes: [{keyClass: String, valueClass: String}],
+    sqlFunctionClasses: [String],
+    statisticsEnabled: Boolean,
+    managementEnabled: Boolean,
+    readFromBackup: Boolean,
+    copyOnRead: Boolean,
+    maxConcurrentAsyncOperations: Number,
+    nearConfiguration: {
+        nearStartSize: Number,
+        nearEvictionPolicy: {
+            kind: {type: String, enum: ['LRU', 'RND', 'FIFO', 'Sorted']},
+            LRU: {
+                batchSize: Number,
+                maxMemorySize: Number,
+                maxSize: Number
+            },
+            RND: {
+                maxSize: Number
+            },
+            FIFO: {
+                batchSize: Number,
+                maxMemorySize: Number,
+                maxSize: Number
+            },
+            SORTED: {
+                batchSize: Number,
+                maxMemorySize: Number,
+                maxSize: Number
+            }
+        }
+    }
+});
+
+exports.Cache = mongoose.model('Cache', CacheSchema);
+
+// Define cluster schema.
+var ClusterSchema = new Schema({
+    space: {type: ObjectId, ref: 'Space'},
+    name: String,
+    discovery: {
+        kind: {type: String, enum: ['Vm', 'Multicast', 'S3', 'Cloud', 'GoogleStorage', 'Jdbc', 'SharedFs']},
+        Vm: {
+            addresses: [String]
+        },
+        Multicast: {
+            multicastGroup: String,
+            multicastPort: Number,
+            responseWaitTime: Number,
+            addressRequestAttempts: Number,
+            localAddress: String
+        },
+        S3: {
+            bucketName: String
+        },
+        Cloud: {
+            credential: String,
+            credentialPath: String,
+            identity: String,
+            provider: String,
+            regions: [String],
+            zones:  [String]
+        },
+        GoogleStorage: {
+            projectName: String,
+            bucketName: String,
+            serviceAccountP12FilePath: String,
+            addrReqAttempts: String
+        },
+        Jdbc: {
+            initSchema: Boolean
+        },
+        SharedFs: {
+            path: String
+        }
+    },
+    atomicConfiguration: {
+        backups: Number,
+        cacheMode: {type: String, enum: ['LOCAL', 'REPLICATED', 'PARTITIONED']},
+        atomicSequenceReserveSize: Number
+    },
+    caches: [{type: ObjectId, ref: 'Cache'}],
+    cacheSanityCheckEnabled: Boolean,
+    clockSyncSamples: Number,
+    clockSyncFrequency: Number,
+    deploymentMode: {type: String, enum: ['PRIVATE', 'ISOLATED', 'SHARED', 'CONTINUOUS']},
+    discoveryStartupDelay: Number,
+    igfsThreadPoolSize: Number,
+    includeEventTypes: [{
+        type: String, enum: ['EVTS_CHECKPOINT', 'EVTS_DEPLOYMENT', 'EVTS_ERROR', 'EVTS_DISCOVERY',
+            'EVTS_JOB_EXECUTION', 'EVTS_TASK_EXECUTION', 'EVTS_CACHE', 'EVTS_CACHE_REBALANCE', 'EVTS_CACHE_LIFECYCLE',
+            'EVTS_CACHE_QUERY', 'EVTS_SWAPSPACE', 'EVTS_IGFS']
+    }],
+    managementThreadPoolSize: Number,
+    marshaller: {
+        kind: {type: String, enum: ['OptimizedMarshaller', 'JdkMarshaller']},
+        OptimizedMarshaller: {
+            poolSize: Number,
+            requireSerializable: Boolean
+        }
+    },
+    marshalLocalJobs: Boolean,
+    marshallerCacheKeepAliveTime: Number,
+    marshallerCacheThreadPoolSize: Number,
+    metricsExpireTime: Number,
+    metricsHistorySize: Number,
+    metricsLogFrequency: Number,
+    metricsUpdateFrequency: Number,
+    networkTimeout: Number,
+    networkSendRetryDelay: Number,
+    networkSendRetryCount: Number,
+    peerClassLoadingEnabled: Boolean,
+    peerClassLoadingLocalClassPathExclude: [String],
+    peerClassLoadingMissedResourcesCacheSize: Number,
+    peerClassLoadingThreadPoolSize: Number,
+    publicThreadPoolSize: Number,
+    segmentCheckFrequency: Number,
+    segmentationPolicy: {type: String, enum: ['RESTART_JVM', 'STOP', 'NOOP']},
+    allSegmentationResolversPassRequired: Boolean,
+    segmentationResolveAttempts: Number,
+    swapSpaceSpi: {
+        kind: {type: String, enum: ['FileSwapSpaceSpi']},
+        FileSwapSpaceSpi: {
+            baseDirectory: String,
+            readStripesNumber: Number,
+            maximumSparsity: Number,
+            maxWriteQueueSize: Number,
+            writeBufferSize: Number
+        }
+    },
+    systemThreadPoolSize: Number,
+    timeServerPortBase: Number,
+    timeServerPortRange: Number,
+    transactionConfiguration: {
+        defaultTxConcurrency: {type: String, enum: ['OPTIMISTIC', 'PESSIMISTIC']},
+        transactionIsolation: {type: String, enum: ['READ_COMMITTED', 'REPEATABLE_READ', 'SERIALIZABLE']},
+        defaultTxTimeout: Number,
+        pessimisticTxLogLinger: Number,
+        pessimisticTxLogSize: Number,
+        txSerializableEnabled: Boolean
+    },
+    waitForSegmentOnStart: Boolean
+});
+
+ClusterSchema.plugin(deepPopulate, {
+    whitelist: [
+        'caches',
+        'caches.queryMetadata',
+        'caches.storeMetadata'
+    ]
+});
+
+// Define cluster model.
+exports.Cluster = mongoose.model('Cluster', ClusterSchema);
+
+// Define persistence schema.
+var PersistenceSchema = new Schema({
+    space: {type: ObjectId, ref: 'Space'},
+    name: String,
+    rdbms: {type: String, enum: ['oracle', 'db2', 'mssql', 'postgre', 'mysql', 'h2']},
+    dbName: String,
+    host: String,
+    user: String,
+    tables: [{
+        use: Boolean,
+        schemaName: String,
+        tableName: String,
+        keyClass: String,
+        valueClass: String,
+        columns: [{
+            use: Boolean,
+            pk: Boolean,
+            ak: Boolean,
+            notNull: Boolean,
+            databaseName: String,
+            databaseType: Number,
+            javaName: String,
+            javaType: String
+        }]
+    }]
+});
+
+// Define persistence model.
+exports.Persistence = mongoose.model('Persistence', PersistenceSchema);
+
+exports.upsert = function (model, data, cb) {
+    if (data._id) {
+        var id = data._id;
+
+        delete data._id;
+
+        model.findOneAndUpdate({_id: id}, data, cb);
+    }
+    else
+        new model(data).save(cb);
+};
+
+exports.mongoose = mongoose;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/control-center-web/src/main/js/helpers/configuration-loader.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/helpers/configuration-loader.js b/modules/control-center-web/src/main/js/helpers/configuration-loader.js
new file mode 100644
index 0000000..6dbb577
--- /dev/null
+++ b/modules/control-center-web/src/main/js/helpers/configuration-loader.js
@@ -0,0 +1,22 @@
+/*
+ * 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.
+ */
+
+var config = require('nconf');
+
+config.file({'file': 'config/default.json'});
+
+module.exports = config;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/control-center-web/src/main/js/helpers/data-structures.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/helpers/data-structures.js b/modules/control-center-web/src/main/js/helpers/data-structures.js
new file mode 100644
index 0000000..2462708
--- /dev/null
+++ b/modules/control-center-web/src/main/js/helpers/data-structures.js
@@ -0,0 +1,84 @@
+/*
+ * 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.
+ */
+
+eventGroups = {
+    EVTS_CHECKPOINT: ['EVT_CHECKPOINT_SAVED', 'EVT_CHECKPOINT_LOADED', 'EVT_CHECKPOINT_REMOVED'],
+    EVTS_DEPLOYMENT: ['EVT_CLASS_DEPLOYED', 'EVT_CLASS_UNDEPLOYED', 'EVT_CLASS_DEPLOY_FAILED', 'EVT_TASK_DEPLOYED',
+        'EVT_TASK_UNDEPLOYED', 'EVT_TASK_DEPLOY_FAILED'],
+    EVTS_ERROR: ['EVT_JOB_TIMEDOUT', 'EVT_JOB_FAILED', 'EVT_JOB_FAILED_OVER', 'EVT_JOB_REJECTED', 'EVT_JOB_CANCELLED',
+        'EVT_TASK_TIMEDOUT', 'EVT_TASK_FAILED', 'EVT_CLASS_DEPLOY_FAILED', 'EVT_TASK_DEPLOY_FAILED',
+        'EVT_TASK_DEPLOYED', 'EVT_TASK_UNDEPLOYED', 'EVT_CACHE_REBALANCE_STARTED', 'EVT_CACHE_REBALANCE_STOPPED'],
+    EVTS_DISCOVERY: ['EVT_NODE_JOINED', 'EVT_NODE_LEFT', 'EVT_NODE_FAILED', 'EVT_NODE_SEGMENTED',
+        'EVT_CLIENT_NODE_DISCONNECTED', 'EVT_CLIENT_NODE_RECONNECTED'],
+    EVTS_JOB_EXECUTION: ['EVT_JOB_MAPPED', 'EVT_JOB_RESULTED', 'EVT_JOB_FAILED_OVER', 'EVT_JOB_STARTED',
+        'EVT_JOB_FINISHED', 'EVT_JOB_TIMEDOUT', 'EVT_JOB_REJECTED', 'EVT_JOB_FAILED', 'EVT_JOB_QUEUED',
+        'EVT_JOB_CANCELLED'],
+    EVTS_TASK_EXECUTION: ['EVT_TASK_STARTED', 'EVT_TASK_FINISHED', 'EVT_TASK_FAILED', 'EVT_TASK_TIMEDOUT',
+        'EVT_TASK_SESSION_ATTR_SET', 'EVT_TASK_REDUCED'],
+    EVTS_CACHE: ['EVT_CACHE_ENTRY_CREATED', 'EVT_CACHE_ENTRY_DESTROYED', 'EVT_CACHE_OBJECT_PUT',
+        'EVT_CACHE_OBJECT_READ', 'EVT_CACHE_OBJECT_REMOVED', 'EVT_CACHE_OBJECT_LOCKED', 'EVT_CACHE_OBJECT_UNLOCKED',
+        'EVT_CACHE_OBJECT_SWAPPED', 'EVT_CACHE_OBJECT_UNSWAPPED', 'EVT_CACHE_OBJECT_EXPIRED'],
+    EVTS_CACHE_REBALANCE: ['EVT_CACHE_REBALANCE_STARTED', 'EVT_CACHE_REBALANCE_STOPPED',
+        'EVT_CACHE_REBALANCE_PART_LOADED', 'EVT_CACHE_REBALANCE_PART_UNLOADED', 'EVT_CACHE_REBALANCE_OBJECT_LOADED',
+        'EVT_CACHE_REBALANCE_OBJECT_UNLOADED', 'EVT_CACHE_REBALANCE_PART_DATA_LOST'],
+    EVTS_CACHE_LIFECYCLE: ['EVT_CACHE_STARTED', 'EVT_CACHE_STOPPED', 'EVT_CACHE_NODES_LEFT'],
+    EVTS_CACHE_QUERY: ['EVT_CACHE_QUERY_EXECUTED', 'EVT_CACHE_QUERY_OBJECT_READ'],
+    EVTS_SWAPSPACE: ['EVT_SWAP_SPACE_CLEARED', 'EVT_SWAP_SPACE_DATA_REMOVED', 'EVT_SWAP_SPACE_DATA_READ',
+        'EVT_SWAP_SPACE_DATA_STORED', 'EVT_SWAP_SPACE_DATA_EVICTED'],
+    EVTS_IGFS: ['EVT_IGFS_FILE_CREATED', 'EVT_IGFS_FILE_RENAMED', 'EVT_IGFS_FILE_DELETED', 'EVT_IGFS_FILE_OPENED_READ',
+        'EVT_IGFS_FILE_OPENED_WRITE', 'EVT_IGFS_FILE_CLOSED_WRITE', 'EVT_IGFS_FILE_CLOSED_READ', 'EVT_IGFS_FILE_PURGED',
+        'EVT_IGFS_META_UPDATED', 'EVT_IGFS_DIR_CREATED', 'EVT_IGFS_DIR_RENAMED', 'EVT_IGFS_DIR_DELETED']
+};
+
+jdbcTypes = {
+    BIT: {value: "BIT", code: -7, label: "BIT"},
+    TINYINT: {value: "TINYINT", code: -6, label: "TINYINT"},
+    SMALLINT: {value: "SMALLINT", code: 5, label: "SMALLINT"},
+    INTEGER: {value: "INTEGER", code: 4, label: "INTEGER"},
+    BIGINT: {value: "BIGINT", code: -5, label: "BIGINT"},
+    FLOAT: {value: "FLOAT", code: 6, label: "FLOAT"},
+    REAL: {value: "REAL", code: 7, label: "REAL"},
+    DOUBLE: {value: "DOUBLE", code: 8, label: "DOUBLE"},
+    NUMERIC: {value: "NUMERIC", code: 2, label: "NUMERIC"},
+    DECIMAL: {value: "DECIMAL", code: 3, label: "DECIMAL"},
+    CHAR: {value: "CHAR", code: 1, label: "CHAR"},
+    VARCHAR: {value: "VARCHAR", code: 12, label: "VARCHAR"},
+    DATE: {value: "DATE", code: 91, label: "DATE"},
+    TIME: {value: "TIME", code: 92, label: "TIME"},
+    TIMESTAMP: {value: "TIMESTAMP", code: 93, label: "TIMESTAMP"},
+    BINARY: {value: "BINARY", code: -2, label: "BINARY"}
+};
+
+javaTypes = {
+    INTEGER: {value: "java.lang.Integer", label: "Integer"},
+    LONG: {value: "java.lang.Long", label: "Long"},
+    BIGDECIMAL: {value: "java.math.BigDecimal", label: "BigDecimal"},
+    FLOAT: {value: "java.lang.Float", label: "Float"},
+    DOUBLE: {value: "java.lang.Double", label: "Double"},
+    STRING: {value: "java.lang.String", label: "String"},
+    BOOLEAN: {value: "java.lang.Boolean", label: "Boolean"},
+    BYTE_ARRAY: {value: "byte[]", label: "byte[]"},
+    DATE: {value: "java.sql.Date", label: "Date"},
+    TIME: {value: "java.sql.Time", label: "Time"},
+    TIMESTAMP: {value: "java.sql.Timestamp", label: "Timestamp"}
+};
+
+if (typeof window === 'undefined') {
+    exports.eventGroups = eventGroups;
+    exports.jdbcTypes = jdbcTypes;
+    exports.javaTypes = javaTypes;
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/control-center-web/src/main/js/package.json
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/package.json b/modules/control-center-web/src/main/js/package.json
new file mode 100644
index 0000000..fd82196
--- /dev/null
+++ b/modules/control-center-web/src/main/js/package.json
@@ -0,0 +1,49 @@
+{
+  "name": "ignite-web-control-center",
+  "version": "1.0.0",
+  "description": "Web application for configuration, monitoring Ignite Cluster",
+  "private": true,
+  "scripts": {
+    "start": "node ./bin/www"
+  },
+  "author": "",
+  "contributors": [
+    {
+      "name": "",
+      "email": ""
+    }
+  ],
+  "license": "Apache-2.0",
+  "keywords": "grid",
+  "homepage": "https://ignite.incubator.apache.org/",
+  "engines": {
+    "node": ">=0.12.4"
+  },
+  "dependencies": {
+    "angular-ui-ace": "^0.2.3",
+    "archiver": "^0.14.4",
+    "body-parser": "~1.12.0",
+    "connect-flash": "^0.1.1",
+    "connect-mongo": "^0.8.1",
+    "cookie-parser": "~1.3.4",
+    "debug": "~2.1.1",
+    "express": "~4.12.2",
+    "express-session": "^1.11.1",
+    "jade": "~1.9.2",
+    "lodash": "3.10.0",
+    "mongoose": "^4.0.2",
+    "mongoose-deep-populate": "1.1.0",
+    "nconf": "^0.7.1",
+    "node-sass-middleware": "^0.9.0",
+    "passport": "^0.2.1",
+    "passport-local": "^1.0.0",
+    "passport-local-mongoose": "^1.0.0",
+    "serve-favicon": "~2.2.0"
+  },
+  "devDependencies": {
+    "morgan": "~1.5.1",
+    "supertest": "^1.0.1",
+    "mocha": "~2.0.1",
+    "should": "~3.1.3"
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/control-center-web/src/main/js/public/favicon.ico
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/public/favicon.ico b/modules/control-center-web/src/main/js/public/favicon.ico
new file mode 100644
index 0000000..74ec626
Binary files /dev/null and b/modules/control-center-web/src/main/js/public/favicon.ico differ

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/control-center-web/src/main/js/public/images/docker.png
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/public/images/docker.png b/modules/control-center-web/src/main/js/public/images/docker.png
new file mode 100644
index 0000000..7ec3aef
Binary files /dev/null and b/modules/control-center-web/src/main/js/public/images/docker.png differ

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/control-center-web/src/main/js/public/images/java.png
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/public/images/java.png b/modules/control-center-web/src/main/js/public/images/java.png
new file mode 100644
index 0000000..ddb3b8e
Binary files /dev/null and b/modules/control-center-web/src/main/js/public/images/java.png differ

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/control-center-web/src/main/js/public/images/logo.png
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/public/images/logo.png b/modules/control-center-web/src/main/js/public/images/logo.png
new file mode 100644
index 0000000..c3577c5
Binary files /dev/null and b/modules/control-center-web/src/main/js/public/images/logo.png differ

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/control-center-web/src/main/js/public/images/xml.png
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/public/images/xml.png b/modules/control-center-web/src/main/js/public/images/xml.png
new file mode 100644
index 0000000..029065e
Binary files /dev/null and b/modules/control-center-web/src/main/js/public/images/xml.png differ