Thursday, November 26, 2015

Oracle Dynamic SQL scripts

There are scenarios where you used scheduled jobs to run some script procedure. In such a situation if you need to create/drop temp tables, with scheduled jobs it might cause errors if the temp table creation/deletion is done outside the procedure. Therefore in order to add all that logic into a single procedure you need to use dynamic SQL.

Below is a sample oracle  procedure written with dynamic sql. In dynamic sql in order to execute a query you need to add your query login within a statement.So the first step would be to define these statements inside the procedure.

CREATE OR REPLACE PROCEDURE  cleanData 
IS
  stmt1  VARCHAR2(2048);
  stmt2 VARCHAR2(2048);
  stmt3 VARCHAR2(2048);
  stmt4 VARCHAR2(2048);


Next we can initialize the defined statement variables and execute them accordingly.

stmt := 'CREATE TABLE TEMP_DATA(ID NUMBER)';
  EXECUTE IMMEDIATE stmt;


  stmt2 := 'INSERT INTO TEMP_DATA (ID) SELECT ID FROM NEW_DATA WHERE DATA_ID IN (4,5,6)';
  EXECUTE IMMEDIATE stmt2;


  stmt3 := 'INSERT INTO MAIN_DATA WHERE MAIN_ID IN (SELECT ID FROM TEMP_DATA)';
  EXECUTE IMMEDIATE stmt3;
  stmt4 := 'DROP TABLE TEMP_DATA';


  EXECUTE IMMEDIATE stmt4;
  COMMIT;

 END;
/



What happens in this script is ,

1. create a temp table.
2.Insert data into temp table from an existing table.
3. Add temp table data into another table.
4.Drop temp table.

Note that the statements need to be within ' ' .



Next if you execute this procedure you might receive an error stating user doesn't have sufficient privileges. This is due to oracle security model, and in order to execute dynamic queries you need to specify the permissions given to execute this procedure. Here I'm providing the permissions available of the currently logged in user. This can be done like below by placing an 'AUTHID'.

CREATE OR REPLACE PROCEDURE  cleanData AUTHID CURRENT_USER
IS
You could look into http://www.dba-oracle.com/t_authid_current_user.htm 

which explains other types of users that can be defined with AUTHID property.







Friday, November 20, 2015

Revoke OAuth Access Token from Soap Endpoint

In Wso2 Identity Provider when you need to revoke an OAuth token endpoint, there are two options that you could follow.

1. Rest endpoint
2. Soap endpoint

Rest endpoint is detailed and explained in https://docs.wso2.com/display/IS500/OAuth+Token+Revocation+with+WSO2+Identity+Server.  However if you need to revoke the token based on the resource owner, then you could go for Soap endpoint revoke operation. A good explanation on these differences can be found in https://nallaa.wordpress.com/2013/07/24/oauth-token-revocation-with-wso2-identity-server/.

These are the steps to follow in order to try out this soap endpoint. For this example I have used IS 5.0. + Service Pack 1.

The operation we are going to invoke is admin service, OAuthAdminService's  operation revokeAuthzForAppsByResourceOwner. Therefore make sure that you set <HideAdminWsdl> to false in <IS_HOME>/repository/conf/carbon.xml.

1. Create a new Service Provider (RWM) through management console and enable OAuth.
2. Note down the Client key and client secret values of the new SP. (under OAuth section)
2. Make the grant type password.
3. Create a new user (user1) and provide login permission for the user.( through internal role)
4. Use below curl command and invoke an access token for the newly created user 'user1'.

Here the format would be,

curl -v -k -X POST --user clientKey:clientSecret -H "Content-Type: application/x-www-form-urlencoded;charset=UTF-8" -d 'grant_type=password&username=user1&password=test123' https://localhost:9443/oauth2/token

For this example I have used,
curl -v -k -X POST --user mlwL69uKnERmOwDnygn2kwAgVJca:vhW8WZ1qSHsAX6RZH7YQ7QvxVwwa -H "Content-Type: application/x-www-form-urlencoded;charset=UTF-8" -d 'grant_type=password&username=user1&password=test123' https://localhost:9443/oauth2/token

5. Once you invoke this, you should get a json response with the access token and refresh token values.

6. You could check if this user1 gained authorization for the SP RWM, by accessing
 https://localhost:9443/dashboard/  as 'user1' and go to autorized apps - > view details. If previous invoke was successful, you should see that RWM app listed under this page.

7. Now in order to revoke create a soapui project with https://localhost:9443/services/OAuthAdminService?wsdl and send a request to
revokeAuthzForAppsByResourceOwner operation like below.

Make sure to enable 'authenticate pre-emptively option ,else you would get an illegal login attempt error, and the token will not be revoked. Also the basic:auth credentials should be the user credentials that you used to invoke the the token in the first place. 

