Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@

@Singleton
@AutoBind(interfaces = {EntityDataDefaultsStore.class, AppLifeCycle.class})
@SuppressWarnings("PMD.TooManyMethods")
public class EntityDataDefaultsStoreImpl extends AbstractMergeableKeyValueStore<Map<String, Object>>
implements EntityDataDefaultsStore, AppLifeCycle {

Expand All @@ -87,6 +88,7 @@ public EntityDataDefaultsStoreImpl(
Jackson jackson,
Substitutions substitutions,
Lazy<Set<EntityFactory>> entityFactories) {
super();
StoreConfiguration store = appContext.getConfiguration().getStore();
this.entityFactories = new EntityFactoriesImpl(entityFactories);
this.eventStore = eventStore;
Expand Down Expand Up @@ -152,7 +154,7 @@ public boolean has(Predicate<Identifier> keyMatcher) {

@Override
public Map<String, Object> get(Identifier identifier) {
return null;
return new LinkedHashMap<>();
}
}));

Expand Down Expand Up @@ -290,7 +292,7 @@ public Map<String, Object> subtractDefaults(
data, defaults, factory.getIgnoreKeys(), factory.getListEntryKeys());

} catch (Throwable e) {
boolean br = true;
// ignore
}

return data;
Expand Down Expand Up @@ -346,7 +348,7 @@ public Optional<Map<String, Object>> getAllDefaults(
return Optional.ofNullable(defaults);

} catch (Throwable e) {
boolean br = true;
// ignore
}
}

Expand Down Expand Up @@ -375,7 +377,7 @@ private Map<String, Object> getDefaults(Identifier identifier) {

return deserialize;
} catch (IOException e) {
throw new RuntimeException(e);
throw new IllegalStateException("Error deserializing defaults", e);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@
*/
@Singleton
@AutoBind(interfaces = {EntityDataStore.class, AppLifeCycle.class})
@SuppressWarnings({"PMD.GodClass", "PMD.TooManyMethods"})
public class EntityDataStoreImpl extends AbstractMergeableKeyValueStore<EntityData>
implements EntityDataStore<EntityData>, AppLifeCycle {

Expand Down Expand Up @@ -125,6 +126,7 @@ public EntityDataStoreImpl(
ResourceStore blobStore,
ValueStore valueStore,
boolean noDefaults) {
super();
StoreConfiguration store = appContext.getConfiguration().getStore();
this.isEventStoreReadOnly = eventStore.isReadOnly();
this.entityFactories = new EntityFactoriesImpl(entityFactories);
Expand Down Expand Up @@ -184,7 +186,7 @@ public boolean has(Predicate<Identifier> keyMatcher) {

@Override
public Map<String, Object> get(Identifier identifier) {
return null;
return new LinkedHashMap<>();
}
}));
}
Expand Down Expand Up @@ -229,33 +231,42 @@ protected Map<String, Object> modifyPatch(Map<String, Object> partialData) {
}

