Sunday, February 7, 2016

SVN cheat sheet

This is not the place to learn SVN commands, I'm just creating this as a  reference to some important commands.

Revert local file change

svn revert <file_name>

Take a diff from two revisions

svn diff -r <old_revision>:<new_revision>

Update to the latest revision

svn update "<path>"

Update to a specific revision

svn update -<revision_number> "<path>"

Add new files/directory to track

svn add <file_name>|<directory_name>

Delete with a message

svn -m "<messahe>" delete "<path>"

Saturday, January 30, 2016

Build Carbon Application(capp) for WSO2 DAS

You need to work with multiple artifact types while working with WSO2 DAS. Following is a list of artifacts supported in WSO2 DAS, (Tried both DAS 3.0.0 and 3.0.1)


  • Event Streams
  • Event Stores
  • Even Receivers
  • Analytic Scripts
  • Execution Plans
  • Gadgets
  • Layouts
  • Dashboards


Rather than deploying these artifacts one by one we can deploy a set of artifacts using a single deployable artifact, Carbon Application (capp)[1]. Here what we do is, create an archive with .car extension and deploy using management console.


But there can be usecases where we need to build above archive programmatically, using a build tool. Here I’m using Maven to fulfil above requirement.


Assume we have all artifacts within das-capp directory,


.
├── das-capp
│   ├── artifacts.xml
│   ├── Dashboard_1.0.0
│   ├── Eventreceiver_1.0.0
│   ├── Eventstore_1.0.0
│   ├── Eventstream_1.0.0
│   ├── GadgetTotalDailyViews_1.0.0
│   ├── GadgetViewsPreviousmonth_1.0.0
│   ├── GagdetPageFilter_1.0.0
│   ├── Layout_1.0.0
│   └── Sparkscripts_1.0.0
└── pom.xml

pom.xml


<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 <modelVersion>4.0.0</modelVersion>
 <groupId>org.wso2.das.example</groupId>
 <artifactId>das-capp</artifactId>
 <version>1.0.0-SNAPSHOT</version>
 <packaging>pom</packaging>
 <name>DAS CAR</name>
 <description>This project contains artifacts to process and display sample capp</description>
 <properties>
    <artifact.types>jaggery/app=zip,service/rule=aar,lib/library/bundle=jar,event/receiver=xml,synapse/message-processors=xml,synapse/endpointTemplate=xml,synapse/message-store=xml,synapse/proxy-service=xml,event/execution-plan=siddhiql,carbon/application=car,registry/resource=zip,lib/dataservice/validator=jar,synapse/endpoint=xml,web/application=war,synapse/inbound-endpoint=xml,synapse/sequence=xml,synapse/configuration=xml,lib/registry/handlers=jar,synapse/task=xml,service/meta=xml,webapp/jaxws=war,synapse/api=xml,synapse/lib=zip,bpel/workflow=zip,lib/registry/filter=jar,service/dataservice=dbs,event/publisher=xml,synapse/local-entry=xml,synapse/priority-executor=xml,synapse/event-source=xml,synapse/template=xml,event/stream=json,lib/carbon/ui=jar,service/axis2=aar,synapse/sequenceTemplate=xml,wso2/gadget=dar,lib/synapse/mediator=jar</artifact.types>
 </properties>
 <build>
    <pluginManagement>
     <plugins>
       <plugin>
         <artifactId>maven-antrun-plugin</artifactId>
         <version>1.7</version>
       </plugin>
     </plugins>
    </pluginManagement>
    <plugins>
     <plugin>
       <artifactId>maven-antrun-plugin</artifactId>
       <executions>
         <execution>
           <phase>process-resources</phase>
           <goals>
             <goal>run</goal>
           </goals>
           <configuration>
             <tasks>
               <zip destfile="target/das-example.car">
                 <zipfileset dir="das-capp" />
               </zip>
             </tasks>
           </configuration>
         </execution>
       </executions>
     </plugin>
    </plugins>
 </build>
</project>


You can build above using mvn clean install and find the capp artifact within target/ directory. Then we can upload this deployable artifact to WSO2 DAS using management console.


[1] https://docs.wso2.com/display/DAS301/Packaging+Artifacts+as+a+C-App+Archive

Thursday, January 28, 2016

Configure WSO2 server to start automatically after reboot

I have tested following within a RHEL box, but with a slight modification to the run-level, same script can be used within other Linux distros.

Assume we have WSO2 DAS server within /carbon/wso2/das directory and JDK installed in /carbon/java/ directory. Make sure to update these two according to your environment.

 1. Copy following startup-script to the /etc/init.d directory.
 2. Execute chmod a+x and a+r on the script.
 3. Set run level using "sudo chkconfig dasserver on"
 4. Recheck above using "chkconfig --list dasserver" This should output ,
 "dasserver       0:off   1:off   2:on    3:on    4:on    5:on    6:off"
Startup script
#! /bin/sh
#
# dasserver          Start up the WSO2 DAS server
#
# chkconfig: 2345 55 25
# description: WSO2 Data Analytics Server is a comprehensive enterprise data analytics platform.

export JAVA_HOME="/carbon/java/jdk1.8.0_65"


startcmd='/carbon/wso2/das/
wso2das-3.0.0/bin/wso2server.sh start > /dev/null &'
restartcmd='/carbon/wso2/das/
wso2das-3.0.0/bin/wso2server.sh restart > /dev/null &'
stopcmd='/carbon/wso2/das/
wso2das-3.0.0/bin/wso2server.sh stop > /dev/null &'

case "$1" in
start)
   echo "Starting the WSO2 DAS Server ..."
   su -c "${startcmd}" wso2usr
