Wednesday, January 22, 2014

API Manager 1.6.0 - tanancy


Came across a question on API Manager tenancy ...

As per docs [1]
"WSO2 API Manager supports creating multiple tenants and managing APIs in a tenant-isolated manner. When you create multiple tenants in an API Manager deployment, the API Stores of each tenant will be displayed in a muti-tenanted view for all users to browse and permitted users to subscribe to. "

Let's try it and see !!

Step 1 - Create a tenant

  • Login to management console - https://localhost:9443/carbon/
  • Create a new tenant from Home > Configure > Multitenancy > Add New Tenant - lets say my tenant is yumani.com. 
  • Now if you check in API Store, you will see tenant domains there.
When you click on yumani.com above, you will be taken to yumani.com's API store.
Lets try working within a tenant and see;
Step 2 - Create users within the tenant
We need 3 user roles - creator, publisher and subscriber
  • Login to management console, using tenant admin's credentials
  • Create a new user role from Home > Configure > Users and Roles > Roles
    • name - creator
    • permissions - as given in [2]
  • Create a role for subscriber
    • name -subscriber
    • permissions - login, Manage -> API ->Subscribe [3]
  • Create a role for publisher
    • name -publisher
    • permissions -login, Manage -> API ->Publish [4]
  • Create 3 users and assign them to each role.
Small test - if the permissions are correctly set as per above;
 
