From 846077f939bcbd7fc80e9f490c8136a8d624554b Mon Sep 17 00:00:00 2001 From: djizatt-avio <146856310+djizatt-avio@users.noreply.github.com> Date: Thu, 14 Nov 2024 17:21:05 -0500 Subject: [PATCH] fix: Corrected logic to enable additional secure properties to be passed into a cloudhub v2 deployment request --- .../RuntimeFabricDeploymentRequest.groovy | 4 +- .../CloudhubV2DeploymentRequestTest.groovy | 265 +----------------- .../RuntimeFabricDeploymentRequestTest.groovy | 86 ++++-- 3 files changed, 79 insertions(+), 276 deletions(-) diff --git a/library/src/main/java/com/avioconsulting/mule/deployment/api/models/deployment/RuntimeFabricDeploymentRequest.groovy b/library/src/main/java/com/avioconsulting/mule/deployment/api/models/deployment/RuntimeFabricDeploymentRequest.groovy index b5efee8d..abf983e1 100644 --- a/library/src/main/java/com/avioconsulting/mule/deployment/api/models/deployment/RuntimeFabricDeploymentRequest.groovy +++ b/library/src/main/java/com/avioconsulting/mule/deployment/api/models/deployment/RuntimeFabricDeploymentRequest.groovy @@ -124,7 +124,9 @@ class RuntimeFabricDeploymentRequest extends ExchangeAppDeploymentRequest { def secureProps = [:] secureProps[CloudhubAppProperties.ANYPOINT_PLATFORM_CLIENT_SECRET] = anypointClientSecret secureProps[cloudhubAppProperties.cryptoKeyProperty] = cryptoKey - this.appSecureProperties + if (appSecureProperties) { + secureProps += appSecureProperties + } def result = [ // CloudHub's v2 API calls the Mule application the 'domain' diff --git a/library/src/test/java/com/avioconsulting/mule/deployment/api/models/CloudhubV2DeploymentRequestTest.groovy b/library/src/test/java/com/avioconsulting/mule/deployment/api/models/CloudhubV2DeploymentRequestTest.groovy index 3945e9e4..e23f896f 100644 --- a/library/src/test/java/com/avioconsulting/mule/deployment/api/models/CloudhubV2DeploymentRequestTest.groovy +++ b/library/src/test/java/com/avioconsulting/mule/deployment/api/models/CloudhubV2DeploymentRequestTest.groovy @@ -12,12 +12,7 @@ import static org.hamcrest.MatcherAssert.assertThat import static org.hamcrest.Matchers.equalTo import static org.hamcrest.Matchers.is -class CloudhubV2DeploymentRequestTest implements MavenInvoke { - - @BeforeAll - static void setup() { - buildApp() - } +class CloudhubV2DeploymentRequestTest { WorkerSpecRequest getWorkerSpecBase() { @@ -32,6 +27,8 @@ class CloudhubV2DeploymentRequestTest implements MavenInvoke { @Test void test_deploymentRequest_creation_ok() { + double vCoreSizeExpected = 0.1 + def request = new CloudhubV2DeploymentRequest('DEV', null, getWorkerSpecBase(), 'theKey', null, @@ -41,6 +38,8 @@ class CloudhubV2DeploymentRequestTest implements MavenInvoke { '1.2.3', 'f2ea2cb4-c600-4bb5-88e8-e952ff5591ee') + def appInfo = request.getCloudhubAppInfo() + request.with { assertThat appName.baseAppName, is(equalTo('new-app')) @@ -53,254 +52,8 @@ class CloudhubV2DeploymentRequestTest implements MavenInvoke { assertThat target, is(equalTo('us-west-2')) } + assertThat appInfo.target.deploymentSettings.enforceDeployingReplicasAcrossNodes, is(equalTo(true)) + assertThat appInfo.target.deploymentSettings.persistentObjectStore, is(equalTo(false)) + assertThat appInfo.application.vCores, is(equalTo(vCoreSizeExpected)) } - - /** - * This case validates that the application to deploy doesn't contain spaces in it's name - * example: appName="some app name" is not a valid name. appName="my-app" is a valid one. - */ - @Test - void spaces_in_nametest_deploymentRequest_appName_should_not_contain_spaces() { - - def exception = shouldFail { - new CloudhubV2DeploymentRequest('DEV', null, - getWorkerSpecBase(), - 'theKey', null, - 'theClientId', - 'theSecret', - new ApplicationName('some app name', 'client', null), - '4.2.2', - 'f2ea2cb4-c600-4bb5-88e8-e952ff5591ee') - } - - MatcherAssert.assertThat('fail', exception.message.contains("Name must be alphanumeric with dashes allowed within")) - } - - /** - * This case validates that a new CloudhubV2DeploymentRequest contains all the attributes correctly set by using - * getCloudhubAppInfo() method. - */ -// @Test - void test_getCloudhubAppInfo_only_required() { - - def request = new CloudhubV2DeploymentRequest('DEV', null, - getWorkerSpecBase(), - 'theKey', null, - 'theClientId', - 'theSecret', - new ApplicationName('new-app', null, null), - '2.2.9', - 'f2ea2cb4-c600-4bb5-88e8-e952ff5591ee') - def appInfo = request.getCloudhubAppInfo() - - assertThat appInfo, - is(equalTo([ - name : 'new-app', - application: [ - ref : [ - groupId : 'f2ea2cb4-c600-4bb5-88e8-e952ff5591ee', - artifactId: 'new-app', - version : '2.2.9', - packaging : "jar" - ], - desiredState : "STARTED", - configuration: [ - "mule.agent.application.properties.service": [ - applicationName : 'new-app', - properties : ['anypoint.platform.client_id' : 'theClientId', 'env': 'dev', - 'anypoint.platform.visualizer.layer': 'null'], - secureProperties: ['anypoint.platform.client_secret': 'theSecret', 'crypto.key': 'theKey'] - ] - ], - integrations : [ - services: [ - objectStoreV2: [ - enabled: true - - ] - ] - ], - "vCores" : VCoresSize.vCore1GB.vCoresSize - ], - target : [ - targetId : null, - provider : "MC", - deploymentSettings: [ - clustered : true, - updateStrategy : UpdateStrategy.rolling, - enforceDeployingReplicasAcrossNodes: true, - disableAmLogForwarding : false, - generateDefaultPublicUrl : true, - http : [ - inbound: [ - publicUrl : null, - pathRewrite : null, - lastMileSecurity : false, - forwardSslSession: false - ] - ], - jvm : [:], - outbound : [:], - runtime : [ - version : '4.2.2', - releaseChannel: 'LTS', - java : '8' - ], - tracingEnabled : false, - persistentObjectStore : false - ], - replicas : 1 - ]] - )) - } - -// @Test - void test_deploymentRequest_getCloudhubAppInfo_ok() { - - def request = new CloudhubV2DeploymentRequest('DEV', null, - new WorkerSpecRequest('us-west-2', - '4.2.2', - true, - true, - true, - UpdateStrategy.recreate, - true, - true, - VCoresSize.vCore15GB, - 13, - true, - false, - 20, - 700, - "testUrl", - "testpath", - "EDGE", - "17", - true), - 'theKey', null, - 'theClientId', - 'theSecret', - new ApplicationName('new-app', 'prefix', null), - '1.2.3', - 'new-group-id', - ["prop1": "value1", "prop2": "value2"], - ["secureProp1": "secureValue1", "secureProp2": "secureValue2"]) - - request.setAutoDiscoveryId("apiId", "123") - - def appInfo = request.getCloudhubAppInfo() - - assertThat appInfo, - is(equalTo([ - name : 'prefix-new-app', - application: [ - ref : [ - groupId : 'new-group-id', - artifactId: 'new-app', - version : '1.2.3', - packaging : "jar" - ], - desiredState : "STARTED", - configuration: [ - "mule.agent.application.properties.service": [ - applicationName : 'new-app', - properties : [ - apiId: '123', - prop1: 'value1', - prop2: 'value2' - ], - secureProperties: [ - secureProp1: 'secureValue1', - secureProp2: 'secureValue2' - ] - ] - ], - integrations : [ - services: [ - objectStoreV2: [ - enabled: true - ] - ] - ], - "vCores" : VCoresSize.vCore15GB.vCoresSize - ], - target : [ - targetId : null, - provider : "MC", - deploymentSettings: [ - persistentObjectStore : false, - clustered : true, - updateStrategy : UpdateStrategy.recreate, - enforceDeployingReplicasAcrossNodes: true, - disableAmLogForwarding : false, - generateDefaultPublicUrl : true, - http : [ - inbound: [ - publicUrl : 'testUrl', - pathRewrite : 'testpath', - forwardSslSession: true, - lastMileSecurity : true - ] - ], - jvm : [:], - outbound : [:], - runtime : [ - version : '4.2.2', - releaseChannel: 'EDGE', - java : '17' - ], - tracingEnabled : true - ], - replicas : 13 - ]])) - } - - /** - * This case validates that the name of application to deploy is not larger that the maximum required of 42 characters. - * however, this validation happens after build the final appName (normalizedAppName) like this: ${cloudhubAppprefix}-${appName}-${env} length should not larger than 42 characters. - * example: ApplicationName{ baseName=myVeryVeryVeryLargeApplicationName, prefix=someprefix, suffix=prod -> someprefix-myVeryVeryLargeApplicationName-prod is larger than 42 characters, it's not a valid name - */ - @Test - void test_deploymentRequest_appName_should_not_larger_than_required() { - - def appName = 'app-myVeryVeryVeryLargeApplicationName' - def prefix = 'client' - def environment = 'DEV' - def exception = shouldFail { - new CloudhubV2DeploymentRequest(environment, null, - new WorkerSpecRequest('us-west-2', - '4.2.2', null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null), - 'theKey', null, - 'theClientId', - 'theSecret', - new ApplicationName(appName, prefix, environment), - '4.2.2', - 'f2ea2cb4-c600-4bb5-88e8-e952ff5591ee') - } - - MatcherAssert.assertThat exception.message, - is(equalTo("Maximum size of application name is 42 and the provided name has 49 characters")) - } - - @Test - void test_deploymentRequest_appName_empty() { - - def appName = null - def environment = 'DEV' - def exception = shouldFail { - new CloudhubV2DeploymentRequest(environment, null, - new WorkerSpecRequest('us-west-2', - '4.2.2', null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null), - 'theKey', null, - 'theClientId', - 'theSecret', - new ApplicationName(appName, null, null), - '4.2.2', - 'f2ea2cb4-c600-4bb5-88e8-e952ff5591ee') - } - - MatcherAssert.assertThat exception.message, - is(equalTo("Property applicationName.baseAppName is required for CloudHub 2.0 and RTF applications")) - } - -} +} \ No newline at end of file diff --git a/library/src/test/java/com/avioconsulting/mule/deployment/api/models/RuntimeFabricDeploymentRequestTest.groovy b/library/src/test/java/com/avioconsulting/mule/deployment/api/models/RuntimeFabricDeploymentRequestTest.groovy index fa2098bd..1636ea2f 100644 --- a/library/src/test/java/com/avioconsulting/mule/deployment/api/models/RuntimeFabricDeploymentRequestTest.groovy +++ b/library/src/test/java/com/avioconsulting/mule/deployment/api/models/RuntimeFabricDeploymentRequestTest.groovy @@ -2,6 +2,7 @@ package com.avioconsulting.mule.deployment.api.models import com.avioconsulting.mule.MavenInvoke import com.avioconsulting.mule.deployment.api.models.deployment.ApplicationName +import com.avioconsulting.mule.deployment.api.models.deployment.CloudhubV2DeploymentRequest import com.avioconsulting.mule.deployment.api.models.deployment.RuntimeFabricDeploymentRequest import org.hamcrest.MatcherAssert import org.junit.jupiter.api.BeforeAll @@ -12,19 +13,18 @@ import static org.hamcrest.MatcherAssert.assertThat import static org.hamcrest.Matchers.equalTo import static org.hamcrest.Matchers.is -class RuntimeFabricDeploymentRequestTest implements MavenInvoke { +class RuntimeFabricDeploymentRequestTest { - @BeforeAll - static void setup() { - buildApp() + WorkerSpecRequest getWorkerSpecBase() { + return new WorkerSpecRequest('us-west-2', + '4.2.2', null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null); } @Test - void explicit() { + void test_deploymentRequest_creation_ok() { def request = new RuntimeFabricDeploymentRequest('DEV', null, - new WorkerSpecRequest('us-west-2', - '4.2.2', null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null), + getWorkerSpecBase(), 'theKey', null, 'theClientId', 'theSecret', @@ -50,8 +50,7 @@ class RuntimeFabricDeploymentRequestTest implements MavenInvoke { void derived_app_version_and_name_normal() { def request = new RuntimeFabricDeploymentRequest('DEV', null, - new WorkerSpecRequest('us-west-2', - '4.2.2', null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null), + getWorkerSpecBase(), 'theKey', null, 'theClientId', 'theSecret', @@ -80,12 +79,11 @@ class RuntimeFabricDeploymentRequestTest implements MavenInvoke { } @Test - void spaces_in_name() { + void test_deploymentRequest_appName_should_not_have_spaces_in_name() { def exception = shouldFail { new RuntimeFabricDeploymentRequest('DEV', null, - new WorkerSpecRequest('us-west-2', - '4.2.2', null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null), + getWorkerSpecBase(), 'theKey', null, 'theClientId', 'theSecret', @@ -95,12 +93,58 @@ class RuntimeFabricDeploymentRequestTest implements MavenInvoke { } MatcherAssert.assertThat('fail', exception.message.contains("Name must be alphanumeric with dashes allowed within")) } + /** + * This case validates that the name of application to deploy is not larger that the maximum required of 42 characters. + * however, this validation happens after build the final appName (normalizedAppName) like this: ${cloudhubAppprefix}-${appName}-${env} length should not larger than 42 characters. + * example: ApplicationName{ baseName=myVeryVeryVeryLargeApplicationName, prefix=someprefix, suffix=prod -> someprefix-myVeryVeryLargeApplicationName-prod is larger than 42 characters, it's not a valid name + */ + + @Test + void test_deploymentRequest_appName_should_not_larger_than_required() { + + def appName = 'app-myVeryVeryVeryLargeApplicationName' + def prefix = 'client' + def environment = 'DEV' + def exception = shouldFail { + new RuntimeFabricDeploymentRequest(environment, null, + getWorkerSpecBase(), + 'theKey', null, + 'theClientId', + 'theSecret', + new ApplicationName(appName, prefix, environment), + '4.2.2', + 'f2ea2cb4-c600-4bb5-88e8-e952ff5591ee') + } + + MatcherAssert.assertThat exception.message, + is(equalTo("Maximum size of application name is 42 and the provided name has 49 characters")) + } -// @Test + @Test + void test_deploymentRequest_appName_empty() { + + def appName = null + def environment = 'DEV' + def exception = shouldFail { + new RuntimeFabricDeploymentRequest(environment, null, + getWorkerSpecBase(), + 'theKey', null, + 'theClientId', + 'theSecret', + new ApplicationName(appName, null, null), + '4.2.2', + 'f2ea2cb4-c600-4bb5-88e8-e952ff5591ee') + } + + MatcherAssert.assertThat exception.message, + is(equalTo("Property applicationName.baseAppName is required for CloudHub 2.0 and RTF applications")) + } + + @Test void getCloudhubAppInfo_only_required() { def request = new RuntimeFabricDeploymentRequest('DEV', null, - new WorkerSpecRequest('us-west-2', '4.2.2', null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null), + getWorkerSpecBase(), 'theKey', null, 'theClientId', 'theSecret', @@ -125,7 +169,7 @@ class RuntimeFabricDeploymentRequestTest implements MavenInvoke { "mule.agent.application.properties.service": [ applicationName : 'new-app', properties : ['anypoint.platform.client_id' : 'theClientId', 'env': 'dev', - 'anypoint.platform.visualizer.layer': 'null'], + 'anypoint.platform.visualizer.layer': null], secureProperties: ['anypoint.platform.client_secret': 'theSecret', 'crypto.key': 'theKey'] ] ], @@ -177,7 +221,7 @@ class RuntimeFabricDeploymentRequestTest implements MavenInvoke { ])) } -// @Test + @Test void getCloudhubAppInfo_all_properties() { def request = new RuntimeFabricDeploymentRequest('DEV', null, @@ -199,8 +243,8 @@ class RuntimeFabricDeploymentRequestTest implements MavenInvoke { "testpath", "EDGE", "17", - true), null, - 'theKey', + true), 'theKey', + null, 'theClientId', 'theSecret', new ApplicationName('new-app', 'prefix', 'DEV'), @@ -229,10 +273,15 @@ class RuntimeFabricDeploymentRequestTest implements MavenInvoke { applicationName : 'new-app', properties : [ apiId: '123', + 'anypoint.platform.client_id': 'theClientId', + 'env': 'dev', + 'anypoint.platform.visualizer.layer': null, prop1: 'value1', prop2: 'value2' ], secureProperties: [ + 'anypoint.platform.client_secret': 'theSecret', + 'crypto.key': 'theKey', secureProp1: 'secureValue1', secureProp2: 'secureValue2' ] @@ -251,7 +300,6 @@ class RuntimeFabricDeploymentRequestTest implements MavenInvoke { targetId : null, provider : "MC", deploymentSettings: [ - persistentObjectStore : true, clustered : true, updateStrategy : UpdateStrategy.recreate, enforceDeployingReplicasAcrossNodes: true,