From fe3018e6cc19cc1704c32d481bebc1fb27cfdb4f Mon Sep 17 00:00:00 2001 From: "igor.petrenko" Date: Tue, 27 Feb 2024 08:34:10 +0200 Subject: [PATCH] OAP-244 Add "include" support to hocon configurations --- .../test/java/oap/application/KernelTest.java | 12 ++++++++++ .../application/KernelTest/testInclude-2.conf | 8 +++++++ .../application/KernelTest/testInclude.conf | 12 ++++++++++ .../java/oap/application/Configuration.java | 3 +-- oap-stdlib/src/main/java/oap/json/Binder.java | 15 ++++++------ .../HoconFactoryWithSystemProperties.java | 24 +++++++++++++++++++ pom.xml | 4 ++-- 7 files changed, 66 insertions(+), 12 deletions(-) create mode 100644 oap-application/oap-application-test/src/test/resources/oap/application/KernelTest/testInclude-2.conf create mode 100644 oap-application/oap-application-test/src/test/resources/oap/application/KernelTest/testInclude.conf diff --git a/oap-application/oap-application-test/src/test/java/oap/application/KernelTest.java b/oap-application/oap-application-test/src/test/java/oap/application/KernelTest.java index 8a2fa1eaf0..dcb9ba5b22 100644 --- a/oap-application/oap-application-test/src/test/java/oap/application/KernelTest.java +++ b/oap-application/oap-application-test/src/test/java/oap/application/KernelTest.java @@ -416,6 +416,7 @@ public void testFinalParameter() { try { TestDirectoryFixture.deployTestData( getClass() ); + assertThatThrownBy( () -> kernel.start( Map.of( "boot.main", "testFinalParameter" ) ) ) .isInstanceOf( ApplicationException.class ) .hasMessageContaining( "al=[val1], a=new value" ); @@ -425,6 +426,17 @@ public void testFinalParameter() { } } + @Test + public void testInclude() { + try( var kernel = new Kernel( + List.of( urlOfTestResource( getClass(), "testInclude.conf" ) ) ) ) { + kernel.start( Map.of( "boot.main", "testInclude" ) ); + + assertThat( kernel.service( "testInclude.service3" ).get().name ).isEqualTo( "a" ); + assertThat( kernel.service( "testInclude.service32" ).get().name ).isEqualTo( "b" ); + } + } + public enum Enum { ONE, TWO } diff --git a/oap-application/oap-application-test/src/test/resources/oap/application/KernelTest/testInclude-2.conf b/oap-application/oap-application-test/src/test/resources/oap/application/KernelTest/testInclude-2.conf new file mode 100644 index 0000000000..f414ddfd91 --- /dev/null +++ b/oap-application/oap-application-test/src/test/resources/oap/application/KernelTest/testInclude-2.conf @@ -0,0 +1,8 @@ +services { + service32 { + implementation = oap.application.KernelTest.Service3 + parameters { + name = b + } + } +} \ No newline at end of file diff --git a/oap-application/oap-application-test/src/test/resources/oap/application/KernelTest/testInclude.conf b/oap-application/oap-application-test/src/test/resources/oap/application/KernelTest/testInclude.conf new file mode 100644 index 0000000000..bd12e62baa --- /dev/null +++ b/oap-application/oap-application-test/src/test/resources/oap/application/KernelTest/testInclude.conf @@ -0,0 +1,12 @@ +name = testInclude + +include required("testInclude-2.conf") + +services { + service3 { + implementation = oap.application.KernelTest.Service3 + parameters { + name = a + } + } +} diff --git a/oap-application/oap-application/src/main/java/oap/application/Configuration.java b/oap-application/oap-application/src/main/java/oap/application/Configuration.java index 4684fcf56b..294ebaa9be 100644 --- a/oap-application/oap-application/src/main/java/oap/application/Configuration.java +++ b/oap-application/oap-application/src/main/java/oap/application/Configuration.java @@ -26,7 +26,6 @@ import lombok.SneakyThrows; import lombok.ToString; import oap.io.Resources; -import oap.io.content.ContentReader; import oap.json.Binder; import oap.util.Lists; import oap.util.Strings; @@ -63,7 +62,7 @@ public List urlsFromClassPath() { @SneakyThrows public T fromUrl( URL url ) { - return fromString( ContentReader.read( url, ContentReader.ofString() ), Binder.Format.of( url, true ) ); + return Binder.Format.of( url, true ).binder.unmarshal( clazz, url ); } public T fromResource( Class contextClass, String name ) { diff --git a/oap-stdlib/src/main/java/oap/json/Binder.java b/oap-stdlib/src/main/java/oap/json/Binder.java index caf061e159..70cc62b0c9 100644 --- a/oap-stdlib/src/main/java/oap/json/Binder.java +++ b/oap-stdlib/src/main/java/oap/json/Binder.java @@ -237,6 +237,11 @@ public static void update( Object obj, String json ) { } } + private static String getLimitation( String json ) { + if( json != null && json.length() > 20 ) return json.substring( 0, 20 ) + "..."; + return json; + } + public ObjectMapper getMapper() { return mapper; } @@ -405,8 +410,8 @@ public T unmarshal( Class clazz, Path path ) throws JsonException { } public T unmarshal( Class clazz, URL url ) throws JsonException { - try( var in = url.openStream() ) { - return unmarshal( clazz, in ); + try { + return mapper.readValue( url, clazz ); } catch( IOException e ) { throw new JsonException( "Cannot deserialize to class: " + clazz.getCanonicalName(), e ); } @@ -620,7 +625,6 @@ public ObjectWriter writerFor( TypeReference ref ) { return mapper.writerFor( ref ); } - @SuppressWarnings( "unchecked" ) public T clone( T object ) { return unmarshal( ( Class ) object.getClass(), marshal( object ) ); @@ -649,9 +653,4 @@ public static Format of( String path, boolean withSystemProperties ) { return withSystemProperties ? HOCON : HOCON_WO_SYSTEM_PROPERTIES; } } - - private static String getLimitation( String json ) { - if ( json != null && json.length() > 20 ) return json.substring( 0, 20 ) + "..."; - return json; - } } diff --git a/oap-stdlib/src/main/java/oap/json/HoconFactoryWithSystemProperties.java b/oap-stdlib/src/main/java/oap/json/HoconFactoryWithSystemProperties.java index 925b804b83..cc84aa04a4 100644 --- a/oap-stdlib/src/main/java/oap/json/HoconFactoryWithSystemProperties.java +++ b/oap-stdlib/src/main/java/oap/json/HoconFactoryWithSystemProperties.java @@ -31,10 +31,16 @@ import com.typesafe.config.ConfigException; import com.typesafe.config.ConfigFactory; import com.typesafe.config.ConfigParseOptions; +import lombok.SneakyThrows; import org.slf4j.Logger; +import java.io.File; import java.io.IOException; import java.io.Reader; +import java.net.URI; +import java.net.URL; +import java.net.URLClassLoader; +import java.nio.file.Paths; public class HoconFactoryWithSystemProperties extends HoconFactory { private final Logger log; @@ -44,9 +50,27 @@ public HoconFactoryWithSystemProperties( Logger log ) { // if( log.isTraceEnabled() ) System.setProperty( "config.trace", "loads" ); } + @SneakyThrows @Override protected HoconTreeTraversingParser _createParser( Reader r, IOContext ctxt ) throws IOException { var options = ConfigParseOptions.defaults(); + + Object rawContent = ctxt.contentReference().getRawContent(); + if( rawContent instanceof URL urlContext ) { + URL parentURL = Paths.get( urlContext.toURI() ).getParent().toUri().toURL(); + + options = options.setClassLoader( new URLClassLoader( new URL[] { parentURL } ) ); + } else if( rawContent instanceof File fileContext ) { + URL parentURL = Paths.get( fileContext.toURI() ).getParent().toUri().toURL(); + + options = options.setClassLoader( new URLClassLoader( new URL[] { parentURL } ) ); + } else if( rawContent instanceof URI uriContext ) { + URL parentURL = Paths.get( uriContext ).getParent().toUri().toURL(); + + options = options.setClassLoader( new URLClassLoader( new URL[] { parentURL } ) ); + } + + var config = ConfigFactory.parseReader( r, options ); var unresolvedConfig = config.withFallback( ConfigFactory.systemProperties() ); diff --git a/pom.xml b/pom.xml index 56174c16fb..7f20859011 100644 --- a/pom.xml +++ b/pom.xml @@ -54,7 +54,7 @@ - 21.15.0 + 21.15.1 21.0.0 21.0.1 @@ -109,7 +109,7 @@ Metrics.gauge( "task_queue_extra", Tags.of( "type", "current" ), this, 5 ); --> - 1.11.2 + 1.11.3 8.5.12 2.3.2