infinispan 0.8.0 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Jenkinsfile-release +1 -1
- package/README.md +31 -907
- package/documentation/asciidoc/stories/assembly_client_usage_examples.adoc +10 -0
- package/documentation/asciidoc/stories/assembly_installation_configuration.adoc +20 -0
- package/documentation/asciidoc/titles/js_client.asciidoc +28 -0
- package/documentation/asciidoc/titles/stories.adoc +5 -0
- package/documentation/asciidoc/topics/attributes/community-attributes.adoc +8 -0
- package/documentation/asciidoc/topics/attributes/downstream-attributes.adoc +2 -0
- package/documentation/asciidoc/topics/code_examples/authentication-digest.js +12 -0
- package/documentation/asciidoc/topics/code_examples/authentication-external.js +15 -0
- package/documentation/asciidoc/topics/code_examples/authentication-oauthbearer.js +10 -0
- package/documentation/asciidoc/topics/code_examples/authentication-plain.js +11 -0
- package/documentation/asciidoc/topics/code_examples/authentication-scram.js +11 -0
- package/documentation/asciidoc/topics/code_examples/await-multiple-entries.js +36 -0
- package/documentation/asciidoc/topics/code_examples/await-single-entries.js +29 -0
- package/documentation/asciidoc/topics/code_examples/conditional-operations.js +57 -0
- package/documentation/asciidoc/topics/code_examples/connection-multiple-servers.js +23 -0
- package/documentation/asciidoc/topics/code_examples/connection-xsite-cluster-switch.js +39 -0
- package/documentation/asciidoc/topics/code_examples/connection-xsite.js +13 -0
- package/documentation/asciidoc/topics/code_examples/data-types.js +30 -0
- package/documentation/asciidoc/topics/code_examples/encryption-crypto-store.js +11 -0
- package/documentation/asciidoc/topics/code_examples/encryption-private-key.js +13 -0
- package/documentation/asciidoc/topics/code_examples/encryption-sni-hostname.js +9 -0
- package/documentation/asciidoc/topics/code_examples/encryption-trust-certs.js +8 -0
- package/documentation/asciidoc/topics/code_examples/ephemeral-data.js +52 -0
- package/documentation/asciidoc/topics/code_examples/hello-world.js +42 -0
- package/documentation/asciidoc/topics/code_examples/key-value-converter.js +67 -0
- package/documentation/asciidoc/topics/code_examples/logging-configuration.js +2 -0
- package/documentation/asciidoc/topics/code_examples/multiple-entries.js +64 -0
- package/documentation/asciidoc/topics/code_examples/register-event-listener.js +64 -0
- package/documentation/asciidoc/topics/code_examples/sample-script-execute.js +33 -0
- package/documentation/asciidoc/topics/code_examples/sample-script.js +3 -0
- package/documentation/asciidoc/topics/code_examples/single-entries.js +49 -0
- package/documentation/asciidoc/topics/config_examples/logging.json +14 -0
- package/documentation/asciidoc/topics/proc_configuring_authentication.adoc +16 -0
- package/documentation/asciidoc/topics/proc_configuring_connections.adoc +25 -0
- package/documentation/asciidoc/topics/proc_configuring_connections_xsite.adoc +18 -0
- package/documentation/asciidoc/topics/proc_configuring_data_formats.adoc +30 -0
- package/documentation/asciidoc/topics/proc_configuring_encryption.adoc +15 -0
- package/documentation/asciidoc/topics/proc_configuring_logging.adoc +28 -0
- package/documentation/asciidoc/topics/proc_installing_clients.adoc +58 -0
- package/documentation/asciidoc/topics/proc_switching_clusters.adoc +17 -0
- package/documentation/asciidoc/topics/ref_authentication_mechanisms.adoc +68 -0
- package/documentation/asciidoc/topics/ref_client_usage.adoc +116 -0
- package/documentation/asciidoc/topics/ref_encryption.adoc +71 -0
- package/lib/codec.js +153 -2
- package/lib/infinispan.js +33 -1
- package/lib/io.js +23 -16
- package/lib/protocols.js +165 -68
- package/lib/protostream/message-wrapping.proto +134 -0
- package/lib/protostream/query.proto +122 -0
- package/lib/sasl/bitops.js +24 -0
- package/lib/sasl/digest.js +188 -0
- package/lib/sasl/external.js +54 -0
- package/lib/sasl/factory.js +71 -0
- package/lib/sasl/oauthbearer.js +63 -0
- package/lib/sasl/plain.js +65 -0
- package/lib/sasl/scram.js +135 -0
- package/lib/utils.js +1 -1
- package/memory-profiling/helper.js +9 -0
- package/memory-profiling/infinispan_memory_many_get.js +1 -3
- package/memory-profiling/infinispan_memory_one_get.js +6 -4
- package/package.json +7 -13
- package/run-servers.sh +17 -8
- package/run-testsuite.sh +1 -1
- package/smoke-tests.sh +8 -2
- package/spec/codec_spec.js +7 -7
- package/spec/configs/infinispan-clustered.xml +17 -14
- package/spec/configs/infinispan-ssl.xml +25 -22
- package/spec/configs/infinispan-xsite-EARTH.xml +17 -14
- package/spec/configs/infinispan-xsite-MOON.xml +14 -11
- package/spec/configs/infinispan.xml +22 -13
- package/spec/infinispan_auth_spec.js +16 -37
- package/spec/protostream_spec.js +237 -0
- package/spec/utils/testing.js +1 -3
- package/lib/bitops.js +0 -26
- package/lib/scram.js +0 -116
package/lib/protocols.js
CHANGED
|
@@ -3,16 +3,22 @@
|
|
|
3
3
|
(function() {
|
|
4
4
|
|
|
5
5
|
var _ = require('underscore');
|
|
6
|
-
|
|
6
|
+
|
|
7
7
|
var f = require('./functional');
|
|
8
8
|
var u = require('./utils');
|
|
9
9
|
var codec = require('./codec');
|
|
10
10
|
|
|
11
11
|
var logger = u.logger('protocols');
|
|
12
|
-
var
|
|
13
|
-
var factory = new
|
|
14
|
-
|
|
15
|
-
|
|
12
|
+
var Factory = require('./sasl/factory');
|
|
13
|
+
var factory = new Factory();
|
|
14
|
+
factory.use(require('./sasl/plain'));
|
|
15
|
+
factory.use(require('./sasl/external'));
|
|
16
|
+
factory.use('DIGEST-MD5', require('./sasl/digest'));
|
|
17
|
+
factory.use('SCRAM-SHA-1', require('./sasl/scram'));
|
|
18
|
+
factory.use('SCRAM-SHA-256', require('./sasl/scram'));
|
|
19
|
+
factory.use('SCRAM-SHA-384', require('./sasl/scram'));
|
|
20
|
+
factory.use('SCRAM-SHA-512', require('./sasl/scram'));
|
|
21
|
+
factory.use('OAUTHBEARER', require('./sasl/oauthbearer'));
|
|
16
22
|
|
|
17
23
|
var INFINITE_LIFESPAN = 0x01, INFINITE_MAXIDLE = 0x02; // Duration flag masks
|
|
18
24
|
var MAGIC = 0xA0;
|
|
@@ -49,6 +55,7 @@
|
|
|
49
55
|
var DECODE_TIMESTAMP = f.actions([codec.decodeLong(), codec.decodeVInt()], codec.allDecoded(2));
|
|
50
56
|
var DECODE_UBYTE = f.actions([codec.decodeUByte()], codec.lastDecoded);
|
|
51
57
|
var DECODE_VINT = f.actions([codec.decodeVInt()], codec.lastDecoded);
|
|
58
|
+
var DECODE_SHORT = f.actions([codec.decodeShort()], codec.lastDecoded);
|
|
52
59
|
|
|
53
60
|
function hasOpt(opts, name) { return _.has(opts, name) && f.truthy(opts[name]); }
|
|
54
61
|
function hasOptPrev(opts) { return hasOpt(opts, 'previous'); }
|
|
@@ -111,6 +118,11 @@
|
|
|
111
118
|
return [outer.encodeMediaKey(k)]; // key
|
|
112
119
|
}
|
|
113
120
|
},
|
|
121
|
+
encodeQuery: function (q) {
|
|
122
|
+
return function() {
|
|
123
|
+
return [codec.encodeQuery(q)]; // query
|
|
124
|
+
}
|
|
125
|
+
},
|
|
114
126
|
encodeKeyVersion: function (k, version) {
|
|
115
127
|
var outer = this;
|
|
116
128
|
return function() {
|
|
@@ -355,6 +367,12 @@
|
|
|
355
367
|
return decodeObject(header, bytebuf, decodeAction);
|
|
356
368
|
}
|
|
357
369
|
},
|
|
370
|
+
decodeQuery: function() {
|
|
371
|
+
return function(header, bytebuf) {
|
|
372
|
+
var decodeAction = f.actions([f.partial2(codec.decodeQuery,ProtostreamType.lookupProtostreamTypeById,ProtobufRoot.findRootByTypeName)()],codec.lastDecoded);
|
|
373
|
+
return decodeObject(header, bytebuf, decodeAction);
|
|
374
|
+
}
|
|
375
|
+
},
|
|
358
376
|
decodeWithMeta: function() {
|
|
359
377
|
var decoderValue = decoderMedia(this.valueMediaType);
|
|
360
378
|
return function(header, bytebuf) {
|
|
@@ -743,6 +761,7 @@
|
|
|
743
761
|
return f.dispatch(
|
|
744
762
|
f.isa('application/json', encoder(2, encoderJson, decoderJson()))
|
|
745
763
|
, f.isa('text/plain', encoder(13, encoderString, decoderString()))
|
|
764
|
+
, f.isa('application/x-protostream', encoder(12, encoderProtobuf, decoderProtobuf()))
|
|
746
765
|
)(mediaType);
|
|
747
766
|
}
|
|
748
767
|
|
|
@@ -762,6 +781,14 @@
|
|
|
762
781
|
return codec.decodeString();
|
|
763
782
|
}
|
|
764
783
|
|
|
784
|
+
function encoderProtobuf(message){
|
|
785
|
+
return codec.encodeProtobuf(message,ProtostreamType.lookupProtostreamTypeByName);
|
|
786
|
+
}
|
|
787
|
+
|
|
788
|
+
function decoderProtobuf(){
|
|
789
|
+
return f.partial2(codec.decodeProtobuf,ProtostreamType.lookupProtostreamTypeById,ProtobufRoot.findRootByTypeName)();
|
|
790
|
+
}
|
|
791
|
+
|
|
765
792
|
function encoder(id, mediaEncoder, mediaDecoder) {
|
|
766
793
|
return function() {
|
|
767
794
|
return [
|
|
@@ -867,9 +894,9 @@
|
|
|
867
894
|
if (keyMediaType.continue) {
|
|
868
895
|
var valueMediaType = decodeServerMediaType(bytebuf);
|
|
869
896
|
if (valueMediaType.continue)
|
|
897
|
+
|
|
870
898
|
return {result: undefined, continue: true};
|
|
871
899
|
}
|
|
872
|
-
|
|
873
900
|
return {continue: false};
|
|
874
901
|
}
|
|
875
902
|
}
|
|
@@ -877,8 +904,6 @@
|
|
|
877
904
|
|
|
878
905
|
var SASLMixin = (function() {
|
|
879
906
|
var logger = u.logger('sasl');
|
|
880
|
-
var currentAuthMech = '';
|
|
881
|
-
var challengeNum = 0;
|
|
882
907
|
return {
|
|
883
908
|
decodeAuthMech: function(header, bytebuf) {
|
|
884
909
|
var authMechsCount = DECODE_VINT(bytebuf);
|
|
@@ -894,82 +919,117 @@
|
|
|
894
919
|
logger.tracef(authMechs);
|
|
895
920
|
return {result: authMechs, continue: true};
|
|
896
921
|
},
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
logger.debugf(authOpts);
|
|
922
|
+
sasl: function(authOpts, holder) {
|
|
923
|
+
logger.tracef(authOpts);
|
|
900
924
|
return function () {
|
|
901
925
|
var response;
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
var scramSecResp = scramSha1.challenge(challenge)
|
|
927
|
-
.response({username: authOpts.userName, password: authOpts.password});
|
|
928
|
-
|
|
929
|
-
return [ codec.encodeString('SCRAM-SHA-1'), codec.encodeString(scramSecResp)];
|
|
930
|
-
case 'DIGEST-MD5':
|
|
931
|
-
logger.tracef('Try auth with DIGEST');
|
|
932
|
-
currentAuthMech = 'DIGEST-MD5';
|
|
933
|
-
if (challenge == undefined) {
|
|
934
|
-
// initial challenge
|
|
935
|
-
logger.tracef('Initial DIGEST challenge');
|
|
936
|
-
challengeNum = 1;
|
|
937
|
-
return [codec.encodeString('DIGEST-MD5'), codec.encodeString('')];
|
|
938
|
-
}
|
|
939
|
-
var digestResponse = digest.challenge(challenge)
|
|
940
|
-
.response({ username: authOpts.userName,
|
|
941
|
-
password: authOpts.password});
|
|
942
|
-
return [codec.encodeString('DIGEST-MD5'), codec.encodeString(digestResponse)];
|
|
943
|
-
default:
|
|
944
|
-
throw new Error('Unsupported auth mechanism mech [' + authOpts.saslMechanism) + ']';
|
|
926
|
+
if (holder.mech == undefined) {
|
|
927
|
+
holder.mech = factory.create([authOpts.saslMechanism]);
|
|
928
|
+
if (holder.mech.clientFirst) {
|
|
929
|
+
response = holder.mech.response({
|
|
930
|
+
username: authOpts.userName,
|
|
931
|
+
password: authOpts.password,
|
|
932
|
+
mechanism: authOpts.saslMechanism,
|
|
933
|
+
qop: 'auth',
|
|
934
|
+
serviceType: 'hotrod',
|
|
935
|
+
host: 'infinispan'
|
|
936
|
+
});
|
|
937
|
+
} else {
|
|
938
|
+
response = '';
|
|
939
|
+
}
|
|
940
|
+
} else {
|
|
941
|
+
logger.tracef("SASL server challenge response [%s]", holder.mech.name);
|
|
942
|
+
response = holder.mech.challenge(holder.challenge).response({
|
|
943
|
+
username: authOpts.userName,
|
|
944
|
+
password: authOpts.password,
|
|
945
|
+
mechanism: authOpts.saslMechanism,
|
|
946
|
+
qop: 'auth',
|
|
947
|
+
serviceType: 'hotrod',
|
|
948
|
+
host: 'infinispan'
|
|
949
|
+
});
|
|
945
950
|
}
|
|
951
|
+
logger.tracef("SASL client response [%s]", holder.mech.name);
|
|
952
|
+
return [codec.encodeString(authOpts.saslMechanism), codec.encodeString(response)];
|
|
946
953
|
}
|
|
947
954
|
},
|
|
948
955
|
decodeSasl: function(header, bytebuf) {
|
|
949
956
|
var authDone = DECODE_UBYTE(bytebuf);
|
|
950
957
|
if(authDone == 1) {
|
|
951
|
-
logger.tracef('
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
return {result: {
|
|
958
|
+
logger.tracef('SASL authentication complete');
|
|
959
|
+
return {result: {response: DECODE_UBYTE(bytebuf)}, continue: true};
|
|
960
|
+
} else {
|
|
961
|
+
return {result: {response: DECODE_STRING(bytebuf)}, continue: true};
|
|
955
962
|
}
|
|
963
|
+
}
|
|
964
|
+
}
|
|
965
|
+
}());
|
|
956
966
|
|
|
957
|
-
|
|
967
|
+
var Ping29Mixin = (function() {
|
|
968
|
+
return {
|
|
969
|
+
decodePingResponse: function(header,bytebuf){
|
|
970
|
+
logger.debugf("header and bytebuf %s %s",header,bytebuf);
|
|
971
|
+
return MediaTypesMixin.decodeServerMediaTypes(header,bytebuf);
|
|
972
|
+
}
|
|
973
|
+
}
|
|
974
|
+
}());
|
|
958
975
|
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
976
|
+
var Ping30Mixin = (function() {
|
|
977
|
+
return {
|
|
978
|
+
decodePingResponse: function(header,bytebuf){
|
|
979
|
+
var serverMediaTypes= MediaTypesMixin.decodeServerMediaTypes(header,bytebuf);
|
|
980
|
+
var version=DECODE_UBYTE(bytebuf);
|
|
981
|
+
var opCount=DECODE_VINT(bytebuf);
|
|
982
|
+
var opRequestCodes=[];
|
|
983
|
+
for(let i=0;i<opCount;i++){
|
|
984
|
+
opRequestCodes.push(DECODE_SHORT(bytebuf));
|
|
962
985
|
}
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
986
|
+
return serverMediaTypes;
|
|
987
|
+
}
|
|
988
|
+
}
|
|
989
|
+
}());
|
|
990
|
+
|
|
991
|
+
var ProtostreamType = (function() {
|
|
992
|
+
var protostreamTypes=[];
|
|
993
|
+
return {
|
|
994
|
+
registerProtostreamType: function(protostreamTypeName,protostreamDescriptorId){
|
|
995
|
+
var protostreamType={
|
|
996
|
+
protostreamTypeName,
|
|
997
|
+
protostreamDescriptorId
|
|
998
|
+
};
|
|
999
|
+
protostreamTypes.push(protostreamType);
|
|
1000
|
+
return protostreamType;
|
|
1001
|
+
},
|
|
1002
|
+
lookupProtostreamTypeByName: function (protostreamTypeName) {
|
|
1003
|
+
return _.find(protostreamTypes,function(protostreamType){
|
|
1004
|
+
return _.isEqual(protostreamType.protostreamTypeName,protostreamTypeName)
|
|
1005
|
+
}).protostreamDescriptorId;
|
|
1006
|
+
},
|
|
1007
|
+
lookupProtostreamTypeById: function(protostreamDescriptorId){
|
|
1008
|
+
return _.find(protostreamTypes,function(protostreamType){
|
|
1009
|
+
return _.isEqual(protostreamType.protostreamDescriptorId,protostreamDescriptorId)
|
|
1010
|
+
}).protostreamTypeName;
|
|
1011
|
+
}
|
|
1012
|
+
}
|
|
1013
|
+
}());
|
|
1014
|
+
|
|
1015
|
+
var ProtobufRoot = (function() {
|
|
1016
|
+
var protobufRoot;
|
|
1017
|
+
return {
|
|
1018
|
+
registerProtostreamRoot: function(root){
|
|
1019
|
+
protobufRoot=root;
|
|
1020
|
+
return protobufRoot;
|
|
1021
|
+
},
|
|
1022
|
+
findRootByTypeName: function(typeName){
|
|
1023
|
+
try{
|
|
1024
|
+
var root= protobufRoot.lookupType(typeName);
|
|
1025
|
+
return root;
|
|
1026
|
+
}catch(err){
|
|
1027
|
+
throw new Error("Protobuf root not found");
|
|
967
1028
|
}
|
|
968
|
-
// continue for the next challenge
|
|
969
|
-
return {result: 'auth error', continue: false};
|
|
970
1029
|
}
|
|
971
1030
|
}
|
|
972
1031
|
}());
|
|
1032
|
+
|
|
973
1033
|
|
|
974
1034
|
function Protocol(v, clientOpts) {
|
|
975
1035
|
this.version = v;
|
|
@@ -991,6 +1051,10 @@
|
|
|
991
1051
|
Protocol.call(this, 29, clientOpts);
|
|
992
1052
|
};
|
|
993
1053
|
|
|
1054
|
+
var Protocol30 = function(clientOpts) {
|
|
1055
|
+
Protocol.call(this, 30, clientOpts);
|
|
1056
|
+
};
|
|
1057
|
+
|
|
994
1058
|
// TODO: Missing operations, just for reference
|
|
995
1059
|
var IdsMixin = {
|
|
996
1060
|
queryId: function() { return 0x1F },
|
|
@@ -1006,6 +1070,8 @@
|
|
|
1006
1070
|
, ListenersMixin
|
|
1007
1071
|
, NoListenerInterestsMixin
|
|
1008
1072
|
, NoMediaTypesMixin
|
|
1073
|
+
, ProtostreamType
|
|
1074
|
+
, ProtobufRoot
|
|
1009
1075
|
);
|
|
1010
1076
|
|
|
1011
1077
|
_.extend(Protocol25.prototype
|
|
@@ -1017,6 +1083,8 @@
|
|
|
1017
1083
|
, NoListenerInterestsMixin
|
|
1018
1084
|
, IteratorMixin
|
|
1019
1085
|
, NoMediaTypesMixin
|
|
1086
|
+
, ProtostreamType
|
|
1087
|
+
, ProtobufRoot
|
|
1020
1088
|
);
|
|
1021
1089
|
|
|
1022
1090
|
_.extend(Protocol29.prototype
|
|
@@ -1029,6 +1097,9 @@
|
|
|
1029
1097
|
, IteratorMixin
|
|
1030
1098
|
, MediaTypesMixin
|
|
1031
1099
|
, SASLMixin
|
|
1100
|
+
, Ping29Mixin
|
|
1101
|
+
, ProtostreamType
|
|
1102
|
+
, ProtobufRoot
|
|
1032
1103
|
// TODO 2.6 new ops: getStream and putStream
|
|
1033
1104
|
// TODO 2.6 add listener change: listener event interests
|
|
1034
1105
|
// TODO 2.7 new ops: prepare, commit and rollback
|
|
@@ -1038,6 +1109,28 @@
|
|
|
1038
1109
|
// TODO 2.8 header change: media types
|
|
1039
1110
|
);
|
|
1040
1111
|
|
|
1112
|
+
_.extend(Protocol30.prototype
|
|
1113
|
+
, EncodeMixin
|
|
1114
|
+
, ExpiryEncodeMixin
|
|
1115
|
+
, DecodeMixin
|
|
1116
|
+
, IdsMixin
|
|
1117
|
+
, ListenersMixin
|
|
1118
|
+
, ListenerInterestsMixin
|
|
1119
|
+
, IteratorMixin
|
|
1120
|
+
, MediaTypesMixin
|
|
1121
|
+
, SASLMixin
|
|
1122
|
+
, Ping30Mixin
|
|
1123
|
+
, ProtostreamType
|
|
1124
|
+
, ProtobufRoot
|
|
1125
|
+
// TODO 2.6 new ops: getStream and putStream
|
|
1126
|
+
// TODO 2.6 add listener change: listener event interests
|
|
1127
|
+
// TODO 2.7 new ops: prepare, commit and rollback
|
|
1128
|
+
// TODO 2.7 new ops: counter operations
|
|
1129
|
+
// TODO 2.7 new events: counter events
|
|
1130
|
+
// TODO 2.8 listener events: can come from any connection
|
|
1131
|
+
// TODO 2.8 header change: media types
|
|
1132
|
+
);
|
|
1133
|
+
|
|
1041
1134
|
exports.version22 = function(clientOpts) {
|
|
1042
1135
|
return new Protocol22(clientOpts);
|
|
1043
1136
|
};
|
|
@@ -1050,4 +1143,8 @@
|
|
|
1050
1143
|
return new Protocol29(clientOpts);
|
|
1051
1144
|
};
|
|
1052
1145
|
|
|
1146
|
+
exports.version30 = function(clientOpts) {
|
|
1147
|
+
return new Protocol30(clientOpts);
|
|
1148
|
+
};
|
|
1149
|
+
|
|
1053
1150
|
}.call(this));
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
syntax = "proto2";
|
|
2
|
+
|
|
3
|
+
package org.infinispan.protostream;
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Protobuf messages do not indicate their message type or structure. Readers of protobuf data streams are expected to
|
|
7
|
+
* know in advance what message type to expect next in the stream. Also, the wire format is not self-delimiting so the
|
|
8
|
+
* length of the next message must be computed based on the known schema so that not too much nor too little is read.
|
|
9
|
+
* This is particularly important if a sequence of multiple messages are contained in a stream. A detailed explanation
|
|
10
|
+
* is offered here: https://developers.google.com/protocol-buffers/docs/techniques#streaming
|
|
11
|
+
* <p>
|
|
12
|
+
* WrappedMessage solves this problem of self-describing messages by allowing the stream reader to detect
|
|
13
|
+
* the type of the message. Still, only the type name (or type id) is provided but the actual schema is not provided as
|
|
14
|
+
* it would not be efficient to carry so much information over the wire with each message. The application is expected
|
|
15
|
+
* to have knowledge of the schema and use it once it learns the type name/id.
|
|
16
|
+
* <p>
|
|
17
|
+
* This is similar to 'google.protobuf.Any' but is also able to handle scalars not just messages.
|
|
18
|
+
* <p>
|
|
19
|
+
* Fields should ideally arrive in the data stream in the order defined here for efficiency reasons, but implementations
|
|
20
|
+
* should be able to deal with any field order.
|
|
21
|
+
*
|
|
22
|
+
* @TypeId(0)
|
|
23
|
+
*/
|
|
24
|
+
message WrappedMessage {
|
|
25
|
+
|
|
26
|
+
// Exactly one of the following fields is used if the wrapped value is a primitive (scalar) type.
|
|
27
|
+
oneof scalarOrMessage {
|
|
28
|
+
double wrappedDouble = 1;
|
|
29
|
+
float wrappedFloat = 2;
|
|
30
|
+
int64 wrappedInt64 = 3;
|
|
31
|
+
uint64 wrappedUInt64 = 4;
|
|
32
|
+
int32 wrappedInt32 = 5;
|
|
33
|
+
fixed64 wrappedFixed64 = 6;
|
|
34
|
+
fixed32 wrappedFixed32 = 7;
|
|
35
|
+
bool wrappedBool = 8;
|
|
36
|
+
string wrappedString = 9;
|
|
37
|
+
bytes wrappedBytes = 10;
|
|
38
|
+
uint32 wrappedUInt32 = 11;
|
|
39
|
+
sfixed32 wrappedSFixed32 = 12;
|
|
40
|
+
sfixed64 wrappedSFixed64 = 13;
|
|
41
|
+
sint32 wrappedSInt32 = 14;
|
|
42
|
+
sint64 wrappedSInt64 = 15;
|
|
43
|
+
|
|
44
|
+
/** There is no native char type in protobuf so it is mapped to int32. */
|
|
45
|
+
int32 wrappedChar = 20;
|
|
46
|
+
|
|
47
|
+
/** There is no native short type in protobuf so it is mapped to int32. */
|
|
48
|
+
int32 wrappedShort = 21;
|
|
49
|
+
|
|
50
|
+
/** There is no native byte type in protobuf so it is mapped to int32. */
|
|
51
|
+
int32 wrappedByte = 22;
|
|
52
|
+
|
|
53
|
+
/** There is no native Date type in protobuf so it is mapped to int64 (milliseconds). */
|
|
54
|
+
int64 wrappedDateMillis = 23;
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* There is no native Instant type in protobuf so it is mapped to an int64 (the seconds) + an int32 (the nanoseconds).
|
|
58
|
+
* The field wrappedInstantNanos must be also present if this field is present.
|
|
59
|
+
* A close equivalent to this, with binary compatible representation, is google.protobuf.Timestamp defined in timestamp.proto.
|
|
60
|
+
*/
|
|
61
|
+
int64 wrappedInstantSeconds = 24;
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* This is used if the wrapped value is an enum. The actual type is indicated by oneof typeNameOrId, which
|
|
65
|
+
* is required if this field is present.
|
|
66
|
+
*/
|
|
67
|
+
int32 wrappedEnum = 18;
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Stores the message's protobuf encoded bytes when the wrapped value is a message type.
|
|
71
|
+
* This is similar to google.protobuf.Any.value field. The actual type is indicated by oneof typeNameOrId, which
|
|
72
|
+
* is required if this field is present.
|
|
73
|
+
*/
|
|
74
|
+
bytes wrappedMessage = 17;
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* A flag that indicates that the contents of the wrapper is empty/null.
|
|
78
|
+
*/
|
|
79
|
+
bool wrappedEmpty = 26;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* The nanoseconds of the Instant. Always present if wrappedInstantSeconds is present.
|
|
84
|
+
* This field is declared outside of scalarOrMessage oneof because it's not legal to have two of the oneof fields
|
|
85
|
+
* present simultaneously in the data stream.
|
|
86
|
+
*/
|
|
87
|
+
optional int32 wrappedInstantNanos = 25;
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Stores the fully qualified type name or the optional numeric type id of the payload. This is not used for primitive types
|
|
91
|
+
* (scalars), only for message and enum types.
|
|
92
|
+
*/
|
|
93
|
+
oneof typeNameOrId {
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Stores the fully qualified type name if the wrapped value is a message or an enum type.
|
|
97
|
+
* This is similar to google.protobuf.Any.type_url field.
|
|
98
|
+
*/
|
|
99
|
+
string wrappedTypeName = 16;
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* This is used as an alternative to wrappedTypeName if a unique id was assigned to the type with the TypeId
|
|
103
|
+
* annotation. Values in the range 0..65535 are reserved for internal use by Protostream and other projects
|
|
104
|
+
* from the Infinispan organisation.
|
|
105
|
+
*/
|
|
106
|
+
uint32 wrappedTypeId = 19;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Number of repeated elements. Optional; if present it indicates a container (array or Collection). The value must
|
|
111
|
+
* be positive, or 0 if the array/collection is empty. If this is present, then containerTypeNameOrId and
|
|
112
|
+
* containerMessage must also be present.
|
|
113
|
+
*/
|
|
114
|
+
optional uint32 wrappedContainerSize = 27;
|
|
115
|
+
|
|
116
|
+
oneof wrappedContainerTypeNameOrId {
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Stores the fully qualified type name if the container.
|
|
120
|
+
*/
|
|
121
|
+
string wrappedContainerTypeName = 28;
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* This is used as an alternative to wrappedContainerTypeName if a unique id was assigned to the type with the
|
|
125
|
+
*/
|
|
126
|
+
uint32 wrappedContainerTypeId = 29;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* The fields of the container itself. Must always be present when wrappedContainerSize is present. If the container
|
|
131
|
+
* type itself does not have any fields then this will be a zero length bytes field.
|
|
132
|
+
*/
|
|
133
|
+
optional bytes wrappedContainerMessage = 30;
|
|
134
|
+
}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
/**********************************************************************************************************************
|
|
2
|
+
* REMOTE QUERY RELATED PROTOBUF DEFINITIONS *
|
|
3
|
+
* *
|
|
4
|
+
* Allocated TypeId range is: [4400 .. 4599] (see org.infinispan.commons.marshall.ProtoStreamTypeIds) *
|
|
5
|
+
* Actually used range is: [4400 .. 4403] *
|
|
6
|
+
*********************************************************************************************************************/
|
|
7
|
+
syntax = "proto2";
|
|
8
|
+
import "Protos/message-wrapping.proto";
|
|
9
|
+
|
|
10
|
+
package org.infinispan.query.remote.client;
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* @TypeId(4400)
|
|
14
|
+
*/
|
|
15
|
+
message QueryRequest {
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* The query string, in Infinispan's query language aka Ickle (a JP-QL micro-subset with full-text enhancements).
|
|
19
|
+
*/
|
|
20
|
+
required string queryString = 1;
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* The number of matching results to skip before the first returned result.
|
|
25
|
+
*/
|
|
26
|
+
optional int64 startOffset = 3;
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Maximum number of matching results to return.
|
|
30
|
+
*/
|
|
31
|
+
optional int32 maxResults = 4;
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Multiple, optional, named parameters. Each name must occur only once.
|
|
35
|
+
*/
|
|
36
|
+
repeated NamedParameter namedParameters = 5;
|
|
37
|
+
/**
|
|
38
|
+
* Whether the query is limited to the data from node that receives the request
|
|
39
|
+
*/
|
|
40
|
+
optional bool local = 6;
|
|
41
|
+
|
|
42
|
+
message NamedParameter {
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Parameter unique name.
|
|
46
|
+
*/
|
|
47
|
+
required string name = 1;
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Parameter value.
|
|
51
|
+
*/
|
|
52
|
+
required org.infinispan.protostream.WrappedMessage value = 2;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* @TypeId(4401)
|
|
58
|
+
*/
|
|
59
|
+
message QueryResponse {
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* The number of returned results.
|
|
63
|
+
*/
|
|
64
|
+
required int32 numResults = 1;
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Indicates presence and size of projections.
|
|
68
|
+
*
|
|
69
|
+
* 0 - no projection
|
|
70
|
+
* 1 .. N - projection with N components
|
|
71
|
+
* < 0 - illegal value
|
|
72
|
+
*/
|
|
73
|
+
required int32 projectionSize = 2;
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* The list of matching results. The size should be either numResults, if no projections are used, or numResults *
|
|
77
|
+
* projectionSize otherwise. If projections are used, then each group of projectionSize consecutive elements
|
|
78
|
+
* represent together a row from the result. We use this simple schema in order to avoid bi-dimensional arrays when
|
|
79
|
+
* projections are present.
|
|
80
|
+
*/
|
|
81
|
+
repeated org.infinispan.protostream.WrappedMessage results = 3;
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Total number of results that match the query. This is usually larger than numResults due to
|
|
85
|
+
* QueryRequest.startOffset and QueryRequest.maxResults.
|
|
86
|
+
*/
|
|
87
|
+
required int64 totalResults = 4;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* @TypeId(4402)
|
|
92
|
+
*/
|
|
93
|
+
message FilterResult {
|
|
94
|
+
|
|
95
|
+
optional bytes instance = 1;
|
|
96
|
+
|
|
97
|
+
repeated org.infinispan.protostream.WrappedMessage projection = 2;
|
|
98
|
+
|
|
99
|
+
repeated org.infinispan.protostream.WrappedMessage sortProjection = 3;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* @TypeId(4403)
|
|
104
|
+
*/
|
|
105
|
+
message ContinuousQueryResult {
|
|
106
|
+
|
|
107
|
+
enum ResultType {
|
|
108
|
+
LEAVING = 0;
|
|
109
|
+
JOINING = 1;
|
|
110
|
+
UPDATED = 2;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
required ResultType resultType = 1;
|
|
114
|
+
|
|
115
|
+
required bytes key = 2;
|
|
116
|
+
|
|
117
|
+
/* Only present if resultType is JOINING or UPDATED and 'projection' field is missing */
|
|
118
|
+
optional bytes value = 3;
|
|
119
|
+
|
|
120
|
+
/* Only present if resultType is JOINING or UPDATED and 'value' field is missing */
|
|
121
|
+
repeated org.infinispan.protostream.WrappedMessage projection = 4;
|
|
122
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
var crypto = require('crypto');
|
|
2
|
+
var xor = require('buffer-xor');
|
|
3
|
+
|
|
4
|
+
exports.XOR = xor;
|
|
5
|
+
|
|
6
|
+
exports.H = function (algorithm, str) {
|
|
7
|
+
return crypto.createHash(algorithm).update(str).digest();
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
exports.HMAC = function (algorithm, key, str) {
|
|
11
|
+
return crypto.createHmac(algorithm, key).update(str).digest();
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
exports.Hi = function (algorithm, str, salt, iterations) {
|
|
15
|
+
var INT1 = Buffer.from([0, 0, 0, 1], 'binary');
|
|
16
|
+
var ui1 = crypto.createHmac(algorithm, str).update(salt).update(INT1).digest();
|
|
17
|
+
var ui = ui1;
|
|
18
|
+
for (var i = 1; i < iterations; i++) {
|
|
19
|
+
ui1 = exports.HMAC(algorithm, str, ui1);
|
|
20
|
+
ui = exports.XOR(ui, ui1);
|
|
21
|
+
}
|
|
22
|
+
return ui;
|
|
23
|
+
};
|
|
24
|
+
|