Skip to content

Commit

Permalink
link cache operational! now to wire it up.
Browse files Browse the repository at this point in the history
Signed-off-by: Dave Shanley <dave@quobix.com>
  • Loading branch information
daveshanley committed Jun 21, 2023
1 parent 64bc6dd commit ec9ea97
Show file tree
Hide file tree
Showing 11 changed files with 364 additions and 35 deletions.
4 changes: 3 additions & 1 deletion ui/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@
<title>wiretap: Sniff your API traffic for OpenAPI compliance</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no">
<script>
sessionStorage.setItem('wiretapPort', '%WIRETAP_PORT%')
//sessionStorage.setItem('wiretapPort', '%WIRETAP_PORT%')
sessionStorage.setItem('wiretapPort', '9092')
</script>
<script type="module" src="/src/index.ts"></script>
<script type="module" src="/src/workers/link_cache_worker.ts"></script>
</head>
<body>
<!-- start wiretap. To learn more: https://pb33f.io/wiretap -->
Expand Down
3 changes: 2 additions & 1 deletion ui/src/components/controls/filters.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,8 @@ export class WiretapControlsFiltersComponent extends LitElement {
</sl-tag>`
})}
</div>
${requestChainsFeature}
`
}
Expand Down
38 changes: 34 additions & 4 deletions ui/src/components/transaction/transaction-container.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {SpecEditor} from "@/components/editor/editor";
import {ViolationLocation} from "@/model/events";
import {WiretapCurrentSpec, WiretapFiltersKey, WiretapLocalStorage} from "@/model/constants";
import {AreFiltersActive, WiretapFilters} from "@/model/controls";
import {TransactionLinkCache} from "@/model/link_cache";

