diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 00000000000..461646baa33
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,350 @@
+root = true
+
+[*]
+charset = utf-8
+end_of_line = lf
+indent_size = 4
+indent_style = space
+insert_final_newline = true
+max_line_length = 120
+tab_width = 4
+ij_continuation_indent_size = 8
+ij_formatter_off_tag = @formatter:off
+ij_formatter_on_tag = @formatter:on
+ij_formatter_tags_enabled = false
+ij_smart_tabs = false
+ij_visual_guides = none
+ij_wrap_on_typing = false
+
+[*.java]
+ij_java_align_consecutive_assignments = false
+ij_java_align_consecutive_variable_declarations = false
+ij_java_align_group_field_declarations = false
+ij_java_align_multiline_annotation_parameters = false
+ij_java_align_multiline_array_initializer_expression = false
+ij_java_align_multiline_assignment = false
+ij_java_align_multiline_binary_operation = false
+ij_java_align_multiline_chained_methods = false
+ij_java_align_multiline_extends_list = false
+ij_java_align_multiline_for = true
+ij_java_align_multiline_method_parentheses = false
+ij_java_align_multiline_parameters = true
+ij_java_align_multiline_parameters_in_calls = false
+ij_java_align_multiline_parenthesized_expression = false
+ij_java_align_multiline_records = true
+ij_java_align_multiline_resources = true
+ij_java_align_multiline_ternary_operation = false
+ij_java_align_multiline_text_blocks = false
+ij_java_align_multiline_throws_list = false
+ij_java_align_subsequent_simple_methods = false
+ij_java_align_throws_keyword = false
+ij_java_annotation_parameter_wrap = off
+ij_java_array_initializer_new_line_after_left_brace = false
+ij_java_array_initializer_right_brace_on_new_line = false
+ij_java_array_initializer_wrap = off
+ij_java_assert_statement_colon_on_next_line = false
+ij_java_assert_statement_wrap = off
+ij_java_assignment_wrap = off
+ij_java_binary_operation_sign_on_next_line = false
+ij_java_binary_operation_wrap = off
+ij_java_blank_lines_after_anonymous_class_header = 0
+ij_java_blank_lines_after_class_header = 0
+ij_java_blank_lines_after_imports = 1
+ij_java_blank_lines_after_package = 1
+ij_java_blank_lines_around_class = 1
+ij_java_blank_lines_around_field = 0
+ij_java_blank_lines_around_field_in_interface = 0
+ij_java_blank_lines_around_initializer = 1
+ij_java_blank_lines_around_method = 1
+ij_java_blank_lines_around_method_in_interface = 1
+ij_java_blank_lines_before_class_end = 0
+ij_java_blank_lines_before_imports = 1
+ij_java_blank_lines_before_method_body = 0
+ij_java_blank_lines_before_package = 0
+ij_java_block_brace_style = end_of_line
+ij_java_block_comment_at_first_column = true
+ij_java_builder_methods = none
+ij_java_call_parameters_new_line_after_left_paren = false
+ij_java_call_parameters_right_paren_on_new_line = false
+ij_java_call_parameters_wrap = off
+ij_java_case_statement_on_separate_line = true
+ij_java_catch_on_new_line = false
+ij_java_class_annotation_wrap = split_into_lines
+ij_java_class_brace_style = end_of_line
+ij_java_class_count_to_use_import_on_demand = 999
+ij_java_class_names_in_javadoc = 1
+ij_java_do_not_indent_top_level_class_members = false
+ij_java_do_not_wrap_after_single_annotation = false
+ij_java_do_while_brace_force = never
+ij_java_doc_add_blank_line_after_description = true
+ij_java_doc_add_blank_line_after_param_comments = false
+ij_java_doc_add_blank_line_after_return = false
+ij_java_doc_add_p_tag_on_empty_lines = true
+ij_java_doc_align_exception_comments = true
+ij_java_doc_align_param_comments = true
+ij_java_doc_do_not_wrap_if_one_line = false
+ij_java_doc_enable_formatting = true
+ij_java_doc_enable_leading_asterisks = true
+ij_java_doc_indent_on_continuation = false
+ij_java_doc_keep_empty_lines = true
+ij_java_doc_keep_empty_parameter_tag = true
+ij_java_doc_keep_empty_return_tag = true
+ij_java_doc_keep_empty_throws_tag = true
+ij_java_doc_keep_invalid_tags = true
+ij_java_doc_param_description_on_new_line = false
+ij_java_doc_preserve_line_breaks = false
+ij_java_doc_use_throws_not_exception_tag = true
+ij_java_else_on_new_line = false
+ij_java_entity_dd_suffix = EJB
+ij_java_entity_eb_suffix = Bean
+ij_java_entity_hi_suffix = Home
+ij_java_entity_lhi_prefix = Local
+ij_java_entity_lhi_suffix = Home
+ij_java_entity_li_prefix = Local
+ij_java_entity_pk_class = java.lang.String
+ij_java_entity_vo_suffix = VO
+ij_java_enum_constants_wrap = off
+ij_java_extends_keyword_wrap = off
+ij_java_extends_list_wrap = off
+ij_java_field_annotation_wrap = split_into_lines
+ij_java_finally_on_new_line = false
+ij_java_for_brace_force = never
+ij_java_for_statement_new_line_after_left_paren = false
+ij_java_for_statement_right_paren_on_new_line = false
+ij_java_for_statement_wrap = off
+ij_java_generate_final_locals = false
+ij_java_generate_final_parameters = false
+ij_java_if_brace_force = never
+ij_java_imports_layout = *,|,javax.**,java.**,|,$*
+ij_java_indent_case_from_switch = true
+ij_java_insert_inner_class_imports = false
+ij_java_insert_override_annotation = true
+ij_java_keep_blank_lines_before_right_brace = 2
+ij_java_keep_blank_lines_between_package_declaration_and_header = 2
+ij_java_keep_blank_lines_in_code = 2
+ij_java_keep_blank_lines_in_declarations = 2
+ij_java_keep_builder_methods_indents = false
+ij_java_keep_control_statement_in_one_line = true
+ij_java_keep_first_column_comment = true
+ij_java_keep_indents_on_empty_lines = false
+ij_java_keep_line_breaks = true
+ij_java_keep_multiple_expressions_in_one_line = false
+ij_java_keep_simple_blocks_in_one_line = false
+ij_java_keep_simple_classes_in_one_line = false
+ij_java_keep_simple_lambdas_in_one_line = false
+ij_java_keep_simple_methods_in_one_line = false
+ij_java_label_indent_absolute = false
+ij_java_label_indent_size = 0
+ij_java_lambda_brace_style = end_of_line
+ij_java_layout_static_imports_separately = true
+ij_java_line_comment_add_space = false
+ij_java_line_comment_at_first_column = true
+ij_java_message_dd_suffix = EJB
+ij_java_message_eb_suffix = Bean
+ij_java_method_annotation_wrap = split_into_lines
+ij_java_method_brace_style = end_of_line
+ij_java_method_call_chain_wrap = off
+ij_java_method_parameters_new_line_after_left_paren = false
+ij_java_method_parameters_right_paren_on_new_line = false
+ij_java_method_parameters_wrap = off
+ij_java_modifier_list_wrap = false
+ij_java_names_count_to_use_import_on_demand = 999
+ij_java_new_line_after_lparen_in_record_header = false
+ij_java_packages_to_use_import_on_demand = java.awt.*,javax.swing.*
+ij_java_parameter_annotation_wrap = off
+ij_java_parentheses_expression_new_line_after_left_paren = false
+ij_java_parentheses_expression_right_paren_on_new_line = false
+ij_java_place_assignment_sign_on_next_line = false
+ij_java_prefer_longer_names = true
+ij_java_prefer_parameters_wrap = false
+ij_java_record_components_wrap = normal
+ij_java_repeat_synchronized = true
+ij_java_replace_instanceof_and_cast = false
+ij_java_replace_null_check = true
+ij_java_replace_sum_lambda_with_method_ref = true
+ij_java_resource_list_new_line_after_left_paren = false
+ij_java_resource_list_right_paren_on_new_line = false
+ij_java_resource_list_wrap = off
+ij_java_rparen_on_new_line_in_record_header = false
+ij_java_session_dd_suffix = EJB
+ij_java_session_eb_suffix = Bean
+ij_java_session_hi_suffix = Home
+ij_java_session_lhi_prefix = Local
+ij_java_session_lhi_suffix = Home
+ij_java_session_li_prefix = Local
+ij_java_session_si_suffix = Service
+ij_java_space_after_closing_angle_bracket_in_type_argument = false
+ij_java_space_after_colon = true
+ij_java_space_after_comma = true
+ij_java_space_after_comma_in_type_arguments = true
+ij_java_space_after_for_semicolon = true
+ij_java_space_after_quest = true
+ij_java_space_after_type_cast = true
+ij_java_space_before_annotation_array_initializer_left_brace = false
+ij_java_space_before_annotation_parameter_list = false
+ij_java_space_before_array_initializer_left_brace = false
+ij_java_space_before_catch_keyword = true
+ij_java_space_before_catch_left_brace = true
+ij_java_space_before_catch_parentheses = true
+ij_java_space_before_class_left_brace = true
+ij_java_space_before_colon = true
+ij_java_space_before_colon_in_foreach = true
+ij_java_space_before_comma = false
+ij_java_space_before_do_left_brace = true
+ij_java_space_before_else_keyword = true
+ij_java_space_before_else_left_brace = true
+ij_java_space_before_finally_keyword = true
+ij_java_space_before_finally_left_brace = true
+ij_java_space_before_for_left_brace = true
+ij_java_space_before_for_parentheses = true
+ij_java_space_before_for_semicolon = false
+ij_java_space_before_if_left_brace = true
+ij_java_space_before_if_parentheses = true
+ij_java_space_before_method_call_parentheses = false
+ij_java_space_before_method_left_brace = true
+ij_java_space_before_method_parentheses = false
+ij_java_space_before_opening_angle_bracket_in_type_parameter = false
+ij_java_space_before_quest = true
+ij_java_space_before_switch_left_brace = true
+ij_java_space_before_switch_parentheses = true
+ij_java_space_before_synchronized_left_brace = true
+ij_java_space_before_synchronized_parentheses = true
+ij_java_space_before_try_left_brace = true
+ij_java_space_before_try_parentheses = true
+ij_java_space_before_type_parameter_list = false
+ij_java_space_before_while_keyword = true
+ij_java_space_before_while_left_brace = true
+ij_java_space_before_while_parentheses = true
+ij_java_space_inside_one_line_enum_braces = false
+ij_java_space_within_empty_array_initializer_braces = false
+ij_java_space_within_empty_method_call_parentheses = false
+ij_java_space_within_empty_method_parentheses = false
+ij_java_spaces_around_additive_operators = true
+ij_java_spaces_around_assignment_operators = true
+ij_java_spaces_around_bitwise_operators = true
+ij_java_spaces_around_equality_operators = true
+ij_java_spaces_around_lambda_arrow = true
+ij_java_spaces_around_logical_operators = true
+ij_java_spaces_around_method_ref_dbl_colon = false
+ij_java_spaces_around_multiplicative_operators = true
+ij_java_spaces_around_relational_operators = true
+ij_java_spaces_around_shift_operators = true
+ij_java_spaces_around_type_bounds_in_type_parameters = true
+ij_java_spaces_around_unary_operator = false
+ij_java_spaces_within_angle_brackets = false
+ij_java_spaces_within_annotation_parentheses = false
+ij_java_spaces_within_array_initializer_braces = false
+ij_java_spaces_within_braces = false
+ij_java_spaces_within_brackets = false
+ij_java_spaces_within_cast_parentheses = false
+ij_java_spaces_within_catch_parentheses = false
+ij_java_spaces_within_for_parentheses = false
+ij_java_spaces_within_if_parentheses = false
+ij_java_spaces_within_method_call_parentheses = false
+ij_java_spaces_within_method_parentheses = false
+ij_java_spaces_within_parentheses = false
+ij_java_spaces_within_record_header = false
+ij_java_spaces_within_switch_parentheses = false
+ij_java_spaces_within_synchronized_parentheses = false
+ij_java_spaces_within_try_parentheses = false
+ij_java_spaces_within_while_parentheses = false
+ij_java_special_else_if_treatment = true
+ij_java_subclass_name_suffix = Impl
+ij_java_ternary_operation_signs_on_next_line = false
+ij_java_ternary_operation_wrap = off
+ij_java_test_name_suffix = Test
+ij_java_throws_keyword_wrap = off
+ij_java_throws_list_wrap = off
+ij_java_use_external_annotations = false
+ij_java_use_fq_class_names = false
+ij_java_use_relative_indents = false
+ij_java_use_single_class_imports = true
+ij_java_variable_annotation_wrap = off
+ij_java_visibility = public
+ij_java_while_brace_force = never
+ij_java_while_on_new_line = false
+ij_java_wrap_comments = false
+ij_java_wrap_first_method_in_call_chain = false
+ij_java_wrap_long_lines = false
+
+[.editorconfig]
+ij_editorconfig_align_group_field_declarations = false
+ij_editorconfig_space_after_colon = false
+ij_editorconfig_space_after_comma = true
+ij_editorconfig_space_before_colon = false
+ij_editorconfig_space_before_comma = false
+ij_editorconfig_spaces_around_assignment_operators = true
+
+[{*.ant,*.fxml,*.jhm,*.jnlp,*.jrxml,*.pom,*.rng,*.tld,*.wadl,*.wsdd,*.wsdl,*.xjb,*.xml,*.xsd,*.xsl,*.xslt,*.xul}]
+ij_xml_align_attributes = true
+ij_xml_align_text = false
+ij_xml_attribute_wrap = normal
+ij_xml_block_comment_at_first_column = true
+ij_xml_keep_blank_lines = 2
+ij_xml_keep_indents_on_empty_lines = false
+ij_xml_keep_line_breaks = true
+ij_xml_keep_line_breaks_in_text = true
+ij_xml_keep_whitespaces = false
+ij_xml_keep_whitespaces_around_cdata = preserve
+ij_xml_keep_whitespaces_inside_cdata = false
+ij_xml_line_comment_at_first_column = true
+ij_xml_space_after_tag_name = false
+ij_xml_space_around_equals_in_attribute = false
+ij_xml_space_inside_empty_tag = false
+ij_xml_text_wrap = normal
+ij_xml_use_custom_settings = false
+
+[{*.bash,*.sh,*.zsh}]
+indent_size = 2
+tab_width = 2
+ij_shell_binary_ops_start_line = false
+ij_shell_keep_column_alignment_padding = false
+ij_shell_minify_program = false
+ij_shell_redirect_followed_by_space = false
+ij_shell_switch_cases_indented = false
+ij_shell_use_unix_line_separator = true
+
+[{*.har,*.jsb2,*.jsb3,*.json,.babelrc,.eslintrc,.stylelintrc,bowerrc,jest.config}]
+indent_size = 2
+ij_json_keep_blank_lines_in_code = 0
+ij_json_keep_indents_on_empty_lines = false
+ij_json_keep_line_breaks = true
+ij_json_space_after_colon = true
+ij_json_space_after_comma = true
+ij_json_space_before_colon = true
+ij_json_space_before_comma = false
+ij_json_spaces_within_braces = false
+ij_json_spaces_within_brackets = false
+ij_json_wrap_long_lines = false
+
+[{*.markdown,*.md}]
+ij_markdown_force_one_space_after_blockquote_symbol = true
+ij_markdown_force_one_space_after_header_symbol = true
+ij_markdown_force_one_space_after_list_bullet = true
+ij_markdown_force_one_space_between_words = true
+ij_markdown_keep_indents_on_empty_lines = false
+ij_markdown_max_lines_around_block_elements = 1
+ij_markdown_max_lines_around_header = 1
+ij_markdown_max_lines_between_paragraphs = 1
+ij_markdown_min_lines_around_block_elements = 1
+ij_markdown_min_lines_around_header = 1
+ij_markdown_min_lines_between_paragraphs = 1
+
+[{*.properties,spring.handlers,spring.schemas}]
+ij_properties_align_group_field_declarations = false
+ij_properties_keep_blank_lines = false
+ij_properties_key_value_delimiter = equals
+ij_properties_spaces_around_key_value_delimiter = false
+
+[{*.yaml,*.yml}]
+indent_size = 2
+ij_yaml_align_values_properties = do_not_align
+ij_yaml_autoinsert_sequence_marker = true
+ij_yaml_block_mapping_on_new_line = false
+ij_yaml_indent_sequence_value = true
+ij_yaml_keep_indents_on_empty_lines = false
+ij_yaml_keep_line_breaks = true
+ij_yaml_sequence_on_new_line = false
+ij_yaml_space_before_colon = false
+ij_yaml_spaces_within_braces = true
+ij_yaml_spaces_within_brackets = true
diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml
index d26d7485344..4cc56e55058 100644
--- a/.github/workflows/pullrequest.yml
+++ b/.github/workflows/pullrequest.yml
@@ -17,7 +17,7 @@ jobs:
strategy:
matrix:
- java: [8]
+ java: [8, 11]
steps:
- uses: actions/checkout@v1
diff --git a/.github/workflows/release-drafter.yml b/.github/workflows/release-drafter.yml
index f5d07b2639d..b34d4827eae 100644
--- a/.github/workflows/release-drafter.yml
+++ b/.github/workflows/release-drafter.yml
@@ -14,7 +14,7 @@ jobs:
- name: Extract tag from commit message
run: |
target_tag=${COMMIT_MSG#"Prebid Server prepare release "}
- echo "::set-env name=TARGET_TAG::$target_tag"
+ echo "TARGET_TAG=$target_tag" >> $GITHUB_ENV
env:
COMMIT_MSG: ${{ github.event.head_commit.message }}
- name: Create and publish release
diff --git a/README.md b/README.md
index e7edc4aca48..c4f9d91d0fa 100644
--- a/README.md
+++ b/README.md
@@ -1,26 +1,28 @@
-### This code is being used in production by multiple Prebid.org members, but is not the "official" version. See https://github.com/prebid/prebid-server/
+### This is the Java version of Prebid Server. See the Prebid Server [Feature List](https://docs.prebid.org/prebid-server/features/pbs-feature-idx.html) and [FAQ entry](https://docs.prebid.org/faq/prebid-server-faq.html#why-are-there-two-versions-of-prebid-server-are-they-kept-in-sync) to understand the differences between PBS-Java and [PBS-Go](https://github.com/prebid/prebid-server).
-# Prebid Server
+# Prebid Server (Java)
-[![GitHub version](https://badge.fury.io/gh/rubicon-project%2fprebid-server-java.svg)](http://badge.fury.io/gh/rubicon-project%2fprebid-server-java)
-[![Language grade: Java](https://img.shields.io/lgtm/grade/java/g/rubicon-project/prebid-server-java.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/rubicon-project/prebid-server-java/context:java)
-[![Total alerts](https://img.shields.io/lgtm/alerts/g/rubicon-project/prebid-server-java.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/rubicon-project/prebid-server-java/alerts/)
-[![GitHub contributors](https://img.shields.io/github/contributors/rubicon-project/prebid-server-java.svg)](https://GitHub.com/rubicon-project/prebid-server-java/contributors/)
-[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](https://github.com/rubicon-project/prebid-server-java/blob/master/docs/contributing.md)
-[![GitHub pull-requests closed](https://img.shields.io/github/issues-pr-closed/rubicon-project/prebid-server-java.svg)](https://GitHub.com/rubicon-project/prebid-server-java/pull/)
+[![GitHub version](https://badge.fury.io/gh/prebid%2fprebid-server-java.svg)](http://badge.fury.io/gh/prebid%2fprebid-server-java)
+[![Language grade: Java](https://img.shields.io/lgtm/grade/java/g/prebid/prebid-server-java.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/prebid/prebid-server-java/context:java)
+[![Total alerts](https://img.shields.io/lgtm/alerts/g/prebid/prebid-server-java.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/prebid/prebid-server-java/alerts/)
+[![GitHub contributors](https://img.shields.io/github/contributors/prebid/prebid-server-java.svg)](https://GitHub.com/prebid/prebid-server-java/contributors/)
+[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](https://github.com/prebid/prebid-server-java/blob/master/docs/contributing.md)
+[![GitHub pull-requests closed](https://img.shields.io/github/issues-pr-closed/prebid/prebid-server-java.svg)](https://GitHub.com/prebid/prebid-server-java/pull/)
Prebid Server is an open source implementation of Server-Side Header Bidding.
-It is managed by [Prebid.org](http://prebid.org/overview/what-is-prebid-org.html),
-and upholds the principles from the [Prebid Code of Conduct](http://prebid.org/wrapper_code_of_conduct.html).
+It is managed by Prebid.org,
+and upholds the principles from the [Prebid Code of Conduct](https://prebid.org/wrapper_code_of_conduct.html).
This project does not support the same set of Bidders as Prebid.js, although there is overlap.
The current set can be found in the [adapters](./src/main/java/org/prebid/server/bidder) package. If you don't see the one you want, feel free to [contribute it](docs/developers/add-new-bidder.md).
For more information, see:
-- [What is Prebid?](http://prebid.org/overview/intro.html)
-- [Getting started with Prebid Server](http://prebid.org/dev-docs/get-started-with-prebid-server.html)
-- [Current Bidders](http://prebid.org/dev-docs/prebid-server-bidders.html)
+- [What is Prebid?](https://prebid.org/why-prebid/)
+- [Getting started with Prebid Server](https://docs.prebid.org/prebid-server/overview/prebid-server-overview.html)
+- [Current Bidders](https://docs.prebid.org/dev-docs/pbs-bidders.html)
+
+Please consider [registering your Prebid Server](https://docs.prebid.org/prebid-server/hosting/pbs-hosting.html#optional-registration) to get on the mailing list for updates, etc.
# Getting Started
@@ -28,23 +30,21 @@ The server makes the following assumptions:
- No ranking or decisioning is performed by this server. It just proxies requests.
- No ad quality management (e.g., malware, viruses, deceptive creatives) is performed by this server.
- This server does no fraud scanning and does nothing to prevent bad traffic.
-- This server does no logging.
-- This server has not user profiling or user data collection capabilities.
+- This server logs errors but not requests.
+- This server has no user profiling or user data collection capabilities.
This project is built upon [Vert.x](http://vertx.io) to achieve high request throughput.
We use [Maven](https://maven.apache.org) and attempt to introduce minimal dependencies.
When running, the server responds to several HTTP [endpoints](docs/endpoints).
-To start the Prebid Server you need to do the following steps:
-
## Building
Follow next steps to create JAR file which can be deployed locally.
- Download or clone a project:
```bash
-git clone https://github.com/rubicon-project/prebid-server-java.git
+git clone https://github.com/prebid/prebid-server-java.git
```
- Move to project directory:
@@ -84,28 +84,27 @@ and verify response status is `200 OK`.
# Documentation
## Development
-- [Differences Between Prebid Server Go and Java](differenceBetweenPBSGo-and-Java.md)
-- [Endpoints](endpoints)
-- [Adding new bidder](developers/add-new-bidder.md)
-- [Adding new analytics module](developers/add-new-analytics-module.md)
-- [Adding viewability support](developers/add-viewability-vendors.md)
-- [Auction result post-processing](developers/auction-result-post-processing.md)
-- [Cookie Syncs](developers/cookie-syncs.md)
-- [Stored Requests](developers/stored-requests.md)
-- [Unit Tests](developers/unit-tests.md)
-- [GDPR](developers/gdpr.md)
+- [Endpoints](docs/endpoints)
+- [Adding new bidder](docs/developers/add-new-bidder.md)
+- [Adding new analytics module](docs/developers/add-new-analytics-module.md)
+- [Adding viewability support](docs/developers/add-viewability-vendors.md)
+- [Auction result post-processing](docs/developers/auction-result-post-processing.md)
+- [Cookie Syncs](docs/developers/cookie-syncs.md)
+- [Stored Requests](docs/developers/stored-requests.md)
+- [Unit Tests](docs/developers/unit-tests.md)
+- [GDPR](docs/developers/gdpr.md)
## Maintenance
-- [Build for local](build.md)
-- [Build for AWS](build-aws.md)
-- [Configure application](config.md)
- - [Full list of configuration options](config-app.md)
- - [Application settings](application-settings.md)
-- [Run with optimizations](run.md)
-- [Metrics](metrics.md)
+- [Build for local](docs/build.md)
+- [Build for AWS](docs/build-aws.md)
+- [Configure application](docs/config.md)
+ - [Full list of configuration options](docs/config-app.md)
+ - [Application settings](docs/application-settings.md)
+- [Run with optimizations](docs/run.md)
+- [Metrics](docs/metrics.md)
## Contributing
-- [Contributing](contributing.md)
-- [Code Style](code-style.md)
-- [Code Review](code-reviews.md)
-- [Versioning](versioning.md)
+- [Contributing](docs/contributing.md)
+- [Code Style](docs/code-style.md)
+- [Code Review](docs/code-reviews.md)
+- [Versioning](docs/versioning.md)
diff --git a/checkstyle.xml b/checkstyle.xml
index 86235beeacf..64f253767e3 100644
--- a/checkstyle.xml
+++ b/checkstyle.xml
@@ -44,7 +44,7 @@
-
+
diff --git a/docs/application-settings.md b/docs/application-settings.md
index 178ae5c9cc2..a12b46d3ad4 100644
--- a/docs/application-settings.md
+++ b/docs/application-settings.md
@@ -1,28 +1,52 @@
# Application Settings
+
There are two ways to configure application settings: database and file. This document will describe both approaches.
## Account properties
+
- `id` - identifies publisher account.
-- `price-granularity` - defines price granularity types: 'low','med','high','auto','dense','unknown'.
-- `banner-cache-ttl` - how long (in seconds) banner will be available via the external Cache Service.
-- `video-cache-ttl`- how long (in seconds) video creative will be available via the external Cache Service.
-- `events-enabled` - enables events for account if true
-- `enforce-ccpa` - enforces ccpa if true. Has higher priority than configuration in application.yaml.
-- `gdpr.enabled` - enables gdpr verifications if true. Has higher priority than configuration in application.yaml.
-- `gdpr.integration-enabled.web` - overrides `gdpr.enabled` property behaviour for web requests type.
-- `gdpr.integration-enabled.amp` - overrides `gdpr.enabled` property behaviour for amp requests type.
-- `gdpr.integration-enabled.app` - overrides `gdpr.enabled` property behaviour for app requests type.
-- `gdpr.integration-enabled.video` - overrides `gdpr.enabled` property behaviour for video requests type.
-- `gdpr.purposes.[p1-p10].enforce-purpose` - define type of enforcement confirmation: `no`/`basic`/`full`. Default `full`
-- `gdpr.purposes.[p1-p10].enforce-vendors` - if equals to `true`, user must give consent to use vendors. Purposes will be omitted. Default `true`
-- `gdpr.purposes.[p1-p10].vendor-exceptions[]` - bidder names that will be treated opposite to `pN.enforce-vendors` value.
-- `gdpr.special-features.[f1-f2].enforce`- if equals to `true`, special feature will be enforced for purpose. Default `true`
-- `gdpr.special-features.[f1-f2].vendor-exceptions` - bidder names that will be treated opposite to `sfN.enforce` value.
-- `gdpr.purpose-one-treatment-interpretation` - option that allows to skip the Purpose one enforcement workflow. Values: ignore, no-access-allowed, access-allowed.
-- `analytics-sampling-factor` - Analytics sampling factor value.
-- `truncate-target-attr` - Maximum targeting attributes size. Values between 1 and 255.
-- `default-integration` - Default integration to assume.
-- `analytics-config.auction-events.` - defines which channels are supported by analytics for this account
+- `status` - allows to mark account as `active` or `inactive`.
+- `auction.price-granularity` - defines price granularity types: 'low','med','high','auto','dense','unknown'.
+- `auction.banner-cache-ttl` - how long (in seconds) banner will be available via the external Cache Service.
+- `auction.video-cache-ttl`- how long (in seconds) video creative will be available via the external Cache Service.
+- `auction.truncate-target-attr` - Maximum targeting attributes size. Values between 1 and 255.
+- `auction.default-integration` - Default integration to assume.
+- `auction.bid-validations.banner-creative-max-size` - Overrides creative max size validation for banners. Valid values
+ are:
+ - "skip": don't do anything about creative max size for this publisher
+ - "warn": if a bidder returns a creative that's larger in height or width than any of the allowed sizes, log an
+ operational warning.
+ - "enforce": if a bidder returns a creative that's larger in height or width than any of the allowed sizes, reject
+ the bid and log an operational warning.
+- `auction.events.enabled` - enables events for account if true
+- `privacy.enforce-ccpa` - enforces ccpa if true. Has higher priority than configuration in application.yaml.
+- `privacy.gdpr.enabled` - enables gdpr verifications if true. Has higher priority than configuration in
+ application.yaml.
+- `privacy.gdpr.integration-enabled.web` - overrides `privacy.gdpr.enabled` property behaviour for web requests type.
+- `privacy.gdpr.integration-enabled.amp` - overrides `privacy.gdpr.enabled` property behaviour for amp requests type.
+- `privacy.gdpr.integration-enabled.app` - overrides `privacy.gdpr.enabled` property behaviour for app requests type.
+- `privacy.gdpr.integration-enabled.video` - overrides `privacy.gdpr.enabled` property behaviour for video requests
+ type.
+- `privacy.gdpr.purposes.[p1-p10].enforce-purpose` - define type of enforcement confirmation: `no`/`basic`/`full`.
+ Default `full`
+- `privacy.gdpr.purposes.[p1-p10].enforce-vendors` - if equals to `true`, user must give consent to use vendors.
+ Purposes will be omitted. Default `true`
+- `privacy.gdpr.purposes.[p1-p10].vendor-exceptions[]` - bidder names that will be treated opposite
+ to `pN.enforce-vendors` value.
+- `privacy.gdpr.special-features.[f1-f2].enforce`- if equals to `true`, special feature will be enforced for purpose.
+ Default `true`
+- `privacy.gdpr.special-features.[f1-f2].vendor-exceptions` - bidder names that will be treated opposite
+ to `sfN.enforce` value.
+- `privacy.gdpr.purpose-one-treatment-interpretation` - option that allows to skip the Purpose one enforcement workflow.
+ Values: ignore, no-access-allowed, access-allowed.
+- `analytics.auction-events.` - defines which channels are supported by analytics for this account
+- `analytics.modules..*` - space for `module-name` analytics module specific configuration, may be of any shape
+- `cookie-sync.default-limit` - if the "limit" isn't specified in the `/cookie_sync` request, this is what to use
+- `cookie-sync.max-limit` - if the "limit" is specified in the `/cookie_sync` request, it can't be greater than this
+ value
+- `cookie-sync.default-coop-sync` - if the "coopSync" value isn't specified in the `/cookie_sync` request, use this
+
+Here are the definitions of the "purposes" that can be defined in the GDPR setting configurations:
```
Purpose | Purpose goal | Purpose meaning for PBS (n\a - not affected)
@@ -30,7 +54,7 @@ Purpose | Purpose goal | Purpose meaning for PBS (n\a - not
p1 | Access device | Stops usersync for given vendor and stops settings cookie on `/seuid`
p2 | Select basic ads | Verify consent for each vendor as appropriate for the enforcement method before calling a bid adapter. If consent is not granted, log a metric and skip it.
p3 | Personalized ads profile | n\a
-p4 | Select personalized ads | Verify consent for each vendor that passed the Purpose 2. If consent is not granted, remove the bidrequest.userId, user.ext.eids, user.ext.digitrust, device.if attributes and call the adapter.
+p4 | Select personalized ads | Verify consent for each vendor that passed the Purpose 2. If consent is not granted, remove the bidrequest.userId, user.ext.eids, device.if attributes and call the adapter.
p5 | Personalized content profile | n\a
p6 | Select personalized content | n\a
p7 | Measure ad performance | Verify consent for each analytics module. If consent is not grantet skip it.
@@ -42,277 +66,382 @@ sf1 | Precise geo | Verifies user opt-in. If the user
sf2 | Fingerprinting | n\a
```
-## File application setting
+## Setting Account Configuration in Files
In file based approach all configuration stores in .yaml files, path to which are defined in application properties.
### Configuration in application.yaml
-```
+The general idea is that you'll place all the account-specific settings in a separate YAML file and point to that file.
+
+```yaml
settings:
filesystem:
settings-filename:
```
+
### File format
+Here's an example YAML file containing account-specific settings:
+
+```yaml
+ accounts:
+ - id: 1111
+ status: active
+ auction:
+ price-granularity: low
+ banner-cache-ttl: 100
+ video-cache-ttl: 100
+ truncate-target-attr: 40
+ default-integration: web
+ bid-validations:
+ banner-creative-max-size: enforce
+ events:
+ enabled: true
+ privacy:
+ enforce-ccpa: true
+ gdpr:
+ enabled: true
+ integration-enabled:
+ video: true
+ web: true
+ app: true
+ amp: true
+ purposes:
+ p1:
+ enforce-purpose: full
+ enforce-vendors: true
+ vendor-exceptions:
+ - bidder1
+ - bidder2
+ p2:
+ enforce-purpose: full
+ enforce-vendors: true
+ vendor-exceptions:
+ - bidder1
+ - bidder2
+ p3:
+ enforce-purpose: full
+ enforce-vendors: true
+ vendor-exceptions:
+ - bidder1
+ - bidder2
+ p4:
+ enforce-purpose: full
+ enforce-vendors: true
+ vendor-exceptions:
+ - bidder1
+ - bidder2
+ p5:
+ enforce-purpose: full
+ enforce-vendors: true
+ vendor-exceptions:
+ - bidder1
+ - bidder2
+ p6:
+ enforce-purpose: full
+ enforce-vendors: true
+ vendor-exceptions:
+ - bidder1
+ - bidder2
+ p7:
+ enforce-purpose: full
+ enforce-vendors: true
+ vendor-exceptions:
+ - bidder1
+ - bidder2
+ p8:
+ enforce-purpose: full
+ enforce-vendors: true
+ vendor-exceptions:
+ - bidder1
+ - bidder2
+ p9:
+ enforce-purpose: full
+ enforce-vendors: true
+ vendor-exceptions:
+ - bidder1
+ - bidder2
+ p10:
+ enforce-purpose: full
+ enforce-vendors: true
+ vendor-exceptions:
+ - bidder1
+ - bidder2
+ special-features:
+ sf1:
+ enforce: true
+ vendor-exceptions:
+ - bidder1
+ - bidder2
+ sf2:
+ enforce: true
+ vendor-exceptions:
+ - bidder1
+ - bidder2
+ purpose-one-treatment-interpretation: ignore
+ analytics:
+ auction-events:
+ amp: true
+ cookie-sync:
+ default-limit: 5
+ max-limit: 8
+ default-coop-sync: true
```
-accounts:
- - id: 14062
- bannerCacheTtl: 100
- videoCacheTtl: 100
- eventsEnabled: true
- priceGranularity: low
- enforceCcpa: true
- analyticsSamplingFactor: 1
- truncateTargetAttr: 40
- defaultIntegration: web
- analytics-config:
- auction-events:
- amp: true
- gdpr:
- enabled: true
- integration-enabled:
- video: true
- web: true
- app: true
- amp: true
- purposes:
- p1:
- enforce-purpose: full
- enforce-vendors: true
- vendor-exceptions:
- - bidder1
- - bidder2
- p2:
- enforce-purpose: full
- enforce-vendors: true
- vendor-exceptions:
- - bidder1
- - bidder2
- p3:
- enforce-purpose: full
- enforce-vendors: true
- vendor-exceptions:
- - bidder1
- - bidder2
- p4:
- enforce-purpose: full
- enforce-vendors: true
- vendor-exceptions:
- - bidder1
- - bidder2
- p5:
- enforce-purpose: full
- enforce-vendors: true
- vendor-exceptions:
- - bidder1
- - bidder2
- p6:
- enforce-purpose: full
- enforce-vendors: true
- vendor-exceptions:
- - bidder1
- - bidder2
- p7:
- enforce-purpose: full
- enforce-vendors: true
- vendor-exceptions:
- - bidder1
- - bidder2
- p8:
- enforce-purpose: full
- enforce-vendors: true
- vendor-exceptions:
- - bidder1
- - bidder2
- p9:
- enforce-purpose: full
- enforce-vendors: true
- vendor-exceptions:
- - bidder1
- - bidder2
- p10:
- enforce-purpose: full
- enforce-vendors: true
- vendor-exceptions:
- - bidder1
- - bidder2
- special-features:
- sf1:
- enforce: true
- vendor-exceptions:
- - bidder1
- - bidder2
- sf2:
- enforce: true
- vendor-exceptions:
- - bidder1
- - bidder2
- purpose-one-treatment-interpretation: ignore
-```
-
-## Database application setting
+## Setting Account Configuration in the Database
+
+In database approach account properties are stored in database table(s).
-In database approach account properties are stored in database table with name accounts_account.
+SQL query for retrieving account is configurable and can be specified in [application configuration](config-app.md).
+Requirements for the SQL query stated below.
### Configuration in application.yaml
-```
+
+```yaml
settings:
database:
- type:
pool-size: 20
- type: mysql
+ type:
host:
port:
+ account-query:
```
-### Table description
+### Configurable SQL query for account requirements
-Query to create accounts_account table:
+The general approach is that each host company can set up their database however they wish, so long as the configurable
+query run by Prebid Server returns expected data in the expected order. Here's an example configuration:
-```
-'CREATE TABLE `accounts_account` (
-`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
-`uuid` varchar(40) NOT NULL,
-`price_granularity` enum('low','med','high','auto','dense','unknown') NOT NULL DEFAULT 'unknown',
-`granularityMultiplier` decimal(9,3) DEFAULT NULL,
-`banner_cache_ttl` int(11) DEFAULT NULL,
-`video_cache_ttl` int(11) DEFAULT NULL,
-`events_enabled` bit(1) DEFAULT NULL,
-`enforce_ccpa` bit(1) DEFAULT NULL,
-`enforce_gdpr` bit(1) DEFAULT NULL,
-`tcf_config` json DEFAULT NULL,
-`analytics_sampling_factor` tinyint(4) DEFAULT NULL,
-`truncate_target_attr` tinyint(3) unsigned DEFAULT NULL,
-`default_integration` varchar(64) DEFAULT NULL,
-`analytics_config` varchar(512) DEFAULT NULL,
-`status` enum('active','inactive') DEFAULT 'active',
-`updated_by` int(11) DEFAULT NULL,
-`updated_by_user` varchar(64) DEFAULT NULL,
-`updated` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
-PRIMARY KEY (`id`),
-UNIQUE KEY `uuid` (`uuid`))
-ENGINE=InnoDB DEFAULT CHARSET=utf8'
+```yaml
+settings:
+ database:
+ type: mysql
+ account-query: SELECT config FROM accounts_account where uuid = ? LIMIT 1
```
-where tcf_config column is json with next format
+The SQL query for account must:
-```
+* return following columns, with specified type, in this order:
+ * configuration document, JSON string, see below
+* specify a special single `%ACCOUNT_ID%` placeholder in the `WHERE` clause that will be replaced with account ID in
+ runtime
+
+It is recommended to include `LIMIT 1` clause in the query because only the very first result returned will be taken.
+
+### Configuration document JSON
+
+The configuration document JSON returned by the SQL query must conform to the format illustrated with the following
+example:
+
+```json
{
- "enabled": true,
- "integration-enabled": {
- "video": true,
- "web": true,
- "app": true,
- "amp": true
- }
- "purpose-one-treatment-interpretation": "ignore"
- "purposes": {
- "p1": {
- "enforce-purpose": "full",
- "enforce-vendors": true,
- "vendor-exceptions": [
- "bidder1",
- "bidder2"
- ]
- },
- "p2": {
- "enforce-purpose": "full",
- "enforce-vendors": true,
- "vendor-exceptions": [
- "bidder1",
- "bidder2"
- ]
- },
- "p3": {
- "enforce-purpose": "full",
- "enforce-vendors": true,
- "vendor-exceptions": [
- "bidder1",
- "bidder2"
- ]
- },
- "p4": {
- "enforce-purpose": "full",
- "enforce-vendors": true,
- "vendor-exceptions": [
- "bidder1",
- "bidder2"
- ]
- },
- "p5": {
- "enforce-purpose": "full",
- "enforce-vendors": true,
- "vendor-exceptions": [
- "bidder1",
- "bidder2"
- ]
+ "id": "1111",
+ "status": "active",
+ "auction": {
+ "price-granularity": "low",
+ "banner-cache-ttl": 100,
+ "video-cache-ttl": 100,
+ "truncate-target-attr": 40,
+ "default-integration": "web",
+ "bid-validations": {
+ "banner-creative-max-size": "enforce"
},
- "p6": {
- "enforce-purpose": "full",
- "enforce-vendors": true,
- "vendor-exceptions": [
- "bidder1",
- "bidder2"
- ]
- },
- "p7": {
- "enforce-purpose": "full",
- "enforce-vendors": true,
- "vendor-exceptions": [
- "bidder1",
- "bidder2"
- ]
- },
- "p8": {
- "enforce-purpose": "full",
- "enforce-vendors": true,
- "vendor-exceptions": [
- "bidder1",
- "bidder2"
- ]
- },
- "p9": {
- "enforce-purpose": "full",
- "enforce-vendors": true,
- "vendor-exceptions": [
- "bidder1",
- "bidder2"
- ]
- },
- "p10": {
- "enforce-purpose": "full",
- "enforce-vendors": true,
- "vendor-exceptions": [
- "bidder1",
- "bidder2"
- ]
+ "events": {
+ "enabled": true
}
},
- "special-features": {
- "sf1": {
- "enforce": true,
- "vendor-exceptions": [
- "bidder1",
- "bidder2"
- ]
- },
- "sf2": {
- "enforce": true,
- "vendor-exceptions": [
- "bidder1",
- "bidder2"
- ]
+ "privacy": {
+ "enforce-ccpa": true,
+ "gdpr": {
+ "enabled": true,
+ "integration-enabled": {
+ "video": true,
+ "web": true,
+ "app": true,
+ "amp": true
+ },
+ "purpose-one-treatment-interpretation": "ignore",
+ "purposes": {
+ "p1": {
+ "enforce-purpose": "full",
+ "enforce-vendors": true,
+ "vendor-exceptions": [
+ "bidder1",
+ "bidder2"
+ ]
+ },
+ "p2": {
+ "enforce-purpose": "full",
+ "enforce-vendors": true,
+ "vendor-exceptions": [
+ "bidder1",
+ "bidder2"
+ ]
+ },
+ "p3": {
+ "enforce-purpose": "full",
+ "enforce-vendors": true,
+ "vendor-exceptions": [
+ "bidder1",
+ "bidder2"
+ ]
+ },
+ "p4": {
+ "enforce-purpose": "full",
+ "enforce-vendors": true,
+ "vendor-exceptions": [
+ "bidder1",
+ "bidder2"
+ ]
+ },
+ "p5": {
+ "enforce-purpose": "full",
+ "enforce-vendors": true,
+ "vendor-exceptions": [
+ "bidder1",
+ "bidder2"
+ ]
+ },
+ "p6": {
+ "enforce-purpose": "full",
+ "enforce-vendors": true,
+ "vendor-exceptions": [
+ "bidder1",
+ "bidder2"
+ ]
+ },
+ "p7": {
+ "enforce-purpose": "full",
+ "enforce-vendors": true,
+ "vendor-exceptions": [
+ "bidder1",
+ "bidder2"
+ ]
+ },
+ "p8": {
+ "enforce-purpose": "full",
+ "enforce-vendors": true,
+ "vendor-exceptions": [
+ "bidder1",
+ "bidder2"
+ ]
+ },
+ "p9": {
+ "enforce-purpose": "full",
+ "enforce-vendors": true,
+ "vendor-exceptions": [
+ "bidder1",
+ "bidder2"
+ ]
+ },
+ "p10": {
+ "enforce-purpose": "full",
+ "enforce-vendors": true,
+ "vendor-exceptions": [
+ "bidder1",
+ "bidder2"
+ ]
+ }
+ },
+ "special-features": {
+ "sf1": {
+ "enforce": true,
+ "vendor-exceptions": [
+ "bidder1",
+ "bidder2"
+ ]
+ },
+ "sf2": {
+ "enforce": true,
+ "vendor-exceptions": [
+ "bidder1",
+ "bidder2"
+ ]
+ }
+ }
}
+ },
+ "analytics": {
+ "auction-events": {
+ // the analytics adapter should log auction events when the channel is web
+ "web": true,
+ // the analytics adapter should log auction events when the channel is AMP
+ "amp": true,
+ // the analytics adapter should not log auction events when the channel is app
+ "app": false
+ }
+ },
+ "cookie-sync": {
+ "default-limit": 5,
+ "max-limit": 8,
+ "default-coop-sync": true
}
}
```
-Query used to get an account:
+At some point this format might be formalized into an
+exhaustive [JSON Schema](https://json-schema.org/specification.html).
+
+#### SQL Query example
+
+Prebid Server does not impose any rules for the table(s) schema but requires SQL query specified in
+configuration to return a single column of JSON type containing the document adhering to the format shown above.
+
+It might be the case that the host companies store account configuration in a table of arbitrary structure or even in
+several tables. MySQL and Postgres provides necessary functions allowing to project practically any table structure to
+expected JSON format.
+
+Let's assume following table schema for example:
+```sql
+'CREATE TABLE `accounts_account` (
+ `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
+ `uuid` varchar(40) NOT NULL,
+ `price_granularity` enum('low','med','high','auto','dense','unknown') NOT NULL DEFAULT 'unknown',
+ `banner_cache_ttl` int(11) DEFAULT NULL,
+ `video_cache_ttl` int(11) DEFAULT NULL,
+ `events_enabled` bit(1) DEFAULT NULL,
+ `enforce_ccpa` bit(1) DEFAULT NULL,
+ `tcf_config` json DEFAULT NULL,
+ `truncate_target_attr` tinyint(3) unsigned DEFAULT NULL,
+ `default_integration` varchar(64) DEFAULT NULL,
+ `analytics_config` json DEFAULT NULL,
+ `bid_validations` json DEFAULT NULL,
+ `config` json DEFAULT NULL,
+ `status` enum('active','inactive') DEFAULT 'active',
+ `updated_by` int(11) DEFAULT NULL,
+ `updated_by_user` varchar(64) DEFAULT NULL,
+ `updated` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+PRIMARY KEY (`id`),
+UNIQUE KEY `uuid` (`uuid`))
+ENGINE=InnoDB DEFAULT CHARSET=utf8'
```
-SELECT uuid, price_granularity, banner_cache_ttl, video_cache_ttl, events_enabled, enforce_ccpa, tcf_config, analytics_sampling_factor, truncate_target_attr, default_integration, analytics_config
-FROM accounts_account where uuid = ?
-LIMIT 1
+The following Mysql SQL query could be used to construct a JSON document of required shape on the fly:
+
+```sql
+SELECT
+ JSON_MERGE_PATCH(config, JSON_OBJECT(
+ 'id', uuid,
+ 'status', status,
+ 'auction', JSON_OBJECT(
+ 'price-granularity', price_granularity,
+ 'banner-cache-ttl', banner_cache_ttl,
+ 'video-cache-ttl', video_cache_ttl,
+ 'truncate-target-attr', truncate_target_attr,
+ 'default-integration', default_integration,
+ 'bid-validations', bid_validations,
+ 'events', JSON_OBJECT(
+ 'enabled', NOT NOT(events_enabled)
+ )
+ ),
+ 'privacy', JSON_OBJECT(
+ 'enforce-ccpa', NOT NOT(enforce_ccpa),
+ 'gdpr', tcf_config
+ ),
+ 'analytics', analytics_config
+ )) as consolidated_config
+FROM accounts_account
+WHERE uuid = %ACCOUNT_ID%
+LIMIT 1;
```
diff --git a/docs/bidders/appnexus.md b/docs/bidders/appnexus.md
index 434ba8048f0..2868740d234 100644
--- a/docs/bidders/appnexus.md
+++ b/docs/bidders/appnexus.md
@@ -15,7 +15,7 @@ The AppNexus endpoint expects `imp.displaymanagerver` to be populated for mobile
requests, however not all SDKs will populate this field. If the `imp.displaymanagerver` field
is not supplied for an `imp`, but `request.app.ext.prebid.source`
and `request.app.ext.prebid.version` are supplied, the adapter will fill in a value for
-`diplaymanagerver`. It will concatonate the two `app` fields as `