Project

General

Profile

1
package eu.dnetlib.functionality.index.utils;
2

    
3
import com.google.common.collect.Maps;
4
import com.google.gson.JsonElement;
5
import com.google.gson.JsonObject;
6
import com.google.gson.JsonParser;
7
import eu.dnetlib.data.provision.index.rmi.IndexServiceException;
8
import eu.dnetlib.functionality.index.model.Any.ValueType;
9
import org.apache.commons.logging.Log;
10
import org.apache.commons.logging.LogFactory;
11
import org.apache.http.HttpResponse;
12
import org.apache.http.client.HttpClient;
13
import org.apache.http.client.methods.HttpGet;
14
import org.apache.solr.client.solrj.SolrClient;
15
import org.apache.solr.client.solrj.SolrServerException;
16
import org.apache.solr.client.solrj.impl.CloudSolrClient;
17
import org.apache.solr.client.solrj.request.LukeRequest;
18
import org.apache.solr.client.solrj.response.LukeResponse;
19
import org.apache.solr.client.solrj.response.LukeResponse.FieldInfo;
20
import org.apache.solr.client.solrj.response.SolrPingResponse;
21
import org.apache.solr.common.cloud.SolrZkClient;
22
import org.apache.zookeeper.WatchedEvent;
23
import org.apache.zookeeper.Watcher;
24
import org.apache.zookeeper.data.Stat;
25
import org.springframework.beans.factory.annotation.Required;
26

    
27
import java.io.IOException;
28
import java.util.Map;
29

    
30
public class RemoteSolrAdministrator {
31

    
32
	/**
33
	 * The log.
34
	 */
35
	private static final Log log = LogFactory.getLog(RemoteSolrAdministrator.class);
36

    
37
	/** The create url request. */
38
	private static String createURLRequest = "http://%s:%s/solr/admin/collections?action=CREATE&name=%s&numShards=%s&replicationFactor=%s&maxShardsPerNode=%s&collection.configName=%s";
39

    
40
	/** The create url request. */
41
	private static String reloadURLRequest = "http://%s:%s/solr/admin/collections?action=RELOAD&name=%s";
42

    
43
	/** The http client. */
44
	private HttpClient httpClient;
45

    
46
	protected Map<String, Map<String, ValueType>> cachedSchema;
47

    
48
	public RemoteSolrAdministrator() {
49
		this.cachedSchema = Maps.newHashMap();
50
	}
51

    
52
	public boolean createSolrIndex(final String host,
53
			final String port,
54
			final String collectionName,
55
			final String numShard,
56
			final String replicationFactor,
57
			final String maxShardsPerNode,
58
		final String collectionConfigName) throws IndexServiceException {
59

    
60
		final String uri = generateCreateIndexRequest(host, port, collectionName, numShard, replicationFactor, maxShardsPerNode, collectionConfigName);
61
		log.info(uri);
62
		HttpGet request = new HttpGet(uri);
63
		HttpResponse response;
64
		try {
65
			response = getHttpClient().execute(request);
66

    
67
		} catch (Exception e) {
68
			throw new IndexServiceException("Unable to send request to solr server", e);
69
		} finally {
70
			request.releaseConnection();
71
		}
72
		if (response.getStatusLine().getStatusCode() != 200)
73
			throw new IndexServiceException("Error on creating index the error code from solr is" + response.toString());
74
		return false;
75
	}
76

    
77
	public boolean indexCollectionExists(final String indexCollectionId, final CloudSolrClient client) {
78

    
79
		Watcher watcher = new Watcher() {
80

    
81
			@Override
82
			public void process(final WatchedEvent arg0) {}
83
		};
84
		try {
85
			// server.connect();
86
			SolrZkClient zkClient = client.getZkStateReader().getZkClient();
87
			if (!zkClient.isConnected()) {
88
				client.close();
89
				client.connect();
90
			}
91

    
92
			byte[] data = zkClient.getData("/clusterstate.json", watcher, new Stat(), true);
93
			if (data == null) return false;
94
			String jsonLine = new String(data);
95
			JsonElement jelement = new JsonParser().parse(jsonLine);
96
			JsonObject jobject = jelement.getAsJsonObject();
97
			if (jobject.has(indexCollectionId)) {
98
				client.setDefaultCollection(indexCollectionId);
99
				client.connect();
100
				SolrPingResponse status = client.ping();
101
				return (Integer) status.getResponseHeader().get("status") == 0;
102
			} else return false;
103

    
104
		} catch (Exception e) {
105
			log.error(e);
106
			return false;
107
		}
108
	}
109

    
110
	private ValueType resolveSolrTypeClassName(final String solrTypeName) {
111
		if (solrTypeName.contains("LongField")) return ValueType.LONG;
112
		else if (solrTypeName.contains("IntField")) return ValueType.LONG;
113
		else if (solrTypeName.contains("short")) return ValueType.LONG;
114
		else if (solrTypeName.contains("float")) return ValueType.DOUBLE;
115
		else if (solrTypeName.contains("double")) return ValueType.DOUBLE;
116
		else if (solrTypeName.contains("date")) return ValueType.DATETIME;
117
		else return ValueType.STRING;
118
	}
119

    
120
	public Map<String, ValueType> getFieldNamesAndTypes(final String coreName, final SolrClient client) throws IndexServiceException {
121
		try {
122
			if (cachedSchema.get(coreName) == null) {
123
				synchronized (cachedSchema) {
124
					Map<String, ValueType> schema = readFieldNamesAndTypes(coreName, client);
125
					log.info("setting cache for schema of collection: " + coreName);
126
					cachedSchema.put(coreName, schema);
127
				}
128
			}
129
			return cachedSchema.get(coreName);
130
		} catch (Exception e) {
131
			throw new IndexServiceException("Unable to get Schema for " + coreName + " exception", e);
132
		}
133
	}
134

    
135
	private Map<String, ValueType> readFieldNamesAndTypes(final String coreName, final SolrClient client) throws SolrServerException, IOException {
136
		final LukeRequest request = new LukeRequest();
137
		request.setShowSchema(true);
138
		request.setNumTerms(0);
139
		final LukeResponse response = request.process(client);
140
		final Map<String, FieldInfo> fieldInfos = response.getFieldInfo();
141
		final Map<String, LukeResponse.FieldTypeInfo> fieldTypeInfos = response.getFieldTypeInfo();
142
		final Map<String, ValueType> result = Maps.newHashMap();
143
		for (FieldInfo fieldInfo : fieldInfos.values()) {
144
			LukeResponse.FieldTypeInfo fieldTypeInfo = fieldTypeInfos.get(fieldInfo.getType());
145
			final String fieldName = fieldTypeInfo.getName().toLowerCase();
146
			final ValueType fieldType = resolveSolrTypeClassName(fieldName);
147
			result.put(fieldInfo.getName(), fieldType);
148
		}
149
		return result;
150
	}
151

    
152
	private String generateCreateIndexRequest(final String host,
153
			final String port,
154
			final String collectionName,
155
			final String numShard,
156
			final String replicationFactor,
157
			final String collectionConfigName,
158
			final String maxShardsPerNode) {
159
		return String.format(createURLRequest, host, port, collectionName, numShard, replicationFactor, maxShardsPerNode, collectionConfigName);
160
	}
161

    
162
	private String generateUpdateIndexRequest(final String host, final String port, final String collectionName) {
163
		return String.format(reloadURLRequest, host, port, collectionName);
164
	}
165

    
166
	/**
167
	 * @return the httpClient
168
	 */
169
	public HttpClient getHttpClient() {
170
		return httpClient;
171
	}
172

    
173
	/**
174
	 * @param httpClient
175
	 *            the httpClient to set
176
	 */
177
	@Required
178
	public void setHttpClient(final HttpClient httpClient) {
179
		log.info("setting http client " + httpClient.getClass());
180
		this.httpClient = httpClient;
181
	}
182

    
183
	public void reloadCollection(final String host, final String port, final String collectionName) throws IndexServiceException {
184
		log.info("creating the request of reload index " + generateUpdateIndexRequest(host, port, collectionName));
185
		HttpGet request = new HttpGet(generateUpdateIndexRequest(host, port, collectionName));
186
		HttpResponse response;
187
		try {
188
			response = httpClient.execute(request);
189
		} catch (Exception e) {
190
			throw new IndexServiceException("Unable to send request to solr server", e);
191
		} finally {
192
			request.releaseConnection();
193
		}
194
		if (response.getStatusLine().getStatusCode() != 200)
195
			throw new IndexServiceException("Error on reloading index the error code from solr is" + response.toString());
196

    
197
	}
198

    
199
}
(3-3/4)