@customElement('http-transaction-container')
export class HttpTransactionContainerComponent extends LitElement {
Expand All @@ -22,6 +23,7 @@ export class HttpTransactionContainerComponent extends LitElement {
private _transactionComponents: HttpTransactionItemComponent[] = [];
private _filteredTransactionComponents: HttpTransactionItemComponent[] = [];
private readonly _filtersStore: Bag<WiretapFilters>;
private _transactionLinkCache: TransactionLinkCache;

@state()
private _mappedHttpTransactions: Map<string, HttpTransactionContainer>
Expand Down Expand Up @@ -52,6 +54,17 @@ export class HttpTransactionContainerComponent extends LitElement {
// filters store & subscribe to filter changes.
this._filtersStore.subscribe(WiretapFiltersKey, this.filtersChanged.bind(this))

// create a transaction link cache
// todo: come back and wire this up to state in indexeddb.









}

filtersChanged(filters: WiretapFilters) {
Expand All @@ -77,7 +90,7 @@ export class HttpTransactionContainerComponent extends LitElement {
storeData.forEach((value: HttpTransaction, key: string) => {
const container: HttpTransactionContainer = {
Transaction: BuildLiveTransactionFromState(value),
Listener: (update: HttpTransaction) => {
Listener: () => {
this.requestUpdate();
}
}
Expand All @@ -86,7 +99,6 @@ export class HttpTransactionContainerComponent extends LitElement {
// save our internal state.
this._mappedHttpTransactions = savedTransactions


// extract state
this._mappedHttpTransactions.forEach(
(v: HttpTransactionContainer) => {
Expand All @@ -95,8 +107,12 @@ export class HttpTransactionContainerComponent extends LitElement {
}
);

// perform filtering.
this.filterComponents()
});

this._transactionLinkCache = new TransactionLinkCache()

}

handleSelectedTransactionChange(key: string, transaction: HttpTransaction) {
Expand Down Expand Up @@ -170,6 +186,7 @@ export class HttpTransactionContainerComponent extends LitElement {
this.filterComponents();
}
this.requestUpdate();
this._transactionLinkCache.sync();
}

filterComponents() {
Expand All @@ -187,13 +204,26 @@ export class HttpTransactionContainerComponent extends LitElement {

// re-filter by keywords
if (this._filters.filterKeywords.length > 0) {

filtered = filtered.filter( (v: HttpTransactionItemComponent) => {
const filter = v.httpTransaction.matchesKeywordFilter(this._filters);
return filter != false;
})
}


// re-filter by chains
if (this._filters.filterChain.length > 0) {
filtered = filtered.filter( (v: HttpTransactionItemComponent) => {
const filter = v.httpTransaction.containsActiveLink(this._filters);
v.httpTransaction.containsChainLink = (filter != false);
v.requestUpdate()
return true
})
} else {
// wipe out links, nothing to link.
filtered.forEach( (v: HttpTransactionItemComponent) => {
v.httpTransaction.containsChainLink = false;
v.requestUpdate()
})
}

this._filteredTransactionComponents = filtered;
Expand Down
19 changes: 19 additions & 0 deletions ui/src/components/transaction/transaction-item.css.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,5 +80,24 @@ export default css`
font-size: 21px;
color: var(--dark-font-color);
}
.chain {
width: 20px;
margin: 5px 10px 0 10px;
color: var(--secondary-color);
}
.chain sl-icon {
vertical-align: bottom;
font-size: 21px;
color: var(--dark-font-color);
}
.chain sl-icon:hover {
color: var(--terminal-yellow);
}
.transaction-status {
display: flex;
}
`
8 changes: 8 additions & 0 deletions ui/src/components/transaction/transaction-item.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,13 @@ export class HttpTransactionItemComponent extends LitElement {
delay = html`<div class="delay"><sl-icon name="hourglass-split" ></sl-icon>${this._httpTransaction.delay}ms</div>`
}


let chainLink: TemplateResult;

if (this._httpTransaction.containsChainLink) {
chainLink = html`<div class="chain"><sl-icon name="link-45deg"></sl-icon></div>`
}

return html`
<div class="${tClass}" @click="${this.setActive}">
<header>
Expand All @@ -106,6 +113,7 @@ export class HttpTransactionItemComponent extends LitElement {
</header>
${delay}
<div class="transaction-status">
${chainLink}
${statusIcon}
</div>
</div>`
Expand Down
24 changes: 16 additions & 8 deletions ui/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

import '@shoelace-style/shoelace/dist/themes/light.css';
import '@shoelace-style/shoelace/dist/themes/dark.css';
import '@shoelace-style/shoelace/dist/components/tag/tag.js';
Expand All @@ -20,13 +19,13 @@ import '@shoelace-style/shoelace/dist/components/divider/divider.js';
import '@shoelace-style/shoelace/dist/components/select/select.js';
import '@shoelace-style/shoelace/dist/components/option/option.js';



// css
import './css/variables.css'
import './css/pb33f.css'
import './css/header.css'
import './css/syntax.css'

// wiretap components
import './components/wiretap-header/header';
import './components/transaction/transaction-container';
import './components/transaction/transaction-view';
Expand All @@ -40,13 +39,22 @@ import './components/controls/settings.component';
import './components/controls/filters.component';


// models
import './model/http_transaction';
import './wiretap';

// boot.
import './wiretap';

// configure shoelace
// Set the base path to the folder you copied Shoelace's assets to
//setBasePath('/assets/shoelace');
import {setBasePath} from '@shoelace-style/shoelace/dist/utilities/base-path.js';
setBasePath('/shoelace');

export const workerFactory = (workerScript: URL, workerOptions: WorkerOptions) => () =>
new Worker(workerScript, workerOptions);

export const linkCacheFactory = workerFactory(new URL('./workers/link_cache_worker.ts', import.meta.url), {
type: 'module',
});


// Set the base path to the folder you copied Shoelace's assets to
setBasePath('/assets/shoelace');
//setBasePath('/shoelace');
4 changes: 4 additions & 0 deletions ui/src/model/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ export const WiretapControlsStore = "wiretap-controls-store";

export const WiretapFiltersStore = "wiretap-filters-store";

export const WiretapLinkCacheStore = "http-link-cache-store";

export const WiretapLinkCacheKey = "http-link-cache";


export const WiretapFiltersKey = "wiretap-filters";

Expand Down
43 changes: 37 additions & 6 deletions ui/src/model/http_transaction.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import {ExtractQueryString} from "@/model/extract_query";
import {Filter, WiretapFilters} from "@/model/controls";
import {Filter, WiretapControls, WiretapFilters} from "@/model/controls";
import {Bag, CreateBagManager, GetBagManager} from "@pb33f/saddlebag";
import {WiretapHttpTransactionStore} from "@/model/constants";
import {linkCacheFactory} from "@/index";
import {LinkCacheUpdate} from "@/workers/link_cache_worker";

export interface HttpCookie {
value?: string;
Expand Down Expand Up @@ -89,29 +93,40 @@ export class HttpResponse {
}
}

export class HttpTransaction {
export class HttpTransactionBase {
id?: string;
timestamp?: number;
}

export interface HttpTransactionLink extends HttpTransactionBase {
queryString?: string;
}

export class HttpTransaction extends HttpTransactionBase {
delay?: number;
httpRequest?: HttpRequest;
requestValidation?: ValidationError[];
httpResponse?: HttpResponse;
responseValidation?: ValidationError[];
id?: string;
containsChainLink?: boolean;
httpRequest?: HttpRequest;

constructor(timestamp?: number,
delay?: number,
httpRequest?: HttpRequest,
httpResponse?: HttpResponse,
id?: string,
requestValidation?: ValidationError[],
responseValidation?: ValidationError[]) {
responseValidation?: ValidationError[],
containsChainLink?: boolean) {
super();
this.timestamp = timestamp;
this.delay = delay;
this.httpRequest = httpRequest;
this.httpResponse = httpResponse;
this.id = id;
this.requestValidation = requestValidation;
this.responseValidation = responseValidation;
this.containsChainLink = containsChainLink
}

matchesMethodFilter(filter: WiretapFilters): Filter | boolean {
Expand Down Expand Up @@ -157,8 +172,23 @@ export class HttpTransaction {
return false;
}

containsActiveLink(filter: WiretapFilters): Filter | boolean {
if (filter?.filterChain?.length > 0) {
for (let i = 0; i < filter.filterChain.length; i++) {
const chainFilter = filter.filterChain[i];
const rex = `(${chainFilter.keyword.toLowerCase()})=([\\w\\d]+)`
if (this.httpRequest.query?.toLowerCase().match(rex)) {
return chainFilter;
}
}
}
return false;
}

}



export function BuildLiveTransactionFromState(httpTransaction: HttpTransaction): HttpTransaction {
return new HttpTransaction(
httpTransaction.timestamp,
Expand All @@ -167,5 +197,6 @@ export function BuildLiveTransactionFromState(httpTransaction: HttpTransaction):
Object.assign(new HttpResponse(), httpTransaction.httpResponse),
httpTransaction.id,
httpTransaction.requestValidation,
httpTransaction.responseValidation);
httpTransaction.responseValidation,
httpTransaction.containsChainLink)
}
Loading

0 comments on commit ec9ea97

Please sign in to comment.