You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by ak...@apache.org on 2015/07/02 10:27:03 UTC
[8/9] incubator-ignite git commit: # ignite-843 Cleanup module.
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/8e792605/modules/web-control-center/nodejs/public/form-models/clusters.json
----------------------------------------------------------------------
diff --git a/modules/web-control-center/nodejs/public/form-models/clusters.json b/modules/web-control-center/nodejs/public/form-models/clusters.json
new file mode 100644
index 0000000..3258cc8
--- /dev/null
+++ b/modules/web-control-center/nodejs/public/form-models/clusters.json
@@ -0,0 +1,849 @@
+{
+ "templateTip": [
+ "Use following template for add cluster:",
+ "<ul>",
+ " <li>blank - Empty configuration.</li>",
+ " <li>local - Configuration with static ips discovery and pre-configured list of IP addresses.</li>",
+ " <li>multicast - Configuration with multicast discovery.</li>",
+ "</ul>"
+ ],
+ "general": [
+ {
+ "label": "Name",
+ "type": "text",
+ "model": "name",
+ "required": true,
+ "placeholder": "Input name"
+ },
+ {
+ "label": "Caches",
+ "type": "dropdown-multiple",
+ "model": "caches",
+ "placeholder": "Choose caches",
+ "items": "caches",
+ "tip": [
+ "Select caches to start in cluster."
+ ],
+ "addLink": {
+ "label": "Add cache(s)",
+ "ref": "/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": [
+ {
+ "tableLabel": "Addresses",
+ "label": "address",
+ "type": "table-simple",
+ "path": "discovery.Vm",
+ "model": "addresses",
+ "editIdx": -1,
+ "reordering": true,
+ "placeholder": "IP address:port",
+ "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",
+ "path": "discovery.S3",
+ "model": "bucketName",
+ "placeholder": ""
+ }
+ ]
+ },
+ "Cloud": {
+ "expanded": true,
+ "fields": [
+ {
+ "label": "Credential",
+ "type": "text",
+ "path": "discovery.Cloud",
+ "model": "credential",
+ "placeholder": "",
+ "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",
+ "placeholder": "",
+ "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",
+ "path": "discovery.Cloud",
+ "model": "identity",
+ "placeholder": "",
+ "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",
+ "model": "discovery.Cloud.provider",
+ "placeholder": "",
+ "tip": [
+ "Cloud provider to use."
+ ]
+ }
+ ]
+ },
+ "GoogleStorage": {
+ "expanded": true,
+ "fields": [
+ {
+ "label": "Project name",
+ "type": "text",
+ "path": "discovery.GoogleStorage",
+ "model": "projectName",
+ "placeholder": "",
+ "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",
+ "path": "discovery.GoogleStorage",
+ "model": "bucketName",
+ "placeholder": "",
+ "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",
+ "path": "discovery.GoogleStorage",
+ "model": "serviceAccountP12FilePath",
+ "placeholder": "",
+ "tip": [
+ "Full path to the private key in PKCS12 format of the Service Account."
+ ]
+ },
+ {
+ "label": "Account id",
+ "type": "text",
+ "path": "discovery.GoogleStorage",
+ "model": "accountId",
+ "placeholder": "",
+ "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": "Atomic 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": "1,000",
+ "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": "5,000",
+ "tip": [
+ "Maximum timeout in milliseconds for network requests."
+ ]
+ },
+ {
+ "label": "Send retry delay",
+ "type": "number",
+ "model": "networkSendRetryDelay",
+ "placeholder": "1,000",
+ "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": "10,000",
+ "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": "600,000",
+ "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": "10,000",
+ "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": "10,000",
+ "min": 1,
+ "tip": [
+ "Number of metrics kept in history to compute totals and averages."
+ ]
+ },
+ {
+ "label": "Log frequency",
+ "type": "number",
+ "model": "metricsLogFrequency",
+ "placeholder": "60,000",
+ "tip": [
+ "Frequency of metrics log print out. To disable set to 0"
+ ]
+ },
+ {
+ "label": "Update frequency",
+ "type": "number",
+ "model": "metricsUpdateFrequency",
+ "placeholder": "60,000",
+ "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": "120,000",
+ "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": "Cache 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": "10,000",
+ "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": "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."
+ ]
+ }
+ ]
+ },
+ {
+ "label": "Utility",
+ "tip": ["Settings for utility messages processing."],
+ "fields": [
+ {
+ "label": "Keep alive time",
+ "type": "number",
+ "model": "utilityCacheKeepAliveTime",
+ "placeholder": "10,000",
+ "tip": [
+ "Keep alive time of thread pool that is in charge of processing utility cache messages."
+ ]
+ },
+ {
+ "label": "Pool size",
+ "type": "number",
+ "model": "utilityCachePoolSize",
+ "placeholder": "max(8, availableProcessors) * 2",
+ "tip": [
+ "Thread pool that is in charge of processing utility cache messages."
+ ]
+ }
+ ]
+ }
+ ]
+}
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/8e792605/modules/web-control-center/nodejs/public/form-models/persistence.json
----------------------------------------------------------------------
diff --git a/modules/web-control-center/nodejs/public/form-models/persistence.json b/modules/web-control-center/nodejs/public/form-models/persistence.json
new file mode 100644
index 0000000..edf5344
--- /dev/null
+++ b/modules/web-control-center/nodejs/public/form-models/persistence.json
@@ -0,0 +1,66 @@
+{
+ "connection": [
+ {
+ "label": "Name",
+ "type": "text",
+ "model": "name",
+ "required": true
+ },
+ {
+ "label": "Database type",
+ "type": "dropdown",
+ "model": "dbType",
+ "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,
+ "placeholder": "",
+ "tip": [
+ "Port number for connecting to database."
+ ]
+ },
+ {
+ "label": "User",
+ "type": "text",
+ "model": "user",
+ "placeholder": "",
+ "tip": [
+ "User name for connecting to database."
+ ]
+ },
+ {
+ "label": "Password",
+ "type": "password",
+ "model": "password",
+ "placeholder": "",
+ "tip": [
+ "Password for connecting to database.",
+ "Note, password would not be saved."
+ ]
+ }
+ ]
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/8e792605/modules/web-control-center/nodejs/public/images/docker.png
----------------------------------------------------------------------
diff --git a/modules/web-control-center/nodejs/public/images/docker.png b/modules/web-control-center/nodejs/public/images/docker.png
new file mode 100644
index 0000000..7ec3aef
Binary files /dev/null and b/modules/web-control-center/nodejs/public/images/docker.png differ
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/8e792605/modules/web-control-center/nodejs/public/images/java.png
----------------------------------------------------------------------
diff --git a/modules/web-control-center/nodejs/public/images/java.png b/modules/web-control-center/nodejs/public/images/java.png
new file mode 100644
index 0000000..ddb3b8e
Binary files /dev/null and b/modules/web-control-center/nodejs/public/images/java.png differ
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/8e792605/modules/web-control-center/nodejs/public/images/logo.png
----------------------------------------------------------------------
diff --git a/modules/web-control-center/nodejs/public/images/logo.png b/modules/web-control-center/nodejs/public/images/logo.png
new file mode 100644
index 0000000..c3577c5
Binary files /dev/null and b/modules/web-control-center/nodejs/public/images/logo.png differ
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/8e792605/modules/web-control-center/nodejs/public/images/xml.png
----------------------------------------------------------------------
diff --git a/modules/web-control-center/nodejs/public/images/xml.png b/modules/web-control-center/nodejs/public/images/xml.png
new file mode 100644
index 0000000..029065e
Binary files /dev/null and b/modules/web-control-center/nodejs/public/images/xml.png differ
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/8e792605/modules/web-control-center/nodejs/public/javascripts/bundle.js
----------------------------------------------------------------------
diff --git a/modules/web-control-center/nodejs/public/javascripts/bundle.js b/modules/web-control-center/nodejs/public/javascripts/bundle.js
new file mode 100644
index 0000000..840da56
--- /dev/null
+++ b/modules/web-control-center/nodejs/public/javascripts/bundle.js
@@ -0,0 +1,18 @@
+/*
+ * 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.
+ */
+
+// Place here all common utility functions that will be available on each page.
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/8e792605/modules/web-control-center/nodejs/public/javascripts/controllers/caches.js
----------------------------------------------------------------------
diff --git a/modules/web-control-center/nodejs/public/javascripts/controllers/caches.js b/modules/web-control-center/nodejs/public/javascripts/controllers/caches.js
new file mode 100644
index 0000000..006f065
--- /dev/null
+++ b/modules/web-control-center/nodejs/public/javascripts/controllers/caches.js
@@ -0,0 +1,237 @@
+/*
+ * 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.
+ */
+
+configuratorModule.controller('cachesController', ['$scope', '$alert', '$http', 'commonFunctions', function ($scope, $alert, $http, commonFunctions) {
+ $scope.swapSimpleItems = commonFunctions.swapSimpleItems;
+ $scope.joinTip = commonFunctions.joinTip;
+ $scope.getModel = commonFunctions.getModel;
+
+ $scope.atomicities = [
+ {value: 'ATOMIC', label: 'ATOMIC'},
+ {value: 'TRANSACTIONAL', label: 'TRANSACTIONAL'}
+ ];
+
+ $scope.modes = [
+ {value: 'PARTITIONED', label: 'PARTITIONED'},
+ {value: 'REPLICATED', label: 'REPLICATED'},
+ {value: 'LOCAL', label: 'LOCAL'}
+ ];
+
+ $scope.atomicWriteOrderModes = [
+ {value: 'CLOCK', label: 'CLOCK'},
+ {value: 'PRIMARY', label: 'PRIMARY'}
+ ];
+
+ $scope.memoryModes = [
+ {value: 'ONHEAP_TIERED', label: 'ONHEAP_TIERED'},
+ {value: 'OFFHEAP_TIERED', label: 'OFFHEAP_TIERED'},
+ {value: 'OFFHEAP_VALUES', label: 'OFFHEAP_VALUES'}
+ ];
+
+ $scope.evictionPolicies = [
+ {value: 'LRU', label: 'Least Recently Used'},
+ {value: 'RND', label: 'Random'},
+ {value: 'FIFO', label: 'FIFO'},
+ {value: 'SORTED', label: 'Sorted'},
+ {value: undefined, label: 'Not set'}
+ ];
+
+ $scope.rebalanceModes = [
+ {value: 'SYNC', label: 'SYNC'},
+ {value: 'ASYNC', label: 'ASYNC'},
+ {value: 'NONE', label: 'NONE'}
+ ];
+
+ $scope.cacheStoreFactories = [
+ {value: 'CacheJdbcPojoStoreFactory', label: 'JDBC POJO store factory'},
+ {value: 'CacheJdbcBlobStoreFactory', label: 'JDBC BLOB store factory'},
+ {value: 'CacheHibernateBlobStoreFactory', label: 'Hibernate BLOB store factory'},
+ {value: undefined, label: 'Not set'}
+ ];
+
+ $scope.cacheStoreJdbcDialects = [
+ {value: 'BasicJdbcDialect', label: 'Generic JDBC dialect'},
+ {value: 'OracleDialect', label: 'Oracle'},
+ {value: 'DB2Dialect', label: 'IBM DB2'},
+ {value: 'SQLServerDialect', label: 'Microsoft SQL Server'},
+ {value: 'MySQLDialect', label: 'My SQL'},
+ {value: 'H2Dialect', label: 'H2 database'}
+ ];
+
+ $scope.general = [];
+ $scope.advanced = [];
+
+ $http.get('/form-models/caches.json')
+ .success(function (data) {
+ $scope.general = data.general;
+ $scope.advanced = data.advanced;
+ });
+
+ $scope.caches = [];
+
+ // When landing on the page, get caches and show them.
+ $http.get('/rest/caches')
+ .success(function (data) {
+ $scope.spaces = data.spaces;
+ $scope.caches = data.caches;
+
+ var restoredItem = angular.fromJson(sessionStorage.cacheBackupItem);
+
+ if (restoredItem) {
+ var idx = _.findIndex($scope.caches, function (cache) {
+ return cache._id == restoredItem._id;
+ });
+
+ if (idx >= 0)
+ $scope.selectedItem = $scope.caches[idx];
+
+ $scope.backupItem = restoredItem;
+ }
+
+ $scope.$watch('backupItem', function (val) {
+ if (val)
+ sessionStorage.cacheBackupItem = angular.toJson(val);
+ }, true);
+ });
+
+ $scope.selectItem = function (item) {
+ $scope.selectedItem = item;
+
+ $scope.backupItem = angular.copy(item);
+ };
+
+ // Add new cache.
+ $scope.createItem = function () {
+ $scope.backupItem = {mode: 'PARTITIONED', atomicityMode: 'ATOMIC'};
+ $scope.backupItem.space = $scope.spaces[0]._id;
+ };
+
+ // Save cache in db.
+ $scope.saveItem = function () {
+ var item = $scope.backupItem;
+
+ console.log(item);
+
+ if (item.cacheStoreFactory && !item.readThrough && !item.writeThrough) {
+ $alert({position: 'top', title: 'Store is configured but read/write through are not enabled!'});
+
+ return;
+ }
+
+ if ((item.readThrough || item.writeThrough) && (!item.cacheStoreFactory || !item.cacheStoreFactory.kind)) {
+ $alert({position: 'top', title: 'Read / write through are enabled but strore is not configured!'});
+
+ return;
+ }
+
+ $http.post('/rest/caches/save', item)
+ .success(function (_id) {
+ var idx = _.findIndex($scope.caches, function (cache) {
+ return cache._id == _id;
+ });
+
+ if (idx >= 0)
+ angular.extend($scope.caches[idx], item);
+ else {
+ item._id = _id;
+
+ $scope.caches.push(item);
+ }
+
+ $scope.selectItem(item);
+
+ $alert({
+ type: 'success',
+ title: 'Cache "' + item.name + '" saved.',
+ duration: 2,
+ container: '#save-btn'
+ });
+ })
+ .error(function (errorMessage) {
+ $alert({title: errorMessage});
+ });
+ };
+
+ $scope.removeItem = function () {
+ var _id = $scope.selectedItem._id;
+
+ $http.post('/rest/caches/remove', {_id: _id})
+ .success(function () {
+ var i = _.findIndex($scope.caches, function (cache) {
+ return cache._id == _id;
+ });
+
+ if (i >= 0) {
+ $scope.caches.splice(i, 1);
+
+ $scope.selectedItem = undefined;
+ $scope.backupItem = undefined;
+ }
+ })
+ .error(function (errorMessage) {
+ $alert({title: errorMessage});
+ });
+ };
+
+ $scope.addIndexedTypes = function (keyCls, valCls) {
+ var idxTypes = $scope.backupItem.indexedTypes;
+
+ var newItem = {keyClass: keyCls, valueClass: valCls};
+
+ if (idxTypes)
+ idxTypes.push(newItem);
+ else
+ $scope.backupItem.indexedTypes = [newItem];
+ };
+
+ $scope.editIndexedTypes = function (idx) {
+ $scope.indexedTypeIdx = idx;
+
+ if (idx < 0) {
+ $scope.currKeyCls = '';
+ $scope.currValCls = '';
+ }
+ else {
+ var idxType = $scope.backupItem.indexedTypes[idx];
+
+ $scope.currKeyCls = idxType.keyClass;
+ $scope.currValCls = idxType.valueClass;
+ }
+ };
+
+ $scope.saveIndexedType = function (k, v) {
+ var idxTypes = $scope.backupItem.indexedTypes;
+
+ var idx = $scope.indexedTypeIdx;
+
+ if (idx < 0) {
+ var newItem = {keyClass: k, valueClass: v};
+
+ if (idxTypes)
+ idxTypes.push(newItem);
+ else
+ $scope.backupItem.indexedTypes = [newItem];
+ }
+ else {
+ var idxType = idxTypes[idx];
+
+ idxType.keyClass = k;
+ idxType.valueClass = v;
+ }
+ };
+ }]
+);
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/8e792605/modules/web-control-center/nodejs/public/javascripts/controllers/clusters.js
----------------------------------------------------------------------
diff --git a/modules/web-control-center/nodejs/public/javascripts/controllers/clusters.js b/modules/web-control-center/nodejs/public/javascripts/controllers/clusters.js
new file mode 100644
index 0000000..ce38381
--- /dev/null
+++ b/modules/web-control-center/nodejs/public/javascripts/controllers/clusters.js
@@ -0,0 +1,207 @@
+/*
+ * 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.
+ */
+
+configuratorModule.controller('clustersController', ['$scope', '$alert', '$http', 'commonFunctions', function ($scope, $alert, $http, commonFunctions) {
+ $scope.swapSimpleItems = commonFunctions.swapSimpleItems;
+ $scope.joinTip = commonFunctions.joinTip;
+ $scope.getModel = commonFunctions.getModel;
+
+ $scope.templates = [
+ {value: {}, label: 'blank'},
+ {value: {discovery: {kind: 'Vm', Vm: {addresses: ['127.0.0.1:47500..47510']}}}, label: 'local'},
+ {value: {discovery: {kind: 'Multicast', Multicast: {}}}, label: 'multicast'}
+ ];
+
+ $scope.discoveries = [
+ {value: 'Vm', label: 'static IPs'},
+ {value: 'Multicast', label: 'multicast'},
+ {value: 'S3', label: 'AWS S3'},
+ {value: 'Cloud', label: 'apache jclouds'},
+ {value: 'GoogleStorage', label: 'google cloud storage'},
+ {value: 'Jdbc', label: 'JDBC'},
+ {value: 'SharedFs', label: 'shared filesystem'}
+ ];
+
+ $scope.swapSpaceSpis = [
+ {value: 'FileSwapSpaceSpi', label: 'File-based swap'},
+ {value: undefined, label: 'Not set'}
+ ];
+
+ $scope.events = [];
+
+ for (var eventGroupName in eventGroups) {
+ if (eventGroups.hasOwnProperty(eventGroupName)) {
+ $scope.events.push({value: eventGroupName, label: eventGroupName});
+ }
+ }
+
+ $scope.cacheModes = [
+ {value: 'LOCAL', label: 'LOCAL'},
+ {value: 'REPLICATED', label: 'REPLICATED'},
+ {value: 'PARTITIONED', label: 'PARTITIONED'}
+ ];
+
+ $scope.deploymentModes = [
+ {value: 'PRIVATE', label: 'PRIVATE'},
+ {value: 'ISOLATED', label: 'ISOLATED'},
+ {value: 'SHARED', label: 'SHARED'},
+ {value: 'CONTINUOUS', label: 'CONTINUOUS'}
+ ];
+
+ $scope.transactionConcurrency = [
+ {value: 'OPTIMISTIC', label: 'OPTIMISTIC'},
+ {value: 'PESSIMISTIC', label: 'PESSIMISTIC'}
+ ];
+
+ $scope.transactionIsolation = [
+ {value: 'READ_COMMITTED', label: 'READ_COMMITTED'},
+ {value: 'REPEATABLE_READ', label: 'REPEATABLE_READ'},
+ {value: 'SERIALIZABLE', label: 'SERIALIZABLE'}
+ ];
+
+ $scope.segmentationPolicy = [
+ {value: 'RESTART_JVM', label: 'RESTART_JVM'},
+ {value: 'STOP', label: 'STOP'},
+ {value: 'NOOP', label: 'NOOP'}
+ ];
+
+ $scope.marshallers = [
+ {value: 'JdkMarshaller', label: 'JdkMarshaller'},
+ {value: 'OptimizedMarshaller', label: 'OptimizedMarshaller'}
+ ];
+
+ $scope.clusters = [];
+
+ $http.get('/form-models/clusters.json')
+ .success(function (data) {
+ $scope.templateTip = data.templateTip;
+
+ $scope.general = data.general;
+ $scope.advanced = data.advanced;
+ });
+
+ // When landing on the page, get clusters and show them.
+ $http.get('/rest/clusters')
+ .success(function (data) {
+ $scope.caches = data.caches;
+ $scope.spaces = data.spaces;
+ $scope.clusters = data.clusters;
+
+ var restoredItem = angular.fromJson(sessionStorage.clusterBackupItem);
+
+ if (restoredItem) {
+ var idx = _.findIndex($scope.clusters, function (cluster) {
+ return cluster._id == restoredItem._id;
+ });
+
+ if (idx >= 0)
+ $scope.selectedItem = $scope.clusters[idx];
+
+ $scope.backupItem = restoredItem;
+ }
+
+ $scope.$watch('backupItem', function (val) {
+ if (val)
+ sessionStorage.clusterBackupItem = angular.toJson(val);
+ }, true);
+ });
+
+ $scope.selectItem = function (item) {
+ $scope.selectedItem = item;
+
+ $scope.backupItem = angular.copy(item);
+ };
+
+ // Add new cluster.
+ $scope.createItem = function () {
+ $scope.backupItem = angular.copy($scope.create.template);
+
+ $scope.backupItem.space = $scope.spaces[0]._id;
+ };
+
+ // Save cluster in db.
+ $scope.saveItem = function () {
+ var item = $scope.backupItem;
+
+ if (!item.swapSpaceSpi || !item.swapSpaceSpi.kind) {
+ for (var cacheId in item.caches) {
+ var idx = _.findIndex($scope.caches, function (cache) {
+ return cache._id == cacheId.value;
+ });
+
+ if (idx >= 0) {
+ var cache = $scope.caches[idx];
+
+ if (cache.swapEnabled) {
+ $alert({title: 'Swap space SPI is not configured, but cache "' + cache.label + '" configured to use swap!'});
+
+ return;
+ }
+ }
+ }
+ }
+
+ $http.post('/rest/clusters/save', item)
+ .success(function (_id) {
+ var idx = _.findIndex($scope.clusters, function (cluster) {
+ return cluster._id == _id;
+ });
+
+ if (idx >= 0)
+ angular.extend($scope.clusters[idx], item);
+ else {
+ item._id = _id;
+
+ $scope.clusters.push(item);
+ }
+
+ $scope.selectItem(item);
+
+ $alert({
+ type: 'success',
+ title: 'Cluster "' + item.name + '" saved.',
+ duration: 2,
+ container: '#save-btn'
+ });
+ })
+ .error(function (errorMessage) {
+ $alert({title: errorMessage});
+ });
+ };
+
+ $scope.removeItem = function () {
+ var _id = $scope.selectedItem._id;
+
+ $http.post('/rest/clusters/remove', {_id: _id})
+ .success(function () {
+ var i = _.findIndex($scope.clusters, function (cluster) {
+ return cluster._id == _id;
+ });
+
+ if (i >= 0) {
+ $scope.clusters.splice(i, 1);
+
+ $scope.selectedItem = undefined;
+ $scope.backupItem = undefined;
+ }
+ })
+ .error(function (errorMessage) {
+ $alert({title: errorMessage});
+ });
+ };
+ }]
+);
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/8e792605/modules/web-control-center/nodejs/public/javascripts/controllers/common.js
----------------------------------------------------------------------
diff --git a/modules/web-control-center/nodejs/public/javascripts/controllers/common.js b/modules/web-control-center/nodejs/public/javascripts/controllers/common.js
new file mode 100644
index 0000000..4d1e411
--- /dev/null
+++ b/modules/web-control-center/nodejs/public/javascripts/controllers/common.js
@@ -0,0 +1,169 @@
+/*
+ * 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 configuratorModule = angular.module('ignite-web-configurator', ['smart-table', 'mgcrea.ngStrap', 'ngSanitize']);
+
+configuratorModule.service('commonFunctions', function () {
+ return {
+ getModel: function(obj, path) {
+ if (!path)
+ return obj;
+
+ path = path.replace(/\[(\w+)\]/g, '.$1'); // convert indexes to properties
+ path = path.replace(/^\./, ''); // strip a leading dot
+
+ var segs = path.split('.');
+ var root = obj;
+
+ while (segs.length > 0) {
+ var pathStep = segs.shift();
+
+ if (typeof root[pathStep] === 'undefined')
+ root[pathStep] = {};
+
+ root = root[pathStep];
+ }
+
+ return root;
+ },
+ swapSimpleItems: function (a, ix1, ix2) {
+ var tmp = a[ix1];
+
+ a[ix1] = a[ix2];
+ a[ix2] = tmp;
+ },
+ joinTip: function(arr) {
+ if (!arr) {
+ return arr;
+ }
+
+ var lines = arr.map(function (line) {
+ var rtrimmed = line.replace(/\s+$/g, '');
+
+ if (rtrimmed.indexOf('>', this.length - 1) == -1) {
+ rtrimmed = rtrimmed + '<br/>';
+ }
+
+ return rtrimmed;
+ });
+
+ return lines.join("");
+ }
+ }
+});
+
+configuratorModule.config(function ($tooltipProvider) {
+ angular.extend($tooltipProvider.defaults, {
+ container: 'body',
+ placement: 'right',
+ html: 'true',
+ trigger: 'click hover'
+ //,delay: { hide: 600 }
+ });
+});
+
+configuratorModule.config(function ($selectProvider) {
+ angular.extend($selectProvider.defaults, {
+ maxLength: '1',
+ allText: 'Select All',
+ noneText: 'Clear All',
+ template: '/select'
+ });
+});
+
+// Alert settings
+configuratorModule.config(function ($alertProvider) {
+ angular.extend($alertProvider.defaults, {
+ container: 'body',
+ placement: 'top-right',
+ duration: '5',
+ type: 'danger'
+ });
+});
+
+// Decode name using map(value, label).
+configuratorModule.filter('displayValue', function () {
+ return function (v, m, dflt) {
+ var i = _.findIndex(m, function (item) {
+ return item.value == v;
+ });
+
+ if (i >= 0) {
+ return m[i].label;
+ }
+
+ if (dflt) {
+ return dflt;
+ }
+
+ return 'Unknown value';
+ }
+});
+
+/**
+ * Replaces all occurrences of {@code org.apache.ignite.} with {@code o.a.i.},
+ * {@code org.apache.ignite.internal.} with {@code o.a.i.i.},
+ * {@code org.apache.ignite.internal.visor.} with {@code o.a.i.i.v.} and
+ * {@code org.apache.ignite.scalar.} with {@code o.a.i.s.}.
+ *
+ * @param s String to replace in.
+ * @return Replaces string.
+ */
+configuratorModule.filter('compact', function () {
+ return function (s) {
+ return s.replace("org.apache.ignite.internal.visor.", "o.a.i.i.v.").
+ replace("org.apache.ignite.internal.", "o.a.i.i.").
+ replace("org.apache.ignite.scalar.", "o.a.i.s.").
+ replace("org.apache.ignite.", "o.a.i.");
+ }
+});
+
+configuratorModule.controller('activeLink', ['$scope', function ($scope) {
+ $scope.isActive = function (path) {
+ return window.location.pathname.substr(0, path.length) == path;
+ };
+}]);
+
+configuratorModule.controller('auth', ['$scope', '$modal', '$alert', '$http', '$window', function ($scope, $modal, $alert, $http, $window) {
+ $scope.action = 'login';
+
+ $scope.errorMessage = '';
+
+ $scope.valid = false;
+
+ // Pre-fetch an external template populated with a custom scope
+ var authModal = $modal({scope: $scope, template: '/login', show: false});
+
+ $scope.login = function () {
+ // Show when some event occurs (use $promise property to ensure the template has been loaded)
+ authModal.$promise.then(authModal.show);
+ };
+
+ $scope.auth = function (action, user_info) {
+ $http.post('/rest/auth/' + action, user_info)
+ .success(function (data) {
+ authModal.hide();
+
+ $window.location = '/clusters';
+ })
+ .error(function (data) {
+ console.log(data);
+
+ $alert({placement: 'top', container: '#errors-container', title: data});
+ });
+ };
+}]);
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/8e792605/modules/web-control-center/nodejs/public/javascripts/controllers/persistences.js
----------------------------------------------------------------------
diff --git a/modules/web-control-center/nodejs/public/javascripts/controllers/persistences.js b/modules/web-control-center/nodejs/public/javascripts/controllers/persistences.js
new file mode 100644
index 0000000..10e3f8f
--- /dev/null
+++ b/modules/web-control-center/nodejs/public/javascripts/controllers/persistences.js
@@ -0,0 +1,202 @@
+/*
+ * 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.
+ */
+
+configuratorModule.controller('persistenceController', ['$scope', '$alert', '$http', 'commonFunctions', function ($scope, $alert, $http, commonFunctions) {
+ $scope.joinTip = commonFunctions.joinTip;
+ $scope.getModel = commonFunctions.getModel;
+
+ $scope.databases = [
+ {value: 'oracle', label: 'Oracle database'},
+ {value: 'db2', label: 'IBM DB2'},
+ {value: 'mssql', label: 'MS SQL Server'},
+ {value: 'postgre', label: 'PostgreSQL'},
+ {value: 'mysql', label: 'MySQL'},
+ {value: 'h2', label: 'H2 database'}
+ ];
+
+ $scope.connection = [];
+
+ $http.get('/form-models/persistence.json')
+ .success(function (data) {
+ $scope.connection = data.connection;
+ });
+
+ $scope.persistences = [];
+
+ // When landing on the page, get persistences and show them.
+ $http.get('/rest/persistences')
+ .success(function (data) {
+ $scope.spaces = data.spaces;
+ $scope.persistences = data.persistences;
+
+ var restoredItem = angular.fromJson(sessionStorage.persistenceBackupItem);
+
+ if (restoredItem) {
+ var idx = _.findIndex($scope.persistences, function (persistence) {
+ return persistence._id == restoredItem._id;
+ });
+
+ if (idx >= 0)
+ $scope.selectedItem = $scope.persistences[idx];
+
+ $scope.backupItem = restoredItem;
+ }
+
+ $scope.$watch('backupItem', function (val) {
+ if (val)
+ sessionStorage.persistenceBackupItem = angular.toJson(val);
+ }, true);
+ });
+
+ $scope.selectItem = function (item) {
+ $scope.selectedItem = item;
+ $scope.backupItem = angular.copy(item);
+ };
+
+ // Add new persistence.
+ $scope.createItem = function () {
+ $scope.backupItem = {database: 'oracle'};
+ $scope.backupItem.space = $scope.spaces[0]._id;
+ };
+
+ // Save persistence in db.
+ $scope.saveItem = function () {
+ var item = $scope.backupItem;
+
+ $http.post('/rest/persistences/save', item)
+ .success(function (_id) {
+ var i = _.findIndex($scope.persistences, function (persistence) {
+ return persistence._id == _id;
+ });
+
+ if (i >= 0)
+ angular.extend($scope.persistences[i], item);
+ else {
+ item._id = _id;
+
+ $scope.persistences.push(item);
+ }
+
+ $scope.selectItem(item);
+ })
+ .error(function (errorMessage) {
+ $alert({title: errorMessage});
+ });
+ };
+
+ $scope.removeItem = function () {
+ var _id = $scope.selectedItem._id;
+
+ $http.post('/rest/persistences/remove', {_id: _id})
+ .success(function () {
+ var i = _.findIndex($scope.persistences, function (persistence) {
+ return persistence._id == _id;
+ });
+
+ if (i >= 0) {
+ $scope.persistences.splice(i, 1);
+
+ $scope.selectedItem = undefined;
+ $scope.backupItem = undefined;
+ }
+ })
+ .error(function (errorMessage) {
+ $alert({title: errorMessage});
+ });
+ };
+
+ $scope.data = {
+ curTableIdx: -1,
+ curFieldIdx: -1,
+ curKeyClass: '',
+ curValueClass: '',
+ curJavaName: '',
+ curJavaType: '',
+ tables: [
+ {schemaName: 'Schema1', use: true},
+ {schemaName: 'Schema1', use: true, tableName: 'Table1', keyClass: 'KeyClass1', valueClass: 'ValueClass1',
+ fields: [
+ {use: true, key: true, ak: true, dbName: 'name1', dbType: 'dbType1', javaName: 'javaName1', javaType: 'javaType1'},
+ {use: true, key: false, ak: false, dbName: 'name2', dbType: 'dbType2', javaName: 'javaName2', javaType: 'javaType2'},
+ {use: false, key: false, ak: false, dbName: 'name3', dbType: 'dbType3', javaName: 'javaName3', javaType: 'javaType3'}
+ ]
+ },
+ {schemaName: 'Schema2 with very long name', use: false},
+ {schemaName: 'Schema2', use: false, tableName: 'Table2', keyClass: 'KeyClass2', valueClass: 'ValueClass2',
+ fields: [
+ {use: true, key: true, ak: true, dbName: 'name4', dbType: 'dbType4', javaName: 'javaName4', javaType: 'javaType4'},
+ {use: true, key: false, ak: false, dbName: 'name5', dbType: 'dbType5', javaName: 'javaName5', javaType: 'javaType5'},
+ {use: false, key: false, ak: false, dbName: 'name6', dbType: 'dbType6', javaName: 'javaName6', javaType: 'javaType6'}
+ ]},
+ {schemaName: 'Schema2', use: false, tableName: 'Table3', keyClass: 'KeyClass3', valueClass: 'ValueClass3',
+ fields: [
+ {use: true, key: true, ak: true, dbName: 'name7', dbType: 'dbType7', javaName: 'javaName7', javaType: 'javaType7'},
+ {use: true, key: false, ak: false, dbName: 'name8', dbType: 'dbType8', javaName: 'javaName8', javaType: 'javaType8'},
+ {use: false, key: false, ak: false, dbName: 'name9', dbType: 'dbType9', javaName: 'javaName9', javaType: 'javaType9'},
+ {use: false, key: false, ak: false, dbName: 'name10', dbType: 'dbType10', javaName: 'javaName10', javaType: 'javaType10'},
+ {use: false, key: false, ak: false, dbName: 'name11', dbType: 'dbType11', javaName: 'javaName11', javaType: 'javaType11'},
+ {use: false, key: false, ak: false, dbName: 'name12', dbType: 'dbType12', javaName: 'javaName12', javaType: 'javaType12'}
+ ]}]
+ };
+
+ $scope.selectSchema = function (idx) {
+ var data = $scope.data;
+ var tables = data.tables;
+ var schemaName = tables[idx].schemaName;
+ var use = tables[idx].use;
+
+ for (var i = idx + 1; i < tables.length; i++) {
+ var item = tables[i];
+
+ if (item.schemaName == schemaName && item.tableName)
+ item.use = use;
+ else
+ break;
+ }
+
+ data.curTableIdx = -1;
+ data.curFieldIdx = -1;
+ };
+
+ $scope.selectTable = function (idx) {
+ var data = $scope.data;
+
+ data.curTableIdx = idx;
+ data.curFieldIdx = -1;
+
+ if (idx >= 0) {
+ var tbl = data.tables[idx];
+
+ data.curKeyClass = tbl.keyClass;
+ data.curValueClass = tbl.valueClass;
+ }
+ };
+
+ $scope.selectField = function (idx) {
+ var data = $scope.data;
+
+ data.curFieldIdx = idx;
+
+ if (idx >= 0) {
+ var fld = data.tables[data.curTableIdx].fields[idx];
+
+ data.curJavaName = fld.javaName;
+ data.curJavaType = fld.javaType;
+ }
+ };
+ }]
+);
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/8e792605/modules/web-control-center/nodejs/public/javascripts/controllers/summary.js
----------------------------------------------------------------------
diff --git a/modules/web-control-center/nodejs/public/javascripts/controllers/summary.js b/modules/web-control-center/nodejs/public/javascripts/controllers/summary.js
new file mode 100644
index 0000000..53cac48
--- /dev/null
+++ b/modules/web-control-center/nodejs/public/javascripts/controllers/summary.js
@@ -0,0 +1,137 @@
+/*
+ * 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.
+ */
+
+configuratorModule.controller('summaryController', ['$scope', '$http', function ($scope, $http) {
+ $http.get('/rest/clusters').success(function (data) {
+ $scope.caches = data.caches;
+ $scope.spaces = data.spaces;
+ $scope.clusters = data.clusters;
+ });
+
+ $scope.selectItem = function (item) {
+ $scope.selectedItem = item;
+
+ $scope.generateConfig()
+ };
+
+ $scope.generateConfig = function() {
+ var lang = $scope.cfgLang;
+
+ if (lang == 'docker')
+ return;
+
+ var cluster = $scope.selectedItem;
+
+ if (!cluster)
+ return;
+
+ $scope.loading = true;
+
+ $http.get('/rest/configGenerator', {params:
+ {name: cluster.name, lang: lang, generateJavaClass: $scope.generateJavaClass}})
+ .success(
+ function (data) {
+ if (lang == 'java') {
+ $("<pre class='brush:java' />").text(data).appendTo($('#javaResultDiv').empty());
+ }
+ else if (lang == 'xml') {
+ $("<pre class='brush:xml' />").text(data).appendTo($('#xmlResultDiv').empty());
+ }
+
+ SyntaxHighlighter.highlight();
+
+ $scope.loading = false;
+ }).error(function (data) {
+ $scope.generateError = "Failed to generate config: " + data;
+
+ $scope.loading = false;
+ });
+ };
+
+ $scope.cfgLang = 'xml';
+
+ $scope.$watch('cfgLang', $scope.generateConfig);
+ $scope.$watch('generateJavaClass', $scope.generateConfig);
+
+ $scope.dockerArg = {};
+
+ $scope.downloadDocker = function() {
+ var dockerText = $scope.dockerFile();
+
+ if (dockerText.length == 0)
+ return;
+
+ var pom = document.createElement('a');
+ pom.setAttribute('href', 'data:application/octet-stream;charset=utf-8,' + encodeURIComponent(dockerText));
+ pom.setAttribute('download', 'Dockerfile');
+
+ pom.style.display = 'none';
+ document.body.appendChild(pom);
+
+ pom.click();
+
+ document.body.removeChild(pom);
+ };
+
+ $scope.dockerFile = function() {
+ if (!$scope.selectedItem || !$scope.dockerArg) {
+ return '';
+ }
+
+ var os = $scope.dockerArg.os;
+ if (!os) {
+ os = 'debian:8'
+ }
+
+ return "" +
+ "# Start from a Debian image.\n"+
+ "FROM " + os + "\n"+
+ "\n"+
+ "# Install tools.\n"+
+ "RUN apt-get update && apt-get install -y --fix-missing \\\n"+
+ " wget \\\n"+
+ " dstat \\\n"+
+ " maven \\\n"+
+ " git\n"+
+ "\n"+
+ "# Intasll Oracle JDK.\n"+
+ "RUN mkdir /opt/jdk\n"+
+ "\n"+
+ "RUN wget --header \"Cookie: oraclelicense=accept-securebackup-cookie\" \\\n"+
+ " http://download.oracle.com/otn-pub/java/jdk/7u79-b15/jdk-7u79-linux-x64.tar.gz\n"+
+ "\n"+
+ "RUN tar -zxf jdk-7u79-linux-x64.tar.gz -C /opt/jdk\n"+
+ "\n"+
+ "RUN rm jdk-7u79-linux-x64.tar.gz\n"+
+ "\n"+
+ "RUN update-alternatives --install /usr/bin/java java /opt/jdk/jdk1.7.0_79/bin/java 100\n"+
+ "\n"+
+ "RUN update-alternatives --install /usr/bin/javac javac /opt/jdk/jdk1.7.0_79/bin/javac 100\n"+
+ "\n"+
+ "# Sets java variables.\n"+
+ "ENV JAVA_HOME /opt/jdk/jdk1.7.0_79/\n"+
+ "\n"+
+ "# Create working directory\n"+
+ "WORKDIR /home\n"+
+ "\n"+
+ "RUN wget -O ignite.zip http://tiny.cc/updater/download_ignite.php && unzip ignite.zip && rm ignite.zip\n"+
+ "\n"+
+ "COPY *.xml /tmp/\n"+
+ "\n"+
+ "RUN mv /tmp/*.xml /home/$(ls)/config";
+ };
+}]);
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/8e792605/modules/web-control-center/nodejs/public/javascripts/dataStructures.js
----------------------------------------------------------------------
diff --git a/modules/web-control-center/nodejs/public/javascripts/dataStructures.js b/modules/web-control-center/nodejs/public/javascripts/dataStructures.js
new file mode 100644
index 0000000..2462708
--- /dev/null
+++ b/modules/web-control-center/nodejs/public/javascripts/dataStructures.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;
+}