| /** |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package org.apache.felix.useradmin.mongodb; |
| |
| import java.net.UnknownHostException; |
| import java.util.ArrayList; |
| import java.util.List; |
| import java.util.concurrent.atomic.AtomicReference; |
| |
| import com.mongodb.DB; |
| import com.mongodb.DBCollection; |
| import com.mongodb.Mongo; |
| import com.mongodb.MongoException; |
| import com.mongodb.ServerAddress; |
| |
| /** |
| * Provides a simple facade for accessing MongoDB. |
| */ |
| final class MongoDB { |
| |
| private final List<ServerAddress> m_servers; |
| private final String m_dbName; |
| private final String m_collectionName; |
| |
| private final AtomicReference<Mongo> m_mongoRef; |
| |
| /** |
| * Creates a new {@link MongoDB} instance. |
| * |
| * @param serverNames the space separated list of Mongo servers, cannot be <code>null</code> or empty; |
| * @param dbName the name of the MongoDB to connect to, cannot be <code>null</code> or empty; |
| * @param collectionName the name of the collection to use, cannot be <code>null</code> or empty. |
| */ |
| public MongoDB(String serverNames, String dbName, String collectionName) { |
| if (serverNames == null || "".equals(serverNames.trim())) { |
| throw new IllegalArgumentException("ServerNames cannot be null or empty!"); |
| } |
| if (dbName == null || "".equals(dbName.trim())) { |
| throw new IllegalArgumentException("DbName cannot be null or empty!"); |
| } |
| if (collectionName == null || "".equals(collectionName.trim())) { |
| throw new IllegalArgumentException("CollectionName cannot be null or empty!"); |
| } |
| |
| m_mongoRef = new AtomicReference<Mongo>(); |
| |
| m_servers = parseServers(serverNames); |
| m_dbName = dbName; |
| m_collectionName = collectionName; |
| } |
| |
| /** |
| * Parses the space separated list of server names. |
| * |
| * @param serverNames the server names, cannot be <code>null</code>. |
| * @return a list of {@link ServerAddress}es to connect to, never <code>null</code>. |
| * @throws IllegalArgumentException in case the given server names was invalid. |
| */ |
| private static List<ServerAddress> parseServers(String serverNames) { |
| String[] parts = serverNames.split("\\s+"); |
| |
| List<ServerAddress> servers = new ArrayList<ServerAddress>(); |
| for (int i = 0; i < parts.length; i++) { |
| String part = parts[i]; |
| try { |
| int colonPos = part.indexOf(":"); |
| if (colonPos > 0 && (colonPos < part.length() - 1)) { |
| String name = part.substring(0, colonPos); |
| String portStr = part.substring(colonPos + 1); |
| servers.add(new ServerAddress(name, Integer.valueOf(portStr))); |
| } |
| } |
| catch (NumberFormatException e) { |
| throw new IllegalArgumentException("Illegal port number in: " + part); |
| } |
| catch (UnknownHostException e) { |
| throw new IllegalArgumentException("Unknown host: " + part); |
| } |
| } |
| |
| if (servers.isEmpty()) { |
| throw new IllegalArgumentException("No (valid) servers defined!"); |
| } |
| |
| return servers; |
| } |
| |
| /** |
| * Connects to the MongoDB with the supplied credentials. |
| * |
| * @param userName the optional user name to use; |
| * @param password the optional password to use. |
| * @return <code>true</code> if the connection was succesful, <code>false</code> otherwise. |
| */ |
| public boolean connect(String userName, String password) { |
| Mongo newMongo = new Mongo(m_servers); |
| |
| Mongo oldMongo; |
| do { |
| oldMongo = m_mongoRef.get(); |
| } while (!m_mongoRef.compareAndSet(oldMongo, newMongo)); |
| |
| DB db = newMongo.getDB(m_dbName); |
| if ((userName != null) && (password != null)) { |
| if (!db.authenticate(userName, password.toCharArray())) { |
| return false; |
| } |
| } |
| |
| return true; |
| } |
| |
| /** |
| * Returns the database collection to work in. |
| * |
| * @return the {@link DBCollection}, never <code>null</code>. |
| * @throws MongoException in case no connection to Mongo exists. |
| */ |
| public DBCollection getCollection() { |
| Mongo mongo = m_mongoRef.get(); |
| if (mongo == null) { |
| throw new MongoException("Not connected to MongoDB!"); |
| } |
| DB db = mongo.getDB(m_dbName); |
| return db.getCollection(m_collectionName); |
| } |
| |
| /** |
| * Disconnects from the MongoDB. |
| */ |
| public void disconnect() { |
| Mongo mongo = m_mongoRef.get(); |
| if (mongo != null) { |
| try { |
| mongo.close(); |
| } finally { |
| m_mongoRef.compareAndSet(mongo, null); |
| } |
| } |
| } |
| } |