// TODO: onEmit middleware
@SuppressWarnings({
"PMD.CyclomaticComplexity",
"PMD.NPathComplexity",
"PMD.CognitiveComplexity",
"PMD.CollapsibleIfStatements"
})
private List<ReplayEvent> processEvent(ReplayEvent event) {

if (valueEncoding.isEmpty(event.payload()) || !valueEncoding.isSupported(event.format())) {
return List.of();
}

if (!event.isDelete()
&& event.type().equals(EntityDataStore.EVENT_TYPE_ENTITIES)
&& EntityDataStore.EVENT_TYPE_ENTITIES.equals(event.type())
&& eventSourcing.has(isDuplicate(event.identifier()))) {
LOGGER.warn(
"Ignoring entity '{}' from {} because it already exists. An entity can only exist in a single group.",
event.asPathNoType(),
event.source().orElse("UNKNOWN"));
if (LOGGER.isWarnEnabled()) {
LOGGER.warn(
"Ignoring entity '{}' from {} because it already exists. An entity can only exist in a single group.",
event.asPathNoType(),
event.source().orElse("UNKNOWN"));
}
return List.of();
}

if (!event.isDelete()
&& event.type().equals(EntityDataStore.EVENT_TYPE_ENTITIES)
&& EntityDataStore.EVENT_TYPE_ENTITIES.equals(event.type())
&& eventSourcing.has(event.identifier())) {
LOGGER.warn(
"Ignoring entity '{}' from {} because it already exists. An entity can only exist in a single source, use overrides to update it from another source.",
event.asPathNoType(),
event.source().orElse("UNKNOWN"));
return List.of();
if (LOGGER.isWarnEnabled()) {
LOGGER.warn(
"Ignoring entity '{}' from {} because it already exists. An entity can only exist in a single source, use overrides to update it from another source.",
event.asPathNoType(),
event.source().orElse("UNKNOWN"));
}
}

if (!event.type().equals(EntityDataStore.EVENT_TYPE_OVERRIDES)) {
if (!EntityDataStore.EVENT_TYPE_OVERRIDES.equals(event.type())) {
return List.of(event);
}

Expand All @@ -266,8 +277,10 @@ private List<ReplayEvent> processEvent(ReplayEvent event) {

// override without matching entity
if (!eventSourcing.has(cacheKey)) {
LOGGER.warn("Ignoring override '{}', no matching entity found", event.asPath());
return List.of();
if (LOGGER.isWarnEnabled()) {
LOGGER.warn("Ignoring override '{}', no matching entity found", event.asPath());
return List.of();
}
}

ImmutableReplayEvent.Builder builder =
Expand Down Expand Up @@ -484,10 +497,8 @@ protected CompletableFuture<Void> onCreate(Identifier identifier, EntityData ent
.createInstance(hydratedData)
.whenComplete(
(entity, throwable) -> {
if (Objects.nonNull(entity)) {
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Entity created: {}", identifier);
}
if (Objects.nonNull(entity) && LOGGER.isTraceEnabled()) {
LOGGER.trace("Entity created: {}", identifier);
}
})
.thenAccept(ignore -> CompletableFuture.completedFuture(null));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,9 @@
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

// TODO:
public class EntityDeserialization {
private static final Logger LOGGER = LoggerFactory.getLogger(EntityDeserialization.class);

public static final Module DESERIALIZE_MERGEABLE_MAP_BUILDER_WRAPPER =
new SimpleModule()
Expand Down Expand Up @@ -75,6 +72,7 @@ public JsonDeserializer<?> modifyDeserializer(

public static class ImmutableBuilderMapWrapperDeserializer extends BeanDeserializer {

private static final long serialVersionUID = 1L;
private final String wrappedPropertyName;

ImmutableBuilderMapWrapperDeserializer(
Expand All @@ -83,7 +81,16 @@ public static class ImmutableBuilderMapWrapperDeserializer extends BeanDeseriali
this.wrappedPropertyName = wrappedPropertyName;
}

private List<SettableBeanProperty> remapBeanProperties(
BeanDeserializer unwrapping, SettableBeanProperty mapProp, String wrappedPropertyName) {
Iterable<SettableBeanProperty> iterable = unwrapping::properties;
return StreamSupport.stream(iterable.spliterator(), false)
.map(prop -> prop == mapProp ? mapProp.withSimpleName(wrappedPropertyName) : prop)
.collect(Collectors.toList());
}

@Override
@SuppressWarnings("PMD.AvoidDeeplyNestedIfStmts")
public void resolve(DeserializationContext ctxt) throws JsonMappingException {
super.resolve(ctxt);

Expand All @@ -97,20 +104,13 @@ public void resolve(DeserializationContext ctxt) throws JsonMappingException {

JsonDeserializer<Object> orig = prop.getValueDeserializer();
JsonDeserializer<Object> unwrapping = orig.unwrappingDeserializer(xform);
if (unwrapping != orig && unwrapping != null && unwrapping instanceof BeanDeserializer) {
if (!Objects.equals(unwrapping, orig)
&& unwrapping != null
&& unwrapping instanceof BeanDeserializer) {
SettableBeanProperty mapProp = ((BeanDeserializer) unwrapping).findProperty("map");
if (mapProp != null) {
Iterable<SettableBeanProperty> iterable = ((BeanDeserializer) unwrapping)::properties;
List<SettableBeanProperty> beanProperties =
StreamSupport.stream(iterable.spliterator(), false)
.map(
settableBeanProperty -> {
if (settableBeanProperty == mapProp) {
return mapProp.withSimpleName(wrappedPropertyName);
}
return settableBeanProperty;
})
.collect(Collectors.toList());
remapBeanProperties((BeanDeserializer) unwrapping, mapProp, wrappedPropertyName);
BeanPropertyMap beanPropertyMap =
new BeanPropertyMap(
false, beanProperties, Collections.<String, List<PropertyName>>emptyMap());
Expand All @@ -121,6 +121,10 @@ public void resolve(DeserializationContext ctxt) throws JsonMappingException {
_unwrappedPropertyHandler.addProperty(prop);
_beanProperties.remove(prop);
}

prop = prop.withValueDeserializer(unwrapping);
_unwrappedPropertyHandler.addProperty(prop);
_beanProperties.remove(prop);
}
}
}
Expand All @@ -139,7 +143,8 @@ public Version version() {
}

@Override
public void setupModule(com.fasterxml.jackson.databind.Module.SetupContext context) {
@SuppressWarnings({"PMD.CognitiveComplexity", "PMD.CloseResource"})
public void setupModule(Module.SetupContext context) {
context.addDeserializationProblemHandler(
new DeserializationProblemHandler() {
@Override
Expand All @@ -157,8 +162,6 @@ public JavaType handleMissingTypeId(

JsonLocation currentLocation = p.getCurrentLocation();
byte[] sourceRef = (byte[]) currentLocation.getSourceRef();
long line = currentLocation.getLineNr();
long column = currentLocation.getColumnNr();

JsonParser parser2 = p.getCodec().getFactory().createParser(sourceRef);
parser2.nextToken();
Expand All @@ -184,6 +187,8 @@ public JavaType handleMissingTypeId(

long currentLine = parser2.getCurrentLocation().getLineNr();
long currentColumn = parser2.getCurrentLocation().getColumnNr();
long line = currentLocation.getLineNr();
long column = currentLocation.getColumnNr();

String lastExtensionType = null;

Expand All @@ -192,9 +197,8 @@ public JavaType handleMissingTypeId(
for (;
currentToken != JsonToken.END_OBJECT;
currentToken = parser2.nextToken()) {
if (currentToken == JsonToken.FIELD_NAME
&& parser2.getCurrentName().equals("extensionType")) {
currentToken = parser2.nextToken();
if (JsonToken.FIELD_NAME == currentToken
&& "extensionType".equals(parser2.getCurrentName())) {
lastExtensionType = parser2.getValueAsString();
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ public <T extends PersistentEntity> List<T> getEntitiesForType(Class<T> type) {
.flatMap(entityFactory -> entityFactory.instances().stream())
.filter(
persistentEntity ->
(async && ((EntityState) persistentEntity).getEntityState() != STATE.DISABLED)
async && ((EntityState) persistentEntity).getEntityState() != STATE.DISABLED
|| ((EntityState) persistentEntity).isActive())
.map(type::cast)
.collect(ImmutableList.toImmutableList());
Expand All @@ -62,7 +62,7 @@ public <T extends PersistentEntity> Optional<T> getEntity(Class<T> type, String
.map(Optional::get)
.filter(
persistentEntity ->
(async && ((EntityState) persistentEntity).getEntityState() != STATE.DISABLED)
async && ((EntityState) persistentEntity).getEntityState() != STATE.DISABLED
|| ((EntityState) persistentEntity).isActive())
.map(type::cast)
.findFirst();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
import org.slf4j.LoggerFactory;

// TODO: should this really be a facade for EventStore? or can we make it plain ValueCache?
@SuppressWarnings({"PMD.GodClass", "PMD.CogntitiveComplexity", "PMD.CyclomaticComplexity"})
public class EventSourcing<T> implements EventStoreSubscriber, ValueCache<T> {

private static final Logger LOGGER = LoggerFactory.getLogger(EventSourcing.class);
Expand Down Expand Up @@ -128,6 +129,7 @@ public List<String> getEventTypes() {
}

@Override
@SuppressWarnings("PMD.CognitiveComplexity")
public void onEmit(Event event) {
if (event instanceof EntityEvent) {
EntityEvent entityEvent = (EntityEvent) event;
Expand All @@ -139,9 +141,8 @@ public void onEmit(Event event) {
} else if (mutationEventProcessor.isPresent() && event instanceof MutationEvent) {
CompletableFuture<T> completableFuture = null;
// TODO
if (queue.containsKey(entityEvent.identifier())
&& entityEvent.type().equals("defaults")
&& entityEvent.identifier().id().equals("services.ogc_api")) {
if ("defaults".equals(entityEvent.type())
&& "services.ogc_api".equals(entityEvent.identifier().id())) {
completableFuture = queue.get(entityEvent.identifier());
queue.remove(entityEvent.identifier());
}
Expand All @@ -155,10 +156,8 @@ public void onEmit(Event event) {
} else {
onEmit(entityEvent);
}
} catch (Throwable e) {
if (e instanceof NoSuchElementException
&& Objects.nonNull(e.getMessage())
&& e.getMessage().contains("providers/feature/")) {
} catch (NoSuchElementException e) {
if (Objects.nonNull(e.getMessage()) && e.getMessage().contains("providers/feature/")) {
LOGGER.error(
"Cannot load '{}', feature provider type not supported: {}",
entityEvent.asPath(),
Expand All @@ -168,20 +167,32 @@ public void onEmit(Event event) {
} else {
LogContext.error(LOGGER, e, "Cannot load '{}'", entityEvent.asPath());
}
} catch (Throwable e) {
LogContext.error(LOGGER, e, "Cannot load '{}'", entityEvent.asPath());
}

} else if (event instanceof StateChangeEvent) {
switch (((StateChangeEvent) event).state()) {
StateChangeEvent stateChangeEvent = (StateChangeEvent) event;
switch (stateChangeEvent.state()) {
case REPLAYING:
LOGGER.debug("Loading {}", ((StateChangeEvent) event).type());
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Loading {}", stateChangeEvent.type());
}
break;
case LISTENING:
started.add(((StateChangeEvent) event).type());

started.add(stateChangeEvent.type());
if (started.containsAll(getEventTypes())) {
onStart.get().thenRun(() -> LOGGER.debug("Loaded {}", String.join(" and ", started)));
onStart
.get()
.thenRun(
() -> {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Loaded {}", String.join(" and ", started));
}
});
}
break;
default:
break;
}
} else if (event instanceof ReloadEvent) {
Optional<BiFunction<Identifier, T, CompletableFuture<Void>>> hook =
Expand Down Expand Up @@ -273,6 +284,7 @@ private CompletableFuture<T> pushMutationEventRaw(
return completableFuture;
}

@SuppressWarnings({"PMD.CognitiveComplexity", "PMD.NPathComplexity"})
private void onEmit(EntityEvent event) throws Throwable {
Identifier key = event.identifier();
FORMAT payloadFormat = FORMAT.fromString(event.format());
Expand Down
Loading