Thursday, July 9, 2015

SantaESClient

ClientConfig

package flipkart.dsp.santa.client;


import lombok.Data;
import lombok.Getter;

/**
 * Created by dhruv.chandhok on 01/06/15.
 */
@Data
public class ClientConfig
{
    public ClientConfig(String name)
    {
        clientName=name;
    }

    @Getter
    private String clientName;


    public String getClientName()
    {
        return clientName;
    }
}




DecoratorListener

package flipkart.dsp.santa.client;

import com.yammer.metrics.core.TimerContext;
import org.elasticsearch.action.ActionListener;

/**
 * Created by dhruv.chandhok on 09/06/15.
 */
public class DecorateListner
    {
        static  <V> ActionListener<V> decorateWithTimerStop(ActionListener<V> listener, TimerContext timerContext)
            {

                ActionListener<V> wrapperListener = new ActionListener<V>() //decorated listner
                {
                    @Override
                    public void onResponse(V getFields)
                        {
                            timerContext.stop();
                            listener.onResponse(getFields);
                        }

                    @Override
                    public void onFailure(Throwable e)
                        {
                            timerContext.stop();
                            listener.onFailure(e);
                        }
                };
                return wrapperListener;
            }
    }


MetricsUtils


package flipkart.dsp.santa.client;

import com.yammer.metrics.core.Timer;
import com.yammer.metrics.core.TimerContext;

/**
 * Created by dhruv.chandhok on 09/06/15.
 */
public class MetricsUtils
    {
        //Asynchronus Lambda Functions & Interfaces

        static interface EnclosureCallback<V>
            {
                void call(TimerContext timerContext);
            }




        static <V> void measureAsync(Timer timer, EnclosureCallback<V> enclosureCallback)
            {
                TimerContext timerContext = timer.time();
                enclosureCallback.call(timerContext);
            }

        //


        // synchronus Timer & interfaces

        static interface Enclosure<V>
            {
                V call();
            }

        static <V> V  measure(Timer timer, Enclosure<V> callable)
            {
                TimerContext timerContext = timer.time();
                try
                    {
                        return callable.call();
                    }
                finally
                    {
                        timerContext.stop();
                    }
            }

        //

    }


SantaESNodeClient

package flipkart.dsp.santa.client;

import com.yammer.metrics.Metrics;
import com.yammer.metrics.core.MetricName;
import org.elasticsearch.action.*;
import org.elasticsearch.action.support.TransportAction;
import org.elasticsearch.client.Client;
import org.elasticsearch.client.node.NodeAdminClient;
import org.elasticsearch.client.node.NodeClient;
import org.elasticsearch.client.support.Headers;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.threadpool.ThreadPool;
import com.yammer.metrics.core.Timer;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import static flipkart.dsp.santa.client.DecorateListner.decorateWithTimerStop;
import static flipkart.dsp.santa.client.MetricsUtils.measure;
import static flipkart.dsp.santa.client.MetricsUtils.measureAsync;

//import static flipkart.dsp.santa.client.DecorateListner.decorateWithTimerStop;

/**
 * Created by dhruv.chandhok on 09/06/15.
 */
public class SantaESNodeClient extends NodeClient
    {
        ClientConfig clientDescription;
        private Timer executeTimer;
        private static final String METRICS_GROUP_PREFIX = "dsp-santa-node";
        private MetricName metricName(String name)
            {
                return new MetricName(METRICS_GROUP_PREFIX ,"ESClient", name);
            }
        private void init()
            {
                executeTimer= Metrics.newTimer(SantaESTransportClient.class,clientDescription.getClientName()+
                        "execute Response", TimeUnit.MILLISECONDS, TimeUnit.SECONDS);
            }

        public SantaESNodeClient(ClientConfig clientDescription,Settings settings, ThreadPool threadPool,
                                 NodeAdminClient admin, Map<GenericAction, TransportAction> actions, Headers headers)
            {
                super(settings, threadPool, admin, actions, headers);
                this.clientDescription=clientDescription;
                init();
            }


        @Override
        public <Request extends ActionRequest, Response extends ActionResponse,
                RequestBuilder extends ActionRequestBuilder<Request, Response, RequestBuilder, Client>>
        ActionFuture<Response> execute(Action<Request, Response, RequestBuilder, Client> action, Request request)
            {
               return measure(executeTimer,()->super.execute(action,request));
            }

        @Override
        public <Request extends ActionRequest, Response extends ActionResponse,
                RequestBuilder extends ActionRequestBuilder<Request, Response, RequestBuilder, Client>>
        void execute(Action<Request, Response, RequestBuilder, Client> action, Request request, ActionListener<Response> listener)
            {

                measureAsync(executeTimer,(tc)->super.execute(action, request, decorateWithTimerStop(listener, tc)));
            }
    }


