Tenant Aware Load balancer

Tenant Aware Load Balancer is the upcoming Load Balancer from WSO2. Here in this article i will briefly describe it's architecture and how it works. 

Introduction
 
LoadBalancer
Load balancing is a key concern in a Platform-as-a-Service (PaaS) or a middleware platform deployed on the Cloud.
The primary functionality of a load balancer is to distribute the load of the incoming traffic amongst a set of back end worker nodes. This set of worker nodes can be either statically configured or can be dynamically discovered. In WSO2 carbon based products we use cluster messages which based on axis2 clustering to identify the node join to cluster or leave cluster.

Multi-tenancy - Tenant-aware Load Balancing
If a Cloud deployment has to be able to scale to thousands, hundreds of thousands or millions of tenants, we need tenant-partitioning. This means, for a single Cloud service, there will be multiple clusters, and each of these Service clusters will handle a subset of the tenants in the system. Creating dynamic tenant clusters & tenant partitioning strategies are some of the ongoing research areas. In such a tenant-partitioned deployment, the load balancers themselves need to be tenant-aware, in order to be able to route the requests to the proper tenant clusters. This means the load balancer has to be tenant-aware as well as Service-aware, since it is the Service clusters that are partitioned according to the tenants. WSO2 Load Balancer is now capable of routing messages in both tenant aware and service aware way.

How WSO2 Tenant Aware Load Balancer Works
Load Balancer's task is to distribute the load of the incoming traffic amongst a set of back end worker nodes.
We will see how this works now.
when the request comes in to Load Balancer we have to identify host header and determine cluster domain
Eg: Host header = https://appserver.cloud-test.wso2.com/t/ttt.ttt/carbon/admin/login.jsp
Service domain is appserver domain
Then determine tenant Id from the url. Here tenant domain is ttt.ttt so we can determine tenant domain.
These parameters can extract from host header.
Now we have both service domain and tenant domain. so with both of them we can direct this request to correct cluster as we defined in loadbalancer.conf. There we can configure services with their cluster domains and tenant ranges. When load balancer loads it picks those ranges and cluster domains.

See the following sample configuration . You can find those configuration under the “repository/conf” folder. There you will find loadbalancer.conf file.
appserver {
# multiple hosts should be separated by a comma.
hosts appserver.cloud-test.wso2.com;
domains {
wso2.as1.domain {
tenant_range 1-100;
}
wso2.as.domain {
tenant_range *;
}
}
}

Let’s examine this configuration.
Above configuration is for Application service with two service clusters. Let’s examine it line by line.
First line says appserver is the main node of this configurations.
In next line you will find hosts entries. There we have to add host address that maps to application server service. If you need to add multiple service domains add it with separated by commas.
Next you will find domains there you will find two domains with pre defined tenant ranges.
wso2.as1.domain named cluster is responsible for load tenants with tenant id 1 to 100
wso2.as.domain named cluster is responsible for load tenants with all tenants except the tenants belong to above range.
Then it can forward request to correct cluster based on service domain and tenant domain.

 
How Load Balance End Point works
For load balancing we are using synapse end point as a end point to determine how message should forward. So here we have defined external end point which is named as Tenant Aware Load Balance End point. It has logic to forward messages to correct back end node. We can define loadbalance end point in synapse main sequence.

In order to do this you have to change main sequence with correct load balance end point. If you need to implement your own custom load balancing implementation you can write your own end point and configure load balancer to use it.
 As an example we can load balance based on any other parameter which is available in request header (something similar to tenant domain). It's simple and straightforward.

See the following diagram to get general idea on how it works.


