Skip to content

Commit

Permalink
API-668 Document and Validate Properties (#1001)
Browse files Browse the repository at this point in the history
  • Loading branch information
srknzl authored Aug 17, 2021
1 parent cb07e21 commit 19cc638
Show file tree
Hide file tree
Showing 142 changed files with 219 additions and 245 deletions.
61 changes: 33 additions & 28 deletions DOCUMENTATION.md

Large diffs are not rendered by default.

41 changes: 29 additions & 12 deletions scripts/test-runner.js
Original file line number Diff line number Diff line change
Expand Up @@ -128,9 +128,22 @@ const startRC = async () => {
throw `Could not reach to Hazelcast Remote Controller (127.0.0.1:9701) after trying ${retryCount} times.`;
};

const shutdownProcesses = () => {
console.log('Stopping remote controller and test processes...');
shutdownRC();
const shutdown = async () => {
if (testProcess && testProcess.exitCode === null) {
stopTestProcess();
}

if (rcProcess && rcProcess.exitCode === null) {
await stopRC();
}

if (testProcess && testProcess.exitCode !== null) {
process.exit(testProcess.exitCode);
}
};

const stopTestProcess = () => {
console.log('Stopping test process');
if (ON_WINDOWS) {
spawnSync('taskkill', ['/pid', testProcess.pid, '/f', '/t']); // simple sigkill not enough on windows
} else {
Expand All @@ -140,7 +153,8 @@ const shutdownProcesses = () => {
}
};

const shutdownRC = async () => {
const stopRC = async () => {
console.log('Stopping cluster and remote controller');
if (cluster) {
const RC = getRC();
await RC.terminateCluster(cluster.id);
Expand Down Expand Up @@ -206,11 +220,11 @@ if (!fs.existsSync('./lib')) {
// If running unit test, no need to start rc.
if (testType === 'unit') {
console.log(`Running unit tests... Test command: ${testCommand}`);
spawnSync(testCommand, [], {
const subprocess = spawnSync(testCommand, [], {
stdio: ['ignore', 'inherit', 'inherit'],
shell: true
});
process.exit(0);
process.exit(subprocess.status);
}

// For other tests, download rc files if needed.
Expand All @@ -221,9 +235,9 @@ try {
throw err;
}

process.on('SIGINT', shutdownProcesses);
process.on('SIGTERM', shutdownProcesses);
process.on('SIGHUP', shutdownProcesses);
process.on('SIGINT', shutdown);
process.on('SIGTERM', shutdown);
process.on('SIGHUP', shutdown);

startRC().then(async () => {
console.log('Hazelcast Remote Controller is started!');
Expand All @@ -233,17 +247,20 @@ startRC().then(async () => {
stdio: ['ignore', 'inherit', 'inherit'],
shell: true
});
testProcess.on('exit', shutdownRC);
testProcess.on('exit', shutdown);
} else if (testType === 'check-code-samples') {
const RC = getRC();
cluster = await RC.createClusterKeepClusterName(null, DEV_CLUSTER_CONFIG);
let exitCode = 0;
try {
await codeSampleChecker.main(cluster);
} catch (e) {
console.error(e);
process.exit(1);
exitCode = 1;
} finally {
await shutdownRC();
await shutdown();
// testProcess is undefined `shutdown` won't exit the process, so we exit with non-zero error code
process.exit(exitCode);
}
}
}).catch(err => {
Expand Down
8 changes: 4 additions & 4 deletions src/config/Config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,10 @@ export interface ClientConfig {

}

/** @internal */
/**
* If you are adding a new property, don't forget to add its validation in `handleProperties`.
* @internal
*/
const DEFAULT_PROPERTIES: Properties = {
'hazelcast.client.heartbeat.interval': 5000,
'hazelcast.client.heartbeat.timeout': 60000,
Expand All @@ -179,9 +182,6 @@ const DEFAULT_PROPERTIES: Properties = {
'hazelcast.discovery.public.ip.enabled': null,
};

/** @internal */
export const PROPERTY_SET = new Set(Object.keys(DEFAULT_PROPERTIES));

/** @internal */
export class ClientConfigImpl implements ClientConfig {
properties: Properties = {...DEFAULT_PROPERTIES}; // Create a new object
Expand Down
75 changes: 71 additions & 4 deletions src/config/ConfigBuilder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import {
tryGetNumber,
tryGetString
} from '../util/Util';
import {ClientConfig, ClientConfigImpl, PROPERTY_SET} from './Config';
import {ClientConfig, ClientConfigImpl} from './Config';
import {EvictionPolicy} from './EvictionPolicy';
import {FlakeIdGeneratorConfigImpl} from './FlakeIdGeneratorConfig';
import {InMemoryFormat} from './InMemoryFormat';
Expand All @@ -35,6 +35,7 @@ import {ReliableTopicConfigImpl} from './ReliableTopicConfig';
import {JsonStringDeserializationPolicy} from './JsonStringDeserializationPolicy';
import {ReconnectMode} from './ConnectionStrategyConfig';
import {LoadBalancerType} from './LoadBalancerConfig';
import {LogLevel} from '../logging';

/**
* Responsible for user-defined config validation. Builds the effective config with necessary defaults.
Expand Down Expand Up @@ -223,10 +224,76 @@ export class ConfigBuilder {

private handleProperties(jsonObject: any): void {
for (const key in jsonObject) {
if (!PROPERTY_SET.has(key)) {
throw new RangeError(`Unexpected property '${key}' is passed to the Hazelcast Client`);
let value = jsonObject[key];
try {
switch (key) {
case 'hazelcast.client.heartbeat.interval':
value = tryGetNumber(value);
break;
case 'hazelcast.client.heartbeat.timeout':
value = tryGetNumber(value);
break;
case 'hazelcast.client.invocation.retry.pause.millis':
value = tryGetNumber(value);
break;
case 'hazelcast.client.invocation.timeout.millis':
value = tryGetNumber(value);
break;
case 'hazelcast.client.internal.clean.resources.millis':
value = tryGetNumber(value);
break;
case 'hazelcast.client.cloud.url':
value = tryGetString(value);
break;
case 'hazelcast.client.statistics.enabled':
value = tryGetBoolean(value);
break;
case 'hazelcast.client.statistics.period.seconds':
value = tryGetNumber(value);
break;
case 'hazelcast.invalidation.reconciliation.interval.seconds':
value = tryGetNumber(value);
break;
case 'hazelcast.invalidation.max.tolerated.miss.count':
value = tryGetNumber(value);
break;
case 'hazelcast.invalidation.min.reconciliation.interval.seconds':
value = tryGetNumber(value);
break;
case 'hazelcast.logging.level':
tryGetEnum(LogLevel, value);
break;
case 'hazelcast.client.autopipelining.enabled':
value = tryGetBoolean(value);
break;
case 'hazelcast.client.autopipelining.threshold.bytes':
value = tryGetNumber(value);
break;
case 'hazelcast.client.socket.no.delay':
value = tryGetBoolean(value);
break;
case 'hazelcast.client.shuffle.member.list':
value = tryGetBoolean(value);
break;
case 'hazelcast.client.operation.backup.timeout.millis':
value = tryGetNumber(value);
break;
case 'hazelcast.client.operation.fail.on.indeterminate.state':
value = tryGetBoolean(value);
break;
case 'hazelcast.discovery.public.ip.enabled':
if (value !== null && typeof value !== 'boolean') {
throw new RangeError(`${value} is not null or a boolean.`);
}
break;
default:
throw new RangeError(`Unexpected property '${key}' is passed to the Hazelcast Client`);
}
} catch (e) {
throw new RangeError(`Property validation error: Property: ${key}, value: ${value}. Error: ${e}`);
}
this.effectiveConfig.properties[key] = jsonObject[key];

this.effectiveConfig.properties[key] = value;
}
}

Expand Down
3 changes: 2 additions & 1 deletion test/.eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@
"max-len": ["warn", 130],
"mocha/prefer-arrow-callback": ["error", {
"allowNamedFunctions": true
}]
}],
"padded-blocks": ["error", "never"]
},
"parserOptions": {
"ecmaVersion": 11
Expand Down
2 changes: 0 additions & 2 deletions test/TestUtil.js
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,6 @@ exports.randomString = function (length) {
};

class CountingMembershipListener {

constructor(expectedAdds, expectedRemoves) {
this.adds = 0;
this.expectedAdds = expectedAdds;
Expand Down Expand Up @@ -230,7 +229,6 @@ class CountingMembershipListener {
}
this._resolve();
}

}

exports.CountingMembershipListener = CountingMembershipListener;
Expand Down
1 change: 0 additions & 1 deletion test/integration/ClientShutdownTest.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ const { ConnectionManager } = require('../../lib/network/ConnectionManager');
const { InvocationService } = require('../../lib/invocation/InvocationService');

describe('ClientShutdownTest', function () {

let cluster;

afterEach(async function () {
Expand Down
1 change: 0 additions & 1 deletion test/integration/ConnectionManagerTest.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ const { promiseWaitMilliseconds } = require('../TestUtil');
* Basic tests for `ConnectionManager`.
*/
describe('ConnectionManagerTest', function () {

let cluster;
let client;
let server;
Expand Down
1 change: 0 additions & 1 deletion test/integration/ConnectionManagerTranslateTest.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ const { EndpointQualifier, ProtocolType } = require('../../lib/core/EndpointQual
* Tests address translation done by `ConnectionManager`.
*/
describe('ConnectionManagerTranslateTest', function () {

const PROPERTY_DISCOVERY_PUBLIC_IP_ENABLED = 'hazelcast.discovery.public.ip.enabled';
const REACHABLE_HOST = '127.0.0.1';
const UNREACHABLE_HOST = '192.168.0.1';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ const RC = require('../RC');
const { Client } = require('../../../');

describe('AutoPipeliningDisabledTest', function () {

let cluster;
let client;
let map;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ const { ClientLocalBackupListenerCodec } = require('../../../lib/codec/ClientLoc
* so there is no need for additional member side configuration.
*/
describe('ClientBackupAcksTest', function () {

let cluster;
let client;

Expand Down
2 changes: 0 additions & 2 deletions test/integration/backward_compatible/ClientFailoverTest.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,6 @@ function createClientConfig({ clusterName, lifecycleListener, connectTimeoutMs }
* Tests blue/green failover support for OSS.
*/
describe('ClientFailoverTest - community', function () {

let cluster1;
let cluster2;

Expand Down Expand Up @@ -101,7 +100,6 @@ describe('ClientFailoverTest - community', function () {
* Tests blue/green failover support for EE.
*/
describe('ClientFailoverTest - enterprise', function () {

let cluster1;
let member1;
let cluster2;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ const TestUtil = require('../../TestUtil');
* This test assumes cluster with a single member.
*/
describe('ClientHotRestartEventTest', function () {

let client;
let cluster;

Expand Down
2 changes: 0 additions & 2 deletions test/integration/backward_compatible/ClientLabelTest.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ const RC = require('./../RC');
const { Client } = require('../../../');

describe('ClientLabelTest', function () {

let cluster;
let client;

Expand Down Expand Up @@ -50,5 +49,4 @@ describe('ClientLabelTest', function () {
expect(res.result).to.not.be.null;
expect(res.result.toString()).to.equal('testLabel');
});

});
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ const TestUtil = require('../../TestUtil');
* Advanced tests for reconnection to cluster scenarios.
*/
describe('ClientReconnectAdvancedTest', function () {

let cluster;
let client;

Expand Down Expand Up @@ -95,7 +94,6 @@ describe('ClientReconnectAdvancedTest', function () {
const member = members[0];
expect(member.uuid.toString()).to.be.equal(newMember.uuid);
});

}

async function testListenersAfterClientDisconnected(memberAddress, clientAddress) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ const { markClientVersionAtLeast } = require('../../TestUtil');
* Basic tests for reconnection to cluster scenarios.
*/
describe('ClientReconnectTest', function () {

let cluster;
let client;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ const {
} = require('../../../');

describe('ClientRedoEnabledTest', function () {

let cluster;
let client;

Expand Down
1 change: 0 additions & 1 deletion test/integration/backward_compatible/ClusterServiceTest.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ const RC = require('../RC');
const { Client } = require('../../../');

describe('ClusterServiceTest', function () {

let cluster;
let member1;
let client;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ const { LifecycleState } = require('../../../lib/LifecycleService');
const TestUtil = require('../../TestUtil');

describe('ConnectionStrategyTest', function () {

let cluster;
let client;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ const { Client } = require('../../../');
const TestUtil = require('../../TestUtil');

describe('DistributedObjectsTest', function () {

let cluster;
let client;

Expand Down
3 changes: 0 additions & 3 deletions test/integration/backward_compatible/HazelcastClientTest.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ const { deferredPromise } = require('../../../lib/util/Util');
const TestUtil = require('../../TestUtil');

class ManagedObjects {

constructor() {
this.managedObjects = [];
}
Expand Down Expand Up @@ -53,7 +52,6 @@ class ManagedObjects {
});
return deferred.promise;
}

}

const dummyConfig = {
Expand All @@ -75,7 +73,6 @@ const configParams = [

configParams.forEach((cfg) => {
describe('HazelcastClientTest[smart=' + cfg.network.smartRouting + ']', function () {

let cluster;
let client;
let managed;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ const { Client } = require('../../../');
const { deferredPromise } = require('../../../lib/util/Util');

describe('InitialMembershipListenerTest', function () {

let cluster;
let initialMember;
let client;
Expand Down
Loading

0 comments on commit 19cc638

Please sign in to comment.