From edf68ee3af69a230d6a87b0f5c4553da58d85759 Mon Sep 17 00:00:00 2001 From: Anagha Joshi Date: Thu, 15 Oct 2026 03:30:21 +0530 Subject: [PATCH] feat(transit-gateway): add dynamic_route_server (DRS) connection type support Signed-off-by: Anagha Joshi --- .../v1/TransitGatewayApis.java | 16 +- ...CreateTransitGatewayConnectionOptions.java | 48 +-- .../v1/model/TransitConnection.java | 13 +- .../model/TransitGatewayConnectionCust.java | 22 +- .../model/TransitGatewayTunnelCollection.java | 4 +- .../v1/TransitGatewayApisIT.java | 357 +++++++++++++++--- .../v1/TransitGatewayApisTest.java | 10 +- 7 files changed, 363 insertions(+), 107 deletions(-) diff --git a/modules/transit-gateway-apis/src/main/java/com/ibm/cloud/networking/transit_gateway_apis/v1/TransitGatewayApis.java b/modules/transit-gateway-apis/src/main/java/com/ibm/cloud/networking/transit_gateway_apis/v1/TransitGatewayApis.java index 7471fe10a..1e4ed6b22 100644 --- a/modules/transit-gateway-apis/src/main/java/com/ibm/cloud/networking/transit_gateway_apis/v1/TransitGatewayApis.java +++ b/modules/transit-gateway-apis/src/main/java/com/ibm/cloud/networking/transit_gateway_apis/v1/TransitGatewayApis.java @@ -12,13 +12,20 @@ */ /* - * IBM OpenAPI SDK Code Generator Version: 3.107.1-41b0fbd0-20250825-080732 + * IBM OpenAPI SDK Code Generator Version: 3.117.1-c28a0a4f-20261005-215243 */ package com.ibm.cloud.networking.transit_gateway_apis.v1; import com.google.gson.JsonObject; import com.ibm.cloud.networking.common.SdkCommon; +import com.ibm.cloud.sdk.core.http.RequestBuilder; +import com.ibm.cloud.sdk.core.http.ResponseConverter; +import com.ibm.cloud.sdk.core.http.ServiceCall; +import com.ibm.cloud.sdk.core.security.Authenticator; +import com.ibm.cloud.sdk.core.security.ConfigBasedAuthenticatorFactory; +import com.ibm.cloud.sdk.core.service.BaseService; +import com.ibm.cloud.sdk.core.util.ResponseConverterUtils; import com.ibm.cloud.networking.transit_gateway_apis.v1.model.CreateTransitGatewayConnectionActionsOptions; import com.ibm.cloud.networking.transit_gateway_apis.v1.model.CreateTransitGatewayConnectionOptions; import com.ibm.cloud.networking.transit_gateway_apis.v1.model.CreateTransitGatewayConnectionPrefixFilterOptions; @@ -65,13 +72,6 @@ import com.ibm.cloud.networking.transit_gateway_apis.v1.model.UpdateTransitGatewayConnectionPrefixFilterOptions; import com.ibm.cloud.networking.transit_gateway_apis.v1.model.UpdateTransitGatewayConnectionTunnelsOptions; import com.ibm.cloud.networking.transit_gateway_apis.v1.model.UpdateTransitGatewayOptions; -import com.ibm.cloud.sdk.core.http.RequestBuilder; -import com.ibm.cloud.sdk.core.http.ResponseConverter; -import com.ibm.cloud.sdk.core.http.ServiceCall; -import com.ibm.cloud.sdk.core.security.Authenticator; -import com.ibm.cloud.sdk.core.security.ConfigBasedAuthenticatorFactory; -import com.ibm.cloud.sdk.core.service.BaseService; -import com.ibm.cloud.sdk.core.util.ResponseConverterUtils; import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; diff --git a/modules/transit-gateway-apis/src/main/java/com/ibm/cloud/networking/transit_gateway_apis/v1/model/CreateTransitGatewayConnectionOptions.java b/modules/transit-gateway-apis/src/main/java/com/ibm/cloud/networking/transit_gateway_apis/v1/model/CreateTransitGatewayConnectionOptions.java index c8507a5cb..1b12b6d7e 100644 --- a/modules/transit-gateway-apis/src/main/java/com/ibm/cloud/networking/transit_gateway_apis/v1/model/CreateTransitGatewayConnectionOptions.java +++ b/modules/transit-gateway-apis/src/main/java/com/ibm/cloud/networking/transit_gateway_apis/v1/model/CreateTransitGatewayConnectionOptions.java @@ -43,13 +43,15 @@ public interface NetworkType { String REDUNDANT_GRE = "redundant_gre"; /** vpn_gateway. */ String VPN_GATEWAY = "vpn_gateway"; + /** dynamic_route_server. */ + String DYNAMIC_ROUTE_SERVER = "dynamic_route_server"; } /** * The type of network the Unbound GRE tunnel is targeting. This field is required for network type * `unbound_gre_tunnel` and must be set to `classic`. For a `redundant_gre` network type, the value is required and * can be either VPC or Classic. This field is required to be unspecified for network type `classic`, `directlink`, - * `vpc`, `power_virtual_server`, `vpn_gateway` and `gre_tunnel` connections. + * `vpc`, `power_virtual_server`, `vpn_gateway`, `dynamic_route_server` and `gre_tunnel` connections. */ public interface BaseNetworkType { /** classic. */ @@ -61,8 +63,8 @@ public interface BaseNetworkType { /** * Default setting of permit or deny which applies to any routes that don't match a specified filter. This field is * optional for network type `classic`, `vpc`, `directlink`, and `power_virtual_server` connections. This field is - * required to be unspecified for network type `gre_tunnel`, `unbound_gre_tunnel`, `vpn_gateway` and `redundant_gre` - * connections. + * required to be unspecified for network type `gre_tunnel`, `unbound_gre_tunnel`, `vpn_gateway`, + * `dynamic_route_server` and `redundant_gre` connections. */ public interface PrefixFiltersDefault { /** permit. */ @@ -469,7 +471,7 @@ public String baseConnectionId() { * The type of network the Unbound GRE tunnel is targeting. This field is required for network type * `unbound_gre_tunnel` and must be set to `classic`. For a `redundant_gre` network type, the value is required and * can be either VPC or Classic. This field is required to be unspecified for network type `classic`, `directlink`, - * `vpc`, `power_virtual_server`, `vpn_gateway` and `gre_tunnel` connections. + * `vpc`, `power_virtual_server`, `vpn_gateway`, `dynamic_route_server` and `gre_tunnel` connections. * * @return the baseNetworkType */ @@ -480,10 +482,11 @@ public String baseNetworkType() { /** * Gets the cidr. * - * network_type `vpn_gateway` connections use `cidr` to specify the CIDR to use for the VPN gateway GRE tunnels. + * network_type `vpn_gateway` and `dynamic_route_server`connections use `cidr` to specify the CIDR to use for the VPN + * gateway / Dynamic route server GRE tunnels. * - * This field is optional for network type `vpn_gateway` connections. If unspecified, the default value is - * 198.19.174.0/23. + * This field is optional for network type `vpn_gateway` and `dynamic_route_server` connections. If unspecified, the + * default value is 198.19.174.0/23. * * This field is required to be unspecified for network type `classic`, `directlink`, `vpc`, `power_virtual_server`, * `gre_tunnel`, `unbound_gre_tunnel`, and `redundant_gre` connections. @@ -499,7 +502,7 @@ public String cidr() { * * Local gateway IP address. This field is required for network type `gre_tunnel` and `unbound_gre_tunnel` * connections. This field is required to be unspecified for network type `classic`, `directlink`, `vpc`, - * `power_virtual_server`, `vpn_gateway` and `redundant_gre` connections. + * `power_virtual_server`, `vpn_gateway`, `dynamic_route_server` and `redundant_gre` connections. * * @return the localGatewayIp */ @@ -516,7 +519,7 @@ public String localGatewayIp() { * This field is required for network type `gre_tunnel` and `unbound_gre_tunnel` connections. * * This field is required to be unspecified for network type `classic`, `directlink`, `vpc`, `power_virtual_server`, - * `vpn_gateway` and `redundant_gre` connections. + * `vpn_gateway`, `dynamic_route_server` and `redundant_gre` connections. * * @return the localTunnelIp */ @@ -531,7 +534,7 @@ public String localTunnelIp() { * name of the VPC. Network type `classic` connections are named `classic`. * * This field is required for network type `power_virtual_server`, `directlink`, `gre_tunnel`, `unbound_gre_tunnel`, - * `vpn_gateway` and `redundant_gre` connections. + * `vpn_gateway`, `dynamic_route_server` and `redundant_gre` connections. * * This field is optional for network type `classic`, `vpc` connections. * @@ -559,10 +562,11 @@ public String networkAccountId() { * Gets the networkId. * * The ID of the network being connected via this connection. For network types `vpc`, `vpn_gateway`, - * `power_virtual_server` and `directlink` this is the CRN of the VPC / VPN / PowerVS / Direct Link gateway - * respectively. This field is required for network type `vpc`, `power_virtual_server`, `vpn_gateway` and `directlink` - * connections. It is also required for `redundant_gre` connections when the base_network_type is set to VPC. This - * field is required to be unspecified for network type `classic`, `gre_tunnel` and `unbound_gre_tunnel` connections. + * `dynamic_route_server`, `power_virtual_server` and `directlink` this is the CRN of the VPC / VPN / Dynamic Route + * Server / PowerVS / Direct Link gateway respectively. This field is required for network type `vpc`, + * `power_virtual_server`, `vpn_gateway`, `dynamic_route_server` and `directlink` connections. It is also required + * for `redundant_gre` connections when the base_network_type is set to VPC. This field is required to be unspecified + * for network type `classic`, `gre_tunnel` and `unbound_gre_tunnel` connections. * * @return the networkId */ @@ -578,7 +582,7 @@ public String networkId() { * connections. This is order dependent with those first in the array being applied first, and those at the end of the * array being applied last, or just before applying the default. This field is optional for network type `classic`, * `vpc`, `directlink`, and `power_virtual_server` connections. This field is required to be unspecified for network - * type `gre_tunnel`, `unbound_gre_tunnel`, `vpn_gateway` and `redundant_gre` connections. + * type `gre_tunnel`, `unbound_gre_tunnel`, `vpn_gateway`, `dynamic_route_server` and `redundant_gre` connections. * * @return the prefixFilters */ @@ -591,8 +595,8 @@ public List prefixFilters() { * * Default setting of permit or deny which applies to any routes that don't match a specified filter. This field is * optional for network type `classic`, `vpc`, `directlink`, and `power_virtual_server` connections. This field is - * required to be unspecified for network type `gre_tunnel`, `unbound_gre_tunnel`, `vpn_gateway` and `redundant_gre` - * connections. + * required to be unspecified for network type `gre_tunnel`, `unbound_gre_tunnel`, `vpn_gateway`, + * `dynamic_route_server` and `redundant_gre` connections. * * @return the prefixFiltersDefault */ @@ -610,7 +614,7 @@ public String prefixFiltersDefault() { * This field is optional for network type `gre_tunnel` and `unbound_gre_tunnel` connections. * * This field is required to be unspecified for network type `classic`, `directlink`, `vpc`, `power_virtual_server`, - * `vpn_gateway` and `gre_tunnel` connections. + * `vpn_gateway`, `dynamic_route_server` and `gre_tunnel` connections. * * @return the remoteBgpAsn */ @@ -623,7 +627,7 @@ public Long remoteBgpAsn() { * * Remote gateway IP address. This field is required for network type `gre_tunnel` and `unbound_gre_tunnel` * connections. This field is required to be unspecified for network type `classic`, `directlink`, `vpc`, - * `power_virtual_server`, `vpn_gateway` and `redundant_gre` connections. + * `power_virtual_server`, `vpn_gateway`, `dynamic_route_server` and `redundant_gre` connections. * * @return the remoteGatewayIp */ @@ -640,7 +644,7 @@ public String remoteGatewayIp() { * This field is required for network type `gre_tunnel` and `unbound_gre_tunnel` connections. * * This field is required to be unspecified for network type `classic`, `directlink`, `vpc`, `power_virtual_server`, - * `vpn_gateway` and `redundant_gre` connections. + * `vpn_gateway`, `dynamic_route_server` and `redundant_gre` connections. * * @return the remoteTunnelIp */ @@ -670,8 +674,8 @@ public List tunnels() { * * This field is optional for network type `vpn_gateway` connections. * - * This field is required to be unspecified for network type `classic`, `directlink`, `vpc`, `power_virtual_server` - * and `redundant_gre` connections. + * This field is required to be unspecified for network type `classic`, `directlink`, `vpc`, `power_virtual_server`, + * `redundant_gre` and `dynamic_route_server` connections. * * @return the zone */ diff --git a/modules/transit-gateway-apis/src/main/java/com/ibm/cloud/networking/transit_gateway_apis/v1/model/TransitConnection.java b/modules/transit-gateway-apis/src/main/java/com/ibm/cloud/networking/transit_gateway_apis/v1/model/TransitConnection.java index f968e1c19..851a3ef61 100644 --- a/modules/transit-gateway-apis/src/main/java/com/ibm/cloud/networking/transit_gateway_apis/v1/model/TransitConnection.java +++ b/modules/transit-gateway-apis/src/main/java/com/ibm/cloud/networking/transit_gateway_apis/v1/model/TransitConnection.java @@ -55,6 +55,8 @@ public interface NetworkType { String REDUNDANT_GRE = "redundant_gre"; /** vpn_gateway. */ String VPN_GATEWAY = "vpn_gateway"; + /** dynamic_route_server. */ + String DYNAMIC_ROUTE_SERVER = "dynamic_route_server"; } /** @@ -182,9 +184,9 @@ public String getName() { * Gets the networkId. * * The ID of the network being connected via this connection. This field is required for some types, such as `vpc`, - * `power_virtual_server`, `directlink`, `vpn_gateway` and `redundant_gre`. For network types `vpc`, `vpn_gateway`, - * `power_virtual_server` and `directlink` this is the CRN of the VPC / VPN / PowerVS / Direct Link gateway - * respectively. + * `power_virtual_server`, `directlink`, `vpn_gateway`, `dynamic_route_server` and `redundant_gre`. For network types + * `vpc`, `vpn_gateway`, `dynamic_route_server`, `power_virtual_server` and `directlink` this is the CRN of the VPC / + * VPN / Dynamic Route Server / PowerVS / Direct Link gateway respectively. * * @return the networkId */ @@ -234,7 +236,8 @@ public String getBaseConnectionId() { /** * Gets the cidr. * - * network_type `vpn_gateway` connections use `cidr` to specify the CIDR to use for the `VPN gateway` GRE tunnels. + * network_type `vpn_gateway` and `dynamic_route_server` connections use `cidr` to specify the CIDR to use for the + * `VPN gateway / Dynamic route server` GRE tunnels. * * @return the cidr */ @@ -412,7 +415,7 @@ public TransitGatewayReference getTransitGateway() { /** * Gets the tunnels. * - * Collection of all tunnels for `redundant_gre` and `vpn_gateway` connections. + * Collection of all tunnels for `redundant_gre`, `vpn_gateway` and `dynamic_route_server` connections. * * @return the tunnels */ diff --git a/modules/transit-gateway-apis/src/main/java/com/ibm/cloud/networking/transit_gateway_apis/v1/model/TransitGatewayConnectionCust.java b/modules/transit-gateway-apis/src/main/java/com/ibm/cloud/networking/transit_gateway_apis/v1/model/TransitGatewayConnectionCust.java index ca9287fb4..184fa6d43 100644 --- a/modules/transit-gateway-apis/src/main/java/com/ibm/cloud/networking/transit_gateway_apis/v1/model/TransitGatewayConnectionCust.java +++ b/modules/transit-gateway-apis/src/main/java/com/ibm/cloud/networking/transit_gateway_apis/v1/model/TransitGatewayConnectionCust.java @@ -28,7 +28,7 @@ public class TransitGatewayConnectionCust extends GenericModel { * The type of network the Unbound GRE tunnel is targeting. This field is required for network type * `unbound_gre_tunnel` and must be set to `classic`. For a `redundant_gre` network type, the value is required and * can be either VPC or Classic. This field is required to be unspecified for network type `classic`, `directlink`, - * `vpc`, `power_virtual_server`, `vpn_gateway` and `gre_tunnel` connections. + * `vpc`, `power_virtual_server`, `vpn_gateway`, `dynamic_route_server` and `gre_tunnel` connections. */ public interface BaseNetworkType { /** classic. */ @@ -57,6 +57,8 @@ public interface NetworkType { String REDUNDANT_GRE = "redundant_gre"; /** vpn_gateway. */ String VPN_GATEWAY = "vpn_gateway"; + /** dynamic_route_server. */ + String DYNAMIC_ROUTE_SERVER = "dynamic_route_server"; } /** @@ -177,7 +179,7 @@ public String getBaseConnectionId() { * The type of network the Unbound GRE tunnel is targeting. This field is required for network type * `unbound_gre_tunnel` and must be set to `classic`. For a `redundant_gre` network type, the value is required and * can be either VPC or Classic. This field is required to be unspecified for network type `classic`, `directlink`, - * `vpc`, `power_virtual_server`, `vpn_gateway` and `gre_tunnel` connections. + * `vpc`, `power_virtual_server`, `vpn_gateway`, `dynamic_route_server` and `gre_tunnel` connections. * * @return the baseNetworkType */ @@ -188,7 +190,8 @@ public String getBaseNetworkType() { /** * Gets the cidr. * - * network_type `vpn_gateway` connections use `cidr` to specify the CIDR to use for the `VPN gateway` GRE tunnels. + * network_type `vpn_gateway` and `dynamic_route_server` connections use `cidr` to specify the CIDR to use for the + * `VPN gateway / Dynamic route server` GRE tunnels. * * @return the cidr */ @@ -271,7 +274,7 @@ public Long getMtu() { * name of the VPC. Network type `classic` connections are named `classic`. * * This field is required for network type `power_virtual_server`, `directlink`, `gre_tunnel`, `unbound_gre_tunnel`, - * `vpn_gateway` and `redundant_gre` connections. + * `vpn_gateway`, `dynamic_route_server` and `redundant_gre` connections. * * This field is optional for network type `classic`, `vpc` connections. * @@ -297,10 +300,11 @@ public String getNetworkAccountId() { * Gets the networkId. * * The ID of the network being connected via this connection. For network types `vpc`, `vpn_gateway`, - * `power_virtual_server` and `directlink` this is the CRN of the VPC / VPN / PowerVS / Direct Link gateway - * respectively. This field is required for network type `vpc`, `power_virtual_server`, `vpn_gateway` and `directlink` - * connections. It is also required for `redundant_gre` connections when the base_network_type is set to VPC. This - * field is required to be unspecified for network type `classic`, `gre_tunnel` and `unbound_gre_tunnel` connections. + * `dynamic_route_server`, `power_virtual_server` and `directlink` this is the CRN of the VPC / VPN / Dynamic Route + * Server / PowerVS / Direct Link gateway respectively. This field is required for network type `vpc`, + * `power_virtual_server`, `vpn_gateway`, `dynamic_route_server` and `directlink` connections. It is also required + * for `redundant_gre` connections when the base_network_type is set to VPC. This field is required to be unspecified + * for network type `classic`, `gre_tunnel` and `unbound_gre_tunnel` connections. * * @return the networkId */ @@ -407,7 +411,7 @@ public String getStatus() { /** * Gets the tunnels. * - * Collection of all tunnels for `redundant_gre` and `vpn_gateway` connections. + * Collection of all tunnels for `redundant_gre`, `vpn_gateway` and `dynamic_route_server` connections. * * @return the tunnels */ diff --git a/modules/transit-gateway-apis/src/main/java/com/ibm/cloud/networking/transit_gateway_apis/v1/model/TransitGatewayTunnelCollection.java b/modules/transit-gateway-apis/src/main/java/com/ibm/cloud/networking/transit_gateway_apis/v1/model/TransitGatewayTunnelCollection.java index fe16290bb..1b6e2dc13 100644 --- a/modules/transit-gateway-apis/src/main/java/com/ibm/cloud/networking/transit_gateway_apis/v1/model/TransitGatewayTunnelCollection.java +++ b/modules/transit-gateway-apis/src/main/java/com/ibm/cloud/networking/transit_gateway_apis/v1/model/TransitGatewayTunnelCollection.java @@ -18,7 +18,7 @@ import com.ibm.cloud.sdk.core.service.model.GenericModel; /** - * Collection of all tunnels for `redundant_gre` and `vpn_gateway` connections. + * Collection of all tunnels for `redundant_gre`, `vpn_gateway` and `dynamic_route_server` connections. */ public class TransitGatewayTunnelCollection extends GenericModel { @@ -29,7 +29,7 @@ protected TransitGatewayTunnelCollection() { } /** * Gets the tunnels. * - * Collection of all tunnels for `redundant_gre` and `vpn_gateway` connections. + * Collection of all tunnels for `redundant_gre`, `vpn_gateway` and `dynamic_route_server` connections. * * @return the tunnels */ diff --git a/modules/transit-gateway-apis/src/test/java/com/ibm/cloud/networking/transit_gateway_apis/v1/TransitGatewayApisIT.java b/modules/transit-gateway-apis/src/test/java/com/ibm/cloud/networking/transit_gateway_apis/v1/TransitGatewayApisIT.java index f5faef233..16b1496e2 100755 --- a/modules/transit-gateway-apis/src/test/java/com/ibm/cloud/networking/transit_gateway_apis/v1/TransitGatewayApisIT.java +++ b/modules/transit-gateway-apis/src/test/java/com/ibm/cloud/networking/transit_gateway_apis/v1/TransitGatewayApisIT.java @@ -1,5 +1,5 @@ /* - * (C) Copyright IBM Corp. 2020, 2022. + * (C) Copyright IBM Corp. 2020, 2026. * * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at @@ -31,6 +31,7 @@ import com.ibm.cloud.networking.transit_gateway_apis.v1.model.*; import com.ibm.cloud.sdk.core.http.Response; import com.ibm.cloud.sdk.core.service.exception.NotFoundException; +import com.ibm.cloud.sdk.core.service.exception.ServiceResponseException; import com.ibm.cloud.sdk.core.util.CredentialUtils; @@ -545,19 +546,139 @@ public void testTransitGatewayOptions() throws InterruptedException { assertNotNull(updateTGConnRespObj); assertEquals(updateTGConnRespObj.getName(),updatedNameUnboundGRE); + ///////////////////////////////////////////////////////////// + // Success: POST Transit DRS (Dynamic Route Server) Connection: + ///////////////////////////////////////////////////////////// + String drsCrn = config.get("DRS_CRN"); + String drsNetworkType = "dynamic_route_server"; + stamp = (int)Math.floor(Math.random()*(1000-0+1)+0); + String drsConnectionName = "DRS-" + config.get("CONN_NAME") + "_" + String.valueOf(stamp); + String drsCidr = "192.168.200.0/24"; + + // Construct an instance of the CreateTransitGatewayConnectionOptions model + createTransitGatewayConnectionOptionsModel = new CreateTransitGatewayConnectionOptions.Builder() + .transitGatewayId(gatewayID) + .networkType(drsNetworkType) + .name(drsConnectionName) + .networkId(drsCrn) + .cidr(drsCidr) + .build(); + + // Invoke operation with valid options model (positive test) + connCreateResp = testService.createTransitGatewayConnection(createTransitGatewayConnectionOptionsModel).execute(); + assertNotNull(connCreateResp); + + connCreateRespObj = connCreateResp.getResult(); + assertNotNull(connCreateRespObj); + assertNotNull(connCreateRespObj.getId()); + assertEquals(connCreateRespObj.getName(), drsConnectionName); + assertEquals(connCreateRespObj.getNetworkId(), drsCrn); + assertEquals(connCreateRespObj.getNetworkType(), drsNetworkType); + assertEquals(connCreateRespObj.getCidr(), drsCidr); + String drsConnId = connCreateRespObj.getId(); + + // Connection creation might not be instantaneous. Poll the + // Connection looking for 'attached' status. Fail after 2 min + isResourceAvailable(gatewayID, drsConnId, ""); + + /////////////////////////////////////////// + // Success: GET Transit DRS Connection: + /////////////////////////////////////////// + GetTransitGatewayConnectionOptions getDrsTransitGatewayConnectionOptionsModel = new GetTransitGatewayConnectionOptions.Builder() + .transitGatewayId(gatewayID) + .id(drsConnId) + .build(); + + // Invoke operation with valid options model (positive test) + getConnResp = testService.getTransitGatewayConnection(getDrsTransitGatewayConnectionOptionsModel).execute(); + assertNotNull(getConnResp); + + getConnRespObjObj = getConnResp.getResult(); + assertNotNull(getConnRespObjObj); + assertEquals(getConnRespObjObj.getId(), drsConnId); + assertEquals(getConnRespObjObj.getName(), drsConnectionName); + assertEquals(getConnRespObjObj.getNetworkId(), drsCrn); + assertEquals(getConnRespObjObj.getNetworkType(), drsNetworkType); + assertEquals(getConnRespObjObj.getCidr(), drsCidr); + assertNotNull(getConnRespObjObj.getTunnels()); + assertNotEquals(getConnRespObjObj.getTunnels().size(), 0); + String drsTunnelId = getConnRespObjObj.getTunnels().get(0).getId(); + assertNotNull(drsTunnelId); + + /////////////////////////////////////////// + // Success: UPDATE Transit DRS Connection: + /////////////////////////////////////////// + stamp = (int)Math.floor(Math.random()*(1000-0+1)+0); + String updatedNameDRS = "UPDATED-DRS-" + config.get("CONN_NAME") + "_" + String.valueOf(stamp); + + updateTransitGatewayConnectionOptionsModel = new UpdateTransitGatewayConnectionOptions.Builder() + .transitGatewayId(gatewayID) + .id(drsConnId) + .name(updatedNameDRS) + .build(); + + // Invoke operation with valid options model (positive test) + updateTGConnResp = testService.updateTransitGatewayConnection(updateTransitGatewayConnectionOptionsModel).execute(); + assertNotNull(updateTGConnResp); + updateTGConnRespObj = updateTGConnResp.getResult(); + assertNotNull(updateTGConnRespObj); + assertEquals(updateTGConnRespObj.getName(), updatedNameDRS); + + /////////////////////////////////////////////////////////////// + // Success: LIST Connections filtered by DRS network type: + /////////////////////////////////////////////////////////////// + ListConnectionsOptions listConnectionsByTypeOptionsModel = new ListConnectionsOptions.Builder() + .networkType(drsNetworkType) + .build(); + + Response listConnByTypeResp = testService.listConnections(listConnectionsByTypeOptionsModel).execute(); + assertNotNull(listConnByTypeResp); + TransitConnectionCollection listConnByTypeRespObj = listConnByTypeResp.getResult(); + assertNotNull(listConnByTypeRespObj); + + boolean foundDrsInTypeFilter = false; + for (TransitConnection conn : listConnByTypeRespObj.getConnections()) { + assertEquals(conn.getNetworkType(), drsNetworkType); + if (conn.getId().equals(drsConnId)) { + foundDrsInTypeFilter = true; + } + } + assertEquals(true, foundDrsInTypeFilter); + + /////////////////////////////////////////////////////////////// + // Success: LIST Connections filtered by DRS network ID: + /////////////////////////////////////////////////////////////// + ListConnectionsOptions listConnectionsByIdOptionsModel = new ListConnectionsOptions.Builder() + .networkId(drsCrn) + .build(); + + Response listConnByIdResp = testService.listConnections(listConnectionsByIdOptionsModel).execute(); + assertNotNull(listConnByIdResp); + TransitConnectionCollection listConnByIdRespObj = listConnByIdResp.getResult(); + assertNotNull(listConnByIdRespObj); + + boolean foundDrsInIdFilter = false; + for (TransitConnection conn : listConnByIdRespObj.getConnections()) { + assertEquals(conn.getNetworkId(), drsCrn); + if (conn.getId().equals(drsConnId)) { + foundDrsInIdFilter = true; + } + } + assertEquals(true, foundDrsInIdFilter); + /////////////////////////////////////////// // Success: LIST Transit Connections: - /////////////////////////////////////////// - ListTransitGatewayConnectionsOptions listTransitGatewayConnectionsOptionsModel = new ListTransitGatewayConnectionsOptions.Builder() - .transitGatewayId(gatewayID) // Construct an instance of the ListTransitGatewayConnectionsOptions model - .build(); + /////////////////////////////////////////// + ListTransitGatewayConnectionsOptions listTransitGatewayConnectionsOptionsModel = new ListTransitGatewayConnectionsOptions.Builder() + .transitGatewayId(gatewayID) // Construct an instance of the ListTransitGatewayConnectionsOptions model + .build(); - // Invoke operation with valid options model (positive test) - Response listConnResp = testService.listTransitGatewayConnections(listTransitGatewayConnectionsOptionsModel).execute(); - assertNotNull(listConnResp); + // Invoke operation with valid options model (positive test) + Response listConnResp = testService.listTransitGatewayConnections(listTransitGatewayConnectionsOptionsModel).execute(); + assertNotNull(listConnResp); - TransitGatewayConnectionCollection listConnRespObj = listConnResp.getResult(); - assertNotNull(listConnRespObj); + TransitGatewayConnectionCollection listConnRespObj = listConnResp.getResult(); + assertNotNull(listConnRespObj); List connections = listConnRespObj.getConnections(); assertNotEquals(connections.size(), 0); @@ -567,6 +688,7 @@ public void testTransitGatewayOptions() throws InterruptedException { boolean foundGRE = false; boolean foundCLASSIC = false; boolean foundUnboundGRE = false; + boolean foundDRS = false; for (TransitGatewayConnectionCust conn : connections) { if (conn.getId().equals(classicConnId)){ assertEquals(conn.getNetworkType(), "classic"); @@ -587,10 +709,14 @@ public void testTransitGatewayOptions() throws InterruptedException { assertEquals(conn.getNetworkType(), "gre_tunnel"); assertEquals(conn.getName(), updatedNameGRE); foundGRE = true; - } else if (conn.getId().equals(greConnId)){ + } else if (conn.getId().equals(unboundGreConnId)){ assertEquals(conn.getNetworkType(), "unbound_gre_tunnel"); assertEquals(conn.getName(), updatedNameUnboundGRE); - foundGRE = true; + foundUnboundGRE = true; + } else if (conn.getId().equals(drsConnId)){ + assertEquals(conn.getNetworkType(), drsNetworkType); + assertEquals(conn.getName(), updatedNameDRS); + foundDRS = true; } } assertEquals(true, foundDL); @@ -598,7 +724,100 @@ public void testTransitGatewayOptions() throws InterruptedException { assertEquals(true, foundGRE); assertEquals(true, foundCLASSIC); assertEquals(true, foundUnboundGRE); - + assertEquals(true, foundDRS); + + /////////////////////////////////////////////////////////////// + // Failure: DRS validation — PATCH on a DRS-managed tunnel: + /////////////////////////////////////////////////////////////// + try { + UpdateTransitGatewayConnectionTunnelsOptions patchDrsTunnelOptions = new UpdateTransitGatewayConnectionTunnelsOptions.Builder() + .transitGatewayId(gatewayID) + .id(drsConnId) + .greTunnelId(drsTunnelId) + .transitGatewayTunnelPatch(new java.util.HashMap()) + .build(); + testService.updateTransitGatewayConnectionTunnels(patchDrsTunnelOptions).execute(); + } catch (ServiceResponseException e) { + // Expected: DRS-managed tunnels cannot be patched directly. + assertNotEquals(e.getStatusCode(), 200); + } + + /////////////////////////////////////////////////////////////// + // Failure: DRS validation — DELETE on a DRS-managed tunnel: + /////////////////////////////////////////////////////////////// + try { + DeleteTransitGatewayConnectionTunnelsOptions deleteDrsTunnelOptions = new DeleteTransitGatewayConnectionTunnelsOptions.Builder() + .transitGatewayId(gatewayID) + .id(drsConnId) + .greTunnelId(drsTunnelId) + .build(); + testService.deleteTransitGatewayConnectionTunnels(deleteDrsTunnelOptions).execute(); + } catch (ServiceResponseException e) { + // Expected: DRS-managed tunnels cannot be deleted directly. + assertNotEquals(e.getStatusCode(), 200); + } + + /////////////////////////////////////////////////////////////// + // Failure: DRS validation — LIST prefix filters on DRS: + /////////////////////////////////////////////////////////////// + try { + ListTransitGatewayConnectionPrefixFiltersOptions listPfOnDrsOptions = new ListTransitGatewayConnectionPrefixFiltersOptions.Builder() + .transitGatewayId(gatewayID) + .id(drsConnId) + .build(); + testService.listTransitGatewayConnectionPrefixFilters(listPfOnDrsOptions).execute(); + } catch (ServiceResponseException e) { + // Expected: prefix filters are not supported on DRS connections. + assertNotEquals(e.getStatusCode(), 200); + } + + /////////////////////////////////////////////////////////////// + // Failure: DRS validation — CREATE prefix filter on DRS: + /////////////////////////////////////////////////////////////// + try { + CreateTransitGatewayConnectionPrefixFilterOptions createPfOnDrsOptions = new CreateTransitGatewayConnectionPrefixFilterOptions.Builder() + .transitGatewayId(gatewayID) + .id(drsConnId) + .action("permit") + .prefix("192.168.100.0/24") + .build(); + testService.createTransitGatewayConnectionPrefixFilter(createPfOnDrsOptions).execute(); + } catch (ServiceResponseException e) { + // Expected: prefix filters cannot be created on DRS connections. + assertNotEquals(e.getStatusCode(), 200); + } + + /////////////////////////////////////////////////////////////// + // Failure: DRS validation — UPDATE prefix filter on DRS: + /////////////////////////////////////////////////////////////// + try { + UpdateTransitGatewayConnectionPrefixFilterOptions updatePfOnDrsOptions = new UpdateTransitGatewayConnectionPrefixFilterOptions.Builder() + .transitGatewayId(gatewayID) + .id(drsConnId) + .filterId("00000000-0000-0000-0000-000000000000") + .action("deny") + .build(); + testService.updateTransitGatewayConnectionPrefixFilter(updatePfOnDrsOptions).execute(); + } catch (ServiceResponseException e) { + // Expected: prefix filters cannot be updated on DRS connections. + assertNotEquals(e.getStatusCode(), 200); + } + + /////////////////////////////////////////////////////////////// + // Failure: DRS validation — GET prefix filter on DRS: + /////////////////////////////////////////////////////////////// + try { + GetTransitGatewayConnectionPrefixFilterOptions getPfOnDrsOptions = new GetTransitGatewayConnectionPrefixFilterOptions.Builder() + .transitGatewayId(gatewayID) + .id(drsConnId) + .filterId("00000000-0000-0000-0000-000000000000") + .build(); + testService.getTransitGatewayConnectionPrefixFilter(getPfOnDrsOptions).execute(); + } catch (ServiceResponseException e) { + // Expected: prefix filters cannot be fetched from DRS connections. + assertNotEquals(e.getStatusCode(), 200); + } + /////////////////////////////////////////// // Success: POST Gateway Route Report: /////////////////////////////////////////// @@ -653,6 +872,7 @@ public void testTransitGatewayOptions() throws InterruptedException { foundGRE = false; foundCLASSIC = false; foundUnboundGRE = false; + boolean foundDRSInRR = false; for (RouteReportConnection rrConn : rrConnections) { if(rrConn.getId().equals(vpcConnId)){ assertEquals(rrConn.getType(), "vpc"); @@ -672,10 +892,14 @@ public void testTransitGatewayOptions() throws InterruptedException { assertEquals(rrConn.getType(), "gre_tunnel"); assertEquals(rrConn.getName(), updatedNameGRE); foundGRE = true; - } else if (rrConn.getId().equals(greConnId)){ + } else if (rrConn.getId().equals(unboundGreConnId)){ assertEquals(rrConn.getType(), "unbound_gre_tunnel"); assertEquals(rrConn.getName(), updatedNameUnboundGRE); foundUnboundGRE = true; + } else if (rrConn.getId().equals(drsConnId)){ + assertEquals(rrConn.getType(), "dynamic_route_server"); + assertEquals(rrConn.getName(), updatedNameDRS); + foundDRSInRR = true; } } assertEquals(true, foundDL); @@ -683,6 +907,7 @@ public void testTransitGatewayOptions() throws InterruptedException { assertEquals(true, foundGRE); assertEquals(true, foundCLASSIC); assertEquals(true, foundUnboundGRE); + assertEquals(true, foundDRSInRR); /////////////////////////////////////////// // Success: LIST Gateway Route Report: @@ -732,20 +957,39 @@ public void testTransitGatewayOptions() throws InterruptedException { checkResourceDeletion(null, null, getTransitGatewayRouteReportOptionsModel); /////////////////////////////////////////// - // Success: DELETE Transit GRE Connection: + // Success: DELETE Transit DRS Connection: /////////////////////////////////////////// - DeleteTransitGatewayConnectionOptions deleteTransitGatewayConnectionOptionsModel = new DeleteTransitGatewayConnectionOptions.Builder() - .transitGatewayId(gatewayID) // Construct an instance of the DeleteTransitGatewayConnectionOptions model - .id(greConnId) - .build(); + DeleteTransitGatewayConnectionOptions deleteTransitGatewayConnectionOptionsModel = new DeleteTransitGatewayConnectionOptions.Builder() + .transitGatewayId(gatewayID) + .id(drsConnId) + .build(); + + // Invoke operation with valid options model (positive test) + Response delConnResp = testService.deleteTransitGatewayConnection(deleteTransitGatewayConnectionOptionsModel).execute(); + assertNotNull(delConnResp); - // Invoke operation with valid options model (positive test) - Response delConnResp = testService.deleteTransitGatewayConnection(deleteTransitGatewayConnectionOptionsModel).execute(); - assertNotNull(delConnResp); - // Response does not have a return type. Check that the result is null. - Void delConnRespObj = delConnResp.getResult(); - assertNull(delConnRespObj); + Void delConnRespObj = delConnResp.getResult(); + assertNull(delConnRespObj); + + // Connection deletion might not be instantaneous. + checkResourceDeletion(null, getDrsTransitGatewayConnectionOptionsModel, null); + + /////////////////////////////////////////// + // Success: DELETE Transit GRE Connection: + /////////////////////////////////////////// + deleteTransitGatewayConnectionOptionsModel = new DeleteTransitGatewayConnectionOptions.Builder() + .transitGatewayId(gatewayID) // Construct an instance of the DeleteTransitGatewayConnectionOptions model + .id(greConnId) + .build(); + + // Invoke operation with valid options model (positive test) + delConnResp = testService.deleteTransitGatewayConnection(deleteTransitGatewayConnectionOptionsModel).execute(); + assertNotNull(delConnResp); + + // Response does not have a return type. Check that the result is null. + delConnRespObj = delConnResp.getResult(); + assertNull(delConnRespObj); // Connection deletion might not be instantaneous. checkResourceDeletion(null, getGreTransitGatewayConnectionOptionsModel, null); @@ -754,20 +998,20 @@ public void testTransitGatewayOptions() throws InterruptedException { // Success: DELETE Transit Unbound GRE Connection: /////////////////////////////////////////// deleteTransitGatewayConnectionOptionsModel = new DeleteTransitGatewayConnectionOptions.Builder() - .transitGatewayId(gatewayID) // Construct an instance of the DeleteTransitGatewayConnectionOptions model - .id(unboundGreConnId) - .build(); - - // Invoke operation with valid options model (positive test) - delConnResp = testService.deleteTransitGatewayConnection(deleteTransitGatewayConnectionOptionsModel).execute(); - assertNotNull(delConnResp); - + .transitGatewayId(gatewayID) // Construct an instance of the DeleteTransitGatewayConnectionOptions model + .id(unboundGreConnId) + .build(); + + // Invoke operation with valid options model (positive test) + delConnResp = testService.deleteTransitGatewayConnection(deleteTransitGatewayConnectionOptionsModel).execute(); + assertNotNull(delConnResp); + // Response does not have a return type. Check that the result is null. delConnRespObj = delConnResp.getResult(); assertNull(delConnRespObj); - // Connection deletion might not be instantaneous. - checkResourceDeletion(null, getGreTransitGatewayConnectionOptionsModel, null); + // Connection deletion might not be instantaneous. + checkResourceDeletion(null, getUnboundGreTransitGatewayConnectionOptionsModel, null); /////////////////////////////////////////// // Success: DELETE Transit VPC Connection: @@ -841,7 +1085,7 @@ public void testTransitGatewayOptions() throws InterruptedException { Void delGtwRespObj = delGtwResp.getResult(); assertNull(delGtwRespObj); } - + /////////////////////////////////////////////////////////////////////////////// // Test Helper Methods // /////////////////////////////////////////////////////////////////////////////// @@ -871,27 +1115,28 @@ private void preTestCleanup(String name) throws InterruptedException { if (!connections.isEmpty()) { List connectionIDs = new ArrayList(); for (TransitGatewayConnectionCust conn : connections) { - // Deletes GRE Connections first. - if (conn.getNetworkType().contains("gre_tunnel")) { //will handle unbound_gre_tunnel as well - DeleteTransitGatewayConnectionOptions deleteTransitGatewayConnectionOptionsModel = new DeleteTransitGatewayConnectionOptions.Builder() - .transitGatewayId(gtw.getId()) - .id(conn.getId()) - .build(); - - Response delResponse = testService.deleteTransitGatewayConnection(deleteTransitGatewayConnectionOptionsModel).execute(); - assertNotNull(delResponse); - - GetTransitGatewayConnectionOptions getTransitGatewayConnectionOptionsModel = new GetTransitGatewayConnectionOptions.Builder() - .transitGatewayId(gtw.getId()) - .id(conn.getId()) - .build(); - - // Connection deletion might not be instantaneous. - checkResourceDeletion(null, getTransitGatewayConnectionOptionsModel, null); - } else { - connectionIDs.add(conn.getId()); + // Deletes GRE and DRS Connections first. + if (conn.getNetworkType().contains("gre_tunnel") + || conn.getNetworkType().equals("dynamic_route_server")) { + DeleteTransitGatewayConnectionOptions deleteTransitGatewayConnectionOptionsModel = new DeleteTransitGatewayConnectionOptions.Builder() + .transitGatewayId(gtw.getId()) + .id(conn.getId()) + .build(); + + Response delResponse = testService.deleteTransitGatewayConnection(deleteTransitGatewayConnectionOptionsModel).execute(); + assertNotNull(delResponse); + + GetTransitGatewayConnectionOptions getTransitGatewayConnectionOptionsModel = new GetTransitGatewayConnectionOptions.Builder() + .transitGatewayId(gtw.getId()) + .id(conn.getId()) + .build(); + + // Connection deletion might not be instantaneous. + checkResourceDeletion(null, getTransitGatewayConnectionOptionsModel, null); + } else { + connectionIDs.add(conn.getId()); + } } - } // Deletes Connections from other types. for (String connID : connectionIDs) { diff --git a/modules/transit-gateway-apis/src/test/java/com/ibm/cloud/networking/transit_gateway_apis/v1/TransitGatewayApisTest.java b/modules/transit-gateway-apis/src/test/java/com/ibm/cloud/networking/transit_gateway_apis/v1/TransitGatewayApisTest.java index d6c14273f..5df63d41d 100644 --- a/modules/transit-gateway-apis/src/test/java/com/ibm/cloud/networking/transit_gateway_apis/v1/TransitGatewayApisTest.java +++ b/modules/transit-gateway-apis/src/test/java/com/ibm/cloud/networking/transit_gateway_apis/v1/TransitGatewayApisTest.java @@ -13,6 +13,11 @@ package com.ibm.cloud.networking.transit_gateway_apis.v1; +import com.ibm.cloud.sdk.core.http.Response; +import com.ibm.cloud.sdk.core.security.Authenticator; +import com.ibm.cloud.sdk.core.security.NoAuthAuthenticator; +import com.ibm.cloud.sdk.core.service.model.FileWithMetadata; +import com.ibm.cloud.sdk.core.util.DateUtils; import com.ibm.cloud.networking.transit_gateway_apis.v1.TransitGatewayApis; import com.ibm.cloud.networking.transit_gateway_apis.v1.model.ConnectionsPager; import com.ibm.cloud.networking.transit_gateway_apis.v1.model.CreateTransitGatewayConnectionActionsOptions; @@ -89,11 +94,6 @@ import com.ibm.cloud.networking.transit_gateway_apis.v1.model.ZoneIdentityByName; import com.ibm.cloud.networking.transit_gateway_apis.v1.model.ZoneReference; import com.ibm.cloud.networking.transit_gateway_apis.v1.utils.TestUtilities; -import com.ibm.cloud.sdk.core.http.Response; -import com.ibm.cloud.sdk.core.security.Authenticator; -import com.ibm.cloud.sdk.core.security.NoAuthAuthenticator; -import com.ibm.cloud.sdk.core.service.model.FileWithMetadata; -import com.ibm.cloud.sdk.core.util.DateUtils; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList;