Skip to content

Commit d233e56

Browse files
DATAMONGO-1158 - Add explicit config options for MongoClient.
We added an explicit mongo-client element and client-options to the configuration schema. These elements will replace existing mongo and options elements in a subsequent release.
1 parent 9f43d20 commit d233e56

File tree

13 files changed

+1815
-24
lines changed

13 files changed

+1815
-24
lines changed
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
/*
2+
* Copyright 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.mongodb.config;
17+
18+
import org.springframework.beans.factory.config.BeanDefinition;
19+
import org.springframework.beans.factory.parsing.BeanComponentDefinition;
20+
import org.springframework.beans.factory.parsing.CompositeComponentDefinition;
21+
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
22+
import org.springframework.beans.factory.xml.BeanDefinitionParser;
23+
import org.springframework.beans.factory.xml.ParserContext;
24+
import org.springframework.data.config.BeanComponentDefinitionBuilder;
25+
import org.springframework.data.config.ParsingUtils;
26+
import org.springframework.data.mongodb.core.MongoClientFactoryBean;
27+
import org.springframework.util.StringUtils;
28+
import org.w3c.dom.Element;
29+
30+
/**
31+
* Parser for {@code mongo-client} definitions.
32+
*
33+
* @author Christoph Strobl
34+
* @since 1.7
35+
*/
36+
public class MongoClientParser implements BeanDefinitionParser {
37+
38+
/*
39+
* (non-Javadoc)
40+
* @see org.springframework.beans.factory.xml.BeanDefinitionParser#parse(org.w3c.dom.Element, org.springframework.beans.factory.xml.ParserContext)
41+
*/
42+
public BeanDefinition parse(Element element, ParserContext parserContext) {
43+
44+
Object source = parserContext.extractSource(element);
45+
String id = element.getAttribute("id");
46+
47+
BeanComponentDefinitionBuilder helper = new BeanComponentDefinitionBuilder(element, parserContext);
48+
49+
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(MongoClientFactoryBean.class);
50+
51+
ParsingUtils.setPropertyValue(builder, element, "port", "port");
52+
ParsingUtils.setPropertyValue(builder, element, "host", "host");
53+
54+
MongoParsingUtils.parseMongoClientOptions(element, builder);
55+
MongoParsingUtils.parseReplicaSet(element, builder);
56+
57+
String defaultedId = StringUtils.hasText(id) ? id : BeanNames.MONGO_BEAN_NAME;
58+
59+
parserContext.pushContainingComponent(new CompositeComponentDefinition("Mongo", source));
60+
61+
BeanComponentDefinition mongoComponent = helper.getComponent(builder, defaultedId);
62+
parserContext.registerBeanComponent(mongoComponent);
63+
64+
BeanComponentDefinition serverAddressPropertyEditor = helper.getComponent(MongoParsingUtils
65+
.getServerAddressPropertyEditorBuilder());
66+
parserContext.registerBeanComponent(serverAddressPropertyEditor);
67+
68+
BeanComponentDefinition writeConcernEditor = helper.getComponent(MongoParsingUtils
69+
.getWriteConcernPropertyEditorBuilder());
70+
parserContext.registerBeanComponent(writeConcernEditor);
71+
72+
BeanComponentDefinition readPreferenceEditor = helper.getComponent(MongoParsingUtils
73+
.getReadPreferencePropertyEditorBuilder());
74+
parserContext.registerBeanComponent(readPreferenceEditor);
75+
76+
parserContext.popAndRegisterContainingComponent();
77+
78+
return mongoComponent.getBeanDefinition();
79+
}
80+
81+
}

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoNamespaceHandler.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2011-2014 the original author or authors.
2+
* Copyright 2011-2015 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -22,6 +22,7 @@
2222
*
2323
* @author Oliver Gierke
2424
* @author Martin Baumgartner
25+
* @author Christoph Strobl
2526
*/
2627
public class MongoNamespaceHandler extends NamespaceHandlerSupport {
2728

@@ -33,6 +34,7 @@ public void init() {
3334

3435
registerBeanDefinitionParser("mapping-converter", new MappingMongoConverterParser());
3536
registerBeanDefinitionParser("mongo", new MongoParser());
37+
registerBeanDefinitionParser("mongo-client", new MongoClientParser());
3638
registerBeanDefinitionParser("db-factory", new MongoDbFactoryParser());
3739
registerBeanDefinitionParser("jmx", new MongoJmxParser());
3840
registerBeanDefinitionParser("auditing", new MongoAuditingBeanDefinitionParser());

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoParser.java

Lines changed: 4 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2011-2014 the original author or authors.
2+
* Copyright 2011-2015 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -15,14 +15,10 @@
1515
*/
1616
package org.springframework.data.mongodb.config;
1717

18-
import java.util.Map;
19-
2018
import org.springframework.beans.factory.config.BeanDefinition;
21-
import org.springframework.beans.factory.config.CustomEditorConfigurer;
2219
import org.springframework.beans.factory.parsing.BeanComponentDefinition;
2320
import org.springframework.beans.factory.parsing.CompositeComponentDefinition;
2421
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
25-
import org.springframework.beans.factory.support.ManagedMap;
2622
import org.springframework.beans.factory.xml.BeanDefinitionParser;
2723
import org.springframework.beans.factory.xml.ParserContext;
2824
import org.springframework.data.config.BeanComponentDefinitionBuilder;
@@ -36,6 +32,7 @@
3632
*
3733
* @author Mark Pollack
3834
* @author Oliver Gierke
35+
* @author Christoph Strobl
3936
*/
4037
public class MongoParser implements BeanDefinitionParser {
4138

@@ -64,7 +61,8 @@ public BeanDefinition parse(Element element, ParserContext parserContext) {
6461

6562
BeanComponentDefinition mongoComponent = helper.getComponent(builder, defaultedId);
6663
parserContext.registerBeanComponent(mongoComponent);
67-
BeanComponentDefinition serverAddressPropertyEditor = helper.getComponent(registerServerAddressPropertyEditor());
64+
BeanComponentDefinition serverAddressPropertyEditor = helper.getComponent(MongoParsingUtils
65+
.getServerAddressPropertyEditorBuilder());
6866
parserContext.registerBeanComponent(serverAddressPropertyEditor);
6967
BeanComponentDefinition writeConcernPropertyEditor = helper.getComponent(MongoParsingUtils
7068
.getWriteConcernPropertyEditorBuilder());
@@ -75,19 +73,4 @@ public BeanDefinition parse(Element element, ParserContext parserContext) {
7573
return mongoComponent.getBeanDefinition();
7674
}
7775

78-
/**
79-
* One should only register one bean definition but want to have the convenience of using
80-
* AbstractSingleBeanDefinitionParser but have the side effect of registering a 'default' property editor with the
81-
* container.
82-
*/
83-
private BeanDefinitionBuilder registerServerAddressPropertyEditor() {
84-
85-
Map<String, String> customEditors = new ManagedMap<String, String>();
86-
customEditors.put("com.mongodb.ServerAddress[]",
87-
"org.springframework.data.mongodb.config.ServerAddressPropertyEditor");
88-
89-
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(CustomEditorConfigurer.class);
90-
builder.addPropertyValue("customEditors", customEditors);
91-
return builder;
92-
}
9376
}

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoParsingUtils.java

Lines changed: 78 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2011-2013 the original author or authors.
2+
* Copyright 2011-2015 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -24,6 +24,7 @@
2424
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
2525
import org.springframework.beans.factory.support.ManagedMap;
2626
import org.springframework.beans.factory.xml.BeanDefinitionParser;
27+
import org.springframework.data.mongodb.core.MongoClientOptionsFactoryBean;
2728
import org.springframework.data.mongodb.core.MongoOptionsFactoryBean;
2829
import org.springframework.util.xml.DomUtils;
2930
import org.w3c.dom.Element;
@@ -34,6 +35,7 @@
3435
* @author Mark Pollack
3536
* @author Oliver Gierke
3637
* @author Thomas Darimont
38+
* @author Christoph Strobl
3739
*/
3840
abstract class MongoParsingUtils {
3941

@@ -87,6 +89,47 @@ static boolean parseMongoOptions(Element element, BeanDefinitionBuilder mongoBui
8789
return true;
8890
}
8991

92+
/**
93+
* @param element
94+
* @param mongoClientBuilder
95+
* @return
96+
* @since 1.7
97+
*/
98+
public static boolean parseMongoClientOptions(Element element, BeanDefinitionBuilder mongoClientBuilder) {
99+
100+
Element optionsElement = DomUtils.getChildElementByTagName(element, "client-options");
101+
if (optionsElement == null) {
102+
return false;
103+
}
104+
105+
BeanDefinitionBuilder clientOptionsDefBuilder = BeanDefinitionBuilder
106+
.genericBeanDefinition(MongoClientOptionsFactoryBean.class);
107+
108+
setPropertyValue(clientOptionsDefBuilder, optionsElement, "description", "description");
109+
setPropertyValue(clientOptionsDefBuilder, optionsElement, "min-connections-per-host", "minConnectionsPerHost");
110+
setPropertyValue(clientOptionsDefBuilder, optionsElement, "connections-per-host", "connectionsPerHost");
111+
setPropertyValue(clientOptionsDefBuilder, optionsElement, "threads-allowed-to-block-for-connection-multiplier",
112+
"threadsAllowedToBlockForConnectionMultiplier");
113+
setPropertyValue(clientOptionsDefBuilder, optionsElement, "max-wait-time", "maxWaitTime");
114+
setPropertyValue(clientOptionsDefBuilder, optionsElement, "max-connection-idle-time", "maxConnectionIdleTime");
115+
setPropertyValue(clientOptionsDefBuilder, optionsElement, "max-connection-life-time", "maxConnectionLifeTime");
116+
setPropertyValue(clientOptionsDefBuilder, optionsElement, "connect-timeout", "connectTimeout");
117+
setPropertyValue(clientOptionsDefBuilder, optionsElement, "socket-timeout", "socketTimeout");
118+
setPropertyValue(clientOptionsDefBuilder, optionsElement, "socket-keep-alive", "socketKeepAlive");
119+
setPropertyValue(clientOptionsDefBuilder, optionsElement, "read-preference", "readPreference");
120+
setPropertyValue(clientOptionsDefBuilder, optionsElement, "write-concern", "writeConcern");
121+
setPropertyValue(clientOptionsDefBuilder, optionsElement, "heartbeat-frequency", "heartbeatFrequency");
122+
setPropertyValue(clientOptionsDefBuilder, optionsElement, "min-heartbeat-frequency", "minHeartbeatFrequency");
123+
setPropertyValue(clientOptionsDefBuilder, optionsElement, "heartbeat-connect-timeout", "heartbeatConnectTimeout");
124+
setPropertyValue(clientOptionsDefBuilder, optionsElement, "heartbeat-socket-timeout", "heartbeatSocketTimeout");
125+
setPropertyValue(clientOptionsDefBuilder, optionsElement, "ssl", "ssl");
126+
setPropertyReference(clientOptionsDefBuilder, optionsElement, "ssl-socket-factory-ref", "sslSocketFactory");
127+
128+
mongoClientBuilder.addPropertyValue("mongoClientOptions", clientOptionsDefBuilder.getBeanDefinition());
129+
130+
return true;
131+
}
132+
90133
/**
91134
* Returns the {@link BeanDefinitionBuilder} to build a {@link BeanDefinition} for a
92135
* {@link WriteConcernPropertyEditor}.
@@ -103,4 +146,38 @@ static BeanDefinitionBuilder getWriteConcernPropertyEditorBuilder() {
103146

104147
return builder;
105148
}
149+
150+
/**
151+
* Returns the {@link BeanDefinitionBuilder} to build a {@link BeanDefinition} for a
152+
* {@link ReadPreferencePropertyEditor}.
153+
*
154+
* @return
155+
* @since 1.7
156+
*/
157+
static BeanDefinitionBuilder getReadPreferencePropertyEditorBuilder() {
158+
159+
Map<String, Class<?>> customEditors = new ManagedMap<String, Class<?>>();
160+
customEditors.put("com.mongodb.ReadPreference", ReadPreferencePropertyEditor.class);
161+
162+
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(CustomEditorConfigurer.class);
163+
builder.addPropertyValue("customEditors", customEditors);
164+
165+
return builder;
166+
}
167+
168+
/**
169+
* One should only register one bean definition but want to have the convenience of using
170+
* AbstractSingleBeanDefinitionParser but have the side effect of registering a 'default' property editor with the
171+
* container.
172+
*/
173+
static BeanDefinitionBuilder getServerAddressPropertyEditorBuilder() {
174+
175+
Map<String, String> customEditors = new ManagedMap<String, String>();
176+
customEditors.put("com.mongodb.ServerAddress[]",
177+
"org.springframework.data.mongodb.config.ServerAddressPropertyEditor");
178+
179+
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(CustomEditorConfigurer.class);
180+
builder.addPropertyValue("customEditors", customEditors);
181+
return builder;
182+
}
106183
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/*
2+
* Copyright 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.mongodb.config;
17+
18+
import java.beans.PropertyEditorSupport;
19+
20+
import com.mongodb.ReadPreference;
21+
22+
/**
23+
* Parse a {@link String} to a {@link ReadPreference}.
24+
*
25+
* @author Christoph Strobl
26+
* @since 1.7
27+
*/
28+
public class ReadPreferencePropertyEditor extends PropertyEditorSupport {
29+
30+
@Override
31+
public void setAsText(String readPreferenceString) throws IllegalArgumentException {
32+
33+
if (readPreferenceString == null) {
34+
return;
35+
}
36+
37+
ReadPreference preference = null;
38+
try {
39+
preference = ReadPreference.valueOf(readPreferenceString);
40+
} catch (IllegalArgumentException ex) {
41+
// ignore this one and try to map it differently
42+
}
43+
44+
if (preference != null) {
45+
setValue(preference);
46+
} else if ("PRIMARY".equalsIgnoreCase(readPreferenceString)) {
47+
setValue(ReadPreference.primary());
48+
} else if ("PRIMARY_PREFERRED".equalsIgnoreCase(readPreferenceString)) {
49+
setValue(ReadPreference.primaryPreferred());
50+
} else if ("SECONDARY".equalsIgnoreCase(readPreferenceString)) {
51+
setValue(ReadPreference.secondary());
52+
} else if ("SECONDARY_PREFERRED".equalsIgnoreCase(readPreferenceString)) {
53+
setValue(ReadPreference.secondaryPreferred());
54+
} else if ("NEAREST".equalsIgnoreCase(readPreferenceString)) {
55+
setValue(ReadPreference.nearest());
56+
} else {
57+
throw new IllegalArgumentException(String.format("Cannot find matching ReadPreference for %s",
58+
readPreferenceString));
59+
}
60+
}
61+
}

0 commit comments

Comments
 (0)