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 2019/04/05 11:13:26 UTC
[ignite] branch master updated: IGNITE-11284 Web console:
Actualized cluster configuration.
This is an automated email from the ASF dual-hosted git repository.
akuznetsov pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ignite.git
The following commit(s) were added to refs/heads/master by this push:
new b6a07f6 IGNITE-11284 Web console: Actualized cluster configuration.
b6a07f6 is described below
commit b6a07f65bba402e5bfa165957f526cee95098f44
Author: Vasiliy Sisko <vs...@gridgain.com>
AuthorDate: Fri Apr 5 18:13:08 2019 +0700
IGNITE-11284 Web console: Actualized cluster configuration.
---
modules/web-console/backend/app/schemas.js | 14 +++-
.../components/model-edit-form/templates/query.pug | 72 ++++++++++++++++++++-
.../generator/generator/ConfigurationGenerator.js | 74 ++++++++++++++++++++--
.../generator/generator/JavaTransformer.service.js | 4 +-
.../generator/SpringTransformer.service.js | 6 +-
.../generator/generator/defaults/Cache.service.js | 12 ++++
.../frontend/app/configuration/services/Models.ts | 41 ++++++++++++
.../WebConsoleConfigurationSelfTest.java | 6 ++
8 files changed, 216 insertions(+), 13 deletions(-)
diff --git a/modules/web-console/backend/app/schemas.js b/modules/web-console/backend/app/schemas.js
index 4741776..29493a5 100644
--- a/modules/web-console/backend/app/schemas.js
+++ b/modules/web-console/backend/app/schemas.js
@@ -122,12 +122,21 @@ module.exports.factory = function(mongoose) {
javaFieldType: String
}],
queryKeyFields: [String],
- fields: [{name: String, className: String}],
+ fields: [{
+ name: String,
+ className: String,
+ notNull: Boolean,
+ defaultValue: String,
+ precision: Number,
+ scale: Number
+ }],
aliases: [{field: String, alias: String}],
indexes: [{
name: String,
indexType: {type: String, enum: ['SORTED', 'FULLTEXT', 'GEOSPATIAL']},
- fields: [{name: String, direction: Boolean}]
+ fields: [{name: String, direction: Boolean}],
+ inlineSizeType: Number,
+ inlineSize: Number
}],
generatePojo: Boolean
});
@@ -182,6 +191,7 @@ module.exports.factory = function(mongoose) {
backups: Number,
memoryMode: {type: String, enum: ['ONHEAP_TIERED', 'OFFHEAP_TIERED', 'OFFHEAP_VALUES']},
+ offHeapMode: Number,
offHeapMaxMemory: Number,
startSize: Number,
swapEnabled: Boolean,
diff --git a/modules/web-console/frontend/app/configuration/components/page-configure-advanced/components/model-edit-form/templates/query.pug b/modules/web-console/frontend/app/configuration/components/page-configure-advanced/components/model-edit-form/templates/query.pug
index 2dbb565..9f14980 100644
--- a/modules/web-console/frontend/app/configuration/components/page-configure-advanced/components/model-edit-form/templates/query.pug
+++ b/modules/web-console/frontend/app/configuration/components/page-configure-advanced/components/model-edit-form/templates/query.pug
@@ -77,12 +77,12 @@ panel-collapsible(ng-form=form opened=`!!${model}.queryMetadata`)
ng-change=`$ctrl.onQueryFieldsChange(${model})`
)
list-editable-item-view
- | {{ $item.name}} / {{ $item.className}}
+ | {{$ctrl.Models.fieldProperties.fieldPresentation($item, $ctrl.available)}}
list-editable-item-edit
- form = '$parent.form'
.pc-form-grid-row
- .pc-form-grid-col-30(divider='/')
+ .pc-form-grid-col-30
+form-field__text({
label: 'Field name:',
model: '$item.name',
@@ -98,7 +98,7 @@ panel-collapsible(ng-form=form opened=`!!${model}.queryMetadata`)
.pc-form-grid-col-30
+form-field__java-class--typeahead({
label: 'Field full class name:',
- model: `$item.className`,
+ model: '$item.className',
name: '"className"',
options: '$ctrl.queryFieldTypes',
required: 'true',
@@ -107,6 +107,41 @@ panel-collapsible(ng-form=form opened=`!!${model}.queryMetadata`)
ng-model-options='{allowInvalid: true}'
extra-valid-java-identifiers='$ctrl.queryFieldTypes'
)
+ .pc-form-grid-col-60(ng-if='$ctrl.available("2.4.0")')
+ +form-field__text({
+ label: 'Default value:',
+ model: '$item.defaultValue',
+ name: '"defaultValue"',
+ placeholder: 'Enter default value'
+ })
+ .pc-form-grid-col-30(ng-if-start='$ctrl.available("2.7.0") && $ctrl.Models.fieldProperties.precisionAvailable($item)')
+ +form-field__number({
+ label: 'Precision:',
+ model: '$item.precision',
+ name: '"Precision"',
+ placeholder: 'Input field precision',
+ min: '1',
+ tip: 'Precision of field',
+ required: '$item.scale'
+ })
+ .pc-form-grid-col-30(ng-if-end)
+ +form-field__number({
+ label: 'Scale:',
+ model: '$item.scale',
+ name: '"Scale"',
+ placeholder: 'input field scale',
+ disabled: '!$ctrl.Models.fieldProperties.scaleAvailable($item)',
+ min: '0',
+ max: '{{$item.precision}}',
+ tip: 'Scale of field'
+ })
+ .pc-form-grid-col-60(ng-if='$ctrl.available("2.3.0")')
+ +form-field__checkbox({
+ label: 'Not NULL',
+ model: '$item.notNull',
+ name: '"notNull"',
+ tip: 'Field must have non-null value'
+ })
list-editable-no-items
list-editable-add-item-button(
@@ -223,6 +258,37 @@ panel-collapsible(ng-form=form opened=`!!${model}.queryMetadata`)
placeholder: 'Select index type',
options: '::$ctrl.Models.indexType.values'
})
+ .pc-form-grid-col-60(ng-if='$ctrl.available("2.3.0")')
+ +form-field__dropdown({
+ label: 'Inline size:',
+ model: `queryIndex.inlineSizeType`,
+ name: '"InlineSizeKind"',
+ placeholder: '{{::$ctrl.Models.inlineSizeType.default}}',
+ options: '{{::$ctrl.Models.inlineSizeTypes}}',
+ tip: `Inline size
+ <ul>
+ <li>Auto - Determine inline size automatically</li>
+ <li>Custom - Fixed index inline</li>
+ <li>Disabled - Index inline is disabled</li>
+ </ul>`
+ })(
+ ng-change=`$ctrl.Models.inlineSizeType.onChange(queryIndex)`
+ ng-model-options='{allowInvalid: true}'
+ )
+ .pc-form-grid-col-60(ng-if='$ctrl.available("2.3.0") && queryIndex.inlineSizeType === 1')
+ form-field-size(
+ label='Inline size:'
+ ng-model=`queryIndex.inlineSize`
+ ng-model-options='{allowInvalid: true}'
+ name=`InlineSize`
+ tip='Index inline size in bytes. Part of indexed value will be placed directly to index pages thus minimizing data page accesses'
+ placeholder='Input inline size'
+ min=`1`
+ size-scale-label='kb'
+ size-type='bytes'
+ required='true'
+ )
+ +form-field__error({error: 'min', message: 'Inline size should be greater than 0'})
.pc-form-grid-col-60
.ignite-form-field
+form-field__label({ label: 'Index fields:', name: '"indexFields"', required: true })
diff --git a/modules/web-console/frontend/app/configuration/generator/generator/ConfigurationGenerator.js b/modules/web-console/frontend/app/configuration/generator/generator/ConfigurationGenerator.js
index a71f518..98bfaf2 100644
--- a/modules/web-console/frontend/app/configuration/generator/generator/ConfigurationGenerator.js
+++ b/modules/web-console/frontend/app/configuration/generator/generator/ConfigurationGenerator.js
@@ -1952,8 +1952,54 @@ export default class IgniteConfigurationGenerator {
// Generate domain model for query group.
static domainModelQuery(domain, available, cfg = this.domainConfigurationBean(domain)) {
if (cfg.valueOf('queryMetadata') === 'Configuration') {
+ const notNull = [];
+ const precisions = [];
+ const scales = [];
+ const defaultValues = [];
+
+ const notNullAvailable = available('2.3.0');
+ const defaultAvailable = available('2.4.0');
+ const precisionAvailable = available('2.7.0');
+
const fields = _.filter(_.map(domain.fields,
- (e) => ({name: e.name, className: javaTypes.stringClassName(e.className)})), (field) => {
+ (e) => {
+ if (notNullAvailable && e.notNull)
+ notNull.push(e.name);
+
+ if (defaultAvailable && e.defaultValue) {
+ let value = e.defaultValue;
+
+ switch (e.className) {
+ case 'String':
+ value = new Bean('java.lang.String', 'value', e).stringConstructorArgument('defaultValue');
+
+ break;
+
+ case 'BigDecimal':
+ value = new Bean('java.math.BigDecimal', 'value', e).stringConstructorArgument('defaultValue');
+
+ break;
+
+ case 'byte[]':
+ value = null;
+
+ break;
+
+ default: // No-op.
+ }
+
+ defaultValues.push({name: e.name, value});
+ }
+
+ if (precisionAvailable && e.precision) {
+ precisions.push({name: e.name, value: e.precision});
+
+ if (e.scale)
+ scales.push({name: e.name, value: e.scale});
+ }
+
+ return {name: e.name, className: javaTypes.stringClassName(e.className)};
+ }), (field) => {
return field.name !== domain.keyFieldName && field.name !== domain.valueFieldName;
});
@@ -1977,12 +2023,30 @@ export default class IgniteConfigurationGenerator {
.mapProperty('fields', fields, 'fields', true)
.mapProperty('aliases', 'aliases');
- const indexes = _.map(domain.indexes, (index) =>
- new Bean('org.apache.ignite.cache.QueryIndex', 'index', index, cacheDflts.indexes)
+ if (notNullAvailable && notNull)
+ cfg.collectionProperty('notNullFields', 'notNullFields', notNull, 'java.lang.String', 'java.util.HashSet');
+
+ if (defaultAvailable && defaultValues)
+ cfg.mapProperty('defaultFieldValues', defaultValues, 'defaultFieldValues');
+
+ if (precisionAvailable && precisions) {
+ cfg.mapProperty('fieldsPrecision', precisions, 'fieldsPrecision');
+
+ if (scales)
+ cfg.mapProperty('fieldsScale', scales, 'fieldsScale');
+ }
+
+ const indexes = _.map(domain.indexes, (index) => {
+ const bean = new Bean('org.apache.ignite.cache.QueryIndex', 'index', index, cacheDflts.indexes)
.stringProperty('name')
.enumProperty('indexType')
- .mapProperty('indFlds', 'fields', 'fields', true)
- );
+ .mapProperty('indFlds', 'fields', 'fields', true);
+
+ if (available('2.3.0'))
+ bean.intProperty('inlineSize');
+
+ return bean;
+ });
cfg.collectionProperty('indexes', 'indexes', indexes, 'org.apache.ignite.cache.QueryIndex');
}
diff --git a/modules/web-console/frontend/app/configuration/generator/generator/JavaTransformer.service.js b/modules/web-console/frontend/app/configuration/generator/generator/JavaTransformer.service.js
index fdaf829..c1e1cfd 100644
--- a/modules/web-console/frontend/app/configuration/generator/generator/JavaTransformer.service.js
+++ b/modules/web-console/frontend/app/configuration/generator/generator/JavaTransformer.service.js
@@ -17,6 +17,8 @@
import {nonEmpty} from 'app/utils/lodashMixins';
+import { Bean } from './Beans';
+
import AbstractTransformer from './AbstractTransformer';
import StringBuilder from './StringBuilder';
import VersionService from 'app/services/Version.service';
@@ -413,7 +415,7 @@ export default class IgniteJavaTransformer extends AbstractTransformer {
case 'PROPERTY_INT':
return `Integer.parseInt(props.getProperty("${item}"))`;
default:
- if (this._isBean(clsName)) {
+ if (this._isBean(clsName) || val instanceof Bean) {
if (item.isComplex())
return item.id;
diff --git a/modules/web-console/frontend/app/configuration/generator/generator/SpringTransformer.service.js b/modules/web-console/frontend/app/configuration/generator/generator/SpringTransformer.service.js
index db9109b..5d90ed4 100644
--- a/modules/web-console/frontend/app/configuration/generator/generator/SpringTransformer.service.js
+++ b/modules/web-console/frontend/app/configuration/generator/generator/SpringTransformer.service.js
@@ -17,6 +17,8 @@
import _ from 'lodash';
+import { Bean } from './Beans';
+
import AbstractTransformer from './AbstractTransformer';
import StringBuilder from './StringBuilder';
import VersionService from 'app/services/Version.service';
@@ -138,8 +140,8 @@ export default class IgniteSpringTransformer extends AbstractTransformer {
const key = entry[map.keyField];
const val = entry[map.valField];
- const isKeyBean = this._isBean(map.keyClsName);
- const isValBean = this._isBean(map.valClsName);
+ const isKeyBean = key instanceof Bean || this._isBean(map.keyClsName);
+ const isValBean = val instanceof Bean || this._isBean(map.valClsName);
if (isKeyBean || isValBean) {
diff --git a/modules/web-console/frontend/app/configuration/generator/generator/defaults/Cache.service.js b/modules/web-console/frontend/app/configuration/generator/generator/defaults/Cache.service.js
index 2e818ba..94fc8db 100644
--- a/modules/web-console/frontend/app/configuration/generator/generator/defaults/Cache.service.js
+++ b/modules/web-console/frontend/app/configuration/generator/generator/defaults/Cache.service.js
@@ -97,6 +97,18 @@ const DFLT_CACHE = {
valField: 'className',
entries: []
},
+ defaultFieldValues: {
+ keyClsName: 'java.lang.String',
+ valClsName: 'java.lang.Object'
+ },
+ fieldsPrecision: {
+ keyClsName: 'java.lang.String',
+ valClsName: 'java.lang.Integer'
+ },
+ fieldsScale: {
+ keyClsName: 'java.lang.String',
+ valClsName: 'java.lang.Integer'
+ },
aliases: {
keyClsName: 'java.lang.String',
valClsName: 'java.lang.String',
diff --git a/modules/web-console/frontend/app/configuration/services/Models.ts b/modules/web-console/frontend/app/configuration/services/Models.ts
index ecd06d8..1fda485 100644
--- a/modules/web-console/frontend/app/configuration/services/Models.ts
+++ b/modules/web-console/frontend/app/configuration/services/Models.ts
@@ -53,6 +53,47 @@ export default class Models {
]
};
+ inlineSizeTypes = [
+ {label: 'Auto', value: -1},
+ {label: 'Custom', value: 1},
+ {label: 'Disabled', value: 0}
+ ];
+
+ inlineSizeType = {
+ _val(queryIndex) {
+ return (queryIndex.inlineSizeType === null || queryIndex.inlineSizeType === void 0) ? -1 : queryIndex.inlineSizeType;
+ },
+ onChange: (queryIndex) => {
+ const inlineSizeType = this.inlineSizeType._val(queryIndex);
+ switch (inlineSizeType) {
+ case 1:
+ return queryIndex.inlineSize = queryIndex.inlineSize > 0 ? queryIndex.inlineSize : null;
+ case 0:
+ case -1:
+ return queryIndex.inlineSize = queryIndex.inlineSizeType;
+ default: break;
+ }
+ },
+ default: 'Auto'
+ };
+
+ fieldProperties = {
+ typesWithPrecision: ['BigDecimal', 'String', 'byte[]'],
+ fieldPresentation: (entity, available) => {
+ if (!entity)
+ return '';
+
+ const precision = available('2.7.0') && this.fieldProperties.precisionAvailable(entity);
+ const scale = available('2.7.0') && this.fieldProperties.scaleAvailable(entity);
+
+ return `${entity.name || ''} ${entity.className || ''}${precision && entity.precision ? ' (' + entity.precision : ''}\
+${scale && entity.precision && entity.scale ? ',' + entity.scale : ''}${precision && entity.precision ? ')' : ''}\
+${available('2.3.0') && entity.notNull ? ' Not NULL' : ''}${available('2.4.0') && entity.defaultValue ? ' DEFAULT ' + entity.defaultValue : ''}`;
+ },
+ precisionAvailable: (entity) => entity && this.fieldProperties.typesWithPrecision.includes(entity.className),
+ scaleAvailable: (entity) => entity && entity.className === 'BigDecimal'
+ };
+
indexSortDirection = {
values: [
{value: true, label: 'ASC'},
diff --git a/modules/web-console/src/test/java/org/apache/ignite/console/configuration/WebConsoleConfigurationSelfTest.java b/modules/web-console/src/test/java/org/apache/ignite/console/configuration/WebConsoleConfigurationSelfTest.java
index 66a4ac7..a163a39 100644
--- a/modules/web-console/src/test/java/org/apache/ignite/console/configuration/WebConsoleConfigurationSelfTest.java
+++ b/modules/web-console/src/test/java/org/apache/ignite/console/configuration/WebConsoleConfigurationSelfTest.java
@@ -792,6 +792,7 @@ public class WebConsoleConfigurationSelfTest {
jdbcPojoStoreProps.add("hasher");
jdbcPojoStoreProps.add("transformer");
jdbcPojoStoreProps.add("sqlEscapeAll");
+ jdbcPojoStoreProps.add("types");
// Configured via dataSource property.
Set<String> jdbcPojoStorePropsExcl = new HashSet<>();
@@ -927,12 +928,17 @@ public class WebConsoleConfigurationSelfTest {
qryEntityProps.add("keyFieldName");
qryEntityProps.add("valueFieldName");
qryEntityProps.add("keyFields");
+ qryEntityProps.add("fieldsPrecision");
+ qryEntityProps.add("notNullFields");
+ qryEntityProps.add("fieldsScale");
+ qryEntityProps.add("defaultFieldValues");
metadata.put(QueryEntity.class, new MetadataInfo(qryEntityProps, EMPTY_FIELDS, EMPTY_FIELDS));
Set<String> qryIdxProps = new HashSet<>();
qryIdxProps.add("name");
qryIdxProps.add("indexType");
qryIdxProps.add("fields");
+ qryIdxProps.add("inlineSize");
Set<String> qryIdxPropsExcl = new HashSet<>();
qryIdxPropsExcl.add("fieldNames");