//
// Licensed 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.
//
Unomi is architected so that users can provided extensions in the form of plugins.

=== Types vs. instances

Several extension points in Unomi rely on the concept of type: the extension defines a prototype for what the actual
items will be once parameterized with values known only at runtime. This is similar to the concept of classes in
object-oriented programming: types define classes, providing the expected structure and which fields are expected to
be provided at runtime, that are then instantiated when needed with actual values.

=== Plugin structure

Being built on top of Apache Karaf, Unomi leverages OSGi to support plugins. A Unomi plugin is, thus, an OSGi
bundle specifying some specific metadata to tell Unomi the kind of entities it provides. A plugin can provide the
following entities to extend Unomi, each with its associated definition (as a JSON file), located in a specific spot
within the `META-INF/cxs/` directory of the bundle JAR file:

|====
|Entity |Location in `cxs` directory 

|ActionType |actions 
|ConditionType |conditions 
|Persona |personas 
|PropertyMergeStrategyType |mergers 
|PropertyType |properties then profiles or sessions subdirectory then `&lt;category name&gt;` directory 
|Rule |rules 
|Scoring |scorings 
|Segment |segments 
|ValueType |values 
|====

http://aries.apache.org/modules/blueprint.html[Blueprint] is used to declare what the plugin provides and inject
any required dependency. The Blueprint file is located, as usual, at `OSGI-INF/blueprint/blueprint.xml` in the bundle JAR file.

The plugin otherwise follows a regular maven project layout and should depend on the Unomi API maven artifact:

[source,xml]
----
<dependency>
    <groupId>org.apache.unomi</groupId>
    <artifactId>unomi-api</artifactId>
    <version>...</version>
</dependency>
----

Some plugins consists only of JSON definitions that are used to instantiate the appropriate structures at runtime
while some more involved plugins provide code that extends Unomi in deeper ways.

In both cases, plugins can provide more that one type of extension. For example, a plugin could provide both `ActionType`s and `ConditionType`s.

=== Extension points

==== ActionType

`ActionType`s define new actions that can be used as consequences of Rules being triggered. When a rule triggers, it creates new actions based on the event data and the rule internal processes, providing values for parameters defined in the associated `ActionType`. Example actions include: “Set user property x to value y” or “Send a message to service x”.

==== ConditionType

`ConditionType`s define new conditions that can be applied to items (for example to decide whether a rule needs to be triggered or if a profile is considered as taking part in a campaign) or to perform queries against the stored Unomi data. They may be implemented in Java when attempting to define a particularly complex test or one that can better be optimized by coding it. They may also be defined as combination of other conditions. A simple condition could be: “User is male”, while a more generic condition with parameters may test whether a given property has a specific value: “User property x has value y”.

==== Persona

A persona is a "virtual" profile used to represent categories of profiles, and may also be used to test how a personalized experience would look like using this virtual profile. A persona can define predefined properties and sessions. Persona definition make it possible to “emulate” a certain type of profile, e.g : US visitor, non-US visitor, etc.

==== PropertyMergeStrategyType

A strategy to resolve how to merge properties when merging profile together.

==== PropertyType

Definition for a profile or session property, specifying how possible values are constrained, if the value is multi-valued (a vector of values as opposed to a scalar value). `PropertyType`s can also be categorized using systemTags or file system structure, using sub-directories to organize definition files.

==== Rule

`Rule`s are conditional sets of actions to be executed in response to incoming events. Triggering of rules is guarded by a condition: the rule is only triggered if the associated condition is satisfied. That condition can test the event itself, but also the profile or the session. Once a rule triggers, a list of actions can be performed as consequences. Also, when rules trigger, a specific event is raised so that other parts of Unomi can react accordingly.

==== Scoring

`Scoring`s are set of conditions associated with a value to assign to profiles when matching so that the associated users can be scored along that dimension. Each scoring element is evaluated and matching profiles' scores are incremented with the associated value.

==== Segments

`Segment`s represent dynamically evaluated groups of similar profiles in order to categorize the associated users. To be considered part of a given segment, users must satisfies the segment’s condition. If they match, users are automatically added to the segment. Similarly, if at any given point during, they cease to satisfy the segment’s condition, they are automatically removed from it.

==== Tag

`Tag`s are simple labels that are used to classify all other objects inside Unomi. 

==== ValueType

Definition for values that can be assigned to properties ("primitive" types).

=== Other Unomi entities

==== UserList

User list are simple static lists of users. The associated profile stores the lists it belongs to in a specific property.

==== Goal

Goals represent tracked activities / actions that can be accomplished by site (or more precisely scope) visitors. These are tracked in general because they relate to specific business objectives or are relevant to measure site/scope performance.

Goals can be defined at the scope level or in the context of a particular `Campaign`. Either types of goals behave exactly the same way with the exception of two notable differences:
 - duration: scope-level goals are considered until removed while campaign-level goals are only considered for the campaign duration
 - audience filtering: any visitor is considered for scope-level goals while campaign-level goals only consider visitors who match the campaign's conditions

==== Campaign

A goal-oriented, time-limited marketing operation that needs to be evaluated for return on investment performance by tracking the ratio of visits to conversions.