001/* 002 * Copyright 2012-2017 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.springframework.boot.autoconfigure.mongo; 018 019import java.net.UnknownHostException; 020import java.util.ArrayList; 021import java.util.Collections; 022import java.util.List; 023 024import com.mongodb.MongoClient; 025import com.mongodb.MongoClientOptions; 026import com.mongodb.MongoClientOptions.Builder; 027import com.mongodb.MongoClientURI; 028import com.mongodb.MongoCredential; 029import com.mongodb.ServerAddress; 030 031import org.springframework.boot.context.properties.ConfigurationProperties; 032import org.springframework.core.env.Environment; 033 034/** 035 * Configuration properties for Mongo. 036 * 037 * @author Dave Syer 038 * @author Phillip Webb 039 * @author Josh Long 040 * @author Andy Wilkinson 041 * @author Eddú Meléndez 042 * @author Stephane Nicoll 043 * @author Nasko Vasilev 044 */ 045@ConfigurationProperties(prefix = "spring.data.mongodb") 046public class MongoProperties { 047 048 /** 049 * Default port used when the configured port is {@code null}. 050 */ 051 public static final int DEFAULT_PORT = 27017; 052 053 public static final String DEFAULT_URI = "mongodb://localhost/test"; 054 055 /** 056 * Mongo server host. Cannot be set with uri. 057 */ 058 private String host; 059 060 /** 061 * Mongo server port. Cannot be set with uri. 062 */ 063 private Integer port = null; 064 065 /** 066 * Mongo database URI. Cannot be set with host, port and credentials. 067 */ 068 private String uri; 069 070 /** 071 * Database name. 072 */ 073 private String database; 074 075 /** 076 * Authentication database name. 077 */ 078 private String authenticationDatabase; 079 080 /** 081 * GridFS database name. 082 */ 083 private String gridFsDatabase; 084 085 /** 086 * Login user of the mongo server. Cannot be set with uri. 087 */ 088 private String username; 089 090 /** 091 * Login password of the mongo server. Cannot be set with uri. 092 */ 093 private char[] password; 094 095 /** 096 * Fully qualified name of the FieldNamingStrategy to use. 097 */ 098 private Class<?> fieldNamingStrategy; 099 100 public String getHost() { 101 return this.host; 102 } 103 104 public void setHost(String host) { 105 this.host = host; 106 } 107 108 public String getDatabase() { 109 return this.database; 110 } 111 112 public void setDatabase(String database) { 113 this.database = database; 114 } 115 116 public String getAuthenticationDatabase() { 117 return this.authenticationDatabase; 118 } 119 120 public void setAuthenticationDatabase(String authenticationDatabase) { 121 this.authenticationDatabase = authenticationDatabase; 122 } 123 124 public String getUsername() { 125 return this.username; 126 } 127 128 public void setUsername(String username) { 129 this.username = username; 130 } 131 132 public char[] getPassword() { 133 return this.password; 134 } 135 136 public void setPassword(char[] password) { 137 this.password = password; 138 } 139 140 public Class<?> getFieldNamingStrategy() { 141 return this.fieldNamingStrategy; 142 } 143 144 public void setFieldNamingStrategy(Class<?> fieldNamingStrategy) { 145 this.fieldNamingStrategy = fieldNamingStrategy; 146 } 147 148 public void clearPassword() { 149 if (this.password == null) { 150 return; 151 } 152 for (int i = 0; i < this.password.length; i++) { 153 this.password[i] = 0; 154 } 155 } 156 157 public String getUri() { 158 return this.uri; 159 } 160 161 public String determineUri() { 162 return (this.uri != null ? this.uri : DEFAULT_URI); 163 } 164 165 public void setUri(String uri) { 166 this.uri = uri; 167 } 168 169 public Integer getPort() { 170 return this.port; 171 } 172 173 public void setPort(Integer port) { 174 this.port = port; 175 } 176 177 public String getGridFsDatabase() { 178 return this.gridFsDatabase; 179 } 180 181 public void setGridFsDatabase(String gridFsDatabase) { 182 this.gridFsDatabase = gridFsDatabase; 183 } 184 185 public String getMongoClientDatabase() { 186 if (this.database != null) { 187 return this.database; 188 } 189 return new MongoClientURI(determineUri()).getDatabase(); 190 } 191 192 /** 193 * Creates a {@link MongoClient} using the given {@code options} and 194 * {@code environment}. If the environment contains a {@code local.mongo.port} 195 * property, it is used to configure a client to an embedded MongoDB instance. 196 * @param options the options 197 * @param environment the environment 198 * @return the Mongo client 199 * @throws UnknownHostException if the configured host is unknown 200 */ 201 public MongoClient createMongoClient(MongoClientOptions options, 202 Environment environment) throws UnknownHostException { 203 try { 204 Integer embeddedPort = getEmbeddedPort(environment); 205 if (embeddedPort != null) { 206 return createEmbeddedMongoClient(options, embeddedPort); 207 } 208 return createNetworkMongoClient(options); 209 } 210 finally { 211 clearPassword(); 212 } 213 } 214 215 private Integer getEmbeddedPort(Environment environment) { 216 if (environment != null) { 217 String localPort = environment.getProperty("local.mongo.port"); 218 if (localPort != null) { 219 return Integer.valueOf(localPort); 220 } 221 } 222 return null; 223 } 224 225 private MongoClient createEmbeddedMongoClient(MongoClientOptions options, int port) { 226 if (options == null) { 227 options = MongoClientOptions.builder().build(); 228 } 229 String host = this.host == null ? "localhost" : this.host; 230 return new MongoClient(Collections.singletonList(new ServerAddress(host, port)), 231 Collections.<MongoCredential>emptyList(), options); 232 } 233 234 private MongoClient createNetworkMongoClient(MongoClientOptions options) { 235 if (hasCustomAddress() || hasCustomCredentials()) { 236 if (this.uri != null) { 237 throw new IllegalStateException("Invalid mongo configuration, " 238 + "either uri or host/port/credentials must be specified"); 239 } 240 if (options == null) { 241 options = MongoClientOptions.builder().build(); 242 } 243 List<MongoCredential> credentials = new ArrayList<MongoCredential>(); 244 if (hasCustomCredentials()) { 245 String database = this.authenticationDatabase == null 246 ? getMongoClientDatabase() : this.authenticationDatabase; 247 credentials.add(MongoCredential.createCredential(this.username, database, 248 this.password)); 249 } 250 String host = this.host == null ? "localhost" : this.host; 251 int port = this.port != null ? this.port : DEFAULT_PORT; 252 return new MongoClient( 253 Collections.singletonList(new ServerAddress(host, port)), credentials, 254 options); 255 } 256 // The options and credentials are in the URI 257 return new MongoClient(new MongoClientURI(determineUri(), builder(options))); 258 } 259 260 private boolean hasCustomAddress() { 261 return this.host != null || this.port != null; 262 } 263 264 private boolean hasCustomCredentials() { 265 return this.username != null && this.password != null; 266 } 267 268 private Builder builder(MongoClientOptions options) { 269 if (options != null) { 270 return MongoClientOptions.builder(options); 271 } 272 return MongoClientOptions.builder(); 273 } 274 275}