asset  - token caching for better performance
MODIFY
src/integration/asset/iothink/IothinkAssetIntegration.ts
src/integration/asset/iothink/IothinkAssetIntegration.ts
-import Asset, { AssetType, IothinkProperty } from '../../../types/Asset';
-import { AssetConnectionSetting, AssetSetting } from '../../../types/Setting';
+import Asset, { AssetConnectionToken, AssetType, IothinkProperty } from '../../../types/Asset';
+import { AssetConnectionSetting, AssetConnectionType, AssetSetting } from '../../../types/Setting';
import { AbstractCurrentConsumption } from '../../../types/Consumption';
import AssetIntegration from '../AssetIntegration';
+import AssetTokenCache from '../../../utils/TokenManager';
import AxiosFactory from '../../../utils/AxiosFactory';
import { AxiosInstance } from 'axios';
import BackendError from '../../../exception/BackendError';
@@ -147,11 +148,19 @@ export default class IothinkAssetIntegration extends AssetIntegration<AssetSetti
}
private async connect(): Promise<string> {
- // Check if connection is initialized
+ // Get token from cache
+ let token = AssetTokenCache.getInstanceForTenant(this.tenant).getToken(AssetConnectionType.IOTHINK);
+ if (!token) {
this.checkConnectionIsProvided();
- // Get credential params
- const credentials = await this.getCredentialURLParams();
- // Send credentials to get the token
+ // Get a fresh token (if not found or expired)
+ token = await this.fetchAssetProviderToken(await this.getCredentialURLParams());
+ // Cache it for better performance
+ AssetTokenCache.getInstanceForTenant(this.tenant).setToken(AssetConnectionType.IOTHINK, token);
+ }
+ return token.accessToken;
+ }
+
+ private async fetchAssetProviderToken(credentials: URLSearchParams): Promise<AssetConnectionToken> {
const response = await Utils.executePromiseWithTimeout(5000,
this.axiosInstance.post(`${this.connection.url}/token`,
credentials,
@@ -163,8 +172,15 @@ export default class IothinkAssetIntegration extends AssetIntegration<AssetSetti
}),
`Time out error (5s) when getting the token with the connection URL '${this.connection.url}/token'`
);
- // Return the Token
- return response.data.access_token;
+ const data = response.data;
+ return {
+ accessToken: await Cypher.encrypt(this.tenant, data.access_token),
+ tokenType: data.token_type,
+ expiresIn: data.expires_in,
+ userName: data.userName,
+ issued: data['.issued'],
+ expires: data['.expires']
+ };
}
private async getCredentialURLParams(): Promise<URLSearchParams> {

ADD
src/utils/TokenManager.ts
+import { AssetConnectionTokenSetting, AssetConnectionType } from '../types/Setting';
+
+import Tenant from '../types/Tenant';
+import moment from 'moment';
+
+export default class AssetTokenCache {
+ private static instances = new Map<string, AssetTokenCache>();
+ private tokens = new Map<AssetConnectionType, AssetConnectionTokenSetting>();
+
+ public static getInstanceForTenant(tenant: Tenant): AssetTokenCache {
+ if (!AssetTokenCache.instances.has(tenant.id)) {
+ AssetTokenCache.instances.set(tenant.id, new AssetTokenCache());
+ }
+ return AssetTokenCache.instances.get(tenant.id);
+ }
+
+ public getToken(assetConnectionType: AssetConnectionType): AssetConnectionTokenSetting {
+ const token = this.tokens.get(assetConnectionType);
+ if (token && !moment(new Date(token.expires)).subtract(60, 'seconds').isBefore()) {
+ return token;
+ }
+ return null;
+ }
+
+ public setToken(assetConnectionType: AssetConnectionType, token: AssetConnectionTokenSetting): void {
+ this.tokens.set(assetConnectionType, token);
+ }
+}

asset  - token caching for better performance