Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add adblocker and 0/single node disclaimers #502

Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions packages/jaeger-ui/src/components/App/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,28 @@ a {
a:hover {
color: #00474e;
}

/* TODO: Delete to end of file */
a[href='/deep-dependencies'] {
overflow: hidden;
padding-right: 40px;
position: relative;
}

.ant-menu-horizontal > li:last-child {
padding-right: 0px;
}

a[href='/deep-dependencies']:after {
content: 'New!';
background-color: red;
height: 60px;
overflow: hidden;
padding-left: 30px;
padding-top: 25px;
position: absolute;
right: -50px;
top: -25px;
transform: rotateZ(45deg);
width: 100px;
}
6 changes: 6 additions & 0 deletions packages/jaeger-ui/src/components/DeepDependencies/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,12 @@ limitations under the License.
right: 0;
}

.Ddg--center {
margin: auto;
text-align: center;
max-width: 60%;
}

.Ddg--graphWrapper {
flex: 1;
overflow: hidden;
Expand Down
150 changes: 129 additions & 21 deletions packages/jaeger-ui/src/components/DeepDependencies/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,12 @@ import Graph from './Graph';
import Header from './Header';
import ErrorMessage from '../common/ErrorMessage';
import LoadingIndicator from '../common/LoadingIndicator';
import * as getSearchUrl from '../SearchTracePage/url';
import { fetchedState } from '../../constants';
import getStateEntryKey from '../../model/ddg/getStateEntryKey';
import * as GraphModel from '../../model/ddg/GraphModel';
import * as codec from '../../model/ddg/visibility-codec';
import * as getConfig from '../../utils/config/get-config';

import { ECheckedStatus, EDirection, EDdgDensity, EViewModifier } from '../../model/ddg/types';

Expand Down Expand Up @@ -74,6 +76,7 @@ describe('DeepDependencyGraphPage', () => {
getVisWithUpdatedGeneration: jest.fn(),
},
};
const { operation: _o, ...urlStateWithoutOp } = props.urlState;
const ddgPageImpl = new DeepDependencyGraphPageImpl(props);
const ddgWithoutGraph = new DeepDependencyGraphPageImpl(propsWithoutGraph);
const setIdx = visibilityIdx => ({ visibilityIdx });
Expand Down Expand Up @@ -187,7 +190,6 @@ describe('DeepDependencyGraphPage', () => {

it('removes op from urlState', () => {
ddgPageImpl.clearOperation();
const { operation: _o, ...urlStateWithoutOp } = props.urlState;
expect(getUrlSpy).toHaveBeenLastCalledWith(urlStateWithoutOp, undefined);
expect(trackClearOperationSpy).toHaveBeenCalledTimes(1);
});
Expand Down Expand Up @@ -596,25 +598,27 @@ describe('DeepDependencyGraphPage', () => {

describe('render', () => {
const vertices = [{ key: 'key0' }, { key: 'key1' }, { key: 'key2' }];
const visibleFindCount = vertices.length - 1;
const graph = {
getVisible: () => ({
edges: [
{
from: vertices[0].key,
to: vertices[1].key,
},
{
from: vertices[1].key,
to: vertices[2].key,
},
],
vertices,
}),
getVisible: jest.fn(),
getDerivedViewModifiers: () => ({ edges: new Map(), vertices: new Map() }),
getHiddenUiFindMatches: () => new Set(vertices.slice(1)),
getVisibleUiFindMatches: () => new Set(vertices.slice(0, 1)),
getHiddenUiFindMatches: () => new Set(vertices.slice(visibleFindCount)),
getVisibleUiFindMatches: () => new Set(vertices.slice(0, visibleFindCount)),
getVisibleIndices: () => new Set(),
};
graph.getVisible.mockReturnValue({
edges: [
{
from: vertices[0].key,
to: vertices[1].key,
},
{
from: vertices[1].key,
to: vertices[2].key,
},
],
vertices,
});

it('renders message to query a ddg when no graphState is provided', () => {
const message = shallow(<DeepDependencyGraphPageImpl {...props} graphState={undefined} />)
Expand All @@ -639,9 +643,111 @@ describe('DeepDependencyGraphPage', () => {
expect(errorComponent.prop('error')).toBe(error);
});

it('renders graph when done', () => {
const wrapper = shallow(<DeepDependencyGraphPageImpl {...props} graph={graph} />);
expect(wrapper.find(Graph)).toHaveLength(1);
describe('graphState.state === fetchedState.DONE', () => {
function makeGraphState(specifiedDistance, vertexCount = 1) {
graph.getVisible.mockReturnValueOnce({
edges: [],
vertices: vertices.slice(vertices.length - vertexCount),
});
return {
graphState: {
...props.graphState,
model: {
...props.graphState.model,
distanceToPathElems: specifiedDistance
? new Map([[specifiedDistance, 'test elem']])
: new Map(),
},
},
};
}
let getConfigValueSpy;
let getSearchUrlSpy;
let wrapper;

beforeAll(() => {
getConfigValueSpy = jest.spyOn(getConfig, 'getConfigValue');
getSearchUrlSpy = jest.spyOn(getSearchUrl, 'getUrl');
});

beforeEach(() => {
getConfigValueSpy.mockClear();
getSearchUrlSpy.mockClear();
wrapper = shallow(<DeepDependencyGraphPageImpl {...props} graph={graph} />);
});

it('renders graph if there are multiple vertices visible', () => {
const graphComponent = wrapper.find(Graph);

expect(graphComponent).toHaveLength(1);
expect(graphComponent.prop('vertices')).toBe(vertices);
});

it('renders disclaimer to show more hops if one or fewer vertices are visible and more hops were in paylaod', () => {
const expectedHeader = 'There is nothing visible to show';
const expectedInstruction = 'Select at least one hop to view';
expect(wrapper.find(Graph)).toHaveLength(1);

wrapper.setProps(makeGraphState(1));
expect(wrapper.find(Graph)).toHaveLength(0);
expect(wrapper.find('h1.Ddg--center').text()).toBe(expectedHeader);
expect(wrapper.find('p.Ddg--center').text()).toBe(expectedInstruction);

wrapper.setProps(makeGraphState(-1, 0));
expect(wrapper.find(Graph)).toHaveLength(0);
expect(wrapper.find('h1.Ddg--center').text()).toBe(expectedHeader);
expect(wrapper.find('p.Ddg--center').text()).toBe(expectedInstruction);
});

it('renders disclaimer that service has no known dependencies with correct link to verify', () => {
const expectedHeader = 'There are no dependencies';
const { operation, service } = props.urlState;
const expectedInstruction = (withOp = true) =>
`No traces were found that contain ${service}${
withOp ? `:${operation}` : ''
} and any other service where span.kind is ‘server’.`;
const lookback = 'test look back';
getConfigValueSpy.mockReturnValue(lookback);
const mockUrl = 'test search url';
getSearchUrlSpy.mockReturnValue(mockUrl);

expect(wrapper.find(Graph)).toHaveLength(1);

wrapper.setProps(makeGraphState());
expect(wrapper.find(Graph)).toHaveLength(0);
expect(wrapper.find('h1.Ddg--center').text()).toBe(expectedHeader);
expect(
wrapper
.find('p.Ddg--center')
.first()
.text()
).toBe(expectedInstruction());
expect(wrapper.find('a').prop('href')).toBe(mockUrl);
expect(getSearchUrlSpy).toHaveBeenLastCalledWith({
lookback,
minDuration: '0ms',
operation,
service,
tags: '{"span.kind":"server"}',
});

wrapper.setProps({ urlState: urlStateWithoutOp, ...makeGraphState() });
expect(wrapper.find(Graph)).toHaveLength(0);
expect(wrapper.find('h1.Ddg--center').text()).toBe(expectedHeader);
expect(
wrapper
.find('p.Ddg--center')
.first()
.text()
).toBe(expectedInstruction(false));
expect(wrapper.find('a').prop('href')).toBe(mockUrl);
expect(getSearchUrlSpy).toHaveBeenLastCalledWith({
lookback,
minDuration: '0ms',
service,
tags: '{"span.kind":"server"}',
});
});
});

it('renders indication of unknown graphState', () => {
Expand Down Expand Up @@ -674,8 +780,10 @@ describe('DeepDependencyGraphPage', () => {
expect(wrapper.find(Header).prop('hiddenUiFindMatches')).toBe(undefined);

wrapper.setProps({ graph });
expect(wrapper.find(Header).prop('uiFindCount')).toBe(1);
expect(wrapper.find(Header).prop('hiddenUiFindMatches').size).toBe(vertices.length - 1);
expect(wrapper.find(Header).prop('uiFindCount')).toBe(visibleFindCount);
expect(wrapper.find(Header).prop('hiddenUiFindMatches').size).toBe(
vertices.length - visibleFindCount
);
});

it('passes correct operations to Header', () => {
Expand Down
92 changes: 66 additions & 26 deletions packages/jaeger-ui/src/components/DeepDependencies/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import { getUrl, getUrlState, sanitizeUrlState, ROUTE_PATH } from './url';
import ErrorMessage from '../common/ErrorMessage';
import LoadingIndicator from '../common/LoadingIndicator';
import { extractUiFindFromState, TExtractUiFindFromStateReturn } from '../common/UiFindInput';
import { getUrl as getSearchUrl } from '../SearchTracePage/url';
import ddgActions from '../../actions/ddg';
import * as jaegerApiActions from '../../actions/jaeger-api';
import { fetchedState } from '../../constants';
Expand All @@ -39,6 +40,7 @@ import {
TDdgSparseUrlState,
} from '../../model/ddg/types';
import { encode, encodeDistance } from '../../model/ddg/visibility-codec';
import { getConfigValue } from '../../utils/config/get-config';
import { ReduxState } from '../../types';
import { TDdgStateEntry } from '../../types/TDdgState';

Expand Down Expand Up @@ -262,37 +264,75 @@ export class DeepDependencyGraphPageImpl extends React.PureComponent<TProps> {
visEncoding,
viewModifiers
);
// TODO: using `key` here is a hack, debug digraph to fix the underlying issue
content = (
<Graph
key={JSON.stringify(urlState)}
baseUrl={baseUrl}
density={density}
edges={edges}
edgesViewModifiers={edgesViewModifiers}
extraUrlArgs={extraUrlArgs}
focusPathsThroughVertex={this.focusPathsThroughVertex}
getGenerationVisibility={this.getGenerationVisibility}
getVisiblePathElems={this.getVisiblePathElems}
hideVertex={this.hideVertex}
setOperation={this.setOperation}
setViewModifier={this.setViewModifier}
uiFindMatches={uiFindMatches}
updateGenerationVisibility={this.updateGenerationVisibility}
vertices={vertices}
verticesViewModifiers={verticesViewModifiers}
/>
);
if (vertices.length > 1) {
// TODO: using `key` here is a hack, debug digraph to fix the underlying issue
content = (
<Graph
key={JSON.stringify(urlState)}
baseUrl={baseUrl}
density={density}
edges={edges}
edgesViewModifiers={edgesViewModifiers}
extraUrlArgs={extraUrlArgs}
focusPathsThroughVertex={this.focusPathsThroughVertex}
getGenerationVisibility={this.getGenerationVisibility}
getVisiblePathElems={this.getVisiblePathElems}
hideVertex={this.hideVertex}
setOperation={this.setOperation}
setViewModifier={this.setViewModifier}
uiFindMatches={uiFindMatches}
updateGenerationVisibility={this.updateGenerationVisibility}
vertices={vertices}
verticesViewModifiers={verticesViewModifiers}
/>
);
} else if (
graphState.model.distanceToPathElems.has(-1) ||
graphState.model.distanceToPathElems.has(1)
) {
content = (
<>
<h1 className="Ddg--center">There is nothing visible to show</h1>
<p className="Ddg--center">Select at least one hop to view</p>
</>
);
} else {
const lookback = getConfigValue('search.maxLookback.value');
const checkLink = getSearchUrl({
lookback,
minDuration: '0ms',
operation,
service,
tags: '{"span.kind":"server"}',
});
content = (
<>
<h1 className="Ddg--center">There are no dependencies</h1>
<p className="Ddg--center">
No traces were found that contain {service}
{operation && `:${operation}`} and any other service where span.kind is &lsquo;server&rsquo;.
</p>
<p className="Ddg--center">
<a href={checkLink}>Confirm by searching</a>
</p>
</>
);
}
} else if (graphState.state === fetchedState.LOADING) {
content = <LoadingIndicator centered className="u-mt-vast" />;
} else if (graphState.state === fetchedState.ERROR) {
content = <ErrorMessage error={graphState.error} className="ub-m4" />;
content = (
<>
<ErrorMessage error={graphState.error} className="ub-m4" />
<p className="Ddg--center">If you are using an adblocker, whitelist Jaeger and retry.</p>
</>
);
} else {
content = (
<div>
<h1>Unknown graphState:</h1>
<p>${JSON.stringify(graphState)}</p>
</div>
<>
<h1 className="Ddg--center">Unknown graphState:</h1>
<p className="Ddg--center">{JSON.stringify(graphState, null, 2)}</p>
</>
);
}

Expand Down
4 changes: 4 additions & 0 deletions packages/jaeger-ui/src/constants/default-config.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ export default deepFreeze(
Object.defineProperty(
{
archiveEnabled: false,
// TODO: remove default
deepDependencies: {
menuEnabled: true,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we really want that in oss? There's no backend to generate DDGs.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah hence the TODO and comment above that I thought TODOs were dealt with...
definitely won't have this on by default. same with the New! css

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

},
dependencies: {
dagMaxNumServices: FALLBACK_DAG_MAX_NUM_SERVICES,
menuEnabled: true,
Expand Down