Saturday, August 29, 2015

How to expose SOAP services as SOAP services via WSO2 API Manager?

Exposing SOAP services is well supported by WSO2 ESB. However, if you would like to have features such as design & prototype APIs, publish & govern API use, control access & enforce security, create a store where anyone can come, play around & subscribe to APIs, manage developer community and monitor API usage etc, then WSO2 API Manager is the ideal product. See here for a complete set of features offered by WSO2 API Manager.

In this post, we will see how you can expose a SOAP service as a SOAP service via WSO2 API Manager 1.9.0.

1. If you don't have any SOAP service, find a public SOAP service in http://www.service-repository.com

2. In this post, we will use StockQuote SOAP service from the above public service repository. Below are the details we should have in order to publish a SOAP service via WSO2 API Manager.

StockQuote SOAP WSDL - http://www.webservicex.com/stockquote.asmx?WSDL
StockQuote SOAP Endpoint - http://www.webservicex.com/stockquote.asmx

3. Download WSO2 API Manager 1.9.0 or latest version from here and start it. If you are new to WSO2 API Manager, visit the quick start guide

4. Login to API Publisher (https://localhost:9443/publisher)



5. Click on "Add" under "APIs" from the left menu



6. Click on "I have a SOAP Endpoint" option, provide your WSDL URL and click on "Start Creating"



7. In the "Design API" page, fill in the general details and click on "Next: Implement"



8. Click on "Managed API".



9. Fill in "Production Endpoint" and "Sandbox Endpoint" and click on "Next: Manage". If your endpoint is secured, have a look at this to learn how to configure a secured backend endpoint in WSO2 API Manager.



10. Select "Tier Availability" and "Transports" under "Configurations" and click "Save & Publish". You have now successfully published a SOAP service as a SOAP service via WSO2 API Manager.



11. Login to API Store (https://localhost:9443/store)


12. Click on your API and you will see a WSDL is published under "Overview" space of the API. Click "Download WSDL" and save it in your machine. Later we will use SoapUI to load this WSDL and invoke the API.



13.  Subscribe to the API using one of your Application and go to "My Subscriptions" page.



14. Click on "Generate keys" to generate consumer key & secret and access token. You will need this access token to invoke the API unless you have disable security to your API when publishing the API. See here to learn how to do that.



15. Create a new SOAP project in SoapUI using the WSDL you have downloaded in step 12.

16. Send a request and you will get following error. Reason is you haven't sent the access token as a bearer token when invoking the API.



17. Add a header "Authorization" and set the value as "Bearer #access-token". Replace #access-token with the access token you generated step 14.




18. Send the request and you will get the response.



As you can see, it is very straightforward to expose a SOAP service as a SOAP service via API Manager.

Saturday, August 15, 2015

WSO2 ESB - How to check whether a string is encoded or not?

The following sample demonstrate how to encode a string in WSO2 ESB and how to check whether a string is encoded or not.

<property name="string" value="abcd"/>
<property name="encodedString" expression="base64Encode('abcd')"/>
<log level="custom">
  <property name="encodedString" expression="get-property('encodedString')"/>
</log>
<filter source="get-property('encodedString')"
     regex="^([A-Za-z0-9+/]{4})*([A-Za-z0-9+/]{4}|[A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{2}==)$">
  <then>
     <log level="custom">
        <property name="encoded?" value="yes"/>
     </log>
  </then>
  <else>
     <log level="custom">
        <property name="encoded?" value="no"/>
     </log>
  </else>
</filter>

This is based on the regular expression given here to check whether a string is encoded or not.

Tuesday, July 14, 2015

WSO2 API Manager - Using Custom Handler or Mediation Extensions for Message Transformation?

Custom Handlers and Mediation Extensions are some of the extension points which you can use to extend the functionality of WSO2 API Manager. When it comes to message transformation, it is recommended to use Mediation Extensions over Custom Handlers due to following reasons.

  • If you want to engage a custom handler to all of your APIs, then you need to add it to all the APIs manually unless you modify velocity_template.xml to include the custom handler. If you are changing velocity_template.xml, then already published APIs won't have any impact. You need to republish those APIs to get the effect. On the other hand, if you copy a global mediation extension into AM, it will be engaged with all the APIs immediately.
  • If you decided not to do the transformation, then reverting changes is just a matter of removing mediation extensions from AM. On the other hand, if you are using a custom handler, then you have to remove the custom handler from all the APIs manually. Or else, you need to modify the velocity_template.xml and need to republish all your APIs.
  • If you are using a custom handler, it will be a maintenance overhead when it comes migration and all. If you are migrating, then you need to rebuild your custom handler with correct dependencies.
However, there might be some situations where we can't actually implement our usecase using inbuilt features. Then we should definitely go for a custom handler. For example, DBLookup mediator won't return multiple rows. Hence, while message transformation, if you want to retrieve multiple rows from the database, then you need to go for a custom handler.

As you can see, choice depends on many factors. As a simple rule, we need to use the mediation extensions wherever possible for message transformations within API Manager.

Saturday, July 11, 2015

Jclouds - How to terminate an instance without node-id

If you don't have the node-id of the instance , you can terminate an instance using its instance-id. Following code sample will destroy the instance using node-id, if node-id is available. If node-id is not available, it will use instance-id to destroy the node. Similarly you can terminate an instance using private IP, public IP and so on.

// if node-id is available
if (nodeId != null && !nodeId.isEmpty()) {
       jcloudComputeService.destroyNode(nodeId);
} else if (instanceId != null && !instanceId.isEmpty()) {
 // if instance-id is available
 jcloudComputeService.destroyNodesMatching(new Predicate<NodeMetadata>() {
  @Override
  public boolean apply(NodeMetadata input) {
   // if node id contains instance id
   if (input.getId() != null && !input.getId().isEmpty() 
     && instanceId != null && !instanceId.isEmpty() 
     && input.getId().contains(instanceId)) {
    }
    return true;
   }
   return false;
  }
 });
} else {
   // use other attributes like private IP or public IP to terminate
}

Friday, June 26, 2015

WSO2 ESB - How to print the current thread id in proxy?

You might want to print the current thread id for testing purposes in WSO2 ESB. It might be useful in cases where you want to make sure that the same thread is used for all the operations and no new threads were created. You can add following script mediator in your proxy to print the current thread id.
    <script language="js">java.lang.System.out.println(java.lang.Thread.currentThread().getId());</script>

WSO2 ESB - How to put the current thread into sleep in proxy?

You can add the following script mediator in your proxy to sleep the current thread.
    <script language="js">java.lang.Thread.sleep(10000);</script>

Tuesday, June 23, 2015

WSO2 Carbon Sever Startup Exception - Failed to activate Carbon Application Deployer

You might get the following exception while starting any WSO2 Carbon Server.

TID: [0] [IS] [2015-06-17 16:33:07,706] ERROR
{org.wso2.carbon.application.deployer.internal.AppDeployerServiceComponent} - Failed to activate Carbon Application Deployer {org.wso2.carbon.application.deployer.internal.AppDeployerServiceComponent} java.lang.ExceptionInInitializerError
at org.wso2.carbon.application.deployer.internal.ApplicationManager.findInitialHandlerCount(ApplicationManager.java:765)
at org.wso2.carbon.application.deployer.internal.ApplicationManager.init(ApplicationManager.java:107)
at org.wso2.carbon.application.deployer.internal.AppDeployerServiceComponent.activate(AppDeployerServiceComponent.java:77)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.eclipse.equinox.internal.ds.model.ServiceComponent.activate(ServiceComponent.java:260)
at org.eclipse.equinox.internal.ds.model.ServiceComponentProp.activate(ServiceComponentProp.java:146)
at org.eclipse.equinox.internal.ds.model.ServiceComponentProp.build(ServiceComponentProp.java:347)
at org.eclipse.equinox.internal.ds.InstanceProcess.buildComponent(InstanceProcess.java:620)
at org.eclipse.equinox.internal.ds.InstanceProcess.buildComponents(InstanceProcess.java:197)
at org.eclipse.equinox.internal.ds.Resolver.getEligible(Resolver.java:343)
at org.eclipse.equinox.internal.ds.SCRManager.serviceChanged(SCRManager.java:222)
at org.eclipse.osgi.internal.serviceregistry.FilteredServiceListener.serviceChanged(FilteredServiceListener.java:107)
at org.eclipse.osgi.framework.internal.core.BundleContextImpl.dispatchEvent(BundleContextImpl.java:861)
at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230)
at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148)
at org.eclipse.osgi.internal.serviceregistry.ServiceRegistry.publishServiceEventPrivileged(ServiceRegistry.java:819)
at org.eclipse.osgi.internal.serviceregistry.ServiceRegistry.publishServiceEvent(ServiceRegistry.java:771)
at org.eclipse.osgi.internal.serviceregistry.ServiceRegistrationImpl.register(ServiceRegistrationImpl.java:130)
at org.eclipse.osgi.internal.serviceregistry.ServiceRegistry.registerService(ServiceRegistry.java:214)
at org.eclipse.osgi.framework.internal.core.BundleContextImpl.registerService(BundleContextImpl.java:433)
at org.eclipse.osgi.framework.internal.core.BundleContextImpl.registerService(BundleContextImpl.java:451)
at org.wso2.carbon.core.init.CarbonServerManager.initializeCarbon(CarbonServerManager.java:517)
at org.wso2.carbon.core.init.CarbonServerManager.start(CarbonServerManager.java:219)
at org.wso2.carbon.core.internal.CarbonCoreServiceComponent.activate(CarbonCoreServiceComponent.java:77)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.eclipse.equinox.internal.ds.model.ServiceComponent.activate(ServiceComponent.java:260)
at org.eclipse.equinox.internal.ds.model.ServiceComponentProp.activate(ServiceComponentProp.java:146)
at org.eclipse.equinox.internal.ds.model.ServiceComponentProp.build(ServiceComponentProp.java:347)
at org.eclipse.equinox.internal.ds.InstanceProcess.buildComponent(InstanceProcess.java:620)
at org.eclipse.equinox.internal.ds.InstanceProcess.buildComponents(InstanceProcess.java:197)
at org.eclipse.equinox.internal.ds.Resolver.getEligible(Resolver.java:343)
at org.eclipse.equinox.internal.ds.SCRManager.serviceChanged(SCRManager.java:222)
at org.eclipse.osgi.internal.serviceregistry.FilteredServiceListener.serviceChanged(FilteredServiceListener.java:107)
at org.eclipse.osgi.framework.internal.core.BundleContextImpl.dispatchEvent(BundleContextImpl.java:861)
at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230)
at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148)
at org.eclipse.osgi.internal.serviceregistry.ServiceRegistry.publishServiceEventPrivileged(ServiceRegistry.java:819)
at org.eclipse.osgi.internal.serviceregistry.ServiceRegistry.publishServiceEvent(ServiceRegistry.java:771)
at org.eclipse.osgi.internal.serviceregistry.ServiceRegistrationImpl.register(ServiceRegistrationImpl.java:130)
at org.eclipse.osgi.internal.serviceregistry.ServiceRegistry.registerService(ServiceRegistry.java:214)
at org.eclipse.osgi.framework.internal.core.BundleContextImpl.registerService(BundleContextImpl.java:433)
at org.eclipse.equinox.http.servlet.internal.Activator.registerHttpService(Activator.java:81)
at org.eclipse.equinox.http.servlet.internal.Activator.addProxyServlet(Activator.java:60)
at org.eclipse.equinox.http.servlet.internal.ProxyServlet.init(ProxyServlet.java:40)
at org.wso2.carbon.tomcat.ext.servlet.DelegationServlet.init(DelegationServlet.java:38)
at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:1267)
at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1186)
at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:1081)
at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:5027)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5314)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1559)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1549)
at java.util.concurrent.FutureTask.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.NullPointerException
at org.wso2.carbon.application.deployer.AppDeployerUtils.createDir(AppDeployerUtils.java:713)
at org.wso2.carbon.application.deployer.AppDeployerUtils.(AppDeployerUtils.java:77)
... 63 more

