Skip to content

Commit 1f8b579

Browse files
committed
CAUSEWAY-3982: extend auditing to only log on updates, not create or
delete (forwardport from v2 to v4)
1 parent cda70da commit 1f8b579

File tree

16 files changed

+325
-289
lines changed

16 files changed

+325
-289
lines changed

api/applib/src/main/java/org/apache/causeway/applib/annotation/Publishing.java

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,8 @@ public enum Publishing {
4545
* Publishing of data triggered by interaction with this object
4646
* should be handled as per the default publishing policy
4747
* configured in <tt>application.properties</tt>.
48-
* <p>
49-
* If no publishing policy is configured, then publishing is disabled.
48+
*
49+
* <p>If no publishing policy is configured, then publishing is disabled.
5050
*/
5151
AS_CONFIGURED,
5252

@@ -55,6 +55,23 @@ public enum Publishing {
5555
*/
5656
ENABLED,
5757

58+
/**
59+
* Applies only to {@link EntityPropertyChangeSubscriber}, whereby events are published for modifications to the
60+
* object, but no events are published for the initial creation of an object.
61+
*
62+
* <p>In the case of audit trail extension,
63+
* this effectively suppresses all of the "[NEW] -> value" entries that are created for every property of the
64+
* entity when it is being created, and also all of the "value -> [DELETED]" entries that are created for every property of the
65+
* entity when it is being deleted.
66+
*
67+
* <p>This variant is intended only where the application code has enough traceability built into the domain
68+
* (perhaps to provide visibility to the end-users) that the technical auditing is overkill. It will also
69+
* of course reduce the volume of auditing, so improves performance (likely both response times and throughput).
70+
*
71+
* <p>For other subscribers, behaviour is the same as {@link #ENABLED}.
72+
*/
73+
ENABLED_FOR_UPDATES_ONLY,
74+
5875
/**
5976
* Do <b>not</b> publish data triggered by interaction with this object
6077
* (even if otherwise configured to enable publishing).

core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/members/publish/command/CommandPublishingFacetForActionAnnotation.java

Lines changed: 24 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -62,40 +62,33 @@ public static Optional<CommandPublishingFacet> create(
6262
var publishingPolicy = ActionConfigOptions.actionCommandPublishingPolicy(configuration);
6363

6464
return actionsIfAny
65-
.filter(action -> action.commandPublishing() != Publishing.NOT_SPECIFIED)
66-
.map(action -> {
67-
Publishing publishing = action.commandPublishing();
65+
.filter(action -> action.commandPublishing() != Publishing.NOT_SPECIFIED)
66+
.map(action -> {
67+
Publishing publishing = action.commandPublishing();
6868

69-
final Class<? extends CommandDtoProcessor> processorClass = action.commandDtoProcessor();
70-
final CommandDtoProcessor processor = newProcessorElseNull(processorClass);
69+
final Class<? extends CommandDtoProcessor> processorClass = action.commandDtoProcessor();
70+
final CommandDtoProcessor processor = newProcessorElseNull(processorClass);
7171

72-
if(processor != null) {
73-
publishing = Publishing.ENABLED;
74-
}
72+
if(processor != null) {
73+
publishing = Publishing.ENABLED;
74+
}
7575

76-
switch (publishing) {
77-
case AS_CONFIGURED:
78-
switch (publishingPolicy) {
79-
case NONE:
80-
return new CommandPublishingFacetForActionAnnotationAsConfigured.None(holder, servicesInjector);
81-
case IGNORE_QUERY_ONLY:
82-
case IGNORE_SAFE:
83-
return Facets.hasSafeSemantics(holder)
84-
? new CommandPublishingFacetForActionAnnotationAsConfigured.IgnoreSafe(holder, servicesInjector)
85-
: new CommandPublishingFacetForActionAnnotationAsConfigured.IgnoreSafeYetNot(holder, servicesInjector);
86-
case ALL:
87-
return new CommandPublishingFacetForActionAnnotationAsConfigured.All(holder, servicesInjector);
88-
default:
89-
throw new IllegalStateException(String.format("configured action.commandPublishing policy '%s' not recognised", publishingPolicy));
90-
}
91-
case DISABLED:
92-
return new CommandPublishingFacetForActionAnnotation.Disabled(processor, holder, servicesInjector);
93-
case ENABLED:
94-
return new CommandPublishingFacetForActionAnnotation.Enabled(processor, holder, servicesInjector);
95-
default:
96-
throw new IllegalStateException(String.format("@Action#commandPublishing '%s' not recognised", publishing));
97-
}
98-
});
76+
return switch (publishing) {
77+
case AS_CONFIGURED -> switch (publishingPolicy) {
78+
case NONE -> new CommandPublishingFacetForActionAnnotationAsConfigured.None(holder, servicesInjector);
79+
case IGNORE_QUERY_ONLY, IGNORE_SAFE -> Facets.hasSafeSemantics(holder)
80+
? new CommandPublishingFacetForActionAnnotationAsConfigured.IgnoreSafe(holder, servicesInjector)
81+
: new CommandPublishingFacetForActionAnnotationAsConfigured.IgnoreSafeYetNot(holder, servicesInjector);
82+
case ALL -> new CommandPublishingFacetForActionAnnotationAsConfigured.All(holder, servicesInjector);
83+
default -> throw new IllegalStateException(
84+
String.format("configured action.commandPublishing policy '%s' not recognised", publishingPolicy));
85+
};
86+
case DISABLED -> new CommandPublishingFacetForActionAnnotation.Disabled(processor, holder, servicesInjector);
87+
case ENABLED, ENABLED_FOR_UPDATES_ONLY -> new CommandPublishingFacetForActionAnnotation.Enabled(processor, holder, servicesInjector);
88+
default -> throw new IllegalStateException(
89+
String.format("@Action#commandPublishing '%s' not recognised", publishing));
90+
};
91+
});
9992
}
10093

10194
CommandPublishingFacetForActionAnnotation(

core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/members/publish/command/CommandPublishingFacetForPropertyAnnotation.java

Lines changed: 35 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ public static CommandPublishingFacet create(
6868

6969
return propertyIfAny
7070
.filter(property -> property.commandPublishing() != Publishing.NOT_SPECIFIED)
71-
.map(property -> {
71+
.<CommandPublishingFacet>map(property -> {
7272
Publishing publishing = property.commandPublishing();
7373

7474
var processorClass = property.commandDtoProcessor();
@@ -78,64 +78,54 @@ public static CommandPublishingFacet create(
7878
publishing = Publishing.ENABLED;
7979
}
8080

81-
switch (publishing) {
82-
case AS_CONFIGURED:
83-
switch (publishingPolicy) {
84-
case NONE:
85-
return (CommandPublishingFacet)new CommandPublishingFacetForPropertyAnnotationAsConfigured.None(holder, servicesInjector);
86-
case ALL:
87-
return new CommandPublishingFacetForPropertyAnnotationAsConfigured.All(holder, servicesInjector);
88-
default:
89-
throw new IllegalStateException(String.format("configured property.commandpublishing policy '%s' not recognised", publishingPolicy));
90-
}
91-
case DISABLED:
92-
return new CommandPublishingFacetForPropertyAnnotation.Disabled(processor, holder, servicesInjector);
93-
case ENABLED:
94-
return new CommandPublishingFacetForPropertyAnnotation.Enabled(processor, holder, servicesInjector);
95-
default:
96-
throw new IllegalStateException(String.format("@Property#commandPublishing '%s' not recognised", publishing));
97-
}
81+
return switch (publishing) {
82+
case AS_CONFIGURED -> switch (publishingPolicy) {
83+
case NONE -> new CommandPublishingFacetForPropertyAnnotationAsConfigured.None(holder, servicesInjector);
84+
case ALL -> new CommandPublishingFacetForPropertyAnnotationAsConfigured.All(holder, servicesInjector);
85+
default -> throw new IllegalStateException(
86+
String.format("configured property.commandpublishing policy '%s' not recognised", publishingPolicy));
87+
};
88+
case DISABLED -> new CommandPublishingFacetForPropertyAnnotation.Disabled(processor, holder, servicesInjector);
89+
case ENABLED, ENABLED_FOR_UPDATES_ONLY -> new CommandPublishingFacetForPropertyAnnotation.Enabled(processor, holder, servicesInjector);
90+
default -> throw new IllegalStateException(
91+
String.format("@Property#commandPublishing '%s' not recognised", publishing));
92+
};
9893
})
9994
.orElseGet(() -> {
10095
// there is no publishing facet from either @Action or @Property, so use the appropriate configuration to install a default
101-
if (representsProperty(holder)) {
96+
if (representsProperty(holder))
10297
// we are dealing with a property
103-
switch (publishingPolicy) {
104-
case NONE:
105-
return new CommandPublishingFacetForPropertyFromConfiguration.None(holder, servicesInjector);
106-
case ALL:
107-
return new CommandPublishingFacetForPropertyFromConfiguration.All(holder, servicesInjector);
108-
default:
109-
throw new IllegalStateException(String.format("configured property.commandPublishing policy '%s' not recognised", publishingPolicy));
110-
}
111-
} else {
98+
return switch (publishingPolicy) {
99+
case NONE -> new CommandPublishingFacetForPropertyFromConfiguration.None(holder, servicesInjector);
100+
case ALL -> new CommandPublishingFacetForPropertyFromConfiguration.All(holder, servicesInjector);
101+
default -> throw new IllegalStateException(String.format("configured property.commandPublishing policy '%s' not recognised", publishingPolicy));
102+
};
103+
else {
112104
// we are dealing with an action
113105
var actionPublishingPolicy = ActionConfigOptions.actionCommandPublishingPolicy(configuration);
114-
switch (actionPublishingPolicy) {
115-
case NONE:
116-
return new CommandPublishingFacetForActionFromConfiguration.None(holder, servicesInjector);
117-
case IGNORE_QUERY_ONLY:
118-
case IGNORE_SAFE:
119-
return Facets.hasSafeSemantics(holder)
120-
? new CommandPublishingFacetForActionFromConfiguration.IgnoreSafe(holder, servicesInjector)
121-
: new CommandPublishingFacetForActionFromConfiguration.IgnoreSafeYetNot(holder, servicesInjector);
122-
case ALL:
123-
return new CommandPublishingFacetForActionFromConfiguration.All(holder, servicesInjector);
124-
default:
125-
throw new IllegalStateException(String.format("configured action.commandPublishing policy '%s' not recognised", actionPublishingPolicy));
126-
}
106+
return switch (actionPublishingPolicy) {
107+
case NONE -> new CommandPublishingFacetForActionFromConfiguration.None(holder, servicesInjector);
108+
case IGNORE_QUERY_ONLY, IGNORE_SAFE -> Facets.hasSafeSemantics(holder)
109+
? new CommandPublishingFacetForActionFromConfiguration.IgnoreSafe(holder, servicesInjector)
110+
: new CommandPublishingFacetForActionFromConfiguration.IgnoreSafeYetNot(holder, servicesInjector);
111+
case ALL -> new CommandPublishingFacetForActionFromConfiguration.All(holder, servicesInjector);
112+
default -> throw new IllegalStateException(String.format("configured action.commandPublishing policy '%s' not recognised", actionPublishingPolicy));
113+
};
127114
}
128115
});
116+
129117
}
130118

131119
private static boolean representsProperty(final FacetHolder holder) {
132120
// a property
133-
if (holder instanceof TypedFacetHolder && ((TypedFacetHolder)holder).featureType() == FeatureType.PROPERTY) {
121+
if (holder instanceof TypedFacetHolder typedFacetHolder
122+
&& typedFacetHolder.featureType() == FeatureType.PROPERTY)
134123
return true;
135-
}
136124
// or a mixin
137-
return holder.containsFacet(ContributingFacet.class) &&
138-
holder.getFacet(ContributingFacet.class).contributed() == MixinFacet.Contributing.AS_PROPERTY;
125+
return holder.lookupFacet(ContributingFacet.class)
126+
.map(ContributingFacet::contributed)
127+
.map(MixinFacet.Contributing.AS_PROPERTY::equals)
128+
.orElse(false);
139129
}
140130

141131
CommandPublishingFacetForPropertyAnnotation(

core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/members/publish/execution/ExecutionPublishingFacetForActionAnnotation.java

Lines changed: 18 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -58,34 +58,24 @@ public static Optional<ExecutionPublishingFacet> create(
5858

5959
var publishingPolicy = ActionConfigOptions.actionExecutionPublishingPolicy(configuration);
6060

61-
return
62-
actionsIfAny
63-
.filter(action -> action.executionPublishing() != Publishing.NOT_SPECIFIED)
64-
.map(Action::executionPublishing)
65-
.<ExecutionPublishingFacet>map(publishing -> {
66-
switch (publishing) {
67-
case AS_CONFIGURED:
68-
switch (publishingPolicy) {
69-
case NONE:
70-
return new ExecutionPublishingFacetForActionAnnotationAsConfigured.None(holder);
71-
case IGNORE_QUERY_ONLY:
72-
case IGNORE_SAFE:
73-
return Facets.hasSafeSemantics(holder)
74-
? new ExecutionPublishingFacetForActionAnnotationAsConfigured.IgnoreSafe(holder)
75-
: new ExecutionPublishingFacetForActionAnnotationAsConfigured.IgnoreSafeYetNot(holder);
76-
case ALL:
77-
return new ExecutionPublishingFacetForActionAnnotationAsConfigured.All(holder);
78-
default:
79-
throw new IllegalStateException(String.format("configured action.executionPublishing policy '%s' not recognised", publishingPolicy));
80-
}
81-
case DISABLED:
82-
return new ExecutionPublishingFacetForActionAnnotation.Disabled(holder);
83-
case ENABLED:
84-
return new ExecutionPublishingFacetForActionAnnotation.Enabled(holder);
85-
default:
86-
throw new IllegalStateException(String.format("@Action#executionPublishing '%s' not recognised", publishing));
87-
}
88-
});
61+
return actionsIfAny
62+
.filter(action -> action.executionPublishing() != Publishing.NOT_SPECIFIED)
63+
.map(Action::executionPublishing)
64+
.<ExecutionPublishingFacet>map(publishing -> (switch (publishing) {
65+
case AS_CONFIGURED -> switch (publishingPolicy) {
66+
case NONE -> new ExecutionPublishingFacetForActionAnnotationAsConfigured.None(holder);
67+
case IGNORE_QUERY_ONLY, IGNORE_SAFE -> Facets.hasSafeSemantics(holder)
68+
? new ExecutionPublishingFacetForActionAnnotationAsConfigured.IgnoreSafe(holder)
69+
: new ExecutionPublishingFacetForActionAnnotationAsConfigured.IgnoreSafeYetNot(holder);
70+
case ALL -> new ExecutionPublishingFacetForActionAnnotationAsConfigured.All(holder);
71+
default -> throw new IllegalStateException(
72+
String.format("configured action.executionPublishing policy '%s' not recognised", publishingPolicy));
73+
};
74+
case DISABLED -> new ExecutionPublishingFacetForActionAnnotation.Disabled(holder);
75+
case ENABLED, ENABLED_FOR_UPDATES_ONLY -> new ExecutionPublishingFacetForActionAnnotation.Enabled(holder);
76+
default -> throw new IllegalStateException(
77+
String.format("@Action#executionPublishing '%s' not recognised", publishing));
78+
}));
8979
}
9080

9181
ExecutionPublishingFacetForActionAnnotation(final FacetHolder holder) {

0 commit comments

Comments
 (0)