Sunday, October 11, 2015

Setting up OpenStack python SDK on Oracle Enterprise Linux 6

To setup openstacksdk on Oracle VM Server 3.3.3 or Oracle Enterprise Linux 6:

Oracle Enterprise Linux 6 comes with python 2.6.6 by default.

OpenStackSDK requires at least python 2.7 or 3.3.

Following are the steps to upgrade local python to 2.7.10 and 3.5.0 (the latest as of this writing) and install openstacksdk for development.

It is assumed that OpenStack is hosted on the same host where the test program is being executed.

$ sudo su -
# cd /etc/yum.repos.d
# rm -f *
# yum clean all
# yum makecache
# yum install gcc

The above step may take quite some time and is only required to install gcc. If one already has gcc installed then skip to the following step.


# yum groupinstall "Development tools"
# yum install zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel readline-devel tk-devel gdbm-devel db4-devel libpcap-devel xz-devel
# cd /usr/src

Get ez_setup to install easy_install for python interpreter.

# tar xzf Python-2.7.10.tgz
# tar xzf Python-3.5.0.tgz


Install Python-2.7.10
# cd Python-2.7.10
# ./configure --prefix=/usr/local --enable-unicode=ucs4 --enable-shared LDFLAGS="-Wl,-rpath /usr/local/lib"
# make && make altinstall
# python2.7 -V
# python2.7 ez_setup.py
# easy_install-2.7 pip


OR

Install Python 3.5.0
# cd Python-3.5.0
# ./configure --prefix=/usr/local --enable-shared LDFLAGS="-Wl,-rpath /usr/local/lib"
# make && make altinstall
# python3.5 -V
# python3.3 ez_setup.py
# easy_install-3.3 pip


Setup Virtualenv for your project:
# cd /files/project
# pip2.7 install virtualenv
# virtualenv -p /usr/local/bin/python2.7 venv

OR 
# python3.5 -m venv venv

Activate virtualenv
# source venv/bin/activate

Now install the SDK:
# pip2.7 install openstacksdk
OR
# pip3.5 install openstacksdk

# Run the following test program (test.py) as:
# python3.5 ./test.py
# OR
# python2.7 ./test.py

from openstack import connection
from openstack import utils
import logging
import sys

# Enable requests logging
logger = logging.getLogger('requests')
formatter = logging.Formatter(
    '%(asctime)s %(levelname)s: %(name)s %(message)s')
console = logging.StreamHandler(sys.stdout)
console.setFormatter(formatter)
logger.setLevel(logging.DEBUG)
logger.addHandler(console)

# Enable logging to console
utils.enable_logging(debug=True, stream=sys.stdout)


# Get connection
conn = connection.Connection(auth_url="http://localhost:5000/v2.0",
                             project_name="admin",
                             username="admin",
                             password="password")


# Get network API
network = conn.network.find_network("watshnet")
if network is None:
    network = conn.network.create_network(name="watshnet")
else:
    print(network)

If everything went fine so far then you are all set to begin writing your extensions for OpenStack. Examples using the sdk are available here - https://github.com/stackforge/python-openstacksdk/tree/master/examples

Friday, October 02, 2015

Integrating Morphia and Dropwizard

Recently i had the pleasure of using mongodb's document object mapper framework morphia and the REST webservice framework dropwizard (well it is more than simply for REST but that is the primary purpose of it).

Dropwizard comes with the following essential thirdparty libraries:

  1. Jackson - for JSON parsing
  2. Jetty - as embedded light weight Java EE web container
  3. Jersey - JAX-RS 2.0 implementation
  4. and some more... 
Morphia has annotations for POJO model classes that can be persisted in mongodb and is a nice framework that simplifies the development of a mongodb client application. At the same time we can use the same POJO model classes for REST endpoint implementations as well. So there is no need to have separate DTO and entity classes. The same POJO model classes are annotated as entities (using morphia's annotations) and as DTO (using Jackson's annotations).

A simple example for such a model class is given below:


@Entity(value = "students" , noClassnameStored = true, concern = "SAFE")
public class Student extends BaseModel {
    @Id    private String id = new ObjectId().toHexString();

    @Reference    private User user;

    @Reference    private List courseRefs;

    Date lastUpdated = new Date();

    @PrePersist    void prePersist() {
        lastUpdated = new Date();
    }

    
    public Student(User user) {
        this.user = user;
        this.courseRefs = new ArrayList<>();
    }

    public Student() {
    }


    @JsonProperty    public Date getLastUpdated() {
        return lastUpdated;
    }

    public void setLastUpdated(Date lastUpdated) {
        this.lastUpdated = lastUpdated;
    }


    @JsonProperty    public List getCourseRefs() {
        return courseRefs;
    }

    public void setCourseRefs(List courseRefs) {
        this.courseRefs = courseRefs;
    }


    @JsonProperty    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }

    @JsonProperty    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id != null ? new ObjectId(id).toHexString() : new ObjectId().toHexString();
    }

    @Override    public String toString() {
        return "Student{" +
                "id=" + id +
                ", user=" + user +
                ", courseRefs=" + courseRefs +
                ", lastUpdated=" + lastUpdated +
                '}';
    }
}

Morphia annotations are:
@Entity
@Id
@Reference
@PrePersist

Jackson annotations used are:
@JsonProperty

Additionally with Dropwizard we also get the bean validations through Hibernate Validator framework which can be used in the POJO above to annotate the fields in the model with @NotNull or @MinLength... etc.

One important learning in this integration was to map the mongodb _id (ObjectID BSON type) to a string id in the model but set it to the hex string value from the _id field. Getting this to work without the use of frameworks like MongoJack or Katharsis keeps the code simple to comprehend and yet meets the requirements.

Using VNC with Ubuntu on VirtualBox


  1. Create an Ubuntu 64 bit VM on VirtualBox with following specs:
    1. CPU - 1
    2. Memory - 1GB
    3. HDD - 20GB (VDI, Dynamic allocation)
    4. Network - NAT with Port forwarding - TCP, 5900 (on local host) forwarded to 5900 (on VM)
  2. Download Ubuntu desktop 15.04 and install it on the VM.
  3. Once installation completes, search for Desktop Sharing applet. 
  4. Enable sharing, provide password.
  5. Now launch a VNC viewer and specify the IP of the parent host on which VirtualBox is installed with port 5900.
    1. If connecting from same host where virtual box is installed then you may use localhost:5900. 
  6. It will prompt for password then connect.


Book notes: Designing Data-Intensive Applications: The Big Ideas Behind Reliable, Scalable, and Maintainable Systems, by Martin Kleppmann

My notes from the excellent book on how software has evolved to handle data from hierarchical databases to the NoSQL -  https://www.goodrea...