SantaESTransportClient

Monday, June 29, 2015

Foxtrot Client

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package com.flipkart.foxtrot.client;

import com.flipkart.foxtrot.client.Document;
import com.flipkart.foxtrot.client.EventSender;
import com.flipkart.foxtrot.client.EventSerializationHandler;
import com.flipkart.foxtrot.client.FoxtrotClientConfig;
import com.flipkart.foxtrot.client.MemberSelector;
import com.flipkart.foxtrot.client.cluster.FoxtrotCluster;
import com.flipkart.foxtrot.client.selectors.RandomSelector;
import com.flipkart.foxtrot.client.senders.HttpAsyncEventSender;
import com.flipkart.foxtrot.client.senders.HttpSyncEventSender;
import com.flipkart.foxtrot.client.senders.QueuedSender;
import com.flipkart.foxtrot.client.serialization.JacksonJsonFoxtrotClusterResponseSerializationHandlerImpl;
import com.flipkart.foxtrot.client.serialization.JacksonJsonSerializationHandler;
import com.flipkart.foxtrot.client.util.TypeChecker;
import com.google.common.base.Preconditions;
import com.google.common.base.Strings;
import java.util.List;

public class FoxtrotClient {
    private final FoxtrotCluster foxtrotCluster;
    private final EventSender eventSender;

    public FoxtrotClient(FoxtrotClientConfig config) throws Exception 
    {
        this(config, new RandomSelector(), JacksonJsonSerializationHandler.INSTANCE);
    }

    public FoxtrotClient(FoxtrotClientConfig config, MemberSelector memberSelector, EventSerializationHandler serializationHandler) throws Exception 
    {
        this.foxtrotCluster = new FoxtrotCluster(config, memberSelector, 
                                    JacksonJsonFoxtrotClusterResponseSerializationHandlerImpl.INSTANCE);
        this.eventSender = (EventSender)(Strings.isNullOrEmpty(config.getLocalQueuePath())
                                        ?new HttpAsyncEventSender(config, this.foxtrotCluster, serializationHandler)
                                        :new QueuedSender(new HttpSyncEventSender(config, this.foxtrotCluster, serializationHandler),
                                         serializationHandler, config.getLocalQueuePath(), config.getBatchSize(), config.getRefreshIntervalSecs()));
    }

    public FoxtrotClient(FoxtrotCluster foxtrotCluster, EventSender eventSender) 
    {
        this.foxtrotCluster = foxtrotCluster;
        this.eventSender = eventSender;
    }

    public void send(Document document) throws Exception 
    {
        Preconditions.checkNotNull(document.getData());
        Preconditions.checkArgument(!TypeChecker.isPrimitive(document.getData()));
        this.eventSender.send(document);
    }

    public void send(List<Document> documents) throws Exception 
    {
        this.eventSender.send(documents);
    }

    public void close() throws Exception 
    {
        this.eventSender.close();
        this.foxtrotCluster.stop();
    }
}

Tuesday, June 23, 2015

ListingQueueingTopology

package flipkart.dsp.santa.bernard.zulu.topology;

import backtype.storm.Config;
import backtype.storm.StormSubmitter;
import backtype.storm.generated.AlreadyAliveException;
import backtype.storm.generated.InvalidTopologyException;
import backtype.storm.generated.StormTopology;
import backtype.storm.topology.BoltDeclarer;
import backtype.storm.topology.TopologyBuilder;
import flipkart.dsp.santa.bernanrd.GuiceInjectorFactory;
import flipkart.dsp.santa.bernard.stormcore.kafka.KafkaBolt;
import flipkart.dsp.santa.bernard.stormcore.utils.StormUtils;
import flipkart.dsp.santa.bernard.zulu.zookeeper.VerticalRepository;
import org.yaml.snakeyaml.Yaml;

import java.io.IOException;
import java.util.List;
import java.util.Map;

