Modified: unomi/website/manual/latest/index.html URL: http://svn.apache.org/viewvc/unomi/website/manual/latest/index.html?rev=1903308&r1=1903307&r2=1903308&view=diff ============================================================================== --- unomi/website/manual/latest/index.html (original) +++ unomi/website/manual/latest/index.html Tue Aug 9 12:02:22 2022 @@ -53,14 +53,6 @@ <li><a href="#_where_to_go_from_here">2.3.6. Where to go from here</a></li> </ul> </li> -<li><a href="#_web_tracker">2.4. Web Tracker</a> -<ul class="sectlevel3"> -<li><a href="#_getting_started">2.4.1. Getting started</a></li> -<li><a href="#_how_to_contribute">2.4.2. How to contribute</a></li> -<li><a href="#_tracking_page_views">2.4.3. Tracking page views</a></li> -<li><a href="#_tracking_form_submissions">2.4.4. Tracking form submissions</a></li> -</ul> -</li> </ul> </li> <li><a href="#_configuration">3. Configuration</a> @@ -94,313 +86,341 @@ </li> </ul> </li> -<li><a href="#_migrations">4. Migrations</a> +<li><a href="#_json_schemas">4. JSON schemas</a> +<ul class="sectlevel2"> +<li><a href="#_introduction_2">4.1. Introduction</a> +<ul class="sectlevel3"> +<li><a href="#_what_is_a_json_schema">4.1.1. What is a JSON Schema</a></li> +<li><a href="#_key_concepts">4.1.2. Key concepts</a></li> +<li><a href="#_how_are_json_schema_used_in_unomi">4.1.3. How are JSON Schema used in Unomi</a></li> +</ul> +</li> +<li><a href="#_json_schema_api">4.2. JSON schema API</a> +<ul class="sectlevel3"> +<li><a href="#_list_existing_schemas">4.2.1. List existing schemas</a></li> +<li><a href="#_read_a_schema">4.2.2. Read a schema</a></li> +<li><a href="#_create_update_a_json_schema_to_validate_an_event">4.2.3. Create / update a JSON schema to validate an event</a></li> +<li><a href="#_deleting_a_schema">4.2.4. Deleting a schema</a></li> +<li><a href="#_error_management">4.2.5. Error Management</a></li> +<li><a href="#_details_on_invalid_events">4.2.6. Details on invalid events</a></li> +</ul> +</li> +<li><a href="#_extend_an_existing_schema">4.3. Extend an existing schema</a> +<ul class="sectlevel3"> +<li><a href="#_when_a_extension_is_needed">4.3.1. When a extension is needed?</a></li> +<li><a href="#_understanding_how_extensions_are_merged_in_unomi">4.3.2. Understanding how extensions are merged in unomi</a></li> +<li><a href="#_how_to_add_an_extension_through_the_api">4.3.3. How to add an extension through the API</a></li> +</ul> +</li> +</ul> +</li> +<li><a href="#_migrations">5. Migrations</a> <ul class="sectlevel2"> -<li><a href="#_from_version_1_4_to_1_5">4.1. From version 1.4 to 1.5</a> +<li><a href="#_from_version_1_4_to_1_5">5.1. From version 1.4 to 1.5</a> <ul class="sectlevel3"> -<li><a href="#_data_model_and_elasticsearch_7">4.1.1. Data model and ElasticSearch 7</a></li> -<li><a href="#_api_changes">4.1.2. API changes</a></li> -<li><a href="#_migration_steps">4.1.3. Migration steps</a></li> +<li><a href="#_data_model_and_elasticsearch_7">5.1.1. Data model and ElasticSearch 7</a></li> +<li><a href="#_api_changes">5.1.2. API changes</a></li> +<li><a href="#_migration_steps">5.1.3. Migration steps</a></li> </ul> </li> -<li><a href="#_important_changes_in_public_servlets_since_version_1_5_5_and_2_0_0">4.2. Important changes in public servlets since version 1.5.5 and 2.0.0</a></li> +<li><a href="#_important_changes_in_public_servlets_since_version_1_5_5_and_2_0_0">5.2. Important changes in public servlets since version 1.5.5 and 2.0.0</a></li> </ul> </li> -<li><a href="#_queries_and_aggregations">5. Queries and aggregations</a> +<li><a href="#_queries_and_aggregations">6. Queries and aggregations</a> <ul class="sectlevel2"> -<li><a href="#_query_counts">5.1. Query counts</a></li> -<li><a href="#_metrics">5.2. Metrics</a></li> -<li><a href="#_aggregations">5.3. Aggregations</a> +<li><a href="#_query_counts">6.1. Query counts</a></li> +<li><a href="#_metrics">6.2. Metrics</a></li> +<li><a href="#_aggregations">6.3. Aggregations</a> <ul class="sectlevel3"> -<li><a href="#_aggregation_types">5.3.1. Aggregation types</a></li> +<li><a href="#_aggregation_types">6.3.1. Aggregation types</a></li> </ul> </li> </ul> </li> -<li><a href="#_profile_import_export">6. Profile import & export</a> +<li><a href="#_profile_import_export">7. Profile import & export</a> <ul class="sectlevel2"> -<li><a href="#_importing_profiles">6.1. Importing profiles</a> +<li><a href="#_importing_profiles">7.1. Importing profiles</a> <ul class="sectlevel3"> -<li><a href="#_import_api">6.1.1. Import API</a></li> +<li><a href="#_import_api">7.1.1. Import API</a></li> </ul> </li> -<li><a href="#_exporting_profiles">6.2. Exporting profiles</a> +<li><a href="#_exporting_profiles">7.2. Exporting profiles</a> <ul class="sectlevel3"> -<li><a href="#_export_api">6.2.1. Export API</a></li> +<li><a href="#_export_api">7.2.1. Export API</a></li> </ul> </li> -<li><a href="#_configuration_in_details">6.3. Configuration in details</a></li> +<li><a href="#_configuration_in_details">7.3. Configuration in details</a></li> </ul> </li> -<li><a href="#_consent_management">7. Consent management</a> +<li><a href="#_consent_management">8. Consent management</a> <ul class="sectlevel2"> -<li><a href="#_consent_api">7.1. Consent API</a> +<li><a href="#_consent_api">8.1. Consent API</a> <ul class="sectlevel3"> -<li><a href="#_profiles_with_consents">7.1.1. Profiles with consents</a></li> -<li><a href="#_consent_type_definitions">7.1.2. Consent type definitions</a></li> -<li><a href="#_creating_update_a_visitor_consent">7.1.3. Creating / update a visitor consent</a></li> -<li><a href="#_how_it_works_internally">7.1.4. How it works (internally)</a></li> +<li><a href="#_profiles_with_consents">8.1.1. Profiles with consents</a></li> +<li><a href="#_consent_type_definitions">8.1.2. Consent type definitions</a></li> +<li><a href="#_creating_update_a_visitor_consent">8.1.3. Creating / update a visitor consent</a></li> +<li><a href="#_how_it_works_internally">8.1.4. How it works (internally)</a></li> </ul> </li> </ul> </li> -<li><a href="#_privacy_management">8. Privacy management</a> +<li><a href="#_privacy_management">9. Privacy management</a> <ul class="sectlevel2"> -<li><a href="#_setting_up_access_to_the_privacy_endpoint">8.1. Setting up access to the privacy endpoint</a></li> -<li><a href="#_anonymizing_a_profile">8.2. Anonymizing a profile</a></li> -<li><a href="#_downloading_profile_data">8.3. Downloading profile data</a></li> -<li><a href="#_deleting_a_profile">8.4. Deleting a profile</a></li> -<li><a href="#_related">8.5. Related</a></li> +<li><a href="#_setting_up_access_to_the_privacy_endpoint">9.1. Setting up access to the privacy endpoint</a></li> +<li><a href="#_anonymizing_a_profile">9.2. Anonymizing a profile</a></li> +<li><a href="#_downloading_profile_data">9.3. Downloading profile data</a></li> +<li><a href="#_deleting_a_profile">9.4. Deleting a profile</a></li> +<li><a href="#_related">9.5. Related</a></li> </ul> </li> -<li><a href="#_cluster_setup">9. Cluster setup</a> +<li><a href="#_cluster_setup">10. Cluster setup</a> <ul class="sectlevel2"> -<li><a href="#_cluster_setup_2">9.1. Cluster setup</a></li> +<li><a href="#_cluster_setup_2">10.1. Cluster setup</a></li> </ul> </li> -<li><a href="#_reference">10. Reference</a> +<li><a href="#_reference">11. Reference</a> <ul class="sectlevel2"> -<li><a href="#_useful_apache_unomi_urls">10.1. Useful Apache Unomi URLs</a></li> -<li><a href="#_how_profile_tracking_works">10.2. How profile tracking works</a> +<li><a href="#_useful_apache_unomi_urls">11.1. Useful Apache Unomi URLs</a></li> +<li><a href="#_how_profile_tracking_works">11.2. How profile tracking works</a> <ul class="sectlevel3"> -<li><a href="#_steps">10.2.1. Steps</a></li> +<li><a href="#_steps">11.2.1. Steps</a></li> </ul> </li> -<li><a href="#_context_request_flow">10.3. Context Request Flow</a></li> -<li><a href="#_data_model_overview">10.4. Data Model Overview</a></li> -<li><a href="#_scope">10.5. Scope</a> +<li><a href="#_context_request_flow">11.3. Context Request Flow</a></li> +<li><a href="#_data_model_overview">11.4. Data Model Overview</a></li> +<li><a href="#_scope">11.5. Scope</a> <ul class="sectlevel3"> -<li><a href="#_example">10.5.1. Example</a></li> +<li><a href="#_example">11.5.1. Example</a></li> </ul> </li> -<li><a href="#_item">10.6. Item</a> +<li><a href="#_item">11.6. Item</a> <ul class="sectlevel3"> -<li><a href="#_structure_definition">10.6.1. Structure definition</a></li> +<li><a href="#_structure_definition">11.6.1. Structure definition</a></li> </ul> </li> -<li><a href="#_metadata">10.7. Metadata</a> +<li><a href="#_metadata">11.7. Metadata</a> <ul class="sectlevel3"> -<li><a href="#_structure_definition_2">10.7.1. Structure definition</a></li> -<li><a href="#_example_2">10.7.2. Example</a></li> +<li><a href="#_structure_definition_2">11.7.1. Structure definition</a></li> +<li><a href="#_example_2">11.7.2. Example</a></li> </ul> </li> -<li><a href="#_metadataitem">10.8. MetadataItem</a> +<li><a href="#_metadataitem">11.8. MetadataItem</a> <ul class="sectlevel3"> -<li><a href="#_structure_definition_3">10.8.1. Structure definition</a></li> -<li><a href="#_example_3">10.8.2. Example</a></li> +<li><a href="#_structure_definition_3">11.8.1. Structure definition</a></li> +<li><a href="#_example_3">11.8.2. Example</a></li> </ul> </li> -<li><a href="#_event">10.9. Event</a> +<li><a href="#_event">11.9. Event</a> <ul class="sectlevel3"> -<li><a href="#_fields">10.9.1. Fields</a></li> -<li><a href="#_event_types">10.9.2. Event types</a></li> +<li><a href="#_fields">11.9.1. Fields</a></li> +<li><a href="#_event_types">11.9.2. Event types</a></li> </ul> </li> -<li><a href="#_profile">10.10. Profile</a> +<li><a href="#_profile">11.10. Profile</a> <ul class="sectlevel3"> -<li><a href="#_structure_definition_4">10.10.1. Structure definition</a></li> -<li><a href="#_example_4">10.10.2. Example</a></li> +<li><a href="#_structure_definition_4">11.10.1. Structure definition</a></li> +<li><a href="#_example_4">11.10.2. Example</a></li> </ul> </li> -<li><a href="#_persona">10.11. Persona</a> +<li><a href="#_persona">11.11. Persona</a> <ul class="sectlevel3"> -<li><a href="#_structure_definition_5">10.11.1. Structure definition</a></li> -<li><a href="#_example_5">10.11.2. Example</a></li> +<li><a href="#_structure_definition_5">11.11.1. Structure definition</a></li> +<li><a href="#_example_5">11.11.2. Example</a></li> </ul> </li> -<li><a href="#_consent">10.12. Consent</a> +<li><a href="#_consent">11.12. Consent</a> <ul class="sectlevel3"> -<li><a href="#_structure_definition_6">10.12.1. Structure definition</a></li> -<li><a href="#_example_6">10.12.2. Example</a></li> +<li><a href="#_structure_definition_6">11.12.1. Structure definition</a></li> +<li><a href="#_example_6">11.12.2. Example</a></li> </ul> </li> -<li><a href="#_session">10.13. Session</a> +<li><a href="#_session">11.13. Session</a> <ul class="sectlevel3"> -<li><a href="#_structure_definition_7">10.13.1. Structure definition</a></li> -<li><a href="#_example_7">10.13.2. Example</a></li> +<li><a href="#_structure_definition_7">11.13.1. Structure definition</a></li> +<li><a href="#_example_7">11.13.2. Example</a></li> </ul> </li> -<li><a href="#_segment">10.14. Segment</a> +<li><a href="#_segment">11.14. Segment</a> <ul class="sectlevel3"> -<li><a href="#_structure_definition_8">10.14.1. Structure definition</a></li> -<li><a href="#_example_8">10.14.2. Example</a></li> +<li><a href="#_structure_definition_8">11.14.1. Structure definition</a></li> +<li><a href="#_example_8">11.14.2. Example</a></li> </ul> </li> -<li><a href="#_condition">10.15. Condition</a> +<li><a href="#_condition">11.15. Condition</a> <ul class="sectlevel3"> -<li><a href="#_structure_definition_9">10.15.1. Structure definition</a></li> -<li><a href="#_example_9">10.15.2. Example</a></li> +<li><a href="#_structure_definition_9">11.15.1. Structure definition</a></li> +<li><a href="#_example_9">11.15.2. Example</a></li> </ul> </li> -<li><a href="#_rule">10.16. Rule</a> +<li><a href="#_rule">11.16. Rule</a> <ul class="sectlevel3"> -<li><a href="#_structure_definition_10">10.16.1. Structure definition</a></li> -<li><a href="#_example_10">10.16.2. Example</a></li> +<li><a href="#_structure_definition_10">11.16.1. Structure definition</a></li> +<li><a href="#_example_10">11.16.2. Example</a></li> </ul> </li> -<li><a href="#_action">10.17. Action</a> +<li><a href="#_action">11.17. Action</a> <ul class="sectlevel3"> -<li><a href="#_structure_definition_11">10.17.1. Structure definition</a></li> -<li><a href="#_example_11">10.17.2. Example</a></li> +<li><a href="#_structure_definition_11">11.17.1. Structure definition</a></li> +<li><a href="#_example_11">11.17.2. Example</a></li> </ul> </li> -<li><a href="#_list">10.18. List</a> +<li><a href="#_list">11.18. List</a> <ul class="sectlevel3"> -<li><a href="#_structure_definition_12">10.18.1. Structure definition</a></li> -<li><a href="#_example_12">10.18.2. Example</a></li> +<li><a href="#_structure_definition_12">11.18.1. Structure definition</a></li> +<li><a href="#_example_12">11.18.2. Example</a></li> </ul> </li> -<li><a href="#_goal">10.19. Goal</a> +<li><a href="#_goal">11.19. Goal</a> <ul class="sectlevel3"> -<li><a href="#_structure_definition_13">10.19.1. Structure definition</a></li> -<li><a href="#_example_13">10.19.2. Example</a></li> +<li><a href="#_structure_definition_13">11.19.1. Structure definition</a></li> +<li><a href="#_example_13">11.19.2. Example</a></li> </ul> </li> -<li><a href="#_campaign">10.20. Campaign</a> +<li><a href="#_campaign">11.20. Campaign</a> <ul class="sectlevel3"> -<li><a href="#_structure_definition_14">10.20.1. Structure definition</a></li> -<li><a href="#_example_14">10.20.2. Example</a></li> +<li><a href="#_structure_definition_14">11.20.1. Structure definition</a></li> +<li><a href="#_example_14">11.20.2. Example</a></li> </ul> </li> -<li><a href="#_scoring_plan">10.21. Scoring plan</a> +<li><a href="#_scoring_plan">11.21. Scoring plan</a> <ul class="sectlevel3"> -<li><a href="#_structure_definition_15">10.21.1. Structure definition</a></li> -<li><a href="#_example_15">10.21.2. Example</a></li> +<li><a href="#_structure_definition_15">11.21.1. Structure definition</a></li> +<li><a href="#_example_15">11.21.2. Example</a></li> </ul> </li> -<li><a href="#_built_in_event_types">10.22. Built-in Event types</a> +<li><a href="#_built_in_event_types">11.22. Built-in Event types</a> <ul class="sectlevel3"> -<li><a href="#_login_event_type">10.22.1. Login event type</a></li> -<li><a href="#_view_event_type">10.22.2. View event type</a></li> -<li><a href="#_form_event_type">10.22.3. Form event type</a></li> -<li><a href="#_update_properties_event_type">10.22.4. Update properties event type</a></li> -<li><a href="#_identify_event_type">10.22.5. Identify event type</a></li> -<li><a href="#_session_created_event_type">10.22.6. Session created event type</a></li> -<li><a href="#_goal_event_type">10.22.7. Goal event type</a></li> -<li><a href="#_modify_consent_event_type">10.22.8. Modify consent event type</a></li> +<li><a href="#_login_event_type">11.22.1. Login event type</a></li> +<li><a href="#_view_event_type">11.22.2. View event type</a></li> +<li><a href="#_form_event_type">11.22.3. Form event type</a></li> +<li><a href="#_update_properties_event_type">11.22.4. Update properties event type</a></li> +<li><a href="#_identify_event_type">11.22.5. Identify event type</a></li> +<li><a href="#_session_created_event_type">11.22.6. Session created event type</a></li> +<li><a href="#_goal_event_type">11.22.7. Goal event type</a></li> +<li><a href="#_modify_consent_event_type">11.22.8. Modify consent event type</a></li> </ul> </li> -<li><a href="#_built_in_condition_types">10.23. Built-in condition types</a> +<li><a href="#_built_in_condition_types">11.23. Built-in condition types</a> <ul class="sectlevel3"> -<li><a href="#_existing_condition_type_descriptors">10.23.1. Existing condition type descriptors</a></li> +<li><a href="#_existing_condition_type_descriptors">11.23.1. Existing condition type descriptors</a></li> </ul> </li> -<li><a href="#_built_in_action_types">10.24. Built-in action types</a> +<li><a href="#_built_in_action_types">11.24. Built-in action types</a> <ul class="sectlevel3"> -<li><a href="#_existing_action_types_descriptors">10.24.1. Existing action types descriptors</a></li> +<li><a href="#_existing_action_types_descriptors">11.24.1. Existing action types descriptors</a></li> </ul> </li> -<li><a href="#_updating_events_using_the_context_servlet">10.25. Updating Events Using the Context Servlet</a> +<li><a href="#_updating_events_using_the_context_servlet">11.25. Updating Events Using the Context Servlet</a> <ul class="sectlevel3"> -<li><a href="#_solution">10.25.1. Solution</a></li> -<li><a href="#_defining_rules">10.25.2. Defining Rules</a></li> +<li><a href="#_solution">11.25.1. Solution</a></li> +<li><a href="#_defining_rules">11.25.2. Defining Rules</a></li> </ul> </li> </ul> </li> -<li><a href="#_integration_samples">11. Integration samples</a> +<li><a href="#_integration_samples">12. Integration samples</a> <ul class="sectlevel2"> -<li><a href="#_samples">11.1. Samples</a></li> -<li><a href="#_login_sample">11.2. Login sample</a> +<li><a href="#_samples">12.1. Samples</a></li> +<li><a href="#_login_sample">12.2. Login sample</a> <ul class="sectlevel3"> -<li><a href="#_warning">11.2.1. Warning !</a></li> -<li><a href="#_installing_the_samples">11.2.2. Installing the samples</a></li> +<li><a href="#_warning">12.2.1. Warning !</a></li> +<li><a href="#_installing_the_samples">12.2.2. Installing the samples</a></li> </ul> </li> -<li><a href="#_twitter_sample">11.3. Twitter sample</a> +<li><a href="#_twitter_sample">12.3. Twitter sample</a> <ul class="sectlevel3"> -<li><a href="#_overview">11.3.1. Overview</a></li> -<li><a href="#_interacting_with_the_context_server">11.3.2. Interacting with the context server</a></li> -<li><a href="#_retrieving_context_information_from_unomi_using_the_context_servlet">11.3.3. Retrieving context information from Unomi using the context servlet</a></li> +<li><a href="#_overview">12.3.1. Overview</a></li> +<li><a href="#_interacting_with_the_context_server">12.3.2. Interacting with the context server</a></li> +<li><a href="#_retrieving_context_information_from_unomi_using_the_context_servlet">12.3.3. Retrieving context information from Unomi using the context servlet</a></li> </ul> </li> -<li><a href="#_example_24">11.4. Example</a> +<li><a href="#_example_24">12.4. Example</a> <ul class="sectlevel3"> -<li><a href="#_html_page">11.4.1. HTML page</a></li> -<li><a href="#_javascript">11.4.2. Javascript</a></li> +<li><a href="#_html_page">12.4.1. HTML page</a></li> +<li><a href="#_javascript">12.4.2. Javascript</a></li> </ul> </li> -<li><a href="#_conclusion">11.5. Conclusion</a></li> -<li><a href="#_annex">11.6. Annex</a></li> -<li><a href="#_weather_update_sample">11.7. Weather update sample</a></li> +<li><a href="#_conclusion">12.5. Conclusion</a></li> +<li><a href="#_annex">12.6. Annex</a></li> +<li><a href="#_weather_update_sample">12.7. Weather update sample</a></li> </ul> </li> -<li><a href="#_connectors">12. Connectors</a> +<li><a href="#_connectors">13. Connectors</a> <ul class="sectlevel2"> -<li><a href="#_connectors_2">12.1. Connectors</a> +<li><a href="#_connectors_2">13.1. Connectors</a> <ul class="sectlevel3"> -<li><a href="#_call_for_contributors">12.1.1. Call for contributors</a></li> +<li><a href="#_call_for_contributors">13.1.1. Call for contributors</a></li> </ul> </li> -<li><a href="#_salesforce_connector">12.2. Salesforce Connector</a> +<li><a href="#_salesforce_connector">13.2. Salesforce Connector</a> <ul class="sectlevel3"> -<li><a href="#_getting_started_2">12.2.1. Getting started</a></li> -<li><a href="#_properties">12.2.2. Properties</a></li> -<li><a href="#_hot_deploying_updates_to_the_salesforce_connector_for_developers">12.2.3. Hot-deploying updates to the Salesforce connector (for developers)</a></li> -<li><a href="#_using_the_salesforce_workbench_for_testing_rest_api">12.2.4. Using the Salesforce Workbench for testing REST API</a></li> -<li><a href="#_setting_up_streaming_push_queries">12.2.5. Setting up Streaming Push queries</a></li> -<li><a href="#_executing_the_unit_tests">12.2.6. Executing the unit tests</a></li> +<li><a href="#_getting_started">13.2.1. Getting started</a></li> +<li><a href="#_properties">13.2.2. Properties</a></li> +<li><a href="#_hot_deploying_updates_to_the_salesforce_connector_for_developers">13.2.3. Hot-deploying updates to the Salesforce connector (for developers)</a></li> +<li><a href="#_using_the_salesforce_workbench_for_testing_rest_api">13.2.4. Using the Salesforce Workbench for testing REST API</a></li> +<li><a href="#_setting_up_streaming_push_queries">13.2.5. Setting up Streaming Push queries</a></li> +<li><a href="#_executing_the_unit_tests">13.2.6. Executing the unit tests</a></li> </ul> </li> -<li><a href="#_mailchimp_connector">12.3. MailChimp Connector</a> +<li><a href="#_mailchimp_connector">13.3. MailChimp Connector</a> <ul class="sectlevel3"> -<li><a href="#_getting_started_3">12.3.1. Getting started</a></li> +<li><a href="#_getting_started_2">13.3.1. Getting started</a></li> </ul> </li> </ul> </li> -<li><a href="#_developers">13. Developers</a> +<li><a href="#_developers">14. Developers</a> <ul class="sectlevel2"> -<li><a href="#_building">13.1. Building</a> +<li><a href="#_building">14.1. Building</a> +<ul class="sectlevel3"> +<li><a href="#_initial_setup">14.1.1. Initial Setup</a></li> +<li><a href="#_building_2">14.1.2. Building</a></li> +<li><a href="#_installing_an_elasticsearch_server">14.1.3. Installing an ElasticSearch server</a></li> +<li><a href="#_deploying_the_generated_binary_package">14.1.4. Deploying the generated binary package</a></li> +<li><a href="#_deploying_into_an_existing_karaf_server">14.1.5. Deploying into an existing Karaf server</a></li> +<li><a href="#_jdk_selection_on_mac_os_x">14.1.6. JDK Selection on Mac OS X</a></li> +<li><a href="#_running_the_integration_tests">14.1.7. Running the integration tests</a></li> +<li><a href="#_testing_with_an_example_page">14.1.8. Testing with an example page</a></li> +</ul> +</li> +<li><a href="#_ssh_shell_commands">14.2. SSH Shell Commands</a> <ul class="sectlevel3"> -<li><a href="#_initial_setup">13.1.1. Initial Setup</a></li> -<li><a href="#_building_2">13.1.2. Building</a></li> -<li><a href="#_installing_an_elasticsearch_server">13.1.3. Installing an ElasticSearch server</a></li> -<li><a href="#_deploying_the_generated_binary_package">13.1.4. Deploying the generated binary package</a></li> -<li><a href="#_deploying_into_an_existing_karaf_server">13.1.5. Deploying into an existing Karaf server</a></li> -<li><a href="#_jdk_selection_on_mac_os_x">13.1.6. JDK Selection on Mac OS X</a></li> -<li><a href="#_running_the_integration_tests">13.1.7. Running the integration tests</a></li> -<li><a href="#_testing_with_an_example_page">13.1.8. Testing with an example page</a></li> -</ul> -</li> -<li><a href="#_ssh_shell_commands">13.2. SSH Shell Commands</a> -<ul class="sectlevel3"> -<li><a href="#_using_the_shell">13.2.1. Using the shell</a></li> -<li><a href="#_lifecycle_commands">13.2.2. Lifecycle commands</a></li> -<li><a href="#_runtime_commands">13.2.3. Runtime commands</a></li> -</ul> -</li> -<li><a href="#_writing_plugins">13.3. Writing Plugins</a></li> -<li><a href="#_types_vs_instances">13.4. Types vs. instances</a></li> -<li><a href="#_plugin_structure">13.5. Plugin structure</a></li> -<li><a href="#_extension_points">13.6. Extension points</a> -<ul class="sectlevel3"> -<li><a href="#_actiontype">13.6.1. ActionType</a></li> -<li><a href="#_conditiontype">13.6.2. ConditionType</a></li> -<li><a href="#_persona_2">13.6.3. Persona</a></li> -<li><a href="#_propertymergestrategytype">13.6.4. PropertyMergeStrategyType</a></li> -<li><a href="#_propertytype">13.6.5. PropertyType</a></li> -<li><a href="#_rule_2">13.6.6. Rule</a></li> -<li><a href="#_scoring">13.6.7. Scoring</a></li> -<li><a href="#_segments">13.6.8. Segments</a></li> -<li><a href="#_tag">13.6.9. Tag</a></li> -<li><a href="#_valuetype">13.6.10. ValueType</a></li> -</ul> -</li> -<li><a href="#_custom_plugins">13.7. Custom plugins</a> -<ul class="sectlevel3"> -<li><a href="#_creating_a_plugin">13.7.1. Creating a plugin</a></li> -<li><a href="#_deployment_and_custom_definition">13.7.2. Deployment and custom definition</a></li> -<li><a href="#_predefined_segments">13.7.3. Predefined segments</a></li> -<li><a href="#_predefined_rules">13.7.4. Predefined rules</a></li> -<li><a href="#_predefined_properties">13.7.5. Predefined properties</a></li> -<li><a href="#_predefined_child_conditions">13.7.6. Predefined child conditions</a></li> -<li><a href="#_predefined_personas">13.7.7. Predefined personas</a></li> -<li><a href="#_custom_action_types">13.7.8. Custom action types</a></li> -<li><a href="#_custom_condition_types">13.7.9. Custom condition types</a></li> +<li><a href="#_using_the_shell">14.2.1. Using the shell</a></li> +<li><a href="#_lifecycle_commands">14.2.2. Lifecycle commands</a></li> +<li><a href="#_runtime_commands">14.2.3. Runtime commands</a></li> </ul> </li> -<li><a href="#_migration_patches">13.8. Migration patches</a></li> +<li><a href="#_writing_plugins">14.3. Writing Plugins</a></li> +<li><a href="#_types_vs_instances">14.4. Types vs. instances</a></li> +<li><a href="#_plugin_structure">14.5. Plugin structure</a></li> +<li><a href="#_extension_points">14.6. Extension points</a> +<ul class="sectlevel3"> +<li><a href="#_actiontype">14.6.1. ActionType</a></li> +<li><a href="#_conditiontype">14.6.2. ConditionType</a></li> +<li><a href="#_persona_2">14.6.3. Persona</a></li> +<li><a href="#_propertymergestrategytype">14.6.4. PropertyMergeStrategyType</a></li> +<li><a href="#_propertytype">14.6.5. PropertyType</a></li> +<li><a href="#_rule_2">14.6.6. Rule</a></li> +<li><a href="#_scoring">14.6.7. Scoring</a></li> +<li><a href="#_segments">14.6.8. Segments</a></li> +<li><a href="#_tag">14.6.9. Tag</a></li> +<li><a href="#_valuetype">14.6.10. ValueType</a></li> +</ul> +</li> +<li><a href="#_custom_plugins">14.7. Custom plugins</a> +<ul class="sectlevel3"> +<li><a href="#_creating_a_plugin">14.7.1. Creating a plugin</a></li> +<li><a href="#_deployment_and_custom_definition">14.7.2. Deployment and custom definition</a></li> +<li><a href="#_predefined_segments">14.7.3. Predefined segments</a></li> +<li><a href="#_predefined_rules">14.7.4. Predefined rules</a></li> +<li><a href="#_predefined_properties">14.7.5. Predefined properties</a></li> +<li><a href="#_predefined_child_conditions">14.7.6. Predefined child conditions</a></li> +<li><a href="#_predefined_personas">14.7.7. Predefined personas</a></li> +<li><a href="#_custom_action_types">14.7.8. Custom action types</a></li> +<li><a href="#_custom_condition_types">14.7.9. Custom condition types</a></li> +</ul> +</li> +<li><a href="#_migration_patches">14.8. Migration patches</a></li> </ul> </li> </ul> @@ -462,14 +482,8 @@ make sure you are using the proper versi <div class="ulist"> <ul> <li> -<p>Connect to <a href="http://localhost:8181" class="bare">http://localhost:8181</a> to try our some live examples (such as the web tracker)</p> -</li> -<li> <p>Trying our integration <a href="#_samples">samples page</a></p> </li> -<li> -<p>Learning more about the <a href="#_web_tracker">web tracker</a></p> -</li> </ul> </div> </div> @@ -1127,463 +1141,12 @@ to send additional events.</p> <p>You can find more <a href="#_useful_apache_unomi_urls">useful Apache Unomi URLs</a> that can be used in the same way as the above examples.</p> </li> <li> -<p>You may want to know integrate the provided <a href="#_web_tracker">web tracker</a> into your web site.</p> -</li> -<li> <p>Read the <a href="#_twitter_sample">Twitter sample</a> documentation that contains a detailed example of how to integrate with Apache Unomi.</p> </li> </ul> </div> </div> </div> -<div class="sect2"> -<h3 id="_web_tracker">2.4. Web Tracker</h3> -<div class="paragraph"> -<p>This extension is providing the web tracker to start collecting visitors data on your website. -The tracker is implemented as an integration of <a href="https://github.com/segmentio/analytics.js">analytics.js</a> for Unomi.</p> -</div> -<div class="sect3"> -<h4 id="_getting_started">2.4.1. Getting started</h4> -<div class="paragraph"> -<p>Extension can be tested at : <code><a href="http://localhost:8181/tracker/index.html" class="bare">http://localhost:8181/tracker/index.html</a></code></p> -</div> -<div class="paragraph"> -<p>In your page include unomiOptions and include code snippet from <code>snippet.min.js</code> :</p> -</div> -<div class="listingblock"> -<div class="content"> -<pre class="highlight"><code><script type="text/javascript"> - var unomiOption = { - scope: 'realEstateManager', - url: 'http://localhost:8181' - }; - window.unomiTracker||(window.unomiTracker={}),function(){function e(e){for(unomiTracker.initialize({"Apache Unomi":unomiOption});n.length>0;){var r=n.shift(),t=r.shift();unomiTracker[t]&&unomiTracker[t].apply(unomiTracker,r)}}for(var n=[],r=["trackSubmit","trackClick","trackLink","trackForm","initialize","pageview","identify","reset","group","track","ready","alias","debug","page","once","off","on","personalize"],t=0;t<r.length;t++){var i=r[t];window.unomiTracker[i]=function(e){return function(){var r=Array.prototype.slice.call(arguments);return r.unshift(e),n.push(r),window.unomiTracker}}(i)}unomiTracker.load=function(){var n=document.createElement("script");n.type="text/javascript",n.async=!0,n.src=unomiOption.url+"/tracker/unomi-tracker.min.js",n.addEventListener?n.addEventListener("load",function(n){"function"==typeof e&&e(n)},!1):n.onreadystatechange=function(){"complete"!==this.readyState&&"loaded"!==this.readyState||e(window.event)};var r= document.getElementsByTagName("script")[0];r.parentNode.insertBefore(n,r)},document.addEventListener("DOMContentLoaded",unomiTracker.load),unomiTracker.page()}(); -</script></code></pre> -</div> -</div> -<div class="paragraph"> -<p><code>window.unomiTracker</code> can be used to send additional events when needed.</p> -</div> -<div class="paragraph"> -<p>Check analytics.js API <a href="https://segment.com/docs/sources/website/analytics.js/">here</a>. -All methods can be used on <code>unomiTracker</code> object, although not all event types are supported by Unomi intergation.</p> -</div> -</div> -<div class="sect3"> -<h4 id="_how_to_contribute">2.4.2. How to contribute</h4> -<div class="paragraph"> -<p>The source code is in the folder javascript with a package.json, the file to update is <code>analytics.js-integration-apache-unomi.js</code> apply your modification in this file then use the command <code>yarn build</code> to compile a new JS file. -Then you can use the test page to try your changes <code><a href="http://localhost:8181/tracker/index.html" class="bare">http://localhost:8181/tracker/index.html</a></code>.</p> -</div> -</div> -<div class="sect3"> -<h4 id="_tracking_page_views">2.4.3. Tracking page views</h4> -<div class="paragraph"> -<p>In the initialize call, the tracker will generate an implicit page view event, which by default will be populated with -the following information:</p> -</div> -<div class="listingblock"> -<div class="content"> -<pre class="highlight"><code class="language-javascript" data-lang="javascript"> window.digitalData.page = window.digitalData.page || { - path: location.pathname + location.hash, - pageInfo: { - pageName: document.title, - pageID : location.pathname + location.hash, - pagePath : location.pathname + location.hash, - destinationURL: location.href - } - }</code></pre> -</div> -</div> -<div class="paragraph"> -<p>Now if you want to provide your own custom page information for the initial page view, you can simply do it like this:</p> -</div> -<div class="listingblock"> -<div class="content"> -<pre class="highlight"><code class="language-`javascript" data-lang="`javascript"> unomiTracker.initialize({ - scope: 'myScope', - url: 'http://unomi:8181', // we use an empty URL to make it relative to this page. - initialPageProperties: { - path: path, - pageInfo: { - destinationURL: location.href, - tags: ["tag1", "tag2", "tag3"], - categories: ["category1", "category2", "category3"] - }, - interests: { - "interest1": 1, - "interest2": 2, - "interest3": 3 - } - } - });</code></pre> -</div> -</div> -<div class="paragraph"> -<p>`</p> -</div> -<div class="paragraph"> -<p>Also note that the FIRST call to unomiTracker.page() will be IGNORED because of this initial page view.This is the -way that the Analytics.js library handles it.So make sure you are aware of this when calling it.This is to avoid having -two page views on a single call and to be compatible with old versions that did use the explicit call.</p> -</div> -<div class="paragraph"> -<p>By default the script will track page views, but maybe you want to take control over this mechanism of add page views -to a single page application.In order to generate a page view programmatically from Javascript you can use code similar -to this :</p> -</div> -<div class="listingblock"> -<div class="content"> -<pre class="highlight"><code> <script type="text/javascript"> - // This is an example of how to provide more details page properties to the view event. This can be useful - // in the case of an SPA that wants to provide information about a view that has metadata such as categories, - // tags or interests. - path = location.pathname + location.hash; - properties = { - path: path, - pageInfo: { - destinationURL: location.href, - tags : [ "tag1", "tag2", "tag3"], - categories : ["category1", "category2", "category3"], - }, - interests : { - "interest1" : 1, - "interest2" : 2, - "interest3" : 3 - } - }; - console.log(properties); - // this will trigger a second page view for the same page (the first page view is in the tracker snippet). - window.unomiTracker.page(properties); - </script></code></pre> -</div> -</div> -<div class="paragraph"> -<p>Here is a more detail view of what you may include in the pageInfo object :</p> -</div> -<table class="tableblock frame-all grid-all stretch"> -<caption class="title">Table 1. PageInfo Properties</caption> -<colgroup> -<col style="width: 50%;"> -<col style="width: 50%;"> -</colgroup> -<thead> -<tr> -<th class="tableblock halign-left valign-top">Name</th> -<th class="tableblock halign-left valign-top">Description</th> -</tr> -</thead> -<tbody> -<tr> -<td class="tableblock halign-left valign-top"><p class="tableblock">pageID</p></td> -<td class="tableblock halign-left valign-top"><p class="tableblock">A unique identifier in string format for the page. Default value : page path</p></td> -</tr> -<tr> -<td class="tableblock halign-left valign-top"><p class="tableblock">pageName</p></td> -<td class="tableblock halign-left valign-top"><p class="tableblock">A user-displayed name for the page. Default value : page title</p></td> -</tr> -<tr> -<td class="tableblock halign-left valign-top"><p class="tableblock">pagePath</p></td> -<td class="tableblock halign-left valign-top"><p class="tableblock">The path of the page, stored by Unomi. This value should be the same as the one passed in the <code>page</code> property of the -object passed to the unomiTracker call. Default value : page path</p></td> -</tr> -<tr> -<td class="tableblock halign-left valign-top"><p class="tableblock">destinationURL</p></td> -<td class="tableblock halign-left valign-top"><p class="tableblock">The full URL for the page view. This doesn’t have to be a real existing URL it could be an internal SPA route. Default value : page URL</p></td> -</tr> -<tr> -<td class="tableblock halign-left valign-top"><p class="tableblock">referringURL</p></td> -<td class="tableblock halign-left valign-top"><p class="tableblock">The referringURL also known as the previous URL of the page/screen viewed. Default value : page referrer URL</p></td> -</tr> -<tr> -<td class="tableblock halign-left valign-top"><p class="tableblock">tags</p></td> -<td class="tableblock halign-left valign-top"><p class="tableblock">A String array of tag identifiers. For example <code>['tag1', 'tag2', 'tag3']</code></p></td> -</tr> -<tr> -<td class="tableblock halign-left valign-top"><p class="tableblock">categories</p></td> -<td class="tableblock halign-left valign-top"><p class="tableblock">A String array of category identifiers. For example <code>['category1', 'category2', 'category3']</code></p></td> -</tr> -</tbody> -</table> -<div class="paragraph"> -<p>The <code>interests</code> object is basically list of interests with "weights" attached to them.These interests will be accumulated -in Apache Unomi on profiles to indicate growing interest over time for specific topics.These are freely defined and -will be accepted by Apache Unomi without needing to declare them previously anywhere (the same is true for tags and -categories).</p> -</div> -</div> -<div class="sect3"> -<h4 id="_tracking_form_submissions">2.4.4. Tracking form submissions</h4> -<div class="paragraph"> -<p>Using the web tracker you can also track form submissions. In order to do this a few steps are required to get a form’s -submission to be tracked and then its form values to be sent as events to Apache Unomi. Finally setting up a rule to -react to the incoming event will help use the form values to perform any action that is desired.</p> -</div> -<div class="paragraph"> -<p>Let’s look at a concrete example. Before we get started you should know that this example is already available to -directly test in Apache Unomi at the following URL :</p> -</div> -<div class="literalblock"> -<div class="content"> -<pre>http://localhost:8181/tracker</pre> -</div> -</div> -<div class="paragraph"> -<p>Simply modify the form values and click submit and it will perform all the steps we are describing below.</p> -</div> -<div class="paragraph"> -<p>So here is the form we want to track :</p> -</div> -<div class="listingblock"> -<div class="content"> -<pre class="highlight"><code><form id="testFormTracking" action="#" name="testFormTracking"> - <label for="firstName">First name</label> - <input type="text" id="firstName" name="firstName" value="John"/> - - <label for="lastName">Last name</label> - <input type="text" id="lastName" name="lastName" value="Doe"/> - - <label for="email">Email</label> - <input type="email" id="email" name="email" value="[email protected]"/> - - <input type="submit" name="submitButton" value="Submit"/> -</form></code></pre> -</div> -</div> -<div class="paragraph"> -<p>As you can see it’s composed of three fields - firstName, lastName and email - as well as a submit button. In order to -track it we can add directly under the following snippet :</p> -</div> -<div class="listingblock"> -<div class="content"> -<pre class="highlight"><code><script type="text/javascript"> - window.addEventListener("load", function () { - var form = document.getElementById('testFormTracking'); - unomiTracker.trackForm(form, 'formSubmitted', {formName: form.name}); - }); -</script></code></pre> -</div> -</div> -<div class="paragraph"> -<p>What this snippet does is retrieve the form using its element ID and then uses the unomiTracker to track form submissions. -Be careful to always use in the form event name a string that starts with <code>form</code> in order for the event to be sent back -to Unomi. Also the form name is also a mandatory parameter that will be passed to Unomi inside a event of type <code>form</code> under -the <code>target.itemId</code> property name.</p> -</div> -<div class="paragraph"> -<p>Here is an example of the event that gets sent back to Apache Unomi:</p> -</div> -<div class="listingblock"> -<div class="content"> -<pre class="highlight"><code>{ - "itemId" : "cd627012-963e-4bb5-97f0-480990b41254", - "itemType" : "event", - "scope" : "realEstateManager", - "version" : 1, - "eventType" : "form", - "sessionId" : "aaad09aa-88c2-67bd-b106-5a47ded43ead", - "profileId" : "48563fd0-6319-4260-8dba-ae421beba26f", - "timeStamp" : "2018-11-23T16:32:26Z", - "properties" : { - "firstName" : "John", - "lastName" : "Doe", - "email" : "[email protected]", - "submitButton" : "Submit" - }, - "source" : { - "itemId" : "/tracker/", - "itemType" : "page", - "scope" : "realEstateManager", - "version" : null, - "properties" : { - "pageInfo" : { - "destinationURL" : "http://localhost:8181/tracker/?firstName=Bill&lastName=Gates&email=bgates%40microsoft.com", - "pageID" : "/tracker/", - "pagePath" : "/tracker/", - "pageName" : "Apache Unomi Web Tracker Test Page", - "referringURL" : "http://localhost:8181/tracker/?firstName=John&lastName=Doe&email=johndoe%40acme.com" - }, - "attributes" : [ ], - "consentTypes" : [ ], - "interests" : { } - } - }, - "target" : { - "itemId" : "testFormTracking", - "itemType" : "form", - "scope" : "realEstateManager", - "version" : null, - "properties" : { } - }, - "persistent" : true -}</code></pre> -</div> -</div> -<div class="paragraph"> -<p>You can see in this event that the form values are sent as properties of the event itself, while the form name is sent -as the <code>target.itemId</code></p> -</div> -<div class="paragraph"> -<p>While setting up form tracking, it can be very useful to use the Apache Unomi Karaf SSH shell commands : <code>event-tail</code> -and <code>event-view</code> to check if you are properly receiving the form submission events and that they contain the expected -data. If not, check your tracking code for any errors.</p> -</div> -<div class="paragraph"> -<p>Now that the data is properly sent using an event to Apache Unomi, we must still use it to perform some kind of actions. -Using rules, we could do anything from updating the profile to sending the data to a third-party server (using a custom- -developped action of course). In this example we will illustrate how to update the profile.</p> -</div> -<div class="paragraph"> -<p>In order to do so we will deploy a rule that will copy data coming from the event into a profile. But we will need to -map the form field names to profile names, and this can be done using the <code>setPropertyAction</code> that’s available out of the -box in the Apache Unomi server.</p> -</div> -<div class="paragraph"> -<p>There are two ways to register rules : either by building a custom OSGi bundle plugin or using the REST API to directly -send a JSON representation of the rule to be saved. We will in this example use the CURL shell command to make a call to -the REST API.</p> -</div> -<div class="listingblock"> -<div class="content"> -<pre class="highlight"><code>curl -X POST -k -u karaf:karaf https://localhost:9443/cxs/rules \ - --header "Content-Type: application/json" \ --d @- << EOF -{ - "itemId": "form-mapping-example", - "itemType": "rule", - "linkedItems": null, - "raiseEventOnlyOnceForProfile": false, - "raiseEventOnlyOnceForSession": false, - "priority": -1, - "metadata": { - "id": "form-mapping-example", - "name": "Example Form Mapping", - "description": "An example of how to map event properties to profile properties", - "scope": "realEstateManager", - "tags": [], - "enabled": true, - "missingPlugins": false, - "hidden": false, - "readOnly": false - }, - "condition": { - "type": "formEventCondition", - "parameterValues": { - "formId": "testFormTracking", - "pagePath" : "/tracker/" - } - }, - "actions": [ - { - "type": "setPropertyAction", - "parameterValues": { - "setPropertyName": "properties(firstName)", - "setPropertyValue": "eventProperty::properties(firstName)", - "setPropertyStrategy": "alwaysSet" - } - }, - { - "type": "setPropertyAction", - "parameterValues": { - "setPropertyName": "properties(lastName)", - "setPropertyValue": "eventProperty::properties(lastName)", - "setPropertyStrategy": "alwaysSet" - } - }, - { - "type": "setPropertyAction", - "parameterValues": { - "setPropertyName": "properties(email)", - "setPropertyValue": "eventProperty::properties(email)", - "setPropertyStrategy": "alwaysSet" - } - } - ] -} -EOF</code></pre> -</div> -</div> -<div class="paragraph"> -<p>As you can see in this request, we have a few parameters that need explaining:</p> -</div> -<div class="ulist"> -<ul> -<li> -<p><code>-k</code> is used to accept any certificate as we are in this example using a default Apache Unomi server configuration that -comes with its predefined HTTPS certificates</p> -</li> -<li> -<p><code>-u karaf:karaf</code> is the default username/password for authenticating to the REST API. To change this value you should -edit the `etc/users.properties`file and it is required to modify this login before going to production.</p> -</li> -</ul> -</div> -<div class="paragraph"> -<p>Finally the rule itself should be pretty self-explanatory but there are a few important things to note :</p> -</div> -<div class="ulist"> -<ul> -<li> -<p>the <code>itemId</code> and <code>metadata.id</code> values should be the same</p> -</li> -<li> -<p>the <code>scope</code> should be the same as the scope that was setup in the tracker initialization</p> -</li> -<li> -<p>the <code>formId</code> parameter must have the form name value</p> -</li> -<li> -<p>the <code>pagePath</code> should be the pagePath passed through the event (if you’re not sure of its value, you could either using -network debugging in the browser or use the <code>event-tail</code> and <code>event-view</code> commands in the Apache Unomi Karaf SSH shell).</p> -</li> -<li> -<p>the setPropertyAction may be repeated as many times as desired to copy the values from the event to the profile. Note that -the <code>setPropertyName</code> will define the property to set on the profile and the <code>setPropertyValue</code> will define where the -value is coming from. In this example the name and the value are the same but that is no way a requirement. It could -even be possible to using multiple <code>setPropertyAction</code> instances to copy the same event property into different profile -properties.</p> -</li> -</ul> -</div> -<div class="paragraph"> -<p>To check if your rule is properly deployed you can use the following SSH shell command :</p> -</div> -<div class="paragraph"> -<p><code>unomi:rule-view form-mapping-example</code></p> -</div> -<div class="paragraph"> -<p>The parameter is the <code>itemId</code> of the rule. If you want to see all the rules deployed in the system you can use the -command :</p> -</div> -<div class="paragraph"> -<p><code>unomi:rule-list 1000</code></p> -</div> -<div class="paragraph"> -<p>The <code>1000</code> parameter is the limit of number of objects to retrieve. As the number of rules can grow quickly in an Apache -Unomi instance, it is recommended to put this value a bit high to make sure you get the full list of rules.</p> -</div> -<div class="paragraph"> -<p>Once the rule is in place, try submitting the form with some values and check that the profile is properly updated. One -recommend way of doing this is to use the <code>event-tail</code> command that will output something like this :</p> -</div> -<div class="listingblock"> -<div class="content"> -<pre class="highlight"><code>ID |Type |Session |Profile |Timestamp |Scope |Persi| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -cef09b89-6b99-4e4f-a99c-a4159a66b42b|form |aaad09aa-88c2-67bd-b106-5a47ded43ead|48563fd0-6319-4260-8dba-ae421beba26f|Fri Nov 23 17:52:33 CET 2018 |realEstateManag|true |</code></pre> -</div> -</div> -<div class="paragraph"> -<p>You can directly see the profile that is being used, so you can then simply use the</p> -</div> -<div class="paragraph"> -<p><code>unomi:profile-view 48563fd0-6319-4260-8dba-ae421beba26f</code></p> -</div> -<div class="paragraph"> -<p>command to see a JSON dump of the profile and check that the form values have been properly positioned.</p> -</div> -</div> -</div> </div> </div> <div class="sect1"> @@ -2085,7 +1648,7 @@ org.apache.unomi.security.personalizatio <p>Placed right before the function, the â@Actionâ annotation contains a set of parameter detailing how the action should be triggered.</p> </div> <table class="tableblock frame-all grid-all stretch"> -<caption class="title">Table 2. @Action annotation</caption> +<caption class="title">Table 1. @Action annotation</caption> <colgroup> <col style="width: 25%;"> <col style="width: 25%;"> @@ -2622,15 +2185,562 @@ of the ElasticSearch server(s). But if y </div> </div> <div class="sect1"> -<h2 id="_migrations">4. Migrations</h2> +<h2 id="_json_schemas">4. JSON schemas</h2> +<div class="sectionbody"> +<div class="sect2"> +<h3 id="_introduction_2">4.1. Introduction</h3> +<div class="sect3"> +<h4 id="_what_is_a_json_schema">4.1.1. What is a JSON Schema</h4> +<div class="paragraph"> +<p><a href="https://json-schema.org/specification.html">JSON Schema</a> is a powerful standard for validating the structure of JSON data. +Described as a JSON object, a JSON schema file contains format, types, patterns, and more. +Used against JSON data, a JSON schema validates that the data is compatible with the specified schema.</p> +</div> +<div class="paragraph"> +<p>Example of a basic JSON schema that validates that the path property is a string property:</p> +</div> +<div class="listingblock"> +<div class="content"> +<pre class="highlight"><code>{ + "$id":"https://unomi.apache.org/schemas/json/example/1-0-0", + "$schema":"https://json-schema.org/draft/2019-09/schema", + "title":"Example of a basic schema", + "type":"object", + "properties":{ + "path":{ + "type":"string", + "$comment":"Example of a property." + } + } +}</code></pre> +</div> +</div> +<div class="listingblock"> +<div class="content"> +<pre class="highlight"><code>{ + "path": "example/of/path" //Is valid +}</code></pre> +</div> +</div> +<div class="listingblock"> +<div class="content"> +<pre class="highlight"><code>{ + "path": 100 // Is not valid +}</code></pre> +</div> +</div> +<div class="paragraph"> +<p>Apache Unomi is using json-schema-validator to integrate JSON schema. +The library and its source code is available at: <a href="https://github.com/networknt/json-schema-validator">https://github.com/networknt/json-schema-validator</a>, you can refer to the featureâs pom.xml available at <a href="https://github.com/apache/unomi/blob/master/extensions/json-schema/services/pom.xml#L35">json-schema/service/pom.xml</a> to identify which version of the library is currently integrated.</p> +</div> +<div class="paragraph"> +<p>You can discover and play with JSON schema using online tools such as <a href="https://www.jsonschemavalidator.net/">JSON Schema Validator</a>. +Such tools allow you to validate a schema against JSON data (such as the example above), and can point to particular errors. +More details about JSON schema are available on the official specificationâs website: <a href="https://json-schema.org/specification.html">https://json-schema.org/specification.html</a></p> +</div> +</div> +<div class="sect3"> +<h4 id="_key_concepts">4.1.2. Key concepts</h4> +<div class="paragraph"> +<p>This section details concepts that are important to understand in order to use JSON schema validation with Apache Unomi.</p> +</div> +<div class="sect4"> +<h5 id="_id_keyword">$id keyword</h5> +<div class="paragraph"> +<p>The <strong>$id</strong> keyword:</p> +</div> +<div class="paragraph"> +<p>Each schema in Apache Unomi should have a <strong>$id</strong>, the <strong>$id</strong> value is an URI which will be used to retrieve the schema and must be unique.</p> +</div> +<div class="paragraph"> +<p>Example:</p> +</div> +<div class="listingblock"> +<div class="content"> +<pre class="highlight"><code>{ + "$id":"https://unomi.apache.org/schemas/json/example/1-0-0" +}</code></pre> +</div> +</div> +</div> +<div class="sect4"> +<h5 id="_ref_keyword">$ref keyword</h5> +<div class="paragraph"> +<p>The <strong>$ref</strong> keyword allows you to reference another JSON schema by its <strong>$id</strong> keyword. +Itâs possible to separate complex structures or repetitive parts of schema into other small files and use <strong>$ref</strong> to include them into several json schemas.</p> +</div> +<div class="paragraph"> +<p>Example with a person and an address:</p> +</div> +<div class="listingblock"> +<div class="content"> +<pre class="highlight"><code>{ + "$id": "https://example.com/schemas/address", + "type": "object", + "properties": { + "street_address": { "type": "string" }, + "city": { "type": "string" }, + "state": { "type": "string" } + } +}</code></pre> +</div> +</div> +<div class="listingblock"> +<div class="content"> +<pre class="highlight"><code>{ + "type": "object", + "properties": { + "first_name":{ "type": "string" }, + "last_name": { "type": "string" }, + "shipping_address": { + "$ref": "https://example.com/schemas/address" + }, + "billing_address": { + "$ref": "https://example.com/schemas/address" + } + } +}</code></pre> +</div> +</div> +<div class="paragraph"> +<p>More details about <strong>$ref</strong> can be found in the specifications: <a href="https://json-schema.org/understanding-json-schema/structuring.html#ref">https://json-schema.org/understanding-json-schema/structuring.html#ref</a></p> +</div> +</div> +<div class="sect4"> +<h5 id="_allof_keyword">allOf keyword</h5> +<div class="paragraph"> +<p>The allOf keyword is an array of fields which allows schema composition. +The data will be valid against a schema if the data are valid against all of the given subschemas in the allOf part and are valid against the properties defined in the schema.</p> +</div> +<div class="listingblock"> +<div class="content"> +<pre class="highlight"><code>{ + "$id": "https://unomi.apache.org/schemas/json/example/1-0-0", + "$schema": "https://json-schema.org/draft/2019-09/schema", + "type": "object", + "allOf": [ + { + "type": "object", + "properties": { + "fromAllOf": { + "type": "integer", + "$comment": "Example of allOf." + } + } + } + ], + "properties": { + "myProperty": { + "type": "string", + "$comment": "Example of a property." + } + } +}</code></pre> +</div> +</div> +<div class="paragraph"> +<p>Valid JSON:</p> +</div> +<div class="listingblock"> +<div class="content"> +<pre class="highlight"><code>{ + "myProperty": "My property", + "fromAllOf" : 10 +}</code></pre> +</div> +</div> +<div class="paragraph"> +<p>Invalid JSON:</p> +</div> +<div class="listingblock"> +<div class="content"> +<pre class="highlight"><code>{ + "myProperty": "My property", + "fromAllOf" : "My value" +}</code></pre> +</div> +</div> +<div class="paragraph"> +<p>Itâs also possible to use a reference <strong>$ref</strong> in the <strong>allOf</strong> keyword to reference another schema.</p> +</div> +<div class="paragraph"> +<p>In Unomi, there is an example of using <strong>$ref</strong> in the <strong>allOf</strong> keyword to validate the properties which are defined in the event schema. +This schema contains properties common to all events. +Itâs done in the the view event schema. +The file can be found on github: <a href="https://github.com/apache/unomi/blob/master/extensions/json-schema/services/src/main/resources/META-INF/cxs/schemas/events/view/view.json#L13">view.json</a> +More details about allOf can be found in the specifications: <a href="https://json-schema.org/understanding-json-schema/reference/combining.html#allof">https://json-schema.org/understanding-json-schema/reference/combining.html#allof</a></p> +</div> +</div> +<div class="sect4"> +<h5 id="_unevaluatedproperties_keyword">unevaluatedProperties keyword</h5> +<div class="paragraph"> +<p>The <strong>unevaluatedProperties</strong> keyword is useful for schema composition as well as enforcing stricter schemas. +This keyword is similar to <strong>additionalProperties</strong> except that it can recognize properties declared in sub schemas. +When setting the <strong>unevaluatedProperties</strong> value to <strong>false</strong>, the properties which are not present in the properties part and are not present in the sub schemas will be considered as invalid.</p> +</div> +<div class="paragraph"> +<p>Example with the following schema:</p> +</div> +<div class="listingblock"> +<div class="content"> +<pre class="highlight"><code>{ + "$id": "https://unomi.apache.org/schemas/json/example/1-0-0", + "$schema": "https://json-schema.org/draft/2019-09/schema", + "type": "object", + "allOf": [ + { + "$ref": "https://unomi.apache.org/schemas/json/subschema/1-0-0" + } + ], + "properties": { + "myProperty": { + "type": "string", + "$comment": "Example of a property." + } + }, + "unevaluatedProperties": false +}</code></pre> +</div> +</div> +<div class="paragraph"> +<p>Sub schema:</p> +</div> +<div class="listingblock"> +<div class="content"> +<pre class="highlight"><code>{ + "$id": "https://unomi.apache.org/schemas/json/subschema/1-0-0", + "$schema": "https://json-schema.org/draft/2019-09/schema", + "type": "object", + "properties": { + "fromAllOf": { + "type": "string", + "$comment": "Example of allOf." + } + } +}</code></pre> +</div> +</div> +<div class="paragraph"> +<p>With the following data, the validation will fail because the property <strong>myNewProperty</strong> is not defined neither the <strong>properties</strong> part nor the <strong>allOf</strong> part.</p> +</div> +<div class="listingblock"> +<div class="content"> +<pre class="highlight"><code>{ + "myProperty": "My property", + "fromAllOf" : 10, + "myNewProperty": "another one" //Not valid +}</code></pre> +</div> +</div> +</div> +</div> +<div class="sect3"> +<h4 id="_how_are_json_schema_used_in_unomi">4.1.3. How are JSON Schema used in Unomi</h4> +<div class="paragraph"> +<p>JSON Schema is used in Unomi to validate the data coming from the two public endpoints <strong>/contextRequest</strong> and <strong>/eventCollector</strong>. +Both endpoints have a custom deserializer which will begin by validating the payload of the request, then will filter invalid events present in this payload. +If an event is not valid it will not be processed by the system. +The internal events are not validated by JSON schema as they are not sent through the public endpoints.</p> +</div> +<div class="paragraph"> +<p>In Unomi, each event type must have an associated JSON schema. +To validate an event, Unomi will search for a schema in which the target of the schema is <strong>events</strong>, and with the name of the schema matching the event type.</p> +</div> +<div class="paragraph"> +<p>A custom keyword named <strong>self</strong> has to be present in the JSON schemas to store the information related to each schema. +The following example is the <strong>self</strong> part of the view event JSON schema. +Having the target set to <strong>events</strong> and the name set to <strong>view</strong>, this schema will be used to validate the events of type <strong>view</strong>.</p> +</div> +<div class="listingblock"> +<div class="content"> +<pre class="highlight"><code>⦠+"self":{ + "vendor":"org.apache.unomi", + "target" : "events", + "name": "view", + "format":"jsonschema", + "version":"1-0-0" +}, +â¦</code></pre> +</div> +</div> +<div class="paragraph"> +<p>Link to the schema on github: <a href="https://github.com/apache/unomi/blob/master/extensions/json-schema/services/src/main/resources/META-INF/cxs/schemas/events/view/view.json">view.json</a>.</p> +</div> +<div class="paragraph"> +<p>A set of predefined schema are present in Unomi, these schemas can be found under the folder : <a href="https://github.com/apache/unomi/tree/master/extensions/json-schema/services/src/main/resources/META-INF/cxs/schemas">extensions/json-schema/services/src/main/resources/META-INF/cxs/schemas</a>.</p> +</div> +<div class="paragraph"> +<p>These schemas will be loaded in memory at startup. +Each schema where the <strong>target</strong> value is set to <strong>events</strong>, will be used to validate events. +The others are simply used as part of JSON schema or can be used in additional JSON schemas.</p> +</div> +<div class="paragraph"> +<p>Itâs possible to add JSON schemas to validate your own event by using the API, the explanations to manage JSON schema through the API are +in the <a href="#_create_update_a_json_schema_to_validate_an_event">Create / update a JSON schema to validate an event</a> section.</p> +</div> +<div class="paragraph"> +<p>Contrary to the predefined schemas, the schemas added through the API will be persisted in Elasticsearch in the jsonSchema index. +Schemas persisted in Elasticsearch do not require a restart of the platform to reflect changes.</p> +</div> +<div class="paragraph"> +<p>Process of creation of schemas:</p> +</div> +<div class="imageblock text-center"> +<div class="content"> +<img src="images/process-creation-schema.png" alt="process creation schema"> +</div> +</div> +</div> +</div> +<div class="sect2"> +<h3 id="_json_schema_api">4.2. JSON schema API</h3> +<div class="paragraph"> +<p>The JSON schema endpoints are private, so the user has to be authenticated to manage the JSON schema in Unomi.</p> +</div> +<div class="sect3"> +<h4 id="_list_existing_schemas">4.2.1. List existing schemas</h4> +<div class="paragraph"> +<p>The REST endpoint GET <code>{{url}}/cxs/jsonSchema</code> allows to get all ids of available schemas and subschemas.</p> +</div> +<div class="paragraph"> +<p>List of predefined schemas:</p> +</div> +<div class="listingblock"> +<div class="content"> +<pre class="highlight"><code>[ + "https://unomi.apache.org/schemas/json/events/modifyConsent/properties/1-0-0", + "https://unomi.apache.org/schemas/json/item/1-0-0", + "https://unomi.apache.org/schemas/json/events/login/1-0-0", + "https://unomi.apache.org/schemas/json/events/modifyConsent/1-0-0", + "https://unomi.apache.org/schemas/json/consentType/1-0-0", + "https://unomi.apache.org/schemas/json/items/page/properties/1-0-0", + "https://unomi.apache.org/schemas/json/items/page/properties/attributes/1-0-0", + "https://unomi.apache.org/schemas/json/events/incrementInterest/1-0-0", + "https://unomi.apache.org/schemas/json/events/view/flattenProperties/1-0-0", + "https://unomi.apache.org/schemas/json/interests/1-0-0", + "https://unomi.apache.org/schemas/json/items/site/1-0-0", + "https://unomi.apache.org/schemas/json/items/page/properties/pageInfo/1-0-0", + "https://unomi.apache.org/schemas/json/rest/requestIds/1-0-0", + "https://unomi.apache.org/schemas/json/rest/eventscollectorrequest/1-0-0", + "https://unomi.apache.org/schemas/json/events/view/properties/1-0-0", + "https://unomi.apache.org/schemas/json/items/page/1-0-0", + "https://unomi.apache.org/schemas/json/URLParameters/1-0-0", + "https://unomi.apache.org/schemas/json/event/1-0-0", + "https://unomi.apache.org/schemas/json/timestampeditem/1-0-0", + "https://unomi.apache.org/schemas/json/events/updateProperties/1-0-0", + "https://unomi.apache.org/schemas/json/consent/1-0-0", + "https://unomi.apache.org/schemas/json/events/incrementInterest/flattenProperties/1-0-0", + "https://unomi.apache.org/schemas/json/events/view/1-0-0" +]</code></pre> +</div> +</div> +<div class="paragraph"> +<p>Custom schemas will also be present in this list once added.</p> +</div> +</div> +<div class="sect3"> +<h4 id="_read_a_schema">4.2.2. Read a schema</h4> +<div class="paragraph"> +<p>Itâs possible to get a schema by its id by calling the endpoint <code>POST {{url}}/cxs/jsonSchema/query</code> with the id of the schema in the payload of the query.</p> +</div> +<div class="paragraph"> +<p>Example:</p> +</div> +<div class="listingblock"> +<div class="content"> +<pre class="highlight"><code>curl --location --request POST 'http://localhost:8181/cxs/jsonSchema/query' \ +-u 'karaf:karaf' +--header 'Content-Type: text/plain' \ +--header 'Cookie: context-profile-id=0f2fbca8-c242-4e6d-a439-d65fcbf0f0a8' \ +--data-raw 'https://unomi.apache.org/schemas/json/event/1-0-0'</code></pre> +</div> +</div> +</div> +<div class="sect3"> +<h4 id="_create_update_a_json_schema_to_validate_an_event">4.2.3. Create / update a JSON schema to validate an event</h4> +<div class="paragraph"> +<p>Itâs possible to add or update JSON schema by calling the endpoint <code>POST {{url}}/cxs/jsonSchema</code> with the JSON schema in the payload of the request. +If the JSON schema exists it will be updated with the new one.</p> +</div> +<div class="paragraph"> +<p>Example of creation:</p> +</div> +<div class="listingblock"> +<div class="content"> +<pre class="highlight"><code>curl --location --request POST 'http://localhost:8181/cxs/jsonSchema' \ +-u 'karaf:karaf' \ +--header 'Content-Type: application/json' \ +--header 'Cookie: context-profile-id=0f2fbca8-c242-4e6d-a439-d65fcbf0f0a8' \ +--data-raw '{ + "$id": "https://vendor.test.com/schemas/json/events/dummy/1-0-0", + "$schema": "https://json-schema.org/draft/2019-09/schema", + "self": { + "vendor": "com.vendor.test", + "name": "dummy", + "format": "jsonschema", + "target": "events", + "version": "1-0-0" + }, + "title": "DummyEvent", + "type": "object", + "allOf": [ + { + "$ref": "https://unomi.apache.org/schemas/json/event/1-0-0" + } + ], + "properties": { + "properties": { + "$ref": "https://vendor.test.com/schemas/json/events/dummy/properties/1-0-0" + } + }, + "unevaluatedProperties": false +}'</code></pre> +</div> +</div> +</div> +<div class="sect3"> +<h4 id="_deleting_a_schema">4.2.4. Deleting a schema</h4> +<div class="paragraph"> +<p>To delete a schema, call the endpoint <code>POST {{url}}/cxs/jsonSchema/delete</code> with the id of the schema into the payload of the request</p> +</div> +<div class="paragraph"> +<p>Example:</p> +</div> +<div class="listingblock"> +<div class="content"> +<pre class="highlight"><code>curl --location --request POST 'http://localhost:8181/cxs/jsonSchema/delete' \ +-u 'karaf:karaf' \ +--header 'Content-Type: text/plain' \ +--header 'Cookie: context-profile-id=0f2fbca8-c242-4e6d-a439-d65fcbf0f0a8' \ +--data-raw 'https://vendor.test.com/schemas/json/events/dummy/1-0-0'</code></pre> +</div> +</div> +</div> +<div class="sect3"> +<h4 id="_error_management">4.2.5. Error Management</h4> +<div class="paragraph"> +<p>When calling an endpoint with invalid data, such as an invalid value for the <strong>sessionId</strong> property in the contextRequest object or eventCollectorRequest object, the server would respond with a 400 error code and the message <strong>Request rejected by the server because: Invalid received data</strong>.</p> +</div> +</div> +<div class="sect3"> +<h4 id="_details_on_invalid_events">4.2.6. Details on invalid events</h4> +<div class="paragraph"> +<p>If itâs an event which is incorrect the server will continue to process the request but will exclude the invalid events. +Running Apache Unomi with the logs in debug level will add to the logs the reason why events are rejected. +You can set the log level of the class validating the events to debug by using the following karaf command:</p> +</div> +<div class="listingblock"> +<div class="content"> +<pre class="highlight"><code>log:set DEBUG org.apache.unomi.schema.impl.SchemaServiceImpl</code></pre> +</div> +</div> +</div> +</div> +<div class="sect2"> +<h3 id="_extend_an_existing_schema">4.3. Extend an existing schema</h3> +<div class="sect3"> +<h4 id="_when_a_extension_is_needed">4.3.1. When a extension is needed?</h4> +<div class="paragraph"> +<p>Apache Unomi provides predefined schemas to validate some known events such as a view event.</p> +</div> +<div class="paragraph"> +<p>The Apache Unomi JSON schemas are designed to consider invalid any properties which are not defined in the JSON schema. +So if an unknown property is part of the event, the event will be considered as invalid.</p> +</div> +<div class="paragraph"> +<p>This means that if your events include additional properties, you will need extensions to describe these.</p> +</div> +</div> +<div class="sect3"> +<h4 id="_understanding_how_extensions_are_merged_in_unomi">4.3.2. Understanding how extensions are merged in unomi</h4> +<div class="paragraph"> +<p>An extension schema is a JSON schema whose id will be overridden and be defined by a keyword named <strong>extends</strong> in the <strong>self</strong> part of the extension.</p> +</div> +<div class="paragraph"> +<p>When sending an extension through the API, it will be persisted in Elasticsearch then will be merged to the targeted schema.</p> +</div> +<div class="paragraph"> +<p>What does âmerge a schemaâ mean? +The merge will simply add in the <strong>allOf</strong> keyword of the targeted schema a reference to the extensions. +It means that to be valid, an event should be valid against the base schema and against the ones added in the <strong>allOf</strong>.</p> +</div> +<div class="paragraph"> +<p>Example of an extension to allow to add a new property in the view event properties:</p> +</div> +<div class="listingblock"> +<div class="content"> +<pre class="highlight"><code>{ + "$id": "https://vendor.test.com/schemas/json/events/dummy/extension/1-0-0", + "$schema": "https://json-schema.org/draft/2019-09/schema", + "self":{ + "vendor":"com.vendor.test", + "name":"dummyExtension", + "format":"jsonschema", + "extends": "https://unomi.apache.org/schemas/json/events/view/properties/1-0-0", + "version":"1-0-0" + }, + "title": "DummyEventExtension", + "type": "object", + "properties": { + "myNewProp": { + "type": "string" + } + } +}</code></pre> +</div> +</div> +<div class="paragraph"> +<p>When validating the events of type view, the extension will be added to the schema with the id <strong>https://unomi.apache.org/schemas/json/events/view/properties/1-0-0</strong> like the following:</p> +</div> +<div class="listingblock"> +<div class="content"> +<pre class="highlight"><code>"allOf": [{ + "$ref": "https://vendor.test.com/schemas/json/events/dummy/extension/1-0-0" +}]</code></pre> +</div> +</div> +<div class="paragraph"> +<p>With this extension the property <strong>myNewProp</strong> can now be added to the event.</p> +</div> +<div class="listingblock"> +<div class="content"> +<pre class="highlight"><code>⦠+"properties": { + "myNewProp" : "newValue" +}, +â¦</code></pre> +</div> +</div> +<div class="paragraph"> +<p>Process when adding extension:</p> +</div> +<div class="imageblock text-center"> +<div class="content"> +<img src="images/process-creation-extension.png" alt="process creation extension"> +</div> +</div> +</div> +<div class="sect3"> +<h4 id="_how_to_add_an_extension_through_the_api">4.3.3. How to add an extension through the API</h4> +<div class="paragraph"> +<p>Since an extension is also a JSON schema, it is possible to add extensions by calling the endpoint to add a JSON schema. +By calling <code>POST {{url}}/cxs/jsonSchema</code> with the JSON schema in the payload of the request, the extension will be persisted and will be merged to the targeted schema.</p> +</div> +</div> +</div> +</div> +</div> +<div class="sect1"> +<h2 id="_migrations">5. Migrations</h2> <div class="sectionbody"> <div class="paragraph"> <p>This section contains information and steps to migrate between major Unomi versions.</p> </div> <div class="sect2"> -<h3 id="_from_version_1_4_to_1_5">4.1. From version 1.4 to 1.5</h3> +<h3 id="_from_version_1_4_to_1_5">5.1. From version 1.4 to 1.5</h3> <div class="sect3"> -<h4 id="_data_model_and_elasticsearch_7">4.1.1. Data model and ElasticSearch 7</h4> +<h4 id="_data_model_and_elasticsearch_7">5.1.1. Data model and ElasticSearch 7</h4> <div class="paragraph"> <p>Since Apache Unomi version 1.5.0 we decided to upgrade the supported ElasticSearch version to the latest 7.4.2.</p> </div> @@ -2645,7 +2755,7 @@ of the ElasticSearch server(s). But if y </div> </div> <div class="sect3"> -<h4 id="_api_changes">4.1.2. API changes</h4> +<h4 id="_api_changes">5.1.2. API changes</h4> <div class="paragraph"> <p>To be able to handle the multiple indices the Persistence API implementation (<a href="https://github.com/apache/unomi/blob/9f1bab437fd93826dc54d318ed00d3b2e3161437/persistence-elasticsearch/core/src/main/java/org/apache/unomi/persistence/elasticsearch/ElasticSearchPersistenceServiceImpl.java">ElasticSearchPersistenceServiceImpl</a>) @@ -2685,7 +2795,7 @@ Previously named: <code>geonames</code> </div> </div> <div class="sect3"> -<h4 id="_migration_steps">4.1.3. Migration steps</h4> +<h4 id="_migration_steps">5.1.3. Migration steps</h4> <div class="paragraph"> <p>In order to migrate the data from ElasticSearch 5 to 7, Unomi provides a migration tool that is directly integrated.</p> </div> @@ -2816,7 +2926,7 @@ the profiles:</p> </div> </div> <div class="sect2"> -<h3 id="_important_changes_in_public_servlets_since_version_1_5_5_and_2_0_0">4.2. Important changes in public servlets since version 1.5.5 and 2.0.0</h3> +<h3 id="_important_changes_in_public_servlets_since_version_1_5_5_and_2_0_0">5.2. Important changes in public servlets since version 1.5.5 and 2.0.0</h3> <div class="paragraph"> <p>What used to be dedicated servlets are now part of the REST endpoints. Prior to version 1.5.5 the following servlets were used:</p> @@ -2858,7 +2968,7 @@ to update your client applications.</p> </div> </div> <div class="sect1"> -<h2 id="_queries_and_aggregations">5. Queries and aggregations</h2> +<h2 id="_queries_and_aggregations">6. Queries and aggregations</h2> <div class="sectionbody"> <div class="paragraph"> <p>Apache Unomi contains a <code>query</code> endpoint that is quite powerful. It provides ways to perform queries that can quickly @@ -2868,7 +2978,7 @@ get result counts, apply metrics such as <p>In this section we will show examples of requests that may be built using this API.</p> </div> <div class="sect2"> -<h3 id="_query_counts">5.1. Query counts</h3> +<h3 id="_query_counts">6.1. Query counts</h3> <div class="paragraph"> <p>Query counts are highly optimized queries that will count the number of objects that match a certain condition without retrieving the results. This can be used for example to quickly figure out how many objects will match a given condition @@ -2923,7 +3033,7 @@ EOF</code></pre> </div> </div> <div class="sect2"> -<h3 id="_metrics">5.2. Metrics</h3> +<h3 id="_metrics">6.2. Metrics</h3> <div class="paragraph"> <p>Metric queries make it possible to apply functions to the resulting property. The supported metrics are:</p> </div> @@ -2985,7 +3095,7 @@ EOF</code></pre> </div> </div> <div class="sect2"> -<h3 id="_aggregations">5.3. Aggregations</h3> +<h3 id="_aggregations">6.3. Aggregations</h3> <div class="paragraph"> <p>Aggregations are a very powerful way to build queries in Apache Unomi that will collect and aggregate data by filtering on certain conditions.</p> @@ -2997,7 +3107,7 @@ on certain conditions.</p> - a condition (used to filter the data set that will be aggregated)</p> </div> <div class="sect3"> -<h4 id="_aggregation_types">5.3.1. Aggregation types</h4> +<h4 id="_aggregation_types">6.3.1. Aggregation types</h4> <div class="paragraph"> <p>Aggregations may be of different types. They are listed here below.</p> </div> @@ -3235,14 +3345,14 @@ EOF</code></pre> </div> </div> <div class="sect1"> -<h2 id="_profile_import_export">6. Profile import & export</h2> +<h2 id="_profile_import_export">7. Profile import & export</h2> <div class="sectionbody"> <div class="paragraph"> <p>The profile import and export feature in Apache Unomi is based on configurations and consumes or produces CSV files that contain profiles to be imported and exported.</p> </div> <div class="sect2"> -<h3 id="_importing_profiles">6.1. Importing profiles</h3> +<h3 id="_importing_profiles">7.1. Importing profiles</h3> <div class="paragraph"> <p>Only <code>ftp</code>, <code>sftp</code>, <code>ftps</code> and <code>file</code> are supported in the source path. For example:</p> </div> @@ -3302,7 +3412,7 @@ ftps://USER@HOST?password=PASSWORD&f </ul> </div> <div class="sect3"> -<h4 id="_import_api">6.1.1. Import API</h4> +<h4 id="_import_api">7.1.1. Import API</h4> <div class="paragraph"> <p>Apache Unomi provides REST endpoints to manage import configurations:</p> </div> @@ -3377,7 +3487,7 @@ ftps://USER@HOST?password=PASSWORD&f </div> </div> <div class="sect2"> -<h3 id="_exporting_profiles">6.2. Exporting profiles</h3> +<h3 id="_exporting_profiles">7.2. Exporting profiles</h3> <div class="paragraph"> <p>Only <code>ftp</code>, <code>sftp</code>, <code>ftps</code> and `file are supported in the source path. For example:</p> </div> @@ -3398,7 +3508,7 @@ per file.</p> <p>See <a href="http://camel.apache.org/ftp.html and http://camel.apache.org/file2.html to" class="bare">http://camel.apache.org/ftp.html and http://camel.apache.org/file2.html to</a> build more complex destination path.</p> </div> <div class="sect3"> -<h4 id="_export_api">6.2.1. Export API</h4> +<h4 id="_export_api">7.2.1. Export API</h4> <div class="paragraph"> <p>Apache Unomi provides REST endpoints to manage export configurations:</p> </div> @@ -3466,7 +3576,7 @@ per file.</p> </div> </div> <div class="sect2"> -<h3 id="_configuration_in_details">6.3. Configuration in details</h3> +<h3 id="_configuration_in_details">7.3. Configuration in details</h3> <div class="paragraph"> <p>First configuration you need to change would be the configuration type of your import / export feature (code name router) in the <code>etc/unomi.custom.system.properties</code> file (creating it if necessary):</p> @@ -3560,17 +3670,17 @@ org.apache.unomi.router.config.allowedEn </div> </div> <div class="sect1"> -<h2 id="_consent_management">7. Consent management</h2> +<h2 id="_consent_management">8. Consent management</h2> <div class="sectionbody"> <div class="sect2"> -<h3 id="_consent_api">7.1. Consent API</h3> +<h3 id="_consent_api">8.1. Consent API</h3> <div class="paragraph"> <p>Starting with Apache Unomi 1.3, a new API for consent management is now available. This API is designed to be able to store/retrieve/update visitor consents in order to comply with new privacy regulations such as the <a href="https://en.wikipedia.org/wiki/General_Data_Protection_Regulation">GDPR</a>.</p> </div> <div class="sect3"> -<h4 id="_profiles_with_consents">7.1.1. Profiles with consents</h4> +<h4 id="_profiles_with_consents">8.1.1. Profiles with consents</h4> <div class="paragraph"> <p>Visitor profiles now contain a new Consent object that contains the following information:</p> </div> @@ -3645,7 +3755,7 @@ EOF</code></pre> </div> </div> <div class="sect3"> -<h4 id="_consent_type_definitions">7.1.2. Consent type definitions</h4> +<h4 id="_consent_type_definitions">8.1.2. Consent type definitions</h4> <div class="paragraph"> <p>Apache Unomi does not manage consent definitions, it leaves that to an external system (for example a CMS) so that it can handle user-facing UIs to create, update, internationalize and present consent definitions to end users.</p> @@ -3656,7 +3766,7 @@ consent type.</p> </div> </div> <div class="sect3"> -<h4 id="_creating_update_a_visitor_consent">7.1.3. Creating / update a visitor consent</h4> +<h4 id="_creating_update_a_visitor_consent">8.1.3. Creating / update a visitor consent</h4> <div class="paragraph"> <p>A new built-in event type called "modifyConsent" can be sent to Apache Unomi to update a consent for the current profile.</p> @@ -3739,7 +3849,7 @@ EOF</code></pre> </div> </div> <div class="sect3"> -<h4 id="_how_it_works_internally">7.1.4. How it works (internally)</h4> +<h4 id="_how_it_works_internally">8.1.4. How it works (internally)</h4> <div class="paragraph"> <p>Upon receiving this event, Apache Unomi will trigger the modifyAnyConsent rule that has the following definition:</p> </div> @@ -3782,14 +3892,14 @@ EOF</code></pre> </div> </div> <div class="sect1"> -<h2 id="_privacy_management">8. Privacy management</h2> +<h2 id="_privacy_management">9. Privacy management</h2> <div class="sectionbody"> <div class="paragraph"> <p>Apache Unomi provides an endpoint to manage visitor privacy. You will find in this section information about what it includes as well as how to use it.</p> </div> <div class="sect2"> -<h3 id="_setting_up_access_to_the_privacy_endpoint">8.1. Setting up access to the privacy endpoint</h3> +<h3 id="_setting_up_access_to_the_privacy_endpoint">9.1. Setting up access to the privacy endpoint</h3> <div class="paragraph"> <p>The privacy endpoint is a bit special, because despite being protected by basic authentication as the rest of the REST API is is actually designed to be available to end-users.</p> @@ -3815,7 +3925,7 @@ geographic location)</p> </div> </div> <div class="sect2"> -<h3 id="_anonymizing_a_profile">8.2. Anonymizing a profile</h3> +<h3 id="_anonymizing_a_profile">9.2. Anonymizing a profile</h3> <div class="paragraph"> <p>It is possible to anonymize a profile, meaning it will remove all "identifying" property values from the profile. Basically all properties with the tag <code>personalIdentifierProperties</code> will be purged from the profile.</p> @@ -3834,7 +3944,7 @@ and <code>ASCOPE</code> must be replaced </div> </div> <div class="sect2"> -<h3 id="_downloading_profile_data">8.3. Downloading profile data</h3> +<h3 id="_downloading_profile_data">9.3. Downloading profile data</h3> <div class="paragraph"> <p>It is possible to download the profile data of a user. This will only download the profile for a user using the specified ID as a cookie value.</p> @@ -3855,7 +3965,7 @@ IDs.</p> </div> </div> <div class="sect2"> -<h3 id="_deleting_a_profile">8.4. Deleting a profile</h3> +<h3 id="_deleting_a_profile">9.4. Deleting a profile</h3> <div class="paragraph"> <p>It is possible to delete a profile, but this works a little differently than you might expect. In all cases the data contained in the profile will be completely erased. If the <code>withData</code> optional flag is set to true, all past event and @@ -3872,7 +3982,7 @@ and the <code>withData</code> specifies </div> </div> <div class="sect2"> -<h3 id="_related">8.5. Related</h3> +<h3 id="_related">9.5. Related</h3> <div class="paragraph"> <p>You might also be interested in the <a href="#_consent_api">Consent API</a> section that describe how to manage profile consents.</p> </div> @@ -3880,10 +3990,10 @@ and the <code>withData</code> specifies </div> </div> <div class="sect1"> -<h2 id="_cluster_setup">9. Cluster setup</h2> +<h2 id="_cluster_setup">10. Cluster setup</h2> <div class="sectionbody"> <div class="sect2"> -<h3 id="_cluster_setup_2">9.1. Cluster setup</h3> +<h3 id="_cluster_setup_2">10.1. Cluster setup</h3> <div class="paragraph"> <p>Apache Karaf relies on Apache Karaf Cellar, which in turn uses Hazelcast to discover and configure its cluster.</p> </div> @@ -3924,10 +4034,10 @@ placeholders in the hazelcast.xml file i </div> </div> <div class="sect1"> -<h2 id="_reference">10. Reference</h2> +<h2 id="_reference">11. Reference</h2> <div class="sectionbody"> <div class="sect2"> -<h3 id="_useful_apache_unomi_urls">10.1. Useful Apache Unomi URLs</h3> +<h3 id="_useful_apache_unomi_urls">11.1. Useful Apache Unomi URLs</h3> <div class="paragraph"> <p>In this section we will list some useful URLs that can be used to quickly access parts of Apache Unomi that can help you understand or diagnose what is going on in the system.</p> @@ -3944,7 +4054,7 @@ results as the returned JSON is not beau <p>Important : all URLs are relative to the private Apache Unomi URL, by default: <a href="https://localhost:9443" class="bare">https://localhost:9443</a></p> </div> <table class="tableblock frame-all grid-all stretch"> -<caption class="title">Table 3. Useful URLs</caption> +<caption class="title">Table 2. Useful URLs</caption> <colgroup> <col style="width: 33.3333%;"> <col style="width: 33.3333%;"> @@ -4025,12 +4135,12 @@ where PROFILE_ID is a profile identifier </table> </div> <div class="sect2"> -<h3 id="_how_profile_tracking_works">10.2. How profile tracking works</h3> +<h3 id="_how_profile_tracking_works">11.2. How profile tracking works</h3> <div class="paragraph"> <p>In this section you will learn how Apache Unomi keeps track of visitors.</p> </div> <div class="sect3"> -<h4 id="_steps">10.2.1. Steps</h4> +<h4 id="_steps">11.2.1. Steps</h4> <div class="olist arabic"> <ol class="arabic"> <li> @@ -4070,7 +4180,7 @@ forcing.</p> </div> </div> <div class="sect2"> -<h3 id="_context_request_flow">10.3. Context Request Flow</h3> +<h3 id="_context_request_flow">11.3. Context Request Flow</h3> <div class="paragraph"> <p>Here is an overview of how Unomi processes incoming requests to the <code>ContextServlet</code>.</p> </div> @@ -4081,7 +4191,7 @@ forcing.</p> </div> </div> <div class="sect2"> -<h3 id="_data_model_overview">10.4. Data Model Overview</h3> +<h3 id="_data_model_overview">11.4. Data Model Overview</h3> <div class="paragraph"> <p>Apache Unomi gathers information about users actions, information that is processed and stored by Unomi services. The collected information can then be used to personalize content, derive insights on user behavior, categorize the @@ -4101,7 +4211,7 @@ There are other classes that are less ce </div> </div> <div class="sect2"> -<h3 id="_scope">10.5. Scope</h3> +<h3 id="_scope">11.5. Scope</h3> <div class="paragraph"> <p>Scopes are not actually an object in the system, but simply unique strings that are used to "classify" objects. For example, when using scopes with a web content management system, a scope could be associated with a site identifier or even a host name.</p> @@ -4114,7 +4224,7 @@ For example, when using scopes with a we </blockquote> </div> <div class="sect3"> -<h4 id="_example">10.5.1. Example</h4> +<h4 id="_example">11.5.1. Example</h4> <div class="paragraph"> <p>In the following example, the scope uses the unique identifier of a web site called âdigitallâ.</p> </div> @@ -4130,7 +4240,7 @@ For example, when using scopes with a we </div> </div> <div class="sect2"> -<h3 id="_item">10.6. Item</h3> +<h3 id="_item">11.6. Item</h3> <div class="paragraph"> <p>Unomi structures the information it collects using the concept of <code>Item</code> which provides the base information (an identifier and a type) the context server needs to process and store the data. Items are persisted according to their type (structure) and identifier (identity). @@ -4155,7 +4265,7 @@ Scopes allow clients accessing the conte It contains the following fields, that are inherited by other objects that inherit from it.</p> </div> <div class="sect3"> -<h4 id="_structure_definition">10.6.1. Structure definition</h4> +<h4 id="_structure_definition">11.6.1. Structure definition</h4> <div class="paragraph"> <p>Inherits all the fields from: n/a</p> </div> @@ -4193,13 +4303,13 @@ It contains the following fields, that a </div> </div> <div class="sect2"> -<h3 id="_metadata">10.7. Metadata</h3> +<h3 id="_metadata">11.7. Metadata</h3> <div class="paragraph"> <p>The Metadata object is an object that contains additional information about an object. It is usually associated with an Item object (see MetadataItem below).</p> </div> <div class="sect3"> -<h4 id="_structure_definition_2">10.7.1. Structure definition</h4> +<h4 id="_structure_definition_2">11.7.1. Structure definition</h4> <div class="paragraph"> <p>Inherits all the fields from: n/a</p> </div>
[... 1177 lines stripped ...]
