Ver código fonte

more efficient fetching of all configs. add sql search views to configs

tags/2.0.1
Jonathan Cobb 4 anos atrás
pai
commit
f81510c184
2 arquivos alterados com 53 adições e 16 exclusões
  1. +4
    -0
      wizard-common/src/main/java/org/cobbzilla/wizard/model/entityconfig/EntityConfig.java
  2. +49
    -16
      wizard-server/src/main/java/org/cobbzilla/wizard/resources/AbstractEntityConfigsResource.java

+ 4
- 0
wizard-common/src/main/java/org/cobbzilla/wizard/model/entityconfig/EntityConfig.java Ver arquivo

@@ -8,6 +8,7 @@ import org.cobbzilla.util.reflect.ReflectionUtil;
import org.cobbzilla.util.string.HasLocale;
import org.cobbzilla.util.string.StringUtil;
import org.cobbzilla.wizard.model.entityconfig.annotations.*;
import org.cobbzilla.wizard.model.search.SqlViewField;
import org.cobbzilla.wizard.validation.ValidationResult;
import org.cobbzilla.wizard.validation.Validator;
import org.springframework.core.type.filter.AnnotationTypeFilter;
@@ -146,6 +147,9 @@ public class EntityConfig {
@Setter private List<String> searchFields;
public List<String> getSearchFields() { return !empty(searchFields) ? searchFields : fieldNamesWithAnnotation(getClassName(), ECSearchable.class); }

// AbstractEntityConfigsResource populates this, if the entity supports SQL queries
@Getter @Setter private SqlViewField[] sqlViewFields;

/** The HTTP method to use when deleting an entity. Default value: `DELETE` */
@Getter @Setter private String deleteMethod = "DELETE";
@Setter private String deleteUri;


+ 49
- 16
wizard-server/src/main/java/org/cobbzilla/wizard/resources/AbstractEntityConfigsResource.java Ver arquivo

@@ -2,15 +2,21 @@ package org.cobbzilla.wizard.resources;

import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.experimental.Accessors;
import lombok.extern.slf4j.Slf4j;
import org.cobbzilla.util.cache.AutoRefreshingReference;
import org.cobbzilla.util.string.StringUtil;
import org.cobbzilla.wizard.dao.AbstractCRUDDAO;
import org.cobbzilla.wizard.dao.DAO;
import org.cobbzilla.wizard.model.Identifiable;
import org.cobbzilla.wizard.model.entityconfig.EntityConfig;
import org.cobbzilla.wizard.model.entityconfig.EntityConfigSource;
import org.cobbzilla.wizard.model.entityconfig.EntityFieldConfig;
import org.cobbzilla.wizard.model.entityconfig.annotations.ECType;
import org.cobbzilla.wizard.server.config.HasDatabaseConfiguration;
import org.cobbzilla.wizard.model.search.SqlViewSearchResult;
import org.cobbzilla.wizard.server.config.PgRestServerConfiguration;
import org.cobbzilla.wizard.util.ClasspathScanner;
import org.glassfish.jersey.server.ContainerRequest;
import org.springframework.core.type.filter.AnnotationTypeFilter;
@@ -20,15 +26,12 @@ import javax.ws.rs.core.Context;
import javax.ws.rs.core.Response;
import java.io.File;
import java.io.InputStream;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;

import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
import static org.apache.commons.lang3.StringUtils.capitalize;
import static org.cobbzilla.util.io.StreamUtil.loadResourceAsStream;
import static org.cobbzilla.util.json.JsonUtil.FULL_MAPPER_ALLOW_COMMENTS;
import static org.cobbzilla.util.json.JsonUtil.fromJson;
@@ -43,7 +46,7 @@ public abstract class AbstractEntityConfigsResource implements EntityConfigSourc

public static final String ENTITY_CONFIG_BASE = "entity-config";

protected abstract HasDatabaseConfiguration getConfiguration();
protected abstract PgRestServerConfiguration getConfiguration();

protected long getConfigRefreshInterval() { return TimeUnit.DAYS.toMillis(30); }
protected abstract boolean authorized(ContainerRequest ctx);
@@ -51,7 +54,7 @@ public abstract class AbstractEntityConfigsResource implements EntityConfigSourc

public static final AtomicReference<Map<String, EntityConfig>> lastConfig = new AtomicReference<>();

@Getter(AccessLevel.PROTECTED) private final AutoRefreshingReference<Map<String, EntityConfig>> configs = new EntityConfigsMap();
@Getter(AccessLevel.PROTECTED) private final EntityConfigsMap configs = new EntityConfigsMap();
public boolean refresh() { return refresh(configs); }
public boolean refresh(AutoRefreshingReference<Map<String, EntityConfig>> configsToReset) {
configsToReset.flush();
@@ -59,9 +62,10 @@ public abstract class AbstractEntityConfigsResource implements EntityConfigSourc
}

@GET
public Response getConfigNames (@Context ContainerRequest ctx) {
public Response getConfigs(@Context ContainerRequest ctx,
@QueryParam("full") Boolean full) {
if (!authorized(ctx)) return forbidden();
return ok(getConfigs().get().keySet());
return ok(full != null && full ? getConfigs().getEntries() : getConfigs().get().keySet());
}

@Override public EntityConfig getEntityConfig(Object thing) {
@@ -70,7 +74,7 @@ public abstract class AbstractEntityConfigsResource implements EntityConfigSourc
synchronized (configMap) {
Class<?> clazz = thing instanceof Class ? (Class<?>) thing : thing.getClass();
do {
final EntityConfig entityConfig = configMap.get(clazz.getName());
final EntityConfig entityConfig = configMap.get(clazz.getName().toLowerCase());
if (entityConfig != null) return entityConfig;
clazz = clazz.getSuperclass();
} while (!clazz.equals(Object.class));
@@ -95,7 +99,7 @@ public abstract class AbstractEntityConfigsResource implements EntityConfigSourc

final EntityConfig config;
synchronized (configMap) {
config = configMap.get(capitalize(name));
config = configMap.get(name.toLowerCase());
}

if (debug && config != null) {
@@ -113,7 +117,10 @@ public abstract class AbstractEntityConfigsResource implements EntityConfigSourc

public class EntityConfigsMap extends AutoRefreshingReference<Map<String, EntityConfig>> {

@Getter private List<EntityConfigsEntry> entries = new ArrayList<>();

@Override public Map<String, EntityConfig> refresh() {
entries = new ArrayList<>();
final Map<String, EntityConfig> configMap = new HashMap<>();
final HashSet<Class<?>> classesWithoutConfigs = new HashSet<>();

@@ -126,11 +133,18 @@ public abstract class AbstractEntityConfigsResource implements EntityConfigSourc

final EntityConfig config = toEntityConfig(clazz);
if (config != null) {
configMap.put(clazz.getName(), config);
if (configMap.containsKey(clazz.getSimpleName())) {
log.warn("config already contains "+clazz.getSimpleName()+", not overwriting with "+clazz.getName());
final String lcClass = clazz.getName().toLowerCase();
final String lcSimpleClass = clazz.getSimpleName().toLowerCase();
final EntityConfigsEntry entry = new EntityConfigsEntry(config)
.addName(lcClass)
.addName(clazz.getSimpleName().toLowerCase());
entries.add(entry);

configMap.put(lcClass, config);
if (configMap.containsKey(lcSimpleClass)) {
log.warn("config already contains "+lcSimpleClass+", not overwriting with "+clazz.getName());
} else {
configMap.put(clazz.getSimpleName(), config);
configMap.put(lcSimpleClass, config);
}
} else {
classesWithoutConfigs.add(clazz);
@@ -167,7 +181,16 @@ public abstract class AbstractEntityConfigsResource implements EntityConfigSourc
entityConfig.setClassName(clazz.getName());

try {
return entityConfig.updateWithAnnotations(clazz, root);
final DAO dao = getConfiguration().getDaoForEntityClass(clazz);
final EntityConfig updated = entityConfig.updateWithAnnotations(clazz, root);

// add SQL search fields, if the entity supports them
if (SqlViewSearchResult.class.isAssignableFrom(clazz) && dao instanceof AbstractCRUDDAO) {
updated.setSqlViewFields(((AbstractCRUDDAO) dao).getSearchFields());
}

return updated;

} catch (Exception e) {
log.warn("getEntityConfig(" + clazz.getName() + "): Exception while reading entity cfg annotations", e);
return null;
@@ -213,4 +236,14 @@ public abstract class AbstractEntityConfigsResource implements EntityConfigSourc
}
}
}

@NoArgsConstructor @Accessors(chain=true)
public static class EntityConfigsEntry {
@Getter @Setter private Set<String> names = new LinkedHashSet<>();
@Getter @Setter private EntityConfig entityConfig;

public EntityConfigsEntry(EntityConfig config) { this.entityConfig = config; }

public EntityConfigsEntry addName(String n) { this.names.add(n); return this; }
}
}

Carregando…
Cancelar
Salvar