diff --git a/packages/jaeger-ui/index.html b/packages/jaeger-ui/index.html
index c54d657cb7..d5e30a6e26 100644
--- a/packages/jaeger-ui/index.html
+++ b/packages/jaeger-ui/index.html
@@ -33,6 +33,12 @@
const JAEGER_CONFIG = DEFAULT_CONFIG;
return JAEGER_CONFIG;
}
+ // Jaeger storage compabilities data is embedded by the query-service via search-replace.
+ function getJaegerStorageCapabilities() {
+ const DEFAULT_STORAGE_CAPABILITIES = { "archiveStorage": false };
+ const JAEGER_STORAGE_CAPABILITIES = DEFAULT_STORAGE_CAPABILITIES;
+ return JAEGER_STORAGE_CAPABILITIES;
+ }
// Jaeger version data is embedded by the query-service via search/replace.
function getJaegerVersion() {
const DEFAULT_VERSION = {'gitCommit':'', 'gitVersion':'', 'buildDate':''};
diff --git a/packages/jaeger-ui/src/components/TracePage/index.test.js b/packages/jaeger-ui/src/components/TracePage/index.test.js
index bed1d620b7..de4c1a3da4 100644
--- a/packages/jaeger-ui/src/components/TracePage/index.test.js
+++ b/packages/jaeger-ui/src/components/TracePage/index.test.js
@@ -400,8 +400,12 @@ describe('', () => {
it('is true when not embedded and archive is enabled', () => {
[{ timeline: {} }, undefined].forEach(embedded => {
[true, false].forEach(archiveEnabled => {
- wrapper.setProps({ embedded, archiveEnabled });
- expect(wrapper.find(TracePageHeader).prop('showArchiveButton')).toBe(!embedded && archiveEnabled);
+ [{ archiveStorage: false }, { archiveStorage: true }].forEach(storageCapabilities => {
+ wrapper.setProps({ embedded, archiveEnabled, storageCapabilities });
+ expect(wrapper.find(TracePageHeader).prop('showArchiveButton')).toBe(
+ !embedded && archiveEnabled && storageCapabilities.archiveStorage
+ );
+ });
});
});
});
diff --git a/packages/jaeger-ui/src/components/TracePage/index.tsx b/packages/jaeger-ui/src/components/TracePage/index.tsx
index eb15b2882b..1a887e713d 100644
--- a/packages/jaeger-ui/src/components/TracePage/index.tsx
+++ b/packages/jaeger-ui/src/components/TracePage/index.tsx
@@ -57,7 +57,7 @@ import updateUiFind from '../../utils/update-ui-find';
import TraceStatistics from './TraceStatistics/index';
import TraceSpanView from './TraceSpanView/index';
import TraceFlamegraph from './TraceFlamegraph/index';
-import { TraceGraphConfig } from '../../types/config';
+import { StorageCapabilities, TraceGraphConfig } from '../../types/config';
import './index.css';
import memoizedTraceCriticalPath from './CriticalPath/index';
@@ -78,6 +78,7 @@ type TOwnProps = {
type TReduxProps = {
archiveEnabled: boolean;
+ storageCapabilities: StorageCapabilities | TNil;
archiveTraceState: TraceArchive | TNil;
criticalPathEnabled: boolean;
embedded: null | EmbeddedState;
@@ -326,6 +327,7 @@ export class TracePageImpl extends React.PureComponent {
render() {
const {
archiveEnabled,
+ storageCapabilities,
archiveTraceState,
criticalPathEnabled,
embedded,
@@ -359,6 +361,7 @@ export class TracePageImpl extends React.PureComponent {
}
const isEmbedded = Boolean(embedded);
+ const hasArchiveStorage = Boolean(storageCapabilities?.archiveStorage);
const headerProps = {
focusUiFindMatches: this.focusUiFindMatches,
slimView,
@@ -380,7 +383,7 @@ export class TracePageImpl extends React.PureComponent {
ref: this._searchBar,
resultCount: findCount,
disableJsonView,
- showArchiveButton: !isEmbedded && archiveEnabled,
+ showArchiveButton: !isEmbedded && archiveEnabled && hasArchiveStorage,
showShortcutsHelp: !isEmbedded,
showStandaloneLink: isEmbedded,
showViewOptions: !isEmbedded,
@@ -445,6 +448,7 @@ export function mapStateToProps(state: ReduxState, ownProps: TOwnProps): TReduxP
const trace = id ? traces[id] : null;
const archiveTraceState = id ? archive[id] : null;
const archiveEnabled = Boolean(config.archiveEnabled);
+ const storageCapabilities = config.storageCapabilities;
const { disableJsonView, criticalPathEnabled } = config;
const { state: locationState } = router.location;
const searchUrl = (locationState && locationState.fromSearch) || null;
@@ -453,6 +457,7 @@ export function mapStateToProps(state: ReduxState, ownProps: TOwnProps): TReduxP
return {
...extractUiFindFromState(state),
archiveEnabled,
+ storageCapabilities,
archiveTraceState,
criticalPathEnabled,
embedded,
diff --git a/packages/jaeger-ui/src/constants/default-config.tsx b/packages/jaeger-ui/src/constants/default-config.tsx
index 9f1bc4bff7..9bf2ce2155 100644
--- a/packages/jaeger-ui/src/constants/default-config.tsx
+++ b/packages/jaeger-ui/src/constants/default-config.tsx
@@ -21,7 +21,7 @@ import { version } from '../../package.json';
import { Config } from '../types/config';
const defaultConfig: Config = {
- archiveEnabled: false,
+ archiveEnabled: true,
criticalPathEnabled: true,
dependencies: {
dagMaxNumServices: FALLBACK_DAG_MAX_NUM_SERVICES,
@@ -77,6 +77,9 @@ const defaultConfig: Config = {
},
maxLimit: 1500,
},
+ storageCapabilities: {
+ archiveStorage: false,
+ },
tracking: {
gaID: null,
trackErrors: true,
diff --git a/packages/jaeger-ui/src/types/config.tsx b/packages/jaeger-ui/src/types/config.tsx
index e6938f2a00..e27b43b35e 100644
--- a/packages/jaeger-ui/src/types/config.tsx
+++ b/packages/jaeger-ui/src/types/config.tsx
@@ -82,6 +82,11 @@ export type TraceGraphConfig = {
layoutManagerMemory?: number;
};
+export type StorageCapabilities = {
+ // archiveStorage indicates whether the query service supports archive storage.
+ archiveStorage?: boolean;
+};
+
// Default values are provided in packages/jaeger-ui/src/constants/default-config.tsx
export type Config = {
//
@@ -130,6 +135,9 @@ export type Config = {
// TODO when is it useful?
scripts?: readonly TScript[];
+ // storage capabilities given by the query service.
+ storageCapabilities?: StorageCapabilities;
+
// topTagPrefixes defines a set of prefixes for span tag names that are considered
// "important" and cause the matching tags to appear higher in the list of tags.
// For example, topTagPrefixes=['http.'] would cause all span tags that begin with
diff --git a/packages/jaeger-ui/src/utils/config/get-config.test.js b/packages/jaeger-ui/src/utils/config/get-config.test.js
index d2456036df..75e445b054 100644
--- a/packages/jaeger-ui/src/utils/config/get-config.test.js
+++ b/packages/jaeger-ui/src/utils/config/get-config.test.js
@@ -37,9 +37,10 @@ describe('getConfig()', () => {
console.warn = oldWarn;
});
- describe('`window.getJaegerUiConfig` is not a function', () => {
+ describe('index functions are not yet injected by backend', () => {
beforeAll(() => {
window.getJaegerUiConfig = undefined;
+ window.getJaegerStorageCapabilities = undefined;
});
it('warns once', () => {
@@ -54,15 +55,16 @@ describe('getConfig()', () => {
});
});
- describe('`window.getJaegerUiConfig` is a function', () => {
+ describe('index functions are injected by backend', () => {
let embedded;
- let getJaegerUiConfig;
+ let capabilities;
beforeEach(() => {
getConfig.apply({}, []);
embedded = {};
- getJaegerUiConfig = jest.fn(() => embedded);
- window.getJaegerUiConfig = getJaegerUiConfig;
+ window.getJaegerUiConfig = jest.fn(() => embedded);
+ capabilities = defaultConfig.storageCapabilities;
+ window.getJaegerStorageCapabilities = jest.fn(() => capabilities);
});
it('returns the default config when the embedded config is `null`', () => {
@@ -70,9 +72,10 @@ describe('getConfig()', () => {
expect(getConfig()).toEqual(defaultConfig);
});
- it('merges the defaultConfig with the embedded config ', () => {
+ it('merges the defaultConfig with the embedded config and storage capabilities', () => {
embedded = { novel: 'prop' };
- expect(getConfig()).toEqual({ ...defaultConfig, ...embedded });
+ capabilities = { archiveStorage: true };
+ expect(getConfig()).toEqual({ ...defaultConfig, ...embedded, storageCapabilities: capabilities });
});
describe('overwriting precedence and merging', () => {
@@ -84,7 +87,7 @@ describe('getConfig()', () => {
keys.forEach(key => {
embedded[key] = key;
});
- expect(getConfig()).toEqual({ ...defaultConfig, ...embedded });
+ expect(getConfig()).toEqual({ ...defaultConfig, ...embedded, storageCapabilities: capabilities });
});
});
@@ -94,7 +97,7 @@ describe('getConfig()', () => {
mergeFields.forEach((k, i) => {
embedded[k] = i ? true : null;
});
- expect(getConfig()).toEqual({ ...defaultConfig, ...embedded });
+ expect(getConfig()).toEqual({ ...defaultConfig, ...embedded, storageCapabilities: capabilities });
});
it('merges object values', () => {
@@ -105,8 +108,8 @@ describe('getConfig()', () => {
}
embedded[key] = { a: true, b: false };
const expected = { ...defaultConfig, ...embedded };
- expected[key] = { ...defaultConfig[key], ...embedded[key] };
- expect(getConfig()).toEqual(expected);
+ expected[key] = { ...defaultConfig[key], ...embedded[key]};
+ expect(getConfig()).toEqual({...expected, storageCapabilities: capabilities});
});
});
});
diff --git a/packages/jaeger-ui/src/utils/config/get-config.tsx b/packages/jaeger-ui/src/utils/config/get-config.tsx
index 7d39ac7b93..11f3ee01f6 100644
--- a/packages/jaeger-ui/src/utils/config/get-config.tsx
+++ b/packages/jaeger-ui/src/utils/config/get-config.tsx
@@ -26,36 +26,45 @@ let haveWarnedDeprecations = false;
* default config from `../../constants/default-config`.
*/
const getConfig = memoizeOne(function getConfig() {
- const getJaegerUiConfig = window.getJaegerUiConfig;
- if (typeof getJaegerUiConfig !== 'function') {
- if (!haveWarnedFactoryFn) {
- // eslint-disable-next-line no-console
- console.warn('Embedded config not available');
- haveWarnedFactoryFn = true;
- }
- return { ...defaultConfig };
- }
- const embedded = getJaegerUiConfig();
+ const capabilities = getCapabilities();
+
+ const embedded = getUiConfig();
if (!embedded) {
- return { ...defaultConfig };
+ return {...defaultConfig, storageCapabilities: capabilities};
}
// check for deprecated config values
if (Array.isArray(deprecations)) {
deprecations.forEach(deprecation => processDeprecation(embedded, deprecation, !haveWarnedDeprecations));
haveWarnedDeprecations = true;
}
- const rv = { ...defaultConfig, ...embedded };
+ const rv = { ...defaultConfig, ...embedded};
// mergeFields config values should be merged instead of fully replaced
const keys = mergeFields;
for (let i = 0; i < keys.length; i++) {
const key = keys[i];
- if (typeof embedded[key] === 'object' && embedded[key] !== null) {
+ if (embedded && typeof embedded[key] === 'object' && embedded[key] !== null) {
rv[key] = { ...defaultConfig[key], ...embedded[key] };
}
}
- return rv;
+ return {...rv, storageCapabilities: capabilities};
});
+function getUiConfig() {
+ const getter = window.getJaegerUiConfig;
+ if (typeof getter !== 'function') {
+ // eslint-disable-next-line no-console
+ console.warn('Embedded config not available');
+ return { ...defaultConfig };
+ }
+ return getter();
+}
+
+function getCapabilities() {
+ const getter = window.getJaegerStorageCapabilities;
+ const capabilities = (typeof getter === 'function') ? getter() : null;
+ return (capabilities) ? capabilities : defaultConfig.storageCapabilities;
+}
+
export default getConfig;
export function getConfigValue(path: string) {
diff --git a/packages/jaeger-ui/test/jest-per-test-setup.js b/packages/jaeger-ui/test/jest-per-test-setup.js
index 2a411af60b..30793654eb 100644
--- a/packages/jaeger-ui/test/jest-per-test-setup.js
+++ b/packages/jaeger-ui/test/jest-per-test-setup.js
@@ -32,6 +32,7 @@ expect.addSnapshotSerializer(createSerializer({ mode: 'deep' }));
// Calls to get-config.tsx and get-version.tsx warn if these globals are not functions.
// This file is executed before each test file, so they may be overridden safely.
window.getJaegerUiConfig = () => ({});
+window.getJaegerStorageCapabilities = () => ({});
window.getJaegerVersion = () => ({
gitCommit: '',
gitVersion: '',
diff --git a/packages/jaeger-ui/typings/custom.d.ts b/packages/jaeger-ui/typings/custom.d.ts
index cc78cbc49e..b12c879ab4 100644
--- a/packages/jaeger-ui/typings/custom.d.ts
+++ b/packages/jaeger-ui/typings/custom.d.ts
@@ -22,6 +22,7 @@ declare interface Window {
__webpack_public_path__: string; // eslint-disable-line camelcase
// For getting ui config
getJaegerUiConfig?: () => Record;
+ getJaegerStorageCapabilities?: () => Record;
getJaegerVersion?: () => Record;
}