001/*
002 * (C) Copyright 2017 Nuxeo (http://nuxeo.com/) and others.
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 * Contributors:
017 *     dmetzler
018 */
019package org.nuxeo.ecm.core.storage.mongodb;
020
021import java.util.concurrent.TimeUnit;
022
023import org.apache.commons.logging.Log;
024import org.apache.commons.logging.LogFactory;
025import org.bson.Document;
026import org.nuxeo.launcher.config.ConfigurationException;
027import org.nuxeo.launcher.config.ConfigurationGenerator;
028import org.nuxeo.launcher.config.backingservices.BackingChecker;
029
030import com.mongodb.MongoClient;
031import com.mongodb.MongoClientOptions;
032import com.mongodb.MongoClientURI;
033import com.mongodb.MongoTimeoutException;
034import com.mongodb.ServerAddress;
035
036public class MongoDBChecker implements BackingChecker {
037
038    private static final Log log = LogFactory.getLog(MongoDBChecker.class);
039
040    public static final String TEMPLATE_NAME = "mongodb";
041
042    /**
043     * @since 9.3
044     */
045    public static final String PARAM_MONGODB_CHECK_TIMEOUT = "nuxeo.mongodb.check.timeout";
046
047    /**
048     * @since 9.3
049     */
050    public static final int DEFAULT_CHECK_TIMEOUT_IN_SECONDS = 5;
051
052
053    @Override
054    public boolean accepts(ConfigurationGenerator cg) {
055        return cg.getTemplateList().contains(TEMPLATE_NAME);
056    }
057
058    @Override
059    public void check(ConfigurationGenerator cg) throws ConfigurationException {
060        MongoClient ret = null;
061        String serverName = cg.getUserConfig().getProperty(ConfigurationGenerator.PARAM_MONGODB_SERVER);
062        String dbName = cg.getUserConfig().getProperty(ConfigurationGenerator.PARAM_MONGODB_NAME);
063
064        MongoClientOptions.Builder optionsBuilder = MongoClientOptions.builder()
065                                                                      .serverSelectionTimeout(
066                                                                              (int) TimeUnit.SECONDS.toMillis(getCheckTimeoutInSeconds(cg)))
067                                                                      .description("Nuxeo DB Check");
068        if (serverName.startsWith("mongodb://")) {
069            // allow mongodb:// URI syntax for the server, to pass everything in one string
070            ret = new MongoClient(new MongoClientURI(serverName, optionsBuilder));
071        } else {
072            ret = new MongoClient(new ServerAddress(serverName), optionsBuilder.build());
073        }
074        try {
075            Document ping = new Document("ping", "1");
076            ret.getDatabase(dbName).runCommand(ping);
077        } catch (MongoTimeoutException e) {
078            throw new ConfigurationException(
079                    String.format("Unable to connect to MongoDB at %s, please check your connection", serverName));
080        } finally {
081            ret.close();
082        }
083    }
084
085    /**
086     * Returns the value of the check timeout parameter in seconds.
087     * If value is not parseable or not set, then use the default value.
088     * @return the timeout check in seconds.
089     * @since 9.3
090     */
091    private int getCheckTimeoutInSeconds(ConfigurationGenerator cg) {
092        int checkTimeout = DEFAULT_CHECK_TIMEOUT_IN_SECONDS;
093        try {
094            checkTimeout = Integer.parseInt(cg.getUserConfig().getProperty(PARAM_MONGODB_CHECK_TIMEOUT, String.valueOf(DEFAULT_CHECK_TIMEOUT_IN_SECONDS)));
095        } catch (NumberFormatException e) {
096            log.warn(String.format("Invalid format for %s parameter, using default value instead", PARAM_MONGODB_CHECK_TIMEOUT), e);
097        }
098        return checkTimeout;
099    }
100}