Tuesday, March 25, 2014

How to write a SaaS app on Stratos

Wikipedia defines software as a service (SaaS) as; "On-demand software provided by an application service provider." "A software delivery model in which software associated data are centrally hosted in the cloud."

Gartner defines SaaS as; "Software that is owned, delivered and managed remotely by one or more providers. The provider delivers software based on one set of common code and data definitions that is consumed in a one-to-many model by all contracted customers at anytime on a pay-for-use basis or as a subscription based on use metrics."


Typical Application Vs SaaS

  11.png


SaaS Technical Requirements
1. Elastic
       Scales up and down as needed.
       Works with the underlying IaaS.
2. Self-service
       De-centralized creation and management of tenants.
       Automated Governance across tenants.
3. Multi-tenant
       Virtual isolated instances with near zero incremental cost.
       Implies you have a proper identity model.
4. Granularly Billed and Metered
       Allocate costs to exactly who uses them.
5. Distributed/Dynamically Wired
       Supports deploying in a dynamically sized cluster.
       Finds services across applications even when they move.
6. Incrementally Deployed and Tested
       Supports continuous update, side-by-side operation, in-place testing and
       incremental production.


A cloud platform offers,

  • Automated Provisioning.
  • Versioning.
  • Lifecycle management.
  • Infrastructure as a Service.
  • Virtualization.
  • Federated Identity Management.
  • Clustering.
  • Caching.
  • Billing and Metering.


WSO2 Stratos

 st.png


  • WSO2 Stratos is WSO2’s Cloud Middleware Platform(CMP).
  • A complete SOA platform.
  • In private cloud or public cloud.
  • 100% Open Source under Apache licence.
  • Can run on top of any Cloud IaaS.
  • WSO2 StratosLive is the PaaS offering by WSO2.
  • Significantly ahead of the competition.
  • Stratos is the only 100% Open Source, Open Standards option.
  • Based on OSGi - modular, componentized, standard.

Cloud Native features supported in Stratos
  • Elasticity.
  • Multi-tenancy.
  • Billing and Metering.
  • Self Provisioning.
  • Incremental Testing.

Super Tenant SaaS Applications Vs Tenant SaaS Applications

Tenant SaaS application do not have certain permissions and will not be able to access or modify other tenant's data where the super tenant applications have full controllability and permissions.


Tenant SaaS Web Applications
 Configure security in web.xml

slide-37-638.jpg
23.png

Super Tenant SaaS Application can access tenant's user level information. It uses org.wso2.carbon.context.PrivulegedCarbonContext to access tenant's information such as registry, cache, tenant manager, queue, etc.

Resources

[1]A sample is available at https://svn.wso2.org/repos/wso2/scratch/thilini/SaasTest/
[2]Creating a SaaS App with the Multi-Tenant Carbon Framework: http://blog.cobia.net/cobiacomm/2013/09/10/creating-a-saas-app-with-the-multi-tenant-carbon-framework-step-1/
[3]Webinar on Building and Deploying SaaS Applications: https://www.youtube.com/watch?v=_lEwm6VzAmo

Wednesday, December 12, 2012

Approval based user registration process for WSO2 AppFactory


Human-in-the-Loop


 1. User enters information to register in the Appfactory

 2. User gets a notification 'Registration request has been submitted and it's under approval'

 3. Admin logins to the system

 4. Checking the available tasks

 5. User registration request is available in the Claimable Task list (Task is in READY state)


 6. Admin progressing the task (Task moves from READY to IN_PROGRESS state)


 7. Admin performs 'Approve' or 'Reject'  to complete the task


 8. Task moves from IN_PROGRESS to COMPLETED state


Now the task is no longer in Claimable or MyTasks categories. Earlier performed tasks can only be found in AllTasks list.

If the approval is done by the administrator, new user gets an email with login instructions.

In the next post, I'll discuss how this has been implemented using bpel, humantasks and 
jaggery(jaggery UI).

Monday, October 22, 2012

