Subversion Repositories SmartDukaan

Rev

Rev 2298 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
68 ashish 1
package in.shop2020.thrift.clients;
2
 
3123 rajveer 3
import javax.annotation.PostConstruct;
4
import javax.annotation.PreDestroy;
5
 
68 ashish 6
import in.shop2020.config.ConfigException;
7
import in.shop2020.thrift.clients.config.ConfigClient;
8
import in.shop2020.utils.Logger;
9
 
193 ashish 10
import org.apache.thrift.protocol.TBinaryProtocol;
68 ashish 11
import org.apache.thrift.protocol.TProtocol;
12
import org.apache.thrift.transport.TFramedTransport;
13
import org.apache.thrift.transport.TSocket;
14
import org.apache.thrift.transport.TTransport;
3123 rajveer 15
import org.apache.thrift.transport.TTransportException;
68 ashish 16
 
3123 rajveer 17
public abstract class GenericClient {
18
	/**
19
	 * Socket timeout to be set for thrift
20
	 */
21
	private final int SOCKET_TIMEOUT = 1000 * 60 * 5;
22
	protected TSocket socket = null;
23
	protected TTransport transport = null;
24
	protected TProtocol protocol = null;
68 ashish 25
 
3123 rajveer 26
	/**
27
	 * Max attempts on one instance of service to be tried before falling on next instance of service
28
	 */
29
	protected static final int MAX_ATTEMPTS = 3;
30
	protected static final int FIRST_ATTEMPT = 1;
31
	/**
32
	 * Max instances of service to be tried before dying
33
	 */
34
	protected static final int TOTAL_SERVICES = 2;
35
	/**
36
	 * Current service instance being used
37
	 */
38
	protected int serviceNumber = 0;
68 ashish 39
	protected String hostname = "localhost";
40
	protected int port = 8080;
41
 
3123 rajveer 42
	protected String hostConfigKey;
43
	protected String portConfigKey;
44
 
68 ashish 45
 
46
 
3123 rajveer 47
	/**
48
	 * Constructor
49
	 * @param hostConfigKey
50
	 * @param portConfigKey
51
	 * @throws TTransportException
52
	 */
53
	public GenericClient(String hostConfigKey, String portConfigKey) throws TTransportException{
54
		this.hostConfigKey = hostConfigKey; 
55
		this.portConfigKey = portConfigKey;
56
		loadConfigParameters(hostConfigKey, portConfigKey);
57
		connectToService(FIRST_ATTEMPT);
58
	}
59
 
60
	/**
61
	 * Load config parameters for the given key set
62
	 * @param hostConfigKey
63
	 * @param portConfigKey
64
	 */
65
	private void loadConfigParameters(String hostConfigKey, String  portConfigKey){
68 ashish 66
		this.hostname = getHost(hostConfigKey);
67
		this.port = getPort(portConfigKey);
68
	}
69
 
3123 rajveer 70
 
71
	/**
72
	 * get the Host name from given key
73
	 * @param key
74
	 * @return
75
	 */
68 ashish 76
	private String getHost(String key){
77
		try {
78
			String host = ConfigClient.getClient().get(key);
79
			return host;
80
		} catch (ConfigException e) {
81
			Logger.log("Error while fetching hostname for key "+ key+" using localhost:"+ e, this);
82
			return "localhost";
83
		}
84
	}
85
 
3123 rajveer 86
	/**
87
	 * get the Port from given key
88
	 * @param key
89
	 * @return
90
	 */
68 ashish 91
	private int getPort(String key){
92
		try {
93
			String port = ConfigClient.getClient().get(key);
94
			return Integer.parseInt(port);
95
		}catch (NumberFormatException ne){
96
			Logger.log("Could not convert string to int for key "+ key+" using 8080 as port"+ ne, this);
3123 rajveer 97
			return 8080;
68 ashish 98
		}
99
		catch (ConfigException e) {
100
			Logger.log("Error while fetching port for key "+ key+" using 8080:"+ e, this);
3123 rajveer 101
			return 8080;
68 ashish 102
		}
103
	}
3123 rajveer 104
 
105
	/**
106
	 * Connect to the service. It also have mechanism to handle multiple service instances.
107
	 * Connect to default service:
108
	 *     If fails: Connect to another services instances till have tried all services.
109
	 * Tries the default service at MAX_ATTEMPTS times  
110
	 * @param attemptNumber
111
	 * @throws TTransportException
112
	 */
113
	private void connectToService(int attemptNumber) throws TTransportException{
114
		try{
115
			openTransport();
116
		}catch (TTransportException e) {
117
			if(attemptNumber < MAX_ATTEMPTS){
118
				connectToService(attemptNumber+1);
119
			}else{
120
				if(serviceNumber < TOTAL_SERVICES){
121
					serviceNumber += 1;
122
					Logger.log("Maximum attempts have reached. Failing over to another service", null);
123
					loadConfigParameters(this.hostConfigKey + serviceNumber, this.portConfigKey + serviceNumber);
124
					connectToService(FIRST_ATTEMPT);
125
					updateConfigParameters(this.hostConfigKey, this.portConfigKey);
126
				}else{
127
					Logger.log("Have tried enough services. Giving up.....", null);
128
					throw e;
129
				}
130
			}
131
		}
132
	}
767 rajveer 133
 
3123 rajveer 134
	/**
135
	 * Update the config parameters for the current service being used, so that next time these parameters can be used.
136
	 * @param hostConfigKey
137
	 * @param portConfigKey
138
	 */
139
	private void updateConfigParameters(String hostConfigKey, String portConfigKey){
140
		try {
141
			ConfigClient.getClient().set(hostConfigKey, this.hostname);
142
			ConfigClient.getClient().set(portConfigKey, this.port+"");
143
		} catch (ConfigException e) {
144
			Logger.log("Unable to update the keys in the section", null);
145
		}	
146
	}
147
 
148
	/**
149
	 * Open the transport to connect to service.
150
	 * @throws TTransportException
151
	 */
152
	@PostConstruct
153
	protected void openTransport() throws TTransportException {
154
		Logger.log("Initializing socket infra ", this);
155
		socket = new TSocket(hostname, port);
156
		socket.setTimeout(SOCKET_TIMEOUT);
157
		transport = new TFramedTransport(socket);
158
		protocol = new TBinaryProtocol(transport);
159
 
160
		if(!transport.isOpen()){
161
			transport.open();
162
		}else{
163
			Logger.log("Transport was already open", this);
164
		}
165
	}
166
 
167
 
168
	/**
169
	 * Close the transport
170
	 */
171
	@PreDestroy
172
	protected void closeTransport(){
173
		if(transport != null && transport.isOpen()){
174
			Logger.log("Closing transport :", this);
175
			transport.close();
176
		}
177
	}
178
 
179
	/**
180
	 * Close the connection.
181
	 */
767 rajveer 182
	public void closeConnection(){
183
		if(transport != null && transport.isOpen()){
184
			Logger.log("Closing transport :", this);
185
			transport.close();
186
		}
187
	}
188
 
3123 rajveer 189
 
190
	/**
191
	 * Closing connection in finalize.
192
	 */
767 rajveer 193
	protected void finalize() throws Throwable{
194
		super.finalize();
195
		this.closeConnection();
196
	}
197
 
3123 rajveer 198
	public abstract void closeSession();
199
 
68 ashish 200
}