diff --git a/build.gradle b/build.gradle index c6a46467..3d8fb096 100644 --- a/build.gradle +++ b/build.gradle @@ -93,7 +93,7 @@ subprojects { api "org.slf4j:slf4j-simple:${project.ext.slf4jVersion}" // --- Security Overrides --- - // Pulled in by org.apache.httpcomponents:httpclient:4.5.14 + // Transitive dependency of org.apache.httpcomponents:httpclient:4.5.14 api("commons-codec:commons-codec:1.14") { because "Fixes Low Severity vulnerability SNYK-JAVA-COMMONSCODEC-561518" } @@ -104,10 +104,10 @@ subprojects { testImplementation "org.junit.jupiter:junit-jupiter-api:${project.ext.junitVersion}" } - test { useJUnitPlatform() } - compileJava { options.compilerArgs << "-parameters" } + test { useJUnitPlatform() } + javadoc { classpath = configurations.compileClasspath options { @@ -124,7 +124,7 @@ subprojects { if (it.name != platformProject) { publishing { publications { - maven(MavenPublication) { + register("maven", MavenPublication) { from components.java } } @@ -193,11 +193,11 @@ nexusPublishing { } } -task spotlessApply { +tasks.register("spotlessApply") { dependsOn subprojects.findAll { it.name != platformProject }.collect { "${it.path}:spotlessApply" } } -task subdependencies { +tasks.register("subdependencies") { dependsOn subprojects.findAll { it.name != platformProject }.collect { "${it.path}:dependencies" } } diff --git a/common/src/main/java/com/mx/path/core/common/connect/ConnectionSettings.java b/common/src/main/java/com/mx/path/core/common/connect/ConnectionSettings.java index c1234359..18f184a9 100644 --- a/common/src/main/java/com/mx/path/core/common/connect/ConnectionSettings.java +++ b/common/src/main/java/com/mx/path/core/common/connect/ConnectionSettings.java @@ -54,7 +54,7 @@ default void describe(ObjectMap description) { Duration getRequestTimeout(); /** - * @return true, if host name should be checked against the certificate + * @return true if host name should NOT be checked against the certificate, false otherwise */ boolean getSkipHostNameVerify(); diff --git a/common/src/main/java/com/mx/path/core/common/reflection/Fields.java b/common/src/main/java/com/mx/path/core/common/reflection/Fields.java index 68476318..163caf5b 100644 --- a/common/src/main/java/com/mx/path/core/common/reflection/Fields.java +++ b/common/src/main/java/com/mx/path/core/common/reflection/Fields.java @@ -105,6 +105,10 @@ public static Object coerceValueType(Class targetType, Object value) { return null; } + if (targetType == value.getClass()) { + return value; + } + if (targetType == byte.class || targetType == Byte.class) { return coerceToByte(value); } diff --git a/gateway/src/main/java/com/mx/path/gateway/configuration/ConnectionBinder.java b/gateway/src/main/java/com/mx/path/gateway/configuration/ConnectionBinder.java index b5703aa1..c83eea27 100644 --- a/gateway/src/main/java/com/mx/path/gateway/configuration/ConnectionBinder.java +++ b/gateway/src/main/java/com/mx/path/gateway/configuration/ConnectionBinder.java @@ -9,6 +9,7 @@ import com.mx.path.core.common.collection.ObjectMap; import com.mx.path.core.common.connect.AccessorConnectionSettings; import com.mx.path.core.common.gateway.GatewayException; +import com.mx.path.core.common.lang.Durations; import com.mx.path.core.common.lang.Strings; import com.mx.path.gateway.connect.filter.CallbacksFilter; import com.mx.path.gateway.connect.filter.ErrorHandlerFilter; @@ -64,7 +65,15 @@ public static AccessorConnectionSettings buildConnection(ObjectMap map, String c if (passwordString != null) { connection.keystorePassword(passwordString.toCharArray()); } - connection.skipHostNameVerify(Boolean.parseBoolean(String.valueOf(map.getMap(connectionName).get("skipHostNameVerify")))); + String connectTimeoutString = map.getMap(connectionName).getAsString("connectTimeout"); + if (connectTimeoutString != null) { + connection.connectTimeout(Durations.fromCompactString(connectTimeoutString)); + } + String requestTimeoutString = map.getMap(connectionName).getAsString("requestTimeout"); + if (requestTimeoutString != null) { + connection.requestTimeout(Durations.fromCompactString(requestTimeoutString)); + } + connection.skipHostNameVerify(map.getMap(connectionName).getAsBoolean("skipHostNameVerify", false)); // Default request filters // todo: Provide way to configure the request filters in connection block diff --git a/gateway/src/test/groovy/com/mx/path/gateway/configuration/ConnectionBinderTest.groovy b/gateway/src/test/groovy/com/mx/path/gateway/configuration/ConnectionBinderTest.groovy index 9b871d85..d819fbdc 100644 --- a/gateway/src/test/groovy/com/mx/path/gateway/configuration/ConnectionBinderTest.groovy +++ b/gateway/src/test/groovy/com/mx/path/gateway/configuration/ConnectionBinderTest.groovy @@ -1,11 +1,15 @@ package com.mx.path.gateway.configuration +import java.time.Duration + import com.mx.path.core.common.accessor.PathResponseStatus import com.mx.path.core.common.collection.ObjectMap +import com.mx.path.core.common.configuration.ConfigurationException import com.mx.path.core.common.gateway.GatewayException import com.mx.testing.binding.ConnectionWithBoundConfiguration import spock.lang.Specification +import spock.lang.Unroll class ConnectionBinderTest extends Specification { @@ -40,6 +44,9 @@ class ConnectionBinderTest extends Specification { certificateAlias == "alias" keystorePath == "path" keystorePassword.toString() == "password" + connectTimeout == null + requestTimeout == null + !skipHostNameVerify } } @@ -73,6 +80,9 @@ class ConnectionBinderTest extends Specification { put("certificateAlias", "alias") put("keystorePath", "path") put("keystorePassword", "password") + put("connectTimeout", "500ms") + put("requestTimeout", "20s") + put("skipHostNameVerify", true) } } @@ -85,7 +95,34 @@ class ConnectionBinderTest extends Specification { certificateAlias == "alias" keystorePath == "path" keystorePassword.toString() == "password" + connectTimeout == Duration.ofMillis(500) + requestTimeout == Duration.ofSeconds(20) + skipHostNameVerify + } + } + + @Unroll + def "build connection throws on invalid #fieldName format"(String fieldName) { + given: + def configuration = new ObjectMap().tap { + createMap("TestConnection").tap { + put("baseUrl", "url") + put(fieldName, "not-a-valid-duration") + } } + + when: + subject.buildConnection(configuration, "TestConnection") + + then: + def e = thrown(ConfigurationException) + e.message == "Invalid duration string: not-a-valid-duration" + + where: + fieldName << [ + "connectTimeout", + "requestTimeout" + ] } def "build connection and fail validation"() { diff --git a/utilities/build.gradle b/utilities/build.gradle index b3402751..014cff3a 100644 --- a/utilities/build.gradle +++ b/utilities/build.gradle @@ -8,7 +8,7 @@ dependencies { api "com.auth0:java-jwt:[4.5.1, 5.0.0)" // For JWT Parsing Library constraints { - // Pulled in by com.auth0:java-jwt:4.5.1 + // Transitive dependency of com.auth0:java-jwt:4.5.1 api("com.fasterxml.jackson.core:jackson-core:2.21.1") { because "Fixes High Severity vulnerability SNYK-JAVA-COMFASTERXMLJACKSONCORE-15365924" }