Repository: wso2/carbon-apimgt
Issue: Message Mediation Policies (xml_validator) failing with  Global Mediation Extensions with FULL log

### Description:

Message Mediation Policies (xml_validator) isn't working if Global Mediation Extension with a FULL log mediator added to the synapse folder. 

XMLSchemaValidator directly consumes the stream from the pipe. Therefore, if  log full is used in global in_sequence or any content-aware mediators, it will try to build the message by consuming the stream from the pipe. Since XMLSchemaValidator consumes the pipe later according to the order of the sequences, the pipe is already empty. This produces the error.

### Steps to reproduce:

1. Copy an [WSO2AM-Ext-In.xml](https://support.wso2.com/jira/secure/attachment/248017/248017_WSO2AM--Ext--In.xml) file to <APIM_HOME>/repository\\deployment\\server\\synapse-configs\\default\\sequences folder.
2. Run APIM
3. Create or edit API by enabling Message Mediation Policies (xml_validator)
4. Subscribe to that API
5. Send a request


### Affected Product Version:
2.6



Changed files:
components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/utils/GatewayUtils.java

diff --git a/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/utils/GatewayUtils.java b/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/utils/GatewayUtils.java
index cad3e17f2e1..1953626ce0a 100644
--- a/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/utils/GatewayUtils.java
+++ b/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/utils/GatewayUtils.java
@@ -40,6 +40,7 @@ import org.apache.http.client.methods.CloseableHttpResponse;
 import org.apache.http.client.methods.HttpGet;
 import org.apache.http.impl.client.CloseableHttpClient;
 import org.apache.synapse.Mediator;
+import org.apache.synapse.commons.json.JsonUtil;
 import org.apache.synapse.core.axis2.Axis2MessageContext;
 import org.apache.synapse.rest.RESTConstants;
 import org.apache.synapse.transport.nhttp.NhttpConstants;
@@ -78,6 +79,7 @@ import java.io.IOException;
 import java.io.InputStream;
 import java.io.UnsupportedEncodingException;
 import java.net.URL;
+import java.nio.charset.StandardCharsets;
 import java.security.cert.Certificate;
 import java.util.ArrayList;
 import java.security.interfaces.RSAPublicKey;
@@ -399,15 +401,14 @@ public class GatewayUtils {
      * @return cloned InputStreams.
      * @throws IOException this exception might occurred while cloning the inputStream.
      */
-    public static Map<String, InputStream> cloneRequestMessage(org.apache.synapse.MessageContext messageContext)
+    public static Map<String,InputStream> cloneRequestMessage(org.apache.synapse.MessageContext messageContext)
             throws IOException {
-
         BufferedInputStream bufferedInputStream = null;
-        Map<String, InputStream> inputStreamMap = null;
-        InputStream inputStreamSchema;
-        InputStream inputStreamXml;
-        InputStream inputStreamJSON;
-        InputStream inputStreamOriginal;
+        Map<String, InputStream> inputStreamMap;
+        InputStream inputStreamSchema = null;
+        InputStream inputStreamXml = null;
+        InputStream inputStreamJSON = null ;
+        InputStream inputStreamOriginal = null;
         int requestBufferSize = 1024;
         org.apache.axis2.context.MessageContext axis2MC;
         Pipe pipe;
@@ -422,24 +423,38 @@ public class GatewayUtils {
         if (pipe != null) {
             bufferedInputStream = new BufferedInputStream(pipe.getInputStream());
         }
+        inputStreamMap = new HashMap<>();
+        String contentType = axis2MC.getProperty(ThreatProtectorConstants.CONTENT_TYPE).toString();
+
         if (bufferedInputStream != null) {
-            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
-            byte[] buffer = new byte[requestBufferSize];
-            int length;
-            while ((length = bufferedInputStream.read(buffer)) > -1) {
-                byteArrayOutputStream.write(buffer, 0, length);
+            bufferedInputStream.mark(0);
+            if (bufferedInputStream.read() != -1){
+                bufferedInputStream.reset();
+                ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+                byte[] buffer = new byte[requestBufferSize];
+                int length;
+                while ((length = bufferedInputStream.read(buffer)) > -1) {
+                    byteArrayOutputStream.write(buffer, 0, length);
+                }
+                byteArrayOutputStream.flush();
+                inputStreamSchema = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
+                inputStreamXml = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
+                inputStreamOriginal = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
+                inputStreamJSON = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
+            } else {
+                String payload;
+                if (ThreatProtectorConstants.APPLICATION_JSON.equals(contentType)){
+                    inputStreamJSON = JsonUtil.getJsonPayload(axis2MC);
+                } else {
+                    payload = axis2MC.getEnvelope().getBody().getFirstElement().toString();
+                    inputStreamXml= new ByteArrayInputStream(payload.getBytes(StandardCharsets.UTF_8));
+                }
             }
-            byteArrayOutputStream.flush();
-            inputStreamMap = new HashMap<>();
-            inputStreamSchema = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
-            inputStreamXml = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
-            inputStreamOriginal = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
-            inputStreamJSON = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
-            inputStreamMap.put(ThreatProtectorConstants.SCHEMA, inputStreamSchema);
-            inputStreamMap.put(ThreatProtectorConstants.XML, inputStreamXml);
-            inputStreamMap.put(ThreatProtectorConstants.ORIGINAL, inputStreamOriginal);
-            inputStreamMap.put(ThreatProtectorConstants.JSON, inputStreamJSON);
         }
+        inputStreamMap.put(ThreatProtectorConstants.SCHEMA, inputStreamSchema);
+        inputStreamMap.put(ThreatProtectorConstants.XML, inputStreamXml);
+        inputStreamMap.put(ThreatProtectorConstants.ORIGINAL, inputStreamOriginal);
+        inputStreamMap.put(ThreatProtectorConstants.JSON, inputStreamJSON);
         return inputStreamMap;
     }