Added lock API on Billing
MODIFY
src/integration/billing/BillingIntegration.ts
src/integration/billing/BillingIntegration.ts
@@ -12,6 +12,8 @@ import Transaction from '../../types/Transaction';
import { UserInErrorType } from '../../types/InError';
import UserStorage from '../../storage/mongodb/UserStorage';
import Utils from '../../utils/Utils';
+import LockingManager from '../../locking/LockingManager';
+import { LockEntity } from '../../types/Locking';
const MODULE_NAME = 'BillingIntegration';
@@ -25,6 +27,8 @@ export default abstract class BillingIntegration<T extends BillingSetting> {
}
public async synchronizeUsers(tenantID: string): Promise<BillingUserSynchronizeAction> {
+ const billingLock = LockingManager.createExclusiveLock(this.tenantID, LockEntity.USER, 'synchronize-billing-users');
+ if (await LockingManager.acquire(billingLock)) {
await this.checkConnection();
// Check
const actionsDone: BillingUserSynchronizeAction = {
@@ -142,6 +146,7 @@ export default abstract class BillingIntegration<T extends BillingSetting> {
}
}
}
+
// Log
Utils.logActionsResponse(tenantID, ServerAction.BILLING_SYNCHRONIZE_USERS,
MODULE_NAME, 'synchronizeUsers', actionsDone,
@@ -154,9 +159,11 @@ export default abstract class BillingIntegration<T extends BillingSetting> {
const billingSettings = await SettingStorage.getBillingSettings(tenantID);
billingSettings.stripe.usersLastSynchronizedOn = new Date();
await SettingStorage.saveBillingSettings(tenantID, billingSettings);
+ await LockingManager.release(billingLock);
// Result
return actionsDone;
}
+ }
public async synchronizeUser(user: User, tenantID: string): Promise<void> {
try {
@@ -208,6 +215,8 @@ export default abstract class BillingIntegration<T extends BillingSetting> {
}
public async forceSynchronizeUser(user: User, tenantID: string): Promise<void> {
+ const billingLock = LockingManager.createExclusiveLock(this.tenantID, LockEntity.USER, 'force-synchronize-billing-users');
+ if (await LockingManager.acquire(billingLock)) {
let billingUser: BillingUser;
try {
billingUser = await this.getUserByEmail(user.email);
@@ -233,6 +242,7 @@ export default abstract class BillingIntegration<T extends BillingSetting> {
message: `Successfully forced the synchronization of the user '${user.email}'`,
});
} catch (error) {
+ await LockingManager.release(billingLock);
throw new BackendError({
source: Constants.CENTRAL_SERVER,
module: MODULE_NAME, method: 'forceSynchronizeUser',
@@ -255,10 +265,15 @@ export default abstract class BillingIntegration<T extends BillingSetting> {
message: `Cannot force synchronize invoices for user '${user.email}'`,
detailedMessages: { error: error.message, stack: error.stack }
});
+ } finally {
+ await LockingManager.release(billingLock);
+ }
}
}
public async forceSynchronizeUserInvoices(tenantID: string, user: User): Promise<ActionsResponse> {
+ const billingLock = LockingManager.createExclusiveLock(this.tenantID, LockEntity.USER, 'force-synchronize-billing-invoices');
+ if (await LockingManager.acquire(billingLock)) {
let billingUser: BillingUser = null;
const actionsDone: ActionsResponse = {
inSuccess: 0,
@@ -364,10 +379,14 @@ export default abstract class BillingIntegration<T extends BillingSetting> {
'{{inSuccess}} invoice(s) were successfully synchronized and {{inError}} failed to be synchronized',
'All the invoices are up to date'
);
+ await LockingManager.release(billingLock);
return actionsDone;
}
+ }
public async synchronizeInvoices(tenantID: string, user?: User): Promise<BillingUserSynchronizeAction> {
+ const billingLock = LockingManager.createExclusiveLock(this.tenantID, LockEntity.USER, 'synchronize-billing-invoices');
+ if (await LockingManager.acquire(billingLock)) {
let billingUser: BillingUser = null;
const actionsDone: BillingUserSynchronizeAction = {
inSuccess: 0,
@@ -487,8 +506,10 @@ export default abstract class BillingIntegration<T extends BillingSetting> {
billingSettings.stripe.invoicesLastSynchronizedOn = new Date();
await SettingStorage.saveBillingSettings(tenantID, billingSettings);
}
+ await LockingManager.release(billingLock);
return actionsDone;
}
+ }
private async checkAndGetBillingUser(user: User): Promise<BillingUser> {
const billingUser = await this.getUserByEmail(user.email);

MODIFY
test/api/BillingTest.ts
test/api/BillingTest.ts
@@ -181,7 +181,7 @@ describe('Billing Service', function() {
fakeUser,
false
);
- // TestData.createdUsers.push(fakeUser);
+ testData.createdUsers.push(fakeUser);
const billingUser = await billingImpl.getUserByEmail(fakeUser.email);
expect(billingUser.name).to.be.eq(fakeUser.firstName + ' ' + fakeUser.name);
});

Added lock API on Billing