Advantages and other features of WSO2 Tenant Aware Load Balancer
  • Tenants are loaded in demand to the pre defined cluster based on the configurations in loadbalancer.conf.
  • Unload unused tenants after paticular predefined time.
  • Tenant Partitioning
  • Tenant may have multiple service clusters
  • Tenants will define the partitions.
  • When a new instance added, notify the LB instances.
  • Auto scaling - starting and terminating of instances based on the load. This supports any type of infrastructure as a service. What we have to do is write simple adapter to auto-scaler service based on the service vendor's API. It’s straight forward and simple. External components Autoscaler service can add, assign nodes into LB. So load Balancer is independent from the infrastructure that we are using.
  • Group communication between clusters using cluster messages.
  • Notifying all the load balancers when a new node is added to cluster.
  • Data partitioning(tenants data) - we can use this design to data partitioning based on the Geography or any other factors. As an example if we decide tenant 1 to 100 should loaded and store their data on United state we can deploy new application cluster at united states and inform it to loadbalancer. So we have to add configuration to loadbalancer.conf file saying tenant 1 to 100 are loaded at particular cluster(named as wso2.as.usa.domain). Then all requests come to the tenant 1 to 100 will forward to that cluster. so all data related to those tenants (Application files, databases) will stored at united state servers.
  • Private jet mode - Also we can assign some particular application cluster to specific tenant. Its like private jet. If you are willing to pay for entire cluster we can assign entire cluster for your tenant. This is again we can do using configurations at loadbalancer.conf file. So all request comes to that tenant will forward to that particular cluster.
  • Always running an additional cluster(Default cluster) to quickly load new tenant. This cluster is responsible for all newly created tenants in the system and super admin tenant. We can define this cluster in load balancer configuration file with * mark as upper tenant ID.  

After next release of WSO2 Load Balancer you will be able to use all above mentioned functionalities. Please visit  http://wso2.org/projects/load-balancer










How to avoid loading error in soapui on ubuntu 11.04 (ERROR [SoapUI] An error occured [no protocol: POECommonEPrescribeService-wsdl-soapui-project.xml])

 When you start soapui in ubuntu 11.04 you may see following error.

sanjeewa@sanjeewa-TECRA-M11:/media/9558-83FD/software/soapui-4.0.0/bin$ sh soapui.sh
================================
=
= SOAPUI_HOME = /media/9558-83FD/software/soapui-4.0.0
=
================================
Configuring log4j from [/media/9558-83FD/software/soapui-4.0.0/bin/soapui-log4j.xml]
10:55:27,301 INFO  [DefaultSoapUICore] initialized soapui-settings from [/media/9558-83FD/software/soapui-4.0.0/soapui-settings.xml]
10:55:29,001 INFO  [WorkspaceImpl] Loading workspace from [/media/9558-83FD/software/soapui-4.0.0/bin/../../TestPBE-workspace.xml]
10:55:29,285 INFO  [SoapUI] File [/media/9558-83FD/software/soapui-4.0.0/bin/POECommonEPrescribeService-wsdl-soapui-project.xml] does not exist, trying URL instead
10:55:29,285 ERROR [SoapUI] An error occured [no protocol: POECommonEPrescribeService-wsdl-soapui-project.xml], see error log for details
10:55:30,144 INFO  [SoapUI] Used java version: 1.6.0_21
Exception in thread "XpcMessageLoop" java.lang.RuntimeException: java.io.FileNotFoundException: Library libgthread-2.0 not found at any known locations !
    at com.jniwrapper.linux.utils.LinuxLibraryLoader.(LinuxLibraryLoader.java:90)
    at com.jniwrapper.gdk.GdkMultithreading.(GdkMultithreading.java:48)
    at com.jniwrapper.gdk.GdkMultithreading.getInstance(GdkMultithreading.java:35)
    at com.jniwrapper.gtk.GTK.initialize(GTK.java:97)
    at com.teamdev.xpcom.a.b.a.a.(Unknown Source)
    at com.teamdev.xpcom.XpcMessageLoop.(Unknown Source)
    at com.teamdev.xpcom.XpcMessageLoop.getInstance(Unknown Source)
    at com.teamdev.xpcom.b$a.run(Unknown Source)
Caused by: java.io.FileNotFoundException: Library libgthread-2.0 not found at any known locations !
    ... 8 more
You can fix this issue by disabling browser component. To do that open soapui.sh file locates inside bin folder of the soapui distribution and edit it. you have to uncomment following line.

 JAVA_OPTS="$JAVA_OPTS -Dsoapui.jxbrowser.disable=true"

Then save it and start soapui again.

Tenant Aware Load Balancer Concept

Tenant Aware Load Balancer is the upcoming Load Balancer from WSO2. If a Cloud deployment has to be able to scale to thousands, hundreds of thousands or millions of tenants, we need tenant-partitioning. This means, for a single Cloud service, there will be multiple clusters, and each of these Service clusters will handle a subset of the tenants in the system.Here i will briefly  describe about it. I will add complete article on this later.


  1. Tenants are loaded in demand and assign to a cluster
  2. Unloading the unused tenants.
  3. Notifying the load balancers when a tenant is loaded.
  4. by adding the Loadbalancers in to a group communication group and publishing a message to the group when a tenant is loaded.
  5. Can define statically tenants to each clusters
  6. Single service may have multiple clusters and each cluster is assigned in tp particular tenant range
  7. Always running an additional cluster(Default cluster) to quickly load new tenants.

