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 static java.util.concurrent.TimeUnit.SECONDS; 022 023import java.io.File; 024import java.io.FileInputStream; 025import java.io.IOException; 026import java.io.InputStream; 027 028import org.apache.commons.logging.Log; 029import org.apache.commons.logging.LogFactory; 030import org.bson.Document; 031import org.nuxeo.common.xmap.XMap; 032import org.nuxeo.launcher.config.ConfigurationException; 033import org.nuxeo.launcher.config.ConfigurationGenerator; 034import org.nuxeo.launcher.config.backingservices.BackingChecker; 035import org.nuxeo.runtime.mongodb.MongoDBConnectionConfig; 036import org.nuxeo.runtime.mongodb.MongoDBConnectionHelper; 037 038import com.mongodb.MongoTimeoutException; 039import com.mongodb.client.MongoClient; 040import com.mongodb.client.MongoDatabase; 041 042public class MongoDBChecker implements BackingChecker { 043 044 private static final Log log = LogFactory.getLog(MongoDBChecker.class); 045 046 public static final String TEMPLATE_NAME = "mongodb"; 047 048 public static final String CONFIG_NAME = "mongodb-connection-config.xml"; 049 050 /** 051 * @since 9.3 052 */ 053 public static final String PARAM_MONGODB_CHECK_TIMEOUT = "nuxeo.mongodb.check.timeout"; 054 055 /** 056 * @since 9.3 057 */ 058 public static final int DEFAULT_CHECK_TIMEOUT_IN_SECONDS = 5; 059 060 @Override 061 public boolean accepts(ConfigurationGenerator cg) { 062 return cg.getTemplateList().contains(TEMPLATE_NAME); 063 } 064 065 @Override 066 public void check(ConfigurationGenerator cg) throws ConfigurationException { 067 File configFile = new File(cg.getConfigDir(), CONFIG_NAME); 068 if (!configFile.exists()) { 069 log.warn("Unable to find config file " + CONFIG_NAME); 070 return; 071 } 072 MongoDBConnectionConfig config = getDescriptor(configFile, MongoDBConnectionConfig.class); 073 try (MongoClient mongoClient = MongoDBConnectionHelper.newMongoClient(config, 074 builder -> builder.applicationName("Nuxeo DB Check") 075 .applyToClusterSettings( 076 s -> s.serverSelectionTimeout(getCheckTimeoutInSeconds(cg), SECONDS)))) { 077 MongoDatabase database = mongoClient.getDatabase(config.dbname); 078 Document ping = new Document("ping", "1"); 079 database.runCommand(ping); 080 } catch (MongoTimeoutException e) { 081 throw new ConfigurationException( 082 String.format("Unable to connect to MongoDB at %s, please check your connection", config.server), 083 e); 084 } 085 } 086 087 /** 088 * Creates a descriptor instance for the specified file and descriptor class. 089 * 090 * @since 11.1 091 */ 092 @SuppressWarnings("unchecked") 093 public <T> T getDescriptor(File file, Class<T> klass) throws ConfigurationException { 094 XMap xmap = new XMap(); 095 xmap.register(klass); 096 try (InputStream inStream = new FileInputStream(file)) { 097 return (T) xmap.load(inStream); 098 } catch (IOException e) { 099 throw new ConfigurationException("Unable to load the configuration for " + klass.getSimpleName(), e); 100 } 101 } 102 103 /** 104 * Returns the value of the check timeout parameter in seconds. If value is not parseable or not set, then use the 105 * default value. 106 * 107 * @return the timeout check in seconds. 108 * @since 9.3 109 */ 110 private int getCheckTimeoutInSeconds(ConfigurationGenerator cg) { 111 int checkTimeout = DEFAULT_CHECK_TIMEOUT_IN_SECONDS; 112 try { 113 checkTimeout = Integer.parseInt( 114 cg.getUserConfig() 115 .getProperty(PARAM_MONGODB_CHECK_TIMEOUT, String.valueOf(DEFAULT_CHECK_TIMEOUT_IN_SECONDS))); 116 } catch (NumberFormatException e) { 117 log.warn(String.format("Invalid format for %s parameter, using default value instead", 118 PARAM_MONGODB_CHECK_TIMEOUT), e); 119 } 120 return checkTimeout; 121 } 122}