Skip to content
This repository was archived by the owner on Sep 16, 2024. It is now read-only.

Commit 74401da

Browse files
committed
New ConfiguredDatabaseClientFactory API
1 parent 986387e commit 74401da

13 files changed

+251
-63
lines changed
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package com.marklogic.client.ext;
2+
3+
import com.marklogic.client.DatabaseClient;
4+
5+
/**
6+
* Hides how a DatabaseClient is constructed based on the inputs in a DatabaseClientConfig object. The intent is that a
7+
* client can populate any set of properties on the DatabaseClientConfig, and an implementation of this interface will
8+
* determine how to construct a new DatabaseClient based on those properties.
9+
*/
10+
public interface ConfiguredDatabaseClientFactory {
11+
12+
DatabaseClient newDatabaseClient(DatabaseClientConfig databaseClientConfig);
13+
14+
}

src/main/java/com/marklogic/client/ext/helper/DatabaseClientConfig.java renamed to src/main/java/com/marklogic/client/ext/DatabaseClientConfig.java

Lines changed: 57 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,41 @@
1-
package com.marklogic.client.ext.helper;
1+
package com.marklogic.client.ext;
22

33
import javax.net.ssl.SSLContext;
44

55
import com.marklogic.client.DatabaseClientFactory.Authentication;
66
import com.marklogic.client.DatabaseClientFactory.SSLHostnameVerifier;
77