Following diagram describes the overall design of tenant aware load balancer


Carbon Context and it's usages in WSO2 Products

A context can be defined as a construct that strictly bounds the execution environment. Because Carbon Context is a runtime container for your app(s) you gain the benefit of leveraging the Carbon Context runtime API allows to obtain contextual information about various actors utilizing your web apps and web services. For example, you may want to use registry,cache for that particular user or tenant. The carbon context allows you to access 5 APIs and has several utility methods. In each time we create user specific thing we create carbon context for that user to store specific things. This is valid for all WSO2 Carbon 3.2.2 based servers.

Here is the link to post written by regarding carbon context and its usages.
http://wso2.org/library/articles/2012/03/carbon-context-its-usages-wso2-products

How to trace inside the clone mediator and enable statistics and tracing for dynamic sequences

Trace inside the clone mediator and  enable statistics and tracing for dynamic sequences in WSO2 ESB

Here in this article i will try to brefly describe how to use WSO2 ESB samples and how to trace inside clone mediator.

You can download WSO2 ESB from here
http://wso2.com/products/enterprise-service-bus/

Starting the WSO2 ESB
Goto /bin folder run following command for ubuntu
> sh wso2server.sh
Run with sample here 0 is sample number
>sh wso2esb-samples.sh -sn 0

Log in to ESB as admin and
Goto Home> Configure > Logging > Service Bus Configuration by Clicking on source view. Then you will see synapse configuration source view.
Add following sequence to esb Configuration.


<sequence name="main" trace="enable" statistics="enable">
        <in>
            <clone>
                <target>
                    <sequence>
                        <log/>
                        <property name="a" value="a" scope="default"/>
                        <drop/>
                    </sequence>
                </target>
                <target>
                    <sequence>
                        <log/>
                        <property name="b" value="B" scope="default"/>
                        <drop/>
                    </sequence>
                </target>
            </clone>
        </in>
        <out>
            <send/>
        </out>
    </sequence>


As you can see here this will enable logs inside clone mediator. This will clone message and then add property a and b then drop the message.

Starting the Sample Apache Axis2 Server
Here we are using a standalone Apache Axis2 Web services engine(bundled with your ESB distribution) as the server
user@host:~/wso2esb/samples/axis2Server/src/SimpleStockQuoteService$ ant

now We have to start axis2server. Goto directory wso2esb-3.0.1/samples/axis2Server and type following command
wso2esb-3.0.1/samples/axis2Server$ sh axis2server.sh

To run sample client and send request to server goto folder wso2esb-3.0.1/samples/axis2Client and type following command
ant stockquote -Daddurl=http://localhost:9000/services/SimpleStockQuoteService -Dtrpurl=http://localhost:8280/

When you goto logs you will find logs related to 2 sequences inside clone mediator.See following logs
2012-02-29 14:43:12,029 [-] [HttpServerWorker-17] DEBUG Axis2SynapseEnvironment Injecting MessageContext for asynchronous mediation using the : Anonymous Sequence
2012-02-29 14:43:12,029 [-] [SynapseWorker-9] DEBUG PropertyMediator Setting property : a at scope : default to : a (i.e. constant : a)
2012-02-29 14:43:12,029 [-] [SynapseWorker-9] DEBUG PropertyMediator End : Property mediator
2012-02-29 14:43:12,030 [-] [SynapseWorker-10] DEBUG SequenceMediator Start : Sequence
2012-02-29 14:43:12,030 [-] [SynapseWorker-9] DEBUG DropMediator Start : Drop mediator
2012-02-29 14:43:12,030 [-] [SynapseWorker-9] DEBUG DropMediator End : Drop mediator
2012-02-29 14:43:12,030 [-] [HttpServerWorker-17] DEBUG CloneMediator End : Clone mediator
2012-02-29 14:43:12,030 [-] [SynapseWorker-9] DEBUG SequenceMediator End : Sequence
2012-02-29 14:43:12,030 [-] [SynapseWorker-10] DEBUG SequenceMediator Sequence :: mediate()



