//
// 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.
//
=== Notifications

Apache Syncope can be instructed to send out notification e-mails when certain <<notification-events,events>> occur.

Every notification generates one or more <<tasks-notification,notification tasks>>, holding the actual
e-mails to be sent. The tasks are ordinarily scheduled for execution according to the value provided for
`notificationjob.cronExpression` - see <<configuration-parameters, below>> for details - and can be saved for later
re-execution.

When defining a notification, the following information must be provided:

* <<notification-templates,notification template>> - template for e-mail generation
* sender - e-mail address appearing in the `From` field of the generated e-mail(s)
* subject - text used as e-mail subject
* recipient e-mail attribute - which user attribute shall be considered as e-mail address for delivery (as users might
in principle have different e-mail attributes)
* recipient(s) - the actual e-mail recipient(s) which can be specified either as:
** list of static e-mail addresses
** matching condition to be applied to available users
** Java class implementing the
ifeval::["{snapshotOrRelease}" == "release"]
https://github.com/apache/syncope/blob/syncope-{docVersion}/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/notification/RecipientsProvider.java[RecipientsProvider^]
endif::[]
ifeval::["{snapshotOrRelease}" == "snapshot"]
https://github.com/apache/syncope/blob/4_0_X/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/notification/RecipientsProvider.java[RecipientsProvider^]
endif::[]
interface
* <<notification-events,notification event(s)>> - event(s) triggering the enclosing notification
* about - the condition matching Users, Groups or Any Objects which are evaluated for the specified events; for users,
the matching entities can be also considered as additional recipients
* trace level - control how much tracing (including logs and execution details) shall be carried over during execution
of the generated <<tasks-notification,notification tasks>>

==== Notification Events

Notification (and <<audit-events,Audit>>) events are essentially a means of identifying the invocation of specific methods
within the <<core>>, in line with _join points_ in the
https://en.wikipedia.org/wiki/Aspect-oriented_programming[Aspect Oriented Programming (AOP)^].

An event is identified by the following five coordinates:

. type - which can be one of
** `LOGIC`
** `TASK`
** `PROPAGATION`
** `PULL`
** `PUSH`
** `CUSTOM`
. category - the possible values depend on the selected type: for `LOGIC` the <<logic>> components available,
for `TASK` the various <<tasks-scheduled, Scheduled Tasks>> configured, for `PROPAGATION`, `PULL` and `PUSH` the defined Any Types
. subcategory - completes category with external resource name, when selecting `PROPAGATION`, `PULL` or `PUSH`
. event type - the final identification of the event; depends on the other coordinates
. success or failure - whether the current event shall be considered in case of success or failure

The admin console provides <<console-configuration-notifications,tooling>> to assist with the specification of valid events. 

[TIP]
====
An event is uniquely identified by a string of the following form:

[source]
----
[type]:[category]:[subcategory]:[event type]:[SUCCESS|FAILURE]
----

Some samples:

* `[PUSH]:[GROUP]:[resource-db-scripted]:[matchingrule_deprovision]:[SUCCESS]` +
successful Group <<provisioning-push,push>> to the external resource `resource-db-scripted`, when deprovisioning
matching entities
* `[LOGIC]:[RealmLogic]:[]:[create]:[FAILURE]` +
unsuccessful Realm creation
* `[CUSTOM]:[]:[]:[unexpected identification]:[SUCCESS]` +
successful execution of the event identified by the `unexpected identification` string
====

[NOTE]
====
Custom events can be used to trigger notifications from non-predefined joint points, as BPMN `userTask`
instances within the <<flowable-user-workflow-adapter>>, <<propagationactions>>, <<pushactions>>, <<inboundactions>> or
other custom code.
====

==== Notification Templates

A notification template is defined as a pair of http://commons.apache.org/proper/commons-jexl/[JEXL^] expressions,
to be used respectively for plaintext and HTML e-mails, and is available for selection in the notification specification.

[NOTE]
====
Notification templates can be easily managed via the <<console-configuration-notifications,admin console>>.
====

The full power of JEXL expressions - see http://commons.apache.org/proper/commons-jexl/reference/syntax.html[reference^]
and http://commons.apache.org/proper/commons-jexl/reference/examples.html[some examples^] - is available. +
For example, the `user` variable, an instance of 
ifeval::["{snapshotOrRelease}" == "release"]
https://github.com/apache/syncope/blob/syncope-{docVersion}/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/UserTO.java[UserTO^]
endif::[]
ifeval::["{snapshotOrRelease}" == "snapshot"]
https://github.com/apache/syncope/blob/4_0_X/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/UserTO.java[UserTO^]
endif::[]
with actual value matching the _about_ condition as introduced above, can be used.

.Plaintext notification template
====
[source]
----
Hi ${user.getPlainAttr("firstname").get().values[0]} ${user.getPlainAttr("surname").get().values[0]},
  welcome to Syncope!

Your username is ${user.username}.
Your email address is ${user.getPlainAttr("email").get().values[0]}.

Best regards.
----
====

.HTML notification template
====
[source,html]
----
<html>
  <body>
    <h3>Hi ${user.getPlainAttr("firstname").get().values[0]} ${user.getPlainAttr("surname").get().values[0]},
      welcome to Syncope!</h3>
    <p>Your username is ${user.username}.<br/>
    Your email address is ${user.getPlainAttr("email").get().values[0]}.</p>
    <p>Best regards.</p>
  </body>
</html>
----
====
