From c3098bd76057a6484561742214beb79814d3bbaf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Basl=C3=A9?= Date: Fri, 19 Jun 2015 17:01:52 +0200 Subject: [PATCH] xml conf for CouchbaseEnvironment and Cluster parser, factoryBean and test for CouchbaseEnvironment starting parser for Cluster --- .../data/couchbase/config/BeanNames.java | 11 +- .../config/CouchbaseClusterParser.java | 117 ++++++++ .../CouchbaseEnvironmentFactoryBean.java | 254 ++++++++++++++++++ .../config/CouchbaseEnvironmentParser.java | 139 ++++++++++ .../config/CouchbaseNamespaceHandler.java | 1 + .../CouchbaseEnvironmentParserTest.java | 109 ++++++++ .../configurations/couchbaseEnv-bean.xml | 48 ++++ 7 files changed, 673 insertions(+), 6 deletions(-) create mode 100644 src/main/java/org/springframework/data/couchbase/config/CouchbaseClusterParser.java create mode 100644 src/main/java/org/springframework/data/couchbase/config/CouchbaseEnvironmentFactoryBean.java create mode 100644 src/main/java/org/springframework/data/couchbase/config/CouchbaseEnvironmentParser.java create mode 100644 src/test/java/org/springframework/data/couchbase/config/CouchbaseEnvironmentParserTest.java create mode 100644 src/test/resources/configurations/couchbaseEnv-bean.xml diff --git a/src/main/java/org/springframework/data/couchbase/config/BeanNames.java b/src/main/java/org/springframework/data/couchbase/config/BeanNames.java index 006fd186..ceb620cc 100644 --- a/src/main/java/org/springframework/data/couchbase/config/BeanNames.java +++ b/src/main/java/org/springframework/data/couchbase/config/BeanNames.java @@ -25,28 +25,27 @@ package org.springframework.data.couchbase.config; public class BeanNames { /** - * Refers to the bean. + * Refers to the "<couchbase:env />" bean. */ static final String COUCHBASE_ENV = "couchbaseEnv"; /** - * Refers to the "" bean. + * Refers to the "<couchbase:cluster />" bean. */ static final String COUCHBASE_CLUSTER = "couchbaseCluster"; /** - * Refers to the "" bean. + * Refers to the "<couchbase:bucket />" bean. */ static final String COUCHBASE_BUCKET = "couchbaseBucket"; /** - * Refers to the "" bean. + * Refers to the "<couchbase:template />" bean. */ static final String COUCHBASE_TEMPLATE = "couchbaseTemplate"; /** - * Refers to the "" bean + * Refers to the "<couchbase:translation-service />" bean */ static final String TRANSLATION_SERVICE = "couchbaseTranslationService"; - } diff --git a/src/main/java/org/springframework/data/couchbase/config/CouchbaseClusterParser.java b/src/main/java/org/springframework/data/couchbase/config/CouchbaseClusterParser.java new file mode 100644 index 00000000..f921387f --- /dev/null +++ b/src/main/java/org/springframework/data/couchbase/config/CouchbaseClusterParser.java @@ -0,0 +1,117 @@ +/* + * 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.couchbase.config; + +import java.util.ArrayList; +import java.util.List; + +import com.couchbase.client.java.Cluster; +import org.w3c.dom.Element; +import org.w3c.dom.NodeList; + +import org.springframework.beans.factory.support.AbstractBeanDefinition; +import org.springframework.beans.factory.support.BeanDefinitionBuilder; +import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser; +import org.springframework.beans.factory.xml.ParserContext; +import org.springframework.util.StringUtils; +import org.springframework.util.xml.DomUtils; + +public class CouchbaseClusterParser extends AbstractSingleBeanDefinitionParser { + + /** + * The <node> elements in a cluster definition define the bootstrap hosts to use + */ + public static final String CLUSTER_NODE_TAG = "node"; + + /** + * The unique <env> element in a cluster definition define the environment customizations. + * + * @see CouchbaseEnvironmentParser for the possible fields. + * @see #CLUSTER_ENVIRONMENT_REF as an alternative (giving a reference to an env instead of inline description) + */ + public static final String CLUSTER_ENVIRONMENT_TAG = "env"; + + + public static final String CLUSTER_ENVIRONMENT_REF = "env-ref"; + + /** + * Resolve the bean ID and assign a default if not set. + * + * @param element the XML element which contains the attributes. + * @param definition the bean definition to work with. + * @param parserContext encapsulates the parsing state and configuration. + * @return the ID to work with. + */ + @Override + protected String resolveId(final Element element, final AbstractBeanDefinition definition, final ParserContext parserContext) { + String id = super.resolveId(element, definition, parserContext); + return StringUtils.hasText(id) ? id : BeanNames.COUCHBASE_CLUSTER; + } + + /** + * Defines the bean class that will be constructed. + * + * @param element the XML element which contains the attributes. + * @return the class type to instantiate. + */ + @Override + protected Class getBeanClass(final Element element) { + return Cluster.class; + } + + /** + * Parse the bean definition and build up the bean. + * + * @param element the XML element which contains the attributes. + * @param bean the builder which builds the bean. + */ + @Override + protected void doParse(final Element element, final BeanDefinitionBuilder bean) { + parseEnvironment(bean, element); + + NodeList nodes = element.getElementsByTagName(CLUSTER_NODE_TAG); + if (nodes != null && nodes.getLength() > 0) { + List bootstrapUrls = new ArrayList(nodes.getLength()); + for (int i = 0; i < bootstrapUrls.size(); i++) { + bootstrapUrls.add(nodes.item(i).getNodeValue()); + } + bean.addConstructorArgValue(bootstrapUrls); + } + } + + public static boolean parseEnvironment(BeanDefinitionBuilder clusterBuilder, Element clusterElement) { + //first try a reference + String envRef = clusterElement.getAttribute(CLUSTER_ENVIRONMENT_REF); + if (StringUtils.hasText(envRef)) { + clusterBuilder.addConstructorArgReference(envRef); + return true; + } + + //secondly try to see if an env has been described inline + Element envElement = DomUtils.getChildElementByTagName(clusterElement, CLUSTER_ENVIRONMENT_TAG); + if (envElement == null || !envElement.hasAttributes()) { + return false; + } + + BeanDefinitionBuilder envDefinitionBuilder = BeanDefinitionBuilder + .genericBeanDefinition(CouchbaseEnvironmentFactoryBean.class); + new CouchbaseEnvironmentParser().doParse(envElement, envDefinitionBuilder); + + clusterBuilder.addConstructorArgValue(envDefinitionBuilder.getBeanDefinition()); + return true; + } +} diff --git a/src/main/java/org/springframework/data/couchbase/config/CouchbaseEnvironmentFactoryBean.java b/src/main/java/org/springframework/data/couchbase/config/CouchbaseEnvironmentFactoryBean.java new file mode 100644 index 00000000..c5a57f56 --- /dev/null +++ b/src/main/java/org/springframework/data/couchbase/config/CouchbaseEnvironmentFactoryBean.java @@ -0,0 +1,254 @@ +/* + * 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.couchbase.config; + +import com.couchbase.client.core.retry.BestEffortRetryStrategy; +import com.couchbase.client.core.retry.FailFastRetryStrategy; +import com.couchbase.client.core.retry.RetryStrategy; +import com.couchbase.client.java.env.CouchbaseEnvironment; +import com.couchbase.client.java.env.DefaultCouchbaseEnvironment; + +import org.springframework.beans.factory.config.AbstractFactoryBean; + +/*package*/ class CouchbaseEnvironmentFactoryBean extends AbstractFactoryBean { + + private static final CouchbaseEnvironment DEFAULT_ENV = DefaultCouchbaseEnvironment.create(); + public static final String RETRYSTRATEGY_FAILFAST = "FailFast"; + public static final String RETRYSTRATEGY_BESTEFFORT = "BestEffort"; + + private long managementTimeout = DEFAULT_ENV.managementTimeout(); + private long queryTimeout = DEFAULT_ENV.queryTimeout(); + private long viewTimeout = DEFAULT_ENV.viewTimeout(); + private long kvTimeout = DEFAULT_ENV.kvTimeout(); + private long connectTimeout = DEFAULT_ENV.connectTimeout(); + private long disconnectTimeout = DEFAULT_ENV.disconnectTimeout(); + private boolean dnsSrvEnabled = DEFAULT_ENV.dnsSrvEnabled(); + + private boolean dcpEnabled = DEFAULT_ENV.dcpEnabled(); + private boolean sslEnabled = DEFAULT_ENV.sslEnabled(); + private String sslKeystoreFile = DEFAULT_ENV.sslKeystoreFile(); + private String sslKeystorePassword = DEFAULT_ENV.sslKeystorePassword(); + private boolean queryEnabled = DEFAULT_ENV.queryEnabled(); + private int queryPort = DEFAULT_ENV.queryPort(); + private boolean bootstrapHttpEnabled = DEFAULT_ENV.bootstrapHttpEnabled(); + private boolean bootstrapCarrierEnabled = DEFAULT_ENV.bootstrapCarrierEnabled(); + private int bootstrapHttpDirectPort = DEFAULT_ENV.bootstrapHttpDirectPort(); + private int bootstrapHttpSslPort = DEFAULT_ENV.bootstrapHttpSslPort(); + private int bootstrapCarrierDirectPort = DEFAULT_ENV.bootstrapCarrierDirectPort(); + private int bootstrapCarrierSslPort = DEFAULT_ENV.bootstrapCarrierSslPort(); + private int ioPoolSize = DEFAULT_ENV.ioPoolSize(); + private int computationPoolSize = DEFAULT_ENV.computationPoolSize(); + private int responseBufferSize = DEFAULT_ENV.responseBufferSize(); + private int requestBufferSize = DEFAULT_ENV.requestBufferSize(); + private int kvEndpoints = DEFAULT_ENV.kvEndpoints(); + private int viewEndpoints = DEFAULT_ENV.viewEndpoints(); + private int queryEndpoints = DEFAULT_ENV.queryEndpoints(); + private RetryStrategy retryStrategy = DEFAULT_ENV.retryStrategy(); + private long maxRequestLifetime = DEFAULT_ENV.maxRequestLifetime(); + private long keepAliveInterval = DEFAULT_ENV.keepAliveInterval(); + private long autoreleaseAfter = DEFAULT_ENV.autoreleaseAfter(); + private boolean bufferPoolingEnabled = DEFAULT_ENV.bufferPoolingEnabled(); + + //These are tunings that are not practical to be exposed in a xml configuration + //or not supposed to be modified that easily: +// observeIntervalDelay +// reconnectDelay +// retryDelay +// userAgent +// packageNameAndVersion +// ioPool +// scheduler +// eventBus + + @Override + public Class getObjectType() { + return DefaultCouchbaseEnvironment.class; + } + + @Override + protected CouchbaseEnvironment createInstance() throws Exception { + return DefaultCouchbaseEnvironment.builder() + .managementTimeout(managementTimeout) + .queryTimeout(queryTimeout) + .viewTimeout(viewTimeout) + .kvTimeout(kvTimeout) + .connectTimeout(connectTimeout) + .disconnectTimeout(disconnectTimeout) + .dnsSrvEnabled(dnsSrvEnabled) + .dcpEnabled(dcpEnabled) + .sslEnabled(sslEnabled) + .sslKeystoreFile(sslKeystoreFile) + .sslKeystorePassword(sslKeystorePassword) + .queryEnabled(queryEnabled) + .queryPort(queryPort) + .bootstrapHttpEnabled(bootstrapHttpEnabled) + .bootstrapCarrierEnabled(bootstrapCarrierEnabled) + .bootstrapHttpDirectPort(bootstrapHttpDirectPort) + .bootstrapHttpSslPort(bootstrapHttpSslPort) + .bootstrapCarrierDirectPort(bootstrapCarrierDirectPort) + .bootstrapCarrierSslPort(bootstrapCarrierSslPort) + .ioPoolSize(ioPoolSize) + .computationPoolSize(computationPoolSize) + .responseBufferSize(responseBufferSize) + .requestBufferSize(requestBufferSize) + .kvEndpoints(kvEndpoints) + .viewEndpoints(viewEndpoints) + .queryEndpoints(queryEndpoints) + .retryStrategy(retryStrategy) + .maxRequestLifetime(maxRequestLifetime) + .keepAliveInterval(keepAliveInterval) + .autoreleaseAfter(autoreleaseAfter) + .bufferPoolingEnabled(bufferPoolingEnabled) + .build(); + } + + /** + * Sets the {@link RetryStrategy} to use from an enum-like String value. + * Either "FailFast" or "BestEffort" are recognized. + * + * @param retryStrategy the string value enum from which to choose a strategy. + */ + public void setRetryStrategy(String retryStrategy) { + if (RETRYSTRATEGY_FAILFAST.equals(retryStrategy)){ + this.retryStrategy = FailFastRetryStrategy.INSTANCE; + } else if (RETRYSTRATEGY_BESTEFFORT.equals(retryStrategy)) { + this.retryStrategy = BestEffortRetryStrategy.INSTANCE; + } + } + + //==== SETTERS for the factory bean ==== + + public void setManagementTimeout(long managementTimeout) { + this.managementTimeout = managementTimeout; + } + + public void setQueryTimeout(long queryTimeout) { + this.queryTimeout = queryTimeout; + } + + public void setViewTimeout(long viewTimeout) { + this.viewTimeout = viewTimeout; + } + + public void setKvTimeout(long kvTimeout) { + this.kvTimeout = kvTimeout; + } + + public void setConnectTimeout(long connectTimeout) { + this.connectTimeout = connectTimeout; + } + + public void setDisconnectTimeout(long disconnectTimeout) { + this.disconnectTimeout = disconnectTimeout; + } + + public void setDnsSrvEnabled(boolean dnsSrvEnabled) { + this.dnsSrvEnabled = dnsSrvEnabled; + } + + public void setDcpEnabled(boolean dcpEnabled) { + this.dcpEnabled = dcpEnabled; + } + + public void setSslEnabled(boolean sslEnabled) { + this.sslEnabled = sslEnabled; + } + + public void setSslKeystoreFile(String sslKeystoreFile) { + this.sslKeystoreFile = sslKeystoreFile; + } + + public void setSslKeystorePassword(String sslKeystorePassword) { + this.sslKeystorePassword = sslKeystorePassword; + } + + public void setQueryEnabled(boolean queryEnabled) { + this.queryEnabled = queryEnabled; + } + + public void setQueryPort(int queryPort) { + this.queryPort = queryPort; + } + + public void setBootstrapHttpEnabled(boolean bootstrapHttpEnabled) { + this.bootstrapHttpEnabled = bootstrapHttpEnabled; + } + + public void setBootstrapCarrierEnabled(boolean bootstrapCarrierEnabled) { + this.bootstrapCarrierEnabled = bootstrapCarrierEnabled; + } + + public void setBootstrapHttpDirectPort(int bootstrapHttpDirectPort) { + this.bootstrapHttpDirectPort = bootstrapHttpDirectPort; + } + + public void setBootstrapHttpSslPort(int bootstrapHttpSslPort) { + this.bootstrapHttpSslPort = bootstrapHttpSslPort; + } + + public void setBootstrapCarrierDirectPort(int bootstrapCarrierDirectPort) { + this.bootstrapCarrierDirectPort = bootstrapCarrierDirectPort; + } + + public void setBootstrapCarrierSslPort(int bootstrapCarrierSslPort) { + this.bootstrapCarrierSslPort = bootstrapCarrierSslPort; + } + + public void setIoPoolSize(int ioPoolSize) { + this.ioPoolSize = ioPoolSize; + } + + public void setComputationPoolSize(int computationPoolSize) { + this.computationPoolSize = computationPoolSize; + } + + public void setResponseBufferSize(int responseBufferSize) { + this.responseBufferSize = responseBufferSize; + } + + public void setRequestBufferSize(int requestBufferSize) { + this.requestBufferSize = requestBufferSize; + } + + public void setKvEndpoints(int kvEndpoints) { + this.kvEndpoints = kvEndpoints; + } + + public void setViewEndpoints(int viewEndpoints) { + this.viewEndpoints = viewEndpoints; + } + + public void setQueryEndpoints(int queryEndpoints) { + this.queryEndpoints = queryEndpoints; + } + + public void setMaxRequestLifetime(long maxRequestLifetime) { + this.maxRequestLifetime = maxRequestLifetime; + } + + public void setKeepAliveInterval(long keepAliveInterval) { + this.keepAliveInterval = keepAliveInterval; + } + + public void setAutoreleaseAfter(long autoreleaseAfter) { + this.autoreleaseAfter = autoreleaseAfter; + } + + public void setBufferPoolingEnabled(boolean bufferPoolingEnabled) { + this.bufferPoolingEnabled = bufferPoolingEnabled; + } +} diff --git a/src/main/java/org/springframework/data/couchbase/config/CouchbaseEnvironmentParser.java b/src/main/java/org/springframework/data/couchbase/config/CouchbaseEnvironmentParser.java new file mode 100644 index 00000000..a6c0f503 --- /dev/null +++ b/src/main/java/org/springframework/data/couchbase/config/CouchbaseEnvironmentParser.java @@ -0,0 +1,139 @@ +/* + * 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.couchbase.config; + +import static org.springframework.data.config.ParsingUtils.setPropertyValue; + +import com.couchbase.client.core.retry.RetryStrategy; +import com.couchbase.client.java.env.DefaultCouchbaseEnvironment; +import org.w3c.dom.Element; + +import org.springframework.beans.factory.support.AbstractBeanDefinition; +import org.springframework.beans.factory.support.BeanDefinitionBuilder; +import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser; +import org.springframework.beans.factory.xml.ParserContext; +import org.springframework.util.StringUtils; + +/** + * Allows creation of a {@link DefaultCouchbaseEnvironment} via spring XML configuration. + *

+ * The following properties are supported:

    + *
  • {@link DefaultCouchbaseEnvironment.Builder#managementTimeout(long) managementTimeout}
  • + *
  • {@link DefaultCouchbaseEnvironment.Builder#queryTimeout(long) queryTimeout}
  • + *
  • {@link DefaultCouchbaseEnvironment.Builder#viewTimeout(long) viewTimeout}
  • + *
  • {@link DefaultCouchbaseEnvironment.Builder#kvTimeout(long) kvTimeout}
  • + *
  • {@link DefaultCouchbaseEnvironment.Builder#connectTimeout(long) connectTimeout}
  • + *
  • {@link DefaultCouchbaseEnvironment.Builder#disconnectTimeout(long) disconnectTimeout}
  • + *
  • {@link DefaultCouchbaseEnvironment.Builder#dnsSrvEnabled(boolean) dnsSrvEnabled}
  • + * + *
  • {@link DefaultCouchbaseEnvironment.Builder#dcpEnabled(boolean) dcpEnabled}
  • + *
  • {@link DefaultCouchbaseEnvironment.Builder#sslEnabled(boolean) sslEnabled}
  • + *
  • {@link DefaultCouchbaseEnvironment.Builder#sslKeystoreFile(String) sslKeystoreFile}
  • + *
  • {@link DefaultCouchbaseEnvironment.Builder#sslKeystorePassword(String) sslKeystorePassword}
  • + *
  • {@link DefaultCouchbaseEnvironment.Builder#queryEnabled(boolean) queryEnabled}
  • + *
  • {@link DefaultCouchbaseEnvironment.Builder#queryPort(int) queryPort}
  • + *
  • {@link DefaultCouchbaseEnvironment.Builder#bootstrapHttpEnabled(boolean) bootstrapHttpEnabled}
  • + *
  • {@link DefaultCouchbaseEnvironment.Builder#bootstrapCarrierEnabled(boolean) bootstrapCarrierEnabled}
  • + *
  • {@link DefaultCouchbaseEnvironment.Builder#bootstrapHttpDirectPort(int) bootstrapHttpDirectPort}
  • + *
  • {@link DefaultCouchbaseEnvironment.Builder#bootstrapHttpSslPort(int) bootstrapHttpSslPort}
  • + *
  • {@link DefaultCouchbaseEnvironment.Builder#bootstrapCarrierDirectPort(int) bootstrapCarrierDirectPort}
  • + *
  • {@link DefaultCouchbaseEnvironment.Builder#bootstrapCarrierSslPort(int) bootstrapCarrierSslPort}
  • + *
  • {@link DefaultCouchbaseEnvironment.Builder#ioPoolSize(int) ioPoolSize}
  • + *
  • {@link DefaultCouchbaseEnvironment.Builder#computationPoolSize(int) computationPoolSize}
  • + *
  • {@link DefaultCouchbaseEnvironment.Builder#responseBufferSize(int) responseBufferSize}
  • + *
  • {@link DefaultCouchbaseEnvironment.Builder#requestBufferSize(int) requestBufferSize}
  • + *
  • {@link DefaultCouchbaseEnvironment.Builder#kvEndpoints(int) kvEndpoints}
  • + *
  • {@link DefaultCouchbaseEnvironment.Builder#viewEndpoints(int) viewEndpoints}
  • + *
  • {@link DefaultCouchbaseEnvironment.Builder#queryEndpoints(int) queryEndpoints}
  • + *
  • {@link DefaultCouchbaseEnvironment.Builder#retryStrategy(RetryStrategy) retryStrategy}
  • + *
  • {@link DefaultCouchbaseEnvironment.Builder#maxRequestLifetime(long) maxRequestLifetime}
  • + *
  • {@link DefaultCouchbaseEnvironment.Builder#keepAliveInterval(long) keepAliveInterval}
  • + *
  • {@link DefaultCouchbaseEnvironment.Builder#autoreleaseAfter(long) autoreleaseAfter}
  • + *
  • {@link DefaultCouchbaseEnvironment.Builder#bufferPoolingEnabled(boolean) bufferPoolingEnabled}
  • + *
+ */ +public class CouchbaseEnvironmentParser extends AbstractSingleBeanDefinitionParser { + + /** + * Resolve the bean ID and assign a default if not set. + * + * @param element the XML element which contains the attributes. + * @param definition the bean definition to work with. + * @param parserContext encapsulates the parsing state and configuration. + * @return the ID to work with. + */ + @Override + protected String resolveId(final Element element, final AbstractBeanDefinition definition, final ParserContext parserContext) { + String id = super.resolveId(element, definition, parserContext); + return StringUtils.hasText(id) ? id : BeanNames.COUCHBASE_ENV; + } + + /** + * Defines the bean class that will be constructed. + * + * @param element the XML element which contains the attributes. + * @return the class type to instantiate. + */ + @Override + protected Class getBeanClass(final Element element) { + return CouchbaseEnvironmentFactoryBean.class; + } + + /** + * Parse the bean definition and build up the bean. + * + * @param envElement the XML element which contains the attributes. + * @param envDefinitionBuilder the builder which builds the bean. + */ + @Override + protected void doParse(final Element envElement, final BeanDefinitionBuilder envDefinitionBuilder) { + setPropertyValue(envDefinitionBuilder, envElement, "managementTimeout", "managementTimeout"); + setPropertyValue(envDefinitionBuilder, envElement, "queryTimeout", "queryTimeout"); + setPropertyValue(envDefinitionBuilder, envElement, "viewTimeout", "viewTimeout"); + setPropertyValue(envDefinitionBuilder, envElement, "kvTimeout", "kvTimeout"); + setPropertyValue(envDefinitionBuilder, envElement, "connectTimeout", "connectTimeout"); + setPropertyValue(envDefinitionBuilder, envElement, "disconnectTimeout", "disconnectTimeout"); + setPropertyValue(envDefinitionBuilder, envElement, "dnsSrvEnabled", "dnsSrvEnabled"); + + setPropertyValue(envDefinitionBuilder, envElement, "dcpEnabled", "dcpEnabled"); + setPropertyValue(envDefinitionBuilder, envElement, "sslEnabled", "sslEnabled"); + setPropertyValue(envDefinitionBuilder, envElement, "sslKeystoreFile", "sslKeystoreFile"); + setPropertyValue(envDefinitionBuilder, envElement, "sslKeystorePassword", "sslKeystorePassword"); + setPropertyValue(envDefinitionBuilder, envElement, "queryEnabled", "queryEnabled"); + setPropertyValue(envDefinitionBuilder, envElement, "queryPort", "queryPort"); + setPropertyValue(envDefinitionBuilder, envElement, "bootstrapHttpEnabled", "bootstrapHttpEnabled"); + setPropertyValue(envDefinitionBuilder, envElement, "bootstrapCarrierEnabled", "bootstrapCarrierEnabled"); + setPropertyValue(envDefinitionBuilder, envElement, "bootstrapHttpDirectPort", "bootstrapHttpDirectPort"); + setPropertyValue(envDefinitionBuilder, envElement, "bootstrapHttpSslPort", "bootstrapHttpSslPort"); + setPropertyValue(envDefinitionBuilder, envElement, "bootstrapCarrierDirectPort", "bootstrapCarrierDirectPort"); + setPropertyValue(envDefinitionBuilder, envElement, "bootstrapCarrierSslPort", "bootstrapCarrierSslPort"); + setPropertyValue(envDefinitionBuilder, envElement, "ioPoolSize", "ioPoolSize"); + setPropertyValue(envDefinitionBuilder, envElement, "computationPoolSize", "computationPoolSize"); + setPropertyValue(envDefinitionBuilder, envElement, "responseBufferSize", "responseBufferSize"); + setPropertyValue(envDefinitionBuilder, envElement, "requestBufferSize", "requestBufferSize"); + setPropertyValue(envDefinitionBuilder, envElement, "kvEndpoints", "kvEndpoints"); + setPropertyValue(envDefinitionBuilder, envElement, "viewEndpoints", "viewEndpoints"); + setPropertyValue(envDefinitionBuilder, envElement, "queryEndpoints", "queryEndpoints"); + setPropertyValue(envDefinitionBuilder, envElement, "maxRequestLifetime", "maxRequestLifetime"); + setPropertyValue(envDefinitionBuilder, envElement, "keepAliveInterval", "keepAliveInterval"); + setPropertyValue(envDefinitionBuilder, envElement, "autoreleaseAfter", "autoreleaseAfter"); + setPropertyValue(envDefinitionBuilder, envElement, "bufferPoolingEnabled", "bufferPoolingEnabled"); + + //retry strategy is particular, in the xsd this is an enum (FailFast, BestEffort) + setPropertyValue(envDefinitionBuilder, envElement, "retryStrategy", "retryStrategy"); + } +} diff --git a/src/main/java/org/springframework/data/couchbase/config/CouchbaseNamespaceHandler.java b/src/main/java/org/springframework/data/couchbase/config/CouchbaseNamespaceHandler.java index 6e4d50d6..5402d5bb 100644 --- a/src/main/java/org/springframework/data/couchbase/config/CouchbaseNamespaceHandler.java +++ b/src/main/java/org/springframework/data/couchbase/config/CouchbaseNamespaceHandler.java @@ -36,6 +36,7 @@ public class CouchbaseNamespaceHandler extends NamespaceHandlerSupport { //TODO repositories (CouchbaseRepositoryConfigurationExtension and RepositoryBeanDefinitionParser) //TODO bucket //TODO cluster + registerBeanDefinitionParser("env", new CouchbaseEnvironmentParser()); registerBeanDefinitionParser("jmx", new CouchbaseJmxParser()); registerBeanDefinitionParser("template", new CouchbaseTemplateParser()); //TODO translation service diff --git a/src/test/java/org/springframework/data/couchbase/config/CouchbaseEnvironmentParserTest.java b/src/test/java/org/springframework/data/couchbase/config/CouchbaseEnvironmentParserTest.java new file mode 100644 index 00000000..ad0766f2 --- /dev/null +++ b/src/test/java/org/springframework/data/couchbase/config/CouchbaseEnvironmentParserTest.java @@ -0,0 +1,109 @@ +/* + * 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.couchbase.config; + +import static org.hamcrest.CoreMatchers.*; +import static org.junit.Assert.assertThat; + +import com.couchbase.client.core.retry.BestEffortRetryStrategy; +import com.couchbase.client.core.retry.FailFastRetryStrategy; +import com.couchbase.client.java.env.CouchbaseEnvironment; +import com.couchbase.client.java.env.DefaultCouchbaseEnvironment; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; + +import org.springframework.beans.factory.support.BeanDefinitionReader; +import org.springframework.beans.factory.support.DefaultListableBeanFactory; +import org.springframework.beans.factory.xml.XmlBeanDefinitionReader; +import org.springframework.context.support.GenericApplicationContext; +import org.springframework.core.io.ClassPathResource; + +public class CouchbaseEnvironmentParserTest { + + private static GenericApplicationContext context; + + @BeforeClass + public static void setUp() { + DefaultListableBeanFactory factory = new DefaultListableBeanFactory(); + BeanDefinitionReader reader = new XmlBeanDefinitionReader(factory); + reader.loadBeanDefinitions(new ClassPathResource("configurations/couchbaseEnv-bean.xml")); + context = new GenericApplicationContext(factory); + context.refresh(); + } + + @Test + public void testParsingRetryStrategyFailFast() throws Exception { + CouchbaseEnvironment env = context.getBean("envWithFailFast", CouchbaseEnvironment.class); + + assertThat(env.retryStrategy(), is(instanceOf(FailFastRetryStrategy.class))); + } + + @Test + public void testParsingRetryStrategyBestEffort() throws Exception { + CouchbaseEnvironment env = context.getBean("envWithBestEffort", CouchbaseEnvironment.class); + + assertThat(env.retryStrategy(), is(instanceOf(BestEffortRetryStrategy.class))); + } + + @Test + public void testAllDefaultsOverridden() { + CouchbaseEnvironment env = context.getBean("envWithNoDefault", CouchbaseEnvironment.class); + CouchbaseEnvironment defaultEnv = DefaultCouchbaseEnvironment.create(); + + assertThat(env, is(instanceOf(DefaultCouchbaseEnvironment.class))); + + assertThat(env.managementTimeout(), is(equalTo(1L))); + assertThat(env.queryTimeout(), is(equalTo(2L))); + assertThat(env.viewTimeout(), is(equalTo(3L))); + assertThat(env.kvTimeout(), is(equalTo(4L))); + assertThat(env.connectTimeout(), is(equalTo(5L))); + assertThat(env.disconnectTimeout(), is(equalTo(6L))); + assertThat(env.dnsSrvEnabled(), allOf(equalTo(true), not(defaultEnv.dnsSrvEnabled()))); + + //TODO activate test when dcp can be enabled on the environment (add it in the xml) +// assertThat(env.dcpEnabled(), allOf(equalTo(true), not(defaultEnv.dcpEnabled()))); + assertThat(env.sslEnabled(), allOf(equalTo(true), not(defaultEnv.sslEnabled()))); + assertThat(env.sslKeystoreFile(), is(equalTo("test"))); + assertThat(env.sslKeystorePassword(), is(equalTo("test"))); + assertThat(env.queryEnabled(), allOf(equalTo(true), not(defaultEnv.queryEnabled()))); + assertThat(env.queryPort(), is(equalTo(7))); + assertThat(env.bootstrapHttpEnabled(), allOf(equalTo(false), not(defaultEnv.bootstrapHttpEnabled()))); + assertThat(env.bootstrapCarrierEnabled(), allOf(equalTo(false), not(defaultEnv.bootstrapCarrierEnabled()))); + assertThat(env.bootstrapHttpDirectPort(), is(equalTo(8))); + assertThat(env.bootstrapHttpSslPort(), is(equalTo(9))); + assertThat(env.bootstrapCarrierDirectPort(), is(equalTo(10))); + assertThat(env.bootstrapCarrierSslPort(), is(equalTo(11))); + assertThat(env.ioPoolSize(), is(equalTo(12))); + assertThat(env.computationPoolSize(), is(equalTo(13))); + assertThat(env.responseBufferSize(), is(equalTo(14))); + assertThat(env.requestBufferSize(), is(equalTo(15))); + assertThat(env.kvEndpoints(), is(equalTo(16))); + assertThat(env.viewEndpoints(), is(equalTo(17))); + assertThat(env.queryEndpoints(), is(equalTo(18))); + assertThat(env.retryStrategy(), is(instanceOf(FailFastRetryStrategy.class))); + assertThat(env.maxRequestLifetime(), is(equalTo(19L))); + assertThat(env.keepAliveInterval(), is(equalTo(20L))); + assertThat(env.autoreleaseAfter(), is(equalTo(21L))); + assertThat(env.bufferPoolingEnabled(), allOf(equalTo(false), not(defaultEnv.bufferPoolingEnabled()))); + } + + @AfterClass + public static void tearDown() { + context.close(); + } +} \ No newline at end of file diff --git a/src/test/resources/configurations/couchbaseEnv-bean.xml b/src/test/resources/configurations/couchbaseEnv-bean.xml new file mode 100644 index 00000000..07fedf93 --- /dev/null +++ b/src/test/resources/configurations/couchbaseEnv-bean.xml @@ -0,0 +1,48 @@ + + + + + + + + + + \ No newline at end of file