Here is the reason why this exception can be thrown and how to solve it.


At the startup of a Carbon Server (ESB, IS, APIM, etc), it creates a directory named "work" under the location "$CARBON_HOME/repository/carbonapps/". We will see the above exception, if it fails to create this particular directory at the startup. There can be several reason for this. Some of them are,
  • It could be a permission issue in the file system. To solve it, change the permission.
  • It could be because the "$CARBON_HOME/repository/carbonapps/" directory does not exist. It can happen with some unzipping tools as they don't extract recursive empty folders. The carbonapps folder is an empty folder which is included in any Carbon Server pack by default. You can either create this directory manually or use a correct unzipping tools to solve this issue.
 Double checking above two things will probably solve this issue.

WSO2 ESB - Dynamic JMS Endpoint

Address endpoint doesn't support dynamic endpoints. Hence if you want to have dynamic endpoint for your JMS queue, you can use default endpoint together with a "To" header which you can set dynamically. Here is a sample JMS proxy.

<proxy xmlns="http://ws.apache.org/ns/synapse"
       name="StockQuoteProxy"
       transports="http"
       statistics="disable"
       trace="disable"
       startOnLoad="true">
   <target>
      <inSequence>
         <property name="OUT_ONLY" value="true"/>
         <property name="sendToThisQueue" value="SimpleStockQuoteService"/>
         <header name="To"
                 expression="fn:concat('jms:/', get-property('sendToThisQueue'), '?transport.jms.ConnectionFactoryJNDIName=QueueConnectionFactory&amp;java.naming.factory.initial=org.apache.activemq.jndi.ActiveMQInitialContextFactory&amp;java.naming.provider.url=tcp://localhost:61616')"/>
         <send>
            <endpoint name="dynamicQueue">
               <default>
                  <timeout>
                     <duration>300000</duration>
                     <responseAction>fault</responseAction>
                  </timeout>
                  <suspendOnFailure>
                     <errorCodes>-1</errorCodes>
                     <initialDuration>0</initialDuration>
                     <progressionFactor>1.0</progressionFactor>
                     <maximumDuration>0</maximumDuration>
                  </suspendOnFailure>
                  <markForSuspension>
                     <errorCodes>-1</errorCodes>
                  </markForSuspension>
               </default>
            </endpoint>
         </send>
      </inSequence>
      <outSequence>
         <send/>
      </outSequence>
   </target>
   <publishWSDL uri="file:repository/samples/resources/proxy/sample_proxy_1.wsdl"/>
   <description/>
