domesticPaymentsIdQueue = new LinkedList<>();
+
+ @SuppressFBWarnings("JAXRS_ENDPOINT")
+ // Suppressed content - Endpoint
+ // Suppression reason - False Positive : This endpoint is a demo endpoint that is not exposed in production
+ // Suppressed warning count - 1
+ @GET
+ @Path("/payment-consents/{ConsentId}/funds-confirmation")
+ @Produces("application/json; charset=utf-8")
+ public Response getPaymentTypeFundsConfirmation(@PathParam("ConsentId") String paymentId) {
+
+ Instant currentDate = Instant.now();
+
+ String response = "{\n" +
+ " \"Data\": {\n" +
+ " \"FundsAvailableResult\": {\n" +
+ " \"FundsAvailableDateTime\": \"" + currentDate.toString() + "\",\n" +
+ " \"FundsAvailable\": true\n" +
+ " }\n" +
+ " },\n" +
+ " \"Links\": {\n" +
+ " \"Self\": \"/pisp/payments/" + paymentId + "/funds-confirmation\"\n" +
+ " },\n" +
+ " \"Meta\": {}\n" +
+ "}";
+
+ return Response.status(200).entity(response)
+ .header("x-fapi-interaction-id", UUID.randomUUID().toString())
+ .build();
+ }
+
+ @SuppressFBWarnings("JAXRS_ENDPOINT")
+ // Suppressed content - Endpoint
+ // Suppression reason - False Positive : This endpoint is a demo endpoint that is not exposed in production
+ // Suppressed warning count - 1
+
+ @POST
+ @Path("/payments")
+ @Produces("application/json; charset=utf-8")
+ public Response paymentSubmission(String requestString, @HeaderParam("x-fapi-interaction-id") String fid,
+ @HeaderParam("Account-Request-Information") String accountRequestInfo)
+ throws BankException {
+
+ JSONObject jsonObject;
+ JSONObject accountRequestInformation;
+
+ try {
+ accountRequestInformation = getRequest(accountRequestInfo);
+ JSONParser parser = new JSONParser(JSONParser.MODE_PERMISSIVE);
+ jsonObject = (JSONObject) parser.parse(requestString);
+ } catch (ParseException e) {
+ throw new BankException("Error in casting JSON body " + e);
+ }
+
+ JSONObject additionalConsentInfo = (JSONObject) accountRequestInformation.get("additionalConsentInfo");
+
+ JSONObject response = cacheAndGetPaymentResponse(jsonObject, additionalConsentInfo);
+ return Response.status(201).entity(response.toString())
+ .header("x-fapi-interaction-id", fid)
+ .build();
+
+ }
+
+ @SuppressFBWarnings("JAXRS_ENDPOINT")
+ // Suppressed content - Endpoint
+ // Suppression reason - False Positive : This endpoint is a demo endpoint that is not exposed in production
+ // Suppressed warning count - 1
+
+ @GET
+ @Path("/payments/{paymentId}")
+ @Produces("application/json; charset=utf-8")
+ public Response getPaymentTypePayment(@PathParam("paymentId") String paymentId) {
+
+ JSONObject responseObject = null;
+ if (StringUtils.isNotBlank(paymentId)) {
+
+ responseObject = domesticPayments.get(paymentId);
+
+ }
+ if (responseObject == null) {
+ responseObject = new JSONObject();
+ }
+
+
+ return Response.status(200).entity(responseObject.toString())
+ .header("x-fapi-interaction-id", "93bac548-d2de-4546-b106-880a5018460d")
+ .build();
+ }
+
+ private static JSONObject getRequest(String json) throws ParseException {
+
+ String[] splitString = json.split("\\.");
+ String base64EncodedBody = splitString[1];
+ String decodedString = null;
+ decodedString = new String(Base64.getUrlDecoder()
+ .decode(base64EncodedBody.getBytes(StandardCharsets.UTF_8)), StandardCharsets.UTF_8);
+
+ JSONParser parser = new JSONParser(JSONParser.MODE_PERMISSIVE);
+ JSONObject jsonObject = (JSONObject) parser.parse(decodedString);
+ return jsonObject;
+ }
+
+ @SuppressFBWarnings("PREDICTABLE_RANDOM")
+ // Suppressed content - PREDICTABLE_RANDOM
+ // Suppression reason - False Positive : This endpoint is a demo endpoint that is not exposed in production
+ // Suppressed warning count - 1
+ private JSONObject cacheAndGetPaymentResponse(JSONObject requestObject,
+ JSONObject additionalConsentInfo)
+ throws BankException {
+
+ JSONObject responseObject;
+
+ int randomPIN = new Random().nextInt(100);
+
+ String status;
+ String paymentIdValue;
+
+ paymentIdValue = ((JSONObject) requestObject.get("Data")).getAsString("ConsentId");
+ paymentIdValue = paymentIdValue + "-" + randomPIN;
+
+ status = "AcceptedSettlementCompleted";
+
+
+ DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX");
+ Date date = new Date();
+ String currentDate = dateFormat.format(date);
+
+ String readRefundAccount = additionalConsentInfo.getAsString("ReadRefundAccount");
+ String cutOffTimeAcceptable = additionalConsentInfo.getAsString("CutOffTimeAcceptable");
+
+ try {
+ JSONParser parser = new JSONParser(JSONParser.MODE_PERMISSIVE);
+ responseObject = (JSONObject) parser.parse(requestObject.toString());
+
+ JSONObject dataObject = (JSONObject) responseObject.get("Data");
+
+ dataObject.put("PaymentId", paymentIdValue);
+ dataObject.put("Status", status);
+ dataObject.put("CreationDateTime", currentDate);
+ dataObject.put("StatusUpdateDateTime", currentDate);
+
+ // Add refund account details if requested during consent initiation
+ if (Boolean.parseBoolean(readRefundAccount)) {
+ addRefundAccount(dataObject);
+ }
+
+ JSONObject linksObject = new JSONObject();
+ linksObject.put("Self", "/payments/" + paymentIdValue);
+ responseObject.put("Links", linksObject);
+
+ JSONObject metaObject = new JSONObject();
+ responseObject.put("Meta", metaObject);
+
+ responseObject.remove("Risk");
+
+ } catch (ParseException e) {
+ throw new BankException(e);
+ }
+ addToCache(paymentIdValue, responseObject);
+ return responseObject;
+ }
+
+ /**
+ * Add Refund account details to the response.
+ *
+ * @param dataObject
+ */
+ private void addRefundAccount(JSONObject dataObject) {
+
+ String schemeName = "OB.SortCodeAccountNumber";
+ String identification = "Identification";
+ String name = "NTPC Inc";
+
+ JSONObject accountData = new JSONObject();
+ accountData.put("SchemeName", schemeName);
+ accountData.put("Identification", identification);
+ accountData.put("Name", name);
+
+ JSONObject account = new JSONObject();
+ account.put("Account", accountData);
+
+ dataObject.put("Refund", account);
+ }
+
+ private void addToCache(String paymentIdValue, JSONObject responseObject) {
+
+ if (domesticPayments.size() > MAX_LIMIT) {
+ // Max limit reached
+ domesticPayments.remove(domesticPaymentsIdQueue.poll());
+ }
+ domesticPayments.put(paymentIdValue, responseObject);
+ domesticPaymentsIdQueue.add(paymentIdValue);
+
+ }
+}
diff --git a/financial-services-accelerator/internal-webapps/org.wso2.financial.services.accelerator.demo.backend/src/main/java/org/wso2/financial/services/accelerator/demo/backend/services/VrpService.java b/financial-services-accelerator/internal-webapps/org.wso2.financial.services.accelerator.demo.backend/src/main/java/org/wso2/financial/services/accelerator/demo/backend/services/VrpService.java
new file mode 100644
index 00000000..dd8a2c6c
--- /dev/null
+++ b/financial-services-accelerator/internal-webapps/org.wso2.financial.services.accelerator.demo.backend/src/main/java/org/wso2/financial/services/accelerator/demo/backend/services/VrpService.java
@@ -0,0 +1,265 @@
+/**
+ * Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com).
+ *
+ * WSO2 LLC. licenses this file to you under the Apache License,
+ * Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.wso2.financial.services.accelerator.demo.backend.services;
+
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
+import net.minidev.json.JSONObject;
+import net.minidev.json.parser.JSONParser;
+import net.minidev.json.parser.ParseException;
+import org.apache.commons.lang3.StringUtils;
+import org.wso2.financial.services.accelerator.demo.backend.BankException;
+
+import java.nio.charset.StandardCharsets;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.time.Instant;
+import java.util.Base64;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.Map;
+import java.util.Queue;
+import java.util.Random;
+import java.util.UUID;
+
+import javax.ws.rs.GET;
+import javax.ws.rs.HeaderParam;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.Response;
+
+
+/**
+ * Vrp Service class.
+ */
+@Path("/vrpservice/")
+public class VrpService {
+
+ public static final String EXPECTED_EXECUTION_TIME = "ExpectedExecutionDateTime";
+ public static final String EXPECTED_SETTLEMENT_TIME = "ExpectedSettlementDateTime";
+ private static final int MAX_LIMIT = 500;
+ private static final Queue domesticVRPsIdQueue = new LinkedList<>();
+ private static final Map domesticVRPs = new HashMap<>();
+
+
+ @SuppressFBWarnings("JAXRS_ENDPOINT")
+ // Suppressed content - Endpoint
+ // Suppression reason - False Positive : This endpoint is a demo endpoint that is not exposed in production
+ // Suppressed warning count - 1
+ @GET
+ @Path("/domestic-vrp-consents/{ConsentId}/funds-confirmation")
+ @Produces("application/json; charset=utf-8")
+ public Response getPaymentTypeFundsConfirmation(@PathParam("ConsentId") String domesticVRPId) {
+
+ Instant currentDate = Instant.now();
+
+ String response = "{\n" +
+ " \"Data\": {\n" +
+ " \"FundsAvailableResult\": {\n" +
+ " \"FundsAvailableDateTime\": \"" + currentDate.toString() + "\",\n" +
+ " \"FundsAvailable\": true\n" +
+ " }\n" +
+ " },\n" +
+ " \"Links\": {\n" +
+ " \"Self\": \"/vrp/domestic-vrps/" + domesticVRPId + "/funds-confirmation\"\n" +
+ " },\n" +
+ " \"Meta\": {}\n" +
+ "}";
+
+ return Response.status(200).entity(response)
+ .header("x-fapi-interaction-id", UUID.randomUUID().toString())
+ .build();
+ }
+
+ @SuppressFBWarnings("JAXRS_ENDPOINT")
+ // Suppressed content - Endpoint
+ // Suppression reason - False Positive : This endpoint is a demo endpoint that is not exposed in production
+ // Suppressed warning count - 1
+
+ @POST
+ @Path("/domestic-vrps")
+ @Produces("application/json; charset=utf-8")
+ public Response paymentSubmission(String requestString, @PathParam("paymentType") String paymentType,
+ @HeaderParam("x-fapi-interaction-id") String fid,
+ @HeaderParam("Account-Request-Information") String accountRequestInfo)
+ throws BankException {
+
+ JSONObject jsonObject;
+ JSONObject accountRequestInformation;
+
+ try {
+ accountRequestInformation = getRequest(paymentType, accountRequestInfo);
+ JSONParser parser = new JSONParser(JSONParser.MODE_PERMISSIVE);
+ jsonObject = (JSONObject) parser.parse(requestString);
+ } catch (ParseException e) {
+ throw new BankException("Error in casting JSON body " + e);
+ }
+
+ JSONObject additionalConsentInfo = (JSONObject) accountRequestInformation.get("additionalConsentInfo");
+
+ JSONObject response = cacheAndGetPaymentResponse(paymentType, jsonObject, additionalConsentInfo);
+ return Response.status(201).entity(response.toString())
+ .header("x-fapi-interaction-id", fid)
+ .build();
+
+ }
+
+ @SuppressFBWarnings("JAXRS_ENDPOINT")
+ // Suppressed content - Endpoint
+ // Suppression reason - False Positive : This endpoint is a demo endpoint that is not exposed in production
+ // Suppressed warning count - 1
+
+ @GET
+ @Path("/domestic-vrps/{domesticVRPId}")
+ @Produces("application/json; charset=utf-8")
+ public Response getPaymentTypePayment(@PathParam("domesticVRPId") String domesticVRPId) {
+
+ JSONObject responseObject = null;
+ if (StringUtils.isNotBlank(domesticVRPId)) {
+
+ responseObject = domesticVRPs.get(domesticVRPId);
+
+ }
+ if (responseObject == null) {
+ responseObject = new JSONObject();
+ }
+
+
+ return Response.status(200).entity(responseObject.toString())
+ .header("x-fapi-interaction-id", "93bac548-d2de-4546-b106-880a5018460d")
+ .build();
+ }
+
+
+ private static JSONObject getRequest(String paymentType, String json) throws ParseException {
+
+ String[] splitString = json.split("\\.");
+ String base64EncodedBody = splitString[1];
+ String decodedString = null;
+ decodedString = new String(Base64.getUrlDecoder()
+ .decode(base64EncodedBody.getBytes(StandardCharsets.UTF_8)), StandardCharsets.UTF_8);
+
+ JSONParser parser = new JSONParser(JSONParser.MODE_PERMISSIVE);
+ JSONObject jsonObject = (JSONObject) parser.parse(decodedString);
+ return jsonObject;
+ }
+
+
+ @SuppressFBWarnings("PREDICTABLE_RANDOM")
+ // Suppressed content - PREDICTABLE_RANDOM
+ // Suppression reason - False Positive : This endpoint is a demo endpoint that is not exposed in production
+ // Suppressed warning count - 1
+ private JSONObject cacheAndGetPaymentResponse(String paymentType, JSONObject requestObject,
+ JSONObject additionalConsentInfo)
+ throws BankException {
+
+ JSONObject responseObject;
+
+ int randomPIN = new Random().nextInt(100);
+
+ String status;
+ String paymentIdValue;
+
+ paymentIdValue = ((JSONObject) requestObject.get("Data")).getAsString("ConsentId");
+ paymentIdValue = paymentIdValue + "-" + randomPIN;
+
+ status = "AcceptedSettlementCompleted";
+
+ DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX");
+ Date date = new Date();
+ String currentDate = dateFormat.format(date);
+
+ String readRefundAccount = additionalConsentInfo.getAsString("ReadRefundAccount");
+ String cutOffTimeAcceptable = additionalConsentInfo.getAsString("CutOffTimeAcceptable");
+
+ try {
+ JSONParser parser = new JSONParser(JSONParser.MODE_PERMISSIVE);
+ responseObject = (JSONObject) parser.parse(requestObject.toString());
+
+ JSONObject dataObject = (JSONObject) responseObject.get("Data");
+
+ dataObject.put("DomesticVRPId", paymentIdValue);
+ dataObject.put("Status", status);
+ dataObject.put("CreationDateTime", currentDate);
+ dataObject.put("StatusUpdateDateTime", currentDate);
+
+ if ("domestic-vrps".equals(paymentType)) {
+ JSONObject debtorAccount = new JSONObject();
+ debtorAccount.put("SchemeName", "SortCodeAccountNumber");
+ debtorAccount.put("SecondaryIdentification", "Roll 2901");
+ debtorAccount.put("Name", "Deb Mal");
+ debtorAccount.put("Identification", additionalConsentInfo.getAsString("AccountIds")
+ .split(":")[0].replace("[\"", ""));
+
+ dataObject.put("DebtorAccount", debtorAccount);
+
+ }
+
+ // Add refund account details if requested during consent initiation
+ if (Boolean.parseBoolean(readRefundAccount)) {
+ addRefundAccount(dataObject);
+ }
+
+ JSONObject linksObject = new JSONObject();
+ linksObject.put("Self", "/domestic-vrps/" + paymentIdValue);
+ responseObject.put("Links", linksObject);
+
+ JSONObject metaObject = new JSONObject();
+ responseObject.put("Meta", metaObject);
+
+ } catch (ParseException e) {
+ throw new BankException(e);
+ }
+ addToCache(paymentIdValue, responseObject);
+ return responseObject;
+ }
+
+ /**
+ * Add Refund account details to the response.
+ *
+ * @param dataObject
+ */
+ private void addRefundAccount(JSONObject dataObject) {
+
+ String schemeName = "OB.SortCodeAccountNumber";
+ String identification = "Identification";
+ String name = "NTPC Inc";
+
+ JSONObject accountData = new JSONObject();
+ accountData.put("SchemeName", schemeName);
+ accountData.put("Identification", identification);
+ accountData.put("Name", name);
+
+ JSONObject account = new JSONObject();
+ account.put("Account", accountData);
+
+ dataObject.put("Refund", account);
+ }
+
+ private void addToCache(String paymentIdValue, JSONObject responseObject) {
+
+ if (domesticVRPs.size() > MAX_LIMIT) {
+ // Max limit reached
+ domesticVRPs.remove(domesticVRPsIdQueue.poll());
+ }
+ domesticVRPs.put(paymentIdValue, responseObject);
+ domesticVRPsIdQueue.add(paymentIdValue);
+ }
+}
diff --git a/financial-services-accelerator/internal-webapps/org.wso2.financial.services.accelerator.demo.backend/src/main/resources/findbugs-include.xml b/financial-services-accelerator/internal-webapps/org.wso2.financial.services.accelerator.demo.backend/src/main/resources/findbugs-include.xml
new file mode 100644
index 00000000..c6b932b1
--- /dev/null
+++ b/financial-services-accelerator/internal-webapps/org.wso2.financial.services.accelerator.demo.backend/src/main/resources/findbugs-include.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
diff --git a/financial-services-accelerator/internal-webapps/org.wso2.financial.services.accelerator.demo.backend/src/main/webapp/META-INF/webapp-classloading.xml b/financial-services-accelerator/internal-webapps/org.wso2.financial.services.accelerator.demo.backend/src/main/webapp/META-INF/webapp-classloading.xml
new file mode 100644
index 00000000..c1d9dfcc
--- /dev/null
+++ b/financial-services-accelerator/internal-webapps/org.wso2.financial.services.accelerator.demo.backend/src/main/webapp/META-INF/webapp-classloading.xml
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+ false
+
+
+ Carbon,CXF3
+
diff --git a/financial-services-accelerator/internal-webapps/org.wso2.financial.services.accelerator.demo.backend/src/main/webapp/WEB-INF/cxf-servlet.xml b/financial-services-accelerator/internal-webapps/org.wso2.financial.services.accelerator.demo.backend/src/main/webapp/WEB-INF/cxf-servlet.xml
new file mode 100644
index 00000000..65daf243
--- /dev/null
+++ b/financial-services-accelerator/internal-webapps/org.wso2.financial.services.accelerator.demo.backend/src/main/webapp/WEB-INF/cxf-servlet.xml
@@ -0,0 +1,59 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/financial-services-accelerator/internal-webapps/org.wso2.financial.services.accelerator.demo.backend/src/main/webapp/WEB-INF/web.xml b/financial-services-accelerator/internal-webapps/org.wso2.financial.services.accelerator.demo.backend/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 00000000..442eec82
--- /dev/null
+++ b/financial-services-accelerator/internal-webapps/org.wso2.financial.services.accelerator.demo.backend/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,152 @@
+
+
+
+
+
+ Financial-Services
+
+
+ AccountServiceJAXServlet
+ AccountService JAX-WS/JAX-RS Servlet
+ AccountService JAX-WS/JAX-RS Endpoint
+
+ org.apache.cxf.jaxrs.servlet.CXFNonSpringJaxrsServlet
+
+
+ service-list-stylesheet
+ servicelist.css
+
+
+ jersey.config.server.provider.classnames
+ org.glassfish.jersey.media.multipart.MultiPartFeature
+
+
+ 1
+
+
+ jaxrs.serviceClasses
+
+ org.wso2.financial.services.accelerator.demo.backend.services.AccountService
+
+
+
+
+
+ PaymentServiceJAXServlet
+ PaymentService JAX-WS/JAX-RS Servlet
+ PaymentService JAX-WS/JAX-RS Endpoint
+
+ org.apache.cxf.jaxrs.servlet.CXFNonSpringJaxrsServlet
+
+
+ service-list-stylesheet
+ servicelist.css
+
+
+ jersey.config.server.provider.classnames
+ org.glassfish.jersey.media.multipart.MultiPartFeature
+
+
+ 1
+
+
+ jaxrs.serviceClasses
+
+ org.wso2.financial.services.accelerator.demo.backend.services.PaymentService
+
+
+
+
+
+ VrpServiceJAXServlet
+ VrpService JAX-WS/JAX-RS Servlet
+ VrpService JAX-WS/JAX-RS Endpoint
+
+ org.apache.cxf.jaxrs.servlet.CXFNonSpringJaxrsServlet
+
+
+ service-list-stylesheet
+ servicelist.css
+
+
+ jersey.config.server.provider.classnames
+ org.glassfish.jersey.media.multipart.MultiPartFeature
+
+
+ 1
+
+
+ jaxrs.serviceClasses
+
+ org.wso2.financial.services.accelerator.demo.backend.services.VrpService
+
+
+
+
+
+ FundsConfirmationServiceJAXServlet
+ FundsConfirmationService JAX-WS/JAX-RS Servlet
+ FundsConfirmationService JAX-WS/JAX-RS Endpoint
+
+ org.apache.cxf.jaxrs.servlet.CXFNonSpringJaxrsServlet
+
+
+ service-list-stylesheet
+ servicelist.css
+
+
+ jersey.config.server.provider.classnames
+ org.glassfish.jersey.media.multipart.MultiPartFeature
+
+
+ 1
+
+
+ jaxrs.serviceClasses
+
+ org.wso2.financial.services.accelerator.demo.backend.services.FundsConfirmationService
+
+
+
+
+
+ AccountServiceJAXServlet
+ /services/accounts/*
+
+
+ PaymentServiceJAXServlet
+ /services/payments/*
+
+
+ VrpServiceJAXServlet
+ /services/domestic-vrps/*
+
+
+ FundsConfirmationServiceJAXServlet
+ /services/fundsConfirmation/*
+
+
+
+ 60
+
+
+
diff --git a/financial-services-accelerator/pom.xml b/financial-services-accelerator/pom.xml
index c2b8ba0d..ba196537 100644
--- a/financial-services-accelerator/pom.xml
+++ b/financial-services-accelerator/pom.xml
@@ -30,7 +30,6 @@
WSO2 Financial Services Accelerator
financial-services-accelerator
pom
- 4.0.0-SNAPSHOT
components/org.wso2.financial.services.accelerator.common
@@ -41,5 +40,6 @@
components/org.wso2.financial.services.accelerator.gateway
internal-webapps/org.wso2.financial.services.accelerator.consent.mgt.endpoint
internal-webapps/org.wso2.financial.services.accelerator.authentication.endpoint
+ internal-webapps/org.wso2.financial.services.accelerator.demo.backend
diff --git a/pom.xml b/pom.xml
index 879d236b..025a1d4e 100644
--- a/pom.xml
+++ b/pom.xml
@@ -373,6 +373,11 @@
javax.ws.rs-api
${javax.ws.rs-api.version}
+
+ javax.ws.rs
+ jsr311-api
+ ${javax.ws.rs.version}
+
org.apache.cxf
cxf-core
@@ -580,6 +585,7 @@
1.0.0.wso2v3
1.6.1
2.1.1
+ 1.1.1
5.1.2.RELEASE
2.5
3.3.7