public static class PostWebhook
{
    //The below function will process the incoming WebHook request and return HttpStatusCode'OK' if it is sucessfull 
    [FunctionName("ProcessWebhook")]
    public static async Task ProcessWebhook([HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequestMessage req, TraceWriter log)
    {
        HttpResponseMessage response = new HttpResponseMessage();
        try
        {
            log.Info("C# HTTP trigger function processed a request.");

            //Get request data
            string requestData = new StreamReader(req.Content.ReadAsStreamAsync().Result).ReadToEnd().ToString().Trim();

            if (requestData != "")
            {
                IEnumerable headerValues = req.Headers.GetValues("X-Moduslink-HMAC-SHA256");
                log.Info($"Application XModuslinkHMACSHA256 value: {headerValues.FirstOrDefault()} ");
                log.Info($"WebhookInfo Message: {requestData} ");

                //Get the SecretKey value from the configuration settings
                string SecretKey = System.Environment.GetEnvironmentVariable("X-Moduslink-HMAC-SHA256_Key");
                WebhookInformation objWebhook = new WebhookInformation();
                objWebhook = JsonConvert.DeserializeObject(requestData);

                //Varify whether the computed HMAC value  and the HMAC value in the request Header are matching 
                if (VarifyHMACValue(headerValues.FirstOrDefault().Trim(), SecretKey, objWebhook, log) == true)
                {
                    log.Info($"XModuslinkHMACSHA256 value: {headerValues.FirstOrDefault()} is matching ");
                    string webhookinfoJson = JsonConvert.SerializeObject(objWebhook);
                    log.Info($"Message Received.: {webhookinfoJson} ");
                    response = req.CreateResponse(HttpStatusCode.OK, $"WebhookInfo processed successfully");
                }
                else
                {
                    log.Info($"XModuslinkHMACSHA256 value: {headerValues.FirstOrDefault()} is NOT matching, further processes aborted. ");
                    response = req.CreateResponse(HttpStatusCode.OK, $"WebhookInfo not processed due to the mismtach in XModuslinkHMACSHA256 value");
                }
            }
            else
            {
                response = req.CreateResponse(HttpStatusCode.BadRequest, $"Please pass a name on the query string or in the request body");
            }
        }
        catch (Exception ex)
        {
            log.Info($"Error occured: {ex.Message} ");
            response = req.CreateResponse(ex);
        }
        return await Task.FromResult(response);
    }

    //The below function will calculate the HMAC value by using the secret key provided and compare it with the HMAC value available in the request header 
    public static bool VarifyHMACValue(string ModuslinkHMACValue, string secretKey, WebhookInformation requestData, TraceWriter log)
    {
        string HMAHeader = ModuslinkHMACValue;
        string CalculatedHMAC = null;
        HMACSHA256 HMAC = new HMACSHA256(Encoding.UTF8.GetBytes(secretKey.Trim()));
        byte[] Hash = HMAC.ComputeHash(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(requestData)));
        CalculatedHMAC = Convert.ToBase64String(Hash);

        //remove the padding character from the CalculatedHMAC
        CalculatedHMAC = CalculatedHMAC.Remove(CalculatedHMAC.Length - 1);

        //Now verify that the actual hash value in the request header is matching with the calucalted hash value.
        if (HMAHeader == CalculatedHMAC)
        {
            //Do something
            return true;
        }
        else
        {
            return false;
        }
    }
}

public class WebhookInformation
{
    public WebhookInformation()
    {
        links = new List();
    }

    public string eventType { get; set; }
    public string eventObjectId { get; set; }
    public string eventObjectName { get; set; }
    public string eventObjectReference { get; set; }
    public string eventDateTime { get; set; }
    public List links { get; set; }
}