;;
restart)
   echo "Re-starting the WSO2 DAS Server ..."
   su -c "${restartcmd}" wso2usr
;;
stop)
   echo "Stopping the WSO2 DAS Server ..."
   su -c "${stopcmd}" wso2usr
;;
*)
   echo "Usage: $0 {start|stop|restart}"
exit 1
esac

Sunday, June 7, 2015

How to persist resolv.conf modifications

Default resolv.conf in my Ubuntu box is as follows,
udara@udara-home:~$ cat /etc/resolv.conf
# Dynamic resolv.conf(5) file for glibc resolver(3) generated by resolvconf(8)
#     DO NOT EDIT THIS FILE BY HAND -- YOUR CHANGES WILL BE OVERWRITTEN
nameserver 127.0.1.1
Assume a scenario where I need to use a different DNS.. Eg: -google dns- 8.8.8.8

I can achieve this by modifying above resolv.conf, but that change won't persists after Ubuntu box restart, networking restart or my router restart.

How to persist my change,

Open /etc/network/interfaces using your favorite text editor, in my case it's vi :)
sudo vi /etc/network/interfaces
Update /etc/network/interfaces according to your preference. You can append dns-nameservers 8.8.8.8 to the end.


Eg:-
# interfaces(5) file used by ifup(8) and ifdown(8)
auto lo
iface lo inet loopback
dns-nameservers 8.8.8.8

Note:- I tried different alternatives like update resolv.conf using a bash script during server restart, adding immutable characteristic to resolv.conf using chattr tool. But above is the only viable solution I can recommend to someone.

Tuesday, June 2, 2015

Git merge to restore lost commit

Lets start from a status like following,
udara@udara-home:~/workspace/USSD-Reminder$ git status
# On branch new-feature
# Your branch is ahead of 'origin/new-feature' by 1 commit.
#   (use "git push" to publish your local commits)
#
nothing to commit, working directory clean
So here my local branch is one commit ahead from the remote. Assume mistakenly I did a git reset --hard HEAD^. This will remove my last commit and now I need to find a way to undo my last command.

When we issue the git reset command, commit goes to dangling state and commit is not going to remove permanently. luckily !!

IMPORTANT:

Make sure you don't run git gc until you restore the lost commit. git gc command will trigger the garbage collector and remove all commits which are in dangling state.


Let's start the restoring process....

1. We need to find the SHA1 of the deleted commit so we can bring it back.
 git fsck --lost-found
git fsck command will list down all commits which are in dangling state.
udara@udara-home:~/workspace/USSD-Reminder$ git fsck --lost-found
Checking object directories: 100% (256/256), done.
Checking objects: 100% (16/16), done.
dangling commit 5e3079cc8ac9e15cbfc1f513d249678c0893feab
So we have the SHA1 of the commit which needs to restore.

2. Lets merge this commit.
git merge <SHA1>
udara@udara-home:~/workspace/USSD-Reminder$ git merge 5e3079cc8ac9e15cbfc1f513d249678c0893feab
Updating 0ffdab3..5e3079c
Fast-forward
 config.php | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
Now if we run the git status command it should mention that my local branch is one commit ahead than the remote.

Friday, May 22, 2015

Deleting a remote branch using command line- Git

If you are familiar with GitHub UI after browsing 'branches' tab you can simply delete a branch(If you have relevant permissions).


Lets see how we do the same using command line.
git push <REMOTE_NAME> :<BRANCH_NAME>
Note the space between remote name and the colon. By following this syntax you are asking git to push nothing hence git push will delete the branch in remote repository.

Eg:-
udara@udara-home:~/workspace/h2-social-adaptor$ git push origin :v2
To git@github.com:udarakr/h2-social-adaptor.git
 - [deleted]         v2

Wednesday, May 13, 2015

Cross database pagination problem and how we solved it

When we are developing a webapp with any type of listing, pagination is a must have feature. From the UI perspective we can use infinite scrolling or pages approach.

If you are familiar with google search this is how google uses the second approach,



Now the problem is how we generate listing for a particular page?
Lets take a hypothetical library application where we need to list down existing books, assume we need to list 10 books per page.

This is how we query books to generate the 1st page,
SELECT * FROM BOOKS LIMIT 10;
to generate the 2nd page,
SELECT * FROM BOOKS LIMIT 10 OFFSET 10;
So easy,  by providing the offset value we can dynamically generate our pages.

BUT can we use the same across database types?

If you know the exact backend DB type you gonna use in production, lucky you!
But if you are developing a product which needs to support multiple DB types (MySQL, Oracle, Postgres, H2 ....) above query will fail in some of them. For example above will work in MySQL, H2 and Postgres but will not work in Oracle.

In Oracle 11g you can run following but not in 12c
SELECT *
FROM (
  SELECT b.*, ROWNUM RN
  FROM (
    SELECT *
    FROM BOOKS
    ORDER BY ID ASC
  ) b
  WHERE ROWNUM <= 10
)
WHERE RN > 10
 
Now let's discuss how we solved this problem. Following is high-level architecture of the solution.







In this scenario we have exposed all CRUD operations as OSGI services to the outside world. This component may or may not have DB specific logic. But for sure we don't have any DB type specific logic within our main OSGI component. We have delegated all those DB type specific logic to the DB Adapter.

What are the DB type specific things we can have?

1. Above pagination related stuff (LIMIT, OFFSET)
2. Auto generate key usage(getGenaratedKeys)

How to load correct DB Adapter class through reflection

We can maintain a configuration file where we state the DB Adapter class. Then read that class name within our main component and use/call through reflection.

Reference

http://www.jooq.org/doc/3.5/manual/sql-building/sql-statements/select-statement/limit-clause/