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.couch;
18
19 import java.lang.reflect.Method;
20
21 import org.apache.logging.log4j.Logger;
22 import org.apache.logging.log4j.core.appender.db.nosql.NoSQLProvider;
23 import org.apache.logging.log4j.core.config.plugins.Plugin;
24 import org.apache.logging.log4j.core.config.plugins.PluginAttr;
25 import org.apache.logging.log4j.core.config.plugins.PluginFactory;
26 import org.apache.logging.log4j.core.helpers.NameUtil;
27 import org.apache.logging.log4j.status.StatusLogger;
28 import org.lightcouch.CouchDbClient;
29 import org.lightcouch.CouchDbProperties;
30
31
32
33
34 @Plugin(name = "CouchDb", category = "Core", printObject = true)
35 public final class CouchDBProvider implements NoSQLProvider<CouchDBConnection> {
36 private static final int HTTP = 80;
37 private static final int HTTPS = 443;
38 private static final Logger LOGGER = StatusLogger.getLogger();
39
40 private final CouchDbClient client;
41 private final String description;
42
43 private CouchDBProvider(final CouchDbClient client, final String description) {
44 this.client = client;
45 this.description = "couchDb{ " + description + " }";
46 }
47
48 @Override
49 public CouchDBConnection getConnection() {
50 return new CouchDBConnection(this.client);
51 }
52
53 @Override
54 public String toString() {
55 return this.description;
56 }
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79 @PluginFactory
80 public static CouchDBProvider createNoSQLProvider(@PluginAttr("databaseName") final String databaseName,
81 @PluginAttr("protocol") String protocol,
82 @PluginAttr("server") String server,
83 @PluginAttr("port") final String port,
84 @PluginAttr("username") final String username,
85 @PluginAttr("password") final String password,
86 @PluginAttr("factoryClassName") final String factoryClassName,
87 @PluginAttr("factoryMethodName") final String factoryMethodName) {
88 CouchDbClient client;
89 String description;
90 if (factoryClassName != null && factoryClassName.length() > 0 &&
91 factoryMethodName != null && factoryMethodName.length() > 0) {
92 try {
93 final Class<?> factoryClass = Class.forName(factoryClassName);
94 final Method method = factoryClass.getMethod(factoryMethodName);
95 final Object object = method.invoke(null);
96
97 if (object instanceof CouchDbClient) {
98 client = (CouchDbClient) object;
99 description = "uri=" + client.getDBUri();
100 } else if (object instanceof CouchDbProperties) {
101 final CouchDbProperties properties = (CouchDbProperties) object;
102 client = new CouchDbClient(properties);
103 description = "uri=" + client.getDBUri() + ", username=" + properties.getUsername()
104 + ", passwordHash=" + NameUtil.md5(password + CouchDBProvider.class.getName())
105 + ", maxConnections=" + properties.getMaxConnections() + ", connectionTimeout="
106 + properties.getConnectionTimeout() + ", socketTimeout=" + properties.getSocketTimeout();
107 } else if (object == null) {
108 LOGGER.error("The factory method [{}.{}()] returned null.", factoryClassName, factoryMethodName);
109 return null;
110 } else {
111 LOGGER.error("The factory method [{}.{}()] returned an unsupported type [{}].", factoryClassName,
112 factoryMethodName, object.getClass().getName());
113 return null;
114 }
115 } catch (final ClassNotFoundException e) {
116 LOGGER.error("The factory class [{}] could not be loaded.", factoryClassName, e);
117 return null;
118 } catch (final NoSuchMethodException e) {
119 LOGGER.error("The factory class [{}] does not have a no-arg method named [{}].", factoryClassName,
120 factoryMethodName, e);
121 return null;
122 } catch (final Exception e) {
123 LOGGER.error("The factory method [{}.{}()] could not be invoked.", factoryClassName, factoryMethodName,
124 e);
125 return null;
126 }
127 } else if (databaseName != null && databaseName.length() > 0) {
128 if (protocol != null && protocol.length() > 0) {
129 protocol = protocol.toLowerCase();
130 if (!protocol.equals("http") && !protocol.equals("https")) {
131 LOGGER.error("Only protocols [http] and [https] are supported, [{}] specified.", protocol);
132 return null;
133 }
134 } else {
135 protocol = "http";
136 LOGGER.warn("No protocol specified, using default port [http].");
137 }
138
139 int portInt = protocol.equals("https") ? HTTPS : HTTP;
140 if (port != null && port.length() > 0) {
141 try {
142 portInt = Integer.parseInt(port);
143 } catch (final NumberFormatException ignore) {
144
145 }
146 } else {
147 LOGGER.warn("No port specified, using default port [{}] for protocol [{}].", portInt, protocol);
148 }
149
150 if (server == null || server.length() == 0) {
151 server = "localhost";
152 LOGGER.warn("No server specified, using default server localhost.");
153 }
154
155 if (username == null || username.length() == 0 || password == null || password.length() == 0) {
156 LOGGER.error("You must provide a username and password for the CouchDB provider.");
157 return null;
158 }
159
160 client = new CouchDbClient(databaseName, false, protocol, server, portInt, username, password);
161 description = "uri=" + client.getDBUri() + ", username=" + username + ", passwordHash="
162 + NameUtil.md5(password + CouchDBProvider.class.getName());
163 } else {
164 LOGGER.error("No factory method was provided so the database name is required.");
165 return null;
166 }
167
168 return new CouchDBProvider(client, description);
169 }
170 }