8. Now if you go to admin dashboard and view authorize apps, you should not be able to see the previous RWM listed. You can further clarify that the token got revoked, by invoking another token for the same user, and see if it is a new value given.



 

Wednesday, November 18, 2015

Workaround for ConnectionPool closed error at API Manager Gateway

Hi in a clustered setup if there is a continuous high load , following issue can occur at the gateway node.

An error occurred while submitting resources for indexing {org.wso2.carbon.registry.indexing.ResourceSubmitter}
org.wso2.carbon.registry.core.exceptions.RegistryException: Failed to commit transaction.
    at org.wso2.carbon.registry.core.jdbc.dataaccess.JDBCTransactionManager.commitTransaction(JDBCTransactionManager.java:164)
    at org.wso2.carbon.registry.core.jdbc.dao.JDBCLogsDAO.commitTransaction(JDBCLogsDAO.java:330)
    at org.wso2.carbon.registry.core.jdbc.dao.JDBCLogsDAO.getLogList(JDBCLogsDAO.java:304)
    at org.wso2.carbon.registry.core.jdbc.EmbeddedRegistry.getLogs(EmbeddedRegistry.java:2332)
    at org.wso2.carbon.registry.core.caching.CacheBackedRegistry.getLogs(CacheBackedRegistry.java:402)
    at org.wso2.carbon.registry.core.session.UserRegistry.getLogsInternal(UserRegistry.java:1813)
    at org.wso2.carbon.registry.core.session.UserRegistry.access$3600(UserRegistry.java:60)
    at org.wso2.carbon.registry.core.session.UserRegistry$37.run(UserRegistry.java:1784)
    at org.wso2.carbon.registry.core.session.UserRegistry$37.run(UserRegistry.java:1781)
    at java.security.AccessController.doPrivileged(Native Method)
    at org.wso2.carbon.registry.core.session.UserRegistry.getLogs(UserRegistry.java:1781)
    at org.wso2.carbon.registry.indexing.ResourceSubmitter.submitResource(ResourceSubmitter.java:127)
    at org.wso2.carbon.registry.indexing.ResourceSubmitter.run(ResourceSubmitter.java:83)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
    at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:304)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:178)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:745)
Caused by: java.sql.SQLException: PooledConnection has already been closed.



Here we do not need registry indexing to happen at the gateway node. Therefore we could disable the indexing at the gateway node to overcome this issue. However, in APIM 1.8.0 these index disabling configs are not available. So what you could do is to delay indexing at the gateway node. For this go to /conf/registry.xml file(of the gateway node) and under <indexConfiguration> , increase below interval value to few hours.

<indexingFrequencyInSeconds></indexingFrequencyInSeconds>

Tuesday, November 10, 2015

BPEL process and fault handeling

When it comes to bpel processes, you can handle the faults been thrown by using fault handlers. Suppose the process you invoke will throw custom fault responses. Then in your bpel process you could catch them and perform another sequence.

This is the definition of a fault handler.

<bpel:faultHandlers>
        <bpel:catch faultName="ns2:fault1" faultVariable="fault1"
            faultMessageType="ns2:fault1Response">
            <bpel:sequence>
                <!-- your custom sequence -->
            </bpel:sequence>
        </bpel:catch>

        <bpel:catch faultName="ns2:fault2" faultVariable="fault2"
            faultMessageType="ns2:fault1Response">
            <bpel:sequence>
                <!-- your custom sequence -->
            </bpel:sequence>
        </bpel:catch>

        <bpel:catchAll>
            <bpel:sequence>
                <!-- your custom sequence -->
            </bpel:sequence>
        </bpel:catchAll>


    </bpel:faultHandlers>


As above you could define any number of different catch sequences. 'catchAll' could be used to catch any other that didn't match other clauses. However the use of the faultVariable is, you could access the faults parameters from the fault variable defined. For example, if we are passing a parameter named 'errorCode' from the fault response, we could access it from the fault variable like below.


$fault1.parameters/errorCode



      

Sunday, November 8, 2015

Adding dispatch logic to SOAPUI mock services

There might be instances, where you have few variations of a response that needs to be sent based on a logic. You could do this by adding a dispatch script including your logic like below.

1.Go to required service's process interface and change DISPATCH option to 'script'.

In this example I will be dispatching a specific response based on an element of the incoming request.

Following is the sample script .

// create XmlHolder for request content

def holder = new com.eviware.soapui.support.XmlHolder( mockRequest.requestContent )
def arg1 = holder["//category"]


//if above element is empty
if( !com.eviware.soapui.support.StringUtils.hasContent( arg1 ))
 return "Invalid Input Response"


if(arg1 == "Books" )
return "SendBooksReponse"

else if(arg1 == "Articles")
return "SendArticlesResponse"


So here what we are returning would be the relevant mock response's name.