Skip to content

Commit

Permalink
Update Hibernate Search dev console card for multi-persistence-unit a…
Browse files Browse the repository at this point in the history
…pplications
  • Loading branch information
mun711 committed May 23, 2022
1 parent f2dc9a6 commit 1b3550f
Show file tree
Hide file tree
Showing 8 changed files with 165 additions and 60 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package io.quarkus.hibernate.orm.runtime;

import java.util.Comparator;
import java.util.Locale;

import javax.enterprise.inject.Default;
Expand Down Expand Up @@ -37,6 +38,19 @@ public static <T> InjectableInstance<T> extensionInstanceForPersistenceUnit(Clas
new PersistenceUnitExtension.Literal(persistenceUnitName));
}

public static class PersistenceUnitNameComparator implements Comparator<String> {
@Override
public int compare(String o1, String o2) {
if (DEFAULT_PERSISTENCE_UNIT_NAME.equals(o1)) {
return -1;
} else if (DEFAULT_PERSISTENCE_UNIT_NAME.equals(o2)) {
return +1;
} else {
return o1.compareTo(o2);
}
}
}

@Deprecated
public static <T> InjectableInstance<T> legacySingleExtensionInstanceForPersistenceUnit(Class<T> beanType,
String persistenceUnitName) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.EnumSet;
import java.util.List;
import java.util.Map;
Expand All @@ -24,9 +23,9 @@
import org.hibernate.tool.schema.spi.ScriptTargetOutput;
import org.hibernate.tool.schema.spi.TargetDescriptor;

