Update import statements for ProductType in multiple files

This commit is contained in:
Simon Larsen 2024-04-04 20:56:03 +01:00
parent 1fbdc19645
commit abcde37960
No known key found for this signature in database
GPG Key ID: AB45983AA9C81CDE
11 changed files with 60 additions and 102 deletions

View File

@ -0,0 +1,8 @@
enum ProductType {
Logs = 'Logs',
Traces = 'Traces',
Metrics = 'Metrics',
ActiveMonitoring = 'ActiveMonitoring',
}
export default ProductType;

View File

@ -1,5 +1,4 @@
import SubscriptionPlan from 'Common/Types/Billing/SubscriptionPlan';
import MeteredPlan from 'Common/Types/Billing/MeteredPlan';
import OneUptimeDate from 'Common/Types/Date';
import APIException from 'Common/Types/Exception/ApiException';
import BadDataException from 'Common/Types/Exception/BadDataException';
@ -15,7 +14,7 @@ import BaseService from './BaseService';
import Email from 'Common/Types/Email';
import Dictionary from 'Common/Types/Dictionary';
import Errors from '../Utils/Errors';
import { ProductType } from 'Model/Models/UsageBilling';
import ProductType from 'Common/Types/MeteredPlan/ProductType';
export type SubscriptionItem = Stripe.SubscriptionItem;
@ -876,59 +875,6 @@ export class BillingService extends BaseService {
'Plan with productType ' + productType + ' not found'
);
}
public async getMeteredPlan(data: {
productType: ProductType;
projectId: ObjectID;
}): Promise<MeteredPlan> {
if (data.productType === ProductType.ActiveMonitoring) {
return new MeteredPlan({
priceId: this.getMeteredPlanPriceId(data.productType),
pricePerUnitInUSD: 1,
unitName: 'Active Monitor',
});
}
// const dataRetentionDays: number =
// await ProjectService.getTelemetryDataRetentionInDays(
// data.projectId
// );
const dataRetentionDays: number = 15;
const dataRetentionMultiplier: number = 0.1; // if the retention is 10 days for example, the cost per GB will be 0.01$ per GB per day (0.10 * dataRetentionDays * dataRetentionMultiplier).
if (data.productType === ProductType.Logs) {
return new MeteredPlan({
priceId: this.getMeteredPlanPriceId(data.productType),
pricePerUnitInUSD:
0.1 * dataRetentionDays * dataRetentionMultiplier,
unitName: `GB (${dataRetentionDays} days data retention)`,
});
}
if (data.productType === ProductType.Traces) {
return new MeteredPlan({
priceId: this.getMeteredPlanPriceId(data.productType),
pricePerUnitInUSD:
0.1 * dataRetentionDays * dataRetentionMultiplier,
unitName: `GB (${dataRetentionDays} days data retention)`,
});
}
if (data.productType === ProductType.Metrics) {
return new MeteredPlan({
priceId: this.getMeteredPlanPriceId(data.productType),
pricePerUnitInUSD:
0.1 * dataRetentionDays * dataRetentionMultiplier,
unitName: `GB (${dataRetentionDays} days data retention)`,
});
}
throw new BadDataException(
'Plan with name ' + data.productType + ' not found'
);
}
}
export default new BillingService();

View File

