|
var argv = process.argv.slice(2); |
|
var appd = require('appdynamics'); |
|
|
|
if (!(argv[0] === '-entry' || argv[0] === '-service')) { |
|
console.error('Please specify an -entry or -service role, e.g. `node example -entry`') |
|
process.exit(1); |
|
} |
|
|
|
/* Initialize App Dynamics */ |
|
appd.profile({ |
|
debug: false, |
|
controllerHostName: 'localhost', |
|
controllerPort: 8090, |
|
applicationName: 'microservices', |
|
tierName: 'tier' + argv[0], |
|
nodeName: 'node' + argv[0], // Node names must be unique. |
|
controllerSslEnabled: false // Optional - use if connecting to controller via SSL |
|
}); |
|
|
|
var EventEmitter = require('events').EventEmitter; |
|
var redis = require('redis'); |
|
var publisherClient; |
|
var subscriberClient; |
|
|
|
function publish(channel, message, cb) { |
|
var client = publisherClient || (publisherClient = redis.createClient()); |
|
|
|
client.publish(channel, JSON.stringify(message), cb); |
|
} |
|
|
|
function subscribe(channel) { |
|
var client = subscriberClient || (subscriberClient = redis.createClient()); |
|
var emitter = new EventEmitter(); |
|
|
|
client.on('message', function(messageChannel, message) { |
|
if (channel !== messageChannel) return; |
|
emitter.emit('message', JSON.parse(message)); |
|
}); |
|
|
|
client.subscribe(channel); |
|
return emitter; |
|
} |
|
|
|
function createEntry() { |
|
var publisherTopic = 'entry'; |
|
var subscriberTopic = 'entry:response'; |
|
var subscriber = subscribe(subscriberTopic); |
|
|
|
require('http').createServer(function(req, res) { |
|
var trx = appd.startTransaction(req); |
|
trx.beforeExitCall = function getExitInfo(exitCall) { //Suppress default Redis exit handling |
|
if (exitCall.backendName == 'Redis') |
|
return; |
|
else |
|
return exitCall; |
|
} |
|
|
|
/* Take next message */ |
|
subscriber.once('message', function(message) { |
|
if (message.ci) { |
|
var nci = appd.parseCorrelationInfo(message.ci); |
|
var trx = appd.startTransaction(nci); |
|
} |
|
|
|
res.writeHead(message.statusCode); |
|
res.end(JSON.stringify(message)); |
|
|
|
if (message.ci) trx.end(); |
|
}); |
|
|
|
var exit = trx.startExitCall({ // Inform AppD of upcoming exit call |
|
exitType: 'EXIT_CACHE', |
|
label: 'Event Bus - ' + publisherTopic, |
|
identifyingProperties: { // together, properties must uniquely identify the message destination |
|
bus: "local_redis", |
|
topic: publisherTopic |
|
} |
|
}); |
|
|
|
var request = { |
|
ci: trx.createCorrelationInfo(exit), // put the AppD correlation header into the message payload |
|
at: new Date() |
|
}; |
|
|
|
publish(publisherTopic, request, function(err) { |
|
if (err) console.error(err); |
|
console.log('requested'); |
|
trx.endExitCall(exit); // Inform AppD that exit call has completed |
|
trx.end(); |
|
}); |
|
}).listen(8080, function() { |
|
console.log('example listening on 8080'); |
|
}); |
|
} |
|
|
|
function createService() { |
|
var publisherTopic = 'entry:response'; |
|
var subscriberTopic = 'entry'; |
|
var subscriber = subscribe(subscriberTopic); |
|
|
|
subscriber.on('message', function(message) { |
|
console.log('received', message); |
|
if (!message.ci) return publish(publisherTopic, { statusCode: 400, info: 'CorrelationInfo is empty.' }, noop); |
|
|
|
var nci = appd.parseCorrelationInfo(message.ci); |
|
var trx = appd.startTransaction(nci); // Associate transaction as downstream component of txn defined in ci field (upstream correlato header) |
|
|
|
trx.beforeExitCall = function getExitInfo(exitCall) { // Supress default Redis exit handling |
|
if (exitCall.backendName == 'Redis') |
|
return; |
|
else |
|
return exitCall; |
|
} |
|
|
|
|
|
var exit = trx.startExitCall({ |
|
exitType: 'EXIT_CACHE', |
|
label: 'Event Bus - ' + publisherTopic, |
|
identifyingProperties: { // together, properties must identify the message destination |
|
bus: "local_redis", |
|
topic: publisherTopic |
|
} |
|
}); |
|
|
|
var response = { |
|
ci: trx.createCorrelationInfo(exit), // ci is correlation header for reply message |
|
statusCode: 200, |
|
dates: [message.at, new Date()] |
|
}; |
|
|
|
publish(publisherTopic, response, function(err) { |
|
if (err) console.error(err); |
|
console.log('responded'); |
|
trx.endExitCall(exit); // Inform AppD that exit call is over |
|
trx.end(); |
|
}); |
|
}); |
|
} |
|
|
|
if (argv[0] === '-entry') createEntry(); |
|
else if (argv[0] === '-service') createService(); |
|
|
|
function noop(){} |