:Notice: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at. http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR  CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

WARNING: TODO: was renamed/moved from auditing+publishing to entityChangePublishing

The `entityChangePublishing` element for a domain object means that all registered implementation(s) of the (internal) xref:refguide:core:index/metamodel/services/publishing/ExecutionPublisher.adoc[ExecutionPublisher]

link:https://causeway.apache.org/refguide/2.0.0-M3/applib-svc/PublisherService.html#spi[`PublisherService` SPI] will be notified of the identity and nature of the change (created/updated/deleted) to the domain object.

:examples/demo/domain/src/main/java/demoapp/dom/annotDomain/DomainObject/publishing/DomainObjectPublishingVm-description.adoc
This is done _after_ the interaction in which the object(s) was changed has completed.

This notification is done only once per interaction, so will include _all_ domain objects that were changed.
The event object can be converted to type xref:https://causeway.apache.org/refguide/2.0.0-M3/schema/chg.html[ChangesDto].

Common use cases are to replicate data to another system, or for gathering metrics ("which objects change the most?").
A typical SPI implementation could publish the event over the network, or perhaps store in a database.
(Note that the framework provides an link:https://causeway.apache.org/mappings/2.0.0-M3/outbox-publisher/about.html[out-of-the-box implementation] of the link:https://microservices.io/patterns/data/transactional-outbox.html[outbox pattern]).

The element can be specified using either the `@DomainObject` annotation, or through a meta-annotation.

NOTE: Publishing of domain objects is only supported for domain entities, not view models.


== Explanation of the Demo

The demo provides a view model which can be used to create, update or delete four variations of a domain entity:

* annotated using `@DomainObject(entityChangePublishing=...)` for both enabled and disabled
* meta-annotated as enabled
* meta-annotated as disabled, but then overridden

These can be updated using the view model's `create`, `update all` and `delete` actions, generating publishing events.

TIP: Click through to the entity objects to see examples of the annotations applied.


//
// to fix up
//
//== ExecutionSubscriber
//
//The demo also has a simple implementation of `ExecutionSubscriber` that just stores the DTOs in memory:
//
//[source,java]
//----
//include::spiimpl/PublisherServiceSpiForDomainObject.java[tags=class]
//----
//<.> serializes to `ChangesDto`, as defined by the link:https://causeway.apache.org/refguide/2.0.0-M3/schema/chg.html[Apache Causeway schema].
//
//The demo implementation also provides a way to query these executions:
//
//[source,java,indent=0]
//----
//include::spiimpl/PublisherServiceSpiForDomainObject.java[tags=demo]
//----
//
//Supporting mixins surface this list as contributions on the object:
//
//* `publishedObjects` collection:
//+
//[source,java,indent=0]
//----
//include::spiimpl/DomainObjectPublishingVm_publishedObjects.java[tags=class]
//----
//
//* `clearPublishedObjects` action:
//+
//[source,java,indent=0]
//----
//include::spiimpl/DomainObjectPublishingVm_clearPublishedObjects.java[tags=class]
//----
//
//
//For the three (of the four in total) domain entities where publishing is enabled, this collection should be appended to when the `create`, `update all` or `delete` actions are invoked.
//
//[NOTE]
//====
//Because the `Publisher` is notified after the interaction has completed, it's necessary to refresh the page to see the collection of changes being updated.
//
//This can be done simply by clicking on the view model's title.
//====


== Configuration

By default, publishing of domain objects is disabled.
This can be configured globally:

[source,yaml]
.application.yml
----
causeway:
  applib:
    annotation:
      domain-object:
        entityChangePublishing: none
----

