在IBM Cloud中,我们可以创建 MongoDB服务,我们可以点击OverView看到连接的一些信息。

在Endpoint中,可以看到连接的信息,还有TSL连接需要的CA证书。

MongoDB Compass中的连接方法
填好URI:
mongodb://username:passwrd@xxxx:31236/ibmclouddb?authSource=admin&replicaSet=replset&tls=true
选择

NodeJs TLS的例子
const MongoClient = require("mongodb").MongoClient;
let connectionString = "mongodb://<username>:<password>@<host>:<port>,<host>:<port>/<database>?authSource=admin&replicaSet=replset";
let options = {
tls: true,
tlsCAFile: `/path/to/cert`,
useUnifiedTopology: true
};
// connects to a MongoDB database
MongoClient.connect(connectionString, options, function (err, db) {
if (err) {
console.log(err);
} else {
// lists the databases that exist in the deployment
db.db('example').admin().listDatabases(function(err, dbs) {
console.log(dbs.databases);
db.close();
});
}
});
Java连接的例子1
http://mongodb.github.io/mongo-java-driver/3.0/driver/reference/connecting/ssl/
通过下面的命令,把IBM cloud download下来的 CA文件转换一下。
keytool -importcert -trustcacerts -file <path to certificate authority file>
-keystore <path to trust store> -storepass <password>
keytool -importcert -trustcacerts -file /Users/Documents/ca/631b75c3-4296-4ce9-b0f2-426423c5b0e6 -keystore /Users/Documents/ca/sslkey -storepass test

