1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.logging.log4j.core.appender.db.nosql.mongo;
18
19 import java.lang.reflect.Field;
20 import java.lang.reflect.Method;
21 import java.util.List;
22
23 import org.apache.logging.log4j.Logger;
24 import org.apache.logging.log4j.core.appender.db.nosql.NoSQLProvider;
25 import org.apache.logging.log4j.core.config.plugins.Plugin;
26 import org.apache.logging.log4j.core.config.plugins.PluginAttr;
27 import org.apache.logging.log4j.core.config.plugins.PluginFactory;
28 import org.apache.logging.log4j.core.helpers.NameUtil;
29 import org.apache.logging.log4j.status.StatusLogger;
30
31 import com.mongodb.DB;
32 import com.mongodb.MongoClient;
33 import com.mongodb.ServerAddress;
34 import com.mongodb.WriteConcern;
35
36
37
38
39 @Plugin(name = "MongoDb", category = "Core", printObject = true)
40 public final class MongoDBProvider implements NoSQLProvider<MongoDBConnection> {
41 private static final Logger LOGGER = StatusLogger.getLogger();
42
43 private final String collectionName;
44 private final DB database;
45 private final String description;
46
47 private final WriteConcern writeConcern;
48
49 private MongoDBProvider(final DB database, final WriteConcern writeConcern, final String collectionName,
50 final String description) {
51 this.database = database;
52 this.writeConcern = writeConcern;
53 this.collectionName = collectionName;
54 this.description = "mongoDb{ " + description + " }";
55 }
56
57 @Override
58 public MongoDBConnection getConnection() {
59 return new MongoDBConnection(this.database, this.writeConcern, this.collectionName);
60 }
61
62 @Override
63 public String toString() {
64 return this.description;
65 }
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89 @PluginFactory
90 public static MongoDBProvider createNoSQLProvider(@PluginAttr("collectionName") final String collectionName,
91 @PluginAttr("writeConcernConstant") final String
92 writeConcernConstant,
93 @PluginAttr("writeConcernConstantClass") final String
94 writeConcernConstantClassName,
95 @PluginAttr("databaseName") final String databaseName,
96 @PluginAttr("server") final String server,
97 @PluginAttr("port") final String port,
98 @PluginAttr("username") final String username,
99 @PluginAttr("password") final String password,
100 @PluginAttr("factoryClassName") final String factoryClassName,
101 @PluginAttr("factoryMethodName") final String factoryMethodName) {
102 DB database;
103 String description;
104 if (factoryClassName != null && factoryClassName.length() > 0 &&
105 factoryMethodName != null && factoryMethodName.length() > 0) {
106 try {
107 final Class<?> factoryClass = Class.forName(factoryClassName);
108 final Method method = factoryClass.getMethod(factoryMethodName);
109 final Object object = method.invoke(null);
110
111 if (object instanceof DB) {
112 database = (DB) object;
113 } else if (object instanceof MongoClient) {
114 if (databaseName != null && databaseName.length() > 0) {
115 database = ((MongoClient) object).getDB(databaseName);
116 } else {
117 LOGGER.error("The factory method [{}.{}()] returned a MongoClient so the database name is "
118 + "required.", factoryClassName, factoryMethodName);
119 return null;
120 }
121 } else if (object == null) {
122 LOGGER.error("The factory method [{}.{}()] returned null.", factoryClassName, factoryMethodName);
123 return null;
124 } else {
125 LOGGER.error("The factory method [{}.{}()] returned an unsupported type [{}].", factoryClassName,
126 factoryMethodName, object.getClass().getName());
127 return null;
128 }
129
130 description = "database=" + database.getName();
131 final List<ServerAddress> addresses = database.getMongo().getAllAddress();
132 if (addresses.size() == 1) {
133 description += ", server=" + addresses.get(0).getHost() + ", port=" + addresses.get(0).getPort();
134 } else {
135 description += ", servers=[";
136 for (final ServerAddress address : addresses) {
137 description += " { " + address.getHost() + ", " + address.getPort() + " } ";
138 }
139 description += "]";
140 }
141 } catch (final ClassNotFoundException e) {
142 LOGGER.error("The factory class [{}] could not be loaded.", factoryClassName, e);
143 return null;
144 } catch (final NoSuchMethodException e) {
145 LOGGER.error("The factory class [{}] does not have a no-arg method named [{}].", factoryClassName,
146 factoryMethodName, e);
147 return null;
148 } catch (final Exception e) {
149 LOGGER.error("The factory method [{}.{}()] could not be invoked.", factoryClassName, factoryMethodName,
150 e);
151 return null;
152 }
153 } else if (databaseName != null && databaseName.length() > 0) {
154 description = "database=" + databaseName;
155 try {
156 if (server != null && server.length() > 0) {
157 int portInt = 0;
158 if (port != null && port.length() > 0) {
159 try {
160 portInt = Integer.parseInt(port);
161 } catch (final NumberFormatException ignore) {
162
163 }
164 }
165
166 description += ", server=" + server;
167 if (portInt > 0) {
168 description += ", port=" + portInt;
169 database = new MongoClient(server, portInt).getDB(databaseName);
170 } else {
171 database = new MongoClient(server).getDB(databaseName);
172 }
173 } else {
174 database = new MongoClient().getDB(databaseName);
175 }
176 } catch (final Exception e) {
177 LOGGER.error("Failed to obtain a database instance from the MongoClient at server [{}] and "
178 + "port [{}].", server, port);
179 return null;
180 }
181 } else {
182 LOGGER.error("No factory method was provided so the database name is required.");
183 return null;
184 }
185
186 if (!database.isAuthenticated()) {
187 if (username != null && username.length() > 0 && password != null && password.length() > 0) {
188 description += ", username=" + username + ", passwordHash="
189 + NameUtil.md5(password + MongoDBProvider.class.getName());
190 } else {
191 LOGGER.error("The database is not already authenticated so you must supply a username and password "
192 + "for the MongoDB provider.");
193 return null;
194 }
195 }
196
197 WriteConcern writeConcern;
198 if (writeConcernConstant != null && writeConcernConstant.length() > 0) {
199 if (writeConcernConstantClassName != null && writeConcernConstantClassName.length() > 0) {
200 try {
201 final Class<?> writeConcernConstantClass = Class.forName(writeConcernConstantClassName);
202 final Field field = writeConcernConstantClass.getField(writeConcernConstant);
203 writeConcern = (WriteConcern) field.get(null);
204 } catch (final Exception e) {
205 LOGGER.error("Write concern constant [{}.{}] not found, using default.",
206 writeConcernConstantClassName, writeConcernConstant);
207 writeConcern = WriteConcern.ACKNOWLEDGED;
208 }
209 } else {
210 writeConcern = WriteConcern.valueOf(writeConcernConstant);
211 if (writeConcern == null) {
212 LOGGER.warn("Write concern constant [{}] not found, using default.", writeConcernConstant);
213 writeConcern = WriteConcern.ACKNOWLEDGED;
214 }
215 }
216 } else {
217 writeConcern = WriteConcern.ACKNOWLEDGED;
218 }
219
220 return new MongoDBProvider(database, writeConcern, collectionName, description);
221 }
222 }