/* * Copyright (c) 2017 OBiBa. All rights reserved. * * This program and the accompanying materials * are made available under the terms of the GNU Public License v3.0. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.obiba.magma.datasource.mongodb; import java.io.ByteArrayInputStream; import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; import java.util.Map; import java.util.Properties; import javax.validation.constraints.NotNull; import org.apache.http.client.utils.URIBuilder; import org.obiba.magma.AbstractDatasourceFactory; import org.obiba.magma.Datasource; import com.google.common.base.Charsets; import com.google.common.base.Strings; /** * Create a MongoDB datasource by either providing a connection string * (see <a href="http://docs.mongodb.org/manual/reference/connection-string">MongoDB connection string specifications</a>) * or by providing the elements necessary to build the connection string. */ public class MongoDBDatasourceFactory extends AbstractDatasourceFactory { /** * mongodb://[username:password@]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/[database][?options]] */ @NotNull private String url; private String username; private String password; private String options; private int batchSize = 100; public MongoDBDatasourceFactory(@NotNull String name, @NotNull String url) { this(name, url, null, null, null); } public MongoDBDatasourceFactory(@NotNull String name, @NotNull String url, String username, String password, String options) { setName(name); this.url = url; this.username = username; this.password = password; this.options = options; } @NotNull @Override protected Datasource internalCreate() { MongoDBDatasource datasource = new MongoDBDatasource(getName(), getMongoDBFactory()); datasource.setBatchSize(batchSize); return datasource; } public MongoDBFactory getMongoDBFactory() { return new MongoDBFactory(getUri()); } public URI getUri() { try { URIBuilder uriBuilder = new URIBuilder(url); if(!Strings.isNullOrEmpty(username)) { if(Strings.isNullOrEmpty(password)) { uriBuilder.setUserInfo(username); } else { uriBuilder.setUserInfo(username, password); } } Properties prop = readOptions(); for(Map.Entry<Object, Object> entry : prop.entrySet()) { uriBuilder.addParameter(entry.getKey().toString(), entry.getValue().toString()); } return uriBuilder.build(); } catch(URISyntaxException e) { throw new RuntimeException("Cannot create MongoDB URI", e); } } public String getMongoDbDatabaseName() { try { URIBuilder uriBuilder = new URIBuilder(url); return uriBuilder.getPath().substring(1); } catch(URISyntaxException e) { throw new RuntimeException("Cannot parse MongoDB URI", e); } } public String getOptions() { return options; } public void setOptions(String options) { this.options = options; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } @NotNull public String getUrl() { return url; } public void setUrl(@NotNull String url) { this.url = url; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public Properties readOptions() { Properties prop = new Properties(); try { if(!Strings.isNullOrEmpty(options)) { prop.load(new ByteArrayInputStream(options.getBytes(Charsets.UTF_8))); } } catch(IOException e) { // can't really happen } return prop; } public int getBatchSize() { return batchSize; } public void setBatchSize(int batchSize) { if (batchSize < 1 || batchSize > MongoDBDatasource.MAX_BATCH_SIZE) throw new IllegalArgumentException("batchSize"); this.batchSize = batchSize; } }