在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!!!"; } }