public class HibernateOrmDevConsoleInfoSupplier implements Supplier<HibernateOrmDevConsoleInfoSupplier.PersistenceUnitsInfo> {
import io.quarkus.hibernate.orm.runtime.PersistenceUnitUtil;

private static final String DEFAULT = "<default>";
public class HibernateOrmDevConsoleInfoSupplier implements Supplier<HibernateOrmDevConsoleInfoSupplier.PersistenceUnitsInfo> {

public static final PersistenceUnitsInfo INSTANCE = new PersistenceUnitsInfo();

Expand Down Expand Up @@ -99,7 +98,7 @@ public PersistenceUnitsInfo get() {
public static class PersistenceUnitsInfo {

private final Map<String, PersistenceUnitInfo> persistenceUnits = Collections
.synchronizedMap(new TreeMap<>(new PersistenceUnitNameComparator()));
.synchronizedMap(new TreeMap<>(new PersistenceUnitUtil.PersistenceUnitNameComparator()));

public Collection<PersistenceUnitInfo> getPersistenceUnits() {
return persistenceUnits.values();
Expand Down Expand Up @@ -229,17 +228,4 @@ public String getType() {
}

}

static class PersistenceUnitNameComparator implements Comparator<String> {
@Override
public int compare(String o1, String o2) {
if (DEFAULT.equals(o1)) {
return -1;
} else if (DEFAULT.equals(o2)) {
return +1;
} else {
return o1.compareTo(o2);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@

import org.junit.jupiter.api.Test;

import io.quarkus.hibernate.orm.runtime.PersistenceUnitUtil;

public class PersistenceUnitNameComparatorTestCase {

@Test
Expand All @@ -16,7 +18,7 @@ public void puNameComparatorTest() {
names.add("alpha");
names.add("<default>");
names.add("beta");
names.sort(new HibernateOrmDevConsoleInfoSupplier.PersistenceUnitNameComparator());
names.sort(new PersistenceUnitUtil.PersistenceUnitNameComparator());

assertThat(names.get(0)).isEqualTo("<default>");
assertThat(names.get(1)).isEqualTo("alpha");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,17 @@
import static io.quarkus.deployment.annotations.ExecutionTime.RUNTIME_INIT;
import static io.quarkus.deployment.annotations.ExecutionTime.STATIC_INIT;

import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

import io.quarkus.deployment.IsDevelopment;
import io.quarkus.deployment.annotations.BuildStep;
import io.quarkus.deployment.annotations.Record;
import io.quarkus.deployment.pkg.builditem.CurateOutcomeBuildItem;
import io.quarkus.devconsole.spi.DevConsoleRouteBuildItem;
import io.quarkus.devconsole.spi.DevConsoleRuntimeTemplateInfoBuildItem;
import io.quarkus.hibernate.search.orm.elasticsearch.HibernateSearchElasticsearchPersistenceUnitConfiguredBuildItem;
import io.quarkus.hibernate.search.orm.elasticsearch.runtime.HibernateSearchElasticsearchRuntimeConfig;
import io.quarkus.hibernate.search.orm.elasticsearch.runtime.devconsole.HibernateSearchDevConsoleRecorder;

Expand All @@ -18,9 +23,13 @@ public class HibernateSearchElasticsearchDevConsoleProcessor {
@Record(RUNTIME_INIT)
public DevConsoleRuntimeTemplateInfoBuildItem collectBeanInfo(HibernateSearchDevConsoleRecorder recorder,
HibernateSearchElasticsearchRuntimeConfig runtimeConfig,
CurateOutcomeBuildItem curateOutcomeBuildItem) {
return new DevConsoleRuntimeTemplateInfoBuildItem("indexedEntityTypes",
recorder.infoSupplier(runtimeConfig), this.getClass(), curateOutcomeBuildItem);
CurateOutcomeBuildItem curateOutcomeBuildItem,
List<HibernateSearchElasticsearchPersistenceUnitConfiguredBuildItem> peristenceUnitBuildItems) {
Set<String> persistenceUnitNames = peristenceUnitBuildItems.stream()
.map(HibernateSearchElasticsearchPersistenceUnitConfiguredBuildItem::getPersistenceUnitName)
.collect(Collectors.toSet());
return new DevConsoleRuntimeTemplateInfoBuildItem("indexedPersistenceUnits",
recorder.infoSupplier(runtimeConfig, persistenceUnitNames), this.getClass(), curateOutcomeBuildItem);
}

@BuildStep
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
<a href="{urlbase}/entity-types" class="badge badge-light">
<i class="fa fa-boxes fa-fw"></i>
Persistence units <span class="badge badge-light">{info:indexedPersistenceUnits.persistenceUnits.size}</span></a>
<a href="{urlbase}/entity-types" class="badge badge-light">
<i class="fa fa-search fa-fw"></i>
Indexed entity types <span class="badge badge-light">{info:indexedEntityTypes.size()}</span></a>
Indexed Entities <span class="badge badge-light">{info:indexedPersistenceUnits.numberOfIndexedEntities}</span></a>
<br>
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
{#include main}
{#title}Indexed Entities{/title}
{#body}
{#if info:indexedEntityTypes.isEmpty}
{#if info:indexedPersistenceUnits.persistenceUnits.isEmpty}
<p>No indexed entities were found.</p>
{#else}
<form method="post" enctype="application/x-www-form-urlencoded">
<input id="index" type="submit" class="btn btn-primary mb-2" value="Reindex Entities" >
<input id="index" type="submit" class="btn btn-primary mb-2" value="Reindex Entities">
<br/>
{#for indexedPersistenceUnit in info:indexedPersistenceUnits.persistenceUnits}
<h4><span class="badge">Persistence Unit</span> <i class="badge badge-info">{indexedPersistenceUnit.persistenceUnitName}</i></h4>
<table id="table" class="table table-striped">
<colgroup>
<col span="1" style="width: 5%;">
Expand All @@ -16,19 +19,20 @@
<tr>
<th scope="col">
<div class="custom-control">
<input type="checkbox" class="form-check-input" id="check-all">
<input type="checkbox" class="form-check-input" onChange="handleSelectAll(this)">
</div>
</th>
<th scope="col">Entity name</th>
<th scope="col">Entity type</th>
</tr>
</thead>
<tbody>
{#for indexedEntityType in info:indexedEntityTypes}
{#for indexedEntityType in indexedPersistenceUnit.indexedEntities}
<tr>
<td>
<div class="custom-control">
<input type="checkbox" class="form-check-input checkbox" name="{indexedEntityType.jpaName}" id="{indexedEntityType.jpaName}">
<input type="checkbox" class="form-check-input checkbox" name="{indexedEntityType.jpaName}"
id="{indexedEntityType.jpaName}" value="{indexedPersistenceUnit.persistenceUnitName}">
</div>
</td>
<td>{indexedEntityType.jpaName}</td>
Expand All @@ -37,15 +41,13 @@
{/for}
</tbody>
</table>
{/for}
</form>
<script type="text/javascript">
jQuery('#check-all').change(function() {
if (this.checked) {
jQuery('.checkbox').prop('checked', true);
} else {
jQuery('.checkbox').prop('checked', false);
}
});
function handleSelectAll(elem) {
$(elem).parents('table:first').find('.checkbox').prop('checked', elem.checked);
}

</script>
{/if}
{/body}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import java.time.Duration;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Supplier;
import java.util.stream.Collectors;

Expand All @@ -19,9 +21,9 @@
@Recorder
public class HibernateSearchDevConsoleRecorder {

public Supplier<List<HibernateSearchSupplier.DevUiIndexedEntity>> infoSupplier(
HibernateSearchElasticsearchRuntimeConfig runtimeConfig) {
return new HibernateSearchSupplier(runtimeConfig);
public Supplier<HibernateSearchSupplier.IndexedPersistenceUnits> infoSupplier(
HibernateSearchElasticsearchRuntimeConfig runtimeConfig, Set<String> persistenceUnitNames) {
return new HibernateSearchSupplier(runtimeConfig, persistenceUnitNames);
}

public Handler<RoutingContext> indexEntity() {
Expand All @@ -31,19 +33,25 @@ protected void handlePostAsync(RoutingContext event, MultiMap form) throws Excep
if (form.isEmpty()) {
return;
}
SearchMapping mapping = HibernateSearchSupplier.searchMapping();
if (mapping == null) {
Set<String> persitenceUnitNames = form.entries().stream().map(Map.Entry::getValue)
.collect(Collectors.toSet());
Map<String, SearchMapping> mappings = HibernateSearchSupplier.searchMapping(persitenceUnitNames);
if (mappings.isEmpty()) {
flashMessage(event, "There are no indexed entity types.", FlashScopeUtil.FlashMessageStatus.ERROR);
return;
}
mapping.scope(Object.class,
mapping.allIndexedEntities().stream()
.map(SearchIndexedEntity::jpaName)
.filter(form::contains)
.collect(Collectors.toList()))
.massIndexer()
.startAndWait();
flashMessage(event, "Entities successfully reindexed", Duration.ofSeconds(10));
for (Map.Entry<String, SearchMapping> entry : mappings.entrySet()) {
SearchMapping mapping = entry.getValue();
List<String> entityNames = mapping.allIndexedEntities().stream()
.map(SearchIndexedEntity::jpaName)
.filter(jpaName -> form.contains(jpaName, entry.getKey(), false))
.collect(Collectors.toList());
if (!entityNames.isEmpty()) {
mapping.scope(Object.class, entityNames).massIndexer()
.startAndWait();
flashMessage(event, "Entities successfully reindexed", Duration.ofSeconds(10));
}
}
}
};
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,44 +1,125 @@
package io.quarkus.hibernate.search.orm.elasticsearch.runtime.devconsole;

import java.util.Collections;
import java.lang.annotation.Annotation;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import java.util.function.Supplier;
import java.util.stream.Collector;
import java.util.stream.Collectors;

import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.search.mapper.orm.entity.SearchIndexedEntity;
import org.hibernate.search.mapper.orm.mapping.SearchMapping;

import io.quarkus.arc.Arc;
import io.quarkus.hibernate.orm.PersistenceUnit;
import io.quarkus.hibernate.orm.runtime.PersistenceUnitUtil;
import io.quarkus.hibernate.search.orm.elasticsearch.runtime.HibernateSearchElasticsearchRuntimeConfig;
import io.quarkus.hibernate.search.orm.elasticsearch.runtime.devconsole.HibernateSearchSupplier.DevUiIndexedEntity;

public class HibernateSearchSupplier implements Supplier<List<DevUiIndexedEntity>> {
public class HibernateSearchSupplier implements Supplier<HibernateSearchSupplier.IndexedPersistenceUnits> {

private final HibernateSearchElasticsearchRuntimeConfig runtimeConfig;
private final Set<String> persistenceUnitNames;

HibernateSearchSupplier(HibernateSearchElasticsearchRuntimeConfig runtimeConfig) {
HibernateSearchSupplier(HibernateSearchElasticsearchRuntimeConfig runtimeConfig, Set<String> persistenceUnitNames) {
this.runtimeConfig = runtimeConfig;
this.persistenceUnitNames = persistenceUnitNames;
}

@Override
public List<DevUiIndexedEntity> get() {
public IndexedPersistenceUnits get() {
if (!isEnabled()) {
return Collections.emptyList();
return new IndexedPersistenceUnits();
}
SearchMapping mapping = searchMapping();
if (mapping == null) {
return Collections.emptyList();
Map<String, SearchMapping> mappings = searchMapping(persistenceUnitNames);
if (mappings.isEmpty()) {
return new IndexedPersistenceUnits();
}
return mapping.allIndexedEntities().stream().map(DevUiIndexedEntity::new).sorted()
.collect(Collectors.toList());
return mappings.entrySet().stream()
.map(mapping -> new IndexedPersistenceUnit(mapping.getKey(),
mapping.getValue().allIndexedEntities().stream().map(DevUiIndexedEntity::new).sorted()
.collect(Collectors.toList())))
.collect(Collector.of(IndexedPersistenceUnits::new, IndexedPersistenceUnits::add,
(left, right) -> {
left.addAll(right);
return left;
}));
}

private boolean isEnabled() {
return runtimeConfig.defaultPersistenceUnit.enabled;
}

public static SearchMapping searchMapping() {
return Arc.container().instance(SearchMapping.class).get();
public static Map<String, SearchMapping> searchMapping(Set<String> persistenceUnitNames) {
return Arrays.stream(getPersistenceUnitQualifiers(persistenceUnitNames)).map(
qualifier -> Arc.container().select(SearchMapping.class, qualifier).get())
.collect(Collectors.toMap(HibernateSearchSupplier::getPersistenceUnitName, mapping -> mapping));
}

private static Annotation[] getPersistenceUnitQualifiers(Set<String> persistenceUnitNames) {
return persistenceUnitNames.stream().map(PersistenceUnit.PersistenceUnitLiteral::new).toArray(Annotation[]::new);
}

private static String getPersistenceUnitName(SearchMapping searchMapping) {
SessionFactoryImplementor sessionFactory = searchMapping.toOrmSessionFactory().unwrap(SessionFactoryImplementor.class);
String name = sessionFactory.getName();
if (name != null) {
return name;
}
Object persistenceUnitName = sessionFactory.getProperties().get("hibernate.ejb.persistenceUnitName");
if (persistenceUnitName != null) {
return persistenceUnitName.toString();
}
return PersistenceUnitUtil.DEFAULT_PERSISTENCE_UNIT_NAME;
}

static class IndexedPersistenceUnits {
private final Set<IndexedPersistenceUnit> persistenceUnits = new TreeSet<>(new PersistenceUnitComparator());

public Set<IndexedPersistenceUnit> getPersistenceUnits() {
return persistenceUnits;
}

public void add(IndexedPersistenceUnit indexedPersistenceUnit) {
persistenceUnits.add(indexedPersistenceUnit);
}

public void addAll(IndexedPersistenceUnits right) {
persistenceUnits.addAll(right.persistenceUnits);
}

public int getNumberOfIndexedEntities() {
return persistenceUnits.stream().mapToInt(pu -> pu.indexedEntities.size()).sum();
}
}

static class PersistenceUnitComparator implements Comparator<IndexedPersistenceUnit> {
Comparator<String> persistenceUnitNameComparator = new PersistenceUnitUtil.PersistenceUnitNameComparator();

@Override
public int compare(IndexedPersistenceUnit o1, IndexedPersistenceUnit o2) {
return persistenceUnitNameComparator.compare(o1.persistenceUnitName, o2.persistenceUnitName);
}
}

static class IndexedPersistenceUnit implements Comparable<IndexedPersistenceUnit> {
public final String persistenceUnitName;

public final List<DevUiIndexedEntity> indexedEntities;

public IndexedPersistenceUnit(String persistenceUnitName, List<DevUiIndexedEntity> indexedEntities) {
this.persistenceUnitName = persistenceUnitName;
this.indexedEntities = indexedEntities;
}

@Override
public int compareTo(IndexedPersistenceUnit o) {
return this.persistenceUnitName.compareTo(o.persistenceUnitName);
}
}

public static class DevUiIndexedEntity implements Comparable<DevUiIndexedEntity> {
Expand Down

0 comments on commit 1b3550f

Please sign in to comment.