How to Load Balance across Cluster (setup WSO2 Load Balancer)

How to setup WSO2 Load Balancer

Load balancing is a key concern in a Platform-as-a-Service (PaaS) or a middleware platform deployed on the Cloud. An Elastic Load Balancer (ELB), in addition to carrying out its functionality in load balancing, is also responsible for monitoring the load & starting up new worker nodes or terminating existing worker nodes, depending on the load. An ideal use case of the Load Balancer is WSO2 StratosLive, where the service instances are fronted with the load balancers and the system scales automatically as the service gets more web service calls.  Here in this article we will see how to configure WSO2 Load Balancer Balance to use with Application server cluster

You can download WSO2 Application server from here http://wso2.com/products/application-server/
You can download WSO2 Load Balancer from here https://wso2.org/projects/load-balancer


1.Configure Application Server Cluster
Edit  mgt-transports.xml file as follows
Uncomment the HTTP proxy port in this file. The HTTP proxy port has to be set to port 80.

  
  1. <transport name="http" class="org.wso2.carbon.server.transports.http.HttpTransport">
  2.         <parameter name="protocol">HTTP_11_NIO</parameter>
  3.         <parameter name="port">${Ports.ServletTransports.HTTP}</parameter>
  4.         <parameter name="proxyPort">80</parameter>
  5.         <parameter name="maxHttpHeaderSize">8192</parameter>
  6.         <parameter name="acceptorThreadCount">2</parameter>
  7.         <parameter name="maxThreads">250</parameter>
  8.         <parameter name="minSpareThreads">50</parameter>
  9.         <parameter name="disableUploadTimeout">false</parameter>
  10.         <parameter name="connectionUploadTimeout">120000</parameter>
  11.         <parameter name="maxKeepAliveRequests">200</parameter>
  12.         <parameter name="acceptCount">200</parameter>
  13.         <parameter name="server">WSO2 Carbon Server</parameter>
  14.         <parameter name="compression">on</parameter>
  15.         <parameter name="compressionMinSize">2048</parameter>
  16.         <parameter name="noCompressionUserAgents">gozilla, traviata</parameter>
  17.         <parameter name="compressableMimeType">
  18.             text/html,text/javascript,application/x-javascript,application/javascript,
    application/xml,text/css,application/xslt+xml,text/xsl,image/gif,image/jpg,image/jpeg
  19.         </parameter>
  20.     </transport>
  21.     <transport name="https" class="org.wso2.carbon.server.transports.http.HttpTransport">
  22.         <parameter name="protocol">HTTPS_11_NIO</parameter>
  23.         <parameter name="port">${Ports.ServletTransports.HTTPS}</parameter>
  24.        <parameter name="proxyPort">443</parameter>
  25.         <parameter name="sslProtocol">TLS</parameter>
  26.         <parameter name="maxHttpHeaderSize">8192</parameter>
  27.         <parameter name="acceptorThreadCount">2</parameter>
  28.         <parameter name="maxThreads">250</parameter>
  29.         <parameter name="minSpareThreads">50</parameter>
  30.         <parameter name="enableLookups">false</parameter>
  31.         <parameter name="disableUploadTimeout">false</parameter>
  32.         <parameter name="connectionUploadTimeout">120000</parameter>
  33.         <parameter name="maxKeepAliveRequests">200</parameter>
  34.         <parameter name="acceptCount">200</parameter>
  35.         <parameter name="server">WSO2 Carbon Server</parameter>
  36.         <parameter name="clientAuth">false</parameter>
  37.         <parameter name="compression">on</parameter>
  38.         <parameter name="compressionMinSize">2048</parameter>
  39.         <parameter name="noCompressionUserAgents">gozilla, traviata</parameter>
  40.         <parameter name="compressableMimeType">
  41.             text/html,text/javascript,application/x-javascript,application/javascript,
     application/xml,text/css,application/xslt+xml,text/xsl,image/gif,image/jpg,image/jpeg
  42.         </parameter>
  43.         <parameter name="keystoreFile">
  44.             ${carbon.home}/repository/resources/security/wso2carbon.jks
  45.         </parameter>
  46.         <parameter name="keystorePass">wso2carbon</parameter>
  47.     </transport>


Edit carbon.xml In this file, we have to specify the Host of the App Server
   
<HostName>appserver.cloud-test.wso2.com</HostName>


