Monday, August 17, 2015

Filter by package and type

This is an attempt to filter the classes in during the run-time. Finally succeeded  with a help of online resources and several attempts.

import java.io.File;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

public class ClassCheck {

    private static final Logger LOGGER = Logger.getLogger(ClassCheck.class.getName());
    private static final char DOT = '.';
    private static final char SLASH = '/';
    private static final String CLASS_SUFFIX = ".class";
    private static final String BAD_PACKAGE_ERROR = "Unable to get resources from path '%s'. Are you sure the package '%s' exists?";
    private ClassCheck() {}

    /**
     * @param scannedPackage : Package to analyzed
     * @return list of classes in a package
     */
    public static List<Class<?>> find(String scannedPackage, Class... type) {

        URL scannedUrl = Thread.currentThread().getContextClassLoader().getResource(scannedPackage.replace(DOT, SLASH));
        if (scannedUrl == null) {
            throw new IllegalArgumentException(String.format(BAD_PACKAGE_ERROR, scannedPackage.replace(DOT, SLASH), scannedPackage));
        }
        File scannedDir = new File(scannedUrl.getFile());
        List<Class<?>> classes = new ArrayList<>();
        for (File file : scannedDir.listFiles()) {
            classes.addAll(find(file, scannedPackage, type));
        }
        return classes;
    }

    public static List<Class<?>> find(File file, String scannedPackage, Class... type) {
        List<Class<?>> classes = new ArrayList<>();
        String resource = scannedPackage + DOT + file.getName();
        if (file.isDirectory()) {
            for (File child : file.listFiles()) {
                classes.addAll(find(child, resource, type));
            }
        } else if (resource.endsWith(CLASS_SUFFIX)) {
            int endIndex = resource.length() - CLASS_SUFFIX.length();
            String className = resource.substring(0, endIndex);
            try {
                if (type.length > 0) {
                    for (Class c : type) {
                        Class toCheck = Class.forName(className);
                        if (c!=toCheck && c.isAssignableFrom(toCheck)) {
                            classes.add(toCheck);
                            break;
                        }
                    }
                } else {
                    classes.add(Class.forName(className));
                }
            } catch (ClassNotFoundException e) {
                LOGGER.log(Level.WARNING, "Class not found", e);
            }
        }
        return classes;
    }
}

CHEF Server with jclouds

CHEF solo is a standalone simple application which can be used to manage single instance.But if there is a need to manage multiple instances and want better control over organisations Cookbook's and Data Bags CHEF server will be a good choice .

Environment

CHEF server
Unlicensed version of CHEF server can be downloaded from (link) their site and supported up to 25 nodes.And there also a service provided by CHEF which provide a  access to one of their server by registering to manage.chef.io which is used in this article.

jclouds
When it comes to controlling CHEF server jclouds will be good choice and it also provide number of adapters to communication with other cloud services also.To authenticate to the CHEF server private key is needed

Activity

In this example java client is connected to the CHEF server and  list avilable data bags.

    import com.google.common.base.Charsets;
    import java.io.IOException;
    import java.nio.file.Files;
    import java.nio.file.Paths;
    import java.util.Set;
    import java.util.logging.Level;
    import java.util.logging.Logger;
    import org.jclouds.ContextBuilder;
    import org.jclouds.enterprisechef.EnterpriseChefApi;

    public class Main {

        public static void main(String[] args) {

            String client = "ubuntu";
            String organization = "ubuntu_sl";
            String pemFile = System.getProperty("user.home") + "/.chef/" + client + ".pem";
            String credential = null;
            EnterpriseChefApi chefApi;
            try {
                credential = new String(Files.readAllBytes(Paths.get(pemFile)), Charsets.UTF_8);
            } catch (IOException ex) {
                Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
            }
            chefApi = ContextBuilder.newBuilder("enterprisechef")
                    .endpoint("https://api.opscode.com/organizations/" + organization)
                    .credentials(client, credential).buildApi(EnterpriseChefApi.class);
            Set<String> databags = chefApi.listDatabags();
            for (String databag : databags) {
                System.out.println(" ******************** " + databag);
            }
            try {
                chefApi.close();
            } catch (IOException ex) {
                Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }

Sunday, July 26, 2015

Getting started with CHEF

CHEF is a configuration management tool which comes in handy when it comes to managing thousands of software components in production & development environments. It’s similar in functionality to puppet but use more procedural approach to do the job done. This example going to use CHEF solo

CHEF glossary

CHEF cookbook
        More like an artifact which contains all the things need to have to complete a scenario which include Recipes, data bags, templates and dependencies to other cookbook's

CHEF Server
        Which contains all the cookbook's and data bags which act as central management hub

CHEF Client
        Act as the agent of the CHEF server for each node

WorkStation
        Where user can communicate with CHEF server

Data Bag
        JSON variable which used to store data

Environment setup

In this example going to use plain Ubuntu server 14.04.2. And to install CHEF solo
        root@ubuntu2:~# sudo apt-get install chef

Configuring CHEF solo
Default location for the chef solo is located in /etc/chef/solo.rb
    CHEF solo.rb
        checksum_path "/var/chef/checksums"
        cookbook_path [
            "/var/chef/cookbooks",
            "/var/chef/site-cookbooks"
        ]
        data_bag_path repo "/var/chef/data_bags"
        environment_path "/var/chef/environments"
        file_backup_path "/var/chef/backup"
        file_cache_path "/var/chef/cache"
        role_path "/var/chef/roles"
        log_level :debug
        log_location "/var/chef/logs/chef.log"

Creating a cookbook
Go to site-cookbooks folder and create directory called example and file structure under it

        root@ubuntu2:/var/chef/site-cookbooks/example# tree
            .
            +-- recipes
            ¦   +-- default.rb
            +-- templates
                +-- default
                    +-- apache.conf.erb

Now need to enter execution instruction for our cookbook which is going to create configuration file using template and a data bag
        default.rb          
        item = data_bag_item("config", data_bag("config").last)
            template '/tmp/apache.conf' do
            source 'apache.conf.erb'
            owner 'root'
            group 'root'
            mode '644'
            variables(:config=> item)
        end

Then need to create template file for the recipe
        apache.conf.erb
        <VirtualHost <%= @config['ip']%>:<%= @config['port']%>>
            DocumentRoot /www/<%= @config['folder']%>
            ServerName <%= @config['hostName']%>
        </VirtualHost>

In the data bag directory create a file config and two json files under it
        root@ubuntu2:/var/chef/data_bags# tree
            .
            +-- config
                +-- config1.json
                +-- config2.json
      
        ex :
            {
              "id": "config1",
              "ip": "10.10.10.1",
              "port": "8881",
              "folder": "sample1",
              "hostName": "host1"
            }

Now we can run our cookbook typing chef-solo -o 'recipe[example]'