public class Link
{
    public string href { get; set; }
    public string rel { get; set; }
}
                
            
                
                    public class Function {

                        //The below function will process the incoming WebHook request and return   HttpStatusCode'OK' if it is sucessfull
                    
                        @FunctionName("ProcessWebhook")
                    
                        public HttpResponseMessage run(
                    
                                @HttpTrigger(name = "req", methods = {HttpMethod.GET, HttpMethod.POST}, authLevel = AuthorizationLevel.FUNCTION) HttpRequestMessage> request,
                    
                                final ExecutionContext context) {
                    
                            context.getLogger().info("Java HTTP trigger processed a request.");
                    
                            // Parse query parameter
                    
                            String query = request.getQueryParameters().get("name");
                    
                            String name = request.getBody().orElse(query);
                    
                            //Get the  ModusLink HMAC values from request Header
                    
                            String strHeaderValue = request.getHeaders().get("x-moduslink-hmac-sha256");
                    
                            //Get the SecretKey value from the configuration settings
                    
                            String SecretKey = System.getenv("X-Moduslink-HMAC-SHA256");
                    
                            WebhookInformation webhookInfo = null;
                    
                            try{
                    
                                webhookInfo = (WebhookInformation) new ObjectMapper().readValue(name, WebhookInformation.class);
                    
                                //Varify whether the computed HMAC value  and the HMAC value in the request Header are matching
                    
                                if (VarifyHMACValue(strHeaderValue.trim(), SecretKey, webhookInfo) == true)
                    
                                {
                    
                                    String webhookinfoJson = new ObjectMapper().writeValueAsString(webhookInfo);
                    
                                    return request.createResponseBuilder(HttpStatus.OK).body("WebhookInfo processed successfully").build();
                    
                                }
                    
                          else
                    
                                {
                    
                                    return request.createResponseBuilder(HttpStatus.BAD_REQUEST).body("WebhookInfo not processed due to the mismtach in                 XModuslinkHMACSHA256 value").build();
                    
                                }
                    
                            }catch(IOException io) {
                    
                                io.printStackTrace();
                    
                            } 
                    
                        }
                    
                        //The below function will calculate the HMAC value by using the secret key provided and compare it with the HMAC value              available in the request header
                    
                        private static boolean VarifyHMACValue(String ModuslinkHMACValue, String secretAccessKey, WebhookInformation requestData)
                    
                            {
                    
                                try
                    
                                {
                    
                                    String data = new ObjectMapper().writeValueAsString(requestData);
                    
                                    byte[] secretKey = secretAccessKey.getBytes();
                    
                                    SecretKeySpec signingKey = new SecretKeySpec(secretKey, "HmacSHA256");
                    
                                    Mac mac = Mac.getInstance("HmacSHA256");
                    
                                    mac.init(signingKey);
                    
                                    byte[] bytes = data.getBytes("utf-8");
                    
                                    byte[] rawHmac = mac.doFinal(bytes);
                    
                                    String CalculatedHMAC = Base64.getEncoder().encodeToString(rawHmac);
                    
                                    
                    
                                    if(CalculatedHMAC.contains("="))
                    
                                    {
                    
                                        CalculatedHMAC = CalculatedHMAC.substring(0, CalculatedHMAC.length() -1);
                    
                                    }
                    
                                    //Now verify that the actual hash value in the request header is matching with the calucalted hash value.
                    
                                    if (ModuslinkHMACValue.equals(CalculatedHMAC))
                    
                                    {
                    
                                        //Do something 
                    
                                        return true;
                    
                                    }
                    
                                    else
                    
                                    {
                    
                                        return false;
                    
                                    } 
                    
                                }
                    
                                catch(Exception ex)
                    
                                {
                    
                                }
                    
                                return false;
                    
                            }
                    
                    }
                    
                    class WebhookInformation
                    
                        {
                    
                            private String eventType;
                    
                            public String getEventType() {
                    
                                return this.eventType;
                    
                            }
                    
                            public void setEventType(String eventType) {
                    
                                this.eventType = eventType;
                    
                            }
                    
                            
                    
                            private String eventObjectId ;
                    
                            public String getEventObjectId() {
                    
                                return this.eventObjectId;
                    
                            }
                    
                            public void setEventObjectId(String eventObjectId) {
                    
                                this.eventObjectId = eventObjectId;
                    
                            }
                    
                            private String eventObjectName;
                    
                            public String getEventObjectName() {
                    
                                return this.eventObjectName;
                    
                            }
                    
                            public void setEventObjectName(String eventObjectName) {
                    
                                this.eventObjectName = eventObjectName;
                    
                            }
                    
                            private String eventObjectReference;
                    
                            public String getEventObjectReference() {
                    
                                return this.eventObjectReference;
                    
                            }
                    
                            public void setEventObjectReference(String eventObjectReference) {
                    
                                this.eventObjectReference = eventObjectReference;
                    
                            }
                    
                            private String eventDateTime;
                    
                            public String getEventDateTime() {
                    
                                return this.eventDateTime;
                    
                            }
                    
                            public void setEventDateTime(String eventDateTime) {
                    
                                this.eventDateTime = eventDateTime;
                    
                            }
                    
                            private List links;
                    
                            public List getLinks() {
                    
                                return this.links;
                    
                            }
                    
                            public void setLinks(List links) {
                    
                                this.links = links;
                    
                            }
                    
                        }
                    
                         class Link
                    
                        {
                    
                            private String href;
                    
                            public String getHref() {
                    
                                return this.href;
                    
                            }
                    
                            public void setHref(String href) {
                    
                                this.href = href;
                    
                            }
                    
                            private String rel;
                    
                            public String getRel() {
                    
                                return this.rel;
                    
                            }
                    
                            public void setRel(String rel) {
                    
                                this.rel = rel;
                    
                            }
                    
                        }