-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #153 from boostcampwm-2024/feature/ncloud-price
Ncloud 서버 리소스 가격 조회 배치 기능 구현
- Loading branch information
Showing
5 changed files
with
241 additions
and
50 deletions.
There are no files selected for viewing
137 changes: 137 additions & 0 deletions
137
apps/server/prisma/migrations/20241128085427_/migration.sql
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,137 @@ | ||
-- CreateTable | ||
CREATE TABLE `import` ( | ||
`id` INTEGER NOT NULL AUTO_INCREMENT, | ||
`public_architecture_id` INTEGER NOT NULL, | ||
`user_id` INTEGER NOT NULL, | ||
`created_at` TIMESTAMP(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0), | ||
|
||
PRIMARY KEY (`id`) | ||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; | ||
|
||
-- CreateTable | ||
CREATE TABLE `ncloud_server_resource` ( | ||
`id` INTEGER NOT NULL AUTO_INCREMENT, | ||
`server_resource_type_id` INTEGER NOT NULL, | ||
`server_spec_code` CHAR(50) NOT NULL, | ||
`hour_cost` DOUBLE NOT NULL, | ||
`month_cost` DOUBLE NOT NULL, | ||
`created_at` TIMESTAMP(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0), | ||
`updated_at` TIMESTAMP(0) NULL, | ||
|
||
PRIMARY KEY (`id`) | ||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; | ||
|
||
-- CreateTable | ||
CREATE TABLE `ncloud_server_resource_type` ( | ||
`id` INTEGER NOT NULL AUTO_INCREMENT, | ||
`type` CHAR(50) NOT NULL, | ||
|
||
PRIMARY KEY (`id`) | ||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; | ||
|
||
-- CreateTable | ||
CREATE TABLE `private_architecture` ( | ||
`id` INTEGER NOT NULL AUTO_INCREMENT, | ||
`title` CHAR(50) NOT NULL, | ||
`author_id` INTEGER NOT NULL, | ||
`architecture` JSON NOT NULL, | ||
`cost` DOUBLE NOT NULL DEFAULT 0, | ||
`created_at` TIMESTAMP(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0), | ||
`updated_at` TIMESTAMP(0) NULL, | ||
|
||
PRIMARY KEY (`id`) | ||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; | ||
|
||
-- CreateTable | ||
CREATE TABLE `public_architecture_tag` ( | ||
`id` INTEGER NOT NULL AUTO_INCREMENT, | ||
`public_architecture_id` INTEGER NOT NULL, | ||
`tag_id` INTEGER NOT NULL, | ||
|
||
UNIQUE INDEX `public_architecture_tag_public_architecture_id_tag_id_key`(`public_architecture_id`, `tag_id`), | ||
PRIMARY KEY (`id`) | ||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; | ||
|
||
-- CreateTable | ||
CREATE TABLE `public_architecture` ( | ||
`id` INTEGER NOT NULL AUTO_INCREMENT, | ||
`title` CHAR(50) NOT NULL, | ||
`author_id` INTEGER NOT NULL, | ||
`architecture` JSON NOT NULL, | ||
`created_at` TIMESTAMP(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0), | ||
`cost` DOUBLE NOT NULL DEFAULT 0, | ||
|
||
PRIMARY KEY (`id`) | ||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; | ||
|
||
-- CreateTable | ||
CREATE TABLE `star` ( | ||
`id` INTEGER NOT NULL AUTO_INCREMENT, | ||
`public_architecture_id` INTEGER NOT NULL, | ||
`user_id` INTEGER NOT NULL, | ||
`created_at` TIMESTAMP(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0), | ||
|
||
UNIQUE INDEX `star_public_architecture_id_user_id_key`(`public_architecture_id`, `user_id`), | ||
PRIMARY KEY (`id`) | ||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; | ||
|
||
-- CreateTable | ||
CREATE TABLE `tag` ( | ||
`id` INTEGER NOT NULL AUTO_INCREMENT, | ||
`name` VARCHAR(15) NOT NULL, | ||
`created_at` TIMESTAMP(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0), | ||
|
||
UNIQUE INDEX `tag_name_key`(`name`), | ||
PRIMARY KEY (`id`) | ||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; | ||
|
||
-- CreateTable | ||
CREATE TABLE `user` ( | ||
`id` INTEGER NOT NULL AUTO_INCREMENT, | ||
`name` VARCHAR(30) NOT NULL, | ||
`created_at` TIMESTAMP(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0), | ||
|
||
PRIMARY KEY (`id`) | ||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; | ||
|
||
-- CreateTable | ||
CREATE TABLE `version` ( | ||
`id` INTEGER NOT NULL AUTO_INCREMENT, | ||
`private_architecture_id` INTEGER NOT NULL, | ||
`title` CHAR(50) NOT NULL, | ||
`created_at` TIMESTAMP(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0), | ||
`architecture` JSON NOT NULL, | ||
`cost` DOUBLE NOT NULL DEFAULT 0, | ||
|
||
PRIMARY KEY (`id`) | ||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; | ||
|
||
-- AddForeignKey | ||
ALTER TABLE `import` ADD CONSTRAINT `import_public_architecture_id_fkey` FOREIGN KEY (`public_architecture_id`) REFERENCES `public_architecture`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE; | ||
|
||
-- AddForeignKey | ||
ALTER TABLE `import` ADD CONSTRAINT `import_user_id_fkey` FOREIGN KEY (`user_id`) REFERENCES `user`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE; | ||
|
||
-- AddForeignKey | ||
ALTER TABLE `ncloud_server_resource` ADD CONSTRAINT `ncloud_server_resource_server_resource_type_id_fkey` FOREIGN KEY (`server_resource_type_id`) REFERENCES `ncloud_server_resource_type`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE; | ||
|
||
-- AddForeignKey | ||
ALTER TABLE `private_architecture` ADD CONSTRAINT `private_architecture_author_id_fkey` FOREIGN KEY (`author_id`) REFERENCES `user`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE; | ||
|
||
-- AddForeignKey | ||
ALTER TABLE `public_architecture_tag` ADD CONSTRAINT `public_architecture_tag_public_architecture_id_fkey` FOREIGN KEY (`public_architecture_id`) REFERENCES `public_architecture`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE; | ||
|
||
-- AddForeignKey | ||
ALTER TABLE `public_architecture_tag` ADD CONSTRAINT `public_architecture_tag_tag_id_fkey` FOREIGN KEY (`tag_id`) REFERENCES `tag`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE; | ||
|
||
-- AddForeignKey | ||
ALTER TABLE `public_architecture` ADD CONSTRAINT `public_architecture_author_id_fkey` FOREIGN KEY (`author_id`) REFERENCES `user`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE; | ||
|
||
-- AddForeignKey | ||
ALTER TABLE `star` ADD CONSTRAINT `star_public_architecture_id_fkey` FOREIGN KEY (`public_architecture_id`) REFERENCES `public_architecture`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE; | ||
|
||
-- AddForeignKey | ||
ALTER TABLE `star` ADD CONSTRAINT `star_user_id_fkey` FOREIGN KEY (`user_id`) REFERENCES `user`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE; | ||
|
||
-- AddForeignKey | ||
ALTER TABLE `version` ADD CONSTRAINT `version_private_architecture_id_fkey` FOREIGN KEY (`private_architecture_id`) REFERENCES `private_architecture`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
# Please do not edit this file manually | ||
# It should be added in your version-control system (i.e. Git) | ||
provider = "mysql" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
101 changes: 100 additions & 1 deletion
101
apps/server/src/ncloud-resources/ncloud-resources.service.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,103 @@ | ||
import { Ncloud, PriceApi, ApiKeyCredentials } from '@cloud-canvas/ncloud-sdk'; | ||
import { Injectable } from '@nestjs/common'; | ||
import { Cron, CronExpression } from '@nestjs/schedule'; | ||
import { PrismaService } from 'src/prisma/prisma.service'; | ||
|
||
@Injectable() | ||
export class NcloudResourcesService {} | ||
export class NcloudResourcesService { | ||
constructor(private readonly prisma: PrismaService) {} | ||
|
||
@Cron(CronExpression.EVERY_DAY_AT_3AM, { | ||
name: 'Insert Ncloud Resource Cron Job', | ||
}) | ||
async insertNcloudResource() { | ||
const ncloud = new Ncloud(); | ||
const priceApi = new PriceApi(ncloud.keys() as ApiKeyCredentials); | ||
const result = await priceApi.getProductPriceList({ | ||
regionCode: 'KR', | ||
payCurrencyCode: 'KRW', | ||
productCategoryCode: 'COMPUTE', | ||
}); | ||
const ncloudServerResourceMap: Map< | ||
string, | ||
Record<string, number | string>[] | ||
> = new Map(); | ||
result.productPriceList.forEach((product) => { | ||
if ( | ||
product.productItemKind.code === 'SVR' && | ||
product.serverProductCode && | ||
product.serverProductCode.endsWith('50') | ||
) { | ||
if (!ncloudServerResourceMap.has(product.productType.codeName)) | ||
ncloudServerResourceMap.set( | ||
product.productType.codeName, | ||
[], | ||
); | ||
const { | ||
serverProductCode, | ||
priceList: [{ price: monthPrice }, { price: hourPrice }], | ||
}: { | ||
serverProductCode: string; | ||
priceList: { price: number }[]; | ||
} = product; | ||
ncloudServerResourceMap.get(product.productType.codeName).push({ | ||
serverProductCode: serverProductCode.toLowerCase(), | ||
monthPrice, | ||
hourPrice, | ||
}); | ||
} | ||
}); | ||
await this.prisma.$transaction(async (tx) => { | ||
await tx.ncloudServerResource.deleteMany({}); | ||
await tx.ncloudServerResourceType.deleteMany({}); | ||
|
||
const ncloudServerResourceTypes = [ | ||
...ncloudServerResourceMap.keys(), | ||
].map((key) => ({ type: key })); | ||
|
||
await tx.ncloudServerResourceType.createMany({ | ||
data: ncloudServerResourceTypes, | ||
}); | ||
|
||
const ncloudServerResources = await Promise.all( | ||
[...ncloudServerResourceMap.values()].map( | ||
async (ncloudServerResourceList, index) => { | ||
const serverResourceTypeId = | ||
await tx.ncloudServerResourceType.findFirst({ | ||
select: { id: true }, | ||
where: { | ||
type: ncloudServerResourceTypes[index].type, | ||
}, | ||
}); | ||
|
||
return ncloudServerResourceList.map( | ||
(ncloudServerResource) => ({ | ||
serverResourceTypeId: serverResourceTypeId?.id, | ||
serverSpecCode: | ||
ncloudServerResource.serverProductCode as string, | ||
hourCost: parseFloat( | ||
'' + ncloudServerResource.hourPrice, | ||
), | ||
monthCost: parseFloat( | ||
'' + ncloudServerResource.monthPrice, | ||
), | ||
}), | ||
); | ||
}, | ||
), | ||
); | ||
|
||
const flattenedResources = ncloudServerResources.flat(); | ||
|
||
await tx.ncloudServerResource.createMany({ | ||
data: flattenedResources, | ||
}); | ||
console.log(await tx.ncloudServerResourceType.findMany({})); | ||
console.log(await tx.ncloudServerResource.findMany({})); | ||
}); | ||
} | ||
|
||
async onApplicationBootstrap() { | ||
await this.insertNcloudResource(); | ||
} | ||
} |