|
| 1 | +/* |
| 2 | + *Copyright (c) 2025, WSO2 LLC. (http://www.wso2.org) All Rights Reserved. |
| 3 | + * |
| 4 | + *WSO2 LLC. licenses this file to you under the Apache License, |
| 5 | + *Version 2.0 (the "License"); you may not use this file except |
| 6 | + *in compliance with the License. |
| 7 | + *You may obtain a copy of the License at |
| 8 | + * |
| 9 | + *http://www.apache.org/licenses/LICENSE-2.0 |
| 10 | + * |
| 11 | + *Unless required by applicable law or agreed to in writing, |
| 12 | + *software distributed under the License is distributed on an |
| 13 | + *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| 14 | + *KIND, either express or implied. See the License for the |
| 15 | + *specific language governing permissions and limitations |
| 16 | + *under the License. |
| 17 | + */ |
| 18 | + |
| 19 | +package org.wso2.am.integration.tests.tenantsync; |
| 20 | + |
| 21 | +import com.google.gson.Gson; |
| 22 | +import org.apache.commons.httpclient.HttpStatus; |
| 23 | +import org.junit.Assert; |
| 24 | +import org.testng.annotations.AfterClass; |
| 25 | +import org.testng.annotations.BeforeClass; |
| 26 | +import org.testng.annotations.DataProvider; |
| 27 | +import org.testng.annotations.Factory; |
| 28 | +import org.testng.annotations.Test; |
| 29 | +import org.wso2.am.integration.clients.admin.api.dto.KeyManagerListDTO; |
| 30 | +import org.wso2.am.integration.test.impl.RestAPIAdminImpl; |
| 31 | +import org.wso2.am.integration.test.utils.base.APIMIntegrationBaseTest; |
| 32 | +import org.wso2.am.integration.test.utils.base.APIMIntegrationConstants; |
| 33 | +import org.wso2.am.integration.test.utils.http.HTTPSClientUtils; |
| 34 | +import org.wso2.am.integration.tests.tenantsync.model.TenantManagementEvent; |
| 35 | +import org.wso2.carbon.automation.engine.annotations.ExecutionEnvironment; |
| 36 | +import org.wso2.carbon.automation.engine.annotations.SetEnvironment; |
| 37 | +import org.wso2.carbon.automation.engine.context.AutomationContext; |
| 38 | +import org.wso2.carbon.automation.engine.context.TestUserMode; |
| 39 | +import org.wso2.carbon.automation.test.utils.http.client.HttpResponse; |
| 40 | +import org.wso2.carbon.integration.common.utils.FileManager; |
| 41 | +import org.wso2.carbon.integration.common.utils.mgt.ServerConfigurationManager; |
| 42 | + |
| 43 | +import java.io.File; |
| 44 | +import java.util.Collections; |
| 45 | +import java.util.HashMap; |
| 46 | +import java.util.Map; |
| 47 | +import java.util.UUID; |
| 48 | + |
| 49 | +import static org.testng.Assert.assertEquals; |
| 50 | +import static org.testng.Assert.assertFalse; |
| 51 | + |
| 52 | +/** |
| 53 | + * Test Tenant related actions when tenant related notification received to APIM. |
| 54 | + */ |
| 55 | +@SetEnvironment(executionEnvironments = {ExecutionEnvironment.STANDALONE}) |
| 56 | +public class APIMTenantCreationNotificationTestCase extends APIMIntegrationBaseTest { |
| 57 | + |
| 58 | + private final String TENANT_DOMAIN = "testtenant.com"; |
| 59 | + private final String TENANT_ADMIN = "admin"; |
| 60 | + private final String TENANT_ADMIN_PWD = "admin123"; |
| 61 | + private final String TENANT_ADMIN_PWD_UPDATE = "admin456"; |
| 62 | + private final String TENANT_ADMIN_FIRST_NAME = "John"; |
| 63 | + private final String TENANT_ADMIN_LAST_NAME = "Doe"; |
| 64 | + private final String TENANT_ADMIN_EMAIL = "mymail@test.com"; |
| 65 | + |
| 66 | + public static final String ACTION_CREATE = "CREATE"; |
| 67 | + public static final String ACTION_UPDATE = "UPDATE"; |
| 68 | + public static final String ACTION_ACTIVATE = "ACTIVATE"; |
| 69 | + public static final String ACTION_DEACTIVATE = "DEACTIVATE"; |
| 70 | + public static final String EVENT_CREATE_TENANT_URI = |
| 71 | + "https://schemas.identity.wso2.org/events/tenant/event-type/tenantCreated"; |
| 72 | + public static final String EVENT_UPDATE_TENANT_URI = |
| 73 | + "https://schemas.identity.wso2.org/events/tenant/event-type/tenantOwnerUpdated"; |
| 74 | + public static final String EVENT_ACTIVATE_TENANT_URI = |
| 75 | + "https://schemas.identity.wso2.org/events/tenant/event-type/tenantActivated"; |
| 76 | + public static final String EVENT_INITIATOR = "SYSTEM"; |
| 77 | + |
| 78 | + Map<String, String> requestHeaders = new HashMap<>(); |
| 79 | + private String invokeURL; |
| 80 | + private RestAPIAdminImpl adminClient; |
| 81 | + |
| 82 | + @Factory(dataProvider = "userModeDataProvider") |
| 83 | + public APIMTenantCreationNotificationTestCase(TestUserMode userMode) { |
| 84 | + |
| 85 | + this.userMode = userMode; |
| 86 | + } |
| 87 | + |
| 88 | + @DataProvider |
| 89 | + public static Object[][] userModeDataProvider() { |
| 90 | + |
| 91 | + return new Object[][]{ |
| 92 | + {TestUserMode.SUPER_TENANT_ADMIN} |
| 93 | + }; |
| 94 | + } |
| 95 | + |
| 96 | + @BeforeClass(alwaysRun = true) |
| 97 | + public void setEnvironment() throws Exception { |
| 98 | + |
| 99 | + super.init(userMode); |
| 100 | + requestHeaders.put("Content-Type", "application/json"); |
| 101 | + requestHeaders.put("Authorization", "Basic YWRtaW46YWRtaW4="); |
| 102 | + requestHeaders.put("X-WSO2-KEY-MANAGER", "TENANT_MANAGEMENT"); |
| 103 | + |
| 104 | + invokeURL = keyManagerHTTPSURL + "internal/data/v1/notify"; |
| 105 | + } |
| 106 | + |
| 107 | + protected TenantManagementEvent buildPayload(String type, String eventURI, String tenantAdminPassword, |
| 108 | + boolean isActive) { |
| 109 | + |
| 110 | + // Start building the Tenant object first, as it's nested. |
| 111 | + TenantManagementEvent.Tenant.Builder tenantBuilder = new TenantManagementEvent.Tenant.Builder() |
| 112 | + .id("1234") |
| 113 | + .domain(TENANT_DOMAIN) |
| 114 | + .ref("https://localhost:9444/api/server/v1/tenants/1234"); |
| 115 | + |
| 116 | + // Conditionally build and add owner details for create/update events. |
| 117 | + if (EVENT_CREATE_TENANT_URI.equals(eventURI) |
| 118 | + || EVENT_UPDATE_TENANT_URI.equals(eventURI)) { |
| 119 | + |
| 120 | + TenantManagementEvent.Owner.Builder ownerBuilder = new TenantManagementEvent.Owner.Builder() |
| 121 | + .password(tenantAdminPassword) |
| 122 | + .email(TENANT_ADMIN_EMAIL) |
| 123 | + .firstname(TENANT_ADMIN_FIRST_NAME) |
| 124 | + .lastname(TENANT_ADMIN_LAST_NAME); |
| 125 | + |
| 126 | + // Username is only set during creation. |
| 127 | + if (EVENT_CREATE_TENANT_URI.equals(eventURI)) { |
| 128 | + ownerBuilder.username(TENANT_ADMIN); |
| 129 | + } |
| 130 | + |
| 131 | + // Build the owner and add it to the tenant builder. |
| 132 | + tenantBuilder.owners(Collections.singletonList(ownerBuilder.build())); |
| 133 | + } |
| 134 | + |
| 135 | + // Conditionally build and add lifecycle status for activation events. |
| 136 | + if (EVENT_ACTIVATE_TENANT_URI.equals(eventURI)) { |
| 137 | + TenantManagementEvent.LifecycleStatus lifecycleStatus = |
| 138 | + new TenantManagementEvent.LifecycleStatus.Builder() |
| 139 | + .activated(isActive) |
| 140 | + .build(); |
| 141 | + tenantBuilder.lifecycleStatus(lifecycleStatus); |
| 142 | + } |
| 143 | + |
| 144 | + // Build the final, immutable Tenant object. |
| 145 | + TenantManagementEvent.Tenant tenant = tenantBuilder.build(); |
| 146 | + |
| 147 | + // Build the EventDetail object, including the tenant. |
| 148 | + TenantManagementEvent.EventDetail createEventDetail = new TenantManagementEvent.EventDetail.Builder() |
| 149 | + .initiatorType(EVENT_INITIATOR) |
| 150 | + .action(type) |
| 151 | + .tenant(tenant) |
| 152 | + .build(); |
| 153 | + |
| 154 | + // Create the events map. |
| 155 | + Map<String, TenantManagementEvent.EventDetail> events = new HashMap<>(); |
| 156 | + events.put(eventURI, createEventDetail); |
| 157 | + |
| 158 | + // Build the final TenantManagementEvent and return it. |
| 159 | + return new TenantManagementEvent.Builder() |
| 160 | + .iss("https://localhost:9444") |
| 161 | + .jti(UUID.randomUUID().toString()) |
| 162 | + .iat(System.currentTimeMillis() / 1000L) |
| 163 | + .events(events) |
| 164 | + .build(); |
| 165 | + } |
| 166 | + |
| 167 | + /** |
| 168 | + * Tests tenant creation event. |
| 169 | + */ |
| 170 | + @Test(groups = {"wso2.am"}, description = "Test tenant creation event related tasks.") |
| 171 | + public void testCreateTenantEvent() throws Exception { |
| 172 | + |
| 173 | + String tenantCreatePayload = |
| 174 | + new Gson().toJson(buildPayload(ACTION_CREATE, EVENT_CREATE_TENANT_URI, TENANT_ADMIN_PWD, true)); |
| 175 | + HttpResponse serviceResponse = HTTPSClientUtils. |
| 176 | + doPost(invokeURL, requestHeaders, tenantCreatePayload); |
| 177 | + assertEquals(serviceResponse.getResponseCode(), HttpStatus.SC_OK, |
| 178 | + "Failed to invoke Notify endpoint for tenant creation"); |
| 179 | + |
| 180 | + adminClient = new RestAPIAdminImpl(TENANT_ADMIN,TENANT_ADMIN_PWD, TENANT_DOMAIN, adminURLHttps); |
| 181 | + KeyManagerListDTO keymanagers = adminClient.getKeyManagers(); |
| 182 | + |
| 183 | + assertEquals(1, keymanagers.getCount().intValue(), "Invalid Keymanager count"); |
| 184 | + assertEquals("WSO2-IS-7", keymanagers.getList().get(0).getType(), "Invalid Keymanager type"); |
| 185 | + |
| 186 | + |
| 187 | + } |
| 188 | + |
| 189 | + /** |
| 190 | + * Tests tenant update event. |
| 191 | + */ |
| 192 | + @Test(groups = { |
| 193 | + "wso2.am"}, description = "Test tenant update event related tasks.", dependsOnMethods = "testActivateTenantEvent") |
| 194 | + public void testUpdateTenantEvent() throws Exception { |
| 195 | + |
| 196 | + String tenantCreatePayload = |
| 197 | + new Gson().toJson(buildPayload(ACTION_UPDATE, EVENT_UPDATE_TENANT_URI, TENANT_ADMIN_PWD_UPDATE, true)); |
| 198 | + HttpResponse serviceResponse = HTTPSClientUtils. |
| 199 | + doPost(invokeURL, requestHeaders, tenantCreatePayload); |
| 200 | + assertEquals(serviceResponse.getResponseCode(), HttpStatus.SC_OK, |
| 201 | + "Failed to invoke Notify endpoint for tenant update"); |
| 202 | + |
| 203 | + try { |
| 204 | + adminClient = new RestAPIAdminImpl(TENANT_ADMIN,TENANT_ADMIN_PWD, TENANT_DOMAIN, adminURLHttps); |
| 205 | + Assert.assertTrue("Tenant admin password not updated", false); |
| 206 | + } catch (Exception e) { |
| 207 | + Assert.assertTrue("Tenant admin password is updated", true); |
| 208 | + } |
| 209 | + |
| 210 | + try { |
| 211 | + adminClient = new RestAPIAdminImpl(TENANT_ADMIN,TENANT_ADMIN_PWD_UPDATE, TENANT_DOMAIN, adminURLHttps); |
| 212 | + Assert.assertTrue("Tenant admin password is updated", true); |
| 213 | + |
| 214 | + KeyManagerListDTO keymanagers = adminClient.getKeyManagers(); |
| 215 | + |
| 216 | + assertEquals(1, keymanagers.getCount().intValue(), "Invalid Keymanager count"); |
| 217 | + assertEquals("WSO2-IS-7", keymanagers.getList().get(0).getType(), "Invalid Keymanager type"); |
| 218 | + |
| 219 | + } catch (Exception e) { |
| 220 | + Assert.assertTrue("Tenant admin password not is updated", false); |
| 221 | + } |
| 222 | + |
| 223 | + } |
| 224 | + |
| 225 | + /** |
| 226 | + * Tests tenant activate event. |
| 227 | + */ |
| 228 | + @Test(groups = { |
| 229 | + "wso2.am"}, description = "Test tenant activate event related tasks.", dependsOnMethods = "testDeActivateTenantEvent") |
| 230 | + public void testActivateTenantEvent() throws Exception { |
| 231 | + |
| 232 | + String tenantCreatePayload = |
| 233 | + new Gson().toJson(buildPayload(ACTION_ACTIVATE, EVENT_ACTIVATE_TENANT_URI, TENANT_ADMIN_PWD, true)); |
| 234 | + HttpResponse serviceResponse = HTTPSClientUtils. |
| 235 | + doPost(invokeURL, requestHeaders, tenantCreatePayload); |
| 236 | + assertEquals(serviceResponse.getResponseCode(), HttpStatus.SC_OK, |
| 237 | + "Failed to invoke Notify endpoint for tenant activation"); |
| 238 | + |
| 239 | + try { |
| 240 | + adminClient = new RestAPIAdminImpl(TENANT_ADMIN,TENANT_ADMIN_PWD, TENANT_DOMAIN, adminURLHttps); |
| 241 | + Assert.assertTrue("Tenant is activated", true); |
| 242 | + } catch (Exception e) { |
| 243 | + Assert.assertTrue("Tenant is still not activated", false); |
| 244 | + } |
| 245 | + } |
| 246 | + |
| 247 | + /** |
| 248 | + * Tests tenant deactivate event. |
| 249 | + */ |
| 250 | + @Test(groups = { |
| 251 | + "wso2.am"}, description = "Test tenant deactivate event related tasks.", dependsOnMethods = "testCreateTenantEvent") |
| 252 | + public void testDeActivateTenantEvent() throws Exception { |
| 253 | + |
| 254 | + String tenantCreatePayload = |
| 255 | + new Gson().toJson(buildPayload(ACTION_DEACTIVATE, EVENT_ACTIVATE_TENANT_URI, TENANT_ADMIN_PWD, false)); |
| 256 | + HttpResponse serviceResponse = HTTPSClientUtils. |
| 257 | + doPost(invokeURL, requestHeaders, tenantCreatePayload); |
| 258 | + assertEquals(serviceResponse.getResponseCode(), HttpStatus.SC_OK, |
| 259 | + "Failed to invoke Notify endpoint for tenant deactivation"); |
| 260 | + |
| 261 | + try { |
| 262 | + adminClient = new RestAPIAdminImpl(TENANT_ADMIN,TENANT_ADMIN_PWD, TENANT_DOMAIN, adminURLHttps); |
| 263 | + Assert.assertTrue("Tenant is not deactivated", false); |
| 264 | + } catch (Exception e) { |
| 265 | + Assert.assertTrue("Tenant is deactivated", true); |
| 266 | + } |
| 267 | + } |
| 268 | + |
| 269 | +} |
0 commit comments