How to secure a BPEL Process

Here we will learn how to secure a BPEL process, so that it can only be accessed by authenticated users. 

In a nutshell, we will,
  • Create and protect a BPEL process by user authentication, the process is exposed as a service which requires providing a username and password inside the UsernameToken of the WS-Security specification.
In tutorial part 1 and 2, we learnt how to create a WS-BPEL process. Now we are going to enable security in that process.

[1] Enable security after the deployment
Add a security scenario (for eg: scenario 1, that is UsernameToken) using the Management Console.

[2] Enable security at the deployment time
This is vital when it comes to securing BPELs. Here we are following a service.xml based approach. The BPEL package contains an additional configuration(xml) file to keep the security policy. A sample BPEL process can be found here.

ServicePasswordCallbackHandler is the default password callbackhandler in Carbon, it  resides in the org.wso2.carbon.security package. If you prefer, you can create your own password callback handler and refer it in the policy configuration, so that it will overwrite the default handler;
<rampart:passwordCallbackClass>org.wso2.carbon.appfactory.pwcb.PWCBHandler</rampart:passwordCallbackClass>


Copy password callback handler jar to BPS_HOME/repository/components/lib directory and restart the server.

              






Invoking WSO2 Carbon Admin Services using BPEL

(1) UEP Approach [Relevant to: BPS 3.0.0]
Add basic auth credentials (username and password) as http headers in unified endpoint configuration.

A sample configuration (.epr) is shown below.

<wsa:EndpointReference
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.w3schools.com uep_schema.xsd"
        xmlns:wsa="http://www.w3.org/2005/08/addressing"
        xmlns:wsdl11="http://schemas.xmlsoap.org/wsdl/">
   <wsa:Address>https://localhost:9443/services/UserRegistrationService</wsa:Address>
   <wsa:Metadata>
           <id>SInvokeEPR</id>
           <transport type="http">
     <authorization-username>admin</authorization-username>
    <authorization-password>admin</authorization-password>
           </transport>
       </wsa:Metadata>
</wsa:EndpointReference>

A Sample is available at [1].


(2) Using a proxy service [Relevant to: BPS 3.0.0 and older (carbon 3.2.* ) versions]
First login to AuthenticationAdmin service and get a authenticated cookie, that cookie value can be used for all subsequent invocations.

  • BPEL process invokes the login method in the AuthenticationAdminProxy service which in turn invokes the backend servers' AuthenticationAdmin service. On the return path, this proxy service retrieves the authenticated cookie and sends to BPEL as value in the SOAP message, so the BPEL can keep this value in a variable.
  • For all the subsequent requests from the BPEL process, it sends this cookie to the corresponding proxy services. These proxy services set the cookie as a HTTP header and invoke the backend service.

Monday, October 15, 2012

Part 2: Developing a WS-BPEL Process using WSO2 Developer Studio


Tutorial 1 is a step by step instruction to implement a bpel process using WSO2 Developer Studio and deploy on WSO2 Business Process Server.

