001/* 002 * Copyright 2012-2018 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.util.Collections; 020import java.util.List; 021 022import com.mongodb.MongoClient; 023import com.mongodb.MongoClientOptions; 024import com.mongodb.MongoClientOptions.Builder; 025import com.mongodb.MongoClientURI; 026import com.mongodb.MongoCredential; 027import com.mongodb.ServerAddress; 028 029import org.springframework.core.env.Environment; 030 031/** 032 * A factory for a blocking {@link MongoClient} that applies {@link MongoProperties}. 033 * 034 * @author Dave Syer 035 * @author Phillip Webb 036 * @author Josh Long 037 * @author Andy Wilkinson 038 * @author EddĂș MelĂ©ndez 039 * @author Stephane Nicoll 040 * @author Nasko Vasilev 041 * @author Mark Paluch 042 * @since 2.0.0 043 */ 044public class MongoClientFactory { 045 046 private final MongoProperties properties; 047 048 private final Environment environment; 049 050 public MongoClientFactory(MongoProperties properties, Environment environment) { 051 this.properties = properties; 052 this.environment = environment; 053 } 054 055 /** 056 * Creates a {@link MongoClient} using the given {@code options}. If the environment 057 * contains a {@code local.mongo.port} property, it is used to configure a client to 058 * an embedded MongoDB instance. 059 * @param options the options 060 * @return the Mongo client 061 */ 062 public MongoClient createMongoClient(MongoClientOptions options) { 063 Integer embeddedPort = getEmbeddedPort(); 064 if (embeddedPort != null) { 065 return createEmbeddedMongoClient(options, embeddedPort); 066 } 067 return createNetworkMongoClient(options); 068 } 069 070 private Integer getEmbeddedPort() { 071 if (this.environment != null) { 072 String localPort = this.environment.getProperty("local.mongo.port"); 073 if (localPort != null) { 074 return Integer.valueOf(localPort); 075 } 076 } 077 return null; 078 } 079 080 private MongoClient createEmbeddedMongoClient(MongoClientOptions options, int port) { 081 if (options == null) { 082 options = MongoClientOptions.builder().build(); 083 } 084 String host = (this.properties.getHost() != null) ? this.properties.getHost() 085 : "localhost"; 086 return new MongoClient(Collections.singletonList(new ServerAddress(host, port)), 087 options); 088 } 089 090 private MongoClient createNetworkMongoClient(MongoClientOptions options) { 091 MongoProperties properties = this.properties; 092 if (properties.getUri() != null) { 093 return createMongoClient(properties.getUri(), options); 094 } 095 if (hasCustomAddress() || hasCustomCredentials()) { 096 if (options == null) { 097 options = MongoClientOptions.builder().build(); 098 } 099 MongoCredential credentials = getCredentials(properties); 100 String host = getValue(properties.getHost(), "localhost"); 101 int port = getValue(properties.getPort(), MongoProperties.DEFAULT_PORT); 102 List<ServerAddress> seeds = Collections 103 .singletonList(new ServerAddress(host, port)); 104 return (credentials != null) ? new MongoClient(seeds, credentials, options) 105 : new MongoClient(seeds, options); 106 } 107 return createMongoClient(MongoProperties.DEFAULT_URI, options); 108 } 109 110 private MongoClient createMongoClient(String uri, MongoClientOptions options) { 111 return new MongoClient(new MongoClientURI(uri, builder(options))); 112 } 113 114 private <T> T getValue(T value, T fallback) { 115 return (value != null) ? value : fallback; 116 } 117 118 private boolean hasCustomAddress() { 119 return this.properties.getHost() != null || this.properties.getPort() != null; 120 } 121 122 private MongoCredential getCredentials(MongoProperties properties) { 123 if (!hasCustomCredentials()) { 124 return null; 125 } 126 String username = properties.getUsername(); 127 String database = getValue(properties.getAuthenticationDatabase(), 128 properties.getMongoClientDatabase()); 129 char[] password = properties.getPassword(); 130 return MongoCredential.createCredential(username, database, password); 131 } 132 133 private boolean hasCustomCredentials() { 134 return this.properties.getUsername() != null 135 && this.properties.getPassword() != null; 136 } 137 138 private Builder builder(MongoClientOptions options) { 139 if (options != null) { 140 return MongoClientOptions.builder(options); 141 } 142 return MongoClientOptions.builder(); 143 } 144 145}