Forum Discussion
4 Replies
- Kevin_StewartEmployee
Can you please elaborate, with examples?
- Jack__Sun_16213Nimbostratus
for example Jira
- Kevin_StewartEmployee
Not much more to go on, but based on what I know of this product (very little) and the assumption that you're talking about HTTP communications, I'd say yes. More detail would be required if you need to know how that may work.
- Brian_Talley_15Historic F5 Account
Yes, this is possible!
The solution that you are referencing (Production Web Traffic Replication), will not handle sessions properly. However, the power of the LineRate scripting engine and Node.js allow us to accomplish this with some slight modifications to the script.
The idea is that you need to add some extra code to handle your session information and translate it if necessary. The logic depends on whether you are using a shared authentication system between the Production and Staging environments or if users are authenticated independently in these environments.
If you are using a shared authentication system, you can check for a login request and prevent that request from being replicated so that the auth system only sees a single request. Any subsequent requests should contain the proper session variables/cookies and be validated by either Production or Staging environments.
If you are using local authentication, you'll let the login request pass to both environments. But in this scenario, you'll need to maintain a mapping between the Production system session information and the Staging system session information and replace this info in requests to the Staging environment.
Here's some example code for the local authentication scenario to get you started. There are plenty of inline comments, but let me know if you have any questions!
ReplicateTraffic.prototype.parseSessionCreds = function(res) { // Custom code to parse the session credentials, such as // a session ID, out of the response if they are there. return credentials; // or null } ReplicateTraffic.prototype.replaceCreds = function(req) { // Custom code to replace the service A credentials // (if present in this request) with the service B // credentials. // No return value. } ReplicateTraffic.prototype.copyHeaders = function(from, to) { for(var header in from.headers) { to.setHeader(header, from.headers[header]); } } ReplicateTraffic.prototype.replicate = function(req, res, cliReq) { if(req.method == 'GET' || req.method == 'HEAD' || req.method == 'POST') { // Only do GET and HEAD and POST var newReq = this.cloneReq(req); // Register for and handle responses on the original req req.on('response', function(cliRes) { // manually forward the response on cliRes.bindHeaders(res); cliRes.pipe(res); // also parse the session credentials out of the response if present. // this happens simultaneously with sending data on, so // the user experience is not impacted. var creds = this.parseSessionCreds(cliRes); if (creds) { this.sessionCredsA = creds; } }); // Register for and handle responses on the clone newReq.on('response', function(cliResB) { console.log('saw B resp'); // parse the session credentials out of the B response if present var creds = this.parseSessionCreds(cliResB); if (creds) { this.sessionCredsB = creds; } }); // Send the original request on this.copyHeaders(req, cliReq); req.pipe(cliReq); // Send the original request data on to the second server req.pipe(newReq); } else { // for other requests, forward it and its response on this.copyHeaders(req, cliReq); req.fastPipe(cliReq, {response: res}); } }
Brian