Edit axis2.xml
In the axis2.xml file, you have to enable the clustering.
   
  1. <clustering class="org.apache.axis2.clustering.tribes.TribesClusteringAgent" enable="true">
  2.         <parameter name="AvoidInitiation">true</parameter>
  3.         <parameter name="membershipScheme">wka</parameter>
  4.         <parameter name="domain">wso2.as.domain</parameter>
  5.         <parameter name="synchronizeAll">true</parameter>
  6.         <parameter name="maxRetries">10</parameter>
  7.         <parameter name="mcastAddress">228.0.0.4</parameter>
  8.         <parameter name="mcastPort">45564</parameter>
  9.         <parameter name="mcastFrequency">500</parameter>
  10.         <parameter name="memberDropTime">3000</parameter>
  11.         <parameter name="localMemberPort">4100</parameter>
  12.         <parameter name="preserveMessageOrder">true</parameter>
  13.         <parameter name="atmostOnceMessageSemantics">true</parameter>
  14.         <parameter name="properties">
  15.             <property name="backendServerURL" value="https://${hostName}:${httpsPort}/services/"/>
  16.             <property name="mgtConsoleURL" value="https://${hostName}:${httpsPort}/"/>
  17.         </parameter>
  18.         <members>
  19.             <member>
  20.                 <hostName>appserver.cloud-test.wso2.com</hostName>
  21.                 <port>4000</port>
  22.             </member>
  23.         </members>

Keep rest of this xml file as it is.


2.Configure Load Balancer
Configuring the Load Balancer Cluster

locate the transportReceiver entries for the HTTP & HTTPS ports and change them to port 80 & 443 respectively. The relevant XML segments are shown below.
  
  1. <transportReceiver name="http" class="org.apache.synapse.transport.nhttp.HttpCoreNIOListener">
  2.         <parameter name="port" locked="false">80</parameter>
  3.         <parameter name="non-blocking" locked="false">true</parameter>
  4.         <!--parameter name="bind-address" locked="false">hostname or IP address</parameter-->
  5.         <!--parameter name="WSDLEPRPrefix" locked="false">https://apachehost:port/somepath</parameter-->
  6.         <parameter name="httpGetProcessor" locked="false">org.wso2.carbon.transport.nhttp.api.NHttpGetProcessor</parameter>
  7.     </transportReceiver>
  8.     <!-- the non blocking https transport based on HttpCore + SSL-NIO extensions -->
  9.     <transportReceiver name="https" class="org.apache.synapse.transport.nhttp.HttpCoreNIOSSLListener">
  10.         <parameter name="port" locked="false">443</parameter>
  11.         <parameter name="non-blocking" locked="false">true</parameter>
  12.         <!--parameter name="bind-address" locked="false">hostname or IP address</parameter-->
  13.         <!--parameter name="WSDLEPRPrefix" locked="false">https://apachehost:port/somepath</parameter-->
  14.         <parameter name="httpGetProcessor" locked="false">org.wso2.carbon.transport.nhttp.api.NHttpGetProcessor</parameter>
  15.         <parameter name="keystore" locked="false">
  16.             <KeyStore>
  17.                 <Location>repository/resources/security/wso2carbon.jks</Location>
  18.                 <Type>JKS</Type>
  19.                 <Password>wso2carbon</Password>
  20.                 <KeyPassword>wso2carbon</KeyPassword>
  21.             </KeyStore>
  22.         </parameter>
  23.         <parameter name="truststore" locked="false">
  24.             <TrustStore>
  25.                 <Location>repository/resources/security/client-truststore.jks</Location>
  26.                 <Type>JKS</Type>
  27.                 <Password>wso2carbon</Password>
  28.             </TrustStore>
  29.         </parameter>
  30.         <!--<parameter name="SSLVerifyClient">require</parameter>
  31.             supports optional|require or defaults to none -->
  32.     </transportReceiver>



Edit loadbalancer.xml to map the HTTP host to the clustering domain.Add following segment to services section
  
  1. <services>
  2.         <defaults>
  3.             <property name="availabilityZone" value="us-east-1c"/>
  4.             <property name="securityGroups" value="default-2011-02-23"/>
  5.             <property name="instanceType" value="m1.large"/>
  6.             <property name="minAppInstances" value="1"/>
  7.             <property name="maxAppInstances" value="5"/>
  8.             <property name="queueLengthPerNode" value="400"/>
  9.             <property name="roundsToAverage" value="10"/>
  10.             <property name="instancesPerScaleUp" value="1"/>
  11.             <property name="messageExpiryTime" value="60000"/>
  12.         </defaults>
  13.         <service>
  14.             <hosts>
  15.                 <host>appserver.cloud-test.wso2.com</host>
  16.             </hosts>
  17.             <domain>wso2.as.domain</domain>
  18.         </service>
  19.     </services>


