copy configuration files to etc/ directory on start up
authorMichael Vorburger <mike@vorburger.ch>
Wed, 31 Oct 2018 21:03:36 +0000 (22:03 +0100)
committerMichael Vorburger <mike@vorburger.ch>
Wed, 1 Jul 2020 23:37:39 +0000 (01:37 +0200)
and (by documented convention) have that etc/ dir on the CP

Signed-off-by: Michael Vorburger <mike@vorburger.ch>
.gitignore
README.md
src/main/java/org/opendaylight/controller/simple/ConfigReader.java

index 7ec03469260cbb21c6b4624e09e0e01cad8488c3..f75400f8ffc2d1f22f2f0fc79f11fa316c2381f3 100644 (file)
@@ -1,3 +1,4 @@
+etc/
 data/
 target/
 target-ide/
index 3ad5a275d41992c74f890784386a940b5e2013b5..5de8d11ab6d848b9c59becc25b808c67557952fd 100644 (file)
--- a/README.md
+++ b/README.md
@@ -16,8 +16,12 @@ This includes support for custom Karaf CLI Commands, based on the [ch.vorburger.
 
 ## How to use
 
-    mvn clean package
+    mvn -s .travis-maven-settings.xml clean package
     cd target/poc-1.5.0-SNAPSHOT-simple/poc-1.5.0-SNAPSHOT
-    java -cp "lib/*" org.opendaylight.genius.simple.GeniusMain
+    java -cp "etc/initial/*:lib/*" org.opendaylight.genius.simple.GeniusMain
 
 You'll also find a `poc-*-simple.tar` in `target/` which contains `lib/*`.
+
+Configuration files, like e.g. the `serviceutils-upgrade-config.xml`, can be changed in the `etc/initial` directory (which is on the beginning of the classpath), where they are copied to on the first run.
+
+The use of the custom `.travis-maven-settings.xml` is required due to [issue TBD](https://github.com/vorburger/opendaylight-simple/issues/37).
index 8121540abcdb9a63ef06034f57f8cab2fe703361..762db9dc8ad8ca8ea812f44875472738a1d5a3a9 100644 (file)
@@ -7,9 +7,13 @@
  */
 package org.opendaylight.controller.simple;
 
+import com.google.common.io.Files;
 import com.google.common.io.Resources;
+import java.io.File;
 import java.io.IOException;
 import java.net.URISyntaxException;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
 import java.util.Optional;
 import javax.inject.Inject;
 import javax.inject.Singleton;
@@ -22,6 +26,8 @@ import org.opendaylight.controller.blueprint.ext.DataStoreAppConfigDefaultXMLRea
 import org.opendaylight.mdsal.binding.dom.codec.api.BindingNormalizedNodeSerializer;
 import org.opendaylight.mdsal.dom.api.DOMSchemaService;
 import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.xml.sax.SAXException;
 
 /**
@@ -34,6 +40,11 @@ public class ConfigReader {
 
     // TODO this is currently only tested by the ServiceUtilsModuleTest; create a dedicated test when upstreamed
 
+    private static final Logger LOG = LoggerFactory.getLogger(ConfigReader.class);
+
+    // The idea is that this directory is *also* on the classpath, and *before* the main JARs (so that it can override)
+    private final File configurationFilesBaseDirectory = new File("etc/");
+
     private final DOMSchemaService schemaService;
     private final BindingNormalizedNodeSerializer bindingSerializer;
 
@@ -45,12 +56,32 @@ public class ConfigReader {
 
     public <T extends DataObject> T read(String resourcePathWithoutExtension, Class<T> yangType) {
         String xmlResourcePath = resourcePathWithoutExtension + ".xml";
-        ConfigURLProvider configURLProvider = appConfigFileName -> Optional
-                .of(Resources.getResource(ConfigReader.class, xmlResourcePath));
+        URL xmlResourceURL = Resources.getResource(ConfigReader.class, xmlResourcePath);
+
+        if (!xmlResourceURL.toExternalForm().contains("etc/")) {
+            File newConfigurationFile = new File(configurationFilesBaseDirectory, xmlResourcePath);
+            try {
+                File newConfigurationFileDirectory = newConfigurationFile.getParentFile();
+                if (newConfigurationFileDirectory.mkdirs()) {
+                    LOG.info("Created new directory for configuration files: {}", newConfigurationFileDirectory);
+                }
+                String configurationAsText = Resources.toString(xmlResourceURL, StandardCharsets.UTF_8);
+                Files.write(configurationAsText, newConfigurationFile, StandardCharsets.UTF_8);
+                LOG.warn("Copied configuration file to directory where it can be overriden on next start "
+                        + "(but this run isn't reading this, yet): {}", newConfigurationFile);
+            } catch (IOException e) {
+                LOG.error("Failed to copy configuration file {} to directory {}", xmlResourcePath,
+                        configurationFilesBaseDirectory, e);
+            }
+        }
+
         try {
-            return new DataStoreAppConfigDefaultXMLReader<T>(xmlResourcePath, xmlResourcePath, schemaService,
+            ConfigURLProvider configURLProvider = appConfigFileName -> Optional.of(xmlResourceURL);
+            T configuration = new DataStoreAppConfigDefaultXMLReader<T>(xmlResourcePath, xmlResourcePath, schemaService,
                     bindingSerializer, BindingContext.create(yangType.getName(), yangType, null), configURLProvider)
                             .createDefaultInstance();
+            LOG.info("Read configuration from {} : {}", xmlResourceURL, configuration);
+            return configuration;
         } catch (ConfigXMLReaderException | ParserConfigurationException | XMLStreamException | IOException
                 | SAXException | URISyntaxException e) {
             throw new IllegalArgumentException(