@c8y/client
Version:
Client application programming interface to access the Cumulocity IoT-Platform REST services.
574 lines • 20.9 kB
JavaScript
import { __awaiter } from "tslib";
import { Service } from '../core/index.js';
import { InventoryService } from '../inventory/index.js';
import { TenantService } from '../tenant/index.js';
import { UserService } from '../user/index.js';
import { ApplicationBinaryService } from './ApplicationBinaryService.js';
import { ApplicationType } from './ApplicationType.js';
import { gettext } from '../gettext.js';
export class ApplicationService extends Service {
constructor() {
super(...arguments);
this.baseUrl = 'application';
this.listUrl = 'applications';
this.propertyName = 'applications';
this.channel = '/applications/*';
}
/**
* Creates a new application.
*
* @param {IIdentified} entity Application object.
*
* @returns Response wrapped in [[IResult]]
*
* **Example**
* ```typescript
*
* const newApp = {
* name: 'New application',
* type: 'EXTERNAL',
* key: 'new-app'
* };
*
* (async () => {
* const {data, res} = await applicationService.create(newApp);
* })();
* ```
*/
create(entity) {
const _super = Object.create(null, {
create: { get: () => super.create }
});
return __awaiter(this, void 0, void 0, function* () {
return _super.create.call(this, entity);
});
}
/**
* Clones a given application. The application name, key, and context-path will be
* prefixed with `clone` and if necessary a number.
* @param entity The application to clone.
* @param version If a blueprint, you can define which version to clone. If not provided, it will always clone the latest version.
* @returns The application entity.
*/
clone(entity, version) {
return __awaiter(this, void 0, void 0, function* () {
const url = `${this.getDetailUrl(entity)}/clone`;
const method = 'POST';
const body = '';
const headers = { 'content-type': 'application/json', accept: 'application/json' };
let params = undefined;
if (version) {
params = { version };
}
const res = yield this.fetch(url, { method, body, headers, params });
const data = yield res.json();
return { res, data };
});
}
/**
* Gets the list of existing applications filtered by parameters.
*
* @returns Response wrapped in [[IResultList]]
*
* @param {object} filter Object containing filters for querying applications.
*
* **Example**
* ```typescript
*
* const filter: object = {
* pageSize: 100,
* withTotalPages: true
* };
*
* (async () => {
* const {data, res, paging} = await applicationService.list(filter);
* })();
* ```
*/
list() {
const _super = Object.create(null, {
list: { get: () => super.list }
});
return __awaiter(this, arguments, void 0, function* (filter = {}) {
return _super.list.call(this, filter);
});
}
/**
* Gets the list of all application versions.
*
* @param {string|number|IIdentified} entityOrId Entity or Id of the entity.
*
* @param {object} params Additional request parameters.
*
* @returns Returns list of all application versions.
*
* **Example**
* ```typescript
*
* const applicationId: number = 1;
*
* (async () => {
* const {res, data} = await applicationService.listVersions(applicationId);
* })();
* ```
*/
listVersions(entityOrId_1) {
return __awaiter(this, arguments, void 0, function* (entityOrId, params = {}) {
var _a;
const id = this.getEntityId(entityOrId);
const url = `${this.listUrl}/${id}/versions`;
const headers = { 'content-type': 'application/json' };
try {
const res = yield this.fetch(url, { headers, params });
const data = (_a = (yield res.json())) === null || _a === void 0 ? void 0 : _a.applicationVersions;
return { res, data };
}
catch (ex) {
if (ex.res.status === 404) {
const { data: appDetail, res } = yield this.detail(entityOrId);
return { res, data: appDetail.applicationVersions };
}
throw ex;
}
});
}
/**
* Gets the details of selected application.
*
* @param {string|number|IIdentified} entityOrId Entity or Id of the entity.
*
* @returns Response wrapped in [[IResult]]
*
* **Example**
* ```typescript
*
* const applicationId: number = 1;
*
* (async () => {
* const {data, res} = await applicationService.detail(applicationId);
* })();
* ```
*/
detail(entityOrId) {
const _super = Object.create(null, {
detail: { get: () => super.detail }
});
return __awaiter(this, void 0, void 0, function* () {
return _super.detail.call(this, entityOrId);
});
}
/**
* Allows to retrieve bootstrap user credentials for a specific application (microservice).
* @param {string|number|IIdentified} entityOrId Entity or Id of the entity.
* @returns Response wrapped in [[IResult]]
*/
getBootstrapUser(entityOrId) {
return __awaiter(this, void 0, void 0, function* () {
const url = `${this.getDetailUrl(entityOrId)}/bootstrapUser`;
const res = yield this.fetch(url);
const data = yield res.json();
return { res, data };
});
}
/**
* Updates existing application.
* Make sure that you specifiy the application id within the update object.
*
* @param {IIdentified} entity Application object.
*
* @returns Response wrapped in [[IResult]]
*
* **Example**
* ```typescript
*
* const updateApp = {
* id: 38
* name: 'Updated application'
* };
*
* (async () => {
* const {data, res} = await applicationService.update(updateApp);
* })();
* ```
*/
update(entity) {
const _super = Object.create(null, {
update: { get: () => super.update }
});
return __awaiter(this, void 0, void 0, function* () {
return _super.update.call(this, entity);
});
}
/**
* Removes an application with given id.
*
* @returns Response wrapped in [[IResult]]
*
* @param {string | number | IIdentified} entityOrId entity or id of the application.
*
* **Example**
* ```typescript
*
* const removeApp: object = {
* id: 38
* };
*
* (async () => {
* const {data, res} = await applicationService.delete(removeApp);
* // data will be null
* })();
* ```
*/
delete(entityOrId) {
const _super = Object.create(null, {
delete: { get: () => super.delete }
});
return __awaiter(this, void 0, void 0, function* () {
return _super.delete.call(this, entityOrId);
});
}
listByName(name_1) {
return __awaiter(this, arguments, void 0, function* (name, params = {}) {
const headers = { 'content-type': 'application/json' };
const url = `applicationsByName/${encodeURIComponent(name)}`;
const res = yield this.fetch(url, { headers, params });
const json = yield res.json();
const data = json[this.propertyName];
return { res, data };
});
}
listByTenant(tenantOrName_1) {
return __awaiter(this, arguments, void 0, function* (tenantOrName, params = {}) {
const headers = { 'content-type': 'application/json' };
const tenantService = new TenantService(this.client);
const tenantName = this.getIdString(tenantOrName || (yield tenantService.current()).data.name);
const url = `applicationsByTenant/${encodeURIComponent(tenantName)}`;
const res = yield this.fetch(url, { headers, params });
const json = yield res.json();
const data = json[this.propertyName];
return { res, data };
});
}
listByOwner(tenantOrName_1) {
return __awaiter(this, arguments, void 0, function* (tenantOrName, params = {}) {
const headers = { 'content-type': 'application/json' };
const tenantService = new TenantService(this.client);
const tenantName = this.getIdString(tenantOrName || (yield tenantService.current()).data.name);
const url = `applicationsByOwner/${encodeURIComponent(tenantName)}`;
const res = yield this.fetch(url, { headers, params });
const json = yield res.json();
const data = json[this.propertyName];
return { res, data };
});
}
listByUser(userOrId_1) {
return __awaiter(this, arguments, void 0, function* (userOrId, params = {}) {
const headers = { 'content-type': 'application/json' };
const userService = new UserService(this.client);
const userId = this.getIdString(userOrId || (yield userService.current()).data);
const url = `applicationsByUser/${encodeURIComponent(userId)}`;
const res = yield this.fetch(url, { headers, params });
const json = yield res.json();
const data = json[this.propertyName];
return { res, data };
});
}
reactivateArchive(appId) {
return __awaiter(this, void 0, void 0, function* () {
const url = `${this.listUrl}/${appId}/refresh`;
const method = 'POST';
const body = '';
const headers = { 'content-type': 'application/json', accept: 'application/json' };
const res = yield this.fetch(url, { method, body, headers });
return { res, data: null };
});
}
binary(application) {
return new ApplicationBinaryService(this.client, application);
}
getHref(application) {
if (application.type === ApplicationType.EXTERNAL) {
return application.externalUrl;
}
return `/apps/${application.public ? 'public/' : ''}${application.contextPath}`;
}
/**
* Checks if current user can access specified application.
*
* @returns Response wrapped in [[IResult]]
*
* @param {string | IApplication} application Application name or contextPath as a
* string or Application object.
*
* **Example**
* ```typescript
*
* const checkApp: object = {
* name: 'myApplication'
* };
*
* (async () => {
* const {data, res} = await applicationService.isAvailable(checkApp);
* })();
* ```
*/
isAvailable(application) {
return __awaiter(this, void 0, void 0, function* () {
const { res, data } = yield this.listByUser(undefined, {
dropOverwrittenApps: true,
noPaging: true
});
const available = (data || []).some((availableApp) => typeof application === 'string'
? availableApp.name === application || availableApp.contextPath === application
: this.isMatch(availableApp, application));
return { data: available, res };
});
}
/**
* Gets instance details of the specified application (microservice).
*
* @param {string|number|IApplication} entityOrId Entity or Id of the application.
*
* @returns Response wrapped in [[IResultList]]
*
* **Example**
* ```typescript
*
* const applicationId: number = 1;
*
* (async () => {
* const {data, res} = await applicationService.getStatusDetails(applicationId);
* })();
* ```
*/
getStatusDetails(entityOrId) {
return __awaiter(this, void 0, void 0, function* () {
const appId = this.getEntityId(entityOrId);
const inventory = new InventoryService(this.client, this.realtime);
return inventory.list({ type: `c8y_Application_${appId}` });
});
}
/**
* Extracts instance names of the provided IApplicationManagedObject.
*
* @param {IApplicationManagedObject} appStatusDetails Application details managedObject.
*
* @returns instance names
*
* **Example**
* ```typescript
*
* const applicationId: number = 1;
*
* (async () => {
* const {data, res} = await applicationService.getStatusDetails(applicationId);
* const instances = data.map((appMO) => applicationService.getInstanceNames(appMO));
* })();
* ```
*/
getInstanceNames(appStatusDetails) {
let instanceNames = new Array();
if (appStatusDetails && appStatusDetails.c8y_Status && appStatusDetails.c8y_Status.instances) {
instanceNames = Object.keys(appStatusDetails.c8y_Status.instances);
}
return instanceNames;
}
/**
* Get log for a specific application instance.
*
* @param {string|number|IApplication} entityOrId Entity or Id of the application.
*
* @param {string} instanceName instance name of the application.
*
* @param {IApplicationInstanceLogRequestParams} params Object containing parameters for querying the log file.
*
* @returns Response wrapped in [[IResult]]
*
* **Example**
* ```typescript
*
* const applicationId: number = 1;
* const applicationInstanceName: string = 'apama-ctrl-1c-4g-scope-t123456789-deployment-abcdefghij-abcde';
*
* (async () => {
* const {data, res} = await applicationService.getInstanceLog(applicationId, applicationInstanceName);
* })();
* ```
*/
getInstanceLog(entityOrId, instanceName, params) {
return __awaiter(this, void 0, void 0, function* () {
const url = `${this.getDetailUrl(entityOrId)}/logs/${instanceName}`;
const headers = { accept: this.mimeType('applicationLogs') };
const res = yield this.fetch(url, { headers, params });
const data = yield res.json();
return { res, data };
});
}
/**
* Dynamic options are stored on the API in a specific `config: {}` object. They can
* be used to configure the app dynamically.
*
* Note: To avoids conflicts with the default Config, it is recommended
* to use a certain namespace.
* @param entityOrId Entity or Id of the application.
* @param config Configuration to be updated.
* @returns Returns updated configuration.
*/
updateApplicationConfig(entityOrId, config) {
return __awaiter(this, void 0, void 0, function* () {
var _a;
const id = this.getEntityId(entityOrId);
const { data: app } = yield this.detail(id);
const currentConfig = (app === null || app === void 0 ? void 0 : app.config) || {};
const newConfig = Object.assign(Object.assign({}, currentConfig), config);
const updatedConfigApp = yield this.update({
id,
config: newConfig
});
return (_a = (yield updatedConfigApp)) === null || _a === void 0 ? void 0 : _a.data;
});
}
/**
* Gets manifest (cumulocity.json file) of a given application.
*
* @param {IApplication} app Application entity.
*
* @param {string} app version
*
* @returns Application manifest object.
*/
getAppManifest(app, version) {
return __awaiter(this, void 0, void 0, function* () {
const date = new Date();
let result;
if (!version) {
result = yield this.client.fetch(`/apps/${app.contextPath}/cumulocity.json?nocache=${date.getTime()}`);
}
else {
result = yield this.client.fetch(`/apps/${app.contextPath}@${version}/cumulocity.json?nocache=${date.getTime()}`);
}
if (result.status >= 400) {
throw new Error(gettext('No Cumulocity IoT manifest found.'));
}
const c8yJson = yield result.json();
return c8yJson;
});
}
/**
* Updates manifest (cumulocity.json file) of a given application.
*
* @param {string|number|IApplication} entityOrId Entity or Id of the application.
*
* @param {any} manifestJSON Application manifest object to be stored.
*
* @returns Application manifest object.
*/
storeAppManifest(entityOrId, manifestJSON) {
return __awaiter(this, void 0, void 0, function* () {
return yield this.binary(entityOrId).updateFiles([
{ path: 'cumulocity.json', contents: JSON.stringify(manifestJSON) }
]);
});
}
/**
* Sets tags for specific application package version.
*
* @param {IApplication} app Application entity.
*
* @param {string} version Application package version which tags will be set.
*
* @param {string[]} tags Tags array to set on package version
*
* @returns Application version object.
*/
setPackageVersionTag(app, version, tags) {
return __awaiter(this, void 0, void 0, function* () {
const url = `${this.getDetailUrl(app)}/versions/${version}`;
const method = 'PUT';
const body = JSON.stringify({ tags });
const headers = {
accept: 'application/vnd.com.nsn.cumulocity.applicationVersion+json;charset=UTF-8;ver=0.9',
'content-type': 'application/json'
};
const res = yield this.fetch(url, { method, body, headers });
const data = yield res.json();
return { res, data };
});
}
/**
* Retrieves the manifest of the application behind the given context path.
* @param contextPath
*/
getManifestOfContextPath(contextPath) {
return __awaiter(this, void 0, void 0, function* () {
const url = `${this.getDetailUrl(contextPath)}/manifest`;
const res = yield this.fetch(url);
const { application } = yield res.json();
return {
res,
data: application
};
});
}
/**
* Removes package version.
*
* @param {IApplication} app Application entity.
*
* @param {IApplicationVersionDeleteParams} params Version or tag indication package to remove.
*
* @returns Request response.
*
* **Example**
* ```typescript
*
* const { res } = await applicationService.deleteVersionPackage(app, {version: '1.0.0'});
*
* const { res } = await applicationService.deleteVersionPackage(app, {tag: 'next'});
*
* ```
*/
deleteVersionPackage(app, params) {
return __awaiter(this, void 0, void 0, function* () {
const url = `${this.getDetailUrl(app)}/versions/`;
const method = 'DELETE';
const res = yield this.fetch(url, this.changeFetchOptions({ method, params }, url));
return { res, data: null };
});
}
/**
* Updates the availability of the given application to the provided value.
*
* @param {string|number|IApplication} entityOrId Entity or Id of the application.
*
* @param {any} availability The new application availability.
*
* @returns Updated application.
*/
updateApplicationAvailability(entityOrId, availability) {
return __awaiter(this, void 0, void 0, function* () {
const id = this.getEntityId(entityOrId);
return yield this.update({
id,
availability
});
});
}
isMatch(object, source) {
return Object.keys(source).every(key => {
if (Array.isArray(object[key]) && Array.isArray(source[key])) {
return source[key].every(el => object[key].includes(el));
}
else if (typeof object[key] === 'object' &&
object[key] !== null &&
typeof source[key] === 'object' &&
source[key] !== null) {
return this.isMatch(object[key], source[key]);
}
else {
return object[key] === source[key];
}
});
}
}
//# sourceMappingURL=ApplicationService.js.map