Skip to content
Merged
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
4 changes: 2 additions & 2 deletions generate-manual-config.sh
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ LATEST_BRANCH="master"
LATEST_VERSION="3.1.0-SNAPSHOT"
LATEST_DIR="latest"

# Stable version (release branch)
# Stable version (release branch)
STABLE_BRANCH="unomi-3.0.x"
STABLE_VERSION="3.0.0"
STABLE_DIR="3_0_x"
Expand Down Expand Up @@ -82,7 +82,7 @@ PROJECT_STAGING_DIR="target/staging"
# === TIMEOUTS ===
# Command timeouts in seconds
MAVEN_TIMEOUT=1800 # 30 minutes
GIT_TIMEOUT=300 # 5 minutes
GIT_TIMEOUT=300 # 5 minutes
SVN_TIMEOUT=600 # 10 minutes

# Export all configuration variables
Expand Down
1 change: 0 additions & 1 deletion manual/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,6 @@
<plugin>
<groupId>net.nicoulaj.maven.plugins</groupId>
<artifactId>checksum-maven-plugin</artifactId>
<version>1.7</version>
<executions>
<execution>
<id>package-release-checksum</id>
Expand Down
50 changes: 44 additions & 6 deletions manual/src/main/asciidoc/5-min-quickstart.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
// limitations under the License.
//

[[_five_minutes_quickstart]]
=== Quick start with Docker

Begin by creating a `docker-compose.yml` file. You can choose between ElasticSearch or OpenSearch:
Expand All @@ -30,7 +31,7 @@ services:
- 9200:9200
unomi:
# Unomi version can be updated based on your needs
image: apache/unomi:3.0.0
image: apache/unomi:3.1.0
environment:
- UNOMI_ELASTICSEARCH_ADDRESSES=elasticsearch:9200
- UNOMI_THIRDPARTY_PROVIDER1_IPADDRESSES=0.0.0.0/0,::1,127.0.0.1
Expand Down Expand Up @@ -73,7 +74,7 @@ services:
- 9600:9600

unomi:
image: apache/unomi:3.0.0
image: apache/unomi:3.1.0
environment:
- UNOMI_DISTRIBUTION=unomi-distribution-opensearch
- UNOMI_OPENSEARCH_ADDRESSES=opensearch-node1:9200
Expand All @@ -99,7 +100,7 @@ Try accessing https://localhost:9443/cxs/cluster with username/password: karaf/k

==== Option 1: Using ElasticSearch

1) Install JDK 17 and make sure you set the JAVA_HOME variable (see our <<JDK compatibility,Getting Started>> guide for more information on JDK compatibility)
1) Install JDK 17 and make sure you set the JAVA_HOME variable (see our <<_jdk_compatibility,Getting Started>> guide for more information on JDK compatibility)

2) Download ElasticSearch here : https://www.elastic.co/downloads/past-releases/elasticsearch-9-2-1 (please *make sure* you use the proper version : 9.2.1)

Expand Down Expand Up @@ -148,14 +149,51 @@ which determines which set of features and bundles are installed and started. A

9) Try accessing https://localhost:9443/cxs/cluster with username/password: `karaf/karaf` . You might get a certificate warning in your browser, just accept it despite the warning it is safe.

10) Request your first context by simply accessing : http://localhost:8181/cxs/context.js?sessionId=1234
10) Create a tenant that will own all your data:

11) If something goes wrong, you should check the logs in `./data/log/karaf.log`. If you get errors on the search engine,
[source,bash]
----
curl -X POST http://localhost:8181/cxs/tenants \
--user karaf:karaf \
-H "Content-Type: application/json" \
-d '{
"requestedId": "default",
"properties": {
"name": "Default Tenant",
"description": "Default tenant for quick start"
}
}'
----

Save the API keys from the response - you'll need them for API calls.

11) Request your first context:

[source,bash]
----
curl -X POST http://localhost:8181/cxs/context.json?sessionId=1234 \
-H "Content-Type: application/json" \
-H "X-Unomi-Api-Key: <YOUR_PUBLIC_API_KEY>" \
-d '{
"source": {
"itemId": "homepage",
"itemType": "page",
"scope": "default"
}
}'
----

Or access it directly in a browser (requires API key in header):
`http://localhost:8181/cxs/context.js?sessionId=1234`

NOTE: For the context request to work, you'll need to include the public API key from step 10 in the request header: `X-Unomi-Api-Key: <YOUR_PUBLIC_API_KEY>`

12) If something goes wrong, you should check the logs in `./data/log/karaf.log`. If you get errors on the search engine,
make sure you are using the proper version.

Next steps:

- Trying our integration <<Samples,samples page>>
- Trying our integration <<_samples,samples page>>

Note: When using OpenSearch, make sure to:
- Set up proper SSL certificates or disable SSL verification for development
Expand Down
246 changes: 246 additions & 0 deletions manual/src/main/asciidoc/architecture.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,246 @@
//
// 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.
//

=== High-Level Architecture

[plantuml]
----
@startuml
!include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Component.puml

LAYOUT_WITH_LEGEND()

title Apache Unomi - High Level Architecture

Container(webApp, "Web Application", "JavaScript", "Client application using context.js")
Container(mobileApp, "Mobile App", "Native/Hybrid", "Client using REST API")