public class ListingQueueingTopology
    {

        private static final String TOPOLOGY_NAME = "ListingQueueingTopology";
        private static final String ZULU_DELTA_SPOUT = "ZuluDeltaSpout";
        private static final String SPLIT_BOLT = "SplitBolt";
        private static final String KAFKA_BOLT = "KafkaBolt";
        private static final int WAIT_TIME = 120;
        private static List<String> verticalGroups;
        private static Config topologyConf = new Config();


        public static void main(String[] args) throws AlreadyAliveException,
                InvalidTopologyException, ClassNotFoundException, IOException
            {
                setup();
            }

        static void setup()
            {
                setupConfig();
                verticalGroups = GuiceInjectorFactory.getInstance().getInstance(VerticalRepository.class)
                                                                                            .getGroups();
                StormUtils.killTopologyAndWait(TOPOLOGY_NAME, WAIT_TIME);
                try                    {
                        StormSubmitter.submitTopology(TOPOLOGY_NAME, topologyConf, buildTopology());
                    } 
                catch (AlreadyAliveException | InvalidTopologyException | IOException e)
                    {
                        throw new RuntimeException();
                    }
                System.exit(0);
            }

        static void setupConfig()
            {
                Yaml yaml = new Yaml();
                Map<String, Object> conf = (Map<String, Object>) yaml.load(ListingQueueingTopology.class
                                            .getClassLoader().getResourceAsStream(TOPOLOGY_NAME + ".yaml"));
                topologyConf.putAll(conf);
            }

        static StormTopology buildTopology() throws IOException
            {
                TopologyBuilder builder = new TopologyBuilder();
                BoltDeclarer splitBoltDeclarer = builder.setBolt(SPLIT_BOLT, new SplitBolt(), 4);
                for (String verticalGroup : verticalGroups)
                    {
                        builder.setSpout(ZULU_DELTA_SPOUT + "-" + verticalGroup,
                                new ZuluDeltaSpout(verticalGroup), 1);
                        splitBoltDeclarer.shuffleGrouping(ZULU_DELTA_SPOUT + "-" + verticalGroup);
                    }

                builder.setBolt(KAFKA_BOLT, new KafkaBolt<String, String>(), 4).shuffleGrouping(SPLIT_BOLT);
                StormTopology stormTopology = builder.createTopology();
                return stormTopology;
            }
    }

Sunday, June 14, 2015

Utils & Constants

Utils & Constants

package flipkart.dsp.santa.bernard.es.client;

import flipkart.dsp.santa.bernard.es.client.handler.property.PropertyHandler;
import flipkart.dsp.santa.offer.classification.criteria.CriteriaKey;
import flipkart.dsp.santa.offer.classification.criteria.EntityCriteriaProperty;
import org.elasticsearch.index.query.BoolFilterBuilder;

import java.util.Map;

public class Utils
    {

        public static void addFilter(Map<CriteriaKey, EntityCriteriaProperty> 
                      criteria, BoolFilterBuilder filterBuilder, Boolean isInclude)
            {
              if (criteria != null)
                {
                  for (Map.Entry<CriteriaKey, EntityCriteriaProperty> entry :                                                              criteria.entrySet())
                    {
                       PropertyHandler classificationHandler = BernardClientImpl
                                     .getPropertyFactory().getClassificationHandler                                      (entry.getValue().getClass());
                       if (isInclude)
                            filterBuilder.must(classificationHandler
                                         .prepareAggregation(entry.getValue()));
                       else                            filterBuilder.mustNot(classificationHandler
                                         .prepareAggregation(entry.getValue()));
                     }
                  }
            }
    }


-----------------------------------------------------------------------------------

package flipkart.dsp.santa.bernard.es.client;

public class Constants
    {

        public static final String REF_ID = "ref_id";
        public static final String VICTOR_REF = "victor_ref";
        public static final String ELIGIBLE_SELLER = "eligible_seller";
        public static final String SELLER_ID = "seller_id";
        public static final String BRAND = "brand";
        public static final String VERTICAL = "vertical";
        public static final String FSP = "fsp";
        public static final String SERVICE_PROFILE = "service_profile";
        public static final String CATEGORY_NODE_ID = "category_node_id";
        public static final String DISCOUNT_PERCENT = "discount_percent";
    }

Monday, May 25, 2015

JConsole

The JConsole graphical user interface is a monitoring tool that complies to the Java Management Extensions (JMX) specification. JConsole uses the extensive instrumentation of the Java Virtual Machine (Java VM) to provide information about the performance and resource consumption of applications running on the Java platform.
Starting JConsole
The jconsole executable can be found in JDK_HOME/bin, where JDK_HOME is the directory in which the Java Development Kit (JDK) is installed. 
If this directory is in your system path, you can start JConsole by simply typing jconsole in a command (shell) prompt. Otherwise, you have to type the full path to the executable file.