Today with tutorial 2, I am going to develop a BPEL process (let's call it as FunctionProcess) which has multiple service invocations. This is also going to be a synchronous  process as it does not involve any long-lasting operations. If you have already followed-up tutorial 1, then follow up of tutorial 2 is real easy.

The following flowchart illustrates the bpel process that we are going to develop in this tutorial.


Figure 1

This can simply be shown using an equation as follows.

f(x) = [(a * b) - (a + b) ]^2

Now we are going to design it using WSO2 Developer Studio, BPEL editor. 

Here, we have four service invocations, meaning that four Invoke activities such as InvokeMultiplyService, InvokeAdderService, InvokeSubtractService and InvokeSquareService.

Multiply and Adder activities are not depending on each other, or in other words, these activities can be invoked concurrently. So that they will be defined inside a flow activity (<flow/>) as shown in Figure 2.

Figure2
Open the FunctionProcessArtifacts.wsdl and click on the arrow next to FunctionProcessRequest.  Add two integer elements as shown in Figure 3.
Figure 3

Open the FunctionProcessArtifacts.wsdl and click on the arrow next to FunctionProcessResponse. Add resulting integer element.
Figure4

Let's configure four Assign activities. The source is given for each assign activity below, if you need to know how to do this with Developer Studio Graphical Editor, please follow-up tutorial 1.

AssignActivityInputParams Configuration
<bpel:assign validate="no" name="AssignInputParams">
            <bpel:copy>
                <bpel:from>
                    <bpel:literal>
                        <ns:add xmlns:ns="http://demo.carbon.wso2.org" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
                            <ns:a>0</ns:a>
                              <ns:b>0</ns:b>
                        </ns:add>
                    </bpel:literal>
                </bpel:from>
                <bpel:to variable="adderPLRequest" part="parameters"></bpel:to>
            </bpel:copy>
            <bpel:copy>
                <bpel:from>
                    <bpel:literal>
                        <ns:multiply xmlns:ns="http://demo.carbon.wso2.org" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
                            <ns:a>0</ns:a>
                              <ns:b>0</ns:b>
                        </ns:multiply>
                    </bpel:literal>
                </bpel:from>                
                <bpel:to variable="multiplyPLRequest" part="parameters"></bpel:to>
            </bpel:copy>            
            <bpel:copy>
                <bpel:from part="payload" variable="input">
                    <bpel:query queryLanguage="urn:oasis:names:tc:wsbpel:2.0:sublang:xpath1.0"><![CDATA[tns:a]]></bpel:query>
                </bpel:from>
                <bpel:to part="parameters" variable="multiplyPLRequest">
                    <bpel:query queryLanguage="urn:oasis:names:tc:wsbpel:2.0:sublang:xpath1.0"><![CDATA[ns:a]]></bpel:query>
                </bpel:to>
            </bpel:copy>          
            <bpel:copy>
                <bpel:from part="payload" variable="input">
                    <bpel:query queryLanguage="urn:oasis:names:tc:wsbpel:2.0:sublang:xpath1.0"><![CDATA[tns:b]]></bpel:query>
                </bpel:from>
                <bpel:to part="parameters" variable="multiplyPLRequest">
                    <bpel:query queryLanguage="urn:oasis:names:tc:wsbpel:2.0:sublang:xpath1.0"><![CDATA[ns:b]]></bpel:query>
                </bpel:to>
            </bpel:copy>
            <bpel:copy>
                <bpel:from part="payload" variable="input">
                    <bpel:query queryLanguage="urn:oasis:names:tc:wsbpel:2.0:sublang:xpath1.0"><![CDATA[tns:a]]></bpel:query>
                </bpel:from>
                <bpel:to part="parameters" variable="adderPLRequest">
                    <bpel:query queryLanguage="urn:oasis:names:tc:wsbpel:2.0:sublang:xpath1.0"><![CDATA[ns:a]]></bpel:query>
                </bpel:to>
            </bpel:copy>
            <bpel:copy>
                <bpel:from part="payload" variable="input">
                    <bpel:query queryLanguage="urn:oasis:names:tc:wsbpel:2.0:sublang:xpath1.0"><![CDATA[tns:b]]></bpel:query>
                </bpel:from>
                <bpel:to part="parameters" variable="adderPLRequest">
                    <bpel:query queryLanguage="urn:oasis:names:tc:wsbpel:2.0:sublang:xpath1.0"><![CDATA[ns:b]]></bpel:query>
                </bpel:to>
            </bpel:copy>
        </bpel:assign>




 AssignActivity2 Configuration
<bpel:assign validate="no" name="AssignActivity2">
            <bpel:copy>
                <bpel:from>
                    <bpel:literal>
                        <ns:substract xmlns:ns="http://demo.carbon.wso2.org" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
                            <ns:a>0</ns:a>
                            <ns:b>0</ns:b>
                        </ns:substract>
                    </bpel:literal>
                </bpel:from>
                <bpel:to variable="subtractPLRequest" part="parameters"></bpel:to>
            </bpel:copy>            
            <bpel:copy><bpel:from part="parameters" variable="multiplyPLResponse">
                    <bpel:query queryLanguage="urn:oasis:names:tc:wsbpel:2.0:sublang:xpath1.0"><![CDATA[ns:return]]></bpel:query>
                </bpel:from>
                <bpel:to part="parameters" variable="subtractPLRequest">
                    <bpel:query queryLanguage="urn:oasis:names:tc:wsbpel:2.0:sublang:xpath1.0">
                        <![CDATA[ns:a]]>
                    </bpel:query>
                </bpel:to>            
            </bpel:copy>
            <bpel:copy><bpel:from part="parameters" variable="adderPLResponse">
                    <bpel:query queryLanguage="urn:oasis:names:tc:wsbpel:2.0:sublang:xpath1.0">
                        <![CDATA[ns:return]]>
                    </bpel:query>
                </bpel:from>
                <bpel:to part="parameters" variable="subtractPLRequest">
                    <bpel:query queryLanguage="urn:oasis:names:tc:wsbpel:2.0:sublang:xpath1.0">
                        <![CDATA[ns:b]]>
                    </bpel:query>
                </bpel:to>            
            </bpel:copy> </bpel:assign>



 AssignActivity3 Configuration

             <bpel:assign validate="no" name="AssignActivity3"> 
              <bpel:copy>
                <bpel:from>
                    <bpel:literal>
                        <ns:square xmlns:ns="http://demo.carbon.wso2.org" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
                            <ns:a>0</ns:a>
                        </ns:square>
                    </bpel:literal>
                </bpel:from>
                <bpel:to variable="squarePLRequest" part="parameters"></bpel:to>
            </bpel:copy>
            <bpel:copy>
                <bpel:from part="parameters" variable="subtractPLResponse">
                    <bpel:query queryLanguage="urn:oasis:names:tc:wsbpel:2.0:sublang:xpath1.0"><![CDATA[ns:return]]></bpel:query>
                </bpel:from>
                <bpel:to part="parameters" variable="squarePLRequest">
                    <bpel:query queryLanguage="urn:oasis:names:tc:wsbpel:2.0:sublang:xpath1.0"><![CDATA[ns:a]]></bpel:query>
                </bpel:to>
            </bpel:copy>            
        </bpel:assign>



AssignOutputParams Configuration
      <bpel:assign validate="no" name="AssignOutputParams">
            <bpel:copy>
                <bpel:from>
                    <bpel:literal>
                        <tns:FunctionProcessResponse xmlns:tns="http://wso2.org/bps/sample" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
                            <tns:result>0</tns:result>
                        </tns:FunctionProcessResponse>
                    </bpel:literal>
                </bpel:from>
                <bpel:to variable="output" part="payload"></bpel:to>
            </bpel:copy>
            <bpel:copy>
                <bpel:from part="parameters" variable="squarePLResponse">
                    <bpel:query queryLanguage="urn:oasis:names:tc:wsbpel:2.0:sublang:xpath1.0"><![CDATA[ns:return]]></bpel:query>
                </bpel:from>
                <bpel:to part="payload" variable="output">
                    <bpel:query queryLanguage="urn:oasis:names:tc:wsbpel:2.0:sublang:xpath1.0"><![CDATA[tns:result]]></bpel:query>
                </bpel:to>
            </bpel:copy>
        </bpel:assign>


Now we have completed, implementation of the business logic  of our work flow.
 
Figure 5

Configuring deployment descriptor(deploy.xml)

This process has 4 service invocations, therefore there should have four partnerlinks in the outbound interface section.

Figure 6

Now we have completed the bpel process development. Let's deploy it on WSO2 BPS and test the flow.
Make sure to deploy four external(partner) services on a AppServer.

Testing the bpel process with TryIt (or with any other testing tool) gives the answer as;
  eg: f(x) = [(4*9) - (4+9)]^2 = 529


Figure 7