mirror of
https://github.com/nasa/openmct.git
synced 2024-12-20 21:53:08 +00:00
Add support for multiple CouchDB databases, multiple namespaces, and readOnly
configurations (#7413)
* two namespaces appear * works with two databases * try to batch requests * fix indicators * add option to omit root for myitems * ready for review * ready for review * ready for review * typo in README * spelling * spelling * update readme * fix tests * Update src/plugins/persistence/couch/README.md Co-authored-by: Jesse Mazzella <ozyx@users.noreply.github.com> * remove omitRoot * remove omitRoot * fix my items to check for namespace when intercepting * update readme --------- Co-authored-by: Jesse Mazzella <ozyx@users.noreply.github.com> Co-authored-by: Andrew Henry <akhenry@gmail.com>
This commit is contained in:
parent
69b81c00ca
commit
d42aa545bb
@ -493,6 +493,7 @@
|
|||||||
"WCAG",
|
"WCAG",
|
||||||
"stackedplot",
|
"stackedplot",
|
||||||
"Andale",
|
"Andale",
|
||||||
|
"unnnormalized",
|
||||||
"checksnapshots",
|
"checksnapshots",
|
||||||
"specced"
|
"specced"
|
||||||
],
|
],
|
||||||
|
@ -354,6 +354,9 @@ export default class ObjectAPI {
|
|||||||
isPersistable(idOrKeyString) {
|
isPersistable(idOrKeyString) {
|
||||||
let identifier = utils.parseKeyString(idOrKeyString);
|
let identifier = utils.parseKeyString(idOrKeyString);
|
||||||
let provider = this.getProvider(identifier);
|
let provider = this.getProvider(identifier);
|
||||||
|
if (provider?.isReadOnly) {
|
||||||
|
return !provider.isReadOnly();
|
||||||
|
}
|
||||||
|
|
||||||
return provider !== undefined && provider.create !== undefined && provider.update !== undefined;
|
return provider !== undefined && provider.create !== undefined && provider.update !== undefined;
|
||||||
}
|
}
|
||||||
|
@ -38,7 +38,6 @@ describe('the plugin', function () {
|
|||||||
|
|
||||||
let couchPlugin = openmct.plugins.CouchDB(testPath);
|
let couchPlugin = openmct.plugins.CouchDB(testPath);
|
||||||
openmct.install(couchPlugin);
|
openmct.install(couchPlugin);
|
||||||
|
|
||||||
openmct.install(
|
openmct.install(
|
||||||
new CouchDBSearchFolderPlugin('CouchDB Documents', couchPlugin, {
|
new CouchDBSearchFolderPlugin('CouchDB Documents', couchPlugin, {
|
||||||
selector: {
|
selector: {
|
||||||
|
@ -74,6 +74,10 @@ export default class LocalStorageObjectProvider {
|
|||||||
this.localStorage.setItem(this.spaceKey, JSON.stringify(space));
|
this.localStorage.setItem(this.spaceKey, JSON.stringify(space));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isReadOnly() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
|
@ -1,8 +1,26 @@
|
|||||||
# My Items plugin
|
# My Items plugin
|
||||||
Defines top-level folder named "My Items" to store user-created items. Enabled by default, this can be disabled in a
|
Defines top-level folder named "My Items" to store user-created items. Enabled by default, this can be disabled in a read-only deployment with no user-editable objects.
|
||||||
read-only deployment with no user-editable objects.
|
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
```js
|
```js
|
||||||
openmct.install(openmct.plugins.MyItems());
|
openmct.install(openmct.plugins.MyItems());
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Options
|
||||||
|
When installing, the plugin can take several options:
|
||||||
|
|
||||||
|
- `name`: The label of the root object. Defaults to "My Items"
|
||||||
|
- Example: `'Apple Items'`
|
||||||
|
|
||||||
|
- `namespace`: The namespace to create the root object in. Defaults to the empty string `''`
|
||||||
|
- Example: `'apple-namespace'`
|
||||||
|
|
||||||
|
- `priority`: The optional priority to install this plugin. Defaults to `openmct.priority.LOW`
|
||||||
|
- Example: `'openmct.priority.LOW'`
|
||||||
|
|
||||||
|
E.g., to install with a custom name and namespace, you could use:
|
||||||
|
|
||||||
|
|
||||||
|
```js
|
||||||
|
openmct.install(openmct.plugins.MyItems('Apple Items', 'apple-namespace'));
|
||||||
|
```
|
@ -20,9 +20,7 @@
|
|||||||
* at runtime from the About dialog for additional information.
|
* at runtime from the About dialog for additional information.
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
import { MY_ITEMS_KEY } from './createMyItemsIdentifier.js';
|
function myItemsInterceptor({ openmct, identifierObject, name }) {
|
||||||
|
|
||||||
function myItemsInterceptor(openmct, identifierObject, name) {
|
|
||||||
const myItemsModel = {
|
const myItemsModel = {
|
||||||
identifier: identifierObject,
|
identifier: identifierObject,
|
||||||
name,
|
name,
|
||||||
@ -33,7 +31,10 @@ function myItemsInterceptor(openmct, identifierObject, name) {
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
appliesTo: (identifier) => {
|
appliesTo: (identifier) => {
|
||||||
return identifier.key === MY_ITEMS_KEY;
|
return (
|
||||||
|
identifier.key === myItemsModel.identifier.key &&
|
||||||
|
identifier.namespace === myItemsModel.identifier.namespace
|
||||||
|
);
|
||||||
},
|
},
|
||||||
invoke: (identifier, object) => {
|
invoke: (identifier, object) => {
|
||||||
if (!object || openmct.objects.isMissing(object)) {
|
if (!object || openmct.objects.isMissing(object)) {
|
||||||
|
@ -31,13 +31,13 @@ export default function MyItemsPlugin(
|
|||||||
priority = undefined
|
priority = undefined
|
||||||
) {
|
) {
|
||||||
return function install(openmct) {
|
return function install(openmct) {
|
||||||
const identifier = createMyItemsIdentifier(namespace);
|
const identifierObject = createMyItemsIdentifier(namespace);
|
||||||
|
|
||||||
if (priority === undefined) {
|
if (priority === undefined) {
|
||||||
priority = openmct.priority.LOW;
|
priority = openmct.priority.LOW;
|
||||||
}
|
}
|
||||||
|
|
||||||
openmct.objects.addGetInterceptor(myItemsInterceptor(openmct, identifier, name));
|
openmct.objects.addGetInterceptor(myItemsInterceptor({ openmct, identifierObject, name }));
|
||||||
openmct.objects.addRoot(identifier, priority);
|
openmct.objects.addRoot(identifierObject, priority);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -80,7 +80,7 @@
|
|||||||
keepAliveTimer = setTimeout(self.listenForChanges, keepAliveTime);
|
keepAliveTimer = setTimeout(self.listenForChanges, keepAliveTime);
|
||||||
|
|
||||||
if (!couchEventSource || couchEventSource.readyState === EventSource.CLOSED) {
|
if (!couchEventSource || couchEventSource.readyState === EventSource.CLOSED) {
|
||||||
console.debug('⇿ Opening CouchDB change feed connection ⇿');
|
console.debug(`⇿ Opening CouchDB change feed connection for ${changesFeedUrl} ⇿`);
|
||||||
couchEventSource = new EventSource(changesFeedUrl);
|
couchEventSource = new EventSource(changesFeedUrl);
|
||||||
couchEventSource.onerror = self.onerror;
|
couchEventSource.onerror = self.onerror;
|
||||||
couchEventSource.onopen = self.onopen;
|
couchEventSource.onopen = self.onopen;
|
||||||
@ -88,7 +88,7 @@
|
|||||||
// start listening for events
|
// start listening for events
|
||||||
couchEventSource.addEventListener('message', self.onCouchMessage);
|
couchEventSource.addEventListener('message', self.onCouchMessage);
|
||||||
connected = true;
|
connected = true;
|
||||||
console.debug('⇿ Opened connection ⇿');
|
console.debug(`⇿ Opened connection to ${changesFeedUrl} ⇿`);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -33,13 +33,13 @@ const HEARTBEAT = 50000;
|
|||||||
const ALL_DOCS = '_all_docs?include_docs=true';
|
const ALL_DOCS = '_all_docs?include_docs=true';
|
||||||
|
|
||||||
class CouchObjectProvider {
|
class CouchObjectProvider {
|
||||||
constructor(openmct, options, namespace, indicator) {
|
constructor({ openmct, databaseConfiguration, couchStatusIndicator }) {
|
||||||
options = this.#normalize(options);
|
|
||||||
this.openmct = openmct;
|
this.openmct = openmct;
|
||||||
this.indicator = indicator;
|
this.indicator = couchStatusIndicator;
|
||||||
this.url = options.url;
|
this.url = databaseConfiguration.url;
|
||||||
this.useDesignDocuments = options.useDesignDocuments;
|
this.readOnly = databaseConfiguration.readOnly;
|
||||||
this.namespace = namespace;
|
this.useDesignDocuments = databaseConfiguration.useDesignDocuments;
|
||||||
|
this.namespace = databaseConfiguration.namespace;
|
||||||
this.objectQueue = {};
|
this.objectQueue = {};
|
||||||
this.observers = {};
|
this.observers = {};
|
||||||
this.batchIds = [];
|
this.batchIds = [];
|
||||||
@ -47,6 +47,7 @@ class CouchObjectProvider {
|
|||||||
this.onEventError = this.onEventError.bind(this);
|
this.onEventError = this.onEventError.bind(this);
|
||||||
this.flushPersistenceQueue = _.debounce(this.flushPersistenceQueue.bind(this));
|
this.flushPersistenceQueue = _.debounce(this.flushPersistenceQueue.bind(this));
|
||||||
this.persistenceQueue = [];
|
this.persistenceQueue = [];
|
||||||
|
this.rootObject = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -59,7 +60,10 @@ class CouchObjectProvider {
|
|||||||
// eslint-disable-next-line no-undef
|
// eslint-disable-next-line no-undef
|
||||||
const sharedWorkerURL = `${this.openmct.getAssetPath()}${__OPENMCT_ROOT_RELATIVE__}couchDBChangesFeed.js`;
|
const sharedWorkerURL = `${this.openmct.getAssetPath()}${__OPENMCT_ROOT_RELATIVE__}couchDBChangesFeed.js`;
|
||||||
|
|
||||||
sharedWorker = new SharedWorker(sharedWorkerURL, 'CouchDB SSE Shared Worker');
|
sharedWorker = new SharedWorker(
|
||||||
|
sharedWorkerURL,
|
||||||
|
`CouchDB SSE Shared Worker for ${this.namespace}`
|
||||||
|
);
|
||||||
sharedWorker.port.onmessage = provider.onSharedWorkerMessage.bind(this);
|
sharedWorker.port.onmessage = provider.onSharedWorkerMessage.bind(this);
|
||||||
sharedWorker.port.onmessageerror = provider.onSharedWorkerMessageError.bind(this);
|
sharedWorker.port.onmessageerror = provider.onSharedWorkerMessageError.bind(this);
|
||||||
sharedWorker.port.start();
|
sharedWorker.port.start();
|
||||||
@ -93,7 +97,7 @@ class CouchObjectProvider {
|
|||||||
this.changesFeedSharedWorkerConnectionId = event.data.connectionId;
|
this.changesFeedSharedWorkerConnectionId = event.data.connectionId;
|
||||||
} else if (event.data.type === 'state') {
|
} else if (event.data.type === 'state') {
|
||||||
const state = this.#messageToIndicatorState(event.data.state);
|
const state = this.#messageToIndicatorState(event.data.state);
|
||||||
this.indicator.setIndicatorToState(state);
|
this.indicator?.setIndicatorToState(state);
|
||||||
} else {
|
} else {
|
||||||
let objectChanges = event.data.objectChanges;
|
let objectChanges = event.data.objectChanges;
|
||||||
const objectIdentifier = {
|
const objectIdentifier = {
|
||||||
@ -184,16 +188,8 @@ class CouchObjectProvider {
|
|||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
//backwards compatibility, options used to be a url. Now it's an object
|
isReadOnly() {
|
||||||
#normalize(options) {
|
return this.readOnly;
|
||||||
if (typeof options === 'string') {
|
|
||||||
return {
|
|
||||||
url: options,
|
|
||||||
useDesignDocuments: false
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
return options;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async request(subPath, method, body, signal) {
|
async request(subPath, method, body, signal) {
|
||||||
@ -233,7 +229,7 @@ class CouchObjectProvider {
|
|||||||
|
|
||||||
// Network error, CouchDB unreachable.
|
// Network error, CouchDB unreachable.
|
||||||
if (response === null) {
|
if (response === null) {
|
||||||
this.indicator.setIndicatorToState(DISCONNECTED);
|
this.indicator?.setIndicatorToState(DISCONNECTED);
|
||||||
console.error(error.message);
|
console.error(error.message);
|
||||||
|
|
||||||
throw new Error(`CouchDB Error - No response"`);
|
throw new Error(`CouchDB Error - No response"`);
|
||||||
@ -256,7 +252,7 @@ class CouchObjectProvider {
|
|||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
#handleResponseCode(status, json, fetchOptions) {
|
#handleResponseCode(status, json, fetchOptions) {
|
||||||
this.indicator.setIndicatorToState(this.#statusCodeToIndicatorState(status));
|
this.indicator?.setIndicatorToState(this.#statusCodeToIndicatorState(status));
|
||||||
if (status === CouchObjectProvider.HTTP_CONFLICT) {
|
if (status === CouchObjectProvider.HTTP_CONFLICT) {
|
||||||
const objectName = JSON.parse(fetchOptions.body)?.model?.name;
|
const objectName = JSON.parse(fetchOptions.body)?.model?.name;
|
||||||
throw new this.openmct.objects.errors.Conflict(`Conflict persisting "${objectName}"`);
|
throw new this.openmct.objects.errors.Conflict(`Conflict persisting "${objectName}"`);
|
||||||
@ -684,7 +680,7 @@ class CouchObjectProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const indicatorState = this.#messageToIndicatorState(message);
|
const indicatorState = this.#messageToIndicatorState(message);
|
||||||
this.indicator.setIndicatorToState(indicatorState);
|
this.indicator?.setIndicatorToState(indicatorState);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -51,6 +51,10 @@ class CouchSearchProvider {
|
|||||||
return this.supportedSearchTypes.includes(searchType);
|
return this.supportedSearchTypes.includes(searchType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isReadOnly() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
search(query, abortSignal, searchType) {
|
search(query, abortSignal, searchType) {
|
||||||
if (searchType === this.searchTypes.OBJECTS) {
|
if (searchType === this.searchTypes.OBJECTS) {
|
||||||
return this.searchForObjects(query, abortSignal);
|
return this.searchForObjects(query, abortSignal);
|
||||||
|
@ -153,13 +153,63 @@ sh ./src/plugins/persistence/couch/replace-localstorage-with-couchdb-indexhtml.s
|
|||||||
Add a line to install the CouchDB plugin for Open MCT:
|
Add a line to install the CouchDB plugin for Open MCT:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
openmct.install(openmct.plugins.CouchDB({url: "http://localhost:5984/openmct", useDesignDocuments: false}));
|
openmct.install(
|
||||||
|
openmct.plugins.CouchDB({
|
||||||
|
databases: [
|
||||||
|
{
|
||||||
|
url: 'http://localhost:5984/openmct',
|
||||||
|
namespace: '',
|
||||||
|
additionalNamespaces: [],
|
||||||
|
readOnly: false,
|
||||||
|
useDesignDocuments: false,
|
||||||
|
indicator: true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
})
|
||||||
|
);
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Configuration Options for OpenMCT
|
||||||
|
|
||||||
|
When installing the CouchDB plugin for OpenMCT, you can specify a list of databases with configuration options for each. Here's a breakdown of the available options for each database:
|
||||||
|
|
||||||
|
- `url`: The URL to the CouchDB instance, specifying the protocol, hostname, and port as needed.
|
||||||
|
- Example: `'http://localhost:5984/openmct'`
|
||||||
|
|
||||||
|
- `namespace`: The namespace associated with this database.
|
||||||
|
- Example: `'openmct-sandbox'`
|
||||||
|
|
||||||
|
- `additionalNamespaces`: Other namespaces that this plugin should respond to requests for.
|
||||||
|
- Example: `['apple-namespace', 'pear-namespace']`
|
||||||
|
|
||||||
|
- `readOnly`: A boolean indicating whether the database should be treated as read-only. If set to `true`, OpenMCT will not attempt to write to this database.
|
||||||
|
- Example: `false`
|
||||||
|
|
||||||
|
- `useDesignDocuments`: Indicates whether design documents should be used to speed up annotation search.
|
||||||
|
- Example: `false`
|
||||||
|
|
||||||
|
- `indicator`: A boolean to specify whether an indicator should show the status of this CouchDB connection in the OpenMCT interface.
|
||||||
|
- Example: `true`
|
||||||
|
|
||||||
|
Note: If using the `exampleTags` plugin with non-blank namespaces, you'll need to configure it point to a writable database. For example:
|
||||||
|
|
||||||
|
```js
|
||||||
|
openmct.install(
|
||||||
|
openmct.plugins.example.ExampleTags({ namespaceToSaveAnnotations: 'openmct-sandbox' })
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
Note: If using the `MyItems` plugin, be sure to configure a root for each writable namespace. E.g., if you have two namespaces called `apple-namespace` and `pear-namespace`:
|
||||||
|
```js
|
||||||
|
openmct.install(openmct.plugins.MyItems('Apple Items', 'apple-namespace'));
|
||||||
|
openmct.install(openmct.plugins.MyItems('Pear Items', 'pear-namespace'));
|
||||||
|
```
|
||||||
|
This will create a root object with the id of `mine` in both namespaces upon load if not already created.
|
||||||
|
|
||||||
# Validating a successful Installation
|
# Validating a successful Installation
|
||||||
|
|
||||||
1. Start Open MCT by running `npm start` in the `openmct` path.
|
1. Start Open MCT by running `npm start` in the `openmct` path.
|
||||||
2. Navigate to <http://localhost:8080/> and create a random object in Open MCT (e.g., a 'Clock') and save. You may get an error saying that the object failed to persist - this is a known error that you can ignore, and will only happen the first time you save - just try again.
|
2. Navigate to <http://localhost:8080/> and create a random object in Open MCT (e.g., a 'Clock') and save.
|
||||||
3. Navigate to: <http://127.0.0.1:5984/_utils/#database/openmct/_all_docs>
|
3. Navigate to: <http://127.0.0.1:5984/_utils/#database/openmct/_all_docs>
|
||||||
4. Look at the 'JSON' tab and ensure you can see the specific object you created above.
|
4. Look at the 'JSON' tab and ensure you can see the specific object you created above.
|
||||||
5. All done! 🏆
|
5. All done! 🏆
|
||||||
|
@ -24,29 +24,81 @@ import CouchObjectProvider from './CouchObjectProvider.js';
|
|||||||
import CouchSearchProvider from './CouchSearchProvider.js';
|
import CouchSearchProvider from './CouchSearchProvider.js';
|
||||||
import CouchStatusIndicator from './CouchStatusIndicator.js';
|
import CouchStatusIndicator from './CouchStatusIndicator.js';
|
||||||
|
|
||||||
const NAMESPACE = '';
|
const DEFAULT_NAMESPACE = '';
|
||||||
const LEGACY_SPACE = 'mct';
|
const LEGACY_SPACE = 'mct';
|
||||||
const COUCH_SEARCH_ONLY_NAMESPACE = `COUCH_SEARCH_${Date.now()}`;
|
|
||||||
|
|
||||||
export default function CouchPlugin(options) {
|
export default function CouchPlugin(options) {
|
||||||
|
function normalizeOptions(unnnormalizedOptions) {
|
||||||
|
const normalizedOptions = {};
|
||||||
|
if (typeof unnnormalizedOptions === 'string') {
|
||||||
|
normalizedOptions.databases = [
|
||||||
|
{
|
||||||
|
url: options,
|
||||||
|
namespace: DEFAULT_NAMESPACE,
|
||||||
|
additionalNamespaces: [LEGACY_SPACE],
|
||||||
|
readOnly: false,
|
||||||
|
useDesignDocuments: false,
|
||||||
|
indicator: true
|
||||||
|
}
|
||||||
|
];
|
||||||
|
} else if (!unnnormalizedOptions.databases) {
|
||||||
|
normalizedOptions.databases = [
|
||||||
|
{
|
||||||
|
url: unnnormalizedOptions.url,
|
||||||
|
namespace: DEFAULT_NAMESPACE,
|
||||||
|
additionalNamespaces: [LEGACY_SPACE],
|
||||||
|
readOnly: false,
|
||||||
|
useDesignDocuments: unnnormalizedOptions.useDesignDocuments,
|
||||||
|
indicator: true
|
||||||
|
}
|
||||||
|
];
|
||||||
|
} else {
|
||||||
|
normalizedOptions.databases = unnnormalizedOptions.databases;
|
||||||
|
}
|
||||||
|
|
||||||
|
// final sanity check, ensure we have all options
|
||||||
|
normalizedOptions.databases.forEach((databaseConfiguration) => {
|
||||||
|
if (!databaseConfiguration.url) {
|
||||||
|
throw new Error(
|
||||||
|
`🛑 CouchDB plugin requires a url option. Please check the configuration for namespace ${databaseConfiguration.namespace}`
|
||||||
|
);
|
||||||
|
} else if (databaseConfiguration.namespace === undefined) {
|
||||||
|
// note we can't check for just !databaseConfiguration.namespace because it could be an empty string
|
||||||
|
throw new Error(
|
||||||
|
`🛑 CouchDB plugin requires a namespace option. Please check the configuration for url ${databaseConfiguration.url}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return normalizedOptions;
|
||||||
|
}
|
||||||
|
|
||||||
return function install(openmct) {
|
return function install(openmct) {
|
||||||
|
const normalizedOptions = normalizeOptions(options);
|
||||||
|
normalizedOptions.databases.forEach((databaseConfiguration) => {
|
||||||
|
let couchStatusIndicator;
|
||||||
|
if (databaseConfiguration.indicator) {
|
||||||
const simpleIndicator = openmct.indicators.simpleIndicator();
|
const simpleIndicator = openmct.indicators.simpleIndicator();
|
||||||
openmct.indicators.add(simpleIndicator);
|
openmct.indicators.add(simpleIndicator);
|
||||||
const couchStatusIndicator = new CouchStatusIndicator(simpleIndicator);
|
couchStatusIndicator = new CouchStatusIndicator(simpleIndicator);
|
||||||
install.couchProvider = new CouchObjectProvider(
|
}
|
||||||
|
// the provider is added to the install function to expose couchProvider to unit tests
|
||||||
|
install.couchProvider = new CouchObjectProvider({
|
||||||
openmct,
|
openmct,
|
||||||
options,
|
databaseConfiguration,
|
||||||
NAMESPACE,
|
|
||||||
couchStatusIndicator
|
couchStatusIndicator
|
||||||
);
|
});
|
||||||
|
openmct.objects.addProvider(databaseConfiguration.namespace, install.couchProvider);
|
||||||
|
databaseConfiguration.additionalNamespaces?.forEach((additionalNamespace) => {
|
||||||
|
openmct.objects.addProvider(additionalNamespace, install.couchProvider);
|
||||||
|
});
|
||||||
|
|
||||||
// Unfortunately, for historical reasons, Couch DB produces objects with a mix of namespaces (alternately "mct", and "")
|
// need one search provider for whole couch database
|
||||||
// Installing the same provider under both namespaces means that it can respond to object gets for both namespaces.
|
const searchOnlyNamespace = `COUCH_SEARCH_${databaseConfiguration.namespace}${Date.now()}`;
|
||||||
openmct.objects.addProvider(LEGACY_SPACE, install.couchProvider);
|
|
||||||
openmct.objects.addProvider(NAMESPACE, install.couchProvider);
|
|
||||||
openmct.objects.addProvider(
|
openmct.objects.addProvider(
|
||||||
COUCH_SEARCH_ONLY_NAMESPACE,
|
searchOnlyNamespace,
|
||||||
new CouchSearchProvider(install.couchProvider)
|
new CouchSearchProvider(install.couchProvider)
|
||||||
);
|
);
|
||||||
|
});
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user