8+
/**
9+
* Captures all the possible inputs used to construct an instance of DatabaseClient.
10+
*
11+
* The Authentication attribute is deprecated, as this class is deprecated in version 4.x of the Java Client API.
12+
* Use securityContextType and the constants defined in this class to define the particular kind of security context
13+
* that should be constructed.
14+
*/
815
public class DatabaseClientConfig {
916

10-
private String host;
17+
private SecurityContextType securityContextType = SecurityContextType.DIGEST;
18+
private String host;
1119
private int port;
1220
private String username;
1321
private String password;
1422
private String database;
15-
private Authentication authentication = Authentication.DIGEST;
1623
private SSLContext sslContext;
1724
private SSLHostnameVerifier sslHostnameVerifier;
25+
private String certFile;
26+
private String certPassword;
27+
private String externalName;
28+
29+
@Deprecated
30+
private Authentication authentication;
31+
32+
public DatabaseClientConfig() {
33+
}
34+
35+
public DatabaseClientConfig(String host, int port) {
36+
this.host = host;
37+
this.port = port;
38+
}
1839

1940
public DatabaseClientConfig(String host, int port, String username, String password) {
2041
this.host = host;
@@ -44,10 +65,12 @@ public String getPassword() {
4465
return password;
4566
}
4667

68+
@Deprecated
4769
public Authentication getAuthentication() {
4870
return authentication;
4971
}
5072

73+
@Deprecated
5174
public void setAuthentication(Authentication authentication) {
5275
this.authentication = authentication;
5376
}
@@ -92,4 +115,35 @@ public void setDatabase(String database) {
92115
this.database = database;
93116
}
94117

118+
public SecurityContextType getSecurityContextType() {
119+
return securityContextType;
120+
}
121+
122+
public void setSecurityContextType(SecurityContextType securityContextType) {
123+
this.securityContextType = securityContextType;
124+
}
125+
126+
public String getCertFile() {
127+
return certFile;
128+
}
129+
130+
public void setCertFile(String certFile) {
131+
this.certFile = certFile;
132+
}
133+
134+
public String getCertPassword() {
135+
return certPassword;
136+
}
137+
138+
public void setCertPassword(String certPassword) {
139+
this.certPassword = certPassword;
140+
}
141+
142+
public String getExternalName() {
143+
return externalName;
144+
}
145+
146+
public void setExternalName(String externalName) {
147+
this.externalName = externalName;
148+
}
95149
}
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
package com.marklogic.client.ext;
2+
3+
import com.marklogic.client.DatabaseClient;
4+
import com.marklogic.client.DatabaseClientFactory;
5+
import com.marklogic.client.ext.ConfiguredDatabaseClientFactory;
6+
import com.marklogic.client.ext.DatabaseClientConfig;
7+
8+
import javax.net.ssl.SSLContext;
9+
10+
/**
11+
* Default implementation for constructing a new instance of DatabaseClient based on the inputs in an instance of
12+
* DatabaseClientConfig.
13+
*/
14+
public class DefaultConfiguredDatabaseClientFactory implements ConfiguredDatabaseClientFactory {
15+
16+
@Override
17+
public DatabaseClient newDatabaseClient(DatabaseClientConfig config) {
18+
DatabaseClientFactory.SecurityContext securityContext;
19+
20+
SecurityContextType securityContextType = config.getSecurityContextType();
21+
22+
if (SecurityContextType.BASIC.equals(securityContextType)) {
23+
securityContext = new DatabaseClientFactory.BasicAuthContext(config.getUsername(), config.getPassword());
24+
} else if (SecurityContextType.CERTIFICATE.equals(securityContextType)) {
25+
securityContext = buildCertificateAuthContent(config);
26+
} else if (SecurityContextType.DIGEST.equals(securityContextType)) {
27+
securityContext = new DatabaseClientFactory.DigestAuthContext(config.getUsername(), config.getPassword());
28+
} else if (SecurityContextType.KERBEROS.equals(securityContextType)) {
29+
securityContext = new DatabaseClientFactory.KerberosAuthContext(config.getExternalName());
30+
} else if (SecurityContextType.NONE.equals(securityContextType)) {
31+
securityContext = null;
32+
}
33+
else {
34+
throw new IllegalArgumentException("Unsupported SecurityContextType: " + securityContextType);
35+
}
36+
37+
if (securityContext != null) {
38+
SSLContext sslContext = config.getSslContext();
39+
DatabaseClientFactory.SSLHostnameVerifier verifier = config.getSslHostnameVerifier();
40+
if (sslContext != null) {
41+
securityContext = securityContext.withSSLContext(sslContext);
42+
}
43+
if (verifier != null) {
44+
securityContext = securityContext.withSSLHostnameVerifier(verifier);
45+
}
46+
}
47+
48+
String host = config.getHost();
49+
int port = config.getPort();
50+
String database = config.getDatabase();
51+
52+
if (securityContext == null) {
53+
if (database == null) {
54+
return DatabaseClientFactory.newClient(host, port);
55+
}
56+
return DatabaseClientFactory.newClient(host, port, database);
57+
}
58+
if (database == null) {
59+
return DatabaseClientFactory.newClient(host, port, securityContext);
60+
}
61+
return DatabaseClientFactory.newClient(host, port, database, securityContext);
62+
}
63+
64+
/**
65+
* The Authentication shouldn't be set on the DatabaseClientConfig, but if it is, it's used instead of the value
66+
* of securityContextType.
67+
*
68+
* @param config
69+
* @return
70+
*/
71+
protected SecurityContextType determineSecurityContextType(DatabaseClientConfig config) {
72+
DatabaseClientFactory.Authentication auth = config.getAuthentication();
73+
if (auth != null) {
74+
if (DatabaseClientFactory.Authentication.BASIC.equals(auth)) {
75+
return SecurityContextType.BASIC;
76+
} else if (DatabaseClientFactory.Authentication.CERTIFICATE.equals(auth)) {
77+
return SecurityContextType.CERTIFICATE;
78+
} else if (DatabaseClientFactory.Authentication.KERBEROS.equals(auth)) {
79+
return SecurityContextType.KERBEROS;
80+
}
81+
return SecurityContextType.DIGEST;
82+
}
83+
return config.getSecurityContextType();
84+
}
85+
86+
protected DatabaseClientFactory.SecurityContext buildCertificateAuthContent(DatabaseClientConfig config) {
87+
String certFile = config.getCertFile();
88+
if (certFile != null) {
89+
try {
90+
if (config.getCertPassword() != null) {
91+
return new DatabaseClientFactory.CertificateAuthContext(certFile, config.getCertPassword());
92+
}
93+
return new DatabaseClientFactory.CertificateAuthContext(certFile);
94+
} catch (Exception ex) {
95+
throw new RuntimeException("Unable to build CertificateAuthContext: " + ex.getMessage(), ex);
96+
}
97+
}
98+
DatabaseClientFactory.SSLHostnameVerifier verifier = config.getSslHostnameVerifier();
99+
if (verifier != null) {
100+
return new DatabaseClientFactory.CertificateAuthContext(config.getSslContext(), verifier);
101+
}
102+
return new DatabaseClientFactory.CertificateAuthContext(config.getSslContext());
103+
}
104+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package com.marklogic.client.ext;
2+
3+
/**
4+
* The Authentication enum in marklogic-client-api was deprecated in 4.0.1, but this enum is useful in
5+
* DatabaseClientConfig as a way of referencing a particular SecurityContext implementation to use.
6+
*/
7+
public enum SecurityContextType {
8+
9+
BASIC,
10+
CERTIFICATE,
11+
DIGEST,
12+
KERBEROS,
13+
NONE
14+
}

src/main/java/com/marklogic/client/ext/spring/BasicConfig.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
import org.springframework.context.annotation.PropertySource;
77
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
88

9-
import com.marklogic.client.ext.helper.DatabaseClientConfig;
9+
import com.marklogic.client.ext.DatabaseClientConfig;
1010
import com.marklogic.client.ext.helper.DatabaseClientProvider;
1111
import com.marklogic.xcc.template.XccTemplate;
1212

Lines changed: 43 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
package com.marklogic.client.ext.spring;
22

3-
import org.springframework.beans.factory.DisposableBean;
4-
import org.springframework.beans.factory.FactoryBean;
5-
63
import com.marklogic.client.DatabaseClient;
7-
import com.marklogic.client.DatabaseClientFactory;
8-
import com.marklogic.client.ext.helper.DatabaseClientConfig;
4+
import com.marklogic.client.ext.DatabaseClientConfig;
5+
import com.marklogic.client.ext.DefaultConfiguredDatabaseClientFactory;
96
import com.marklogic.client.ext.helper.LoggingObject;
7+
import org.springframework.beans.factory.DisposableBean;
8+
import org.springframework.beans.factory.FactoryBean;
109

1110
/**
1211
* Hooks into Spring container lifecycle so that the DatabaseClient is initialized when the container starts up and
@@ -17,52 +16,50 @@
1716
*/
1817
public class DatabaseClientManager extends LoggingObject implements FactoryBean<DatabaseClient>, DisposableBean {
1918

20-
private DatabaseClientConfig config;
21-
private DatabaseClient client;
19+
private DatabaseClientConfig config;
20+
private DatabaseClient client;
2221

23-
public DatabaseClientManager() {
24-
super();
25-
}
22+
public DatabaseClientManager() {
23+
super();
24+
}
2625

27-
public DatabaseClientManager(DatabaseClientConfig config) {
28-
this();
29-
this.config = config;
30-
}
26+
public DatabaseClientManager(DatabaseClientConfig config) {
27+
this();
28+
this.config = config;
29+
}
3130

32-
@Override
33-
public DatabaseClient getObject() {
34-
if (client == null) {
35-
if (logger.isInfoEnabled()) {
36-
logger.info("Connecting to REST server with: " + config);
37-
}
38-
client = DatabaseClientFactory.newClient(config.getHost(), config.getPort(), config.getDatabase(),
39-
config.getUsername(), config.getPassword(), config.getAuthentication(), config.getSslContext(),
40-
config.getSslHostnameVerifier());
41-
}
42-
return client;
43-
}
31+
@Override
32+
public DatabaseClient getObject() {
33+
if (client == null) {
34+
if (logger.isInfoEnabled()) {
35+
logger.info("Connecting to REST server with: " + config);
36+
}
37+
client = new DefaultConfiguredDatabaseClientFactory().newDatabaseClient(config);
38+
}
39+
return client;
40+
}
4441

45-
@Override
46-
public Class<?> getObjectType() {
47-
return DatabaseClient.class;
48-
}
42+
@Override
43+
public Class<?> getObjectType() {
44+
return DatabaseClient.class;
45+
}
4946

50-
@Override
51-
public boolean isSingleton() {
52-
return true;
53-
}
47+
@Override
48+
public boolean isSingleton() {
49+
return true;
50+
}
5451

55-
@Override
56-
public void destroy() {
57-
if (client != null) {
58-
if (logger.isInfoEnabled()) {
59-
logger.info("Releasing client with username: " + config.getUsername());
60-
}
61-
client.release();
62-
}
63-
}
52+
@Override
53+
public void destroy() {
54+
if (client != null) {
55+
if (logger.isInfoEnabled()) {
56+
logger.info("Releasing client with username: " + config.getUsername());
57+
}
58+
client.release();
59+
}
60+
}
6461

65-
public void setConfig(DatabaseClientConfig config) {
66-
this.config = config;
67-
}
62+
public void setConfig(DatabaseClientConfig config) {
63+
this.config = config;
64+
}
6865
}

src/main/java/com/marklogic/client/ext/spring/SimpleDatabaseClientProvider.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import org.springframework.beans.factory.DisposableBean;
44

55
import com.marklogic.client.DatabaseClient;
6-
import com.marklogic.client.ext.helper.DatabaseClientConfig;
6+
import com.marklogic.client.ext.DatabaseClientConfig;
77
import com.marklogic.client.ext.helper.DatabaseClientProvider;
88

99
public class SimpleDatabaseClientProvider implements DatabaseClientProvider, DisposableBean {

src/main/java/com/marklogic/client/ext/spring/SpringDatabaseClientConfig.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package com.marklogic.client.ext.spring;
22

3-
import com.marklogic.client.ext.helper.DatabaseClientConfig;
3+
import com.marklogic.client.ext.DatabaseClientConfig;
44
import org.springframework.beans.factory.annotation.Autowired;
55
import org.springframework.beans.factory.annotation.Value;
66
import org.springframework.stereotype.Component;

src/test/java/com/marklogic/client/ext/AbstractIntegrationTest.java

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
package com.marklogic.client.ext;
22

33
import com.marklogic.client.DatabaseClient;
4-
import com.marklogic.client.DatabaseClientFactory;
5-
import com.marklogic.client.ext.helper.DatabaseClientConfig;
64
import com.marklogic.client.ext.spring.config.MarkLogicApplicationContext;
75
import org.junit.After;
86
import org.junit.Assert;
@@ -19,15 +17,18 @@ public abstract class AbstractIntegrationTest extends Assert {
1917
protected DatabaseClientConfig clientConfig;
2018
protected DatabaseClient client;
2119

20+
protected ConfiguredDatabaseClientFactory configuredDatabaseClientFactory = new DefaultConfiguredDatabaseClientFactory();
21+
2222
protected DatabaseClient newClient() {
23-
client = DatabaseClientFactory.newClient(clientConfig.getHost(), clientConfig.getPort(), clientConfig.getUsername(),
24-
clientConfig.getPassword(), DatabaseClientFactory.Authentication.DIGEST);
23+
client = configuredDatabaseClientFactory.newDatabaseClient(clientConfig);
2524
return client;
2625
}
2726

2827
protected DatabaseClient newClient(String database) {
29-
client = DatabaseClientFactory.newClient(clientConfig.getHost(), clientConfig.getPort(), database, clientConfig.getUsername(),
30-
clientConfig.getPassword(), DatabaseClientFactory.Authentication.DIGEST);
28+
String currentDatabase = clientConfig.getDatabase();
29+
clientConfig.setDatabase(database);
30+
client = configuredDatabaseClientFactory.newDatabaseClient(clientConfig);
31+
clientConfig.setDatabase(currentDatabase);
3132
return client;
3233
}
3334

0 commit comments

Comments
 (0)