http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/36063e13/modules/web-control-center/nodejs/controllers/models/clusters.json ---------------------------------------------------------------------- diff --git a/modules/web-control-center/nodejs/controllers/models/clusters.json b/modules/web-control-center/nodejs/controllers/models/clusters.json new file mode 100644 index 0000000..e6be772 --- /dev/null +++ b/modules/web-control-center/nodejs/controllers/models/clusters.json @@ -0,0 +1,891 @@ +{ + "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": [ + { + "type": "table-simple", + "path": "discovery.Vm", + "model": "addresses", + "editIdx": -1, + "reordering": true, + "ipaddress": 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", + "required": true, + "path": "discovery.S3", + "model": "bucketName", + "placeholder": "", + "tip": [ + "Bucket name for IP finder." + ] + } + ] + }, + "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", + "required": true, + "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", + "required": true, + "path": "discovery.Cloud", + "model": "provider", + "placeholder": "", + "tip": [ + "Cloud provider to use." + ] + }, + { + "label": "Regions", + "type": "table-simple", + "path": "discovery.Cloud", + "model": "regions", + "editIdx": -1, + "placeholder": "", + "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, + "placeholder": "", + "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", + "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", + "required": true, + "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", + "required": true, + "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", + "required": true, + "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/36063e13/modules/web-control-center/nodejs/controllers/models/persistence.json ---------------------------------------------------------------------- diff --git a/modules/web-control-center/nodejs/controllers/models/persistence.json b/modules/web-control-center/nodejs/controllers/models/persistence.json new file mode 100644 index 0000000..edf5344 --- /dev/null +++ b/modules/web-control-center/nodejs/controllers/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/36063e13/modules/web-control-center/nodejs/controllers/persistences-controller.js ---------------------------------------------------------------------- diff --git a/modules/web-control-center/nodejs/controllers/persistences-controller.js b/modules/web-control-center/nodejs/controllers/persistences-controller.js new file mode 100644 index 0000000..566c857 --- /dev/null +++ b/modules/web-control-center/nodejs/controllers/persistences-controller.js @@ -0,0 +1,212 @@ +/* + * 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('persistenceController', ['$scope', '$alert', '$http', 'commonFunctions', function ($scope, $alert, $http, commonFunctions) { + $scope.joinTip = commonFunctions.joinTip; + $scope.getModel = commonFunctions.getModel; + $scope.errorMessage = commonFunctions.errorMessage; + + $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('/models/persistence.json') + .success(function (data) { + $scope.connection = data.connection; + }) + .error(function (errMsg) { + $alert({title: $scope.errorMessage(errMsg)}); + }); + + $scope.persistences = []; + + // When landing on the page, get persistences and show them. + $http.post('list') + .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; + } + else + sessionStorage.removeItem('persistenceBackupItem'); + } + + $scope.$watch('backupItem', function (val) { + if (val) + sessionStorage.persistenceBackupItem = angular.toJson(val); + }, true); + }) + .error(function (errMsg) { + $alert({title: $scope.errorMessage(errMsg)}); + }); + + $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('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 (errMsg) { + $alert({title: $scope.errorMessage(errMsg)}); + }); + }; + + $scope.removeItem = function () { + var _id = $scope.selectedItem._id; + + $http.post('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 (errMsg) { + $alert({title: $scope.errorMessage(errMsg)}); + }); + }; + + $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/36063e13/modules/web-control-center/nodejs/controllers/summary-controller.js ---------------------------------------------------------------------- diff --git a/modules/web-control-center/nodejs/controllers/summary-controller.js b/modules/web-control-center/nodejs/controllers/summary-controller.js new file mode 100644 index 0000000..f979dac --- /dev/null +++ b/modules/web-control-center/nodejs/controllers/summary-controller.js @@ -0,0 +1,171 @@ +/* + * 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', function ($scope, $http) { + $scope.generateJavaItems = [ + { label: 'snippet',value: false}, + { label: 'factory class',value: true} + ]; + + $scope.generateJavaClass = false; + + $scope.javaData = undefined; + $scope.xmlData = undefined; + $scope.dockerData = undefined; + + $http.post('/configuration/clusters/list').success(function (data) { + $scope.clusters = data.clusters; + }); + + $scope.selectItem = function (item) { + $scope.selectedItem = item; + + $scope.generate() + }; + + $scope.cfgLang = 'xml'; + + $scope.generate = function() { + var cluster = $scope.selectedItem; + + if (!cluster) + return; + + var lang = $scope.cfgLang; + + $scope.loading = true; + + $http.post('/configuration/summary/generator', {_id: cluster._id, lang: lang, generateJavaClass: $scope.generateJavaClass}) + .success( + function (data) { + switch (lang) { + case 'java': + $scope.javaData = data; + + $("<pre class='brush:java' />").text(data).appendTo($('#javaResultDiv').empty()); + + break; + + case 'xml': + $scope.xmlData = data; + + $("<pre class='brush:xml' />").text(data).appendTo($('#xmlResultDiv').empty()); + + break; + + case 'docker': + $scope.dockerData = data; + + $("<pre class='brush:plain' />").text($scope.dockerFile()).appendTo($('#dockerResultDiv').empty()); + + break; + } + + SyntaxHighlighter.highlight(); + + $scope.loading = false; + }).error(function (data) { + $scope.generateError = "Failed to generate config: " + data; + + $scope.loading = false; + }); + }; + + $scope.$watch('cfgLang', $scope.generate); + $scope.$watch('generateJavaClass', $scope.generate); + + $scope.dockerArg = {}; + + $scope.download = function(text, fileName) { + if (text.length == 0) + return; + + var file = document.createElement('a'); + file.setAttribute('href', 'data:application/octet-stream;charset=utf-8,' + encodeURIComponent(text)); + file.setAttribute('download', fileName); + + file.style.display = 'none'; + document.body.appendChild(file); + + file.click(); + + document.body.removeChild(file); + }; + + $scope.downloadJava = function() { + $scope.download($scope.javaData, + $scope.generateJavaClass ? 'ConfigurationFactory.java' : $scope.selectedItem.name + '.snipplet.txt'); + }; + + $scope.downloadDocker = function() { + $scope.download($scope.dockerFile(), 'Dockerfile'); + }; + + $scope.oss = ['debian:8', 'ubuntu:14.10']; + + $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"+ + "# Install 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"; + }; + + $scope.$watch('dockerArg.os', function() { + $("<pre class='brush:plain' />").text($scope.dockerFile()).appendTo($('#dockerResultDiv').empty()); + }); +}]); http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/36063e13/modules/web-control-center/nodejs/db.js ---------------------------------------------------------------------- diff --git a/modules/web-control-center/nodejs/db.js b/modules/web-control-center/nodejs/db.js index c0f145e..9630303 100644 --- a/modules/web-control-center/nodejs/db.js +++ b/modules/web-control-center/nodejs/db.js @@ -15,7 +15,7 @@ * limitations under the License. */ -var config = require('./configuration.js'); +var config = require('./helpers/configuration-loader.js'); // Mongoose for mongodb. var mongoose = require('mongoose'), http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/36063e13/modules/web-control-center/nodejs/generator/common.js ---------------------------------------------------------------------- diff --git a/modules/web-control-center/nodejs/generator/common.js b/modules/web-control-center/nodejs/generator/common.js deleted file mode 100644 index 763088c..0000000 --- a/modules/web-control-center/nodejs/generator/common.js +++ /dev/null @@ -1,287 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -var _ = require('lodash'); - -exports.mainComment = function() { - return 'This configuration was generated by Ignite Control Center (' - + formatDate(new Date()) + ')'; -}; - -function addLeadingZero(numberStr, minSize) { - if (typeof (numberStr) != 'string') - numberStr = '' + numberStr; - - while (numberStr.length < minSize) { - numberStr = '0' + numberStr; - } - - return numberStr; -} - -exports.formatDate = formatDate; - -function formatDate(date) { - var dd = addLeadingZero(date.getDate(), 2); - var mm = addLeadingZero(date.getMonth() + 1, 2); - - var yyyy = date.getFullYear(); - - return mm + '/' + dd + '/' + yyyy + ' ' + addLeadingZero(date.getHours(), 2) + ':' + addLeadingZero(date.getMinutes(), 2); -} - -exports.builder = function () { - var res = []; - - res.deep = 0; - res.lineStart = true; - - res.append = function(s) { - if (this.lineStart) { - for (var i = 0; i < this.deep; i++) - this.push(' '); - - this.lineStart = false; - } - - this.push(s); - - return this; - }; - - res.line = function(s) { - if (s) - this.append(s); - - this.push('\n'); - this.lineStart = true; - - return this; - }; - - res.startBlock = function(s) { - if (s) - this.append(s); - - this.push('\n'); - this.lineStart = true; - this.deep++; - - return this; - }; - - res.endBlock = function(s) { - this.deep--; - - if (s) - this.append(s); - - this.push('\n'); - this.lineStart = true; - - return this; - }; - - res.emptyLineIfNeeded = function() { - if (this.needEmptyLine) { - this.line(); - - this.needEmptyLine = false; - - return true; - } - - return false; - }; - - res.imports = {}; - - res.importClass = function(fullClassName) { - var dotIdx = fullClassName.lastIndexOf('.'); - - var shortName; - - if (dotIdx > 0) - shortName = fullClassName.substr(dotIdx + 1); - else - shortName = fullClassName; - - if (this.imports[shortName]) { - if (this.imports[shortName] != fullClassName) - throw "Class name conflict: " + this.imports[shortName] + ' and ' + fullClassName; - } - else { - this.imports[shortName] = fullClassName; - } - - return shortName; - }; - - res.generateImports = function() { - var res = []; - - for (var clsName in this.imports) { - if (this.imports.hasOwnProperty(clsName)) - res.push('import ' + this.imports[clsName] + ';'); - } - - return res.join('\n') - }; - - return res; -}; - -function ClassDescriptor(className, fields) { - this.className = className; - - this.fields = fields; -} - -exports.evictionPolicies = { - 'LRU': new ClassDescriptor('org.apache.ignite.cache.eviction.lru.LruEvictionPolicy', - {batchSize: null, maxMemorySize: null, maxSize: null}), - 'RND': new ClassDescriptor('org.apache.ignite.cache.eviction.random.RandomEvictionPolicy', {maxSize: null}), - 'FIFO': new ClassDescriptor('org.apache.ignite.cache.eviction.fifo.FifoEvictionPolicy', - {batchSize: null, maxMemorySize: null, maxSize: null}), - 'SORTED': new ClassDescriptor('org.apache.ignite.cache.eviction.sorted.SortedEvictionPolicy', - {batchSize: null, maxMemorySize: null, maxSize: null}) -}; - -exports.knownClasses = { - Oracle: new ClassDescriptor('org.apache.ignite.cache.store.jdbc.dialect.OracleDialect', {}), - DB2: new ClassDescriptor('org.apache.ignite.cache.store.jdbc.dialect.DB2Dialect', {}), - SQLServer: new ClassDescriptor('org.apache.ignite.cache.store.jdbc.dialect.SQLServerDialect', {}), - MySQL: new ClassDescriptor('org.apache.ignite.cache.store.jdbc.dialect.MySQLDialect', {}), - PostgreSQL: new ClassDescriptor('org.apache.ignite.cache.store.jdbc.dialect.BasicJdbcDialect', {}), - H2: new ClassDescriptor('org.apache.ignite.cache.store.jdbc.dialect.H2Dialect', {}) -}; - -exports.dataSources = { - Oracle: 'oracle.jdbc.pool.OracleDataSource', - DB2: 'com.ibm.db2.jcc.DB2ConnectionPoolDataSource', - SQLServer: 'com.microsoft.sqlserver.jdbc.SQLServerDataSource', - MySQL: 'com.mysql.jdbc.jdbc2.optional.MysqlDataSource', - PostgreSQL: 'org.postgresql.ds.PGPoolingDataSource', - H2: 'org.h2.jdbcx.JdbcDataSource' -}; - -exports.storeFactories = { - CacheJdbcPojoStoreFactory: new ClassDescriptor('org.apache.ignite.cache.store.jdbc.CacheJdbcPojoStoreFactory', { - dataSourceBean: null, - dialect: {type: 'className'} - }), - - CacheJdbcBlobStoreFactory: new ClassDescriptor('org.apache.ignite.cache.store.jdbc.CacheJdbcBlobStoreFactory', { - user: null, - dataSourceBean: null, - initSchema: null, - createTableQuery: null, - loadQuery: null, - insertQuery: null, - updateQuery: null, - deleteQuery: null - }), - - CacheHibernateBlobStoreFactory: new ClassDescriptor('org.apache.ignite.cache.store.hibernate.CacheHibernateBlobStoreFactory', { - hibernateProperties: {type: 'propertiesAsList', propVarName: 'props'} - }) -}; - -exports.atomicConfiguration = new ClassDescriptor('org.apache.ignite.configuration.AtomicConfiguration', { - backups: null, - cacheMode: {type: 'enum', enumClass: 'CacheMode'}, - atomicSequenceReserveSize: null -}); - -exports.swapSpaceSpi = new ClassDescriptor('org.apache.ignite.spi.swapspace.file.FileSwapSpaceSpi', { - baseDirectory: null, - readStripesNumber: null, - maximumSparsity: {type: 'float'}, - maxWriteQueueSize: null, - writeBufferSize: null -}); - -exports.transactionConfiguration = new ClassDescriptor('org.apache.ignite.configuration.TransactionConfiguration', { - defaultTxConcurrency: {type: 'enum', enumClass: 'TransactionConcurrency'}, - transactionIsolation: {type: 'TransactionIsolation', setterName: 'defaultTxIsolation'}, - defaultTxTimeout: null, - pessimisticTxLogLinger: null, - pessimisticTxLogSize: null, - txSerializableEnabled: null -}); - -exports.hasProperty = function(obj, props) { - for (var propName in props) { - if (props.hasOwnProperty(propName)) { - if (obj[propName]) - return true; - } - } - - return false; -}; - -/** - * Convert some name to valid java name. - * - * @param name to convert. - * @returns {string} Valid java name. - */ -exports.toJavaName = function(name) { - var javaName = name.replace(/[^A-Za-z_0-9]+/, '_'); - - return javaName.charAt(0).toLocaleUpperCase() + javaName.slice(1); -}; - -/** - * Generate properties file with properties stubs for stores data sources. - * - * @param cluster Configuration to process. - * @returns {string} Generated content. - */ -exports.generateProperties = function(cluster) { - var res = builder(); - - var datasources = []; - - if (cluster.caches && cluster.caches.length > 0) { - - _.foreach(cluster.caches, function (cache) { - if (cache.cacheStoreFactory && cache.cacheStoreFactory.kind) { - var storeFactory = cache.cacheStoreFactory[cache.cacheStoreFactory.kind]; - - if (storeFactory.dialect) { - var beanId = storeFactory.dataSourceBean; - - if (!_.contains(datasources, beanId)) { - datasources.push(beanId); - - res.line(beanId + '.jdbc.url=YOUR_JDBC_URL'); - res.line(beanId + '.jdbc.username=YOUR_USER_NAME'); - res.line(beanId + '.jdbc.password=YOUR_PASSWORD'); - res.line(); - } - } - } - }); - } - - if (datasources.length > 0) - return '# ' + mainComment() + '\n\n' + res.join(); - - return ''; -}; http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/36063e13/modules/web-control-center/nodejs/generator/java.js ---------------------------------------------------------------------- diff --git a/modules/web-control-center/nodejs/generator/java.js b/modules/web-control-center/nodejs/generator/java.js deleted file mode 100644 index 037df10..0000000 --- a/modules/web-control-center/nodejs/generator/java.js +++ /dev/null @@ -1,608 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -var _ = require('lodash'); - -var generatorUtils = require("./common"); - -exports.generateClusterConfiguration = function(cluster, generateJavaClass) { - var res = generatorUtils.builder(); - - res.datasourceBeans = []; - - if (generateJavaClass) { - res.line('/**'); - res.line(' * ' + generatorUtils.mainComment()); - res.line(' */'); - res.startBlock('public class ConfigurationFactory {'); - res.line('/**'); - res.line(' * Configure grid.'); - res.line(' */'); - res.startBlock('public IgniteConfiguration createConfiguration() {'); - } - - res.importClass('org.apache.ignite.configuration.IgniteConfiguration'); - - res.line('IgniteConfiguration cfg = new IgniteConfiguration();'); - res.line(); - - if (cluster.discovery) { - var d = cluster.discovery; - - res.importClass('org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi'); - res.line('TcpDiscoverySpi discovery = new TcpDiscoverySpi();'); - - switch (d.kind) { - case 'Multicast': - addBeanWithProperties(res, d.Multicast, 'discovery', 'ipFinder', 'ipFinder', - 'org.apache.ignite.spi.discovery.tcp.ipfinder.multicast.TcpDiscoveryMulticastIpFinder', { - multicastGroup: null, - multicastPort: null, - responseWaitTime: null, - addressRequestAttempts: null, - localAddress: null - }, true); - - break; - - case 'Vm': - addBeanWithProperties(res, d.Vm, 'discovery', 'ipFinder', 'ipFinder', - 'org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder', { - addresses: {type: 'list'} - }, true); - - break; - - case 'S3': - if (d.S3) { - addBeanWithProperties(res, d.S3, 'discovery', 'ipFinder', 'ipFinder', - 'org.apache.ignite.spi.discovery.tcp.ipfinder.s3.TcpDiscoveryS3IpFinder', {bucketName: null}, - true); - } - else { - res.importClass('org.apache.ignite.spi.discovery.tcp.ipfinder.s3.TcpDiscoveryS3IpFinder'); - - res.line('discovery.setIpFinder(new TcpDiscoveryS3IpFinder());'); - } - - break; - - case 'Cloud': - addBeanWithProperties(res, d.Cloud, 'discovery', 'ipFinder', 'ipFinder', - 'org.apache.ignite.spi.discovery.tcp.ipfinder.cloud.TcpDiscoveryCloudIpFinder', { - credential: null, - credentialPath: null, - identity: null, - provider: null, - regions: {type: 'list'}, - zones: {type: 'list'} - }, true); - - break; - - case 'GoogleStorage': - addBeanWithProperties(res, d.GoogleStorage, 'discovery', 'ipFinder', 'ipFinder', - 'org.apache.ignite.spi.discovery.tcp.ipfinder.gce.TcpDiscoveryGoogleStorageIpFinder', { - projectName: null, - bucketName: null, - serviceAccountP12FilePath: null - }, true); - - //if (d.GoogleStorage.addrReqAttempts) todo ???? - // res.line('<property name="serviceAccountP12FilePath" value="' + escapeAttr(d.GoogleStorage.addrReqAttempts) + '"/>'); - - break; - - case 'Jdbc': - res.importClass('org.apache.ignite.spi.discovery.tcp.ipfinder.jdbc.TcpDiscoveryJdbcIpFinder'); - - res.line(); - res.line('TcpDiscoveryJdbcIpFinder ipFinder = new TcpDiscoveryJdbcIpFinder();'); - res.line('ipFinder.setInitSchema(' + (d.Jdbc.initSchema != null || d.Jdbc.initSchema) + ');'); - res.line('discovery.setIpFinder(ipFinder);'); - res.needEmptyLine = true; - - break; - - case 'SharedFs': - addBeanWithProperties(res, d.SharedFs, 'discovery', 'ipFinder', 'ipFinder', - 'org.apache.ignite.spi.discovery.tcp.ipfinder.sharedfs.TcpDiscoverySharedFsIpFinder', {path: null}, - true); - - break; - - default: - throw "Unknown discovery kind: " + d.kind; - } - - res.emptyLineIfNeeded(); - - res.line('cfg.setDiscoverySpi(discovery);'); - - res.needEmptyLine = true; - } - - if (cluster.caches && cluster.caches.length > 0) { - res.emptyLineIfNeeded(); - - var names = []; - - for (var i = 0; i < cluster.caches.length; i++) { - res.emptyLineIfNeeded(); - - var cache = cluster.caches[i]; - - var cacheName = 'cache' + generatorUtils.toJavaName(cache.name); - - names.push(cacheName); - - generateCacheConfiguration(cache, cacheName, res); - - res.needEmptyLine = true; - } - - res.emptyLineIfNeeded(); - - res.append('cfg.setCacheConfiguration('); - - for (i = 0; i < names.length; i++) { - if (i > 0) - res.append(', '); - - res.append(names[i]); - } - - res.line(');'); - - res.needEmptyLine = true; - } - - addBeanWithProperties(res, cluster.atomicConfiguration, 'cfg', 'atomicConfiguration', 'atomicCfg', - generatorUtils.atomicConfiguration.className, generatorUtils.atomicConfiguration.fields); - - res.needEmptyLine = true; - - addProperty(res, cluster, 'cfg', 'networkTimeout'); - addProperty(res, cluster, 'cfg', 'networkSendRetryDelay'); - addProperty(res, cluster, 'cfg', 'networkSendRetryCount'); - addProperty(res, cluster, 'cfg', 'segmentCheckFrequency'); - addProperty(res, cluster, 'cfg', 'waitForSegmentOnStart'); - addProperty(res, cluster, 'cfg', 'discoveryStartupDelay'); - - res.needEmptyLine = true; - - addProperty(res, cluster, 'cfg', 'deploymentMode', 'DeploymentMode'); - - res.needEmptyLine = true; - - if (cluster.includeEventTypes && cluster.includeEventTypes.length > 0) { - res.emptyLineIfNeeded(); - - if (cluster.includeEventTypes.length == 1) { - res.importClass('org.apache.ignite.events.EventType'); - - res.line('cfg.setIncludeEventTypes(EventType.' + cluster.includeEventTypes[0] + ');'); - } - else { - res.append('int[] events = new int[EventType.' + cluster.includeEventTypes[0] + '.length'); - - for (i = 1; i < cluster.includeEventTypes.length; i++) { - res.line(); - - res.append(' + EventType.' + cluster.includeEventTypes[i] + '.length'); - } - - res.line('];'); - res.line(); - res.line('int k = 0;'); - - for (i = 0; i < cluster.includeEventTypes.length; i++) { - res.line(); - - var e = cluster.includeEventTypes[i]; - - res.line('System.arraycopy(EventType.' + e + ', 0, events, k, EventType.' + e + '.length);'); - res.line('k += EventType.' + e + '.length;'); - } - - res.line(); - res.line('cfg.setIncludeEventTypes(events);'); - } - - res.needEmptyLine = true; - } - - res.needEmptyLine = true; - - addProperty(res, cluster, 'cfg', 'marshalLocalJobs'); - addProperty(res, cluster, 'cfg', 'marshCacheKeepAliveTime'); - addProperty(res, cluster, 'cfg', 'marshCachePoolSize'); - - res.needEmptyLine = true; - - addProperty(res, cluster, 'cfg', 'metricsExpireTime'); - addProperty(res, cluster, 'cfg', 'metricsHistorySize'); - addProperty(res, cluster, 'cfg', 'metricsLogFrequency'); - addProperty(res, cluster, 'cfg', 'metricsUpdateFrequency'); - res.needEmptyLine = true; - - addProperty(res, cluster, 'cfg', 'peerClassLoadingEnabled'); - addMultiparamProperty(res, cluster, 'cfg', 'peerClassLoadingLocalClassPathExclude'); - addProperty(res, cluster, 'cfg', 'peerClassLoadingMissedResourcesCacheSize'); - addProperty(res, cluster, 'cfg', 'peerClassLoadingThreadPoolSize'); - res.needEmptyLine = true; - - if (cluster.swapSpaceSpi && cluster.swapSpaceSpi.kind == 'FileSwapSpaceSpi') { - addBeanWithProperties(res, cluster.swapSpaceSpi.FileSwapSpaceSpi, 'cfg', 'swapSpaceSpi', 'swapSpi', - generatorUtils.swapSpaceSpi.className, generatorUtils.swapSpaceSpi.fields, true); - - res.needEmptyLine = true; - } - - addProperty(res, cluster, 'cfg', 'clockSyncSamples'); - addProperty(res, cluster, 'cfg', 'clockSyncFrequency'); - addProperty(res, cluster, 'cfg', 'timeServerPortBase'); - addProperty(res, cluster, 'cfg', 'timeServerPortRange'); - - res.needEmptyLine = true; - - addProperty(res, cluster, 'cfg', 'publicThreadPoolSize'); - addProperty(res, cluster, 'cfg', 'systemThreadPoolSize'); - addProperty(res, cluster, 'cfg', 'managementThreadPoolSize'); - addProperty(res, cluster, 'cfg', 'igfsThreadPoolSize'); - - res.needEmptyLine = true; - - addBeanWithProperties(res, cluster.transactionConfiguration, 'cfg', 'transactionConfiguration', - 'transactionConfiguration', generatorUtils.transactionConfiguration.className, - generatorUtils.transactionConfiguration.fields); - - res.needEmptyLine = true; - - addProperty(res, cluster, 'cfg', 'cacheSanityCheckEnabled'); - - res.needEmptyLine = true; - - addProperty(res, cluster, 'cfg', 'utilityCacheKeepAliveTime'); - addProperty(res, cluster, 'cfg', 'utilityCachePoolSize'); - - if (generateJavaClass) { - res.line(); - res.line('return cfg;'); - res.endBlock('}'); - res.endBlock('}'); - - return res.generateImports() + '\n\n' + res.join('') - } - - return res.join(''); -}; - -function createEvictionPolicy(res, evictionPolicy, varName, propertyName) { - if (evictionPolicy && evictionPolicy.kind) { - var e = generatorUtils.evictionPolicies[evictionPolicy.kind]; - - var obj = evictionPolicy[evictionPolicy.kind.toUpperCase()]; - - addBeanWithProperties(res, obj, varName, propertyName, propertyName, e.className, e.fields, true); - } -} - -exports.generateCacheConfiguration = generateCacheConfiguration; - -/** - * Generate java code for cache configuration. - * - * @param cacheCfg Cache config. - * @param varName Variable name. - * @param res Result builder. - * @returns {*} Append generated java code to builder and return it. - */ -function generateCacheConfiguration(cacheCfg, varName, res) { - if (!res) - res = generatorUtils.builder(); - - res.emptyLineIfNeeded(); - - res.importClass('org.apache.ignite.configuration.CacheConfiguration'); - - res.line('CacheConfiguration ' + varName + ' = new CacheConfiguration();'); - - res.needEmptyLine = true; - - addProperty(res, cacheCfg, varName, 'name'); - - addProperty(res, cacheCfg, varName, 'mode', 'CacheMode', 'cacheMode'); - - addProperty(res, cacheCfg, varName, 'atomicityMode', 'CacheAtomicityMode'); - addProperty(res, cacheCfg, varName, 'backups'); - addProperty(res, cacheCfg, varName, 'startSize'); - addProperty(res, cacheCfg, varName, 'readFromBackup'); - - res.needEmptyLine = true; - - addProperty(res, cacheCfg, varName, 'memoryMode', 'CacheMemoryMode'); - addProperty(res, cacheCfg, varName, 'offHeapMaxMemory'); - addProperty(res, cacheCfg, varName, 'swapEnabled'); - addProperty(res, cacheCfg, varName, 'copyOnRead'); - - res.needEmptyLine = true; - - createEvictionPolicy(res, cacheCfg.evictionPolicy, varName, 'evictionPolicy'); - - if (cacheCfg.nearConfiguration && (cacheCfg.nearConfiguration.nearStartSize || cacheCfg.nearConfiguration.nearEvictionPolicy.kind)) { - res.needEmptyLine = true; - - addBeanWithProperties(res, cacheCfg.nearConfiguration, varName, 'nearConfiguration', 'nearConfiguration', - 'org.apache.ignite.configuration.NearCacheConfiguration', - {nearStartSize: null, atomicSequenceReserveSize: null}, true); - - if (cacheCfg.nearConfiguration && cacheCfg.nearConfiguration.nearEvictionPolicy && cacheCfg.nearConfiguration.nearEvictionPolicy.kind) { - createEvictionPolicy(res, cacheCfg.nearConfiguration.nearEvictionPolicy, 'nearConfiguration', 'nearEvictionPolicy'); - } - } - - res.needEmptyLine = true; - - addProperty(res, cacheCfg, varName, 'sqlEscapeAll'); - addProperty(res, cacheCfg, varName, 'sqlOnheapRowCacheSize'); - addProperty(res, cacheCfg, varName, 'longQueryWarningTimeout'); - - if (cacheCfg.indexedTypes && cacheCfg.indexedTypes.length > 0) { - res.emptyLineIfNeeded(); - - res.append(varName + '.setIndexedTypes('); - - for (var i = 0; i < cacheCfg.indexedTypes.length; i++) { - if (i > 0) - res.append(', '); - - var pair = cacheCfg.indexedTypes[i]; - - res.append(toJavaCode(pair.keyClass, 'class')).append(', ').append(toJavaCode(pair.valueClass, 'class')) - } - - res.line(');'); - } - - addMultiparamProperty(res, cacheCfg, varName, 'sqlFunctionClasses', 'class'); - - res.needEmptyLine = true; - - addProperty(res, cacheCfg, varName, 'rebalanceMode', 'CacheRebalanceMode'); - addProperty(res, cacheCfg, varName, 'rebalanceThreadPoolSize'); - addProperty(res, cacheCfg, varName, 'rebalanceBatchSize'); - addProperty(res, cacheCfg, varName, 'rebalanceOrder'); - addProperty(res, cacheCfg, varName, 'rebalanceDelay'); - addProperty(res, cacheCfg, varName, 'rebalanceTimeout'); - addProperty(res, cacheCfg, varName, 'rebalanceThrottle'); - - res.needEmptyLine = true; - - if (cacheCfg.cacheStoreFactory && cacheCfg.cacheStoreFactory.kind) { - var storeFactory = cacheCfg.cacheStoreFactory[cacheCfg.cacheStoreFactory.kind]; - var data = generatorUtils.storeFactories[cacheCfg.cacheStoreFactory.kind]; - - var sfVarName = 'storeFactory' + generatorUtils.toJavaName(cacheCfg.name); - var dsVarName = 'none'; - - if (storeFactory.dialect) { - var dataSourceBean = storeFactory.dataSourceBean; - - dsVarName = 'dataSource' + generatorUtils.toJavaName(dataSourceBean); - - if (!_.contains(res.datasourceBeans, dataSourceBean)) { - res.datasourceBeans.push(dataSourceBean); - - var dataSource = generatorUtils.dataSources[storeFactory.dialect]; - - res.line(); - res.line(dataSource.className + ' ' + dsVarName + ' = new ' + dataSource.className + '();'); - res.line(dsVarName + '.setURL(_URL_);'); - res.line(dsVarName + '.setUsername(_User_Name_);'); - res.line(dsVarName + '.setPassword(_Password_);'); - } - } - - addBeanWithProperties(res, storeFactory, varName, 'cacheStoreFactory', sfVarName, data.className, - data.fields, true); - - if (dsVarName != 'none') - res.line(sfVarName + '.setDataSource(' + dsVarName + ');'); - } - - res.needEmptyLine = true; - - addProperty(res, cacheCfg, varName, 'loadPreviousValue'); - addProperty(res, cacheCfg, varName, 'readThrough'); - addProperty(res, cacheCfg, varName, 'writeThrough'); - - res.needEmptyLine = true; - - addProperty(res, cacheCfg, varName, 'invalidate'); - addProperty(res, cacheCfg, varName, 'defaultLockTimeout'); - addProperty(res, cacheCfg, varName, 'transactionManagerLookupClassName'); - - res.needEmptyLine = true; - - addProperty(res, cacheCfg, varName, 'writeBehindEnabled'); - addProperty(res, cacheCfg, varName, 'writeBehindBatchSize'); - addProperty(res, cacheCfg, varName, 'writeBehindFlushSize'); - addProperty(res, cacheCfg, varName, 'writeBehindFlushFrequency'); - addProperty(res, cacheCfg, varName, 'writeBehindFlushThreadCount'); - - res.needEmptyLine = true; - - addProperty(res, cacheCfg, varName, 'statisticsEnabled'); - addProperty(res, cacheCfg, varName, 'managementEnabled'); - - res.needEmptyLine = true; - - addProperty(res, cacheCfg, varName, 'maxConcurrentAsyncOperations'); - - return res; -} - -function toJavaCode(val, type) { - if (val == null) - return 'null'; - - if (type == 'float') - return val + 'f'; - - if (type == 'class') - return val + '.class'; - - if (type) - return type + '.' + val; - - if (typeof(val) == 'string') - return '"' + val.replace('"', '\\"') + '"'; - - if (typeof(val) == 'number' || typeof(val) == 'boolean') - return '' + val; - - throw "Unknown type: " + typeof(val) + ' (' + val + ')'; -} - -function addProperty(res, obj, objVariableName, propName, enumType, setterName) { - var val = obj[propName]; - - if (val) { - res.emptyLineIfNeeded(); - - res.line(objVariableName + '.' + getSetterName(setterName ? setterName : propName) - + '(' + toJavaCode(val, enumType) + ');'); - } -} - -function getSetterName(propName) { - return 'set' + propName.charAt(0).toLocaleUpperCase() + propName.slice(1); -} - -function addListProperty(res, obj, objVariableName, propName, enumType, setterName) { - var val = obj[propName]; - - if (val && val.length > 0) { - res.append(objVariableName + '.' + getSetterName(setterName ? setterName : propName) + '(Arrays.asList('); - - for (var i = 0; i < val.length; i++) { - if (i > 0) - res.append(', '); - - res.append(toJavaCode(val[i], enumType)); - } - - res.line('));'); - } -} - -function addMultiparamProperty(res, obj, objVariableName, propName, type, setterName) { - var val = obj[propName]; - - if (val && val.length > 0) { - res.append(objVariableName + '.' + getSetterName(setterName ? setterName : propName) + '('); - - for (var i = 0; i < val.length; i++) { - if (i > 0) - res.append(', '); - - res.append(toJavaCode(val[i], type)); - } - - res.line(');'); - } -} - -function addBeanWithProperties(res, bean, objVarName, beanPropName, beanVarName, beanClass, props, createBeanAlthoughNoProps) { - if (!bean) - return; - - if (generatorUtils.hasProperty(bean, props)) { - if (!res.emptyLineIfNeeded()) { - res.line(); - } - - res.line(beanClass + ' ' + beanVarName + ' = new ' + beanClass + '();'); - - for (var propName in props) { - if (props.hasOwnProperty(propName)) { - var descr = props[propName]; - - if (descr) { - switch (descr.type) { - case 'list': - addListProperty(res, bean, beanVarName, propName, descr.elementsType, descr.setterName); - break; - - case 'enum': - addProperty(res, bean, beanVarName, propName, descr.enumClass, descr.setterName); - break; - - case 'float': - addProperty(res, bean, beanVarName, propName, 'float', descr.setterName); - break; - - case 'propertiesAsList': - var val = bean[propName]; - - if (val && val.length > 0) { - res.line('Properties ' + descr.propVarName + ' = new Properties();'); - - for (var i = 0; i < val.length; i++) { - var nameAndValue = val[i]; - - var eqIndex = nameAndValue.indexOf('='); - if (eqIndex >= 0) { - res.line(descr.propVarName + '.setProperty(' - + nameAndValue.substring(0, eqIndex) + ', ' - + nameAndValue.substr(eqIndex + 1) + ');'); - } - - } - - res.line(beanVarName + '.' + getSetterName(propName) + '(' + descr.propVarName + ');'); - } - break; - - case 'className': - if (bean[propName]) { - res.line(beanVarName + '.' + getSetterName(propName) + '(new ' + generatorUtils.knownClasses[bean[propName]].className + '());'); - } - - break; - - default: - addProperty(res, bean, beanVarName, propName, null, descr.setterName); - } - } - else { - addProperty(res, bean, beanVarName, propName); - } - } - } - - res.line(objVarName + '.' + getSetterName(beanPropName) + '(' + beanVarName + ');'); - - res.needEmptyLine = true; - } - else if (createBeanAlthoughNoProps) { - res.emptyLineIfNeeded(); - - res.line(objVarName + '.' + getSetterName(beanPropName) + '(new ' + beanClass + '());'); - } -}