-  when you login to publisher (https://localhost:9443/publisher/) from creator's login- you should see an option to add APIs
 
 - When you login from publisher's login, you should not see an option to add APIs. You will only be able to list APIs and publish them.
 
- Finally, you will not have sufficient privileges to login to publisher using subscriber's login. 
Step 3 - Create and publish API
  • Login to 'API Publisher' from creator's account and create a new API.

 Step 4 - View the API from store
  • Now login to API Store using subscriber's account
  • You will see the above API.
Another test: 
- Create another tenant, try login to tenant 1's (yumani.com) store, you are not allowed!
 
- Login to tenan 3's store and see if you see any of tenant 1's APIs. No! because of tenancy.
NOTE: In earlier versions of APIM (APIM-1.4.0), we had a concept of allowing selected tenant's view other tenant's APIs. But it is not available in latest releases.
 
[2]- http://docs.wso2.org/display/AM160/User+Roles+in+the+API+Manager#UserRolesintheAPIManager-Addingthe creator role
[3] - http://docs.wso2.org/display/AM160/User+Roles+in+the+API+Manager#UserRolesintheAPIManager-Thedefault subscriber role
[4] - http://docs.wso2.org/display/AM160/User+Roles+in+the+API+Manager#UserRolesintheAPIManager-Addingthe publisher role

List of general rules about artifact.xml

Below is a list of general rules which Harshana (WSO2 Tooling guru) mentioned while he was supporting us with customer queries.

1. artifact.xml files in Dev Studio Projects as well as in Composite Application Archive (CAR) files are to manage Artifact metadata. Hence they should not be manipulated manually by users.

2. artifacts list in the artifacts.xml represents the order of artifacts getting deployed in Carbon 4.2.0 based servers including ESB 4.8.0.

3. If there are ESB Message Stores and Message Processors, then Message Stores will be placed before the Message Processors in the artifacts.xml. This process is automatically happens with Dev Studio 3.5.9 version.

4. If you are using Proxy services with Publish WSDL option where the WSDL itself is included in the CAR file in form of Registry Resource or Local entry, that entry need to appear before the Proxy itself because at the time of the Deployment of the proxy, it will use the wsdl pointed as the Publish WSDL.

5. In general the order of the artifacts in artifacts.xml will be Registry Resources, Local entries, Message Stores, Message Processors, other artifact types.

Thursday, January 16, 2014

How to remove these UI bundles from worker node

To remove these UI bundles from worker node, you need to run the following command from [PRODUCT_HOME]/bin:
ant createWorker


The ant task createWorker removes the following set of UI bundles:

org.wso2.carbon.*ui_*
org.wso2.carbon.*stub_*
org.wso2.stratos.*ui_*
org.wso2.stratos.*stub_*
org.jaggeryjs.*ui_*
org.jaggeryjs.*stub_*
org.wso2.carbon.ui.menu.*
org.wso2.*styles_*
org.wso2.carbon.authenticator.proxy_*


A situation where this might not work is;

If you have used -DapplyPatches parameter to start ESB node at some point!! If so it will backup the original jar files in [PRODUCT_HOME]/repository/components/plugins to [PRODUCT_HOME]/repository/components/patches/patch0000 folder. In the next server startup these jars will get replaced in [PRODUCT_HOME]/repository/components/plugins. Hence, the UI bundles could appear again. If this is the case, you need to remove the UI bundles (mentioned in above comment) manually from [PRODUCT_HOME]/repository/components/patches/patch0000 folder.

After you install features from UI ..

When you install the features using the WSO2 management console it will copy the relevant jars to repository/components/plugins directory and will update the bundles.info file which is located in CARBON_HOME/repository/components/configuration/org.eclipse.equinox.simpleconfigurator/. There will not be changes to database with regard to this.

Tuesday, January 14, 2014

How to read properties file from custom UserStoreManager

Scenario

You have developed a XUserStoreManager extending an inbuilt userstoremanager implemetation (i.e. ActiveDirectoryUserStoreManager).

You need to read some configuration files from a property file, which you do not want embed in the XUserStoreManager.jar which is deployed in <IS_HOME>/repository/components/dropins


What is the best approach:

1. You can put your custom properties in <IS_HOME>/repository/conf/user-mgt.xml inside your <CustomUserStoreManager> section as below.
<Property name="customProperty">customValue</Property>

2. Put properties withing your CustomUserStoreManager configuration section. Then you can access your properties as below as in [1]

i.e.

String patterns = realmConfig.getUserStoreProperty(LDAPConstants.USER_DN_PATTERN); 

Applicable : WSO2IS-4.6.0

[1] - https://svn.wso2.org/repos/wso2/carbon/kernel/branches/4.0.0/core/org.wso2.carbon.user.core/4.0.2/src/main/java/org/wso2/carbon/user/core/ldap/ReadOnlyLDAPUserStoreManager.java

Monday, November 25, 2013

How to start CEP server without embedded cassandra

In case you need to start the CEP server without embedded Cassandra which makes is light weight CEP. You can do this, by starting the server with -Ddisable.cassandra.server.startup=true switch.

Eg:
 ./wso2server.sh -Ddisable.cassandra.server.startup=true &

Thursday, July 25, 2013

useOriginalwsdl

I learnt a practical example on using 'useOriginalwsdl' parameters in an ESB proxy service which has a wsdl associated to it.  Thanks Charitha - as this was by listening to how Charitha approached and handled an ESB issue.

Firstly, there is a proxy service which is associating a wsdl and we were to access an operation in it via soap-ui. This particular wsdl-operation has a soap header specified. Issue being addressed is that the soap header is not appearing in the soap-request that was generated by soap-ui.

What we were doing to generate this request was generating ?wsdl of the proxy and using it in soap-ui.

When analyzing this auto generated wsdl (?wsdl), we found out that some of the parameters in the original wsdl are not appearing in it. This is because at the auto generation process ESB recreates the wsdl treating it as part of the proxy.

But for us to avoid this and have the wsdl syntax as its original we could use the parameter 'useOriginalwsdl'. After this correction, when the ?wsdl was used in soap-ui project we were able to see the correct request.

So when creating a proxy with a wsdl associated, if we need to make sure original wsdl is available for message invocation, we need to set useOriginalwsdl=true.
 

 Just now I read about enablePublishWSDLSafeMode  parameter in ESb proxies from one of Prabath's blog posts. Will write about it after trying the scenario.

Friday, July 19, 2013

Diagnosing if a bundle is not activated properly


Whe OSGI bundles fail to start, we should check the root cause using the OSGI commands.
  • Start the server with OSGi console by using ;
sh wso2server.sh -DosgiConsole

  • Once osgiConsole get started execute following command and see whether your bundle is in Active state.
osgi> ss

  • Execute the following command to see whether there are any unresolved dependencies for this bundle.
osgi> diag <your_bundle_id>


Saturday, July 6, 2013

When analyzing Thread Dumps

Thread States

BLOCKED 
          Thread state for a thread blocked waiting for a monitor lock.
NEW 
          Thread state for a thread which has not yet started.
RUNNABLE 
          Thread state for a runnable thread.
TERMINATED 
          Thread state for a terminated thread.
TIMED_WAITING 
          Thread state for a waiting thread with a specified waiting time.
WAITING 
          Thread state for a waiting thread.

Thread LC
http://bip.weizmann.ac.il/course/prog2/tutorial/essential/threads/lifecycle.html

Tool to analyse thread dumps: TDA

Some good guidelines:
http://nirmalfdo.blogspot.com/2013/05/how-to-find-culprit-when-cpu-starts-to.html

Sunday, June 30, 2013

http_access logs



http_access logs files are prefixed with “http_access_”. These files include access information for the server. We can get the access information for webapps also from this. These logs rotates on daily basis.

In Carbon 4.0.* based products, you can disable http access logs by removing the following entry from catalina-server.xml which is located in $CARBON_HOME/repository/conf/tomcat.
<valve classname="org.apache.catalina.valves.AccessLogValve" directory="${carbon.home}/repository/logs" prefix="http_access_" suffix=".log" pattern="combined"/>


For the products which uses nhttp transport (Ex. WSO2 ESB) you also have to define the below entry in log4j.properties file.
log4j.logger.org.apache.synapse.transport.nhttp.Access=WARN
log4j.properties file is located in $CARBON_HOME/repository/conf/

Pointing the correct jars to your classpath

Add relevant $CARBON_HOME/repository/lib jars to your classpath after running "ant" command in $CARBON_HOME/bin

Tuesday, June 18, 2013

Connecting to Active Directory in READ-ONLY mode

When connecting to AD in readOnly mode we need to use the configuration used for "External LDAP as the user store in READ ONLY mode", which is commented in usermgmt.xml by default.

We also need to set values for admin role to connect to Active Directory Server
 <AdminRole>admin</AdminRole>
                <AdminUser>
                     <UserName>support</UserName>
                     <Password>XXXXXX</Password>
                </AdminUser>

In here we need to specify a user who exists in our active directory server. He need not be the administrator user of the AD server. This user will be the admin user of the carbon server. We need not to specify the password here. It can be left as 'XXXX'.

This admin user must be in the user search base ("UserSearchBase") that is configured in user store manager configuration.

In the UserStore configuration also we need to update the properties to match the connecting active directory server.
        <UserStoreManager class="org.wso2.carbon.user.core.ldap.ReadOnlyLDAPUserStoreManager">
            <Property name="ReadOnly">true</Property>
            <Property name="MaxUserNameListLength">100</Property>
            <Property name="ConnectionURL">ldap://10.100.3.131:389</Property>
            <Property name="ConnectionName">CN=Administrator,CN=Users,DC=wso2,DC=test</Property>
            <Property name="ConnectionPassword">pass#word1</Property>
            <Property name="passwordHashMethod">PLAIN_TEXT</Property>
            <Property name="UserSearchBase">CN=Users,DC=wso2,DC=test</Property>
            <Property name="UserNameListFilter">(objectClass=person)</Property>
            <Property name="UserNameAttribute">cn</Property>
            <Property name="ReadLDAPGroups">true</Property>
            <Property name="GroupSearchBase">CN=Users,DC=wso2,DC=test</Property>
            <Property name="GroupNameListFilter">(objectClass=groupOfNames)</Property>
            <Property name="GroupNameAttribute">cn</Property>
            <Property name="MembershipAttribute">member</Property>
            <Property name="UserRolesCacheEnabled">true</Property>
            <Property name="ReplaceEscapeCharactersAtUserLogin">true</Property>
           <Property name="maxFailedLoginAttempt">0</Property>   
           <Property name="Referral">throw</Property>
           <Property name="DomainName">wso2</Property>
        </UserStoreManager>UserRolesCacheEnabled

i) ConnectionURL
This should have the format of ldap://<AD host-ip>:<AD_listen_port>

