Skip to content

Commit

Permalink
Implement the cache card for the new dev ui
Browse files Browse the repository at this point in the history
  • Loading branch information
cescoffier committed Feb 26, 2023
1 parent 88cfc7d commit e0e36e8
Show file tree
Hide file tree
Showing 4 changed files with 228 additions and 0 deletions.
9 changes: 9 additions & 0 deletions extensions/cache/deployment/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,15 @@
<groupId>io.quarkus</groupId>
<artifactId>quarkus-mutiny-deployment</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-vertx-http-dev-ui-spi</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-vertx-http-deployment</artifactId>
<optional>true</optional>
</dependency>

<!-- Test dependencies -->
<dependency>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package io.quarkus.cache.deployment.devconsole;

import io.quarkus.cache.runtime.devconsole.CacheJsonRPCService;
import io.quarkus.deployment.IsDevelopment;
import io.quarkus.deployment.annotations.BuildStep;
import io.quarkus.deployment.pkg.builditem.CurateOutcomeBuildItem;
import io.quarkus.devui.spi.JsonRPCProvidersBuildItem;
import io.quarkus.devui.spi.page.CardPageBuildItem;
import io.quarkus.devui.spi.page.Page;

public class CacheDevUiConsoleProcessor {

@BuildStep(onlyIf = IsDevelopment.class)
CardPageBuildItem create(CurateOutcomeBuildItem bi) {
CardPageBuildItem pageBuildItem = new CardPageBuildItem("Cache");
pageBuildItem.addPage(Page.webComponentPageBuilder()
.title("Caches")
.componentLink("cache-component.js")
.icon("font-awesome-solid:database"));

return pageBuildItem;
}

@BuildStep(onlyIf = IsDevelopment.class)
JsonRPCProvidersBuildItem createJsonRPCServiceForCache() {
return new JsonRPCProvidersBuildItem("Caches", CacheJsonRPCService.class);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
import { LitElement, html, css} from 'lit';
import { JsonRpc } from 'jsonrpc';
import '@vaadin/icon';
import '@vaadin/button';
import '@vaadin/text-field';
import '@vaadin/text-area';
import '@vaadin/form-layout';
import '@vaadin/progress-bar';
import '@vaadin/checkbox';
import { until } from 'lit/directives/until.js';
import '@vaadin/grid';
import { columnBodyRenderer } from '@vaadin/grid/lit.js';
import '@vaadin/grid/vaadin-grid-sort-column.js';

export class CacheComponent extends LitElement {

jsonRpc = new JsonRpc("Caches");

// Component style
static styles = css`
.button {
background-color: transparent;
cursor: pointer;
}
.clearIcon {
color: orange;
}
`;

// Component properties
static properties = {
"_caches": {state: true}
}

// Components callbacks

/**
* Called when displayed
*/
connectedCallback() {
super.connectedCallback();
this.jsonRpc.getAll().then(jsonRpcResponse => {
this._caches = new Map();
jsonRpcResponse.result.forEach(c => {
this._caches.set(c.name, c);
});
});
}

/**
* Called when it needs to render the components
* @returns {*}
*/
render() {
return html`${until(this._renderCacheTable(), html`<span>Loading caches...</span>`)}`;
}

// View / Templates

_renderCacheTable() {
if (this._caches) {
let caches = [...this._caches.values()];
return html`
<vaadin-grid .items="${caches}" class="datatable" theme="no-border">
<vaadin-grid-column auto-width
header="Name"
${columnBodyRenderer(this._nameRenderer, [])}>
</vaadin-grid-column>
<vaadin-grid-column auto-width
header="Size"
path="size">
</vaadin-grid-column>
<vaadin-grid-column auto-width
header=""
${columnBodyRenderer(this._actionRenderer, [])}
resizable>
</vaadin-grid-column>
</vaadin-grid>`;
}
}

_actionRenderer(cache) {
return html`
<vaadin-button theme="small" @click=${() => this._clear(cache.name)} class="button">
<vaadin-icon class="clearIcon" icon="font-awesome-solid:broom"></vaadin-icon> Clear
</vaadin-button>`;
}

_nameRenderer(cache) {
return html`
<vaadin-button theme="small" @click=${() => this._refresh(cache.name)} class="button">
<vaadin-icon icon="font-awesome-solid:rotate"></vaadin-icon>
</vaadin-button>
${cache.name}`;
}

_clear(name) {
this.jsonRpc.clear({name: name}).then(jsonRpcResponse => {
this._updateCache(jsonRpcResponse.result)
});
}

_refresh(name) {
this.jsonRpc.refresh({name: name}).then(jsonRpcResponse => {
this._updateCache(jsonRpcResponse.result)
});
}

_updateCache(cache){
if (this._caches.has(cache.name) && cache.size !== -1) {
this._caches.set(cache.name, cache);
this.requestUpdate();
}
}

}
customElements.define('cache-component', CacheComponent);
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package io.quarkus.cache.runtime.devconsole;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
import java.util.List;
import java.util.Optional;

import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;

import org.jboss.logging.Logger;

import io.quarkus.cache.Cache;
import io.quarkus.cache.CacheManager;
import io.quarkus.cache.CaffeineCache;
import io.quarkus.cache.runtime.caffeine.CaffeineCacheImpl;
import io.vertx.core.json.JsonArray;
import io.vertx.core.json.JsonObject;

@ApplicationScoped
public class CacheJsonRPCService {

@Inject
CacheManager manager;

@Inject
Logger logger;

public JsonArray getAll() {
Collection<String> names = manager.getCacheNames();
List<CaffeineCache> allCaches = new ArrayList<>(names.size());
for (String name : names) {
Optional<Cache> cache = manager.getCache(name);
if (cache.isPresent() && cache.get() instanceof CaffeineCache) {
allCaches.add((CaffeineCache) cache.get());
}
}
allCaches.sort(Comparator.comparing(CaffeineCache::getName));

var array = new JsonArray();
for (CaffeineCache cc : allCaches) {
array.add(getJsonRepresentationForCache(cc));
}
return array;
}

private static JsonObject getJsonRepresentationForCache(Cache cc) {
return new JsonObject().put("name", cc.getName()).put("size", ((CaffeineCacheImpl) cc).getSize());
}

public JsonObject clear(String name) {
Optional<Cache> cache = manager.getCache(name);
if (cache.isPresent()) {
cache.get().invalidateAll().subscribe().asCompletionStage()
.thenAccept(x -> logger.infof("Cache %s cleared", name));
return getJsonRepresentationForCache(cache.get());
} else {
return new JsonObject().put("name", name).put("size", -1);
}
}

public JsonObject refresh(String name) {
Optional<Cache> cache = manager.getCache(name);
if (cache.isPresent()) {
return getJsonRepresentationForCache(cache.get());
} else {
return new JsonObject().put("name", name).put("size", -1);
}
}

}

0 comments on commit e0e36e8

Please sign in to comment.