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

Commit d3126e7

Browse files
authored
Merge pull request #511 from marklogic/dev
Merge in changes for 4.8.0
2 parents 1abffdd + 4f3ec47 commit d3126e7

26 files changed

+409
-51
lines changed

build.gradle

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,12 @@ plugins {
33
id "maven-publish"
44
id "signing"
55
id "com.github.jk1.dependency-license-report" version "1.17"
6-
id "net.saliman.properties" version "1.5.1"
6+
id "net.saliman.properties" version "1.5.2"
77
id "io.snyk.gradle.plugin.snykplugin" version "0.4"
88
}
99

1010
group = "com.marklogic"
11-
version = "4.7.0"
11+
version = "4.8.0"
1212

1313
java {
1414
sourceCompatibility = 1.8
@@ -24,8 +24,8 @@ repositories {
2424
}
2525

2626
dependencies {
27-
api 'com.marklogic:ml-javaclient-util:4.7.0'
28-
api 'org.springframework:spring-web:5.3.31'
27+
api 'com.marklogic:ml-javaclient-util:4.8.0'
28+
api 'org.springframework:spring-web:5.3.34'
2929
api 'com.fasterxml.jackson.core:jackson-databind:2.15.3'
3030

3131
implementation 'jaxen:jaxen:1.2.0'
@@ -37,7 +37,7 @@ dependencies {
3737
implementation 'org.jdom:jdom2:2.0.6.1'
3838

3939
// Forcing httpclient to use this to address https://snyk.io/vuln/SNYK-JAVA-COMMONSCODEC-561518
40-
implementation 'commons-codec:commons-codec:1.15'
40+
implementation 'commons-codec:commons-codec:1.16.1'
4141

4242
// For EqualsBuilder; added in 3.8.1 to support detecting if a mimetype's properties have changed or not
4343
implementation "org.apache.commons:commons-lang3:3.14.0"
@@ -57,15 +57,15 @@ dependencies {
5757
compileOnly "com.beust:jcommander:1.82"
5858
compileOnly "ch.qos.logback:logback-classic:1.3.14"
5959

60-
testImplementation 'org.junit.jupiter:junit-jupiter:5.10.1'
61-
testImplementation 'org.springframework:spring-test:5.3.31'
62-
testImplementation 'commons-io:commons-io:2.15.1'
60+
testImplementation 'org.junit.jupiter:junit-jupiter:5.10.2'
61+
testImplementation 'org.springframework:spring-test:5.3.34'
62+
testImplementation 'commons-io:commons-io:2.16.1'
6363
testImplementation 'xmlunit:xmlunit:1.6'
6464

6565
// Forcing Spring to use logback for testing instead of commons-logging
6666
testImplementation "ch.qos.logback:logback-classic:1.3.14"
67-
testImplementation "org.slf4j:jcl-over-slf4j:1.7.36"
68-
testImplementation "org.slf4j:slf4j-api:1.7.36"
67+
testImplementation "org.slf4j:jcl-over-slf4j:2.0.13"
68+
testImplementation "org.slf4j:slf4j-api:2.0.13"
6969
}
7070

7171
// This ensures that Gradle includes in the published jar any non-java files under src/main/java

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ It is not intended to be used to build this project.
1212
<modelVersion>4.0.0</modelVersion>
1313
<groupId>com.marklogic</groupId>
1414
<artifactId>ml-app-deployer</artifactId>
15-
<version>4.6.1</version>
15+
<version>4.8.0</version>
1616
<name>com.marklogic:ml-app-deployer</name>
1717
<description>Java client for the MarkLogic REST Management API and for deploying applications to MarkLogic</description>
1818
<url>https://github.com/marklogic/ml-app-deployer</url>

src/main/java/com/marklogic/appdeployer/ConfigDir.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,4 +262,8 @@ public File getProjectDir() {
262262
public File getSecureCredentialsDir() {
263263
return new File(getSecurityDir(), "secure-credentials");
264264
}
265+
266+
public File getCredentialsDir() {
267+
return new File(getSecurityDir(), "credentials");
268+
}
265269
}

src/main/java/com/marklogic/appdeployer/DefaultAppConfigFactory.java

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717

1818
import com.marklogic.appdeployer.util.JavaClientUtil;
1919
import com.marklogic.client.DatabaseClient;
20-
import com.marklogic.client.DatabaseClientFactory;
2120
import com.marklogic.client.ext.SecurityContextType;
2221
import com.marklogic.mgmt.util.PropertySource;
2322
import com.marklogic.mgmt.util.PropertySourceFactory;
@@ -250,8 +249,8 @@ public void initialize() {
250249
* different port, in which case you can set this to that port.
251250
*/
252251
propertyConsumerMap.put("mlAppServicesPort", (config, prop) -> {
253-
logger.info("App services port: " + prop);
254-
config.setAppServicesPort(Integer.parseInt(prop));
252+
logger.info("App services port: {}", prop);
253+
config.setAppServicesPort(propertyToInteger("mlAppServicesPort", prop));
255254
});
256255
/**
257256
* The username and password for a ML user with the rest-admin role that is used for e.g. loading
@@ -376,7 +375,7 @@ public void initialize() {
376375
*/
377376
propertyConsumerMap.put("mlRestPort", (config, prop) -> {
378377
logger.info("App REST port: " + prop);
379-
config.setRestPort(Integer.parseInt(prop));
378+
config.setRestPort(propertyToInteger("mlRestPort", prop));
380379
});
381380
/**
382381
* The username and password for a ML user with the rest-admin role. This user is used for operations against the
@@ -559,7 +558,7 @@ public void initialize() {
559558
*/
560559
propertyConsumerMap.put("mlTestRestPort", (config, prop) -> {
561560
logger.info("Test REST port: " + prop);
562-
config.setTestRestPort(Integer.parseInt(prop));
561+
config.setTestRestPort(propertyToInteger("mlTestRestPort", prop));
563562
});
564563

565564
propertyConsumerMap.put("mlTestRestServerName", (config, prop) -> {
@@ -605,7 +604,7 @@ public void initialize() {
605604

606605
propertyConsumerMap.put("mlContentForestsPerHost", (config, prop) -> {
607606
logger.info("Content forests per host: " + prop);
608-
config.setContentForestsPerHost(Integer.parseInt(prop));
607+
config.setContentForestsPerHost(propertyToInteger("mlContentForestsPerHost", prop));
609608
});
610609

611610
propertyConsumerMap.put("mlCreateForests", (config, prop) -> {
@@ -620,7 +619,7 @@ public void initialize() {
620619
logger.info("Forests per host: " + prop);
621620
String[] tokens = prop.split(",");
622621
for (int i = 0; i < tokens.length; i += 2) {
623-
config.getForestCounts().put(tokens[i], Integer.parseInt(tokens[i + 1]));
622+
config.getForestCounts().put(tokens[i], propertyToInteger("mlForestsPerHost", tokens[i + 1]));
624623
}
625624
});
626625

@@ -633,7 +632,7 @@ public void initialize() {
633632
String[] tokens = prop.split(",");
634633
Map<String, Integer> map = new HashMap<>();
635634
for (int i = 0; i < tokens.length; i += 2) {
636-
map.put(tokens[i], Integer.parseInt(tokens[i + 1]));
635+
map.put(tokens[i], propertyToInteger("mlDatabaseNamesAndReplicaCounts", tokens[i + 1]));
637636
}
638637
config.setDatabaseNamesAndReplicaCounts(map);
639638
});
@@ -884,12 +883,12 @@ public void initialize() {
884883

885884
propertyConsumerMap.put("mlModulesLoaderThreadCount", (config, prop) -> {
886885
logger.info("Modules loader thread count: " + prop);
887-
config.setModulesLoaderThreadCount(Integer.parseInt(prop));
886+
config.setModulesLoaderThreadCount(propertyToInteger("mlModulesLoaderThreadCount", prop));
888887
});
889888

890889
propertyConsumerMap.put("mlModulesLoaderBatchSize", (config, prop) -> {
891890
logger.info("Modules loader batch size: " + prop);
892-
config.setModulesLoaderBatchSize(Integer.parseInt(prop));
891+
config.setModulesLoaderBatchSize(propertyToInteger("mlModulesLoaderBatchSize", prop));
893892
});
894893

895894
propertyConsumerMap.put("mlCascadeCollections", (config, prop) -> {
@@ -1000,7 +999,7 @@ public void initialize() {
1000999
protected void registerDataLoadingProperties() {
10011000
propertyConsumerMap.put("mlDataBatchSize", (config, prop) -> {
10021001
logger.info("Batch size for loading data: " + prop);
1003-
config.getDataConfig().setBatchSize(Integer.parseInt(prop));
1002+
config.getDataConfig().setBatchSize(propertyToInteger("mlDataBatchSize", prop));
10041003
});
10051004

10061005
propertyConsumerMap.put("mlDataCollections", (config, prop) -> {

src/main/java/com/marklogic/appdeployer/command/CommandMapBuilder.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,7 @@ private void addCommandsThatDoNotWriteToDatabases(Map<String, List<Command>> map
161161
securityCommands.add(new InsertCertificateHostsTemplateCommand());
162162
securityCommands.add(new DeployExternalSecurityCommand());
163163
securityCommands.add(new DeploySecureCredentialsCommand());
164+
securityCommands.add(new DeployCredentialsCommand());
164165
securityCommands.add(new DeployPrivilegesCommand());
165166
securityCommands.add(new DeployPrivilegeRolesCommand());
166167
securityCommands.add(new DeployProtectedCollectionsCommand());

src/main/java/com/marklogic/appdeployer/command/SortOrderConstants.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ public abstract class SortOrderConstants {
3333

3434
public static Integer DEPLOY_EXTERNAL_SECURITY = 35;
3535
public static Integer DEPLOY_SECURE_CREDENTIALS = 36;
36+
public static Integer DEPLOY_CREDENTIALS = 37;
3637
public static Integer DEPLOY_PROTECTED_COLLECTIONS = 40;
3738
public static Integer DEPLOY_MIMETYPES = 45;
3839

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*
2+
* Copyright (c) 2023 MarkLogic Corporation
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package com.marklogic.appdeployer.command.security;
17+
18+
import com.marklogic.appdeployer.command.AbstractResourceCommand;
19+
import com.marklogic.appdeployer.command.CommandContext;
20+
import com.marklogic.appdeployer.command.SortOrderConstants;
21+
import com.marklogic.appdeployer.command.UndoableCommand;
22+
import com.marklogic.mgmt.resource.ResourceManager;
23+
import com.marklogic.mgmt.resource.security.CredentialsManager;
24+
25+
import java.io.File;
26+
27+
public class DeployCredentialsCommand extends AbstractResourceCommand implements UndoableCommand {
28+
29+
public DeployCredentialsCommand() {
30+
setExecuteSortOrder(SortOrderConstants.DEPLOY_CREDENTIALS);
31+
setUndoSortOrder(SortOrderConstants.DEPLOY_CREDENTIALS);
32+
}
33+
34+
@Override
35+
protected File[] getResourceDirs(CommandContext context) {
36+
return findResourceDirs(context, configDir -> configDir.getCredentialsDir());
37+
}
38+
39+
@Override
40+
protected ResourceManager getResourceManager(CommandContext context) {
41+
return new CredentialsManager(context.getManageClient());
42+
}
43+
}

src/main/java/com/marklogic/mgmt/DefaultManageConfigFactory.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ public void initialize() {
5656

5757
propertyConsumerMap.put("mlManagePort", (config, prop) -> {
5858
logger.info("Manage port: " + prop);
59-
config.setPort(Integer.parseInt(prop));
59+
config.setPort(propertyToInteger("mlManagePort", prop));
6060
});
6161

6262
propertyConsumerMap.put("mlManageAuthentication", (config, prop) -> {

src/main/java/com/marklogic/mgmt/ManageClient.java

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import com.marklogic.rest.util.RestConfig;
2323
import com.marklogic.rest.util.RestTemplateUtil;
2424
import org.jdom2.Namespace;
25+
import org.springframework.core.io.Resource;
2526
import org.springframework.http.*;
2627
import org.springframework.util.LinkedMultiValueMap;
2728
import org.springframework.util.MultiValueMap;
@@ -204,16 +205,28 @@ public String getJsonAsSecurityUser(String path) {
204205
.getBody();
205206
}
206207

207-
public void delete(String path) {
208+
public void delete(String path, String... headerNamesAndValues) {
208209
logRequest(path, "", "DELETE");
209-
getRestTemplate().delete(buildUri(path));
210+
delete(getRestTemplate(), path, headerNamesAndValues);
210211
}
211212

212-
public void deleteAsSecurityUser(String path) {
213+
public void deleteAsSecurityUser(String path, String... headerNamesAndValues) {
213214
logSecurityUserRequest(path, "", "DELETE");
214-
getSecurityUserRestTemplate().delete(buildUri(path));
215+
delete(getSecurityUserRestTemplate(), path, headerNamesAndValues);
215216
}
216217

218+
private void delete(RestTemplate restTemplate, String path, String... headerNamesAndValues) {
219+
URI uri = buildUri(path);
220+
HttpHeaders headers = new HttpHeaders();
221+
if (headerNamesAndValues != null) {
222+
for (int i = 0; i < headerNamesAndValues.length; i += 2) {
223+
headers.add(headerNamesAndValues[i], headerNamesAndValues[i + 1]);
224+
}
225+
}
226+
HttpEntity<Resource> entity = new HttpEntity<>(null, headers);
227+
restTemplate.exchange(uri, HttpMethod.DELETE, entity, String.class);
228+
}
229+
217230
/**
218231
* Per #187 and version 3.1.0, when an HttpEntity is constructed with a JSON payload, this method will check to see
219232
* if it should "clean" the JSON via the Jackson library, which is primarily intended for removing comments from

src/main/java/com/marklogic/mgmt/admin/AdminManager.java

Lines changed: 38 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import com.marklogic.rest.util.Fragment;
2020
import com.marklogic.rest.util.RestConfig;
2121
import com.marklogic.rest.util.RestTemplateUtil;
22+
import org.apache.commons.lang3.tuple.ImmutablePair;
2223
import org.springframework.core.io.ByteArrayResource;
2324
import org.springframework.core.io.Resource;
2425
import org.springframework.http.*;
@@ -80,8 +81,9 @@ public boolean execute() {
8081
HttpHeaders headers = new HttpHeaders();
8182
headers.setContentType(MediaType.APPLICATION_JSON);
8283
HttpEntity<String> entity = new HttpEntity<>(payload, headers);
84+
ImmutablePair<Boolean, Boolean> credentialsStatus = checkCredentialsAndReplaceNulls(adminConfig);
8385
try {
84-
ResponseEntity<String> response = getRestTemplate().exchange(uri, HttpMethod.POST, entity, String.class);
86+
ResponseEntity<String> response = getRestTemplate().exchange(uri, HttpMethod.POST, entity, String.class);
8587
logger.info("Initialization response: " + response);
8688
// According to http://docs.marklogic.com/REST/POST/admin/v1/init, a 202 is sent back in the event a
8789
// restart is needed. A 400 or 401 will be thrown as an error by RestTemplate.
@@ -98,12 +100,14 @@ public boolean execute() {
98100
logger.error("Caught error, response body: " + body);
99101
throw hcee;
100102
}
101-
}
103+
} finally {
104+
restoreCredentials(adminConfig, credentialsStatus);
105+
}
102106
}
103107
});
104108
}
105109

106-
public void installAdmin() {
110+
public void installAdmin() {
107111
installAdmin(null, null);
108112
}
109113

@@ -130,8 +134,9 @@ public boolean execute() {
130134
HttpHeaders headers = new HttpHeaders();
131135
headers.setContentType(MediaType.APPLICATION_JSON);
132136
HttpEntity<String> entity = new HttpEntity<>(payload, headers);
137+
ImmutablePair<Boolean, Boolean> credentialsStatus = checkCredentialsAndReplaceNulls(adminConfig);
133138
try {
134-
ResponseEntity<String> response = getRestTemplate().exchange(uri, HttpMethod.POST, entity, String.class);
139+
ResponseEntity<String> response = getRestTemplate().exchange(uri, HttpMethod.POST, entity, String.class);
135140
logger.info("Admin installation response: " + response);
136141
// According to http://docs.marklogic.com/REST/POST/admin/v1/init, a 202 is sent back in the event a
137142
// restart is needed. A 400 or 401 will be thrown as an error by RestTemplate.
@@ -143,6 +148,8 @@ public boolean execute() {
143148
return false;
144149
}
145150
throw hcee;
151+
} finally {
152+
restoreCredentials(adminConfig, credentialsStatus);
146153
}
147154
}
148155
});
@@ -323,4 +330,31 @@ public RestTemplate getRestTemplate() {
323330
}
324331
return this.restTemplate;
325332
}
333+
334+
private ImmutablePair<Boolean, Boolean> checkCredentialsAndReplaceNulls(AdminConfig adminConfig) {
335+
boolean setNullUsername = false;
336+
boolean setNullPassword = false;
337+
if (adminConfig.getUsername() == null) {
338+
adminConfig.setUsername("");
339+
setNullUsername = true;
340+
this.restTemplate = null;
341+
}
342+
if (adminConfig.getPassword() == null) {
343+
adminConfig.setPassword("");
344+
setNullPassword = true;
345+
this.restTemplate = null;
346+
}
347+
return new ImmutablePair<>(setNullUsername, setNullPassword);
348+
}
349+
350+
private void restoreCredentials(AdminConfig adminConfig, ImmutablePair<Boolean, Boolean> credentialsStatus) {
351+
if (credentialsStatus.getLeft()) {
352+
adminConfig.setUsername(null);
353+
this.restTemplate = null;
354+
}
355+
if (credentialsStatus.getRight()) {
356+
adminConfig.setPassword(null);
357+
this.restTemplate = null;
358+
}
359+
}
326360
}

0 commit comments

Comments
 (0)