In failing to connect to AD server you might get this error [E1]

If you need to validate the listen port you can use portqry utility which is a command-line tool troubleshoot TCP/IP connectivity issues.  Use following command to validate if the port is open and listening:
portqry -n <hostIP> -p udp -e 389
If it resolves the port to the LDAP service, it sends an unformatted user datagram to UDP port 389 on the target system. More Infor [1]


ii) ConnectionName 
This should specify an account that can browse and search your active directory user and group bases. Also this need to be given using relative distinguished names. For an example my ConnectionName is 'CN=Administrator,CN=Users,DC=wso2,DC=test'. How this was worked out is: DC is to demote DNS Name (prefixed as Domain Component). So my DNS name is wso2.test. This makes up DC=wso2,DC=test.

Then in my domain Component, Users directory resides in the root and I have 'Administrator' user in there. So the user account and the folder highrachy to reach it can be made up as: CN=Administrator,CN=Users

So this makes us: ConnectionName=CN=Administrator,CN=Users,DC=wso2,DC=test

You are most likely to get this error [E2] when there is a misconfiguration in this.

iii) ConnectionPassword 
Is the password of above user (Administrator's password in my case)

iv) UserSearchBase
This also should be specified using distinguished name. It should be the folder which should be searched for the users.

v) UserNameAttribute
The attribute used to name users