Command Syntax

You can use JConsole to monitor both local applications and  remote applications.

Setting up Local Monitoring

You start JConsole by typing the following command at the command line.
% jconsole
When JConsole starts, you will be given a choice of all the Java applications that are running locally that JConsole can connect to.
If you want to monitor a specific application, and you know that application's process ID, then you can also start JConsole so that it connects to that application. This application must be running with the same user ID as JConsole. The command syntax to start JConsole for local monitoring of a specific application is the following.
% jconsole processID
For example, if you determined that the process ID of the Notepad application is 2956, then you would start JConsole with the following command.
% jconsole 2956
Both JConsole and the application must by executed by the same user. The management and monitoring system uses the operating system's file permissions. If you do not specify a process ID, JConsole will automatically detect all local Java applications, and display a dialog box that lets you select which one you want to monitor.

Setting up Remote Monitoring


To start JConsole for remote monitoring, you use the following command syntax.
% jconsole hostName:portNum
In the command above, hostName is the name of the system running the application and portNum is the port number you specified when you enabled the JMX agent when you started the Java VM.
If you do not specify a host name/port number combination, then JConsole will display a connection dialog box to enable you to enter a host name and port number.


Sunday, May 24, 2015

MBeans

An MBean is a managed Java object, similar to a JavaBeans component, that follows the design patterns set forth in the JMX specification.An MBean can represent a device, an application, or any resource that needs to be managed.

MBeans expose a management interface that consists of the following:
  • A set of readable or writable attributes, or both.
  • A set of invokable operations.
  • A self-description.
The management interface does not change throughout the life of an MBean instance.

MBeans can also emit notifications when certain predefined events occur.

The JMX specification defines five types of MBean:
  • Standard MBeans
  • Dynamic MBeans
  • Open MBeans
  • Model MBeans
  • MXBeans

Standard MBeans

A standard MBean is defined by writing a Java interface called SomethingMBean and a Java class called Something that implements that interface. Every method in the interface defines either an attribute or an operation in the MBean. By default, every method defines an operation. Attributes and operations are methods that follow certain design patterns. A standard MBean is composed of an MBean interface and a class. The MBean interface lists the methods for all exposed attributes and operations. The class implements this interface and provides the functionality of the instrumented resource.
The following sections examine an example of a standard MBean and a simple JMX technology-enabled agent (JMX agent) that manages the MBean.

MBean Interface

An example of a basic MBean interface, HelloMBean , follows:
package com.example; 
 
public interface HelloMBean { 
 
    public void sayHello(); 
    public int add(int x, int y); 
    
    public String getName(); 
     
    public int getCacheSize(); 
    public void setCacheSize(int size); 
} 

By convention, an MBean interface takes the name of the Java class that implements it, with the suffix MBean added. In this case, the interface is called HelloMBean. TheHello class that implements this interface is described in the next section.

According to the JMX specification, an MBean interface consists of named and typed attributes that are readable and possibly writable, in addition to the named and typed operations that can be invoked by the applications that are managed by the MBean. The HelloMBean interface declares two operations: the Java methods add() andsayHello().

HelloMBean declares two attributes: Name is a read-only string, and CacheSize is an integer that can be both read and written. Getter and setter methods are declared to allow the managed application to access and possibly change the attribute values. As defined by the JMX specification, a getter is any public method that does not return void and whose name begins with get. A getter enables a manager to read the value of the attribute, whose type is that of the returned object. A setter is any public method that takes a single parameter and whose name begins with set. A setter enables a manager to write a new value in the attribute, whose type is the same as that of the parameter.


MBean Implementation

The Hello Java class that follows implements the HelloMBean MBean interface:
package com.example; 
 