</proxy>          


The idea behind is that you can set "To" header dynamically and the default endpoint will send the messages out to the endpoint found in "To" header.

Saturday, May 23, 2015

WSO2 BAM behind reverse proxy using Apache HTTP Server

When you deploy WSO2 BAM in production, you often need to deploy it behind a proxy server or load balancer. We will see how to configure BAM behind Apache HTTP Server as reverse proxy.

Apache HTTP Server Configuration


  • Install and configure Apache HTTP server
  • Enable following modules using a2enmod
  • Run the following command
  • Create a certificate and a key for Apache HTTP server. You will use these when you define a new virtual host
  • Add the following entries to your */etc/hosts* file
  • Create a virtual host like below. You can add this to /etc/apache2/sites-available/default-ssl.conf file
  • Restart Apache HTTP server

 

BAM Configuration


  • Uncomment and modify both HostName and MgtHostName in $BAM_HOME/repository/carbon.xml
  • Uncomment and modify ProxyContextPath in $BAM_HOME/repository/carbon.xml

Now you should be able access the BAM using following URLs

Management console - https://bamproxy.example.com/bamcarbon
Message console - https://bamproxy.example.com/messageconsole
Activity monitoring - https://bamproxy.example.com/activitymonitoring
BAM dashboards - https://bamproxy.example.com/bamdashboards

