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

Commit

Permalink
DATASOLR-211 Provide implementation of CloudSolrClientFactory
Browse files Browse the repository at this point in the history
  • Loading branch information
manios committed Sep 8, 2015
1 parent ffece80 commit 1481fbe
Show file tree
Hide file tree
Showing 4 changed files with 392 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/*
* Copyright 2014 - 2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.solr.server.support;

import java.util.List;

import org.apache.solr.client.solrj.SolrClient;
import org.apache.solr.client.solrj.impl.CloudSolrClient;
import org.springframework.data.solr.core.SolrTemplate;

/**
* A factory class which can be used as a parameter to {@link SolrTemplate} constructor in order to use
* {@link CloudSolrClient} and connect to a SolrCloud collection installation.
*
* @author Christos Manios
*
*/
public class CloudSolrClientFactory extends SolrClientFactoryBase {

public CloudSolrClientFactory() {

}

public CloudSolrClientFactory(SolrClient client) {
super(client);
}

/**
* Returns the same as {@link #getSolrClient()}, as we are in SolrCloud mode.
*/
@Override
public SolrClient getSolrClient(String core) {
return this.getSolrClient();
}

/**
* Returns <code>null</code>, as we are in SolrCloud mode.
*/
@Override
public List<String> getCores() {
return null;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,210 @@
/*
* Copyright 2014 - 2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.solr.server.support;

import org.apache.solr.client.solrj.SolrClient;
import org.apache.solr.client.solrj.impl.CloudSolrClient;
import org.apache.solr.client.solrj.impl.LBHttpSolrClient;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.util.Assert;

/**
*
* @author Christos Manios
*
*/
public class CloudSolrClientFactoryBean extends CloudSolrClientFactory implements FactoryBean<SolrClient>,
InitializingBean, DisposableBean {

private String zkHost;
private String collection;
private Integer zkClientTimeout;
private Integer zkConnectTimeout;
private Integer httpConnectTimeout;
private Integer httpSoTimeout;

@Override
public void afterPropertiesSet() throws Exception {
Assert.hasText(zkHost);
Assert.hasText(collection);

initSolrClient();
}

private void initSolrClient() {

// create a new CloudSolrClient with a specified comma delimited string
// format which contains IP1:port,IP2:port of Zookeeper ensemble
CloudSolrClient solrClient = new CloudSolrClient(zkHost);

// set collection name
solrClient.setDefaultCollection(collection);

// set Zookeeper ensemble connection timeout
if (zkConnectTimeout != null) {
solrClient.setZkConnectTimeout(zkConnectTimeout);
}

// set Zookeeper ensemble client timeout
if (zkClientTimeout != null) {
solrClient.setZkClientTimeout(zkClientTimeout);
}

// set http connection timeout
if (httpConnectTimeout != null) {
solrClient.getLbClient().setConnectionTimeout(httpConnectTimeout);
}

// set http read timeout
if (httpSoTimeout != null) {
solrClient.getLbClient().setSoTimeout(httpSoTimeout);
}

this.setSolrClient(solrClient);
}

@Override
public SolrClient getObject() throws Exception {
return getSolrClient();
}

@Override
public Class<?> getObjectType() {
if (getSolrClient() == null) {
return CloudSolrClient.class;
}
return getSolrClient().getClass();
}

@Override
public boolean isSingleton() {
return true;
}

/**
* Returns a pair of IP and its respective port of the Zookeeper server which belongs to the Zookeeper ensemble. This
* string can contain multiple IP:port definitions separated by comma.
* <p>
* Example: <code>192.168.1.1:2181,192.168.1.2:2181,192.168.1.3:2181</code>
* </p>
*
*/
public String getZkHost() {
return zkHost;
}

/**
* Sets the IPs and their respective ports of the Zookeeper servers which belong to the Zookeeper ensemble. This
* string can contain multiple IP:port definitions separated by comma.
* <p>
* Example: <code>192.168.1.1:2181,192.168.1.2:2181,192.168.1.3:2181</code>
* </p>
*
*/
public void setZkHost(String zkHost) {
this.zkHost = zkHost;
}

/**
* Returns the SolrCloud collection name on which this {@link CloudSolrClient} will be connected to.
*/
public String getCollection() {
return collection;
}

/**
* Set the SolrCloud collection name on which this {@link CloudSolrClient} will be connected to.
*/
public void setCollection(String collectionName) {
this.collection = collectionName;
}

/**
* Returns the HTTP connection timeout of underlying {@link LBHttpSolrClient} used for queries, in milliseconds.
* <p>
* Default is 0 (infinite timeout)
* </p>
*/
public Integer getHttpConnectTimeout() {
return httpConnectTimeout;
}

/**
* Sets the HTTP connection timeout of underlying {@link LBHttpSolrClient} in milliseconds.
*
* @param httpConnectTimeout HTTP connect timeout in milliseconds . Default is 0 (infinite timeout)
*
*/
public void setHttpConnectTimeout(Integer httpConnectTimeout) {
this.httpConnectTimeout = httpConnectTimeout;
}

/**
* Returns the HTTP soTimeout (read timeout) of underlying {@link LBHttpSolrClient} used for queries, in milliseconds.
* <p>
* Default is 0 (infinite timeout)
* </p>
*/
public Integer getHttpSoTimeout() {
return httpSoTimeout;
}

/**
* Sets the HTTP soTimeout (read timeout) of underlying {@link LBHttpSolrClient} in milliseconds.
*
* @param httpReadTimeout HTTP read timeout in milliseconds. Default is 0 (infinite timeout)
*/
public void setHttpSoTimeout(Integer httpSoTimeout) {
this.httpSoTimeout = httpSoTimeout;
}

/**
* Returns the client timeout to the zookeeper ensemble in milliseconds
*/
public Integer getZkClientTimeout() {
return zkClientTimeout;
}

/**
* Sets the client timeout to the zookeeper ensemble in milliseconds. Default value: 10000ms
*
* @param zkClientTimeout client timeout to zookeeper ensemble in milliseconds.
*/
public void setZkClientTimeout(Integer zkClientTimeout) {
this.zkClientTimeout = zkClientTimeout;
}

/**
* Returns the connection timeout to the zookeeper ensemble in milliseconds. Default value: 10000ms
*
* @param zkConnectTimeout connection timeout to zookeeper ensemble in milliseconds.
*/
public Integer getZkConnectTimeout() {
return zkConnectTimeout;
}

/**
* Sets the connection timeout to the zookeeper ensemble in milliseconds. Default value: 10000ms
*
* @param zkConnectTimeout connection timeout to zookeeper ensemble in milliseconds.
*/
public void setZkConnectTimeout(Integer zkConnectTimeout) {
this.zkConnectTimeout = zkConnectTimeout;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
/*
* Copyright 2012 - 2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.solr.server.support;

import java.lang.reflect.Field;

import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.apache.solr.client.solrj.impl.CloudSolrClient;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.data.solr.core.SolrTemplate;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

/**
* @author Manios Christos
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("CloudSolrClientFactoryTest-context.xml")
public class CloudSolrClientFactoryTests {

@Autowired
ApplicationContext context;

private static final String zkHost = "127.0.0.1:2181,127.0.0.1:2182";
private static final Integer expectedHttpConnectTimeout = 1500;
private static final Integer expectedHttpSoTimeout = 1800;
private static final Integer expectedZkConnectTimeout = 1300;
private static final Integer expectedZkClientTimeout = 1400;
private static final String collectionName = "jet2pilot";

/**
* Testing issue DATASOLR-211
*/
@Test
public void testCreateCloudSorlClientUsingFactory() {

// test solrtemplate
SolrTemplate solrTemplate = context.getBean("solrTemplate", SolrTemplate.class);
Assert.assertNotNull(solrTemplate);

CloudSolrClient clientFromfactoryBean = context.getBean("cloudSolrClientFactory", CloudSolrClient.class);
Assert.assertNotNull(clientFromfactoryBean);

// check that solr client is not null
CloudSolrClient solrClient = (CloudSolrClient) solrTemplate.getSolrClient();
Assert.assertNotNull(solrClient);

Assert.assertSame(solrClient, clientFromfactoryBean);

Assert.assertEquals(collectionName, solrClient.getDefaultCollection());

// get httpParams() which is deprecated in order to test timeouts
// I could not find another way to get them..
HttpParams httpParams = solrClient.getLbClient().getHttpClient().getParams();

Assert.assertEquals(expectedHttpConnectTimeout, (Integer) HttpConnectionParams.getConnectionTimeout(httpParams));
Assert.assertEquals(expectedHttpSoTimeout, (Integer) HttpConnectionParams.getSoTimeout(httpParams));

// now try to get private fields using reflection

try {
// try to get zkHost
Field actualZkHostField = solrClient.getClass().getDeclaredField("zkHost");

// try to get zkConnectTimeout
Field actualZkConnectTimeoutField = solrClient.getClass().getDeclaredField("zkConnectTimeout");

// try to get zkClientTimeout
Field actualZkClientTimeoutField = solrClient.getClass().getDeclaredField("zkClientTimeout");

Assert.assertEquals(zkHost, (String) actualZkHostField.get(solrClient));
Assert.assertEquals(expectedZkConnectTimeout.intValue(), actualZkConnectTimeoutField.getInt(solrClient));
Assert.assertEquals(expectedZkClientTimeout.intValue(), actualZkClientTimeoutField.getInt(solrClient));

} catch (NoSuchFieldException e) {
} catch (SecurityException e) {
} catch (IllegalArgumentException e) {
} catch (IllegalAccessException e) {
}

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:solr="http://www.springframework.org/schema/data/solr"
xsi:schemaLocation="http://www.springframework.org/schema/data/solr http://www.springframework.org/schema/data/solr/spring-solr-1.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

<solr:repositories base-package="org.springframework.data.solr.repository.config" />

<!-- Configures CloudSolrClient using a factory bean -->
<bean id="cloudSolrClientFactory"
class="org.springframework.data.solr.server.support.CloudSolrClientFactoryBean">
<property name="zkHost" value="127.0.0.1:2181,127.0.0.1:2182" />
<property name="collection" value="jet2pilot" />
<property name="httpConnectTimeout" value="1500" />
<property name="httpSoTimeout" value="1800" />
<property name="zkConnectTimeout" value="1300" />
<property name="zkClientTimeout" value="1400" />
</bean>

<!-- Configures Solr template -->
<bean id="solrTemplate" class="org.springframework.data.solr.core.SolrTemplate">
<constructor-arg index="0" ref="cloudSolrClientFactory" />
</bean>

</beans>

0 comments on commit 1481fbe

Please sign in to comment.