vi) GroupSearchBase
Distinguished name of the object that holds the groups. In my case it is 'Users'.

v) ReadLDAPGroups
- This property is related to <AdminRole> configurations.
1. If "ReadLDAPGroups" is set to true, This role can be a role from AD, If this role is in the group search based ("GroupSearchBase"). Then <AdminUser> must be assigned to this role from the AD level.

2. If "ReadLDAPGroups" is set to false. Then this role can be an internal role of Carbon.Then while starting server, role is created as internal role and assigned <AdminUser> to it. This mapping kept internally in the user mgt database


[1] - http://support.microsoft.com/kb/816103

[E1] -
[2013-06-18 13:54:18,002] ERROR {org.wso2.carbon.user.core.ldap.LDAPConnectionContext} -  Error obtaining connection for the second time10.100.3.131:10389
javax.naming.CommunicationException: 10.100.3.131:10389 [Root exception is java.net.ConnectException: Connection timed out]
    at com.sun.jndi.ldap.Connection.<init>(Connection.java:223)
    at com.sun.jndi.ldap.LdapClient.<init>(LdapClient.java:136)
    at com.sun.jndi.ldap.LdapClientFactory.createPooledConnection(LdapClientFactory.java:64)
    .
    .
    .
    .
    .
Caused by: java.net.ConnectException: Connection timed out
    at java.net.PlainSocketImpl.socketConnect(Native Method)
    at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:337)
    at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:198)
    at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:180)
    at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:391)
    at java.net.Socket.connect(Socket.java:579)
    at java.net.Socket.connect(Socket.java:528)
    at java.net.Socket.<init>(Socket.java:425)
    at java.net.Socket.<init>(Socket.java:208)
    at com.sun.jndi.ldap.Connection.createSocket(Connection.java:365)
    at com.sun.jndi.ldap.Connection.<init>(Connection.java:200)
    ... 47 more



[2] -
2013-06-18 15:29:11,484] ERROR {org.wso2.carbon.user.core.ldap.LDAPConnectionContext} -  Error obtaining connection. [LDAP: error code 49 - 80090308: LdapErr: DSID-0C0903AA, comment: AcceptSecurityContext error, data 525, v1771]
javax.naming.AuthenticationException: [LDAP: error code 49 - 80090308: LdapErr: DSID-0C0903AA, comment: AcceptSecurityContext error, data 525, v1771]
    at com.sun.jndi.ldap.LdapCtx.mapErrorCode(LdapCtx.java:3087)
    at com.sun.jndi.ldap.LdapCtx.processReturnCode(LdapCtx.java:3033)
    .
    .

Featured

Selenium - Page Object Model and Action Methods

  How we change this code to PageObjectModel and action classes. 1 2 3 driver . findElement ( By . id ( "userEmail" )). sendKeys (...

Popular Posts