WSO2 ESB - Logging VFS Transport Logs to a Different Log File

If you enable DEBUG logs for VFS transport, it might poison the default wso2carbon.log file. Instead, you can do the following configurations to write VFS transport logs to a different log file, while these logs won't be written to default wso2carbon.log

  1. Add the following configurations to $ESB_HOME/repository/conf/log4j.properties file
  2. log4j.logger.org.apache.synapse.transport.vfs=DEBUG, CARBON_VFS_LOGFILE
    log4j.additivity.org.apache.synapse.transport.vfs = false
     
    log4j.appender.CARBON_VFS_LOGFILE=org.wso2.carbon.logging.appenders.CarbonDailyRollingFileAppender
    log4j.appender.CARBON_VFS_LOGFILE.File=${carbon.home}/repository/logs/${instance.log}/wso2carbon-vfs${instance.log}.log
    log4j.appender.CARBON_VFS_LOGFILE.Append=true
    log4j.appender.CARBON_VFS_LOGFILE.layout=org.wso2.carbon.utils.logging.TenantAwarePatternLayout
    log4j.appender.CARBON_VFS_LOGFILE.layout.ConversionPattern=TID: [%T] [%S] [%d] %P%5p {%c} - %x %m {%c}%n
    log4j.appender.CARBON_VFS_LOGFILE.layout.TenantPattern=%U%@%D [%T] [%S]
    log4j.appender.CARBON_VFS_LOGFILE.threshold=DEBUG
    
    
  3. Restart ESB
  4. A new wso2carbon-vfs.log file will be created in $ESB_HOME/repository/logs directory.

