Skip to content

Commit

Permalink
Release 1.7.3 (#1293)
Browse files Browse the repository at this point in the history
# [1.7.3](https://github.com/kuzzleio/kuzzle/releases/tag/1.7.3) (2019-04-29)


#### Bug fixes

- [ [#1288](#1288) ] [bulk] fix an error when trying a non-partial bulk update   ([scottinet](https://github.com/scottinet))
- [ [#1286](#1286) ] [bugfix] allows bulk inserts on aliases   ([benoitvidis](https://github.com/benoitvidis))
- [ [#1282](#1282) ] [bugfix] scan keys on redis cluster   ([benoitvidis](https://github.com/benoitvidis))
- [ [#1279](#1279) ] Users must be authenticated to use auth:logout   ([scottinet](https://github.com/scottinet))

#### Enhancements

- [ [#1292](#1292) ] KZL 1032 - Throw an error when the realtime controller is invoked by plugin developers   ([benoitvidis](https://github.com/benoitvidis))
- [ [#1257](#1257) ] Add ability to define mapping policy for new fields   ([Aschen](https://github.com/Aschen))
- [ [#1291](#1291) ] [Kuzzle CLI] Fix --help on subcommands   ([Yoann-Abbes](https://github.com/Yoann-Abbes))
- [ [#1289](#1289) ] [WebSocket] Handle ping/pong packets   ([scottinet](https://github.com/scottinet))
- [ [#1273](#1273) ] Fix incomplete access logs   ([scottinet](https://github.com/scottinet))
---
  • Loading branch information
kuzzle authored and Aschen committed Apr 29, 2019
1 parent 0060245 commit 3d491d0
Show file tree
Hide file tree
Showing 47 changed files with 3,103 additions and 3,483 deletions.
21 changes: 18 additions & 3 deletions .kuzzlerc.sample
Original file line number Diff line number Diff line change
Expand Up @@ -373,11 +373,18 @@
},
"socketio": {
"enabled": true,
// value of Access-Control-Allow-Origin header to answer the upgrade request
// value of Access-Control-Allow-Origin header to answer the upgrade
// request
"origins": "*:*"
},
"websocket": {
"enabled": true
// * enabled:
// Set to true to enable WebSocket support
// * heartbeat:
// The time, in milliseconds, between the server's PING requests.
// Setting this value to 0 disables PING/PONG requests entirely.
"enabled": true,
"heartbeat": 60000
}
}
},
Expand Down Expand Up @@ -499,6 +506,13 @@
// Elasticsearch constructor options. Use this field to specify your Elasticsearch config options, this object
// is passed through to the Elasticsearch constructor and can contain all options/keys outlined here:
// https://www.elastic.co/guide/en/elasticsearch/client/javascript-api/current/configuration.html
// * dynamic:
// Default policy against new fields that are not referenced in the collection mapping.
// The value of this configuration will change Elasticsearch behavior on fields that are not declared in the collection mapping.
// - "true": Stores document and update the collection mapping with infered type
// - "false": Stores document and does not update the collection mapping (field are not indexed)
// - "strict": Rejects document
// See https://www.elastic.co/guide/en/elasticsearch/guide/current/dynamic-mapping.html
"db": {
"backend": "elasticsearch",
"aliases": ["storageEngine"],
Expand All @@ -525,7 +539,8 @@
"onUpdateConflictRetries": 0,
// Time to live of a paginated search
"scrollTTL": "15s"
}
},
"dynamic": "true"
}
},

Expand Down
145 changes: 87 additions & 58 deletions bin/kuzzle
Original file line number Diff line number Diff line change
Expand Up @@ -29,86 +29,115 @@
*/
const program = require('commander');

program
.version(require('../package.json').version)
.option('-p, --port <port>', 'Kuzzle port number', parseInt)
.option('-h, --host <host>', 'Kuzzle host')
.option('-U, --username <username>', 'Admin username')
.option('-P, --password <password>', 'Admin password')
.option('-d, --debug', 'make errors more verbose')
.option('-C, --noColors', 'do not use ANSI coloring');
program.version(require('../package.json').version).usage('[command] --help');

const bindOption = cmd =>
cmd
.option('-p, --port <port>', 'Kuzzle port number', parseInt)
.option('-h, --host <host>', 'Kuzzle host')
.option('-U, --username <username>', 'Admin username')
.option('-P, --password <password>', 'Admin password')
.option('-d, --debug', 'make errors more verbose')
.option('-C, --noColors', 'do not use ANSI coloring');

// $ kuzzle createFirstAdmin
program
.command('createFirstAdmin')
.description('create the first administrator user')
.action(require('./commands/createFirstAdmin'));
bindOption(
program
.command('createFirstAdmin')
.description('create the first administrator user')
.action(require('./commands/createFirstAdmin'))
);

// $ kuzzle clearCache
program
.command('clearCache')
.description('clear internal caches in Redis')
.action(require('./commands/resetCache'));
bindOption(
program
.command('clearCache')
.description('clear internal caches in Redis')
.action(require('./commands/resetCache'))
);

// $ kuzzle reset
program
.command('reset')
.description('reset all users, profiles, roles and documents validation specifications')
.option('--noint', 'non interactive mode')
.action(require('./commands/resetKuzzleData'));
bindOption(
program
.command('reset')
.description(
'reset all users, profiles, roles and documents validation specifications'
)
.option('--noint', 'non interactive mode')
.action(require('./commands/resetKuzzleData'))
);

// $ kuzzle resetSecurity
program
.command('resetSecurity')
.description('reset all users, profiles and roles')
.option('--noint', 'non interactive mode')
.action(require('./commands/resetSecurity'));
bindOption(
program
.command('resetSecurity')
.description('reset all users, profiles and roles')
.option('--noint', 'non interactive mode')
.action(require('./commands/resetSecurity'))
);

// $ kuzzle resetDatabase
program
.command('resetDatabase')
.description('remove all data stored on Kuzzle')
.option('--noint', 'non interactive mode')
.action(require('./commands/resetDatabase'));
bindOption(
program
.command('resetDatabase')
.description('remove all data stored on Kuzzle')
.option('--noint', 'non interactive mode')
.action(require('./commands/resetDatabase'))
);

// $ kuzzle shutdown
program
.command('shutdown')
.description('gracefully exits after processing remaining requests')
.action(require('./commands/shutdown'));
bindOption(
program
.command('shutdown')
.description('gracefully exits after processing remaining requests')
.action(require('./commands/shutdown'))
);

// $ kuzzle start
program
.command('start')
.description('start a Kuzzle instance')
.option(' --fixtures <file>', 'import data from file')
.option(' --mappings <file>', 'apply mappings from file')
.option(' --securities <file>', 'import roles, profiles and users from file')
.action(require('./commands/start'));
bindOption(
program
.command('start')
.description('start a Kuzzle instance')
.option(' --fixtures <file>', 'import data from file')
.option(' --mappings <file>', 'apply mappings from file')
.option(
' --securities <file>',
'import roles, profiles and users from file'
)
.action(require('./commands/start'))
);

// $ kuzzle dump
program
.command('dump')
.description('create a dump of current state of kuzzle')
.action(require('./commands/dump'));
bindOption(
program
.command('dump')
.description('create a dump of current state of kuzzle')
.action(require('./commands/dump'))
);

// $ kuzzle loadMappings
program
.command('loadMappings <file>')
.description('load database mappings into Kuzzle')
.action(require('./commands/loadMappings'));
bindOption(
program
.command('loadMappings <file>')
.description('load database mappings into Kuzzle')
.action(require('./commands/loadMappings'))
);

// $ kuzzle loadFixtures
program
.command('loadFixtures <file>')
.description('load database fixtures into Kuzzle')
.action(require('./commands/loadFixtures'));
bindOption(
program
.command('loadFixtures <file>')
.description('load database fixtures into Kuzzle')
.action(require('./commands/loadFixtures'))
);

// $ kuzzle loadSecurities
program
.command('loadSecurities <file>')
.description('load roles, profiles and users into Kuzzle')
.action(require('./commands/loadSecurities'));
bindOption(
program
.command('loadSecurities <file>')
.description('load roles, profiles and users into Kuzzle')
.action(require('./commands/loadSecurities'))
);

// Run user command
program.parse(process.argv);
Expand Down
3 changes: 2 additions & 1 deletion cucumber.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,5 +31,6 @@ module.exports = {
websocketEmbedded: '--fail-fast --tags "not @http" --world-parameters \'{"protocol": "websocket", "port": 7512}\'',
httpProxy: '--fail-fast --tags "not @realtime" --world-parameters \'{"protocol": "http", "port": 7513}\'',
socketioProxy: '--fail-fast --tags "not @http" --world-parameters \'{"protocol": "socketio", "port": 7513}\'',
websocketProxy: '--fail-fast --tags "not @http" --world-parameters \'{"protocol": "websocket", "port": 7513}\''
websocketProxy: '--fail-fast --tags "not @http" --world-parameters \'{"protocol": "websocket", "port": 7513}\'',
websocketNoRedis: '--fail-fast --tags "not @redis" --tags "not @http" --world-parameters \'{"protocol": "websocket", "port": 7512}\''
};
6 changes: 4 additions & 2 deletions default.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,8 @@ module.exports = {
origins: '*:*'
},
websocket: {
enabled: true
enabled: true,
heartbeat: 60000
}
}
},
Expand Down Expand Up @@ -252,7 +253,8 @@ module.exports = {
defaults: {
onUpdateConflictRetries: 0,
scrollTTL: '15s'
}
},
dynamic: 'true'
},
garbageCollector: {
cleanInterval: 86400000,
Expand Down
3 changes: 1 addition & 2 deletions docker-compose/scripts/run-dev.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@ elastic_host=${kuzzle_services__db__client__host:-http://elasticsearch:9200}

npm install --unsafe-perm
npm rebuild all --unsafe-perm
find -L node_modules/.bin -type f -exec chmod 776 {} \;
find node_modules/ -type d -exec chmod 755 {} \;
chmod -R 777 node_modules/
docker-compose/scripts/install-plugins.sh

echo "[$(date --rfc-3339 seconds)] - Waiting for elasticsearch to be available"
Expand Down
25 changes: 25 additions & 0 deletions features/kuzzle.feature
Original file line number Diff line number Diff line change
@@ -1,4 +1,26 @@
Feature: Kuzzle functional tests
Scenario: Create a collection
When I create a collection "kuzzle-test-index":"my-collection1"
Then The mapping properties field of "kuzzle-test-index":"my-collection1" is "the default value"
Then The mapping dynamic field of "kuzzle-test-index":"my-collection1" is "the default value"

Scenario: Update collection mapping: dynamic field
When I create a collection "kuzzle-test-index":"my-collection2"
And I update the mapping of "kuzzle-test-index":"my-collection2" with '{ "dynamic": "strict" }'
Then The mapping dynamic field of "kuzzle-test-index":"my-collection2" is "strict"

Scenario: Update collection mapping: properties field
When I create a collection "kuzzle-test-index":"my-collection3"
And I update the mapping of "kuzzle-test-index":"my-collection3" with '{ "properties": { "age": { "type": "integer" } } }'
Then The mapping dynamic field of "kuzzle-test-index":"my-collection3" is "the default value"
Then The mapping properties field of "kuzzle-test-index":"my-collection3" is '{ "age": { "type": "integer" } }'

Scenario: Update collection mapping: _meta field
When I create a collection "kuzzle-test-index":"my-collection4"
And I update the mapping of "kuzzle-test-index":"my-collection4" with '{ "_meta": { "nepali": "liia meh ry" } }'
And I update the mapping of "kuzzle-test-index":"my-collection4" with '{ "properties": { "age": { "type": "integer" } } }'
Then The mapping _meta field of "kuzzle-test-index":"my-collection4" is '{ "_meta": { "nepali": "liia meh ry" } }'

@http
Scenario: Send a request compressed with gzip
Given a request compressed with "gzip"
Expand Down Expand Up @@ -294,6 +316,8 @@ Feature: Kuzzle functional tests
Scenario: Count how many subscription on a room
Given A room subscription listening to "lastName" having value "Hopper" with socket "client1"
Given A room subscription listening to "lastName" having value "Hopper" with socket "client2"
# a little time for cluster replication
And I wait 0.1s
Then I can count "2" subscription

@realtime
Expand Down Expand Up @@ -350,6 +374,7 @@ Feature: Kuzzle functional tests
@realtime
Scenario: get list of subscriptions
Given A room subscription listening to "lastName" having value "Hopper"
And I wait 0.1s
And I get the list subscriptions
Then In my list there is a collection "kuzzle-collection-test" with 1 room and 1 subscriber

Expand Down
46 changes: 46 additions & 0 deletions features/step_definitions/collections.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ const
When,
Then
} = require('cucumber'),
should = require('should'),
stepUtils = require('../support/stepUtils');

When(/^I list "([^"]*)" data collections(?: in index "([^"]*)")?$/, function (type, index, callback) {
Expand Down Expand Up @@ -84,3 +85,48 @@ When(/I check if collection "(.*?)" exists on index "(.*?)"$/, function (collect
return stepUtils.getReturn.call(this, 'collectionExists', index, collection, cb);
});

When('I create a collection {string}:{string}', function (index, collection) {
return this.api.createCollection(index, collection);
});

Then('The mapping dynamic field of {string}:{string} is {string}', function (index, collection, dynamicValue) {
return this.api.getCollectionMapping(index, collection)
.then(({ result }) => {
const expectedValue = dynamicValue === 'the default value' ? this.kuzzleConfig.services.db.dynamic.toString() : dynamicValue;

should(result[index].mappings[collection].dynamic)
.not.be.undefined()
.be.eql(expectedValue);
});
});

When('I update the mapping of {string}:{string} with {string}', function (index, collection, rawMapping) {
const mapping = JSON.parse(rawMapping);

return this.api.updateMapping(index, collection, mapping);
});

Then('The mapping properties field of {string}:{string} is {string}', function (index, collection, rawMapping) {
const includeKuzzleMeta = rawMapping === 'the default value';

return this.api.getCollectionMapping(index, collection, includeKuzzleMeta)
.then(({ result }) => {
const expectedValue = rawMapping === 'the default value' ? this.kuzzleConfig.services.db.commonMapping : JSON.parse(rawMapping);

should(result[index].mappings[collection].properties)
.not.be.undefined()
.be.eql(expectedValue);
});
});

Then('The mapping _meta field of {string}:{string} is {string}', function (index, collection, rawMapping) {
const mapping = JSON.parse(rawMapping);

return this.api.getCollectionMapping(index, collection)
.then(({ result }) => {

should(result[index].mappings[collection]._meta)
.not.be.undefined()
.be.eql(mapping._meta);
});
});
2 changes: 1 addition & 1 deletion features/step_definitions/notifications.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ Then(/^I should receive a ?(.*?) notification with field ?(.*?) equal to "([^"]*
} else {
callbackAsync('No notification received');
}
}, 20);
}, 100);
};

async.retry(20, main, err => {
Expand Down
2 changes: 1 addition & 1 deletion features/step_definitions/wait.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ const
Then
} = require('cucumber');

Then(/^I wait ([\d]*?)s$/, function (time, callback) {
Then(/^I wait ([\d.]*?)s$/, function (time, callback) {
setTimeout(function () {
callback();
}, time*1000);
Expand Down
Loading

0 comments on commit 3d491d0

Please sign in to comment.