Scripting: How to route requests to different services

 
1 Likes

This example shows how to use the Binary/HTTP virtual service together with the C# scripted rule to forward requests to different services based on the SOAPAction HTTP header.

using HP.SV.CSharp;
using System.Collections.Generic;
using System;
using System.Net.Http;

namespace HP.SV {
    public class CSharpRule {
        private static string HttpHeaderSOAPAction = "SOAPAction";
        private static string HttpHeaderContentType = "Content-Type";
        private static string HttpHeaderContentEncoding = "Content-Encoding";

        private static string DefaultTargetKey = "DefaultTargetKey";
        private static Dictionary<string, string> RouteTable = new Dictionary<string, string>() {
            { "DefaultTargetKey", "http://localhost:7200/serviceA"},
            { "http://hp.com/SOAQ/ServiceSimulation/2010/demo/01/IMemberAccounts/memberSearch", "http://localhost:7200/serviceA"},
            { "http://hp.com/SOAQ/ServiceSimulation/2010/demo/01/IMemberAccounts/getMemberPlan", "http://localhost:7200/serviceB"}
        };

        /// <summary>
        /// Main method.
        /// </summary>
        public static void Execute(HpsvRootObject sv) {
            Dictionary<string, string> httpHeaders = GetHttpHeaders(sv.Request);
            byte[] payload = Convert.FromBase64String(sv.Request.BinaryContent.Data);


            string targetUrl = GetTargetUrl(httpHeaders);
            HttpResponseMessage httpResponse = DoHttpPost(targetUrl, httpHeaders, payload);

            CopyToHpsvResponse(httpResponse, sv.Response);
        }

        /// <summary>
        /// Copies data from the .NET HttpResponse structure to SV structure.
        /// </summary>
        private static void CopyToHpsvResponse(HttpResponseMessage httpResponse, HpsvResponse hpsvResponse) {
            hpsvResponse.HTTPOutputParameters.StatusCode = (long)httpResponse.StatusCode;
            hpsvResponse.BinaryContent.Data = Convert.ToBase64String(httpResponse.Content.ReadAsByteArrayAsync().Result);

            hpsvResponse.HTTPOutputParameters.Headers.Content_Type = httpResponse.Content.Headers.ContentType.ToString();
        }

        /// <summary>
        /// Returns URL where we want to forward the request.
        /// </summary>
        private static string GetTargetUrl(Dictionary<string, string> headers) {
            // got SOAPAction HTTP header value
            string key;
            headers.TryGetValue(HttpHeaderSOAPAction, out key);

            if (key == null) {
                key = DefaultTargetKey;
            }

            string requestUri = RouteTable[key];
            return requestUri;
        }

        /// <summary>
        /// Extracts HTTP headers from SV request structure.
        /// </summary>
        private static Dictionary<string, string> GetHttpHeaders(HpsvRequest httpRequest) {
            Dictionary<string, string> headers = new Dictionary<string, string>();
            foreach (KeyValuePair<string, object> header in httpRequest.HTTPInputParameters.Headers.GetAllProperties()) {
                headers.Add(header.Key, (string)header.Value);
            }
            return headers;
        }

        /// <summary>
        /// Invokes the remote service and returns the response.
        /// </summary>
        private static HttpResponseMessage DoHttpPost(string requestUri, Dictionary<string, string> httpHeaders, byte[] payload) {
            HttpContent httpContent = CreateHttpContent(httpHeaders, payload);

            HttpClient client = new HttpClient();

            HttpResponseMessage response = client.PostAsync(requestUri, httpContent).Result;
            return response;
        }

        /// <summary>
        /// Creates the .NET request object.
        /// </summary>
        private static HttpContent CreateHttpContent(Dictionary<string, string> headers, byte[] payload) {
            HttpContent httpContent = new ByteArrayContent(payload);
            foreach (KeyValuePair<string, string> header in headers) {
                if (header.Key == HttpHeaderContentType) {
                    httpContent.Headers.ContentType.MediaType = header.Value;
                } else if (header.Key == HttpHeaderContentEncoding) {
                    httpContent.Headers.ContentEncoding.Add(header.Value);
                } else {
                    httpContent.Headers.Add(header.Key, header.Value);
                }
            }
            return httpContent;
        }
    }
}

Labels:

Education-Training
How To-Best Practice
Comment List
Related
Recommended