Sunday, January 18, 2015

Apache Stratos VM Cartridges

This is another part of A Series of Blog Posts on Apache Stratos Cartridges. We will go through VM Cartridges in this blog post. Please hit Apache Stratos Cartridges if you haven’t read it before.

Apache Stratos VM Cartridges

A VM cartridge is a virtual machine (VM) on an IaaS that has software components to interact with Apache Stratos.

Components of a VM Cartridge

A generic VM cartridge includes Operating System, Puppet Agent, Init Scripts as shown below;
Generic Cartridge.png
A base image or an AMI will contain all these components and the VM will be spawned from this base image. All the other softwares such as Cartridge Agent and Server Apps will be installed at runtime using configuration management tools like Puppet or Chef.

A fully configured cartridge includes Operating System, Puppet Agent, Init Scripts, Cartridge Agent, Server Apps, and any other Dependent Apps as shown below;
Fully Configured Cartridge.png
All the needed softwares are already installed in the base image. Nothing will be installed at runtime, hence cartridge instance will be ready for use as soon as the instance is spawned.

Lets go through each components.

Base Image

As mentioned above, a generic base image will contain OS, Puppet Agent and Init Scripts, a fully configured base image will contain OS, Puppet Agent, Init Scripts, Cartridge Agent, Server Apps, and any other dependent apps. Stratos will use the base image to spawn cartridge instances.

Hit Creating a Cartridge to learn how to create a base image in various IaaSes.

Puppet Agent

The job of the Puppet Agent is to talk with Puppet Master periodically and configure itself according to Puppet Master’s instructions. Hit Puppet Labs to learn about puppet.

Init Scripts

It will start the Puppet Agent at the instance startup, so that Puppet Agent will connect to Puppet Master and do the node configuration.

Cartridge Agent

Cartridge Agent is a component that resides within a cartridge instance and handles the communication between the cartridge and Stratos. Hit Cartridge Agent for more information.

Server Apps

These are your applications such as Tomcat, PHP, MySQL, Wordpress, Ruby etc which you want to run on top of Stratos.

Dependent Apps

These are any apps which are needed for your Server Apps.

Puppet Master

Puppet Master contains all the puppet modules for cartridges.Hit Puppet Labs to learn about puppet.

Puppet Modules

Puppet Modules are self-contained bundles of code and data .Puppet master contains all the puppet modules for cartridges in Stratos. Hit How Cartridge Puppet Modules are organized in Apache Stratos? for more information.

Put it all together

Lets put all the components together and understand how cartridge works.
  • A cartridge deployer deploys a cartridge by giving details such as service name (a.k.a cartridge type), IaaS configuration details, base image id and the region where it resides, etc. Stratos will validate these information, update its in-memory and store these in the registry. 
  • A cartridge subscriber comes and subscribe to a cartridge. Stratos will spawn a new instance using the base image. In addition Stratos will send a payload with some information such as server name, puppet master name and IP, cluster id and so on. 
  • When a new VM (cartridge instance) is started, the Init Script will be executed at the instance boot up. This Init Script in turn will start the Puppet Agent. 
  • Meanwhile, Stratos will set the hostname of the new VM to a random string with service name as substring. 
  • When the Puppet Agent is started, it will talk with Puppet Master. Puppet Master has instructions about how each nodes should be configured. To be more specific, it has instructions about how each cartridge instance of a particular cartridge (service type) to be configured. Puppet Agent will configure the cartridge instance according to what is defined in Puppet Master for its service name by string matching the hostname. 
  • Once Puppet Agent configures everything successfully, Cartridge Agent within cartridge instance will start to communicate with Stratos. At one point, it will publish instance activated event to message broker. Thereafter this cartridge instance will be considered as an active instance and ready to accept traffic.
That is an end-to-end process from cartridge deployment to subscription to instance creation to instance configuration to instance activation.

Next thing to do

Now you have learned about VM Cartridges. Hit How to create a VM Cartridge? if you want to create a VM Cartridge. Hit Apache Stratos Docker Cartridges if you want to learn about Docker Cartridges.

References

Tuesday, January 13, 2015