Container_Boundary(unomi, "Apache Unomi") {
Component(restApi, "REST API", "JAX-RS", "Public and private APIs")
Component(contextServer, "Context Server", "OSGi", "Core server components")
Component(rules, "Rules Engine", "Java", "Event processing & rule evaluation")
Component(profiles, "Profile Service", "Java", "Profile management & tracking")
Component(segments, "Segment Service", "Java", "Dynamic user segmentation")
Component(events, "Event Service", "Java", "Event collection & processing")
Component(privacy, "Privacy Service", "Java", "Consent & privacy management")
}

ContainerDb(elastic, "Search Engine", "Elasticsearch/OpenSearch", "Data persistence")
Container(karaf, "Apache Karaf", "OSGi Container", "Runtime environment")

Rel(webApp, restApi, "Uses", "HTTP/JSON")
Rel(mobileApp, restApi, "Uses", "HTTP/JSON")
Rel(restApi, contextServer, "Uses")
Rel(contextServer, rules, "Uses")
Rel(contextServer, profiles, "Uses")
Rel(contextServer, segments, "Uses")
Rel(contextServer, events, "Uses")
Rel(contextServer, privacy, "Uses")
Rel(contextServer, elastic, "Persists data", "REST")
Rel(karaf, unomi, "Hosts")

@enduml
----

=== Service Architecture

[plantuml]
----
@startuml
skinparam componentStyle uml2
skinparam component {
BackgroundColor<<core>> LightBlue
BackgroundColor<<persistence>> LightGreen
BackgroundColor<<security>> LightYellow
}

package "Core Services" {
[Profile Service] <<core>>
[Event Service] <<core>>
[Segment Service] <<core>>
[Rules Service] <<core>>
[Privacy Service] <<core>>
[Definitions Service] <<core>>
}

package "Security" {
[Security Service] <<security>>
[Authentication] <<security>>
[Authorization] <<security>>
}

package "Persistence" {
[Persistence Service] <<persistence>>
[Cache Service] <<persistence>>
}

package "HTTP APIs" {
[REST Server]
[GraphQL API]
}

package "Extensions" {
[Router]
[Plugins]
}

database "Search Engine" {
[Elasticsearch/OpenSearch]
}

[Profile Service] --> [Persistence Service]
[Event Service] --> [Persistence Service]
[Segment Service] --> [Persistence Service]
[Rules Service] --> [Persistence Service]

[Profile Service] --> [Cache Service]
[Segment Service] --> [Cache Service]
[Rules Service] --> [Cache Service]

[REST Server] --> [Security Service]
[REST Server] --> [Profile Service]
[REST Server] --> [Event Service]
[REST Server] --> [Segment Service]
[REST Server] --> [Rules Service]

[Persistence Service] --> [Elasticsearch/OpenSearch]

[Router] --> [Profile Service]
[Plugins] --> [Core Services]

note right of [Security Service]
Handles authentication,
authorization, and
tenant isolation
end note

note right of [Cache Service]
Multi-level caching for
profiles, segments,
and rules
end note
@enduml
----

=== Condition Evaluation Architecture

[plantuml]
----
@startuml
skinparam componentStyle uml2
skinparam component {
BackgroundColor<<evaluation>> LightBlue
BackgroundColor<<query>> LightGreen
BackgroundColor<<persistence>> LightYellow
}

package "Condition Evaluation" {
[ConditionDispatcher] <<evaluation>>
[ConditionEvaluator] <<evaluation>>
[ConditionESQueryBuilder] <<query>>
[ConditionOSQueryBuilder] <<query>>
}

package "Query Building" {
interface "QueryBuilder" as QB
[ElasticSearchQueryBuilder] <<query>>
[OpenSearchQueryBuilder] <<query>>
}

package "Storage" {
[ElasticSearch] <<persistence>>
[OpenSearch] <<persistence>>
}

[ConditionDispatcher] --> [ConditionEvaluator]
[ConditionDispatcher] --> QB

QB <|.. [ConditionESQueryBuilder]
QB <|.. [ConditionOSQueryBuilder]

[ConditionESQueryBuilder] --> [ElasticSearchQueryBuilder]
[ConditionOSQueryBuilder] --> [OpenSearchQueryBuilder]

[ElasticSearchQueryBuilder] --> [ElasticSearch]
[OpenSearchQueryBuilder] --> [OpenSearch]

note right of [ConditionDispatcher]
Routes condition evaluation:
1. Direct evaluation
2. Query-based evaluation
end note

note right of QB
Abstract query building
for different search
engine implementations
end note
@enduml
----

==== Key Components

1. *ConditionDispatcher*
- Routes conditions to appropriate evaluators
- Determines evaluation strategy (direct vs query-based)
- Handles caching and optimization

2. *ConditionEvaluator*
- Performs direct condition evaluation
- Handles boolean logic and property comparisons
- Evaluates nested conditions

3. *QueryBuilders*
- Convert conditions to search engine queries
- Handle search engine specific syntax
- Optimize query performance

=== Data Flow

[plantuml]
----
@startuml
skinparam activityBackgroundColor LightBlue
skinparam activityBorderColor DarkBlue
skinparam arrowColor DarkBlue

|Client|
start
:Send Event/Context Request;

|REST API|
:Validate Request;
:Authenticate & Authorize;

|Event Processing|
:Process Event;
:Apply Rules;
:Update Profile;

|Segmentation|
:Evaluate Segments;
:Update Profile Segments;

|Persistence|
:Save Profile;
:Save Event;

|REST API|
:Return Response;

|Client|
:Update UI/Take Action;
stop
@enduml
----
Loading
Loading