Skip to content
This repository was archived by the owner on Sep 19, 2023. It is now read-only.

Commit 1481fbe

Browse files
committed
DATASOLR-211 Provide implementation of CloudSolrClientFactory
1 parent ffece80 commit 1481fbe

File tree

4 files changed

+392
-0
lines changed

4 files changed

+392
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/*
2+
* Copyright 2014 - 2015 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.data.solr.server.support;
17+
18+
import java.util.List;
19+
20+
import org.apache.solr.client.solrj.SolrClient;
21+
import org.apache.solr.client.solrj.impl.CloudSolrClient;
22+
import org.springframework.data.solr.core.SolrTemplate;
23+
24+
/**
25+
* A factory class which can be used as a parameter to {@link SolrTemplate} constructor in order to use
26+
* {@link CloudSolrClient} and connect to a SolrCloud collection installation.
27+
*
28+
* @author Christos Manios
29+
*
30+
*/
31+
public class CloudSolrClientFactory extends SolrClientFactoryBase {
32+
33+
public CloudSolrClientFactory() {
34+
35+
}
36+
37+
public CloudSolrClientFactory(SolrClient client) {
38+
super(client);
39+
}
40+
41+
/**
42+
* Returns the same as {@link #getSolrClient()}, as we are in SolrCloud mode.
43+
*/
44+
@Override
45+
public SolrClient getSolrClient(String core) {
46+
return this.getSolrClient();
47+
}
48+
49+
/**
50+
* Returns <code>null</code>, as we are in SolrCloud mode.
51+
*/
52+
@Override
53+
public List<String> getCores() {
54+
return null;
55+
}
56+
57+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,210 @@
1+
/*
2+
* Copyright 2014 - 2015 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.data.solr.server.support;
17+
18+
import org.apache.solr.client.solrj.SolrClient;
19+
import org.apache.solr.client.solrj.impl.CloudSolrClient;
20+
import org.apache.solr.client.solrj.impl.LBHttpSolrClient;
21+
import org.springframework.beans.factory.DisposableBean;
22+
import org.springframework.beans.factory.FactoryBean;
23+
import org.springframework.beans.factory.InitializingBean;
24+
import org.springframework.util.Assert;
25+
26+
/**
27+
*
28+
* @author Christos Manios
29+
*
30+
*/
31+
public class CloudSolrClientFactoryBean extends CloudSolrClientFactory implements FactoryBean<SolrClient>,
32+
InitializingBean, DisposableBean {
33+
34+
private String zkHost;
35+
private String collection;
36+
private Integer zkClientTimeout;
37+
private Integer zkConnectTimeout;
38+
private Integer httpConnectTimeout;
39+
private Integer httpSoTimeout;
40+
41+
@Override
42+
public void afterPropertiesSet() throws Exception {
43+
Assert.hasText(zkHost);
44+
Assert.hasText(collection);
45+
46+
initSolrClient();
47+
}
48+
49+
private void initSolrClient() {
50+
51+
// create a new CloudSolrClient with a specified comma delimited string
52+
// format which contains IP1:port,IP2:port of Zookeeper ensemble
53+
CloudSolrClient solrClient = new CloudSolrClient(zkHost);
54+
55+
// set collection name
56+
solrClient.setDefaultCollection(collection);
57+
58+
// set Zookeeper ensemble connection timeout
59+
if (zkConnectTimeout != null) {
60+
solrClient.setZkConnectTimeout(zkConnectTimeout);
61+
}
62+
63+
// set Zookeeper ensemble client timeout
64+
if (zkClientTimeout != null) {
65+
solrClient.setZkClientTimeout(zkClientTimeout);
66+
}
67+
68+
// set http connection timeout
69+
if (httpConnectTimeout != null) {
70+
solrClient.getLbClient().setConnectionTimeout(httpConnectTimeout);
71+
}
72+
73+
// set http read timeout
74+
if (httpSoTimeout != null) {
75+
solrClient.getLbClient().setSoTimeout(httpSoTimeout);
76+
}
77+
78+
this.setSolrClient(solrClient);
79+
}
80+
81+
@Override
82+
public SolrClient getObject() throws Exception {
83+
return getSolrClient();
84+
}
85+
86+
@Override
87+
public Class<?> getObjectType() {
88+
if (getSolrClient() == null) {
89+
return CloudSolrClient.class;
90+
}
91+
return getSolrClient().getClass();
92+
}
93+
94+
@Override
95+
public boolean isSingleton() {
96+
return true;
97+
}
98+
99+
/**
100+
* Returns a pair of IP and its respective port of the Zookeeper server which belongs to the Zookeeper ensemble. This
101+
* string can contain multiple IP:port definitions separated by comma.
102+
* <p>
103+
* Example: <code>192.168.1.1:2181,192.168.1.2:2181,192.168.1.3:2181</code>
104+
* </p>
105+
*
106+
*/
107+
public String getZkHost() {
108+
return zkHost;
109+
}
110+
111+
/**
112+
* Sets the IPs and their respective ports of the Zookeeper servers which belong to the Zookeeper ensemble. This
113+
* string can contain multiple IP:port definitions separated by comma.
114+
* <p>
115+
* Example: <code>192.168.1.1:2181,192.168.1.2:2181,192.168.1.3:2181</code>
116+
* </p>
117+
*
118+
*/
119+
public void setZkHost(String zkHost) {
120+
this.zkHost = zkHost;
121+
}
122+
123+
/**
124+
* Returns the SolrCloud collection name on which this {@link CloudSolrClient} will be connected to.
125+
*/
126+
public String getCollection() {
127+
return collection;
128+
}
129+
130+
/**
131+
* Set the SolrCloud collection name on which this {@link CloudSolrClient} will be connected to.
132+
*/
133+
public void setCollection(String collectionName) {
134+
this.collection = collectionName;
135+
}
136+
137+
/**
138+
* Returns the HTTP connection timeout of underlying {@link LBHttpSolrClient} used for queries, in milliseconds.
139+
* <p>
140+
* Default is 0 (infinite timeout)
141+
* </p>
142+
*/
143+
public Integer getHttpConnectTimeout() {
144+
return httpConnectTimeout;
145+
}
146+
147+
/**
148+
* Sets the HTTP connection timeout of underlying {@link LBHttpSolrClient} in milliseconds.
149+
*
150+
* @param httpConnectTimeout HTTP connect timeout in milliseconds . Default is 0 (infinite timeout)
151+
*
152+
*/
153+
public void setHttpConnectTimeout(Integer httpConnectTimeout) {
154+
this.httpConnectTimeout = httpConnectTimeout;
155+
}
156+
157+
/**
158+
* Returns the HTTP soTimeout (read timeout) of underlying {@link LBHttpSolrClient} used for queries, in milliseconds.
159+
* <p>
160+
* Default is 0 (infinite timeout)
161+
* </p>
162+
*/
163+
public Integer getHttpSoTimeout() {
164+
return httpSoTimeout;
165+
}
166+
167+
/**
168+
* Sets the HTTP soTimeout (read timeout) of underlying {@link LBHttpSolrClient} in milliseconds.
169+
*
170+
* @param httpReadTimeout HTTP read timeout in milliseconds. Default is 0 (infinite timeout)
171+
*/
172+
public void setHttpSoTimeout(Integer httpSoTimeout) {
173+
this.httpSoTimeout = httpSoTimeout;
174+
}
175+
176+
/**
177+
* Returns the client timeout to the zookeeper ensemble in milliseconds
178+
*/
179+
public Integer getZkClientTimeout() {
180+
return zkClientTimeout;
181+
}
182+
183+
/**
184+
* Sets the client timeout to the zookeeper ensemble in milliseconds. Default value: 10000ms
185+
*
186+
* @param zkClientTimeout client timeout to zookeeper ensemble in milliseconds.
187+
*/
188+
public void setZkClientTimeout(Integer zkClientTimeout) {
189+
this.zkClientTimeout = zkClientTimeout;
190+
}
191+
192+
/**
193+
* Returns the connection timeout to the zookeeper ensemble in milliseconds. Default value: 10000ms
194+
*
195+
* @param zkConnectTimeout connection timeout to zookeeper ensemble in milliseconds.
196+
*/
197+
public Integer getZkConnectTimeout() {
198+
return zkConnectTimeout;
199+
}
200+
201+
/**
202+
* Sets the connection timeout to the zookeeper ensemble in milliseconds. Default value: 10000ms
203+
*
204+
* @param zkConnectTimeout connection timeout to zookeeper ensemble in milliseconds.
205+
*/
206+
public void setZkConnectTimeout(Integer zkConnectTimeout) {
207+
this.zkConnectTimeout = zkConnectTimeout;
208+
}
209+
210+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
/*
2+
* Copyright 2012 - 2015 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.data.solr.server.support;
17+
18+
import java.lang.reflect.Field;
19+
20+
import org.apache.http.params.HttpConnectionParams;
21+
import org.apache.http.params.HttpParams;
22+
import org.apache.solr.client.solrj.impl.CloudSolrClient;
23+
import org.junit.Assert;
24+
import org.junit.Test;
25+
import org.junit.runner.RunWith;
26+
import org.springframework.beans.factory.annotation.Autowired;
27+
import org.springframework.context.ApplicationContext;
28+
import org.springframework.data.solr.core.SolrTemplate;
29+
import org.springframework.test.context.ContextConfiguration;
30+
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
31+
32+
/**
33+
* @author Manios Christos
34+
*/
35+
@RunWith(SpringJUnit4ClassRunner.class)
36+
@ContextConfiguration("CloudSolrClientFactoryTest-context.xml")
37+
public class CloudSolrClientFactoryTests {
38+
39+
@Autowired
40+
ApplicationContext context;
41+
42+
private static final String zkHost = "127.0.0.1:2181,127.0.0.1:2182";
43+
private static final Integer expectedHttpConnectTimeout = 1500;
44+
private static final Integer expectedHttpSoTimeout = 1800;
45+
private static final Integer expectedZkConnectTimeout = 1300;
46+
private static final Integer expectedZkClientTimeout = 1400;
47+
private static final String collectionName = "jet2pilot";
48+
49+
/**
50+
* Testing issue DATASOLR-211
51+
*/
52+
@Test
53+
public void testCreateCloudSorlClientUsingFactory() {
54+
55+
// test solrtemplate
56+
SolrTemplate solrTemplate = context.getBean("solrTemplate", SolrTemplate.class);
57+
Assert.assertNotNull(solrTemplate);
58+
59+
CloudSolrClient clientFromfactoryBean = context.getBean("cloudSolrClientFactory", CloudSolrClient.class);
60+
Assert.assertNotNull(clientFromfactoryBean);
61+
62+
// check that solr client is not null
63+
CloudSolrClient solrClient = (CloudSolrClient) solrTemplate.getSolrClient();
64+
Assert.assertNotNull(solrClient);
65+
66+
Assert.assertSame(solrClient, clientFromfactoryBean);
67+
68+
Assert.assertEquals(collectionName, solrClient.getDefaultCollection());
69+
70+
// get httpParams() which is deprecated in order to test timeouts
71+
// I could not find another way to get them..
72+
HttpParams httpParams = solrClient.getLbClient().getHttpClient().getParams();
73+
74+
Assert.assertEquals(expectedHttpConnectTimeout, (Integer) HttpConnectionParams.getConnectionTimeout(httpParams));
75+
Assert.assertEquals(expectedHttpSoTimeout, (Integer) HttpConnectionParams.getSoTimeout(httpParams));
76+
77+
// now try to get private fields using reflection
78+
79+
try {
80+
// try to get zkHost
81+
Field actualZkHostField = solrClient.getClass().getDeclaredField("zkHost");
82+
83+
// try to get zkConnectTimeout
84+
Field actualZkConnectTimeoutField = solrClient.getClass().getDeclaredField("zkConnectTimeout");
85+
86+
// try to get zkClientTimeout
87+
Field actualZkClientTimeoutField = solrClient.getClass().getDeclaredField("zkClientTimeout");
88+
89+
Assert.assertEquals(zkHost, (String) actualZkHostField.get(solrClient));
90+
Assert.assertEquals(expectedZkConnectTimeout.intValue(), actualZkConnectTimeoutField.getInt(solrClient));
91+
Assert.assertEquals(expectedZkClientTimeout.intValue(), actualZkClientTimeoutField.getInt(solrClient));
92+
93+
} catch (NoSuchFieldException e) {
94+
} catch (SecurityException e) {
95+
} catch (IllegalArgumentException e) {
96+
} catch (IllegalAccessException e) {
97+
}
98+
99+
}
100+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<beans xmlns="http://www.springframework.org/schema/beans"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:solr="http://www.springframework.org/schema/data/solr"
4+
xsi:schemaLocation="http://www.springframework.org/schema/data/solr http://www.springframework.org/schema/data/solr/spring-solr-1.0.xsd
5+
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
6+
7+
<solr:repositories base-package="org.springframework.data.solr.repository.config" />
8+
9+
<!-- Configures CloudSolrClient using a factory bean -->
10+
<bean id="cloudSolrClientFactory"
11+
class="org.springframework.data.solr.server.support.CloudSolrClientFactoryBean">
12+
<property name="zkHost" value="127.0.0.1:2181,127.0.0.1:2182" />
13+
<property name="collection" value="jet2pilot" />
14+
<property name="httpConnectTimeout" value="1500" />
15+
<property name="httpSoTimeout" value="1800" />
16+
<property name="zkConnectTimeout" value="1300" />
17+
<property name="zkClientTimeout" value="1400" />
18+
</bean>
19+
20+
<!-- Configures Solr template -->
21+
<bean id="solrTemplate" class="org.springframework.data.solr.core.SolrTemplate">
22+
<constructor-arg index="0" ref="cloudSolrClientFactory" />
23+
</bean>
24+
25+
</beans>

0 commit comments

Comments
 (0)