A Series of Blog Posts on Apache Stratos Cartridges

Are you looking for a way to start contributing to Apache Stratos? You hit the right page!

The best way to start contributing to Apache Stratos is through developing and testing Cartridges. As I found there are not much useful guides for Stratos cartridge developers, I am writing a series of blog posts on Apache Stratos Cartridges to help those who wish to contribute to Apache Stratos. You will be able to contribute a good quality cartridge to Apache Stratos project by following this blog series.

Blog 5 - How to create a Docker Cartridge?

I will add some more advanced topics to this series later. If you want any specific topic on Apache Stratos Cartridges, feel free to leave a comment here.

Apache Stratos Cartridges

Apache Stratos

Apache Stratos is a highly-extensible Platform-as-a-Service (PaaS) framework from the Apache Community that anyone can use to build a foundation for multiple flavors of Platform as a Services such as Application PaaS (aPaaS), Integration PaaS (iPaaS), or Data PaaS (dPaaS). You should be clear that Stratos is not a PaaS, but can be used to build a PaaS. You can deploy Stratos on top of an IaaS and deploy any application such as Application Servers, Enterprise Service Buses, API Managers etc, on top of Stratos. Stratos takes care of your applications and provides features such as load balancing, auto-scaling, cloud bursting, multi tenancy, billing, monitoring, fault handling and much more.

Please visit Apache Stratos website for more information.

Cartridges

Stratos manages applications using cartridges. A cartridge is a virtual machine (VM) or a Container on an IaaS that has software components to interact with Apache Stratos. For example, a Tomcat cartridge is a Ubuntu virtual machine on Amazon EC2 IaaS with Tomcat server environment (Java + Tomcat) installed.  
 
All cartridges in Apache Stratos provide a very secure, OS level isolated environment for cloud applications. If you subscribe to a cartridge you will get a cartridge instance.

Cartridge Instances

If you subscribe to a cartridge, Stratos will spawn a new VM or Container on an IaaS, and that new VM or Container will be referred to as Cartridge Instance in Stratos terminology.

Cartridge Types

According to the mode of operation, cartridges can be divided into single tenant or multi tenant cartridges. According to the creation methods, cartridges can be divided into generic or fully configured cartridges. According to the virtualization technology, cartridges can be divided into VM or Docker cartridges.

Single Tenant Cartridges

In Apache Stratos, if a tenant user subscribes to a single tenant cartridge, a separate cartridge instance will be spawned for each tenant user. Thereby, single tenant cartridges provide tenant users process level isolation and instance level dedicated tenancy. Single tenant cartridge users can be mapped to one or more cartridge instances.

Multi Tenant Cartridges

Multi-tenant cartridges in Apache Stratos are cartridges that allow multiple tenants to share a single cartridge instance. Although tenant users share a single cartridge instance, the tenant user traffic will be securely directed to isolated application code within the cartridge instance.

Generic Cartridges

A generic cartridge is a cartridge where all the software needed for the cartridge instance are installed only at run-time when a cartridge instance is spawned. It only have the base image operating system (OS) and Puppet Agent (PA) pre-installed with some setup scripts. For example, a generic VM cartridge looks like below;

Fully Configured Cartridges

A fully configured cartridge also known as a pre-configured cartridge is a cartridge where all the software and configurations are pre-configured. Fully configured cartridges include the base image operating system (OS), setup scripts, required software, Puppet Agent (PA) and Cartridge Agent (CA). For example, a fully configured VM cartridge looks like below;
Fully Configured Cartridge.png 
Generic cartridges are slower than fully configured cartridges since all the software will be installed and configured at runtime.

VM Cartridges
A VM cartridge is a virtual machine (VM) on an IaaS that has software components, such as puppet agent, cartridge agent, server apps and any dependent apps, to interact with Stratos.

Please refer Apache Stratos VM Cartridges for more information.

Docker Cartridges

As per now, a Docker cartridge is a container on a coreos cluster configured on an IaaS that has software components, such as cartridge agent, server apps and any dependent apps, to interact with Stratos.

Please refer Apache Stratos Docker Cartridges for more information.

Next thing to do
Now you learned something about Apache Stratos Cartridges. If you are willing to learn more about VM Cartridges, please refer Apache Stratos VM Cartridges. If you are willing to learn more about Docker Cartridges, please refer Apache Stratos Docker Cartridges.