@backstage/backend-defaults 0.17.5-next.1 → 0.17.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +27 -0
- package/config.schema.json +21 -2
- package/dist/cache.d.ts +9 -0
- package/dist/entrypoints/cache/CacheManager.cjs.js +67 -23
- package/dist/entrypoints/cache/CacheManager.cjs.js.map +1 -1
- package/dist/entrypoints/cache/providers/infinispan/InfinispanOptionsMapper.cjs.js +17 -20
- package/dist/entrypoints/cache/providers/infinispan/InfinispanOptionsMapper.cjs.js.map +1 -1
- package/dist/entrypoints/cache/types.cjs.js.map +1 -1
- package/dist/package.json.cjs.js +1 -1
- package/package.json +18 -18
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,32 @@
|
|
|
1
1
|
# @backstage/backend-defaults
|
|
2
2
|
|
|
3
|
+
## 0.17.5
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- aaa7d65: Improved readability of the AWS S3 URL parser by splitting the single monolithic regex into two separate patterns (standard S3 and VPC PrivateLink) with named capture groups. Also made the VPC endpoint region mandatory in the regex, fixing a potential mis-parse when the region segment was absent.
|
|
8
|
+
- d62c384: Fixed a bug where scheduled tasks that were initially registered with a manual trigger and later re-registered with a duration or cron cadence would never be scheduled to run.
|
|
9
|
+
- 8419f51: Added support for AWS PrivateLink for Amazon S3.
|
|
10
|
+
- a624fa3: The `connection` config option for the Redis cache store now accepts either a string URL or an object with additional connection options that are passed directly to the underlying client. The object form is only supported when `backend.cache.store` is `redis`; other stores require a plain string. This allows configuring options like `pingInterval` without needing dedicated config fields. For clustered Redis, the connection object properties are merged into cluster defaults. Fixes https://github.com/backstage/backstage/issues/31813, https://github.com/backstage/backstage/issues/31742.
|
|
11
|
+
- Updated dependencies
|
|
12
|
+
- @backstage/config-loader@1.11.0
|
|
13
|
+
- @backstage/plugin-auth-node@0.7.3
|
|
14
|
+
- @backstage/backend-app-api@1.7.2
|
|
15
|
+
- @backstage/backend-plugin-api@1.9.3
|
|
16
|
+
- @backstage/cli-node@0.3.4
|
|
17
|
+
- @backstage/plugin-events-node@0.4.24
|
|
18
|
+
- @backstage/plugin-permission-node@0.11.2
|
|
19
|
+
|
|
20
|
+
## 0.17.5-next.2
|
|
21
|
+
|
|
22
|
+
### Patch Changes
|
|
23
|
+
|
|
24
|
+
- a624fa3: The `connection` config option for the Redis cache store now accepts either a string URL or an object with additional connection options that are passed directly to the underlying client. The object form is only supported when `backend.cache.store` is `redis`; other stores require a plain string. This allows configuring options like `pingInterval` without needing dedicated config fields. For clustered Redis, the connection object properties are merged into cluster defaults. Fixes https://github.com/backstage/backstage/issues/31813, https://github.com/backstage/backstage/issues/31742.
|
|
25
|
+
- Updated dependencies
|
|
26
|
+
- @backstage/backend-plugin-api@1.9.3-next.1
|
|
27
|
+
- @backstage/cli-node@0.3.4-next.0
|
|
28
|
+
- @backstage/config-loader@1.11.0-next.2
|
|
29
|
+
|
|
3
30
|
## 0.17.5-next.1
|
|
4
31
|
|
|
5
32
|
### Patch Changes
|
package/config.schema.json
CHANGED
|
@@ -1230,8 +1230,27 @@
|
|
|
1230
1230
|
"const": "redis"
|
|
1231
1231
|
},
|
|
1232
1232
|
"connection": {
|
|
1233
|
-
"
|
|
1234
|
-
|
|
1233
|
+
"anyOf": [
|
|
1234
|
+
{
|
|
1235
|
+
"type": "string"
|
|
1236
|
+
},
|
|
1237
|
+
{
|
|
1238
|
+
"type": "object",
|
|
1239
|
+
"properties": {
|
|
1240
|
+
"url": {
|
|
1241
|
+
"type": "string",
|
|
1242
|
+
"description": "The Redis connection URL."
|
|
1243
|
+
}
|
|
1244
|
+
},
|
|
1245
|
+
"required": [
|
|
1246
|
+
"url"
|
|
1247
|
+
],
|
|
1248
|
+
"additionalProperties": {
|
|
1249
|
+
"description": "Other connection settings"
|
|
1250
|
+
}
|
|
1251
|
+
}
|
|
1252
|
+
],
|
|
1253
|
+
"description": "A redis connection string in the form `redis://user:pass@host:port`, or an object with connection options passed directly to the underlying client (e.g. `{ url: 'redis://localhost:6379', pingInterval: 60000 }`). The object form is only supported for the Redis store.",
|
|
1235
1254
|
"visibility": "secret"
|
|
1236
1255
|
},
|
|
1237
1256
|
"defaultTtl": {
|
package/dist/cache.d.ts
CHANGED
|
@@ -57,6 +57,15 @@ declare class CacheManager {
|
|
|
57
57
|
* @returns A new CacheManager instance.
|
|
58
58
|
*/
|
|
59
59
|
static fromConfig(config: RootConfigService, options?: CacheManagerOptions): CacheManager;
|
|
60
|
+
/**
|
|
61
|
+
* Parse the connection config, which can be either a plain URL string
|
|
62
|
+
* or an object with connection options (e.g. `{ url, pingInterval }`)
|
|
63
|
+
* passed through to the underlying store client.
|
|
64
|
+
*
|
|
65
|
+
* @param config - The configuration service
|
|
66
|
+
* @returns The parsed connection config, either a string or an object depending on how it was configured
|
|
67
|
+
*/
|
|
68
|
+
private static parseConnection;
|
|
60
69
|
/**
|
|
61
70
|
* Parse store-specific options from configuration.
|
|
62
71
|
*
|
|
@@ -41,7 +41,7 @@ class CacheManager {
|
|
|
41
41
|
static fromConfig(config$1, options = {}) {
|
|
42
42
|
const store = config$1.getOptionalString("backend.cache.store") || "memory";
|
|
43
43
|
const defaultTtlConfig = config$1.getOptional("backend.cache.defaultTtl");
|
|
44
|
-
const
|
|
44
|
+
const connection = CacheManager.parseConnection(config$1);
|
|
45
45
|
const logger = options.logger?.child({
|
|
46
46
|
type: "cacheManager"
|
|
47
47
|
});
|
|
@@ -60,16 +60,51 @@ class CacheManager {
|
|
|
60
60
|
);
|
|
61
61
|
}
|
|
62
62
|
}
|
|
63
|
-
const storeOptions = CacheManager.parseStoreOptions(
|
|
63
|
+
const storeOptions = CacheManager.parseStoreOptions(
|
|
64
|
+
{ store, connection },
|
|
65
|
+
{ config: config$1, logger }
|
|
66
|
+
);
|
|
64
67
|
return new CacheManager(
|
|
65
68
|
store,
|
|
66
|
-
|
|
69
|
+
connection,
|
|
67
70
|
options.onError,
|
|
68
71
|
logger,
|
|
69
72
|
defaultTtl,
|
|
70
73
|
storeOptions
|
|
71
74
|
);
|
|
72
75
|
}
|
|
76
|
+
/**
|
|
77
|
+
* Parse the connection config, which can be either a plain URL string
|
|
78
|
+
* or an object with connection options (e.g. `{ url, pingInterval }`)
|
|
79
|
+
* passed through to the underlying store client.
|
|
80
|
+
*
|
|
81
|
+
* @param config - The configuration service
|
|
82
|
+
* @returns The parsed connection config, either a string or an object depending on how it was configured
|
|
83
|
+
*/
|
|
84
|
+
static parseConnection(config) {
|
|
85
|
+
const raw = config.getOptional("backend.cache.connection");
|
|
86
|
+
const store = config.getOptionalString("backend.cache.store") || "memory";
|
|
87
|
+
if (raw && typeof raw === "object" && !Array.isArray(raw)) {
|
|
88
|
+
if (store !== "redis") {
|
|
89
|
+
throw new Error(
|
|
90
|
+
"backend.cache.connection object form is only supported when backend.cache.store is 'redis'"
|
|
91
|
+
);
|
|
92
|
+
}
|
|
93
|
+
const url = raw.url;
|
|
94
|
+
if (typeof url !== "string" || url.length === 0) {
|
|
95
|
+
throw new Error(
|
|
96
|
+
"backend.cache.connection object must include a non-empty 'url' string"
|
|
97
|
+
);
|
|
98
|
+
}
|
|
99
|
+
return raw;
|
|
100
|
+
}
|
|
101
|
+
if (raw !== void 0 && typeof raw !== "string") {
|
|
102
|
+
throw new Error(
|
|
103
|
+
`backend.cache.connection must be a string or object, got ${typeof raw}`
|
|
104
|
+
);
|
|
105
|
+
}
|
|
106
|
+
return config.getOptionalString("backend.cache.connection") ?? "";
|
|
107
|
+
}
|
|
73
108
|
/**
|
|
74
109
|
* Parse store-specific options from configuration.
|
|
75
110
|
*
|
|
@@ -78,23 +113,26 @@ class CacheManager {
|
|
|
78
113
|
* @param logger - Optional logger for warnings
|
|
79
114
|
* @returns The parsed store options
|
|
80
115
|
*/
|
|
81
|
-
static parseStoreOptions(
|
|
116
|
+
static parseStoreOptions(config, deps) {
|
|
117
|
+
const { store, connection } = config;
|
|
82
118
|
const storeConfigPath = `backend.cache.${store}`;
|
|
83
|
-
if (store !== "memory" && !config.has(storeConfigPath)) {
|
|
84
|
-
logger?.warn(
|
|
119
|
+
if (store !== "memory" && !deps.config.has(storeConfigPath)) {
|
|
120
|
+
deps.logger?.warn(
|
|
85
121
|
`No configuration found for cache store '${store}' at '${storeConfigPath}'.`
|
|
86
122
|
);
|
|
87
123
|
}
|
|
88
124
|
switch (store) {
|
|
89
125
|
case "redis":
|
|
90
|
-
return CacheManager.parseRedisOptions(
|
|
126
|
+
return CacheManager.parseRedisOptions(
|
|
127
|
+
{ storeConfigPath, connection },
|
|
128
|
+
deps
|
|
129
|
+
);
|
|
91
130
|
case "valkey":
|
|
92
|
-
return CacheManager.parseValkeyOptions(storeConfigPath
|
|
131
|
+
return CacheManager.parseValkeyOptions({ storeConfigPath }, deps);
|
|
93
132
|
case "infinispan":
|
|
94
133
|
return InfinispanOptionsMapper.InfinispanOptionsMapper.parseInfinispanOptions(
|
|
95
|
-
storeConfigPath,
|
|
96
|
-
|
|
97
|
-
logger
|
|
134
|
+
{ storeConfigPath },
|
|
135
|
+
deps
|
|
98
136
|
);
|
|
99
137
|
default:
|
|
100
138
|
return void 0;
|
|
@@ -103,11 +141,11 @@ class CacheManager {
|
|
|
103
141
|
/**
|
|
104
142
|
* Parse Redis-specific options from configuration.
|
|
105
143
|
*/
|
|
106
|
-
static parseRedisOptions(
|
|
144
|
+
static parseRedisOptions(config$1, deps) {
|
|
107
145
|
const redisOptions = {
|
|
108
146
|
type: "redis"
|
|
109
147
|
};
|
|
110
|
-
const redisConfig = config$1.
|
|
148
|
+
const redisConfig = deps.config.getOptionalConfig(config$1.storeConfigPath) ?? new config.ConfigReader({});
|
|
111
149
|
redisOptions.client = {
|
|
112
150
|
namespace: redisConfig.getOptionalString("client.namespace"),
|
|
113
151
|
keyPrefixSeparator: redisConfig.getOptionalString("client.keyPrefixSeparator") || ":",
|
|
@@ -120,14 +158,19 @@ class CacheManager {
|
|
|
120
158
|
if (redisConfig.has("cluster")) {
|
|
121
159
|
const clusterConfig = redisConfig.getConfig("cluster");
|
|
122
160
|
if (!clusterConfig.has("rootNodes")) {
|
|
123
|
-
logger?.warn(
|
|
161
|
+
deps.logger?.warn(
|
|
124
162
|
`Redis cluster config has no 'rootNodes' key, defaulting to non-clustered mode`
|
|
125
163
|
);
|
|
126
164
|
return redisOptions;
|
|
127
165
|
}
|
|
166
|
+
let defaults = clusterConfig.getOptional("defaults");
|
|
167
|
+
if (typeof config$1.connection === "object") {
|
|
168
|
+
const { url: _url, ...connectionDefaults } = config$1.connection;
|
|
169
|
+
defaults = { ...defaults, ...connectionDefaults };
|
|
170
|
+
}
|
|
128
171
|
redisOptions.cluster = {
|
|
129
172
|
rootNodes: clusterConfig.get("rootNodes"),
|
|
130
|
-
defaults
|
|
173
|
+
defaults,
|
|
131
174
|
minimizeConnections: clusterConfig.getOptionalBoolean(
|
|
132
175
|
"minimizeConnections"
|
|
133
176
|
),
|
|
@@ -142,18 +185,18 @@ class CacheManager {
|
|
|
142
185
|
/**
|
|
143
186
|
* Parse Valkey-specific options from configuration.
|
|
144
187
|
*/
|
|
145
|
-
static parseValkeyOptions(
|
|
188
|
+
static parseValkeyOptions(config$1, deps) {
|
|
146
189
|
const valkeyOptions = {
|
|
147
190
|
type: "valkey"
|
|
148
191
|
};
|
|
149
|
-
const valkeyConfig = config$1.
|
|
192
|
+
const valkeyConfig = deps.config.getOptionalConfig(config$1.storeConfigPath) ?? new config.ConfigReader({});
|
|
150
193
|
valkeyOptions.client = {
|
|
151
194
|
keyPrefix: valkeyConfig.getOptionalString("client.keyPrefix")
|
|
152
195
|
};
|
|
153
196
|
if (valkeyConfig.has("cluster")) {
|
|
154
197
|
const clusterConfig = valkeyConfig.getConfig("cluster");
|
|
155
198
|
if (!clusterConfig.has("rootNodes")) {
|
|
156
|
-
logger?.warn(
|
|
199
|
+
deps.logger?.warn(
|
|
157
200
|
`Valkey cluster config has no 'rootNodes' key, defaulting to non-clustered mode`
|
|
158
201
|
);
|
|
159
202
|
return valkeyOptions;
|
|
@@ -194,13 +237,13 @@ class CacheManager {
|
|
|
194
237
|
return `${prefix}${pluginId}`;
|
|
195
238
|
}
|
|
196
239
|
/** @internal */
|
|
197
|
-
constructor(store,
|
|
240
|
+
constructor(store, connection, errorHandler, logger, defaultTtl, storeOptions) {
|
|
198
241
|
if (!this.storeFactories.hasOwnProperty(store)) {
|
|
199
242
|
throw new Error(`Unknown cache store: ${store}`);
|
|
200
243
|
}
|
|
201
244
|
this.logger = logger;
|
|
202
245
|
this.store = store;
|
|
203
|
-
this.connection =
|
|
246
|
+
this.connection = connection;
|
|
204
247
|
this.errorHandler = errorHandler;
|
|
205
248
|
this.defaultTtl = defaultTtl;
|
|
206
249
|
this.storeOptions = storeOptions;
|
|
@@ -225,8 +268,9 @@ class CacheManager {
|
|
|
225
268
|
return this.storeFactories[this.store](pluginId, ttl);
|
|
226
269
|
}
|
|
227
270
|
createRedisStoreFactory() {
|
|
228
|
-
const
|
|
229
|
-
const
|
|
271
|
+
const keyvRedis = require("@keyv/redis");
|
|
272
|
+
const KeyvRedis = keyvRedis.default;
|
|
273
|
+
const { createCluster } = keyvRedis;
|
|
230
274
|
const stores = {};
|
|
231
275
|
return (pluginId, defaultTtl) => {
|
|
232
276
|
if (this.storeOptions?.type !== "redis") {
|
|
@@ -239,7 +283,7 @@ class CacheManager {
|
|
|
239
283
|
keyPrefixSeparator: ":"
|
|
240
284
|
};
|
|
241
285
|
if (this.storeOptions?.cluster) {
|
|
242
|
-
const cluster = createCluster(this.storeOptions
|
|
286
|
+
const cluster = createCluster(this.storeOptions.cluster);
|
|
243
287
|
stores[pluginId] = new KeyvRedis(cluster, redisOptions);
|
|
244
288
|
} else {
|
|
245
289
|
stores[pluginId] = new KeyvRedis(this.connection, redisOptions);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CacheManager.cjs.js","sources":["../../../src/entrypoints/cache/CacheManager.ts"],"sourcesContent":["/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n CacheService,\n CacheServiceOptions,\n LoggerService,\n RootConfigService,\n} from '@backstage/backend-plugin-api';\nimport Keyv from 'keyv';\nimport { DefaultCacheClient } from './CacheClient';\nimport {\n CacheManagerOptions,\n ttlToMilliseconds,\n CacheStoreOptions,\n RedisCacheStoreOptions,\n InfinispanClientBehaviorOptions,\n InfinispanServerConfig,\n ValkeyCacheStoreOptions,\n} from './types';\nimport { InfinispanOptionsMapper } from './providers/infinispan/InfinispanOptionsMapper';\nimport { durationToMilliseconds } from '@backstage/types';\nimport { ConfigReader, readDurationFromConfig } from '@backstage/config';\nimport {\n InfinispanClientCacheInterface,\n InfinispanKeyvStore,\n} from './providers/infinispan/InfinispanKeyvStore';\n\ntype StoreFactory = (pluginId: string, defaultTtl: number | undefined) => Keyv;\n\n/**\n * Implements a Cache Manager which will automatically create new cache clients\n * for plugins when requested. All requested cache clients are created with the\n * connection details provided.\n *\n * @public\n */\nexport class CacheManager {\n /**\n * Keys represent supported `backend.cache.store` values, mapped to factories\n * that return Keyv instances appropriate to the store.\n */\n private readonly storeFactories = {\n redis: this.createRedisStoreFactory(),\n valkey: this.createValkeyStoreFactory(),\n memcache: this.createMemcacheStoreFactory(),\n memory: this.createMemoryStoreFactory(),\n infinispan: this.createInfinispanStoreFactory(),\n };\n\n private readonly logger?: LoggerService;\n private readonly store: keyof CacheManager['storeFactories'];\n private readonly connection: string;\n private readonly errorHandler: CacheManagerOptions['onError'];\n private readonly defaultTtl?: number;\n private readonly storeOptions?: CacheStoreOptions;\n\n /**\n * Creates a new {@link CacheManager} instance by reading from the `backend`\n * config section, specifically the `.cache` key.\n *\n * @param config - The loaded application configuration.\n * @param options - Optional configuration for the CacheManager.\n * @returns A new CacheManager instance.\n */\n static fromConfig(\n config: RootConfigService,\n options: CacheManagerOptions = {},\n ): CacheManager {\n // If no `backend.cache` config is provided, instantiate the CacheManager\n // with an in-memory cache client.\n const store = config.getOptionalString('backend.cache.store') || 'memory';\n const defaultTtlConfig = config.getOptional('backend.cache.defaultTtl');\n const connectionString =\n config.getOptionalString('backend.cache.connection') || '';\n const logger = options.logger?.child({\n type: 'cacheManager',\n });\n\n if (config.has('backend.cache.useRedisSets')) {\n logger?.warn(\n \"The 'backend.cache.useRedisSets' configuration key is deprecated and no longer has any effect. The underlying '@keyv/redis' and '@keyv/valkey' libraries no longer support redis sets.\",\n );\n }\n\n let defaultTtl: number | undefined;\n if (defaultTtlConfig !== undefined) {\n if (typeof defaultTtlConfig === 'number') {\n defaultTtl = defaultTtlConfig;\n } else {\n defaultTtl = durationToMilliseconds(\n readDurationFromConfig(config, { key: 'backend.cache.defaultTtl' }),\n );\n }\n }\n\n // Read store-specific options from config\n const storeOptions = CacheManager.parseStoreOptions(store, config, logger);\n\n return new CacheManager(\n store,\n connectionString,\n options.onError,\n logger,\n defaultTtl,\n storeOptions,\n );\n }\n\n /**\n * Parse store-specific options from configuration.\n *\n * @param store - The cache store type ('redis', 'valkey', 'memcache', 'infinispan', or 'memory')\n * @param config - The configuration service\n * @param logger - Optional logger for warnings\n * @returns The parsed store options\n */\n private static parseStoreOptions(\n store: string,\n config: RootConfigService,\n logger?: LoggerService,\n ): CacheStoreOptions | undefined {\n const storeConfigPath = `backend.cache.${store}`;\n\n if (store !== 'memory' && !config.has(storeConfigPath)) {\n logger?.warn(\n `No configuration found for cache store '${store}' at '${storeConfigPath}'.`,\n );\n }\n\n switch (store) {\n case 'redis':\n return CacheManager.parseRedisOptions(storeConfigPath, config, logger);\n case 'valkey':\n return CacheManager.parseValkeyOptions(storeConfigPath, config, logger);\n case 'infinispan':\n return InfinispanOptionsMapper.parseInfinispanOptions(\n storeConfigPath,\n config,\n logger,\n );\n default:\n return undefined;\n }\n }\n\n /**\n * Parse Redis-specific options from configuration.\n */\n private static parseRedisOptions(\n storeConfigPath: string,\n config: RootConfigService,\n logger?: LoggerService,\n ): RedisCacheStoreOptions {\n const redisOptions: RedisCacheStoreOptions = {\n type: 'redis',\n };\n\n const redisConfig =\n config.getOptionalConfig(storeConfigPath) ?? new ConfigReader({});\n\n redisOptions.client = {\n namespace: redisConfig.getOptionalString('client.namespace'),\n keyPrefixSeparator:\n redisConfig.getOptionalString('client.keyPrefixSeparator') || ':',\n clearBatchSize: redisConfig.getOptionalNumber('client.clearBatchSize'),\n useUnlink: redisConfig.getOptionalBoolean('client.useUnlink'),\n noNamespaceAffectsAll: redisConfig.getOptionalBoolean(\n 'client.noNamespaceAffectsAll',\n ),\n };\n\n if (redisConfig.has('cluster')) {\n const clusterConfig = redisConfig.getConfig('cluster');\n\n if (!clusterConfig.has('rootNodes')) {\n logger?.warn(\n `Redis cluster config has no 'rootNodes' key, defaulting to non-clustered mode`,\n );\n return redisOptions;\n }\n\n redisOptions.cluster = {\n rootNodes: clusterConfig.get('rootNodes'),\n defaults: clusterConfig.getOptional('defaults'),\n minimizeConnections: clusterConfig.getOptionalBoolean(\n 'minimizeConnections',\n ),\n useReplicas: clusterConfig.getOptionalBoolean('useReplicas'),\n maxCommandRedirections: clusterConfig.getOptionalNumber(\n 'maxCommandRedirections',\n ),\n };\n }\n\n return redisOptions;\n }\n\n /**\n * Parse Valkey-specific options from configuration.\n */\n private static parseValkeyOptions(\n storeConfigPath: string,\n config: RootConfigService,\n logger?: LoggerService,\n ): ValkeyCacheStoreOptions {\n const valkeyOptions: ValkeyCacheStoreOptions = {\n type: 'valkey',\n };\n\n const valkeyConfig =\n config.getOptionalConfig(storeConfigPath) ?? new ConfigReader({});\n\n valkeyOptions.client = {\n keyPrefix: valkeyConfig.getOptionalString('client.keyPrefix'),\n };\n\n if (valkeyConfig.has('cluster')) {\n const clusterConfig = valkeyConfig.getConfig('cluster');\n\n if (!clusterConfig.has('rootNodes')) {\n logger?.warn(\n `Valkey cluster config has no 'rootNodes' key, defaulting to non-clustered mode`,\n );\n return valkeyOptions;\n }\n\n valkeyOptions.cluster = {\n rootNodes: clusterConfig.get('rootNodes'),\n options: {\n redisOptions: clusterConfig.getOptional('defaults'),\n scaleReads: clusterConfig.getOptionalBoolean('useReplicas')\n ? 'slave'\n : undefined,\n maxRedirections: clusterConfig.getOptionalNumber(\n 'maxCommandRedirections',\n ),\n lazyConnect: clusterConfig.getOptionalBoolean('minimizeConnections'),\n },\n };\n }\n\n return valkeyOptions;\n }\n\n /**\n * Construct the full namespace based on the options and pluginId.\n *\n * @param pluginId - The plugin ID to namespace\n * @param storeOptions - Optional cache store configuration options\n * @returns The constructed namespace string combining the configured namespace with pluginId\n */\n private static constructNamespace(\n pluginId: string,\n storeOptions: RedisCacheStoreOptions | ValkeyCacheStoreOptions | undefined,\n ): string {\n let prefix: string;\n switch (storeOptions?.type) {\n case 'redis':\n prefix = storeOptions?.client?.namespace\n ? `${storeOptions.client.namespace}${\n storeOptions.client.keyPrefixSeparator ?? ':'\n }`\n : '';\n break;\n case 'valkey':\n prefix = storeOptions.client?.keyPrefix ?? '';\n break;\n default:\n prefix = '';\n }\n\n return `${prefix}${pluginId}`;\n }\n\n /** @internal */\n constructor(\n store: string,\n connectionString: string,\n errorHandler: CacheManagerOptions['onError'],\n logger?: LoggerService,\n defaultTtl?: number,\n storeOptions?: CacheStoreOptions,\n ) {\n if (!this.storeFactories.hasOwnProperty(store)) {\n throw new Error(`Unknown cache store: ${store}`);\n }\n this.logger = logger;\n this.store = store as keyof CacheManager['storeFactories'];\n this.connection = connectionString;\n this.errorHandler = errorHandler;\n this.defaultTtl = defaultTtl;\n this.storeOptions = storeOptions;\n }\n\n /**\n * Generates a PluginCacheManager for consumption by plugins.\n *\n * @param pluginId - The plugin that the cache manager should be created for.\n * Plugin names should be unique.\n */\n forPlugin(pluginId: string): CacheService {\n const clientFactory = (options: CacheServiceOptions) => {\n const ttl = options.defaultTtl ?? this.defaultTtl;\n return this.getClientWithTtl(\n pluginId,\n ttl !== undefined ? ttlToMilliseconds(ttl) : undefined,\n );\n };\n\n return new DefaultCacheClient(clientFactory({}), clientFactory, {});\n }\n\n private getClientWithTtl(pluginId: string, ttl: number | undefined): Keyv {\n return this.storeFactories[this.store](pluginId, ttl);\n }\n\n private createRedisStoreFactory(): StoreFactory {\n const KeyvRedis = require('@keyv/redis').default;\n const { createCluster } = require('@keyv/redis');\n const stores: Record<string, typeof KeyvRedis> = {};\n\n return (pluginId, defaultTtl) => {\n if (this.storeOptions?.type !== 'redis') {\n throw new Error(\n `Internal error: Wrong config type passed to redis factory: ${this.storeOptions?.type}`,\n );\n }\n if (!stores[pluginId]) {\n const redisOptions = this.storeOptions?.client || {\n keyPrefixSeparator: ':',\n };\n if (this.storeOptions?.cluster) {\n // Create a Redis cluster\n const cluster = createCluster(this.storeOptions?.cluster);\n stores[pluginId] = new KeyvRedis(cluster, redisOptions);\n } else {\n // Create a regular Redis connection\n stores[pluginId] = new KeyvRedis(this.connection, redisOptions);\n }\n\n // Always provide an error handler to avoid stopping the process\n stores[pluginId].on('error', (err: Error) => {\n this.logger?.error('Failed to create redis cache client', err);\n this.errorHandler?.(err);\n });\n }\n return new Keyv({\n namespace: CacheManager.constructNamespace(pluginId, this.storeOptions),\n ttl: defaultTtl,\n store: stores[pluginId],\n emitErrors: false,\n useKeyPrefix: false,\n });\n };\n }\n\n private createValkeyStoreFactory(): StoreFactory {\n const KeyvValkey = require('@keyv/valkey').default;\n const { Cluster } = require('iovalkey');\n const stores: Record<string, typeof KeyvValkey> = {};\n\n return (pluginId, defaultTtl) => {\n if (this.storeOptions?.type !== 'valkey') {\n throw new Error(\n `Internal error: Wrong config type passed to valkey factory: ${this.storeOptions?.type}`,\n );\n }\n if (!stores[pluginId]) {\n const valkeyOptions = this.storeOptions?.client;\n if (this.storeOptions?.cluster) {\n // Create an iovalkey Cluster instance, which is the type that @keyv/valkey expects\n const cluster = new Cluster(\n this.storeOptions.cluster.rootNodes,\n this.storeOptions.cluster.options,\n );\n stores[pluginId] = new KeyvValkey(cluster, valkeyOptions);\n } else {\n // Create a regular Valkey connection\n stores[pluginId] = new KeyvValkey(this.connection, valkeyOptions);\n }\n\n // Always provide an error handler to avoid stopping the process\n stores[pluginId].on('error', (err: Error) => {\n this.logger?.error('Failed to create valkey cache client', err);\n this.errorHandler?.(err);\n });\n }\n return new Keyv({\n namespace: CacheManager.constructNamespace(pluginId, this.storeOptions),\n ttl: defaultTtl,\n store: stores[pluginId],\n emitErrors: false,\n useKeyPrefix: false,\n });\n };\n }\n\n private createMemcacheStoreFactory(): StoreFactory {\n const KeyvMemcache = require('@keyv/memcache').default;\n const stores: Record<string, typeof KeyvMemcache> = {};\n\n return (pluginId, defaultTtl) => {\n if (!stores[pluginId]) {\n stores[pluginId] = new KeyvMemcache(this.connection);\n // Always provide an error handler to avoid stopping the process\n stores[pluginId].on('error', (err: Error) => {\n this.logger?.error('Failed to create memcache cache client', err);\n this.errorHandler?.(err);\n });\n }\n return new Keyv({\n namespace: pluginId,\n ttl: defaultTtl,\n emitErrors: false,\n store: stores[pluginId],\n });\n };\n }\n\n private createMemoryStoreFactory(): StoreFactory {\n const store = new Map();\n return (pluginId, defaultTtl) =>\n new Keyv({\n namespace: pluginId,\n ttl: defaultTtl,\n emitErrors: false,\n store,\n });\n }\n\n private createInfinispanStoreFactory(): StoreFactory {\n const stores: Record<string, InfinispanKeyvStore> = {};\n\n return (pluginId, defaultTtl) => {\n if (this.storeOptions?.type !== 'infinispan') {\n throw new Error(\n `Internal error: Wrong config type passed to infinispan factory: ${this.storeOptions?.type}`,\n );\n }\n\n if (!stores[pluginId]) {\n // Use sync version for testing environments\n const isTest =\n process.env.NODE_ENV === 'test' || typeof jest !== 'undefined';\n\n // Create the client promise ONCE and reuse it\n const clientPromise: Promise<InfinispanClientCacheInterface> = isTest\n ? this.createInfinispanClientSync()\n : this.createInfinispanClientAsync();\n\n this.logger?.info(\n `Creating Infinispan cache client for plugin ${pluginId} isTest = ${isTest}`,\n );\n const storeInstance = new InfinispanKeyvStore({\n clientPromise,\n logger: this.logger!,\n });\n\n stores[pluginId] = storeInstance;\n\n // Always provide an error handler to avoid stopping the process\n storeInstance.on('error', (err: Error) => {\n this.logger?.error('Failed to create infinispan cache client', err);\n this.errorHandler?.(err);\n });\n }\n\n return new Keyv({\n namespace: pluginId,\n ttl: defaultTtl,\n store: stores[pluginId],\n emitErrors: false,\n });\n };\n }\n\n /**\n * Creates an Infinispan client using dynamic import (production use).\n * @returns Promise that resolves to an Infinispan client\n */\n private async createInfinispanClientAsync(): Promise<InfinispanClientCacheInterface> {\n return this.createInfinispanClient(false);\n }\n\n /**\n * Creates an Infinispan client using synchronous import (testing purposes).\n * @returns Promise that resolves to an Infinispan client\n */\n private createInfinispanClientSync(): Promise<InfinispanClientCacheInterface> {\n return this.createInfinispanClient(true);\n }\n\n /**\n * Creates an Infinispan client based on the provided configuration.\n * @param useSync - Whether to use synchronous import (for testing) or dynamic import\n * @returns Promise that resolves to an Infinispan client\n */\n private async createInfinispanClient(\n useSync: boolean = false,\n ): Promise<InfinispanClientCacheInterface> {\n try {\n this.logger?.info('Creating Infinispan client');\n\n if (this.storeOptions?.type === 'infinispan') {\n // Import infinispan based on the useSync parameter\n const infinispan = useSync\n ? require('infinispan')\n : await import('infinispan');\n\n const client = await infinispan.client(\n this.storeOptions.servers as InfinispanServerConfig[],\n this.storeOptions.options as InfinispanClientBehaviorOptions,\n );\n\n this.logger?.info('Infinispan client created successfully');\n return client;\n }\n throw new Error('Infinispan store options are not defined');\n } catch (error: any) {\n this.logger?.error('Failed to create Infinispan client', {\n error: error.message,\n });\n throw error;\n }\n }\n}\n"],"names":["config","durationToMilliseconds","readDurationFromConfig","InfinispanOptionsMapper","ConfigReader","ttlToMilliseconds","DefaultCacheClient","Keyv","InfinispanKeyvStore"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"CacheManager.cjs.js","sources":["../../../src/entrypoints/cache/CacheManager.ts"],"sourcesContent":["/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n CacheService,\n CacheServiceOptions,\n LoggerService,\n RootConfigService,\n} from '@backstage/backend-plugin-api';\nimport Keyv from 'keyv';\nimport { DefaultCacheClient } from './CacheClient';\nimport {\n CacheManagerOptions,\n ttlToMilliseconds,\n CacheStoreOptions,\n CacheStoreConnection,\n CacheStoreConnectionObject,\n CacheStoreConfiguration,\n CacheStoreDeps,\n RedisCacheStoreConfiguration,\n RedisCacheStoreOptions,\n InfinispanClientBehaviorOptions,\n InfinispanServerConfig,\n ValkeyCacheStoreOptions,\n} from './types';\nimport { InfinispanOptionsMapper } from './providers/infinispan/InfinispanOptionsMapper';\nimport { durationToMilliseconds } from '@backstage/types';\nimport { ConfigReader, readDurationFromConfig } from '@backstage/config';\nimport {\n InfinispanClientCacheInterface,\n InfinispanKeyvStore,\n} from './providers/infinispan/InfinispanKeyvStore';\nimport type { KeyvRedisOptions, RedisClusterOptions } from '@keyv/redis';\n\ntype StoreFactory = (pluginId: string, defaultTtl: number | undefined) => Keyv;\n\n/**\n * Implements a Cache Manager which will automatically create new cache clients\n * for plugins when requested. All requested cache clients are created with the\n * connection details provided.\n *\n * @public\n */\nexport class CacheManager {\n /**\n * Keys represent supported `backend.cache.store` values, mapped to factories\n * that return Keyv instances appropriate to the store.\n */\n private readonly storeFactories = {\n redis: this.createRedisStoreFactory(),\n valkey: this.createValkeyStoreFactory(),\n memcache: this.createMemcacheStoreFactory(),\n memory: this.createMemoryStoreFactory(),\n infinispan: this.createInfinispanStoreFactory(),\n };\n\n private readonly logger?: LoggerService;\n private readonly store: keyof CacheManager['storeFactories'];\n private readonly connection: CacheStoreConnection;\n private readonly errorHandler: CacheManagerOptions['onError'];\n private readonly defaultTtl?: number;\n private readonly storeOptions?: CacheStoreOptions;\n\n /**\n * Creates a new {@link CacheManager} instance by reading from the `backend`\n * config section, specifically the `.cache` key.\n *\n * @param config - The loaded application configuration.\n * @param options - Optional configuration for the CacheManager.\n * @returns A new CacheManager instance.\n */\n static fromConfig(\n config: RootConfigService,\n options: CacheManagerOptions = {},\n ): CacheManager {\n // If no `backend.cache` config is provided, instantiate the CacheManager\n // with an in-memory cache client.\n const store = config.getOptionalString('backend.cache.store') || 'memory';\n const defaultTtlConfig = config.getOptional('backend.cache.defaultTtl');\n const connection = CacheManager.parseConnection(config);\n const logger = options.logger?.child({\n type: 'cacheManager',\n });\n\n if (config.has('backend.cache.useRedisSets')) {\n logger?.warn(\n \"The 'backend.cache.useRedisSets' configuration key is deprecated and no longer has any effect. The underlying '@keyv/redis' and '@keyv/valkey' libraries no longer support redis sets.\",\n );\n }\n\n let defaultTtl: number | undefined;\n if (defaultTtlConfig !== undefined) {\n if (typeof defaultTtlConfig === 'number') {\n defaultTtl = defaultTtlConfig;\n } else {\n defaultTtl = durationToMilliseconds(\n readDurationFromConfig(config, { key: 'backend.cache.defaultTtl' }),\n );\n }\n }\n\n // Read store-specific options from config\n const storeOptions = CacheManager.parseStoreOptions(\n { store, connection },\n { config, logger },\n );\n\n return new CacheManager(\n store,\n connection,\n options.onError,\n logger,\n defaultTtl,\n storeOptions,\n );\n }\n\n /**\n * Parse the connection config, which can be either a plain URL string\n * or an object with connection options (e.g. `{ url, pingInterval }`)\n * passed through to the underlying store client.\n *\n * @param config - The configuration service\n * @returns The parsed connection config, either a string or an object depending on how it was configured\n */\n private static parseConnection(\n config: RootConfigService,\n ): CacheStoreConnection {\n const raw = config.getOptional('backend.cache.connection');\n const store = config.getOptionalString('backend.cache.store') || 'memory';\n\n if (raw && typeof raw === 'object' && !Array.isArray(raw)) {\n if (store !== 'redis') {\n throw new Error(\n \"backend.cache.connection object form is only supported when backend.cache.store is 'redis'\",\n );\n }\n\n const url = (raw as { url?: unknown }).url;\n if (typeof url !== 'string' || url.length === 0) {\n throw new Error(\n \"backend.cache.connection object must include a non-empty 'url' string\",\n );\n }\n\n return raw as CacheStoreConnectionObject;\n }\n\n if (raw !== undefined && typeof raw !== 'string') {\n throw new Error(\n `backend.cache.connection must be a string or object, got ${typeof raw}`,\n );\n }\n\n return config.getOptionalString('backend.cache.connection') ?? '';\n }\n\n /**\n * Parse store-specific options from configuration.\n *\n * @param store - The cache store type ('redis', 'valkey', 'memcache', 'infinispan', or 'memory')\n * @param config - The configuration service\n * @param logger - Optional logger for warnings\n * @returns The parsed store options\n */\n private static parseStoreOptions(\n config: { store: string; connection: CacheStoreConnection },\n deps: CacheStoreDeps,\n ): CacheStoreOptions | undefined {\n const { store, connection } = config;\n const storeConfigPath = `backend.cache.${store}`;\n\n if (store !== 'memory' && !deps.config.has(storeConfigPath)) {\n deps.logger?.warn(\n `No configuration found for cache store '${store}' at '${storeConfigPath}'.`,\n );\n }\n\n switch (store) {\n case 'redis':\n return CacheManager.parseRedisOptions(\n { storeConfigPath, connection },\n deps,\n );\n case 'valkey':\n return CacheManager.parseValkeyOptions({ storeConfigPath }, deps);\n case 'infinispan':\n return InfinispanOptionsMapper.parseInfinispanOptions(\n { storeConfigPath },\n deps,\n );\n default:\n return undefined;\n }\n }\n\n /**\n * Parse Redis-specific options from configuration.\n */\n private static parseRedisOptions(\n config: RedisCacheStoreConfiguration,\n deps: CacheStoreDeps,\n ): RedisCacheStoreOptions {\n const redisOptions: RedisCacheStoreOptions = {\n type: 'redis',\n };\n\n const redisConfig =\n deps.config.getOptionalConfig(config.storeConfigPath) ??\n new ConfigReader({});\n\n redisOptions.client = {\n namespace: redisConfig.getOptionalString('client.namespace'),\n keyPrefixSeparator:\n redisConfig.getOptionalString('client.keyPrefixSeparator') || ':',\n clearBatchSize: redisConfig.getOptionalNumber('client.clearBatchSize'),\n useUnlink: redisConfig.getOptionalBoolean('client.useUnlink'),\n noNamespaceAffectsAll: redisConfig.getOptionalBoolean(\n 'client.noNamespaceAffectsAll',\n ),\n };\n\n if (redisConfig.has('cluster')) {\n const clusterConfig = redisConfig.getConfig('cluster');\n\n if (!clusterConfig.has('rootNodes')) {\n deps.logger?.warn(\n `Redis cluster config has no 'rootNodes' key, defaulting to non-clustered mode`,\n );\n return redisOptions;\n }\n\n // When connection is an object, merge its properties into cluster\n // defaults so every node inherits those options (e.g. pingInterval).\n let defaults: RedisClusterOptions['defaults'] =\n clusterConfig.getOptional('defaults');\n\n if (typeof config.connection === 'object') {\n const { url: _url, ...connectionDefaults } = config.connection;\n defaults = { ...defaults, ...connectionDefaults };\n }\n\n redisOptions.cluster = {\n rootNodes: clusterConfig.get('rootNodes'),\n defaults,\n minimizeConnections: clusterConfig.getOptionalBoolean(\n 'minimizeConnections',\n ),\n useReplicas: clusterConfig.getOptionalBoolean('useReplicas'),\n maxCommandRedirections: clusterConfig.getOptionalNumber(\n 'maxCommandRedirections',\n ),\n };\n }\n\n return redisOptions;\n }\n\n /**\n * Parse Valkey-specific options from configuration.\n */\n private static parseValkeyOptions(\n config: CacheStoreConfiguration,\n deps: CacheStoreDeps,\n ): ValkeyCacheStoreOptions {\n const valkeyOptions: ValkeyCacheStoreOptions = {\n type: 'valkey',\n };\n\n const valkeyConfig =\n deps.config.getOptionalConfig(config.storeConfigPath) ??\n new ConfigReader({});\n\n valkeyOptions.client = {\n keyPrefix: valkeyConfig.getOptionalString('client.keyPrefix'),\n };\n\n if (valkeyConfig.has('cluster')) {\n const clusterConfig = valkeyConfig.getConfig('cluster');\n\n if (!clusterConfig.has('rootNodes')) {\n deps.logger?.warn(\n `Valkey cluster config has no 'rootNodes' key, defaulting to non-clustered mode`,\n );\n return valkeyOptions;\n }\n\n valkeyOptions.cluster = {\n rootNodes: clusterConfig.get('rootNodes'),\n options: {\n redisOptions: clusterConfig.getOptional('defaults'),\n scaleReads: clusterConfig.getOptionalBoolean('useReplicas')\n ? 'slave'\n : undefined,\n maxRedirections: clusterConfig.getOptionalNumber(\n 'maxCommandRedirections',\n ),\n lazyConnect: clusterConfig.getOptionalBoolean('minimizeConnections'),\n },\n };\n }\n\n return valkeyOptions;\n }\n\n /**\n * Construct the full namespace based on the options and pluginId.\n *\n * @param pluginId - The plugin ID to namespace\n * @param storeOptions - Optional cache store configuration options\n * @returns The constructed namespace string combining the configured namespace with pluginId\n */\n private static constructNamespace(\n pluginId: string,\n storeOptions: RedisCacheStoreOptions | ValkeyCacheStoreOptions | undefined,\n ): string {\n let prefix: string;\n switch (storeOptions?.type) {\n case 'redis':\n prefix = storeOptions?.client?.namespace\n ? `${storeOptions.client.namespace}${\n storeOptions.client.keyPrefixSeparator ?? ':'\n }`\n : '';\n break;\n case 'valkey':\n prefix = storeOptions.client?.keyPrefix ?? '';\n break;\n default:\n prefix = '';\n }\n\n return `${prefix}${pluginId}`;\n }\n\n /** @internal */\n constructor(\n store: string,\n connection: CacheStoreConnection,\n errorHandler: CacheManagerOptions['onError'],\n logger?: LoggerService,\n defaultTtl?: number,\n storeOptions?: CacheStoreOptions,\n ) {\n if (!this.storeFactories.hasOwnProperty(store)) {\n throw new Error(`Unknown cache store: ${store}`);\n }\n this.logger = logger;\n this.store = store as keyof CacheManager['storeFactories'];\n this.connection = connection;\n this.errorHandler = errorHandler;\n this.defaultTtl = defaultTtl;\n this.storeOptions = storeOptions;\n }\n\n /**\n * Generates a PluginCacheManager for consumption by plugins.\n *\n * @param pluginId - The plugin that the cache manager should be created for.\n * Plugin names should be unique.\n */\n forPlugin(pluginId: string): CacheService {\n const clientFactory = (options: CacheServiceOptions) => {\n const ttl = options.defaultTtl ?? this.defaultTtl;\n return this.getClientWithTtl(\n pluginId,\n ttl !== undefined ? ttlToMilliseconds(ttl) : undefined,\n );\n };\n\n return new DefaultCacheClient(clientFactory({}), clientFactory, {});\n }\n\n private getClientWithTtl(pluginId: string, ttl: number | undefined): Keyv {\n return this.storeFactories[this.store](pluginId, ttl);\n }\n\n private createRedisStoreFactory(): StoreFactory {\n const keyvRedis = require('@keyv/redis') as typeof import('@keyv/redis');\n const KeyvRedis = keyvRedis.default;\n const { createCluster } = keyvRedis;\n const stores: Record<string, InstanceType<typeof KeyvRedis>> = {};\n\n return (pluginId, defaultTtl) => {\n if (this.storeOptions?.type !== 'redis') {\n throw new Error(\n `Internal error: Wrong config type passed to redis factory: ${this.storeOptions?.type}`,\n );\n }\n if (!stores[pluginId]) {\n const redisOptions: KeyvRedisOptions = this.storeOptions?.client || {\n keyPrefixSeparator: ':',\n };\n if (this.storeOptions?.cluster) {\n // Create a Redis cluster\n const cluster = createCluster(this.storeOptions.cluster);\n stores[pluginId] = new KeyvRedis(cluster, redisOptions);\n } else {\n // Create a regular Redis connection\n stores[pluginId] = new KeyvRedis(this.connection, redisOptions);\n }\n\n // Always provide an error handler to avoid stopping the process\n stores[pluginId].on('error', (err: Error) => {\n this.logger?.error('Failed to create redis cache client', err);\n this.errorHandler?.(err);\n });\n }\n return new Keyv({\n namespace: CacheManager.constructNamespace(pluginId, this.storeOptions),\n ttl: defaultTtl,\n store: stores[pluginId],\n emitErrors: false,\n useKeyPrefix: false,\n });\n };\n }\n\n private createValkeyStoreFactory(): StoreFactory {\n const KeyvValkey = require('@keyv/valkey').default;\n const { Cluster } = require('iovalkey');\n const stores: Record<string, typeof KeyvValkey> = {};\n\n return (pluginId, defaultTtl) => {\n if (this.storeOptions?.type !== 'valkey') {\n throw new Error(\n `Internal error: Wrong config type passed to valkey factory: ${this.storeOptions?.type}`,\n );\n }\n if (!stores[pluginId]) {\n const valkeyOptions = this.storeOptions?.client;\n if (this.storeOptions?.cluster) {\n // Create an iovalkey Cluster instance, which is the type that @keyv/valkey expects\n const cluster = new Cluster(\n this.storeOptions.cluster.rootNodes,\n this.storeOptions.cluster.options,\n );\n stores[pluginId] = new KeyvValkey(cluster, valkeyOptions);\n } else {\n // Create a regular Valkey connection\n stores[pluginId] = new KeyvValkey(this.connection, valkeyOptions);\n }\n\n // Always provide an error handler to avoid stopping the process\n stores[pluginId].on('error', (err: Error) => {\n this.logger?.error('Failed to create valkey cache client', err);\n this.errorHandler?.(err);\n });\n }\n return new Keyv({\n namespace: CacheManager.constructNamespace(pluginId, this.storeOptions),\n ttl: defaultTtl,\n store: stores[pluginId],\n emitErrors: false,\n useKeyPrefix: false,\n });\n };\n }\n\n private createMemcacheStoreFactory(): StoreFactory {\n const KeyvMemcache = require('@keyv/memcache').default;\n const stores: Record<string, typeof KeyvMemcache> = {};\n\n return (pluginId, defaultTtl) => {\n if (!stores[pluginId]) {\n stores[pluginId] = new KeyvMemcache(this.connection);\n // Always provide an error handler to avoid stopping the process\n stores[pluginId].on('error', (err: Error) => {\n this.logger?.error('Failed to create memcache cache client', err);\n this.errorHandler?.(err);\n });\n }\n return new Keyv({\n namespace: pluginId,\n ttl: defaultTtl,\n emitErrors: false,\n store: stores[pluginId],\n });\n };\n }\n\n private createMemoryStoreFactory(): StoreFactory {\n const store = new Map();\n return (pluginId, defaultTtl) =>\n new Keyv({\n namespace: pluginId,\n ttl: defaultTtl,\n emitErrors: false,\n store,\n });\n }\n\n private createInfinispanStoreFactory(): StoreFactory {\n const stores: Record<string, InfinispanKeyvStore> = {};\n\n return (pluginId, defaultTtl) => {\n if (this.storeOptions?.type !== 'infinispan') {\n throw new Error(\n `Internal error: Wrong config type passed to infinispan factory: ${this.storeOptions?.type}`,\n );\n }\n\n if (!stores[pluginId]) {\n // Use sync version for testing environments\n const isTest =\n process.env.NODE_ENV === 'test' || typeof jest !== 'undefined';\n\n // Create the client promise ONCE and reuse it\n const clientPromise: Promise<InfinispanClientCacheInterface> = isTest\n ? this.createInfinispanClientSync()\n : this.createInfinispanClientAsync();\n\n this.logger?.info(\n `Creating Infinispan cache client for plugin ${pluginId} isTest = ${isTest}`,\n );\n const storeInstance = new InfinispanKeyvStore({\n clientPromise,\n logger: this.logger!,\n });\n\n stores[pluginId] = storeInstance;\n\n // Always provide an error handler to avoid stopping the process\n storeInstance.on('error', (err: Error) => {\n this.logger?.error('Failed to create infinispan cache client', err);\n this.errorHandler?.(err);\n });\n }\n\n return new Keyv({\n namespace: pluginId,\n ttl: defaultTtl,\n store: stores[pluginId],\n emitErrors: false,\n });\n };\n }\n\n /**\n * Creates an Infinispan client using dynamic import (production use).\n * @returns Promise that resolves to an Infinispan client\n */\n private async createInfinispanClientAsync(): Promise<InfinispanClientCacheInterface> {\n return this.createInfinispanClient(false);\n }\n\n /**\n * Creates an Infinispan client using synchronous import (testing purposes).\n * @returns Promise that resolves to an Infinispan client\n */\n private createInfinispanClientSync(): Promise<InfinispanClientCacheInterface> {\n return this.createInfinispanClient(true);\n }\n\n /**\n * Creates an Infinispan client based on the provided configuration.\n * @param useSync - Whether to use synchronous import (for testing) or dynamic import\n * @returns Promise that resolves to an Infinispan client\n */\n private async createInfinispanClient(\n useSync: boolean = false,\n ): Promise<InfinispanClientCacheInterface> {\n try {\n this.logger?.info('Creating Infinispan client');\n\n if (this.storeOptions?.type === 'infinispan') {\n // Import infinispan based on the useSync parameter\n const infinispan = useSync\n ? require('infinispan')\n : await import('infinispan');\n\n const client = await infinispan.client(\n this.storeOptions.servers as InfinispanServerConfig[],\n this.storeOptions.options as InfinispanClientBehaviorOptions,\n );\n\n this.logger?.info('Infinispan client created successfully');\n return client;\n }\n throw new Error('Infinispan store options are not defined');\n } catch (error: any) {\n this.logger?.error('Failed to create Infinispan client', {\n error: error.message,\n });\n throw error;\n }\n }\n}\n"],"names":["config","durationToMilliseconds","readDurationFromConfig","InfinispanOptionsMapper","ConfigReader","ttlToMilliseconds","DefaultCacheClient","Keyv","InfinispanKeyvStore"],"mappings":"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"}
|
|
@@ -4,13 +4,12 @@ class InfinispanOptionsMapper {
|
|
|
4
4
|
/**
|
|
5
5
|
* Parses Infinispan options from the provided configuration path.
|
|
6
6
|
*
|
|
7
|
-
* @param
|
|
8
|
-
* @param
|
|
9
|
-
* @param logger - An optional logger service for logging errors and warnings.
|
|
7
|
+
* @param config - The store configuration.
|
|
8
|
+
* @param deps - Service dependencies.
|
|
10
9
|
* @returns Parsed Infinispan cache store options.
|
|
11
10
|
*/
|
|
12
|
-
static parseInfinispanOptions(
|
|
13
|
-
const infinispanConfig = config.getConfig(storeConfigPath);
|
|
11
|
+
static parseInfinispanOptions(config, deps) {
|
|
12
|
+
const infinispanConfig = deps.config.getConfig(config.storeConfigPath);
|
|
14
13
|
const parsedOptions = {
|
|
15
14
|
type: "infinispan"
|
|
16
15
|
};
|
|
@@ -31,12 +30,12 @@ class InfinispanOptionsMapper {
|
|
|
31
30
|
};
|
|
32
31
|
} else {
|
|
33
32
|
throw new Error(
|
|
34
|
-
`Infinispan 'servers' configuration at ${storeConfigPath} is invalid, must be an object or an array.`
|
|
33
|
+
`Infinispan 'servers' configuration at ${config.storeConfigPath} is invalid, must be an object or an array.`
|
|
35
34
|
);
|
|
36
35
|
}
|
|
37
36
|
} else {
|
|
38
|
-
logger?.warn(
|
|
39
|
-
`Infinispan configuration at ${storeConfigPath} is missing the 'servers' definition, will use client defaults.`
|
|
37
|
+
deps.logger?.warn(
|
|
38
|
+
`Infinispan configuration at ${config.storeConfigPath} is missing the 'servers' definition, will use client defaults.`
|
|
40
39
|
);
|
|
41
40
|
}
|
|
42
41
|
const behaviorOptions = {};
|
|
@@ -54,8 +53,8 @@ class InfinispanOptionsMapper {
|
|
|
54
53
|
if (clientVersion === "2.9" || clientVersion === "2.5" || clientVersion === "2.2") {
|
|
55
54
|
behaviorOptions.version = clientVersion;
|
|
56
55
|
} else if (clientVersion !== null && clientVersion !== void 0) {
|
|
57
|
-
logger?.warn(
|
|
58
|
-
`Invalid Infinispan client version "${clientVersion}" in config at ${storeConfigPath}.version. Must be "2.9", "2.5", or "2.2". It will be ignored, and the client may use a default or fail.`
|
|
56
|
+
deps.logger?.warn(
|
|
57
|
+
`Invalid Infinispan client version "${clientVersion}" in config at ${config.storeConfigPath}.version. Must be "2.9", "2.5", or "2.2". It will be ignored, and the client may use a default or fail.`
|
|
59
58
|
);
|
|
60
59
|
}
|
|
61
60
|
behaviorOptions.cacheName = infinispanConfig.getOptionalString("cacheName") ?? "cache";
|
|
@@ -63,8 +62,8 @@ class InfinispanOptionsMapper {
|
|
|
63
62
|
if (mediaType === "text/plain" || mediaType === "application/json") {
|
|
64
63
|
behaviorOptions.mediaType = mediaType;
|
|
65
64
|
} else if (mediaType !== null && mediaType !== void 0) {
|
|
66
|
-
logger?.warn(
|
|
67
|
-
`Invalid Infinispan mediaType "${mediaType}" in config at ${storeConfigPath}.mediaType. Must be "text/plain" | "application/json". It will be ignored, and the client may use a default or fail.`
|
|
65
|
+
deps.logger?.warn(
|
|
66
|
+
`Invalid Infinispan mediaType "${mediaType}" in config at ${config.storeConfigPath}.mediaType. Must be "text/plain" | "application/json". It will be ignored, and the client may use a default or fail.`
|
|
68
67
|
);
|
|
69
68
|
}
|
|
70
69
|
behaviorOptions.maxRetries = infinispanConfig.getOptionalNumber("maxRetries");
|
|
@@ -103,23 +102,21 @@ class InfinispanOptionsMapper {
|
|
|
103
102
|
if (keyType === "text/plain" || keyType === "application/json") {
|
|
104
103
|
dataFormatOpts.keyType = keyType;
|
|
105
104
|
} else if (keyType !== null && keyType !== void 0) {
|
|
106
|
-
logger?.warn(
|
|
107
|
-
`Invalid Infinispan dataFormat.keyType "${keyType}" in config at ${storeConfigPath}.dataFormat.keyType. Must be "text/plain" | "application/json". Not mapped, client will use default 'text/plain'.`
|
|
105
|
+
deps.logger?.warn(
|
|
106
|
+
`Invalid Infinispan dataFormat.keyType "${keyType}" in config at ${config.storeConfigPath}.dataFormat.keyType. Must be "text/plain" | "application/json". Not mapped, client will use default 'text/plain'.`
|
|
108
107
|
);
|
|
109
108
|
}
|
|
110
109
|
if (valueType === "text/plain" || valueType === "application/json") {
|
|
111
110
|
dataFormatOpts.valueType = valueType;
|
|
112
111
|
} else if (valueType !== null && valueType !== void 0) {
|
|
113
|
-
logger?.warn(
|
|
114
|
-
`Invalid Infinispan dataFormat.valueType "${valueType}" in config at ${storeConfigPath}.dataFormat.valueType. Must be "text/plain" | "application/json". Not mapped, client will use default 'text/plain'.`
|
|
112
|
+
deps.logger?.warn(
|
|
113
|
+
`Invalid Infinispan dataFormat.valueType "${valueType}" in config at ${config.storeConfigPath}.dataFormat.valueType. Must be "text/plain" | "application/json". Not mapped, client will use default 'text/plain'.`
|
|
115
114
|
);
|
|
116
115
|
}
|
|
117
116
|
behaviorOptions.dataFormat = dataFormatOpts;
|
|
118
117
|
parsedOptions.options = behaviorOptions;
|
|
119
|
-
logger?.debug(
|
|
120
|
-
`Parsed Infinispan options from config at ${storeConfigPath}: ${JSON.stringify(
|
|
121
|
-
parsedOptions
|
|
122
|
-
)}`
|
|
118
|
+
deps.logger?.debug(
|
|
119
|
+
`Parsed Infinispan options from config at ${config.storeConfigPath}: ${JSON.stringify(parsedOptions)}`
|
|
123
120
|
);
|
|
124
121
|
return parsedOptions;
|
|
125
122
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"InfinispanOptionsMapper.cjs.js","sources":["../../../../../src/entrypoints/cache/providers/infinispan/InfinispanOptionsMapper.ts"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n LoggerService,\n RootConfigService,\n} from '@backstage/backend-plugin-api';\nimport {\n DataFormatOptions,\n InfinispanAuthOptions,\n InfinispanCacheStoreOptions,\n InfinispanClientAuthOptions,\n InfinispanClientBehaviorOptions,\n InfinispanClusterConfig,\n InfinispanServerConfig,\n InfinispanSslOptions,\n} from '../../types';\n\nexport class InfinispanOptionsMapper {\n /**\n * Parses Infinispan options from the provided configuration path.\n *\n * @param storeConfigPath - The configuration path for the Infinispan store.\n * @param config - The root configuration service to retrieve the Infinispan configuration.\n * @param logger - An optional logger service for logging errors and warnings.\n * @returns Parsed Infinispan cache store options.\n */\n public static parseInfinispanOptions(\n storeConfigPath: string,\n config: RootConfigService,\n logger?: LoggerService,\n ): InfinispanCacheStoreOptions {\n const infinispanConfig = config.getConfig(storeConfigPath);\n const parsedOptions: Partial<InfinispanCacheStoreOptions> = {\n type: 'infinispan',\n };\n\n // Parse Servers & Clusters Configurations\n if (infinispanConfig.has('servers')) {\n const serversConfig = infinispanConfig.get('servers');\n if (Array.isArray(serversConfig)) {\n parsedOptions.servers = infinispanConfig.getConfigArray('servers').map(\n serverConf =>\n ({\n host: serverConf.getString('host'),\n port: serverConf.getOptionalNumber('port') ?? 11222,\n } as InfinispanServerConfig),\n );\n } else if (typeof serversConfig === 'object' && serversConfig !== null) {\n const serverConf = infinispanConfig.getConfig('servers');\n parsedOptions.servers = {\n host: serverConf.getOptionalString('host') ?? '127.0.0.1',\n port: serverConf.getOptionalString('port') ?? 11222,\n } as InfinispanServerConfig;\n } else {\n throw new Error(\n `Infinispan 'servers' configuration at ${storeConfigPath} is invalid, must be an object or an array.`,\n );\n }\n } else {\n logger?.warn(\n `Infinispan configuration at ${storeConfigPath} is missing the 'servers' definition, will use client defaults.`,\n );\n }\n\n // The parsed options block to send to the Infinispan client\n // This will be used to configure the Infinispan client behavior.\n const behaviorOptions: Partial<InfinispanClientBehaviorOptions> = {};\n\n behaviorOptions.clusters = infinispanConfig\n .getOptionalConfigArray('clusters')\n ?.map(clusterConf => {\n const name = clusterConf.getOptionalString('name');\n return {\n ...(name && { name }),\n servers: clusterConf.getConfigArray('servers').map(serverConf => ({\n host: serverConf.getString('host'),\n port: serverConf.getOptionalNumber('port') ?? 11222,\n })),\n } as InfinispanClusterConfig;\n });\n\n // Parse Default Options Start...\n const clientVersion =\n infinispanConfig.getOptionalString('version') ?? '2.9';\n if (\n clientVersion === '2.9' ||\n clientVersion === '2.5' ||\n clientVersion === '2.2'\n ) {\n behaviorOptions.version = clientVersion;\n } else if (clientVersion !== null && clientVersion !== undefined) {\n logger?.warn(\n `Invalid Infinispan client version \"${clientVersion}\" in config at ${storeConfigPath}.version. Must be \"2.9\", \"2.5\", or \"2.2\". It will be ignored, and the client may use a default or fail.`,\n );\n }\n\n behaviorOptions.cacheName =\n infinispanConfig.getOptionalString('cacheName') ?? 'cache';\n\n const mediaType = infinispanConfig.getOptionalString('mediaType');\n if (mediaType === 'text/plain' || mediaType === 'application/json') {\n behaviorOptions.mediaType = mediaType;\n } else if (mediaType !== null && mediaType !== undefined) {\n logger?.warn(\n `Invalid Infinispan mediaType \"${mediaType}\" in config at ${storeConfigPath}.mediaType. Must be \"text/plain\" | \"application/json\". It will be ignored, and the client may use a default or fail.`,\n );\n }\n\n behaviorOptions.maxRetries =\n infinispanConfig.getOptionalNumber('maxRetries');\n\n behaviorOptions.topologyUpdates =\n infinispanConfig.getOptionalBoolean('topologyUpdates') ?? true;\n\n // Default Options End...\n\n // Parse Authentication and SSL Options\n const authConfig = infinispanConfig.getOptionalConfig('authentication');\n const auth: Partial<InfinispanAuthOptions> = {};\n\n auth.enabled = authConfig?.getOptionalBoolean('enabled');\n auth.saslMechanism = authConfig?.getOptionalString('saslMechanism');\n auth.userName = authConfig?.getOptionalString('userName');\n auth.password = authConfig?.getOptionalString('password');\n auth.token = authConfig?.getOptionalString('token');\n auth.authzid = authConfig?.getOptionalString('authzid');\n\n behaviorOptions.authentication = auth as InfinispanAuthOptions;\n\n const sslConfig = infinispanConfig.getOptionalConfig('ssl');\n const ssl: Partial<InfinispanSslOptions> = {};\n\n ssl.enabled = sslConfig?.getOptionalBoolean('enabled');\n ssl.secureProtocol = sslConfig?.getOptionalString('secureProtocol');\n ssl.trustCerts = sslConfig?.getOptionalStringArray('trustCerts');\n ssl.sniHostName = sslConfig?.getOptionalString('sniHostname');\n\n const clientAuth = infinispanConfig.getOptionalConfig('clientAuth');\n const clientAuthOpts: Partial<InfinispanClientAuthOptions> = {};\n\n clientAuthOpts.key = clientAuth?.getOptionalString('key');\n clientAuthOpts.passphrase = clientAuth?.getOptionalString('passphrase');\n clientAuthOpts.cert = clientAuth?.getOptionalString('cert');\n\n ssl.clientAuth = clientAuthOpts as InfinispanClientAuthOptions;\n\n const cryptoStore = infinispanConfig.getOptionalConfig('cryptoStore');\n const cryptoStoreOpts: Partial<InfinispanClientAuthOptions> = {};\n\n cryptoStoreOpts.key = cryptoStore?.getOptionalString('path');\n cryptoStoreOpts.passphrase = cryptoStore?.getOptionalString('passphrase');\n\n ssl.cryptoStore = cryptoStoreOpts as InfinispanClientAuthOptions;\n\n behaviorOptions.ssl = ssl as InfinispanSslOptions;\n\n const dataFormat = infinispanConfig.getOptionalConfig('dataFormat');\n const dataFormatOpts: Partial<DataFormatOptions> = {};\n\n const keyType = dataFormat?.getOptionalString('keyType') ?? 'text/plain';\n const valueType =\n dataFormat?.getOptionalString('valueType') ?? 'text/plain';\n\n if (keyType === 'text/plain' || keyType === 'application/json') {\n dataFormatOpts.keyType = keyType;\n } else if (keyType !== null && keyType !== undefined) {\n logger?.warn(\n `Invalid Infinispan dataFormat.keyType \"${keyType}\" in config at ${storeConfigPath}.dataFormat.keyType. Must be \"text/plain\" | \"application/json\". Not mapped, client will use default 'text/plain'.`,\n );\n }\n\n if (valueType === 'text/plain' || valueType === 'application/json') {\n dataFormatOpts.valueType = valueType;\n } else if (valueType !== null && valueType !== undefined) {\n logger?.warn(\n `Invalid Infinispan dataFormat.valueType \"${valueType}\" in config at ${storeConfigPath}.dataFormat.valueType. Must be \"text/plain\" | \"application/json\". Not mapped, client will use default 'text/plain'.`,\n );\n }\n behaviorOptions.dataFormat = dataFormatOpts as DataFormatOptions;\n parsedOptions.options = behaviorOptions as InfinispanClientBehaviorOptions;\n\n logger?.debug(\n `Parsed Infinispan options from config at ${storeConfigPath}: ${JSON.stringify(\n parsedOptions,\n )}`,\n );\n return parsedOptions as InfinispanCacheStoreOptions;\n }\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"InfinispanOptionsMapper.cjs.js","sources":["../../../../../src/entrypoints/cache/providers/infinispan/InfinispanOptionsMapper.ts"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n CacheStoreConfiguration,\n CacheStoreDeps,\n DataFormatOptions,\n InfinispanAuthOptions,\n InfinispanCacheStoreOptions,\n InfinispanClientAuthOptions,\n InfinispanClientBehaviorOptions,\n InfinispanClusterConfig,\n InfinispanServerConfig,\n InfinispanSslOptions,\n} from '../../types';\n\nexport class InfinispanOptionsMapper {\n /**\n * Parses Infinispan options from the provided configuration path.\n *\n * @param config - The store configuration.\n * @param deps - Service dependencies.\n * @returns Parsed Infinispan cache store options.\n */\n public static parseInfinispanOptions(\n config: CacheStoreConfiguration,\n deps: CacheStoreDeps,\n ): InfinispanCacheStoreOptions {\n const infinispanConfig = deps.config.getConfig(config.storeConfigPath);\n const parsedOptions: Partial<InfinispanCacheStoreOptions> = {\n type: 'infinispan',\n };\n\n // Parse Servers & Clusters Configurations\n if (infinispanConfig.has('servers')) {\n const serversConfig = infinispanConfig.get('servers');\n if (Array.isArray(serversConfig)) {\n parsedOptions.servers = infinispanConfig.getConfigArray('servers').map(\n serverConf =>\n ({\n host: serverConf.getString('host'),\n port: serverConf.getOptionalNumber('port') ?? 11222,\n } as InfinispanServerConfig),\n );\n } else if (typeof serversConfig === 'object' && serversConfig !== null) {\n const serverConf = infinispanConfig.getConfig('servers');\n parsedOptions.servers = {\n host: serverConf.getOptionalString('host') ?? '127.0.0.1',\n port: serverConf.getOptionalString('port') ?? 11222,\n } as InfinispanServerConfig;\n } else {\n throw new Error(\n `Infinispan 'servers' configuration at ${config.storeConfigPath} is invalid, must be an object or an array.`,\n );\n }\n } else {\n deps.logger?.warn(\n `Infinispan configuration at ${config.storeConfigPath} is missing the 'servers' definition, will use client defaults.`,\n );\n }\n\n // The parsed options block to send to the Infinispan client\n // This will be used to configure the Infinispan client behavior.\n const behaviorOptions: Partial<InfinispanClientBehaviorOptions> = {};\n\n behaviorOptions.clusters = infinispanConfig\n .getOptionalConfigArray('clusters')\n ?.map(clusterConf => {\n const name = clusterConf.getOptionalString('name');\n return {\n ...(name && { name }),\n servers: clusterConf.getConfigArray('servers').map(serverConf => ({\n host: serverConf.getString('host'),\n port: serverConf.getOptionalNumber('port') ?? 11222,\n })),\n } as InfinispanClusterConfig;\n });\n\n // Parse Default Options Start...\n const clientVersion =\n infinispanConfig.getOptionalString('version') ?? '2.9';\n if (\n clientVersion === '2.9' ||\n clientVersion === '2.5' ||\n clientVersion === '2.2'\n ) {\n behaviorOptions.version = clientVersion;\n } else if (clientVersion !== null && clientVersion !== undefined) {\n deps.logger?.warn(\n `Invalid Infinispan client version \"${clientVersion}\" in config at ${config.storeConfigPath}.version. Must be \"2.9\", \"2.5\", or \"2.2\". It will be ignored, and the client may use a default or fail.`,\n );\n }\n\n behaviorOptions.cacheName =\n infinispanConfig.getOptionalString('cacheName') ?? 'cache';\n\n const mediaType = infinispanConfig.getOptionalString('mediaType');\n if (mediaType === 'text/plain' || mediaType === 'application/json') {\n behaviorOptions.mediaType = mediaType;\n } else if (mediaType !== null && mediaType !== undefined) {\n deps.logger?.warn(\n `Invalid Infinispan mediaType \"${mediaType}\" in config at ${config.storeConfigPath}.mediaType. Must be \"text/plain\" | \"application/json\". It will be ignored, and the client may use a default or fail.`,\n );\n }\n\n behaviorOptions.maxRetries =\n infinispanConfig.getOptionalNumber('maxRetries');\n\n behaviorOptions.topologyUpdates =\n infinispanConfig.getOptionalBoolean('topologyUpdates') ?? true;\n\n // Default Options End...\n\n // Parse Authentication and SSL Options\n const authConfig = infinispanConfig.getOptionalConfig('authentication');\n const auth: Partial<InfinispanAuthOptions> = {};\n\n auth.enabled = authConfig?.getOptionalBoolean('enabled');\n auth.saslMechanism = authConfig?.getOptionalString('saslMechanism');\n auth.userName = authConfig?.getOptionalString('userName');\n auth.password = authConfig?.getOptionalString('password');\n auth.token = authConfig?.getOptionalString('token');\n auth.authzid = authConfig?.getOptionalString('authzid');\n\n behaviorOptions.authentication = auth as InfinispanAuthOptions;\n\n const sslConfig = infinispanConfig.getOptionalConfig('ssl');\n const ssl: Partial<InfinispanSslOptions> = {};\n\n ssl.enabled = sslConfig?.getOptionalBoolean('enabled');\n ssl.secureProtocol = sslConfig?.getOptionalString('secureProtocol');\n ssl.trustCerts = sslConfig?.getOptionalStringArray('trustCerts');\n ssl.sniHostName = sslConfig?.getOptionalString('sniHostname');\n\n const clientAuth = infinispanConfig.getOptionalConfig('clientAuth');\n const clientAuthOpts: Partial<InfinispanClientAuthOptions> = {};\n\n clientAuthOpts.key = clientAuth?.getOptionalString('key');\n clientAuthOpts.passphrase = clientAuth?.getOptionalString('passphrase');\n clientAuthOpts.cert = clientAuth?.getOptionalString('cert');\n\n ssl.clientAuth = clientAuthOpts as InfinispanClientAuthOptions;\n\n const cryptoStore = infinispanConfig.getOptionalConfig('cryptoStore');\n const cryptoStoreOpts: Partial<InfinispanClientAuthOptions> = {};\n\n cryptoStoreOpts.key = cryptoStore?.getOptionalString('path');\n cryptoStoreOpts.passphrase = cryptoStore?.getOptionalString('passphrase');\n\n ssl.cryptoStore = cryptoStoreOpts as InfinispanClientAuthOptions;\n\n behaviorOptions.ssl = ssl as InfinispanSslOptions;\n\n const dataFormat = infinispanConfig.getOptionalConfig('dataFormat');\n const dataFormatOpts: Partial<DataFormatOptions> = {};\n\n const keyType = dataFormat?.getOptionalString('keyType') ?? 'text/plain';\n const valueType =\n dataFormat?.getOptionalString('valueType') ?? 'text/plain';\n\n if (keyType === 'text/plain' || keyType === 'application/json') {\n dataFormatOpts.keyType = keyType;\n } else if (keyType !== null && keyType !== undefined) {\n deps.logger?.warn(\n `Invalid Infinispan dataFormat.keyType \"${keyType}\" in config at ${config.storeConfigPath}.dataFormat.keyType. Must be \"text/plain\" | \"application/json\". Not mapped, client will use default 'text/plain'.`,\n );\n }\n\n if (valueType === 'text/plain' || valueType === 'application/json') {\n dataFormatOpts.valueType = valueType;\n } else if (valueType !== null && valueType !== undefined) {\n deps.logger?.warn(\n `Invalid Infinispan dataFormat.valueType \"${valueType}\" in config at ${config.storeConfigPath}.dataFormat.valueType. Must be \"text/plain\" | \"application/json\". Not mapped, client will use default 'text/plain'.`,\n );\n }\n behaviorOptions.dataFormat = dataFormatOpts as DataFormatOptions;\n parsedOptions.options = behaviorOptions as InfinispanClientBehaviorOptions;\n\n deps.logger?.debug(\n `Parsed Infinispan options from config at ${\n config.storeConfigPath\n }: ${JSON.stringify(parsedOptions)}`,\n );\n return parsedOptions as InfinispanCacheStoreOptions;\n }\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.cjs.js","sources":["../../../src/entrypoints/cache/types.ts"],"sourcesContent":["/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {
|
|
1
|
+
{"version":3,"file":"types.cjs.js","sources":["../../../src/entrypoints/cache/types.ts"],"sourcesContent":["/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type {\n LoggerService,\n RootConfigService,\n} from '@backstage/backend-plugin-api';\nimport { durationToMilliseconds, type HumanDuration } from '@backstage/types';\nimport type { RedisClusterOptions, KeyvRedisOptions } from '@keyv/redis';\nimport type { KeyvValkeyOptions } from '@keyv/valkey';\nimport type { ClusterNode, ClusterOptions } from 'iovalkey';\n\n/**\n * An object form of a cache store connection, with a URL and additional\n * connection options passed through to the underlying client.\n *\n * @public\n */\nexport type CacheStoreConnectionObject = { url: string } & Record<\n string,\n unknown\n>;\n\n/**\n * A cache store connection, either a URL string or an object with\n * connection options passed through to the underlying client.\n *\n * @public\n */\nexport type CacheStoreConnection = string | CacheStoreConnectionObject;\n\n/**\n * Common config options passed to store-specific config parsers.\n *\n * @public\n */\nexport type CacheStoreConfiguration = {\n storeConfigPath: string;\n};\n\n/**\n * Service dependencies required by cache store config parsers.\n *\n * @public\n */\nexport type CacheStoreDeps = {\n config: RootConfigService;\n logger?: LoggerService;\n};\n\n/**\n * Parse options for the Redis cache store\n *\n * @public\n */\nexport type RedisCacheStoreConfiguration = CacheStoreConfiguration & {\n connection: CacheStoreConnection;\n};\n\n/**\n * Options for Redis cache store.\n *\n * @public\n */\nexport type RedisCacheStoreOptions = {\n type: 'redis';\n client?: KeyvRedisOptions;\n cluster?: RedisClusterOptions;\n};\n\n/**\n * Options for Valkey cache store.\n *\n * @public\n */\nexport type ValkeyCacheStoreOptions = {\n type: 'valkey';\n client?: KeyvValkeyOptions;\n cluster?: {\n rootNodes: Array<ClusterNode>;\n options?: ClusterOptions;\n };\n};\n\n/**\n * Union type of all cache store options.\n *\n * @public\n */\nexport type CacheStoreOptions =\n | RedisCacheStoreOptions\n | ValkeyCacheStoreOptions\n | InfinispanCacheStoreOptions;\n\n/**\n * Options given when constructing a {@link CacheManager}.\n *\n * @public\n */\nexport type CacheManagerOptions = {\n /**\n * An optional logger for use by the PluginCacheManager.\n */\n logger?: LoggerService;\n\n /**\n * An optional handler for connection errors emitted from the underlying data\n * store.\n */\n onError?: (err: Error) => void;\n};\n\nexport function ttlToMilliseconds(ttl: number | HumanDuration): number {\n return typeof ttl === 'number' ? ttl : durationToMilliseconds(ttl);\n}\n\n/**\n * Configuration for a single Infinispan server.\n */\nexport type InfinispanServerConfig = {\n host: string;\n port: number;\n};\n\n/**\n * Options for putting values into Infinispan cache.\n */\nexport type InfinispanPutOptions = {\n lifespan?: string;\n maxIdle?: string;\n previous?: boolean;\n flags?: string[];\n};\n/**\n * SSL/TLS options for the Infinispan client.\n */\nexport type InfinispanSslOptions = {\n enabled: boolean;\n secureProtocol?: string;\n trustCerts?: string[]; // Array of trusted CA certificates\n clientAuth?: InfinispanClientAuthOptions;\n cryptoStore?: InfinispanCryptoStoreOptions;\n sniHostName?: string;\n};\n\n/**\n * Authentication options for the Infinispan client.\n * This is used for client-side authentication with the Infinispan server.\n */\nexport type InfinispanClientAuthOptions = {\n key?: string;\n passphrase?: string;\n cert?: string;\n};\n\n/**\n * Options for the Infinispan client crypto store.\n * This is used for storing keys and certificates securely.\n */\nexport type InfinispanCryptoStoreOptions = {\n path?: string;\n passphrase?: string;\n};\n\n/**\n * Authentication options for the Infinispan client.\n */\nexport type InfinispanAuthOptions = {\n enabled: boolean;\n saslMechanism?: string;\n userName?: string;\n password?: string;\n token?: string;\n authzid?: string;\n};\n\n/**\n * Options for the Infinispan cache store, designed to be configured\n * in app-config.yaml under `backend.cache.infinispan`.\n */\nexport type InfinispanCacheStoreOptions = {\n type: 'infinispan';\n servers: InfinispanServerConfig | InfinispanServerConfig[];\n options?: InfinispanClientBehaviorOptions;\n};\n\nexport type InfinispanClusterConfig = {\n name?: string;\n servers: InfinispanServerConfig[];\n};\n\nexport type DataFormatOptions = {\n keyType: 'text/plain' | 'application/json';\n valueType: 'text/plain' | 'application/json';\n};\n\n/**\n * Detailed client behavior options for the Infinispan client.\n * @public\n */\nexport type InfinispanClientBehaviorOptions = {\n version?: '2.9' | '2.5' | '2.2';\n cacheName?: string;\n maxRetries?: number;\n connectionTimeout?: number;\n socketTimeout?: number;\n authentication?: InfinispanAuthOptions;\n ssl?: InfinispanSslOptions;\n mediaType?: 'text/plain' | 'application/json';\n topologyUpdates?: boolean;\n clusters?: InfinispanClusterConfig[];\n dataFormat: DataFormatOptions;\n};\n"],"names":["durationToMilliseconds"],"mappings":";;;;AA6HO,SAAS,kBAAkB,GAAA,EAAqC;AACrE,EAAA,OAAO,OAAO,GAAA,KAAQ,QAAA,GAAW,GAAA,GAAMA,6BAAuB,GAAG,CAAA;AACnE;;;;"}
|
package/dist/package.json.cjs.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@backstage/backend-defaults",
|
|
3
|
-
"version": "0.17.5
|
|
3
|
+
"version": "0.17.5",
|
|
4
4
|
"description": "Backend defaults used by Backstage backend apps",
|
|
5
5
|
"backstage": {
|
|
6
6
|
"role": "node-library"
|
|
@@ -218,20 +218,20 @@
|
|
|
218
218
|
"@aws-sdk/types": "^3.347.0",
|
|
219
219
|
"@azure/identity": "^4.0.0",
|
|
220
220
|
"@azure/storage-blob": "^12.5.0",
|
|
221
|
-
"@backstage/backend-app-api": "1.7.2
|
|
222
|
-
"@backstage/backend-dev-utils": "0.1.7",
|
|
223
|
-
"@backstage/backend-plugin-api": "1.9.3
|
|
224
|
-
"@backstage/cli-node": "0.3.
|
|
225
|
-
"@backstage/config": "1.3.8",
|
|
226
|
-
"@backstage/config-loader": "1.11.0
|
|
227
|
-
"@backstage/errors": "1.3.1",
|
|
228
|
-
"@backstage/integration": "2.0.3",
|
|
229
|
-
"@backstage/integration-aws-node": "0.2.0",
|
|
230
|
-
"@backstage/plugin-auth-node": "0.7.3
|
|
231
|
-
"@backstage/plugin-events-node": "0.4.24
|
|
232
|
-
"@backstage/plugin-permission-common": "0.9.9",
|
|
233
|
-
"@backstage/plugin-permission-node": "0.11.2
|
|
234
|
-
"@backstage/types": "1.2.2",
|
|
221
|
+
"@backstage/backend-app-api": "^1.7.2",
|
|
222
|
+
"@backstage/backend-dev-utils": "^0.1.7",
|
|
223
|
+
"@backstage/backend-plugin-api": "^1.9.3",
|
|
224
|
+
"@backstage/cli-node": "^0.3.4",
|
|
225
|
+
"@backstage/config": "^1.3.8",
|
|
226
|
+
"@backstage/config-loader": "^1.11.0",
|
|
227
|
+
"@backstage/errors": "^1.3.1",
|
|
228
|
+
"@backstage/integration": "^2.0.3",
|
|
229
|
+
"@backstage/integration-aws-node": "^0.2.0",
|
|
230
|
+
"@backstage/plugin-auth-node": "^0.7.3",
|
|
231
|
+
"@backstage/plugin-events-node": "^0.4.24",
|
|
232
|
+
"@backstage/plugin-permission-common": "^0.9.9",
|
|
233
|
+
"@backstage/plugin-permission-node": "^0.11.2",
|
|
234
|
+
"@backstage/types": "^1.2.2",
|
|
235
235
|
"@google-cloud/storage": "^7.0.0",
|
|
236
236
|
"@keyv/memcache": "^2.0.1",
|
|
237
237
|
"@keyv/redis": "^4.0.1",
|
|
@@ -286,8 +286,8 @@
|
|
|
286
286
|
},
|
|
287
287
|
"devDependencies": {
|
|
288
288
|
"@aws-sdk/util-stream-node": "^3.350.0",
|
|
289
|
-
"@backstage/backend-test-utils": "1.11.5
|
|
290
|
-
"@backstage/cli": "0.36.4
|
|
289
|
+
"@backstage/backend-test-utils": "^1.11.5",
|
|
290
|
+
"@backstage/cli": "^0.36.4",
|
|
291
291
|
"@google-cloud/cloud-sql-connector": "^1.4.0",
|
|
292
292
|
"@types/archiver": "^7.0.0",
|
|
293
293
|
"@types/base64-stream": "^1.0.2",
|
|
@@ -302,7 +302,7 @@
|
|
|
302
302
|
"better-sqlite3": "^12.0.0",
|
|
303
303
|
"get-port": "^5.1.1",
|
|
304
304
|
"http-errors": "^2.0.0",
|
|
305
|
-
"msw": "^
|
|
305
|
+
"msw": "^2.0.0",
|
|
306
306
|
"node-mocks-http": "^1.0.0",
|
|
307
307
|
"supertest": "^7.0.0",
|
|
308
308
|
"wait-for-expect": "^4.0.0"
|