mirror of
https://github.com/yldio/copilot.git
synced 2024-12-01 07:30:07 +02:00
metrics-service spike
This commit is contained in:
parent
2945190dbb
commit
3c1780342d
3
spikes/metrics-service/graphql/.gitignore
vendored
Normal file
3
spikes/metrics-service/graphql/.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
/node_modules
|
||||||
|
/npm-debug.log
|
||||||
|
.idea
|
16
spikes/metrics-service/graphql/package.json
Normal file
16
spikes/metrics-service/graphql/package.json
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
{
|
||||||
|
"name": "graphql",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"scripts": {
|
||||||
|
"start": "node src/index.js"
|
||||||
|
},
|
||||||
|
"main": "src/index.js",
|
||||||
|
"private": true,
|
||||||
|
"dependencies": {
|
||||||
|
"graphql": "^0.7.2",
|
||||||
|
"hapi": "^15.2.0",
|
||||||
|
"hapi-graphql": "^1.0.1",
|
||||||
|
"inert": "^4.0.2",
|
||||||
|
"require-dir": "^0.3.1"
|
||||||
|
}
|
||||||
|
}
|
29
spikes/metrics-service/graphql/src/index.js
Normal file
29
spikes/metrics-service/graphql/src/index.js
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
const requireDir = require('require-dir');
|
||||||
|
const plugins = require('./plugins');
|
||||||
|
const routes = requireDir('./routes');
|
||||||
|
const Hapi = require('hapi');
|
||||||
|
const path = require('path');
|
||||||
|
const fs = require('fs');
|
||||||
|
|
||||||
|
const server = new Hapi.Server();
|
||||||
|
|
||||||
|
server.connection({
|
||||||
|
host: 'localhost',
|
||||||
|
port: 8000
|
||||||
|
});
|
||||||
|
|
||||||
|
server.register(plugins, (err) => {
|
||||||
|
if (err) {
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
|
||||||
|
Object.keys(routes).forEach((name) => {
|
||||||
|
routes[name](server);
|
||||||
|
});
|
||||||
|
|
||||||
|
server.start((err) => {
|
||||||
|
server.connections.forEach((conn) => {
|
||||||
|
console.log(`started at: ${conn.info.uri}`);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
15
spikes/metrics-service/graphql/src/plugins.js
Normal file
15
spikes/metrics-service/graphql/src/plugins.js
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
module.exports = [
|
||||||
|
require('inert'), {
|
||||||
|
register: require('hapi-graphql'),
|
||||||
|
options: {
|
||||||
|
query: {
|
||||||
|
pretty: true,
|
||||||
|
graphiql: true,
|
||||||
|
schema: require('./schema')
|
||||||
|
},
|
||||||
|
route: {
|
||||||
|
path: '/graphql'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
];
|
11
spikes/metrics-service/graphql/src/routes/home.js
Normal file
11
spikes/metrics-service/graphql/src/routes/home.js
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
const path = require('path');
|
||||||
|
|
||||||
|
module.exports = (server) => {
|
||||||
|
server.route({
|
||||||
|
method: 'GET',
|
||||||
|
path: '/',
|
||||||
|
handler: (request, reply) => {
|
||||||
|
reply.file(path.join(__dirname, 'index.html'));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
28
spikes/metrics-service/graphql/src/routes/index.html
Normal file
28
spikes/metrics-service/graphql/src/routes/index.html
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="root"></div>
|
||||||
|
<script>
|
||||||
|
const client = fetch('http://localhost:8000/graphql', {
|
||||||
|
method: 'POST',
|
||||||
|
body: `
|
||||||
|
subscription {
|
||||||
|
events(container:"1") {
|
||||||
|
value,
|
||||||
|
when
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`
|
||||||
|
});
|
||||||
|
|
||||||
|
client.then((client) => {
|
||||||
|
debugger;
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
18
spikes/metrics-service/graphql/src/routes/version.js
Normal file
18
spikes/metrics-service/graphql/src/routes/version.js
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
const Pkg = require('../../package.json');
|
||||||
|
|
||||||
|
const internals = {
|
||||||
|
response: {
|
||||||
|
version: Pkg.version
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = (server) => {
|
||||||
|
server.route({
|
||||||
|
method: 'GET',
|
||||||
|
path: '/ops/version',
|
||||||
|
config: {
|
||||||
|
description: 'Returns the version of the server',
|
||||||
|
handler: (request, reply) => reply(internals.response)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
61
spikes/metrics-service/graphql/src/schema.js
Normal file
61
spikes/metrics-service/graphql/src/schema.js
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
const graphql = require('graphql');
|
||||||
|
|
||||||
|
const {
|
||||||
|
GraphQLID,
|
||||||
|
GraphQLSchema,
|
||||||
|
GraphQLObjectType,
|
||||||
|
GraphQLString
|
||||||
|
} = graphql;
|
||||||
|
|
||||||
|
const EventType = new GraphQLObjectType({
|
||||||
|
name: 'EventType',
|
||||||
|
fields: {
|
||||||
|
value: {
|
||||||
|
type: GraphQLString
|
||||||
|
},
|
||||||
|
when: {
|
||||||
|
type: GraphQLString
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const EventSubscription = {
|
||||||
|
type: EventType,
|
||||||
|
args: {
|
||||||
|
container: {
|
||||||
|
type: GraphQLID
|
||||||
|
}
|
||||||
|
},
|
||||||
|
start: function() {
|
||||||
|
console.log('start', arguments);
|
||||||
|
},
|
||||||
|
stop: function() {
|
||||||
|
console.log('stop', arguments);
|
||||||
|
},
|
||||||
|
resolve: function() {
|
||||||
|
console.log('resolve', arguments);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const subscription = new GraphQLObjectType({
|
||||||
|
name: 'RootSubscriptionType',
|
||||||
|
fields: {
|
||||||
|
events: EventSubscription
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = new GraphQLSchema({
|
||||||
|
query: new GraphQLObjectType({
|
||||||
|
name: 'Q',
|
||||||
|
fields: {
|
||||||
|
a: { type: GraphQLString },
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
mutation: new GraphQLObjectType({
|
||||||
|
name: 'M',
|
||||||
|
fields: {
|
||||||
|
c: { type: GraphQLString },
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
subscription
|
||||||
|
});
|
3
spikes/metrics-service/http1/.gitignore
vendored
Normal file
3
spikes/metrics-service/http1/.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
/node_modules
|
||||||
|
/npm-debug.log
|
||||||
|
.idea
|
14
spikes/metrics-service/http1/package.json
Normal file
14
spikes/metrics-service/http1/package.json
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
"name": "http1",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"scripts": {
|
||||||
|
"start": "node src/index.js"
|
||||||
|
},
|
||||||
|
"main": "src/index.js",
|
||||||
|
"private": true,
|
||||||
|
"dependencies": {
|
||||||
|
"hapi": "^15.2.0",
|
||||||
|
"inert": "^4.0.2",
|
||||||
|
"require-dir": "^0.3.1"
|
||||||
|
}
|
||||||
|
}
|
29
spikes/metrics-service/http1/src/index.js
Normal file
29
spikes/metrics-service/http1/src/index.js
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
const requireDir = require('require-dir');
|
||||||
|
const plugins = require('./plugins');
|
||||||
|
const routes = requireDir('./routes');
|
||||||
|
const Hapi = require('hapi');
|
||||||
|
const path = require('path');
|
||||||
|
const fs = require('fs');
|
||||||
|
|
||||||
|
const server = new Hapi.Server();
|
||||||
|
|
||||||
|
server.connection({
|
||||||
|
host: 'localhost',
|
||||||
|
port: 8000
|
||||||
|
});
|
||||||
|
|
||||||
|
Object.keys(routes).forEach((name) => {
|
||||||
|
routes[name](server);
|
||||||
|
});
|
||||||
|
|
||||||
|
server.register(plugins, (err) => {
|
||||||
|
if (err) {
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
|
||||||
|
server.start((err) => {
|
||||||
|
server.connections.forEach((conn) => {
|
||||||
|
console.log(`started at: ${conn.info.uri}`);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
3
spikes/metrics-service/http1/src/plugins.js
Normal file
3
spikes/metrics-service/http1/src/plugins.js
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
module.exports = [
|
||||||
|
require('inert')
|
||||||
|
];
|
11
spikes/metrics-service/http1/src/routes/home.js
Normal file
11
spikes/metrics-service/http1/src/routes/home.js
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
const path = require('path');
|
||||||
|
|
||||||
|
module.exports = (server) => {
|
||||||
|
server.route({
|
||||||
|
method: 'GET',
|
||||||
|
path: '/',
|
||||||
|
handler: (request, reply) => {
|
||||||
|
reply.file(path.join(__dirname, 'index.html'));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
16
spikes/metrics-service/http1/src/routes/index.html
Normal file
16
spikes/metrics-service/http1/src/routes/index.html
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<script>
|
||||||
|
var source = new EventSource(`${document.location.origin}/stats`);
|
||||||
|
|
||||||
|
source.onmessage = function(e) {
|
||||||
|
document.body.innerHTML += "Message: " + e.data + '<br />';
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
</body>
|
||||||
|
</html>
|
21
spikes/metrics-service/http1/src/routes/metrics.js
Normal file
21
spikes/metrics-service/http1/src/routes/metrics.js
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
let messageId = 0;
|
||||||
|
|
||||||
|
module.exports = (server) => {
|
||||||
|
server.route({
|
||||||
|
method: 'GET',
|
||||||
|
path: '/stats',
|
||||||
|
handler: (request, reply) => {
|
||||||
|
request.raw.res.setHeader('Content-Type', 'text/event-stream');
|
||||||
|
|
||||||
|
const intervalId = setInterval(() => {
|
||||||
|
messageId += 1;
|
||||||
|
|
||||||
|
const str = JSON.stringify({
|
||||||
|
msg: messageId
|
||||||
|
});
|
||||||
|
|
||||||
|
request.raw.res.write(`data:${str}\n\n`);
|
||||||
|
}, 100);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
18
spikes/metrics-service/http1/src/routes/version.js
Normal file
18
spikes/metrics-service/http1/src/routes/version.js
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
const Pkg = require('../../package.json');
|
||||||
|
|
||||||
|
const internals = {
|
||||||
|
response: {
|
||||||
|
version: Pkg.version
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = (server) => {
|
||||||
|
server.route({
|
||||||
|
method: 'GET',
|
||||||
|
path: '/ops/version',
|
||||||
|
config: {
|
||||||
|
description: 'Returns the version of the server',
|
||||||
|
handler: (request, reply) => reply(internals.response)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
3
spikes/metrics-service/http2/.gitignore
vendored
Normal file
3
spikes/metrics-service/http2/.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
/node_modules
|
||||||
|
/npm-debug.log
|
||||||
|
.idea
|
33
spikes/metrics-service/http2/cert.pem
Normal file
33
spikes/metrics-service/http2/cert.pem
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIFtTCCA52gAwIBAgIJAK4ScT3ylJVTMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV
|
||||||
|
BAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBX
|
||||||
|
aWRnaXRzIFB0eSBMdGQwHhcNMTYxMTAzMTQyNDIyWhcNMTcxMTAzMTQyNDIyWjBF
|
||||||
|
MQswCQYDVQQGEwJBVTETMBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50
|
||||||
|
ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC
|
||||||
|
CgKCAgEA6gusYDdyFH9e6iNRT7epiZrGh7R9nwD930d1UM37cZiF5/6oKKY2rP/N
|
||||||
|
pe9qnhC+k1LV2ItEZieEun1k4c+ayFSknWtbC+2tKaX5iNVIeqTKP+f0sG+FRpZk
|
||||||
|
VMPZF4eAKze+BjFZDPoFFkvhKC9MOxEyleSR8cCzSmyhVlrgBTRWhhcSMn2BPh41
|
||||||
|
lnUplVP/43lHUWfgs3Et5EDJihzHDjfw0jo2AZ5KtqlYxQSAMt9Z5UsvYQSRUKvD
|
||||||
|
U7YUqHMUGo5F9wZCrcYyn/KbViiiIygX0A6uHU+0ajUyf2EnR1iJsdZ5oLgG6jyk
|
||||||
|
gCwQcNstXi4JVvthXi5HPmHs+i5H1aAOnMy0t21ssARYiZUq3rSmJ2mPXzJw8SYC
|
||||||
|
SLxCEo3WxBXTDOzzne7kzNl6TC0IHTfGDa80wIa3qitK7PaLQaVrGaFy2ITwt76B
|
||||||
|
414+txdM1JINW4/P1S9jv59zkwYKaoFVGdCvnt33XtAlj7C6sManZLzgxvtHhj9i
|
||||||
|
q//GjWswea2hPTezWcpzxJRVXDzVfJGu/lfoGTnZXSVRSQ5EbKQYbVRL3zI5x0hj
|
||||||
|
MPx+w8vDV88qJgywbBZkRwLaunjAwwPdpuLUwsObc5WuwOMobe+G3ycYqHswQpjc
|
||||||
|
6Mw1158nO4Kdx8DJUq7qyRDk3g7kkvp75cbF1xU4fxNzB3VJD6sCAwEAAaOBpzCB
|
||||||
|
pDAdBgNVHQ4EFgQUyt+QUohMXTlCx4nOaozvYR3wbSowdQYDVR0jBG4wbIAUyt+Q
|
||||||
|
UohMXTlCx4nOaozvYR3wbSqhSaRHMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpT
|
||||||
|
b21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGSCCQCu
|
||||||
|
EnE98pSVUzAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4ICAQBAZ4Wvcnoi
|
||||||
|
dAZ3HMBODZTw9E6NZLKgl4aVQiktkCOBOwzJKxkzCrrrr+YQXYx4rHPi85FBevt/
|
||||||
|
NkSsm/Ux+am5iNLjMOW3kDIt1VYYQ6Wn4iPEPUeWzCeyHCOfbG3gOsjDWC1GmWaY
|
||||||
|
WIBi3Zh+7txvrzyhRdNwoS+pAZOzbljCisSDmt1an48tpojI/ZqLD+oGg0LEMuik
|
||||||
|
sBWl227KxyW9DEwLcK9K3I0zhR3NKqWYt47XYvVDq+CqiVI7+/RMwnX/gtIjjGGS
|
||||||
|
5gLdD7mS+Fjig0LtCasDqKYraNQfTAyW3afYITeU4QAKukpJXwwGil3SEP2PxG/y
|
||||||
|
GBz2x6hgQZHB+8VzeA4Zxu5SmLOetJ3yxHRi8NWbiaIn/J+wdRLMjXZ0jTvv86mE
|
||||||
|
VB9X9e0ltvCH/o/VrCOVWHuUXP0zNRawQqYB1qRZ7I7Z/Aes0TQTcQOD/RYUnsfK
|
||||||
|
Mk9XhEpp9IQerufd4e0wlUq6BBA2sN6mkgy57Zsix+LAjU15z0hDRE2xWWNmbakY
|
||||||
|
VBgUTQ8KObAMaSbzUwTildtbsDhtI6pYr8y096NjFiWqkon6R8dveZBfvv5vwoxc
|
||||||
|
h2HTw85eGHyBDcWUe7c7+D+Tp7feNVOeeWtvF7LSRnmTlzqoHdMQ5ns9DxaoUu1Y
|
||||||
|
kbIEE8WnLU0m72Vq5Jzvode8VP3tZpxyvw==
|
||||||
|
-----END CERTIFICATE-----
|
51
spikes/metrics-service/http2/key.pem
Normal file
51
spikes/metrics-service/http2/key.pem
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
-----BEGIN RSA PRIVATE KEY-----
|
||||||
|
MIIJKQIBAAKCAgEA6gusYDdyFH9e6iNRT7epiZrGh7R9nwD930d1UM37cZiF5/6o
|
||||||
|
KKY2rP/Npe9qnhC+k1LV2ItEZieEun1k4c+ayFSknWtbC+2tKaX5iNVIeqTKP+f0
|
||||||
|
sG+FRpZkVMPZF4eAKze+BjFZDPoFFkvhKC9MOxEyleSR8cCzSmyhVlrgBTRWhhcS
|
||||||
|
Mn2BPh41lnUplVP/43lHUWfgs3Et5EDJihzHDjfw0jo2AZ5KtqlYxQSAMt9Z5Usv
|
||||||
|
YQSRUKvDU7YUqHMUGo5F9wZCrcYyn/KbViiiIygX0A6uHU+0ajUyf2EnR1iJsdZ5
|
||||||
|
oLgG6jykgCwQcNstXi4JVvthXi5HPmHs+i5H1aAOnMy0t21ssARYiZUq3rSmJ2mP
|
||||||
|
XzJw8SYCSLxCEo3WxBXTDOzzne7kzNl6TC0IHTfGDa80wIa3qitK7PaLQaVrGaFy
|
||||||
|
2ITwt76B414+txdM1JINW4/P1S9jv59zkwYKaoFVGdCvnt33XtAlj7C6sManZLzg
|
||||||
|
xvtHhj9iq//GjWswea2hPTezWcpzxJRVXDzVfJGu/lfoGTnZXSVRSQ5EbKQYbVRL
|
||||||
|
3zI5x0hjMPx+w8vDV88qJgywbBZkRwLaunjAwwPdpuLUwsObc5WuwOMobe+G3ycY
|
||||||
|
qHswQpjc6Mw1158nO4Kdx8DJUq7qyRDk3g7kkvp75cbF1xU4fxNzB3VJD6sCAwEA
|
||||||
|
AQKCAgEAx0w/cgNk6p13totyjx6HiPy6eA6zNjYC+SIBfViZ+CZ4SJCqo0q+nlyJ
|
||||||
|
wvZ35Le/gPZ10RrumMqoFKH4yO0fEd45+y7S7fprjV6feeyc9orjCr47uA6PAAfK
|
||||||
|
0f+gGpAxDRw/fUiCWzGAKXdd+PklwdqoJ8nmmWWNhx+v1zg1MVlbIH3+6e3Do6DX
|
||||||
|
4xJL4bQQ36SDnYeGaWdEO+0LcceFnc73DB2zpXckihz00Xg+rpNRGpcGdmgMUhSh
|
||||||
|
lOQk/ThZcy+Z1nuHRjDTJS7TJfAd+TAH7wzBKYaYzCQWpy+U4gU746sOEVUD1mzj
|
||||||
|
a52aNm/9Vwh+vYn8ZNWlpzJ+OKA2W8sDFGSQFwieRhTQhUC3YWmexmM7tED6b8GW
|
||||||
|
Z0LlIBLwcgka2Jl9YVslPVPZLmWjnA+7mqRoZjfe7R+87ssN64ldPl8JTL+zAw3J
|
||||||
|
UnqPefPZ/rkGsCO22FC9HmvPs55n9itWlZay/Fu/y0X0Ce6yfoqBhdWRR16U/xHL
|
||||||
|
DbeSd/hUaw0HgpM74DAr5wqZA1jJYGxQno+UJOVLA8VPGhASTzQT0h7RHFIZaiOz
|
||||||
|
Aj+HbruY8jR53xSATRGNxszJMh+PY3ZvGWMnb2WrFKEj6vfozcu11UCqL4fzFuJS
|
||||||
|
yCJQI035Sg1ndgq+E55612WJT8w3txjgqoo+XP6vU83oA8CPzdECggEBAPzGmuai
|
||||||
|
XzmEm3Uvt8MA9kw3nBhv50tGG/GNtJ3nHoFNYXzBj5Qez2yyT248aFFMZnbYnJoD
|
||||||
|
Vmm9MJb8uMM6k/zp9U1xc27F39y/Fyxtdpt9OupmylBDkFztRA/L4boItnnCJJ/C
|
||||||
|
oWfTR6rNoPKomw+j4u09W93qWTkt/yMgAUNT9UJSgg1Pmspjq1TeWi9wEh+XeYx9
|
||||||
|
81HZN1uBlpvNLtbvT8KV65mbkLjrSeP96aUXFPBL4hDnJOTNP8Zxi8iL3REJkiUW
|
||||||
|
Tfny68uCIYolEQ8GQuLJmR5z/DkZ3jtmL43bQty1tTeq6XsiMSoS1JibjBEJ+LRg
|
||||||
|
kt43fd5wGjUkvuMCggEBAO0H6Hf9Ty+CtVPnQQAxmHBIyDLcSTmHK6pBQwh+zX9d
|
||||||
|
2jUne3JDVRF2jspWY667f+lf7aUEOjLA3SM/huKulxVHLvEVSmvFWg4LXdStpeIO
|
||||||
|
Xo2FFZjuKjorSuG3MNzn2fzTyPNTX1TYmkvR3v7lQdpx+t9ajOjWoj9bi49uyFPS
|
||||||
|
3lmUcyR9BkDr4tA+ER9Qr2OBFwoXZ+fKO8cu9DV/61EGdmz3Re+l+BO+y0yWmofQ
|
||||||
|
UC92CCMAM/zUCEZS68HNCdld35CULqmCPnUHL30bSDIBa5SHR8HTfwr8lgkekWRw
|
||||||
|
DxhHHQQ7BRepZDvdVqBK90j4g4LAUUUZWf3znucIPpkCggEAW8ALAaP2RH5pnwOP
|
||||||
|
A+0ZeVjGA+i6X4w3IFp7MMVvQSfBNvNbFjyItb+TLUQn6Tp+Bq1hSlXjy8WsGWHp
|
||||||
|
/pMInEifjVicuZyBQTLrSmkBIDc4Z1SgIrojcFd+2Oz8JfZ7pX5epM6Un4cFAG5a
|
||||||
|
+TlR7z9hYxNegRJLCII1lZ5MVw/meghQxFwcp1G+IrQCsC1Rpr3olKIy64aYnVJQ
|
||||||
|
RIUZd1Kt9MdOGRdqVHSzAVpssEvMgdxJVjFQJuyJNZKJVmXN/B0pOuT5sLwH8npt
|
||||||
|
iiMiKf3v0TmzpmYbKu7Ex3Kz2B26Czq5aFdVICitB8SF/k6XbKfd6jsTlC04NsEi
|
||||||
|
AiAwWQKCAQEAmEanU0a6M4SeZ2u+t5glHaW0b/BTXpD3PWa14ORNstChmdpmlS6q
|
||||||
|
nRB0hYrgeWXdtBk7u/KuTOLYboemaUTOrQ3RG3KZIAlmZHVq73IrisG+ft6L1HbV
|
||||||
|
TA96CO4+hvywb5vDkobyTLjmz2TiBRFVsDffetRaiE8zZs6yJxB9xFRJInWbT0q+
|
||||||
|
1MB2M2BccajNNHi/S21kBGZI5xrEKwamL6SeOjzVgjM238CILQjn9+6dRRBoA8xi
|
||||||
|
mb/CHSOycAwAktObB/Aa1i1lYJugJ5h6Vh3Rdlc+g0gTawSAgxVPRJ41JFyzSH9+
|
||||||
|
MwhQ66CzwUDIAuoc2sggrequhNaZNEV4qQKCAQAM8WpFVOZiTQS1wH4trLIO/SkP
|
||||||
|
gYZW0n1JGHKihf5E3/KWkOwEIewPrff1wCjFJYDncbPbV7UqyOGC1qLv5tHSLBQ/
|
||||||
|
sr3e4pAcqHh1bJWjq7+VN41LwPsoQ8EZdHsoS4Nw0zDln0VTKk532b6yisXCvaye
|
||||||
|
zpoWnfPNS6JfL6M1zw+6vLZCEyBO+d8rVo9lCeO+FOI1N84dTZwmZD3K7QubMKco
|
||||||
|
QShjtmygjEpmw02yRF/85mh1ki6f5rklCeJGqgTj8CDQr6uMczC80n5ISXn87uYW
|
||||||
|
HAkErZpC4ZEqsq+ZexAZSJElATogEsfx7psS4UoYfvf52/X8/Idl+MEmY5h6
|
||||||
|
-----END RSA PRIVATE KEY-----
|
17
spikes/metrics-service/http2/package.json
Normal file
17
spikes/metrics-service/http2/package.json
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
{
|
||||||
|
"name": "http2",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"scripts": {
|
||||||
|
"start": "node src/index.js"
|
||||||
|
},
|
||||||
|
"main": "src/index.js",
|
||||||
|
"private": true,
|
||||||
|
"dependencies": {
|
||||||
|
"bunyan": "^1.8.4",
|
||||||
|
"hapi": "^15.2.0",
|
||||||
|
"http2": "^3.3.6",
|
||||||
|
"inert": "^4.0.2",
|
||||||
|
"require-dir": "^0.3.1",
|
||||||
|
"string-to-stream": "^1.1.0"
|
||||||
|
}
|
||||||
|
}
|
40
spikes/metrics-service/http2/src/index.js
Normal file
40
spikes/metrics-service/http2/src/index.js
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
const http2 = require('http2');
|
||||||
|
const requireDir = require('require-dir');
|
||||||
|
const plugins = require('./plugins');
|
||||||
|
const routes = requireDir('./routes');
|
||||||
|
const Hapi = require('hapi');
|
||||||
|
const path = require('path');
|
||||||
|
const fs = require('fs');
|
||||||
|
|
||||||
|
const server = new Hapi.Server();
|
||||||
|
|
||||||
|
server.connection({
|
||||||
|
listener: http2.createServer({
|
||||||
|
key: fs.readFileSync(path.join(__dirname, '../key.pem')),
|
||||||
|
cert: fs.readFileSync(path.join(__dirname, '../cert.pem')),
|
||||||
|
log: require('bunyan').createLogger({
|
||||||
|
name: 'server',
|
||||||
|
stream: process.stdout,
|
||||||
|
serializers: require('http2/lib/http').serializers
|
||||||
|
})
|
||||||
|
}),
|
||||||
|
host: 'localhost',
|
||||||
|
port: 8000,
|
||||||
|
tls: true
|
||||||
|
});
|
||||||
|
|
||||||
|
Object.keys(routes).forEach((name) => {
|
||||||
|
routes[name](server);
|
||||||
|
});
|
||||||
|
|
||||||
|
server.register(plugins, (err) => {
|
||||||
|
if (err) {
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
|
||||||
|
server.start((err) => {
|
||||||
|
server.connections.forEach((conn) => {
|
||||||
|
console.log(`started at: ${conn.info.uri}`);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
3
spikes/metrics-service/http2/src/plugins.js
Normal file
3
spikes/metrics-service/http2/src/plugins.js
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
module.exports = [
|
||||||
|
require('inert')
|
||||||
|
];
|
11
spikes/metrics-service/http2/src/routes/home.js
Normal file
11
spikes/metrics-service/http2/src/routes/home.js
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
const path = require('path');
|
||||||
|
|
||||||
|
module.exports = (server) => {
|
||||||
|
server.route({
|
||||||
|
method: 'GET',
|
||||||
|
path: '/',
|
||||||
|
handler: (request, reply) => {
|
||||||
|
reply.file(path.join(__dirname, 'index.html'));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
25
spikes/metrics-service/http2/src/routes/index.html
Normal file
25
spikes/metrics-service/http2/src/routes/index.html
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<script>
|
||||||
|
var source = new EventSource(`${document.location.origin}/stats`);
|
||||||
|
|
||||||
|
source.onmessage = function(e) {
|
||||||
|
document.body.innerHTML += "SSE notification: " + e.data + '<br />';
|
||||||
|
|
||||||
|
// fetch resource via XHR... from cache!
|
||||||
|
var xhr = new XMLHttpRequest();
|
||||||
|
xhr.open('GET', e.data);
|
||||||
|
xhr.onload = function() {
|
||||||
|
document.body.innerHTML += "Message: " + this.response + '<br />';
|
||||||
|
};
|
||||||
|
|
||||||
|
xhr.send();
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
</body>
|
||||||
|
</html>
|
38
spikes/metrics-service/http2/src/routes/metrics.js
Normal file
38
spikes/metrics-service/http2/src/routes/metrics.js
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
const str = require('string-to-stream');
|
||||||
|
|
||||||
|
let messageId = 0;
|
||||||
|
|
||||||
|
module.exports = (server) => {
|
||||||
|
server.route({
|
||||||
|
method: 'GET',
|
||||||
|
path: '/stats',
|
||||||
|
handler: (request, reply) => {
|
||||||
|
request.raw.res.setHeader('Content-Type', 'text/event-stream');
|
||||||
|
|
||||||
|
const intervalId = setInterval(() => {
|
||||||
|
const resourcePath = `/resource/${messageId}`;
|
||||||
|
|
||||||
|
if (!request.raw.res.push) {
|
||||||
|
clearInterval(intervalId);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const stream = request.raw.res.push(resourcePath, {
|
||||||
|
status: 200,
|
||||||
|
method: 'GET',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
str(JSON.stringify({
|
||||||
|
msg: messageId
|
||||||
|
})).pipe(stream);
|
||||||
|
|
||||||
|
request.raw.res.write(`data:${resourcePath}\n\n`);
|
||||||
|
|
||||||
|
messageId += 1;
|
||||||
|
}, 100);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
18
spikes/metrics-service/http2/src/routes/version.js
Normal file
18
spikes/metrics-service/http2/src/routes/version.js
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
const Pkg = require('../../package.json');
|
||||||
|
|
||||||
|
const internals = {
|
||||||
|
response: {
|
||||||
|
version: Pkg.version
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = (server) => {
|
||||||
|
server.route({
|
||||||
|
method: 'GET',
|
||||||
|
path: '/ops/version',
|
||||||
|
config: {
|
||||||
|
description: 'Returns the version of the server',
|
||||||
|
handler: (request, reply) => reply(internals.response)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
30
spikes/metrics-service/readme.md
Normal file
30
spikes/metrics-service/readme.md
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
# metrics-service
|
||||||
|
|
||||||
|
> A service which produces random streams of data (firehose) of interpretable metric information for various subsystems that can or will be pulled out from a container. These are currently defined in [RFD-0037](https://github.com/joyent/rfd/blob/master/rfd/0037/README.md#default-metric-keys).
|
||||||
|
|
||||||
|
This spike's purpose was to find the best pattern to expose such metrics service with mock data.
|
||||||
|
|
||||||
|
## http1
|
||||||
|
|
||||||
|
+ very simple API to push data from the server to the client
|
||||||
|
+ plain HTTP
|
||||||
|
- requires a connection to each container - because it's not bidirectional, we can't subscribe to more containers on-demand
|
||||||
|
|
||||||
|
## http2
|
||||||
|
|
||||||
|
+ very simple API to push data from the server to the client
|
||||||
|
+ multiplexing
|
||||||
|
- push doesn't really help us, because it's only useful for static resources
|
||||||
|
|
||||||
|
## graphql
|
||||||
|
|
||||||
|
+ common interface between all data resources
|
||||||
|
+ filter received data
|
||||||
|
- api not finalised yet
|
||||||
|
- api not documented
|
||||||
|
|
||||||
|
## ws (with [nes](https://github.com/hapijs/nes))
|
||||||
|
|
||||||
|
+ strong integration with [Hapi](https://github.com/hapijs/hapi)
|
||||||
|
+ allow to subscribe and unsubscribe on-demand on a single connection
|
||||||
|
- some networks might require fallback to pooling
|
3
spikes/metrics-service/ws/.gitignore
vendored
Normal file
3
spikes/metrics-service/ws/.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
/node_modules
|
||||||
|
/npm-debug.log
|
||||||
|
.idea
|
16
spikes/metrics-service/ws/package.json
Normal file
16
spikes/metrics-service/ws/package.json
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
{
|
||||||
|
"name": "ws",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"scripts": {
|
||||||
|
"start": "node src/index.js"
|
||||||
|
},
|
||||||
|
"main": "src/index.js",
|
||||||
|
"private": true,
|
||||||
|
"dependencies": {
|
||||||
|
"component-emitter": "^1.2.1",
|
||||||
|
"hapi": "^15.2.0",
|
||||||
|
"inert": "^4.0.2",
|
||||||
|
"nes": "^6.3.1",
|
||||||
|
"require-dir": "^0.3.1"
|
||||||
|
}
|
||||||
|
}
|
29
spikes/metrics-service/ws/src/index.js
Normal file
29
spikes/metrics-service/ws/src/index.js
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
const requireDir = require('require-dir');
|
||||||
|
const plugins = require('./plugins');
|
||||||
|
const routes = requireDir('./routes');
|
||||||
|
const Hapi = require('hapi');
|
||||||
|
const path = require('path');
|
||||||
|
const fs = require('fs');
|
||||||
|
|
||||||
|
const server = new Hapi.Server();
|
||||||
|
|
||||||
|
server.connection({
|
||||||
|
host: 'localhost',
|
||||||
|
port: 8000
|
||||||
|
});
|
||||||
|
|
||||||
|
server.register(plugins, (err) => {
|
||||||
|
if (err) {
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
|
||||||
|
Object.keys(routes).forEach((name) => {
|
||||||
|
routes[name](server);
|
||||||
|
});
|
||||||
|
|
||||||
|
server.start((err) => {
|
||||||
|
server.connections.forEach((conn) => {
|
||||||
|
console.log(`started at: ${conn.info.uri}`);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
30
spikes/metrics-service/ws/src/metric.js
Normal file
30
spikes/metrics-service/ws/src/metric.js
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
const Emitter = require('component-emitter');
|
||||||
|
|
||||||
|
const cdm = {};
|
||||||
|
|
||||||
|
module.exports = (server) => ({
|
||||||
|
on: (id) => {
|
||||||
|
if (cdm[id]) {
|
||||||
|
cdm[id].sockets +=1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
let messageId = 0;
|
||||||
|
const interval = setInterval(() => {
|
||||||
|
server.publish(`/stats/${id}`, {
|
||||||
|
id: messageId += 1
|
||||||
|
});
|
||||||
|
}, 500);
|
||||||
|
|
||||||
|
cdm[id] = {
|
||||||
|
interval,
|
||||||
|
sockets: 1
|
||||||
|
};
|
||||||
|
},
|
||||||
|
off: (id) => {
|
||||||
|
if (!(cdm[id].sockets -= 1)) {
|
||||||
|
clearInterval(cdm[id].interval);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
4
spikes/metrics-service/ws/src/plugins.js
Normal file
4
spikes/metrics-service/ws/src/plugins.js
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
module.exports = [
|
||||||
|
require('inert'),
|
||||||
|
require('nes')
|
||||||
|
];
|
11
spikes/metrics-service/ws/src/routes/home.js
Normal file
11
spikes/metrics-service/ws/src/routes/home.js
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
const path = require('path');
|
||||||
|
|
||||||
|
module.exports = (server) => {
|
||||||
|
server.route({
|
||||||
|
method: 'GET',
|
||||||
|
path: '/',
|
||||||
|
handler: (request, reply) => {
|
||||||
|
reply.file(path.join(__dirname, 'index.html'));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
33
spikes/metrics-service/ws/src/routes/index.html
Normal file
33
spikes/metrics-service/ws/src/routes/index.html
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<script src="https://unpkg.com/nes@6.3.1"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="root"></div>
|
||||||
|
<script>
|
||||||
|
const client = new window.nes.Client('ws://localhost:8000');
|
||||||
|
|
||||||
|
client.connect((err) => {
|
||||||
|
if (err) {
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('connected');
|
||||||
|
|
||||||
|
client.subscribe('/stats/5', (update, flag) => {
|
||||||
|
console.log(update, flag);
|
||||||
|
}, (err) => {
|
||||||
|
if (err) {
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('subscribed');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
18
spikes/metrics-service/ws/src/routes/metrics.js
Normal file
18
spikes/metrics-service/ws/src/routes/metrics.js
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
const Metric = require('../metric');
|
||||||
|
|
||||||
|
module.exports = (server) => {
|
||||||
|
const metric = Metric(server);
|
||||||
|
|
||||||
|
server.subscription('/stats/{id}', {
|
||||||
|
onSubscribe: (socket, path, params, next) => {
|
||||||
|
console.log('onSubscribe');
|
||||||
|
metric.on(params.id);
|
||||||
|
next();
|
||||||
|
},
|
||||||
|
onUnsubscribe: (socket, path, params, next) => {
|
||||||
|
console.log('onUnsubscribe');
|
||||||
|
metric.off(params.id);
|
||||||
|
next();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
18
spikes/metrics-service/ws/src/routes/version.js
Normal file
18
spikes/metrics-service/ws/src/routes/version.js
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
const Pkg = require('../../package.json');
|
||||||
|
|
||||||
|
const internals = {
|
||||||
|
response: {
|
||||||
|
version: Pkg.version
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = (server) => {
|
||||||
|
server.route({
|
||||||
|
method: 'GET',
|
||||||
|
path: '/ops/version',
|
||||||
|
config: {
|
||||||
|
description: 'Returns the version of the server',
|
||||||
|
handler: (request, reply) => reply(internals.response)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
Loading…
Reference in New Issue
Block a user