Repository: amplify-education/serverless-domain-manager (ts)

Issue:
getCustomDomainInfo does not work in Jakarta Region as APIGatewayV2 has not been supported in this region yet
<!--- Please keep this note for the community --->

### Community Note

* Please vote on this issue by adding a 👍 [reaction](https://blog.github.com/2016-03-10-add-reactions-to-pull-requests-issues-and-comments/) to the original issue to help the community and maintainers prioritize this request
* Please do not leave "+1" or "me too" comments, they generate extra noise for issue followers and do not help prioritize the request
* If you are interested in working on this issue or have submitted a pull request, please leave a comment

<!--- Thank you for keeping this note for the community --->

## Bug Report

**Error Description**
Unable to  use getCustomDomainInfo function in ap-southeast-3 (Jakarta region) since this function had used the APIGatewayV2

**Command Run**
`sls create_domain`

**Console Output**
```sh
Error:
Error: Unable to fetch information about <DOMAIN_NAME>
    at APIGatewayWrapper.<anonymous> (/Users/<USER>/<Project>/<Service>/node_modules/serverless-domain-manager/dist/src/aws/api-gateway-wrapper.js:110:27)
    at Generator.throw (<anonymous>)
    at rejected (/Users/<USER>/<Project>/<Service>/node_modules/serverless-domain-manager/dist/src/aws/api-gateway-wrapper.js:6:65)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
```

**Domain Manager Configuration**
```yaml
custom:
  customDomain:
    domainName: ${self:provider.domain}
    hostedZoneId: ${self:provider.hostzoneid}
    basePath: ''
    certificateArn: ${self:provider.certificatearn}
    stage: ${self:provider.stage}
    createRoute53Record: true
    endpointType: REGIONAL
    securityPolicy: TLS_1_0
    autoDomain: true

provider:
  name: aws
  runtime: nodejs14.x
  memorySize: 128
  domain: <$DOMAIN>
  hostzoneid: <$HOSTZONE_ID>
  certificatearn: <$CERT_ARN>
  stage: staging
  region: ${opt:region, 'ap-southeast-3'}
  environment: ${file(env.yml):${self:provider.stage}}
```

**Versions**
- Domain Manager version(s): [6.2.2]
- Node/npm version: [Node 18.13.0/ npm 8.19.3]
- Serverless Version: [3.26.0]
- Lambda Code [Javascript

**Possible Solution**
In getCustomDomainInfo function, we can rollback to use APIGateway version 1 instead of version 2 to make it compatible with ap-southeast-3 region.

Pull request:
fix: fix getCustomDomainInfo function to different APIGateway versions
<!--- Information about referencing Github Issues: https://help.github.com/articles/basic-writing-and-formatting-syntax/#referencing-issues-and-pull-requests --->
Fixes #536 
**Description of Issue Fixed**

- Fix getCustomDomainInfo function to use different APIGateway versions according to `endpointType` and 
`securityPolicy`

**Changes proposed in this pull request**:

* In getCustomDomainInfo function, using **APIGateway version 1** when `endpointType` == "EDGE" and `securityPolicy` == "TLS_1_0". Otherwise, using **APIGateway version 2**.

<!--- Please remember to allow edits from maintainers: https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/allowing-changes-to-a-pull-request-branch-created-from-a-fork --->


Patch:
diff --git a/src/aws/api-gateway-wrapper.ts b/src/aws/api-gateway-wrapper.ts
index 18f18e6..c85e6ff 100644
--- a/src/aws/api-gateway-wrapper.ts
+++ b/src/aws/api-gateway-wrapper.ts
@@ -134,6 +134,38 @@ class APIGatewayWrapper {
      * Get Custom Domain Info through API Gateway
      */
     public async getCustomDomainInfo(domain: DomainConfig): Promise<DomainInfo> {
+        const isEdgeType = domain.endpointType === Globals.endpointTypes.edge;
+        if (isEdgeType || domain.securityPolicy === Globals.tlsVersions.tls_1_0) {
+            // For EDGE domain name or TLS 1.0, get info with APIGateway (v1)
+            return await this.getCustomDomainInfoV1(domain)
+        } else {
+            /// For Regional domain name get info with ApiGatewayV2
+            return await this.getCustomDomainInfoV2(domain)
+        }
+    }
+
+    /**
+     * Get Custom Domain Info through API Gateway (v1)
+     */
+    private async getCustomDomainInfoV1(domain: DomainConfig): Promise<DomainInfo> {
+        // Make API call
+        try {
+            const domainInfo = await throttledCall(this.apiGateway, "getDomainName", {
+                domainName: domain.givenDomainName,
+            });
+            return new DomainInfo(domainInfo);
+        } catch (err) {
+            if (err.code !== "NotFoundException") {
+                throw new Error(`Unable to fetch information about '${domain.givenDomainName}':\n${err.message}`);
+            }
+            Globals.logInfo(`'${domain.givenDomainName}' does not exist.`);
+        }
+    }
+
+    /**
+     * Get Custom Domain Info through API Gateway (v2)
+     */
+    private async getCustomDomainInfoV2(domain: DomainConfig): Promise<DomainInfo> {
         // Make API call
         try {
             const domainInfo = await throttledCall(this.apiGatewayV2, "getDomainName", {
diff --git a/src/domain-info.ts b/src/domain-info.ts
index 7b40fc2..5cdfdfe 100644
--- a/src/domain-info.ts
+++ b/src/domain-info.ts
@@ -21,7 +21,8 @@ class DomainInfo {
         this.domainName = data.distributionDomainName
             || data.regionalDomainName
             || data.DomainNameConfigurations && data.DomainNameConfigurations[0].ApiGatewayDomainName
-            || data.DomainName;
+            || data.DomainName
+            || data.domainName;
 
         this.hostedZoneId = data.distributionHostedZoneId
             || data.regionalHostedZoneId


Test patch:
diff --git a/test/unit-tests/index.test.ts b/test/unit-tests/index.test.ts
index 43559f6..d6de8f1 100644
--- a/test/unit-tests/index.test.ts
+++ b/test/unit-tests/index.test.ts
@@ -1627,6 +1627,11 @@ describe("Custom Domain Plugin", () => {
 
     describe("Hook Methods", () => {
         it("setupBasePathMapping", async () => {
+            AWS.mock("APIGateway", "getDomainName", (params, callback) => {
+                callback(null, {
+                    domainName: "test_domain"
+                });
+            });
             AWS.mock("ApiGatewayV2", "getDomainName", (params, callback) => {
                 callback(null, {
                     DomainName: "test_domain",
@@ -1680,6 +1685,12 @@ describe("Custom Domain Plugin", () => {
         });
 
         it("deleteDomain", async () => {
+            AWS.mock("APIGateway", "getDomainName", (params, callback) => {
+                callback(null, {
+                    domainName: "test_domain",
+                    regionalHostedZoneId: "test_id"
+                });
+            });
             AWS.mock("ApiGatewayV2", "getDomainName", (params, callback) => {
                 callback(null, {DomainName: "test_domain", DomainNameConfigurations: [{HostedZoneId: "test_id"}]});
             });
@@ -1705,6 +1716,10 @@ describe("Custom Domain Plugin", () => {
 
         it("createDomain if one does not exist before", async () => {
             AWS.mock("ACM", "listCertificates", certTestData);
+            AWS.mock("APIGateway", "getDomainName", (params, callback) => {
+                 // @ts-ignore
+                 callback({code: "NotFoundException"}, {});
+            });
             AWS.mock("ApiGatewayV2", "getDomainName", (params, callback) => {
                 // @ts-ignore
                 callback({code: "NotFoundException"}, {});
@@ -1738,6 +1753,10 @@ describe("Custom Domain Plugin", () => {
 
         it("Does not create domain if one existed before", async () => {
             AWS.mock("ACM", "listCertificates", certTestData);
+            AWS.mock("ACM", "listCertificates", certTestData);
+            AWS.mock("APIGateway", "getDomainName", (params, callback) => {
+                 callback(null, {domainName: "test_domain", regionalHostedZoneId: "test_id"});
+            });
             AWS.mock("ApiGatewayV2", "getDomainName", (params, callback) => {
                 callback(null, {DomainName: "test_domain", DomainNameConfigurations: [{HostedZoneId: "test_id"}]});
             });
@@ -2084,6 +2103,10 @@ describe("Custom Domain Plugin", () => {
 
     describe("Summary Printing", () => {
         it("Prints Summary", async () => {
+            AWS.mock("APIGateway", "getDomainName", (params, callback) => {
+                // @ts-ignore
+                callback(null, {domainName: params, distributionDomainName: "test_distributed_domain_name"});
+            });
             AWS.mock("ApiGatewayV2", "getDomainName", (params, callback) => {
                 // @ts-ignore
                 callback(null, {domainName: params, distributionDomainName: "test_distributed_domain_name"});
@@ -2352,7 +2375,7 @@ describe("Custom Domain Plugin", () => {
         });
 
         it("createOrGetDomainForCfOutputs should call createDomain when autoDomain is true", async () => {
-            AWS.mock("ApiGatewayV2", "getDomainName", (params, callback) => {
+            AWS.mock("APIGateway", "getDomainName", (params, callback) => {
                 callback(null, params);
             });
             const plugin = constructPlugin({
@@ -2367,7 +2390,7 @@ describe("Custom Domain Plugin", () => {
 
             plugin.domains[0].apiMapping = {ApiMappingId: "test_mapping_id"};
 
-            const spy = chai.spy.on(plugin.apiGatewayWrapper.apiGatewayV2, "getDomainName");
+            const spy = chai.spy.on(plugin.apiGatewayWrapper.apiGateway, "getDomainName");
 
             await plugin.createOrGetDomainForCfOutputs();
 
@@ -2376,6 +2399,9 @@ describe("Custom Domain Plugin", () => {
         });
 
         it("createOrGetDomainForCfOutputs should not call createDomain when autoDomain is not true", async () => {
+            AWS.mock("APIGateway", "getDomainName", (params, callback) => {
+                callback(null, params);
+            });
             AWS.mock("ApiGatewayV2", "getDomainName", (params, callback) => {
                 callback(null, params);
             });
@@ -2427,6 +2453,9 @@ describe("Custom Domain Plugin", () => {
             AWS.mock("ApiGatewayV2", "deleteDomainName", (params, callback) => {
                 callback(null, params);
             });
+            AWS.mock("APIGateway", "getDomainName", (params, callback) => {
+                callback(null, params);
+            });
             AWS.mock("ApiGatewayV2", "getDomainName", (params, callback) => {
                 callback(null, params);
             });
@@ -2584,6 +2613,9 @@ describe("Custom Domain Plugin", () => {
             AWS.mock("ApiGatewayV2", "deleteDomainName", (params, callback) => {
                 callback(null, params);
             });
+            AWS.mock("APIGateway", "getDomainName", (params, callback) => {
+                callback(null, params);
+            });
             AWS.mock("ApiGatewayV2", "getDomainName", (params, callback) => {
                 callback(null, params);
             });