@ -1,5 +1,6 @@
import PostgresDatabase from '../Infrastructure/PostgresDatabase';
import Model, { ProductType } from 'Model/Models/TelemetryUsageBilling';
import Model from 'Model/Models/TelemetryUsageBilling';
import ProductType from 'Common/Types/MeteredPlan/ProductType';
import DatabaseService from './DatabaseService';
import ObjectID from 'Common/Types/ObjectID';
import { LIMIT_PER_PROJECT } from 'Common/Types/Database/LimitMax';
@ -7,10 +8,9 @@ import OneUptimeDate from 'Common/Types/Date';
import QueryHelper from '../Types/Database/QueryHelper';
import SortOrder from 'Common/Types/BaseDatabase/SortOrder';
import { MeteredPlanUtil } from '../Types/Billing/MeteredPlan/AllMeteredPlans';
import MeteredPlan from 'Common/Types/Billing/MeteredPlan';
import ServerMeteredPlan from '../Types/Billing/MeteredPlan/ServerMeteredPlan';
import Decimal from 'Common/Types/Decimal';
import TelemetryMeteredPlan from '../Types/Billing/MeteredPlan/TelemetryMeteredPlan';
import BadDataException from 'Common/Types/Exception/BadDataException';
export class Service extends DatabaseService<Model> {
public constructor(postgresDatabase?: PostgresDatabase) {
@ -53,8 +53,13 @@ export class Service extends DatabaseService<Model> {
dataIngestedInGB: number;
retentionInDays: number;
}): Promise<void> {
if(data.productType !== ProductType.Traces && data.productType !== ProductType.Metrics && data.productType !== ProductType.Logs) {
throw new BadDataException("This product type is not a telemetry product type.");
}
const serverMeteredPlan: TelemetryMeteredPlan =
MeteredPlanUtil.getTelemetryMeteredPlanByProductType(data.productType);
MeteredPlanUtil.getMeteredPlanByProductType(data.productType) as TelemetryMeteredPlan;
const totalCostOfThisOperationInUSD: number =
serverMeteredPlan.getTotalCostInUSD(
@ -95,8 +100,8 @@ export class Service extends DatabaseService<Model> {
await this.updateOneById({
id: usageBilling.id,
data: {
usageCount: new Decimal(
(usageBilling.usageCount?.value || 0) + data.usageCount
dataIngestedInGB: new Decimal(
(usageBilling.dataIngestedInGB?.value || 0) + data.dataIngestedInGB
),
totalCostInUSD: new Decimal(
(usageBilling.totalCostInUSD?.value || 0) +
@ -111,12 +116,16 @@ export class Service extends DatabaseService<Model> {
const usageBilling: Model = new Model();
usageBilling.projectId = data.projectId;
usageBilling.productType = data.productType;
usageBilling.usageCount = new Decimal(data.usageCount);
usageBilling.dataIngestedInGB = new Decimal(data.dataIngestedInGB);
usageBilling.telemetryServiceId = data.telemetryServiceId;
usageBilling.retainTelemetryDataForDays = data.retentionInDays;
usageBilling.isReportedToBillingProvider = false;
usageBilling.createdAt = OneUptimeDate.getCurrentDate();
usageBilling.day = OneUptimeDate.getDateString(
OneUptimeDate.getCurrentDate()
);
usageBilling.totalCostInUSD = new Decimal(
totalCostOfThisOperationInUSD
);

View File

@ -14,7 +14,7 @@ import {
ChangePlan,
CouponData,
} from '../../TestingUtils/Services/Types';
import { ProductType } from 'Model/Models/UsageBilling';
import ProductType from 'Common/Types/MeteredPlan/ProductType';
/// @dev consider modifyfing the EnvirontmentConfig to use functions instead of constants so that we can mock them

View File

@ -7,7 +7,7 @@ import PositiveNumber from 'Common/Types/PositiveNumber';
import ProjectService from '../../../Services/ProjectService';
import BillingService from '../../../Services/BillingService';
import Project from 'Model/Models/Project';
import { ProductType } from 'Model/Models/UsageBilling';
import ProductType from 'Common/Types/MeteredPlan/ProductType';
export default class ActiveMonitoringMeteredPlan extends ServerMeteredPlan {
public override getProductType(): ProductType {

View File

@ -1,27 +1,27 @@
import ActiveMonitoringMeteredPlanType from './ActiveMonitoringMeteredPlan';
import ServerMeteredPlan from './ServerMeteredPlan';
import TelemetryMeteredPlanType from './TelemetryMeteredPlan';
import { ProductType as TelemetryProductType } from 'Model/Models/TelemetryUsageBilling';
import BadDataException from 'Common/Types/Exception/BadDataException';
import ProductType from 'Common/Types/MeteredPlan/ProductType';
export const ActiveMonitoringMeteredPlan: ActiveMonitoringMeteredPlanType =
new ActiveMonitoringMeteredPlanType();
export const LogDataIngestMeteredPlan: TelemetryMeteredPlanType =
new TelemetryMeteredPlanType({
productType: TelemetryProductType.Logs,
productType: ProductType.Logs,
unitCostInUSD: 0.10 / 15, // 0.10 per 15 days per GB
});
export const MetricsDataIngestMeteredPlan: TelemetryMeteredPlanType =
new TelemetryMeteredPlanType({
productType: TelemetryProductType.Metrics,
productType: ProductType.Metrics,
unitCostInUSD: 0.10 / 15, // 0.10 per 15 days per GB
});
export const TracesDataIngestMetredPlan: TelemetryMeteredPlanType =
new TelemetryMeteredPlanType({
productType: TelemetryProductType.Traces,
productType: ProductType.Traces,
unitCostInUSD: 0.10 / 15, // 0.10 per 15 days per GB
});
@ -33,16 +33,19 @@ const AllMeteredPlans: Array<ServerMeteredPlan> = [
];
export class MeteredPlanUtil {
public static getTelemetryMeteredPlanByProductType(
productType: TelemetryProductType
): TelemetryMeteredPlanType {
if (productType === TelemetryProductType.Logs) {
public static getMeteredPlanByProductType(
productType: ProductType
): ServerMeteredPlan {
if (productType === ProductType.Logs) {
return LogDataIngestMeteredPlan;
} else if (productType === TelemetryProductType.Metrics) {
} else if (productType === ProductType.Metrics) {
return MetricsDataIngestMeteredPlan;
} else if (productType === TelemetryProductType.Traces) {
} else if (productType === ProductType.Traces) {
return TracesDataIngestMetredPlan;
} else if (productType === ProductType.ActiveMonitoring) {
return ActiveMonitoringMeteredPlan;
}
throw new BadDataException(`Unknown product type ${productType}`);
}
}

View File

@ -2,21 +2,13 @@ import NotImplementedException from 'Common/Types/Exception/NotImplementedExcept
import ObjectID from 'Common/Types/ObjectID';
import BillingService from '../../../Services/BillingService';
import MeteredPlan from 'Common/Types/Billing/MeteredPlan';
import { ProductType } from 'Model/Models/TelemetryUsageBilling';
import ProductType from 'Common/Types/MeteredPlan/ProductType';
export default class ServerMeteredPlan {
public getProductType(): ProductType {
throw new NotImplementedException();
}
public async getCostByProjectId(
projectId: ObjectID,
quantity: number
): Promise<number> {
const meteredPlan: MeteredPlan = await this.getMeteredPlan(projectId);
return this.getCostByMeteredPlan(meteredPlan, quantity);
}
public getCostByMeteredPlan(
meteredPlan: MeteredPlan,
quantity: number
@ -24,13 +16,6 @@ export default class ServerMeteredPlan {
return meteredPlan.getPricePerUnit() * quantity;
}
public async getMeteredPlan(projectId: ObjectID): Promise<MeteredPlan> {
return await BillingService.getMeteredPlan({
projectId: projectId,
productType: this.getProductType(),
});
}
public async reportQuantityToBillingProvider(
_projectId: ObjectID,
_options: {

View File

@ -3,9 +3,11 @@ import ObjectID from 'Common/Types/ObjectID';
import ProjectService from '../../../Services/ProjectService';
import BillingService from '../../../Services/BillingService';
import Project from 'Model/Models/Project';
import TelemetryUsageBilling, { ProductType } from 'Model/Models/TelemetryUsageBilling';
import TelemetryUsageBilling from 'Model/Models/TelemetryUsageBilling';
import TelemetryUsageBillingService from '../../../Services/TelemetryUsageBillingService';
import OneUptimeDate from 'Common/Types/Date';
import ProductType from 'Common/Types/MeteredPlan/ProductType';
export default class TelemetryMeteredPlan extends ServerMeteredPlan {
private _productType!: ProductType;

View File

@ -1,4 +1,4 @@
import { ProductType } from 'Model/Models/UsageBilling';
import ProductType from 'Common/Types/MeteredPlan/ProductType';
import Express, {
ExpressRequest,
ExpressResponse,

View File

@ -8,15 +8,17 @@ import BadRequestException from 'Common/Types/Exception/BadRequestException';
import GlobalCache from 'CommonServer/Infrastructure/GlobalCache';
import DiskSize from 'Common/Types/DiskSize';
import ObjectID from 'Common/Types/ObjectID';
import UsageBillingService from 'CommonServer/Services/UsageBillingService';
import { ProductType } from 'Model/Models/UsageBilling';
import TelemetryUsageBillingService from 'CommonServer/Services/TelemetryUsageBillingService';
import ProductType from 'Common/Types/MeteredPlan/ProductType';
import TelemetryServiceService from 'CommonServer/Services/TelemetryServiceService';
import TelemetryService from 'Model/Models/TelemetryService';
import logger from 'CommonServer/Utils/Logger';
import { DEFAULT_RETENTION_IN_DAYS } from 'Model/Models/TelemetryUsageBilling';
export interface TelemetryRequest extends ExpressRequest {
serviceId: ObjectID; // Service ID
projectId: ObjectID; // Project ID
dataRententionInDays: number; // how long the data should be retained.
productType: ProductType; // what is the product type of the request - logs, metrics or traces.
}
@ -68,6 +70,7 @@ export default class TelemetryIngest {
select: {
_id: true,
projectId: true,
retainTelemetryDataForDays: true,
},
props: {
isRoot: true,
@ -92,6 +95,7 @@ export default class TelemetryIngest {
(req as TelemetryRequest).serviceId = service.id as ObjectID;
(req as TelemetryRequest).projectId =
service.projectId as ObjectID;
(req as TelemetryRequest).dataRententionInDays = service.retainTelemetryDataForDays || DEFAULT_RETENTION_IN_DAYS;
}
(req as TelemetryRequest).serviceId = ObjectID.fromString(
@ -102,10 +106,12 @@ export default class TelemetryIngest {
);
// report to Usage Service.
UsageBillingService.updateUsageBilling({
TelemetryUsageBillingService.updateUsageBilling({
projectId: (req as TelemetryRequest).projectId,
productType: (req as TelemetryRequest).productType,
usageCount: sizeToGb,
dataIngestedInGB: sizeToGb,
telemetryServiceId: (req as TelemetryRequest).serviceId,
retentionInDays: (req as TelemetryRequest).dataRententionInDays,
}).catch((err: Error) => {
logger.error('Failed to update usage billing for OTel');
logger.error(err);

View File

@ -17,12 +17,11 @@ import IconProp from 'Common/Types/Icon/IconProp';
import Decimal from 'Common/Types/Decimal';
import BaseModel from 'Common/Models/BaseModel';
import TelemetryService from './TelemetryService';
import ProductType from 'Common/Types/MeteredPlan/ProductType';
export const DEFAULT_RETENTION_IN_DAYS: number = 15;
export enum ProductType {
Logs = 'Logs',
Traces = 'Traces',
Metrics = 'Metrics',
}
@TenantColumn('projectId')
@TableAccessControl({
@ -169,7 +168,7 @@ export default class TelemetryUsageBilling extends BaseModel {
type: ColumnType.Number,
nullable: true,
unique: false,
default: 15,
default: DEFAULT_RETENTION_IN_DAYS,
})
public retainTelemetryDataForDays?: number = undefined;