Please note that appserver.cloud-test.wso2.com is mapped to 127.0.0.1 in my machine by changing /etc/hosts entries.Also change carbon.xml file located in appserver repository/conf by adding following entry.
   
<HostName>appserver.cloud-test.wso2.com</HostName>




Now you have to up and run load balancer product first then run appserver product. You will see following message in loadbalancer log when appserver joins to the load balance cluster.
[2012-02-23 17:34:12,048]  INFO - RpcMembershipRequestHandler Received JOIN message from 10.200.2.85:4100(wso2.as.domain)
[2012-02-23 17:34:12,052]  INFO - MembershipManager Application member 10.200.2.85:4100(wso2.as.domain) joined group wso2.as.domain
[2012-02-23 17:34:23,062]  INFO - DefaultGroupManagementAgent Application member Host:10.200.2.85, Port: 4100, HTTP:9763, HTTPS:9443, ACTIVE:true joined application cluster

Now you can invoke Application server by typing https://appserver.cloud-test.wso2.com:443/carbon/ URL in browser. So you will see the logs related to the requested page in loadbalancer logs.
To remove autoscale you have to remove autoscaler.xml file from wso2lb-1.0.2/repository/deployment/server/synapse-configs/default/tasks folder. Also remove autoscalein and autoscaleout configurations from main.sequence(from main.xml file located in wso2lb-1.0.2/repository/deployment/server/synapse-configs/default/sequences).

How to use SQS Client to invoke SQS service in message broker

  1. Create SQS Client Code

    Generate code from wsdltojava tool. See following figure





















    Unzip given zip file from wsdl to java tool and open it with some IDE(eclipse or idea). Use following command to create idea project
    mvn idea:idea

    Build project with maven using the command
    mvn clean install

    Then we have to add necessary jars to class path
    First run ant command inside your message broker product as follows
    packs/wso2mb-1.0.2/bin$ ant
    Then this will copy jars to repository/lib folder inside your pack. We have to add those jars to class path of created project(Eclipse or idea)















    Then build your project using ide. If it complaints about axiom or rampart jars please remove them from the class path(remove any axiom jars except version 1.2.11.wso2v1)

    Then add SQSClient java code to project. We must run the main method in this class in order to run the SQS operations. Code is available at following url http://wso2.org/project/message-broker/1.0.2/docs/samples/sqs_soap_client.html
    Change the "accessKey" and the "secretAccessKey" in sqsClient.java code to the keys which can be found at "Home > Manage> Message Boxes(SQS)> Access Keys" of wso2mb server














  1. Run sqsClient java code and you will see following output in terminal
    createQueueResponse.getCreateQueueResult().getQueueUrl() = http://localhost:9763/services/MessageQueue/admin/Shared
    createQueueResponse.getCreateQueueResult().getQueueUrl() = http://localhost:9763/services/MessageQueue/admin/Shared
    message_type0.getBody() = TEST MESSAGE
    message_type0.getBody() = TEST MESSAGE
    message_type0.getBody() = TEST MESSAGE
    message_type0.getBody() = TEST MESSAGE
    message_type0.getBody() = TEST MESSAGE
    message_type0.getBody() = TEST MESSAGE
    message_type0.getBody() = TEST MESSAGE
    message_type0.getBody() = TEST MESSAGE
    message_type0.getBody() = TEST MESSAGE
    message_type0.getBody() = TEST MESSAGE
    createQueueResponse.getCreateQueueResult().getQueueUrl() = http://localhost:9763/services/MessageQueue/admin/Shared
    createQueueResponse.getCreateQueueResult().getQueueUrl() = http://localhost:9763/services/MessageQueue/admin/Shared

Empowering the Future of API Management: Unveiling the Journey of WSO2 API Platform for Kubernetes (APK) Project and the Anticipated Alpha Release

  Introduction In the ever-evolving realm of API management, our journey embarked on the APK project eight months ago, and now, with great a...