public class Hello ... 
    implements HelloMBean { 
    public void sayHello() { 
        System.out.println("hello, world"); 
    } 
     
    public int add(int x, int y) { 
        return x + y; 
    } 
     
    public String getName() { 
        return this.name; 
    }  
     
    public int getCacheSize() { 
        return this.cacheSize; 
    } 
     
    public synchronized void setCacheSize(int size) {
        ...
    
        this.cacheSize = size; 
        System.out.println("Cache size now " + this.cacheSize); 
    } 
    ...
     
    private final String name = "Reginald"; 
    private int cacheSize = DEFAULT_CACHE_SIZE; 
    private static final int 
        DEFAULT_CACHE_SIZE = 200; 
}
The straightforward Hello class provides the definitions of the operations and attributes that are declared by HelloMBean. The sayHello() and add() operations are extremely simple, but real-life operations can be as simple or as sophisticated as needed.
The methods to get the Name attribute and to get and set the CacheSize attribute are also defined. In this example, the Name attribute value never changes. However, in a real scenario this attribute might change as the managed resource runs. For example, the attribute might represent statistics such as uptime or memory usage. Here, the attribute is merely the name Reginald.
Calling the setCacheSize method enables you to alter the CacheSize attribute from its declared default value of 200. In a real scenario, changing the CacheSizeattribute could require other operations to be performed, such as discarding entries or allocating new entries. This example merely prints a message to confirm that the cache size has changed. However, more sophisticated operations could be defined instead of the simple call to println().
With the Hello MBean and its interface thus defined, they can now be used to manage the resource they represent, as shown in the following section.

Creating a JMX Agent to Manage a Resource

Once a resource has been instrumented by MBeans, the management of that resource is performed by a JMX agent.
The core component of a JMX agent is the MBean server. An MBean server is a managed object server in which MBeans are registered. A JMX agent also includes a set of services to manage MBeans. See the API documentation for the MBeanServer interface for details of the MBean server implementation.
The Main class that follows represents a basic JMX agent:
package com.example; 
 
import java.lang.management.*; 
import javax.management.*; 
 
public class Main { 
 
    public static void main(String[] args) 
        throws Exception { 
     
        MBeanServer mbs = ManagementFactory.getPlatformMBeanServer(); 
        ObjectName name = new ObjectName("com.example:type=Hello"); 
        Hello mbean = new Hello(); 
        mbs.registerMBean(mbean, name); 
          
        ...
     
        System.out.println("Waiting forever..."); 
        Thread.sleep(Long.MAX_VALUE); 
    } 
} 
The JMX agent Main begins by obtaining an MBean server that has been created and initialized by the platform, by calling the getPlatformMBeanServer() method of the java.lang.management.ManagementFactory class. If no MBean server has been created by the platform already, then getPlatformMBeanServer() creates an MBean server automatically by calling the JMX method MBeanServerFactory.createMBeanServer(). The MBeanServer instance obtained by Main is namedmbs.
Next, Main defines an object name for the MBean instance that it will create. Every JMX MBean must have an object name. The object name is an instance of the JMX class ObjectName and must conform to the syntax defined by the JMX specification. Namely, the object name must contain a domain and a list of key-properties. In the object name defined by Main, the domain is com.example (the package in which the example MBean is contained). In addition, the key-property declares that this object is of the type Hello.
An instance of a Hello object, named mbean, is created. The Hello object named mbean is then registered as an MBean in the MBean server mbs with the object namename, by passing the object and the object name into a call to the JMX method MBeanServer.registerMBean().
With the Hello MBean registered in the MBean server, Main simply waits for management operations to be performed on Hello. In this example, these management operations are invoking sayHello() and add(), and getting and setting the attribute values.

Java Bean

Java Bean

A bean is a regular java object used for modelling data. e.g. GuestBookEntry

A Java Bean is a java class that  should follow following conventions:
  • It should have a no-arg constructor.
  • It should be Serializable.
  • It should provide methods to set and get the values of the properties, known as getter and setter methods.

Why use Java Bean?

According to Java white paper, it is a reusable software component. A bean encapsulates many objects into one object, so we can access this object from multiple places. Moreover, it provides the easy maintenance.

Simple example of java bean class

  1. //Employee.java  
  2.   
  3. package mypack;  
  4. public class Employee implements java.io.Serializable{  
  5. private int id;  
  6. private String name;  
  7.   
  8. public Employee(){}  
  9.   
  10. public void setId(int id){this.id=id;}  
  11.   
  12. public int getId(){return id;}  
  13.   
  14. public void setName(String name){this.name=name;}  
  15.   
  16. public String getName(){return name;}  
  17.   
  18. }  

How to access the java bean class?

To access the java bean class, we should use getter and setter methods.
  1. package mypack;  
  2. public class Test{  
  3. public static void main(String args[]){  
  4.   
  5. Employee e=new Employee();//object is created  
  6.   
  7. e.setName("Arjun");//setting value to the object  
  8.   
  9. System.out.println(e.getName());  
  10.   
  11. }}  

Note: There are two ways to provide values to the object, one way is by constructor and second is by setter method.