import java.io.FileNotFoundException;
import java.net.UnknownHostException;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.mongodb.MongoDatabaseFactory;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.SimpleMongoClientDatabaseFactory;
import org.springframework.util.ResourceUtils;
import com.mongodb.client.MongoClient;
import com.mongodb.client.MongoClients;
@Configuration
public class MongoConfig {
@Value("${ssl.key.path}")
private String sslkeypath;
private String sslkeypass = "test";
private String mongouri= "mongodb://userid:passwod@ip:31236/ibmclouddb?authSource=admin&replicaSet=replset&ssl=true";
private String dbname = "testdb";
@Bean
public MongoDatabaseFactory mongoDbFactory() throws FileNotFoundException {
MongoClient mongoClient;
// ------打成jar会报错,下面这种写法待验证!----------
// InputStream stream = getClass().getClassLoader().getResourceAsStream(cafile);
// File caFile = new File("cafile");
// FileUtils.copyInputStreamToFile(stream, caFile);
// -------------------------------------------
// sslkey是上面用keytool,生成的文件
System.setProperty("javax.net.ssl.trustStore",
StringUtil.joinStr(ResourceUtils.getURL("classpath:").getPath(), "sslkey"));
// sslkeypass是keytool生成文件时指定的密码
System.setProperty("javax.net.ssl.trustStorePassword", sslkeypass);
final String mongoURI = mongouri;
mongoClient = MongoClients.create(mongoURI);
return new SimpleMongoClientDatabaseFactory(mongoClient, dbdbname);
}
@Bean
@Primary
public MongoTemplate mongoTemplate(MongoDatabaseFactory mongoDbFactory) throws UnknownHostException {
return new MongoTemplate(mongoDbFactory);
}
}
但是上面的方法本地测试好用,在IBM Cloud Engine上会出错。
Java连接的例子2
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.UnknownHostException;
import java.nio.charset.StandardCharsets;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManagerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.mongodb.MongoDatabaseFactory;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.SimpleMongoClientDatabaseFactory;
import com.mongodb.ConnectionString;
import com.mongodb.MongoClientSettings;
import com.mongodb.client.MongoClient;
import com.mongodb.client.MongoClients;
@Configuration
public class MongoConfig {
private String mongouri= "mongodb://userid:passwod@ip:31236/ibmclouddb?authSource=admin&replicaSet=replset&ssl=true";
@Value("${mongodb.db}")
private String dbname;
private String certificateDecoded = "-----BEGIN CERTIFICATE-----\n"
+ "xxxxxxIYKLSZthAzzXtJpTW1\n" + "-----END CERTIFICATE-----\n" + "";
@Bean
public MongoDatabaseFactory mongoDbFactory() throws CertificateException, KeyStoreException,
NoSuchAlgorithmException, IOException, KeyManagementException {
final String mongoURI = mongouri;
InputStream inputStream = new ByteArrayInputStream(certificateDecoded.getBytes(StandardCharsets.UTF_8));
CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
X509Certificate caCert = (X509Certificate) certificateFactory.generateCertificate(inputStream);
TrustManagerFactory trustManagerFactory = TrustManagerFactory
.getInstance(TrustManagerFactory.getDefaultAlgorithm());
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
keyStore.load(null);
keyStore.setCertificateEntry("caCert", caCert);
trustManagerFactory.init(keyStore);
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, trustManagerFactory.getTrustManagers(), null);
ConnectionString cs = new ConnectionString(mongoURI);
MongoClientSettings settings = MongoClientSettings.builder().applyConnectionString(cs)
.applyToSslSettings(builder -> {
builder.enabled(true);
builder.context(sslContext);
}).build();
MongoClient client = MongoClients.create(settings);
return new SimpleMongoClientDatabaseFactory(client, dbname);
}
@Bean
@Primary
public MongoTemplate mongoTemplate(MongoDatabaseFactory mongoDbFactory) throws UnknownHostException {
return new MongoTemplate(mongoDbFactory);
}
}
也可以用下面的写法,把certificateDecoded作成一个文件。然后读取这个文件,成字符串。
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.concurrent.TimeUnit;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManagerFactory;
import org.apache.commons.io.FileUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.mongodb.MongoDatabaseFactory;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.SimpleMongoClientDatabaseFactory;
import com.mongodb.ConnectionString;
import com.mongodb.MongoClientSettings;
import com.mongodb.client.MongoClient;
import com.mongodb.client.MongoClients;
@Configuration
public class MongoConfig {
@Value("${mongodb.uri}")
private String mongouri;
@Value("${mongodb.db}")
private String dbName;
@Value("${mongodb.cafile}")
private String cafile;
@Bean
public MongoDatabaseFactory mongoDbFactory() throws CertificateException, KeyStoreException,
NoSuchAlgorithmException, IOException, KeyManagementException {
// 注意这里面读取了本地的一个文件,文件里面有certificateDecoded信息
InputStream stream = getClass().getClassLoader().getResourceAsStream(cafile);
File caFile = new File("cafile");
FileUtils.copyInputStreamToFile(stream, caFile);
String certificateDecoded = "";
FileInputStream fileInputStream = null;
try {
fileInputStream = new FileInputStream(caFile);
byte[] bytes = new byte[2048];
int readCount = fileInputStream.read(bytes);
certificateDecoded = new String(bytes, 0, readCount);
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
if (fileInputStream != null) {
fileInputStream.close();
}
}
InputStream inputStream = new ByteArrayInputStream(certificateDecoded.getBytes(StandardCharsets.UTF_8));
CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
X509Certificate caCert = (X509Certificate) certificateFactory.generateCertificate(inputStream);
TrustManagerFactory trustManagerFactory = TrustManagerFactory
.getInstance(TrustManagerFactory.getDefaultAlgorithm());
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
keyStore.load(null);
keyStore.setCertificateEntry("caCert", caCert);
trustManagerFactory.init(keyStore);
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, trustManagerFactory.getTrustManagers(), null);
ConnectionString cs = new ConnectionString(mongouri);
// 注意这里面用到了数据库连接池
MongoClientSettings settings = MongoClientSettings.builder().applyToConnectionPoolSettings(
builder -> builder.maxWaitTime(10, TimeUnit.SECONDS).minSize(2).maxConnectionIdleTime(30, TimeUnit.SECONDS)).applyConnectionString(cs)
.applyToSslSettings(builder -> {
builder.enabled(true);
builder.context(sslContext);
}).build();
MongoClient client = MongoClients.create(settings);
return new SimpleMongoClientDatabaseFactory(client, dbName);
}
@Bean
@Primary
public MongoTemplate mongoTemplate(MongoDatabaseFactory mongoDbFactory) {
return new MongoTemplate(mongoDbFactory);
}
}


@RestController
@RequestMapping("/sample/v1")
public class SampleController {
@Autowired
private MongoTemplate mongoTemplate;
@GetMapping("/hello")
public String hello() {
Set<String> set = mongoTemplate.getCollectionNames();
for (String t : set) {
System.out.println(t);
}
return "hello!!!";
}
}