Skip to content

Commit

Permalink
fix: Globalconf reload failure recovery when the underlying conf vers…
Browse files Browse the repository at this point in the history
…ion should change

Refs: XRDDEV-1689
  • Loading branch information
andresrosenthal committed Oct 20, 2023
1 parent 3122ce4 commit ae9dca9
Show file tree
Hide file tree
Showing 23 changed files with 1,389 additions and 66 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -81,11 +81,11 @@ protected AbstractXmlConf() {
schemaValidator = null;
}

protected AbstractXmlConf(Class<? extends SchemaValidator> schemaValidator) {
protected AbstractXmlConf(Class<? extends SchemaValidator> schemaValidator) throws Exception {
this((String) null, schemaValidator);
}

protected AbstractXmlConf(String fileName, Class<? extends SchemaValidator> schemaValidator) {
protected AbstractXmlConf(String fileName, Class<? extends SchemaValidator> schemaValidator) throws Exception {
try {
this.schemaValidator = schemaValidator;
load(fileName);
Expand Down Expand Up @@ -114,7 +114,7 @@ protected AbstractXmlConf(AbstractXmlConf<T> original) {
* @param fileBytes
* @param schemaValidator
*/
protected AbstractXmlConf(byte[] fileBytes, Class<? extends SchemaValidator> schemaValidator) {
protected AbstractXmlConf(byte[] fileBytes, Class<? extends SchemaValidator> schemaValidator) throws Exception {
try {
this.schemaValidator = schemaValidator;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,10 @@ public ConfigurationDirectoryV2(String directoryPath, ConfigurationDirectoryV2 b
}

@Override
protected void loadPrivateParameters(Path instanceDir, Map<String, PrivateParametersV2> basePrivateParameters) {
protected void loadPrivateParameters(Path instanceDir, Map<String, PrivateParametersV2> basePrivateParameters) throws Exception {
String instanceId = instanceDir.getFileName().toString();

Path privateParametersPath = Paths.get(instanceDir.toString(),
ConfigurationConstants.FILE_NAME_PRIVATE_PARAMETERS);
Path privateParametersPath = Paths.get(instanceDir.toString(), ConfigurationConstants.FILE_NAME_PRIVATE_PARAMETERS);
if (Files.exists(privateParametersPath)) {
try {
log.trace("Loading private parameters from {}", privateParametersPath);
Expand All @@ -76,13 +75,15 @@ protected void loadPrivateParameters(Path instanceDir, Map<String, PrivateParame
privateParameters.put(instanceId, parametersToUse);
} catch (Exception e) {
log.error("Unable to load private parameters from {}", instanceDir, e);
throw e;
}
} else {
log.trace("Not loading private parameters from {}, file does not exist", privateParametersPath);
}
}

protected void loadSharedParameters(Path instanceDir, Map<String, SharedParametersV2> baseSharedParameters) {
protected void loadSharedParameters(Path instanceDir, Map<String, SharedParametersV2> baseSharedParameters)
throws Exception {
String instanceId = instanceDir.getFileName().toString();

Path sharedParametersPath = Paths.get(instanceDir.toString(),
Expand All @@ -106,6 +107,7 @@ protected void loadSharedParameters(Path instanceDir, Map<String, SharedParamete
sharedParameters.put(instanceId, parametersToUse);
} catch (Exception e) {
log.error("Unable to load shared parameters from {}", instanceDir, e);
throw e;
}
} else {
log.trace("Not loading shared parameters from {}, file does not exist", sharedParametersPath);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,10 @@ public ConfigurationDirectoryV3(String directoryPath, ConfigurationDirectoryV3 b
}

@Override
protected void loadPrivateParameters(Path instanceDir, Map<String, PrivateParametersV3> basePrivateParameters) {
protected void loadPrivateParameters(Path instanceDir, Map<String, PrivateParametersV3> basePrivateParameters) throws Exception {
String instanceId = instanceDir.getFileName().toString();

Path privateParametersPath = Paths.get(instanceDir.toString(),
ConfigurationConstants.FILE_NAME_PRIVATE_PARAMETERS);
Path privateParametersPath = Paths.get(instanceDir.toString(), ConfigurationConstants.FILE_NAME_PRIVATE_PARAMETERS);
if (Files.exists(privateParametersPath)) {
try {
log.trace("Loading private parameters from {}", privateParametersPath);
Expand All @@ -76,13 +75,14 @@ protected void loadPrivateParameters(Path instanceDir, Map<String, PrivateParame
privateParameters.put(instanceId, parametersToUse);
} catch (Exception e) {
log.error("Unable to load private parameters from {}", instanceDir, e);
throw e;
}
} else {
log.trace("Not loading private parameters from {}, file does not exist", privateParametersPath);
}
}

protected void loadSharedParameters(Path instanceDir, Map<String, SharedParametersV3> baseSharedParameters) {
protected void loadSharedParameters(Path instanceDir, Map<String, SharedParametersV3> baseSharedParameters) throws Exception {
String instanceId = instanceDir.getFileName().toString();

Path sharedParametersPath = Paths.get(instanceDir.toString(),
Expand All @@ -106,6 +106,7 @@ protected void loadSharedParameters(Path instanceDir, Map<String, SharedParamete
sharedParameters.put(instanceId, parametersToUse);
} catch (Exception e) {
log.error("Unable to load shared parameters from {}", instanceDir, e);
throw e;
}
} else {
log.trace("Not loading shared parameters from {}, file does not exist", sharedParametersPath);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,18 +52,18 @@ public class PrivateParametersV2 extends AbstractXmlConf<PrivateParametersType>
private final OffsetDateTime expiresOn;


// variable to prevent using load methods after constrution
// variable to prevent using load methods after construction
private boolean initCompleted;


PrivateParametersV2(byte[] content) {
PrivateParametersV2(byte[] content) throws Exception {
super(content, PrivateParametersSchemaValidatorV2.class);
expiresOn = OffsetDateTime.MAX;
privateParameters = converter.convert(confType);
initCompleted = true;
}

PrivateParametersV2(Path privateParametersPath, OffsetDateTime expiresOn) {
PrivateParametersV2(Path privateParametersPath, OffsetDateTime expiresOn) throws Exception {
super(privateParametersPath.toString(), PrivateParametersSchemaValidatorV2.class);
this.expiresOn = expiresOn;
privateParameters = converter.convert(confType);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,14 +57,14 @@ public class PrivateParametersV3 extends AbstractXmlConf<PrivateParametersType>
private boolean initCompleted;


PrivateParametersV3(byte[] content) {
PrivateParametersV3(byte[] content) throws Exception {
super(content, PrivateParametersSchemaValidatorV2.class);
expiresOn = OffsetDateTime.MAX;
privateParameters = converter.convert(confType);
initCompleted = true;
}

PrivateParametersV3(Path privateParametersPath, OffsetDateTime expiresOn) {
PrivateParametersV3(Path privateParametersPath, OffsetDateTime expiresOn) throws Exception {
super(privateParametersPath.toString(), PrivateParametersSchemaValidatorV2.class);
this.expiresOn = expiresOn;
privateParameters = converter.convert(confType);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,7 @@
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;

import java.io.IOException;
import java.nio.file.Path;
import java.security.cert.CertificateEncodingException;
import java.time.OffsetDateTime;

/**
Expand All @@ -60,23 +58,21 @@ public class SharedParametersV2 extends AbstractXmlConf<SharedParametersTypeV2>

// This constructor is used for simple verifications after configuration download.
// It does not initialise class fully!
SharedParametersV2(byte[] content) throws CertificateEncodingException, IOException {
SharedParametersV2(byte[] content) throws Exception {
super(content, SharedParametersSchemaValidatorV2.class);
expiresOn = OffsetDateTime.MAX;
sharedParameters = converter.convert(confType);
initCompleted = true;
}

public SharedParametersV2(Path sharedParametersPath, OffsetDateTime expiresOn)
throws CertificateEncodingException, IOException {
public SharedParametersV2(Path sharedParametersPath, OffsetDateTime expiresOn) throws Exception {
super(sharedParametersPath.toString(), SharedParametersSchemaValidatorV2.class);
this.expiresOn = expiresOn;
sharedParameters = converter.convert(confType);
initCompleted = true;
}

public SharedParametersV2(SharedParametersV2 original, OffsetDateTime newExpiresOn)
throws CertificateEncodingException, IOException {
public SharedParametersV2(SharedParametersV2 original, OffsetDateTime newExpiresOn) throws Exception {
super(original);
expiresOn = newExpiresOn;
sharedParameters = converter.convert(confType);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,7 @@
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;

import java.io.IOException;
import java.nio.file.Path;
import java.security.cert.CertificateEncodingException;
import java.time.OffsetDateTime;

@Getter(AccessLevel.PACKAGE)
Expand All @@ -57,23 +55,21 @@ public class SharedParametersV3 extends AbstractXmlConf<SharedParametersTypeV3>

// This constructor is used for simple verifications after configuration download.
// It does not initialise class fully!
SharedParametersV3(byte[] content) throws CertificateEncodingException, IOException {
SharedParametersV3(byte[] content) throws Exception {
super(content, SharedParametersSchemaValidatorV3.class);
expiresOn = OffsetDateTime.MAX;
sharedParameters = converter.convert(confType);
initCompleted = true;
}

public SharedParametersV3(Path sharedParametersPath, OffsetDateTime expiresOn)
throws CertificateEncodingException, IOException {
public SharedParametersV3(Path sharedParametersPath, OffsetDateTime expiresOn) throws Exception {
super(sharedParametersPath.toString(), SharedParametersSchemaValidatorV3.class);
this.expiresOn = expiresOn;
sharedParameters = converter.convert(confType);
initCompleted = true;
}

public SharedParametersV3(SharedParametersV3 original, OffsetDateTime newExpiresOn)
throws CertificateEncodingException, IOException {
public SharedParametersV3(SharedParametersV3 original, OffsetDateTime newExpiresOn) throws Exception {
super(original);
expiresOn = newExpiresOn;
sharedParameters = converter.convert(confType);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,10 +106,9 @@ public abstract class VersionableConfigurationDirectory<T extends PrivateParamet

/**
* Reloads the configuration directory. Only files that are new or have changed, are actually loaded.
* @throws Exception if an error occurs during reload
* @throws IOException if an error occurs during reload
*/
private void loadParameters(Map<String, T> basePrivateParams,
Map<String, S> baseSharedParams) throws Exception {
private void loadParameters(Map<String, T> basePrivateParams, Map<String, S> baseSharedParams) throws Exception {
log.trace("Reloading configuration from {}", path);

try (DirectoryStream<Path> stream = Files.newDirectoryStream(path, Files::isDirectory)) {
Expand Down Expand Up @@ -273,8 +272,8 @@ private String loadInstanceIdentifier() {
}
}

protected abstract void loadPrivateParameters(Path instanceDir, Map<String, T> basePrivateParameters);
protected abstract void loadPrivateParameters(Path instanceDir, Map<String, T> basePrivateParameters) throws Exception;

protected abstract void loadSharedParameters(Path instanceDir, Map<String, S> basePrivateParameters);
protected abstract void loadSharedParameters(Path instanceDir, Map<String, S> basePrivateParameters) throws Exception;

}
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
</documentation>
</annotation>
</element>
<element name="source" type="tns:ConfigurationSourceType" minOccurs="0" maxOccurs="unbounded">
<element name="source" type="tns:ConfigurationSourceType" maxOccurs="unbounded">
<annotation>
<documentation>
Describes one configuration source.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
*/
package ee.ria.xroad.common.conf.globalconf;

import ee.ria.xroad.common.CodedException;
import ee.ria.xroad.common.util.ExpectedCodedException;

import org.junit.Rule;
Expand All @@ -34,13 +35,16 @@
import java.util.List;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.jupiter.api.Assertions.assertThrows;

/**
* Tests to verify configuration directories are read correctly.
* Tests to verify v2 configuration directories are read correctly.
*/
public class ConfigurationDirectoryTest {
public class ConfigurationDirectoryV2Test {

@Rule
public ExpectedCodedException thrown = ExpectedCodedException.none();
Expand Down Expand Up @@ -92,11 +96,12 @@ public void readEmptyDirectoryV2() throws Exception {
* @throws Exception in case of any unexpected errors
*/
@Test
public void readMalformedDirectoryV2() throws Exception {
ConfigurationDirectoryV2 dir = new ConfigurationDirectoryV2("src/test/resources/globalconf_malformed");

assertNull(dir.getPrivate("foo"));
assertNull(dir.getShared("foo"));
public void readMalformedDirectoryV2() {
CodedException exception = assertThrows(
CodedException.class,
() -> new ConfigurationDirectoryV2("src/test/resources/globalconf_malformed")
);
assertEquals("Content is not allowed in prolog.", exception.getFaultString());
}

/**
Expand All @@ -112,22 +117,22 @@ public void readConfigurationFilesV2() throws Exception {

List<Path> configurationFiles = dir.getConfigurationFiles();

assertEquals(false, pathExists(configurationFiles, rootDir + "/instance-identifier"));
assertFalse(pathExists(configurationFiles, rootDir + "/instance-identifier"));

assertEquals(true, pathExists(configurationFiles, rootDir + "/bar/shared-params.xml"));
assertEquals(false, pathExists(configurationFiles, rootDir + "/bar/shared-params.xml.metadata"));
assertEquals(false, pathExists(configurationFiles, rootDir + "/bar/private-params.xml"));
assertEquals(false, pathExists(configurationFiles, rootDir + "/bar/private-params.xml.metadata"));
assertTrue(pathExists(configurationFiles, rootDir + "/bar/shared-params.xml"));
assertFalse(pathExists(configurationFiles, rootDir + "/bar/shared-params.xml.metadata"));
assertFalse(pathExists(configurationFiles, rootDir + "/bar/private-params.xml"));
assertFalse(pathExists(configurationFiles, rootDir + "/bar/private-params.xml.metadata"));

assertEquals(true, pathExists(configurationFiles, rootDir + "/EE/shared-params.xml"));
assertEquals(false, pathExists(configurationFiles, rootDir + "/EE/shared-params.xml.metadata"));
assertEquals(true, pathExists(configurationFiles, rootDir + "/EE/private-params.xml"));
assertEquals(false, pathExists(configurationFiles, rootDir + "/EE/private-params.xml.metadata"));
assertTrue(pathExists(configurationFiles, rootDir + "/EE/shared-params.xml"));
assertFalse(pathExists(configurationFiles, rootDir + "/EE/shared-params.xml.metadata"));
assertTrue(pathExists(configurationFiles, rootDir + "/EE/private-params.xml"));
assertFalse(pathExists(configurationFiles, rootDir + "/EE/private-params.xml.metadata"));

assertEquals(true, pathExists(configurationFiles, rootDir + "/foo/shared-params.xml"));
assertEquals(false, pathExists(configurationFiles, rootDir + "/foo/shared-params.xml.metadata"));
assertEquals(true, pathExists(configurationFiles, rootDir + "/foo/private-params.xml"));
assertEquals(false, pathExists(configurationFiles, rootDir + "/foo/private-params.xml.metadata"));
assertTrue(pathExists(configurationFiles, rootDir + "/foo/shared-params.xml"));
assertFalse(pathExists(configurationFiles, rootDir + "/foo/shared-params.xml.metadata"));
assertTrue(pathExists(configurationFiles, rootDir + "/foo/private-params.xml"));
assertFalse(pathExists(configurationFiles, rootDir + "/foo/private-params.xml.metadata"));
}

private boolean pathExists(List<Path> paths, String path) {
Expand Down
Loading

0 comments on commit ae9dca9

Please sign in to comment.