Add code formatting guidelines

Add 'eclipse' folder containing Eclipse code
formatter configuration and instructions how to use
 it.

Update rule for join_wrapped_lines

 - Set to `false`

Resolves #930

Update README

Address review comments
This commit is contained in:
Ilayaperumal Gopinathan
2017-05-12 21:34:39 +05:30
committed by Marius Bogoevici
parent 9632546f03
commit bd002e4aaf
159 changed files with 1770 additions and 1283 deletions

View File

@@ -37,6 +37,19 @@ Any question that is not a bug or an issue should be asked on Stack Overflow, us
We love contributions. Follow this https://github.com/spring-cloud/spring-cloud-commons#contributing[link] for more information on how to contribute.
=== Code formatting guidelines
* The directory `eclipse` contains two files that can be used to configure the formatting rules in your IDE: `eclipse-code-formatter.xml` for the majority of the code formatting rules and `eclipse.importorder` to order the import statements.
* In Eclipse you import these files by navigating `Windows -> Preferences` and then the menu items `Preferences > Java > Code Style > Formatter` and `Preferences > Java > Code Style > Organize Imports` respectively.
* In `IntelliJ`, install the plugin `Eclipse Code Formatter`.
You can find it by searching the "Browse Repositories" under the plugin option within `IntelliJ` (Once installed you will need to reboot Intellij for it to take effect).
Then navigate to `Intellij IDEA > Preferences` and select the Eclipse Code Formatter.
Select the `eclipse-code-formatter.xml` file for the field `Eclipse Java Formatter config file` and the file `eclipse.importorder` for the field `Import order`.
Enable the `Eclipse code formatter` by clicking `Use the Eclipse code formatter` then click the *OK* button.
** NOTE: If you configure the `Eclipse Code Formatter` from `File > Other Settings > Default Settings` it will set this policy across all of your Intellij projects.
== Code of Conduct
This project adheres to the Contributor Covenant link:CODE_OF_CONDUCT.adoc[code of conduct]. By participating, you are expected to uphold this code. Please report unacceptable behavior to spring-code-of-conduct@pivotal.io.

View File

@@ -0,0 +1,397 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<profiles version="12">
<profile kind="CodeFormatterProfile" name="Spring Boot Java Conventions" version="12">
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_ellipsis" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration"
value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters"
value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_imports" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags" value="do not insert"/>
<setting
id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_javadoc_comments" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.indentation.size" value="4"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration"
value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.disabling_tag" value="@formatter:off"/>
<setting id="org.eclipse.jdt.core.formatter.continuation_indentation" value="2"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_enum_constants" value="49"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_imports" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_package" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_binary_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations"
value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant" value="16"/>
<setting
id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.indent_root_tags" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.enabling_tag" value="@formatter:on"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return"
value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments"
value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer"
value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration"
value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column" value="false"/>
<setting id="org.eclipse.jdt.core.compiler.problem.enumIdentifier" value="error"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_statements_compare_to_block" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.line_length" value="90"/>
<setting id="org.eclipse.jdt.core.formatter.use_on_off_tags" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration"
value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments"
value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_method_declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_binary_expression" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference"
value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations"
value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header"
value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_lambda_body" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.compact_else_if" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments"
value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.compiler.problem.assertIdentifier" value="error"/>
<setting id="org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_binary_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_unary_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_ellipsis" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_line_comments" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.align_type_members_on_columns" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_assignment" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_conditional_expression" value="80"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block_in_case" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_header" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while" value="insert"/>
<setting id="org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode" value="enabled"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_method_declaration" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.join_wrapped_lines" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration"
value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_resources_in_try" value="80"/>
<setting id="org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column" value="false"/>
<setting id="org.eclipse.jdt.core.compiler.source" value="1.8"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws"
value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.tabulation.size" value="4"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_source_code" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer"
value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_field" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer" value="2"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_method" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw"
value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.compiler.codegen.targetPlatform" value="1.8"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_switch" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters"
value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_type_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer"
value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_html" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters"
value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_compact_if" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.indent_empty_lines" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_unary_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_label" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header"
value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional" value="insert"/>
<setting
id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_member_type" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference"
value="do not insert"/>
<setting
id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression"
value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_block_comments" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_lambda_arrow" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration"
value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws"
value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_statements_compare_to_body" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_multiple_fields" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments"
value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_array_initializer" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_binary_operator" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration"
value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch" value="do not insert"/>
<setting id="org.eclipse.jdt.core.compiler.compliance" value="1.8"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration"
value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_constant" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_type_declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_package" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments" value="do not insert"/>
<setting
id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header"
value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_lambda_arrow" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration"
value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.join_lines_in_comments" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.indent_parameter_description" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.tabulation.char" value="tab"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_import_groups" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.lineSplit" value="120"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch" value="insert"/>
</profile>
</profiles>

View File

@@ -0,0 +1,7 @@
#Organize Import Order
#Wed Apr 26 12:53:22 EDT 2017
4=\#
3=org.springframework
2=
1=javax
0=java

View File

@@ -57,23 +57,23 @@ public abstract class AbstractBinderTests<B extends AbstractTestBinder<? extends
protected B testBinder;
/**
* Subclasses may override this default value to have tests wait longer for a message receive, for example if
* running
* in an environment that is known to be slow (e.g. travis).
* Subclasses may override this default value to have tests wait longer for a message
* receive, for example if running in an environment that is known to be slow (e.g.
* travis).
*/
protected double timeoutMultiplier = 1.0D;
/**
* Attempt to receive a message on the given channel,
* waiting up to 1s (times the {@link #timeoutMultiplier}).
* Attempt to receive a message on the given channel, waiting up to 1s (times the
* {@link #timeoutMultiplier}).
*/
protected Message<?> receive(PollableChannel channel) {
return receive(channel, 1);
}
/**
* Attempt to receive a message on the given channel,
* waiting up to 1s * additionalMultiplier * {@link #timeoutMultiplier}).
* Attempt to receive a message on the given channel, waiting up to 1s *
* additionalMultiplier * {@link #timeoutMultiplier}).
*
* Allows accomodating tests which are slower than normal (e.g. retry).
*/
@@ -170,7 +170,6 @@ public abstract class AbstractBinderTests<B extends AbstractTestBinder<? extends
moduleOutputChannel1.send(message1);
moduleOutputChannel2.send(message2);
Message<?>[] messages = new Message[2];
messages[0] = receive(moduleInputChannel);
messages[1] = receive(moduleInputChannel);
@@ -211,7 +210,6 @@ public abstract class AbstractBinderTests<B extends AbstractTestBinder<? extends
consumerBinding.unbind();
}
protected abstract B getBinder() throws Exception;
protected abstract CP createConsumerProperties();
@@ -224,15 +222,14 @@ public abstract class AbstractBinderTests<B extends AbstractTestBinder<? extends
return bindingProperties;
}
protected BindingProperties createProducerBindingProperties(PP producerProperties) {
BindingProperties bindingProperties = new BindingProperties();
bindingProperties.setProducer(producerProperties);
return bindingProperties;
}
protected DirectChannel createBindableChannel(String channelName, BindingProperties bindingProperties) throws
Exception {
protected DirectChannel createBindableChannel(String channelName, BindingProperties bindingProperties)
throws Exception {
BindingServiceProperties bindingServiceProperties = new BindingServiceProperties();
bindingServiceProperties.getBindings().put(channelName, bindingProperties);
ConfigurableApplicationContext applicationContext = new GenericApplicationContext();
@@ -259,7 +256,8 @@ public abstract class AbstractBinderTests<B extends AbstractTestBinder<? extends
}
/**
* If appropriate, let the binder middleware settle down a bit while binding/unbinding actually happens.
* If appropriate, let the binder middleware settle down a bit while binding/unbinding
* actually happens.
*/
protected void binderBindUnbindLatency() throws InterruptedException {
// default none

View File

@@ -28,24 +28,16 @@ import org.springframework.messaging.MessageChannel;
* @author Gary Russell
* @author Mark Fisher
*/
public abstract class AbstractTestBinder<C extends AbstractBinder<MessageChannel, CP, PP>, CP extends ConsumerProperties, PP extends ProducerProperties> implements Binder<MessageChannel, CP, PP> {
public abstract class AbstractTestBinder<C extends AbstractBinder<MessageChannel, CP, PP>, CP extends ConsumerProperties, PP extends ProducerProperties>
implements Binder<MessageChannel, CP, PP> {
protected Set<String> queues = new HashSet<String>();
private C binder;
public void setBinder(C binder) {
try {
binder.afterPropertiesSet();
}
catch (Exception e) {
throw new RuntimeException("Failed to initialize binder", e);
}
this.binder = binder;
}
@Override
public Binding<MessageChannel> bindConsumer(String name, String group, MessageChannel moduleInputChannel, CP properties) {
public Binding<MessageChannel> bindConsumer(String name, String group, MessageChannel moduleInputChannel,
CP properties) {
queues.add(name);
return binder.bindConsumer(name, group, moduleInputChannel, properties);
}
@@ -66,4 +58,14 @@ public abstract class AbstractTestBinder<C extends AbstractBinder<MessageChannel
return this.binder;
}
public void setBinder(C binder) {
try {
binder.afterPropertiesSet();
}
catch (Exception e) {
throw new RuntimeException("Failed to initialize binder", e);
}
this.binder = binder;
}
}

View File

@@ -25,7 +25,8 @@ import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.MapPropertySource;
/**
* An {@link EnvironmentPostProcessor} that sets some common configuration properties (log config etc.,) for binder tests.
* An {@link EnvironmentPostProcessor} that sets some common configuration properties (log
* config etc.,) for binder tests.
*
* @author Ilayaperumal Gopinathan
*/

View File

@@ -25,19 +25,18 @@ import org.springframework.integration.support.utils.IntegrationUtils;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
/**
*
* @author Gary Russell
*/
public abstract class BinderTestUtils {
private static final MessageBuilderFactory mbf = new MutableMessageBuilderFactory();
public static final AbstractApplicationContext MOCK_AC = mock(AbstractApplicationContext.class);
public static final ConfigurableListableBeanFactory MOCK_BF = mock(ConfigurableListableBeanFactory.class);
private static final MessageBuilderFactory mbf = new MutableMessageBuilderFactory();
static {
when(MOCK_BF.getBean(IntegrationUtils.INTEGRATION_MESSAGE_BUILDER_FACTORY_BEAN_NAME,
MessageBuilderFactory.class)).thenReturn(mbf);

View File

@@ -44,8 +44,7 @@ import static org.assertj.core.api.Assertions.assertThat;
* @author Mark Fisher
* @author Marius Bogoevici
*/
public abstract class PartitionCapableBinderTests<B extends AbstractTestBinder<? extends
AbstractBinder<MessageChannel, CP, PP>, CP, PP>, CP extends ConsumerProperties, PP extends ProducerProperties>
public abstract class PartitionCapableBinderTests<B extends AbstractTestBinder<? extends AbstractBinder<MessageChannel, CP, PP>, CP, PP>, CP extends ConsumerProperties, PP extends ProducerProperties>
extends AbstractBinderTests<B, CP, PP> {
protected static final SpelExpressionParser spelExpressionParser = new SpelExpressionParser();

View File

@@ -18,7 +18,6 @@ package org.springframework.cloud.stream.binder;
import org.springframework.messaging.Message;
/**
* @author Gary Russell
*/

View File

@@ -17,9 +17,8 @@
package org.springframework.cloud.stream.binder;
/**
* Represents an out-of-band connection to the underlying middleware,
* so that tests can check that some messages actually do (or do not)
* transit through it.
* Represents an out-of-band connection to the underlying middleware, so that tests can
* check that some messages actually do (or do not) transit through it.
*
* @author Eric Bottard
*/

View File

@@ -43,7 +43,6 @@ import org.springframework.util.MimeTypeUtils;
import static org.assertj.core.api.Assertions.assertThat;
/**
* @author Gary Russell
* @author David Turanski
@@ -132,7 +131,6 @@ public class MessageChannelBinderSupportTests {
assertThat(reconstructed.get(MessageHeaders.CONTENT_TYPE)).isEqualTo(MimeTypeUtils.APPLICATION_JSON_VALUE);
}
@Test
public void testContentTypePreservedForNonSCStApp() {
Message<String> inbound = MessageBuilder.withPayload("{\"foo\":\"bar\"}")
@@ -253,19 +251,6 @@ public class MessageChannelBinderSupportTests {
}
public class TestMessageChannelBinder extends AbstractBinder<MessageChannel, ConsumerProperties, ProducerProperties> {
@Override
protected Binding<MessageChannel> doBindConsumer(String name, String group, MessageChannel channel, ConsumerProperties properties) {
return null;
}
@Override
public Binding<MessageChannel> doBindProducer(String name, MessageChannel channel, ProducerProperties properties) {
return null;
}
}
private static class TupleRegistrar implements KryoRegistrar {
private final TupleKryoRegistrar delegate = new TupleKryoRegistrar();
@@ -280,4 +265,20 @@ public class MessageChannelBinderSupportTests {
}
}
public class TestMessageChannelBinder
extends AbstractBinder<MessageChannel, ConsumerProperties, ProducerProperties> {
@Override
protected Binding<MessageChannel> doBindConsumer(String name, String group, MessageChannel channel,
ConsumerProperties properties) {
return null;
}
@Override
public Binding<MessageChannel> doBindProducer(String name, MessageChannel channel,
ProducerProperties properties) {
return null;
}
}
}

View File

@@ -33,7 +33,6 @@ import org.springframework.integration.codec.kryo.FileKryoRegistrar;
import org.springframework.integration.codec.kryo.KryoRegistrar;
import org.springframework.integration.codec.kryo.PojoCodec;
/**
* Auto configures {@link PojoCodec} if Kryo is on the class path.
* @author David Turanski
@@ -53,8 +52,7 @@ public class KryoCodecAutoConfiguration {
@Bean
@ConditionalOnMissingBean(PojoCodec.class)
public PojoCodec codec() {
Map<String, KryoRegistrar> kryoRegistrarMap = applicationContext.getBeansOfType(KryoRegistrar
.class);
Map<String, KryoRegistrar> kryoRegistrarMap = applicationContext.getBeansOfType(KryoRegistrar.class);
return new PojoCodec(new ArrayList<>(kryoRegistrarMap.values()), kryoCodecProperties.isReferences());
}

View File

@@ -40,7 +40,7 @@ import static org.assertj.core.api.Assertions.assertThat;
* @author Ilayaperumal Gopinathan
*/
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = {ContentTypeOutboundSourceTests.TestSource.class})
@SpringBootTest(classes = { ContentTypeOutboundSourceTests.TestSource.class })
public class ContentTypeOutboundSourceTests {
@Autowired
@@ -54,8 +54,9 @@ public class ContentTypeOutboundSourceTests {
@SuppressWarnings("unchecked")
public void testMessageHeaderWhenNoExplicitContentTypeOnMessage() throws Exception {
testSource.output().send(MessageBuilder.withPayload("{\"message\":\"Hi\"}").build());
Message<String> received = (Message<String>) ((TestSupportBinder) binderFactory.getBinder(null, MessageChannel.class))
.messageCollector().forChannel(testSource.output()).poll();
Message<String> received = (Message<String>) ((TestSupportBinder) binderFactory.getBinder(null,
MessageChannel.class))
.messageCollector().forChannel(testSource.output()).poll();
assertThat(received.getHeaders().get(MessageHeaders.CONTENT_TYPE).toString()).isEqualTo("application/json");
assertThat(received).hasFieldOrPropertyWithValue("payload", "{\"message\":\"Hi\"}");
}
@@ -67,4 +68,3 @@ public class ContentTypeOutboundSourceTests {
}
}

View File

@@ -71,8 +71,9 @@ public class CustomMessageConverterTests {
BarConverter.class, DefaultDatatypeChannelMessageConverter.class);
testSource.output().send(MessageBuilder.withPayload(new Foo("hi")).build());
@SuppressWarnings("unchecked")
Message<String> received = (Message<String>) ((TestSupportBinder) binderFactory.getBinder(null, MessageChannel.class))
.messageCollector().forChannel(testSource.output()).poll(1, TimeUnit.SECONDS);
Message<String> received = (Message<String>) ((TestSupportBinder) binderFactory.getBinder(null,
MessageChannel.class))
.messageCollector().forChannel(testSource.output()).poll(1, TimeUnit.SECONDS);
Assert.assertThat(received, notNullValue());
assertThat(received.getHeaders().get(MessageHeaders.CONTENT_TYPE)).isEqualTo(MimeType.valueOf("test/foo"));
}
@@ -128,7 +129,6 @@ public class CustomMessageConverterTests {
super(MimeType.valueOf("test/bar"));
}
@Override
protected boolean supports(Class<?> clazz) {
return clazz.equals(Bar.class);

View File

@@ -58,7 +58,8 @@ public class DeserializeJSONToJavaTypeTests {
@Test
public void testMessageDeserialized() throws Exception {
testProcessor.input().send(MessageBuilder.withPayload("{\"name\":\"Bar\"}").setHeader("contentType", "application/json").build());
testProcessor.input().send(
MessageBuilder.withPayload("{\"name\":\"Bar\"}").setHeader("contentType", "application/json").build());
@SuppressWarnings("unchecked")
Message<?> received = ((TestSupportBinder) binderFactory.getBinder(null, MessageChannel.class))
.messageCollector().forChannel(testProcessor.output()).poll(1, TimeUnit.SECONDS);

View File

@@ -56,7 +56,8 @@ public class ErrorChannelTests {
@Test
public void testErrorChannelBinding() throws Exception {
Message<?> message = ((TestSupportBinder) binderFactory.getBinder(null, MessageChannel.class)).messageCollector().forChannel(errorChannel).poll(10, TimeUnit.SECONDS);
Message<?> message = ((TestSupportBinder) binderFactory.getBinder(null, MessageChannel.class))
.messageCollector().forChannel(errorChannel).poll(10, TimeUnit.SECONDS);
Assert.isTrue(message instanceof ErrorMessage, "Message should be an instance of ErrorMessage");
Assert.isTrue(message.getPayload() instanceof MessagingException, "Message payload should be an instance" +
"of MessagingException");
@@ -81,4 +82,3 @@ public class ErrorChannelTests {
}
}
}

View File

@@ -61,10 +61,9 @@ public class InboundJsonToTupleConversionTest {
Message<?> received = ((TestSupportBinder) binderFactory.getBinder(null, MessageChannel.class))
.messageCollector().forChannel(testProcessor.output()).poll(1, TimeUnit.SECONDS);
assertThat(received).isNotNull();
assertThat(received.getPayload()).isEqualTo(TupleBuilder.tuple().of("name","foo"));
assertThat(received.getPayload()).isEqualTo(TupleBuilder.tuple().of("name", "foo"));
}
@EnableBinding(Processor.class)
@EnableAutoConfiguration
@PropertySource("classpath:/org/springframework/cloud/stream/config/inboundjsontuple/inbound-json-tuple.properties")

View File

@@ -21,7 +21,6 @@ import java.util.concurrent.TimeUnit;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -54,7 +53,8 @@ import static org.junit.Assert.assertNull;
* @author Gary Russell
*/
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = {MessageChannelConfigurerTests.TestSink.class, MessageChannelConfigurerTests.TestSource.class})
@SpringBootTest(classes = { MessageChannelConfigurerTests.TestSink.class,
MessageChannelConfigurerTests.TestSource.class })
public class MessageChannelConfigurerTests {
@Autowired
@@ -92,12 +92,13 @@ public class MessageChannelConfigurerTests {
@Test
public void testObjectMapperConfig() throws Exception {
CompositeMessageConverter converters = (CompositeMessageConverter) messageConverterFactory.getMessageConverterForType(MimeTypeUtils
.APPLICATION_JSON);
CompositeMessageConverter converters = (CompositeMessageConverter) messageConverterFactory
.getMessageConverterForType(MimeTypeUtils.APPLICATION_JSON);
for (MessageConverter converter : converters.getConverters()) {
DirectFieldAccessor converterAccessor = new DirectFieldAccessor(converter);
ObjectMapper objectMapper = (ObjectMapper) converterAccessor.getPropertyValue("objectMapper");
// assert that the ObjectMapper used by the converters is compliant with the Boot configuration
// assert that the ObjectMapper used by the converters is compliant with the
// Boot configuration
assertThat(!objectMapper.getSerializationConfig().isEnabled(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS))
.withFailMessage("SerializationFeature 'WRITE_DATES_AS_TIMESTAMPS' should be disabled");
// assert that the globally set bean is used by the converters

View File

@@ -61,7 +61,8 @@ public class StreamListenerAnnotatedMethodArgumentsTests {
sink.input().send(MessageBuilder.withPayload("{\"foo\":\"barbar" + id + "\"}")
.setHeader("contentType", "application/json").setHeader("testHeader", "testValue").build());
assertThat(testPojoWithAnnotatedArguments.receivedArguments).hasSize(3);
assertThat(testPojoWithAnnotatedArguments.receivedArguments.get(0)).isInstanceOf(StreamListenerTestUtils.FooPojo.class);
assertThat(testPojoWithAnnotatedArguments.receivedArguments.get(0))
.isInstanceOf(StreamListenerTestUtils.FooPojo.class);
assertThat(testPojoWithAnnotatedArguments.receivedArguments.get(0)).hasFieldOrPropertyWithValue("foo",
"barbar" + id);
assertThat(testPojoWithAnnotatedArguments.receivedArguments.get(1)).isInstanceOf(Map.class);
@@ -77,7 +78,7 @@ public class StreamListenerAnnotatedMethodArgumentsTests {
public void testInputAnnotationAtMethodParameter() throws Exception {
try {
SpringApplication.run(TestPojoWithInvalidInputAnnotatedArgument.class, "--server.port=0");
fail("Exception expected: "+ INVALID_DECLARATIVE_METHOD_PARAMETERS);
fail("Exception expected: " + INVALID_DECLARATIVE_METHOD_PARAMETERS);
}
catch (BeanCreationException e) {
assertThat(e.getCause().getMessage()).contains(INVALID_DECLARATIVE_METHOD_PARAMETERS);

View File

@@ -73,11 +73,6 @@ public class StreamListenerAnnotationBeanPostProcessorOverrideTest {
public static class TestPojoWithAnnotatedArguments {
List<StreamListenerTestUtils.FooPojo> receivedFoo = new ArrayList<>();
@StreamListener(value = Sink.INPUT, condition = "foo")
public void receive(@Payload StreamListenerTestUtils.FooPojo fooPojo) {
this.receivedFoo.add(fooPojo);
}
/**
* Overrides the default {@link StreamListenerAnnotationBeanPostProcessor}.
@@ -86,12 +81,19 @@ public class StreamListenerAnnotationBeanPostProcessorOverrideTest {
public static BeanPostProcessor streamListenerAnnotationBeanPostProcessor() {
return new StreamListenerAnnotationBeanPostProcessor() {
@Override
protected StreamListener postProcessAnnotation(StreamListener originalAnnotation, Method annotatedMethod) {
Map<String,Object> attributes = new HashMap<>(AnnotationUtils.getAnnotationAttributes(originalAnnotation));
protected StreamListener postProcessAnnotation(StreamListener originalAnnotation,
Method annotatedMethod) {
Map<String, Object> attributes = new HashMap<>(
AnnotationUtils.getAnnotationAttributes(originalAnnotation));
attributes.put("condition", "headers['type']=='" + originalAnnotation.condition() + "'");
return AnnotationUtils.synthesizeAnnotation(attributes, StreamListener.class, annotatedMethod);
}
};
}
@StreamListener(value = Sink.INPUT, condition = "foo")
public void receive(@Payload StreamListenerTestUtils.FooPojo fooPojo) {
this.receivedFoo.add(fooPojo);
}
}
}

View File

@@ -40,11 +40,40 @@ import org.springframework.messaging.handler.annotation.Payload;
import static org.assertj.core.api.Assertions.assertThat;
@Target({ ElementType.METHOD, ElementType.ANNOTATION_TYPE })
@Retention(RetentionPolicy.RUNTIME)
@MessageMapping
@Documented
@StreamListener
@interface EventHandler {
/**
* The name of the binding target (e.g. channel) that the method subscribes to.
* @return the name of the binding target.
*/
@AliasFor(annotation = StreamListener.class, attribute = "target")
String value() default "";
/**
* The name of the binding target (e.g. channel) that the method subscribes to.
* @return the name of the binding target.
*/
@AliasFor(annotation = StreamListener.class, attribute = "target")
String target() default "";
/**
* A condition that must be met by all items that are dispatched to this method.
* @return a SpEL expression that must evaluate to a {@code boolean} value.
*/
@AliasFor(annotation = StreamListener.class, attribute = "condition")
String condition() default "";
}
/**
* @author David Turanski
*/
public class StreamListenerAsMetaAnnotationTests {
@Test
public void testCustomAnnotation() {
ConfigurableApplicationContext context = SpringApplication.run(TestPojoWithCustomAnnotatedArguments.class,
@@ -62,7 +91,7 @@ public class StreamListenerAsMetaAnnotationTests {
"barbar" + id);
context.close();
}
@Test
public void testAnnotation() {
ConfigurableApplicationContext context = SpringApplication.run(TestPojoWithAnnotatedArguments.class,
@@ -80,7 +109,7 @@ public class StreamListenerAsMetaAnnotationTests {
"barbar" + id);
context.close();
}
@EnableBinding(Sink.class)
@EnableAutoConfiguration
public static class TestPojoWithCustomAnnotatedArguments {
@@ -94,7 +123,7 @@ public class StreamListenerAsMetaAnnotationTests {
this.receivedFoo.add(fooPojo);
}
}
@EnableBinding(Sink.class)
@EnableAutoConfiguration
public static class TestPojoWithAnnotatedArguments {
@@ -109,32 +138,3 @@ public class StreamListenerAsMetaAnnotationTests {
}
}
}
@Target({ ElementType.METHOD, ElementType.ANNOTATION_TYPE })
@Retention(RetentionPolicy.RUNTIME)
@MessageMapping
@Documented
@StreamListener
@interface EventHandler {
/**
* The name of the binding target (e.g. channel) that the method subscribes to.
* @return the name of the binding target.
*/
@AliasFor(annotation=StreamListener.class, attribute="target")
String value() default "";
/**
* The name of the binding target (e.g. channel) that the method subscribes to.
* @return the name of the binding target.
*/
@AliasFor(annotation=StreamListener.class, attribute="target")
String target() default "";
/**
* A condition that must be met by all items that are dispatched to this method.
* @return a SpEL expression that must evaluate to a {@code boolean} value.
*/
@AliasFor(annotation=StreamListener.class, attribute="condition")
String condition() default "";
}

View File

@@ -63,6 +63,7 @@ public class StreamListenerContentTypeConversionTests {
public static class TestSinkWithContentTypeConversion {
List<StreamListenerTestUtils.FooPojo> receivedArguments = new ArrayList<>();
CountDownLatch latch = new CountDownLatch(1);
@StreamListener(Sink.INPUT)

View File

@@ -64,8 +64,8 @@ public class StreamListenerDuplicateMappingTests {
context = SpringApplication.run(TestDuplicateMappingFromAbstractMethod.class, "--server.port=0");
}
catch (BeanCreationException e) {
String errorMessage = e.getCause().getMessage().startsWith("Duplicate @StreamListener mapping") ?
"Duplicate mapping exception is not expected" : "Test failed with exception";
String errorMessage = e.getCause().getMessage().startsWith("Duplicate @StreamListener mapping")
? "Duplicate mapping exception is not expected" : "Test failed with exception";
fail(errorMessage + ": " + e.getMessage());
}
finally {
@@ -75,6 +75,14 @@ public class StreamListenerDuplicateMappingTests {
}
}
public interface GenericSink<T extends Base> {
void testMethod(T msg);
}
public interface Base {
}
@EnableBinding(Processor.class)
@EnableAutoConfiguration
public static class TestMultipleMappingsWithReturnValue {
@@ -102,14 +110,6 @@ public class StreamListenerDuplicateMappingTests {
}
}
public interface GenericSink<T extends Base> {
void testMethod(T msg);
}
public interface Base {
}
public class TestBase implements Base {
}

View File

@@ -79,7 +79,8 @@ public class StreamListenerHandlerMethodTests {
@Test
public void testMethodWithObjectAsMethodArgument() throws Exception {
ConfigurableApplicationContext context = SpringApplication.run(TestMethodWithObjectAsMethodArgument.class, "--server.port=0");
ConfigurableApplicationContext context = SpringApplication.run(TestMethodWithObjectAsMethodArgument.class,
"--server.port=0");
Processor processor = context.getBean(Processor.class);
String id = UUID.randomUUID().toString();
final CountDownLatch latch = new CountDownLatch(1);
@@ -94,11 +95,13 @@ public class StreamListenerHandlerMethodTests {
@Test
public void testStreamListenerMethodWithTargetBeanFromOutside() throws Exception {
ConfigurableApplicationContext context = SpringApplication.run(TestStreamListenerMethodWithTargetBeanFromOutside.class, "--server.port=0");
ConfigurableApplicationContext context = SpringApplication
.run(TestStreamListenerMethodWithTargetBeanFromOutside.class, "--server.port=0");
Sink sink = context.getBean(Sink.class);
final String testMessageToSend = "testing";
sink.input().send(MessageBuilder.withPayload(testMessageToSend).build());
DirectChannel directChannel = (DirectChannel) context.getBean(testMessageToSend.toUpperCase(), MessageChannel.class);
DirectChannel directChannel = (DirectChannel) context.getBean(testMessageToSend.toUpperCase(),
MessageChannel.class);
MessageCollector messageCollector = context.getBean(MessageCollector.class);
Message<?> result = messageCollector.forChannel(directChannel).poll(1000, TimeUnit.MILLISECONDS);
sink.input().send(MessageBuilder.withPayload(testMessageToSend).build());
@@ -159,7 +162,8 @@ public class StreamListenerHandlerMethodTests {
}
catch (BeanCreationException e) {
assertThat(e.getCause()).isInstanceOf(IllegalArgumentException.class);
assertThat(e.getCause()).hasMessageContaining(StreamListenerErrorMessages.INVALID_DECLARATIVE_METHOD_PARAMETERS);
assertThat(e.getCause())
.hasMessageContaining(StreamListenerErrorMessages.INVALID_DECLARATIVE_METHOD_PARAMETERS);
}
}
@@ -232,9 +236,11 @@ public class StreamListenerHandlerMethodTests {
@Test
public void testMethodWithMultipleInputParameters() throws Exception {
ConfigurableApplicationContext context = SpringApplication.run(TestMethodWithMultipleInputParameters.class, "--server.port=0");
ConfigurableApplicationContext context = SpringApplication.run(TestMethodWithMultipleInputParameters.class,
"--server.port=0");
Processor processor = context.getBean(Processor.class);
StreamListenerTestUtils.FooInboundChannel1 inboundChannel2 = context.getBean(StreamListenerTestUtils.FooInboundChannel1.class);
StreamListenerTestUtils.FooInboundChannel1 inboundChannel2 = context
.getBean(StreamListenerTestUtils.FooInboundChannel1.class);
String id = UUID.randomUUID().toString();
final CountDownLatch latch = new CountDownLatch(2);
((SubscribableChannel) processor.output()).subscribe(new MessageHandler() {
@@ -254,10 +260,12 @@ public class StreamListenerHandlerMethodTests {
@Test
public void testMethodWithMultipleOutputParameters() throws Exception {
ConfigurableApplicationContext context = SpringApplication.run(TestMethodWithMultipleOutputParameters.class, "--server.port=0");
ConfigurableApplicationContext context = SpringApplication.run(TestMethodWithMultipleOutputParameters.class,
"--server.port=0");
Processor processor = context.getBean(Processor.class);
String id = UUID.randomUUID().toString();
StreamListenerTestUtils.FooOutboundChannel1 source2 = context.getBean(StreamListenerTestUtils.FooOutboundChannel1.class);
StreamListenerTestUtils.FooOutboundChannel1 source2 = context
.getBean(StreamListenerTestUtils.FooOutboundChannel1.class);
final CountDownLatch latch = new CountDownLatch(2);
((SubscribableChannel) processor.output()).subscribe(new MessageHandler() {
@Override
@@ -281,28 +289,31 @@ public class StreamListenerHandlerMethodTests {
context.close();
}
@EnableBinding({Processor.class, StreamListenerTestUtils.FooOutboundChannel1.class})
@EnableBinding({ Processor.class, StreamListenerTestUtils.FooOutboundChannel1.class })
@EnableAutoConfiguration
public static class TestMethodWithMultipleOutputParameters {
@StreamListener
public void receive(@Input(Processor.INPUT) SubscribableChannel input, @Output(Processor.OUTPUT) final MessageChannel output1,
public void receive(@Input(Processor.INPUT) SubscribableChannel input,
@Output(Processor.OUTPUT) final MessageChannel output1,
@Output(StreamListenerTestUtils.FooOutboundChannel1.OUTPUT) final MessageChannel output2) {
input.subscribe(new MessageHandler() {
@Override
public void handleMessage(Message<?> message) throws MessagingException {
if (message.getHeaders().get("output").equals("output1")) {
output1.send(org.springframework.messaging.support.MessageBuilder.withPayload(message.getPayload().toString().toUpperCase()).build());
output1.send(org.springframework.messaging.support.MessageBuilder
.withPayload(message.getPayload().toString().toUpperCase()).build());
}
else if (message.getHeaders().get("output").equals("output2")) {
output2.send(org.springframework.messaging.support.MessageBuilder.withPayload(message.getPayload().toString().toLowerCase()).build());
output2.send(org.springframework.messaging.support.MessageBuilder
.withPayload(message.getPayload().toString().toLowerCase()).build());
}
}
});
}
}
@EnableBinding({Sink.class})
@EnableBinding({ Sink.class })
@EnableAutoConfiguration
public static class TestMethodWithoutInput {
@@ -311,7 +322,7 @@ public class StreamListenerHandlerMethodTests {
}
}
@EnableBinding({Processor.class})
@EnableBinding({ Processor.class })
@EnableAutoConfiguration
public static class TestMethodWithObjectAsMethodArgument {
@@ -340,7 +351,7 @@ public class StreamListenerHandlerMethodTests {
}
}
@EnableBinding({Sink.class})
@EnableBinding({ Sink.class })
@EnableAutoConfiguration
public static class TestInvalidInputOnMethod {
@@ -350,7 +361,7 @@ public class StreamListenerHandlerMethodTests {
}
}
@EnableBinding({Sink.class})
@EnableBinding({ Sink.class })
@EnableAutoConfiguration
public static class TestAmbiguousMethodArguments1 {
@@ -359,27 +370,29 @@ public class StreamListenerHandlerMethodTests {
}
}
@EnableBinding({Sink.class})
@EnableBinding({ Sink.class })
@EnableAutoConfiguration
public static class TestAmbiguousMethodArguments2 {
@StreamListener(Processor.INPUT)
public void receive(@Payload StreamListenerTestUtils.FooPojo fooPojo, @Payload StreamListenerTestUtils.BarPojo barPojo) {
public void receive(@Payload StreamListenerTestUtils.FooPojo fooPojo,
@Payload StreamListenerTestUtils.BarPojo barPojo) {
}
}
@EnableBinding({Processor.class, StreamListenerTestUtils.FooOutboundChannel1.class})
@EnableBinding({ Processor.class, StreamListenerTestUtils.FooOutboundChannel1.class })
@EnableAutoConfiguration
public static class TestReturnTypeWithMultipleOutput {
@StreamListener
public String receive(@Input(Processor.INPUT) SubscribableChannel input1, @Output(Processor.OUTPUT) MessageChannel output1,
public String receive(@Input(Processor.INPUT) SubscribableChannel input1,
@Output(Processor.OUTPUT) MessageChannel output1,
@Output(StreamListenerTestUtils.FooOutboundChannel1.OUTPUT) MessageChannel output2) {
return "foo";
}
}
@EnableBinding({Processor.class, StreamListenerTestUtils.FooOutboundChannel1.class})
@EnableBinding({ Processor.class, StreamListenerTestUtils.FooOutboundChannel1.class })
@EnableAutoConfiguration
public static class TestInvalidReturnTypeWithNoOutput {
@@ -389,7 +402,7 @@ public class StreamListenerHandlerMethodTests {
}
}
@EnableBinding({Processor.class})
@EnableBinding({ Processor.class })
@EnableAutoConfiguration
public static class TestInvalidInputAnnotationWithNoValue {
@@ -398,7 +411,7 @@ public class StreamListenerHandlerMethodTests {
}
}
@EnableBinding({Processor.class})
@EnableBinding({ Processor.class })
@EnableAutoConfiguration
public static class TestInvalidOutputAnnotationWithNoValue {
@@ -407,7 +420,7 @@ public class StreamListenerHandlerMethodTests {
}
}
@EnableBinding({Sink.class})
@EnableBinding({ Sink.class })
@EnableAutoConfiguration
public static class TestMethodInvalidInboundName {
@@ -416,16 +429,17 @@ public class StreamListenerHandlerMethodTests {
}
}
@EnableBinding({Processor.class})
@EnableBinding({ Processor.class })
@EnableAutoConfiguration
public static class TestMethodInvalidOutboundName {
@StreamListener
public void receive(@Input(Processor.INPUT) SubscribableChannel input, @Output("invalid") MessageChannel output) {
public void receive(@Input(Processor.INPUT) SubscribableChannel input,
@Output("invalid") MessageChannel output) {
}
}
@EnableBinding({Sink.class})
@EnableBinding({ Sink.class })
@EnableAutoConfiguration
public static class TestMethodWithInputAsMethodAndParameter {
@@ -434,39 +448,44 @@ public class StreamListenerHandlerMethodTests {
}
}
@EnableBinding({Processor.class, StreamListenerTestUtils.FooOutboundChannel1.class})
@EnableBinding({ Processor.class, StreamListenerTestUtils.FooOutboundChannel1.class })
@EnableAutoConfiguration
public static class TestMethodWithOutputAsMethodAndParameter {
@StreamListener
@Output(StreamListenerTestUtils.FooOutboundChannel1.OUTPUT)
public void receive(@Input(Processor.INPUT) SubscribableChannel input, @Output(Processor.OUTPUT) final MessageChannel output1) {
public void receive(@Input(Processor.INPUT) SubscribableChannel input,
@Output(Processor.OUTPUT) final MessageChannel output1) {
input.subscribe(new MessageHandler() {
@Override
public void handleMessage(Message<?> message) throws MessagingException {
output1.send(org.springframework.messaging.support.MessageBuilder.withPayload(message.getPayload().toString().toUpperCase()).build());
output1.send(org.springframework.messaging.support.MessageBuilder
.withPayload(message.getPayload().toString().toUpperCase()).build());
}
});
}
}
@EnableBinding({Processor.class, StreamListenerTestUtils.FooInboundChannel1.class})
@EnableBinding({ Processor.class, StreamListenerTestUtils.FooInboundChannel1.class })
@EnableAutoConfiguration
public static class TestMethodWithMultipleInputParameters {
@StreamListener
public void receive(@Input(Processor.INPUT) SubscribableChannel input1, @Input(StreamListenerTestUtils.FooInboundChannel1.INPUT) SubscribableChannel input2,
public void receive(@Input(Processor.INPUT) SubscribableChannel input1,
@Input(StreamListenerTestUtils.FooInboundChannel1.INPUT) SubscribableChannel input2,
final @Output(Processor.OUTPUT) MessageChannel output) {
input1.subscribe(new MessageHandler() {
@Override
public void handleMessage(Message<?> message) throws MessagingException {
output.send(org.springframework.messaging.support.MessageBuilder.withPayload(message.getPayload().toString().toUpperCase()).build());
output.send(org.springframework.messaging.support.MessageBuilder
.withPayload(message.getPayload().toString().toUpperCase()).build());
}
});
input2.subscribe(new MessageHandler() {
@Override
public void handleMessage(Message<?> message) throws MessagingException {
output.send(org.springframework.messaging.support.MessageBuilder.withPayload(message.getPayload().toString().toUpperCase()).build());
output.send(org.springframework.messaging.support.MessageBuilder
.withPayload(message.getPayload().toString().toUpperCase()).build());
}
});
}

View File

@@ -56,7 +56,7 @@ public class StreamListenerMessageArgumentTests {
@Parameterized.Parameters
public static Collection InputConfigs() {
return Arrays.asList(new Class[] {TestPojoWithMessageArgument1.class, TestPojoWithMessageArgument2.class});
return Arrays.asList(new Class[] { TestPojoWithMessageArgument1.class, TestPojoWithMessageArgument2.class });
}
@Test

View File

@@ -52,11 +52,12 @@ import static org.assertj.core.api.Assertions.assertThat;
* @author Ilayaperumal Gopinathan
*/
@RunWith(StreamListenerMethodReturnWithConversionTests.class)
@Suite.SuiteClasses({StreamListenerMethodReturnWithConversionTests.TestReturnConversion.class,
StreamListenerMethodReturnWithConversionTests.TestReturnNoConversion.class})
@Suite.SuiteClasses({ StreamListenerMethodReturnWithConversionTests.TestReturnConversion.class,
StreamListenerMethodReturnWithConversionTests.TestReturnNoConversion.class })
public class StreamListenerMethodReturnWithConversionTests extends Suite {
public StreamListenerMethodReturnWithConversionTests(Class<?> klass, RunnerBuilder builder) throws InitializationError {
public StreamListenerMethodReturnWithConversionTests(Class<?> klass, RunnerBuilder builder)
throws InitializationError {
super(klass, builder);
}
@@ -71,7 +72,7 @@ public class StreamListenerMethodReturnWithConversionTests extends Suite {
@Parameterized.Parameters
public static Collection InputConfigs() {
return Arrays.asList(new Class[] {TestPojoWithMimeType1.class, TestPojoWithMimeType2.class});
return Arrays.asList(new Class[] { TestPojoWithMimeType1.class, TestPojoWithMimeType2.class });
}
@Test
@@ -87,10 +88,12 @@ public class StreamListenerMethodReturnWithConversionTests extends Suite {
TestPojoWithMimeType testPojoWithMimeType = context.getBean(TestPojoWithMimeType.class);
assertThat(testPojoWithMimeType.receivedPojos).hasSize(1);
assertThat(testPojoWithMimeType.receivedPojos.get(0)).hasFieldOrPropertyWithValue("foo", "barbar" + id);
Message<String> message = (Message<String>) collector.forChannel(processor.output()).poll(1, TimeUnit.SECONDS);
Message<String> message = (Message<String>) collector.forChannel(processor.output()).poll(1,
TimeUnit.SECONDS);
assertThat(message).isNotNull();
assertThat(message.getPayload()).isEqualTo("{\"bar\":\"barbar" + id + "\"}");
assertThat(message.getHeaders().get(MessageHeaders.CONTENT_TYPE, MimeType.class).includes(MimeTypeUtils.APPLICATION_JSON));
assertThat(message.getHeaders().get(MessageHeaders.CONTENT_TYPE, MimeType.class)
.includes(MimeTypeUtils.APPLICATION_JSON));
context.close();
}
}
@@ -106,7 +109,7 @@ public class StreamListenerMethodReturnWithConversionTests extends Suite {
@Parameterized.Parameters
public static Collection InputConfigs() {
return Arrays.asList(new Class[] {TestPojoWithMimeType1.class, TestPojoWithMimeType2.class});
return Arrays.asList(new Class[] { TestPojoWithMimeType1.class, TestPojoWithMimeType2.class });
}
@Test
@@ -121,8 +124,9 @@ public class StreamListenerMethodReturnWithConversionTests extends Suite {
TestPojoWithMimeType testPojoWithMimeType = context.getBean(TestPojoWithMimeType.class);
assertThat(testPojoWithMimeType.receivedPojos).hasSize(1);
assertThat(testPojoWithMimeType.receivedPojos.get(0)).hasFieldOrPropertyWithValue("foo", "barbar" + id);
Message<StreamListenerTestUtils.BarPojo> message = (Message<StreamListenerTestUtils.BarPojo>) collector.forChannel(processor.output()).poll(1,
TimeUnit.SECONDS);
Message<StreamListenerTestUtils.BarPojo> message = (Message<StreamListenerTestUtils.BarPojo>) collector
.forChannel(processor.output()).poll(1,
TimeUnit.SECONDS);
assertThat(message).isNotNull();
assertThat(message.getPayload().getBar()).isEqualTo("barbar" + id);
assertThat(message.getHeaders().get(MessageHeaders.CONTENT_TYPE, MimeType.class) == null);

View File

@@ -56,7 +56,7 @@ public class StreamListenerMethodWithReturnMessageTests {
@Parameterized.Parameters
public static Collection InputConfigs() {
return Arrays.asList(new Class[]{TestPojoWithMessageReturn1.class, TestPojoWithMessageReturn2.class});
return Arrays.asList(new Class[] { TestPojoWithMessageReturn1.class, TestPojoWithMessageReturn2.class });
}
@Test

View File

@@ -56,7 +56,7 @@ public class StreamListenerMethodWithReturnValueTests {
@Parameterized.Parameters
public static Collection InputConfigs() {
return Arrays.asList(new Class[]{TestStringProcessor1.class, TestStringProcessor2.class});
return Arrays.asList(new Class[] { TestStringProcessor1.class, TestStringProcessor2.class });
}
@Test

View File

@@ -26,6 +26,24 @@ import org.springframework.messaging.SubscribableChannel;
*/
public class StreamListenerTestUtils {
public interface FooInboundChannel1 {
String INPUT = "foo1-input";
@Input(FooInboundChannel1.INPUT)
SubscribableChannel input();
}
public interface FooOutboundChannel1 {
String OUTPUT = "foo1-output";
@Output(FooOutboundChannel1.OUTPUT)
MessageChannel output();
}
public static class FooPojo {
private String foo;
@@ -51,22 +69,4 @@ public class StreamListenerTestUtils {
this.bar = bar;
}
}
public interface FooInboundChannel1 {
String INPUT = "foo1-input";
@Input(FooInboundChannel1.INPUT)
SubscribableChannel input();
}
public interface FooOutboundChannel1 {
String OUTPUT = "foo1-output";
@Output(FooOutboundChannel1.OUTPUT)
MessageChannel output();
}
}

View File

@@ -73,13 +73,15 @@ public class StreamListenerWithAnnotatedInputOutputArgsTests {
}
catch (BeanCreationException e) {
assertThat(e.getCause()).isInstanceOf(IllegalArgumentException.class);
assertThat(e.getCause()).hasMessageContaining(StreamListenerErrorMessages.INVALID_DECLARATIVE_METHOD_PARAMETERS);
assertThat(e.getCause())
.hasMessageContaining(StreamListenerErrorMessages.INVALID_DECLARATIVE_METHOD_PARAMETERS);
}
}
@Test
public void testInputOutputArgsWithParameterOrderChanged() throws Exception {
ConfigurableApplicationContext context = SpringApplication.run(TestInputOutputArgsWithParameterOrderChanged.class, "--server.port=0");
ConfigurableApplicationContext context = SpringApplication
.run(TestInputOutputArgsWithParameterOrderChanged.class, "--server.port=0");
sendMessageAndValidate(context);
}
@@ -94,13 +96,13 @@ public class StreamListenerWithAnnotatedInputOutputArgsTests {
context.close();
}
@EnableBinding(Processor.class)
@EnableAutoConfiguration
public static class TestInputOutputArgs {
@StreamListener
public void receive(@Input(Processor.INPUT) SubscribableChannel input, @Output(Processor.OUTPUT) final MessageChannel output) {
public void receive(@Input(Processor.INPUT) SubscribableChannel input,
@Output(Processor.OUTPUT) final MessageChannel output) {
input.subscribe(new MessageHandler() {
@Override
public void handleMessage(Message<?> message) throws MessagingException {
@@ -115,7 +117,8 @@ public class StreamListenerWithAnnotatedInputOutputArgsTests {
public static class TestInputOutputArgsWithMoreParameters {
@StreamListener
public void receive(@Input(Processor.INPUT) SubscribableChannel input, @Output(Processor.OUTPUT) final MessageChannel output,
public void receive(@Input(Processor.INPUT) SubscribableChannel input,
@Output(Processor.OUTPUT) final MessageChannel output,
String someArg) {
input.subscribe(new MessageHandler() {
@Override
@@ -131,7 +134,8 @@ public class StreamListenerWithAnnotatedInputOutputArgsTests {
public static class TestInputOutputArgsWithInvalidBindableTarget {
@StreamListener
public void receive(@Input("invalid") SubscribableChannel input, @Output(Processor.OUTPUT) final MessageChannel output) {
public void receive(@Input("invalid") SubscribableChannel input,
@Output(Processor.OUTPUT) final MessageChannel output) {
input.subscribe(new MessageHandler() {
@Override
public void handleMessage(Message<?> message) throws MessagingException {
@@ -146,7 +150,8 @@ public class StreamListenerWithAnnotatedInputOutputArgsTests {
public static class TestInputOutputArgsWithParameterOrderChanged {
@StreamListener
public void receive(@Output(Processor.OUTPUT) final MessageChannel output, @Input("input") SubscribableChannel input) {
public void receive(@Output(Processor.OUTPUT) final MessageChannel output,
@Input("input") SubscribableChannel input) {
input.subscribe(new MessageHandler() {
@Override
public void handleMessage(Message<?> message) throws MessagingException {

View File

@@ -75,13 +75,16 @@ public class StreamListenerWithConditionsTest {
@SuppressWarnings("unchecked")
public void testConditionalFailsWithReturnValue() throws Exception {
try {
ConfigurableApplicationContext context = SpringApplication.run(TestConditionalOnMethodWithReturnValueFails.class,
ConfigurableApplicationContext context = SpringApplication.run(
TestConditionalOnMethodWithReturnValueFails.class,
"--server.port=0");
context.close();
fail("Context creation failure expected");
} catch (BeanCreationException e) {
}
catch (BeanCreationException e) {
assertThat(e).hasRootCauseInstanceOf(IllegalArgumentException.class);
assertThat(e.getCause()).hasMessageContaining(StreamListenerErrorMessages.CONDITION_ON_METHOD_RETURNING_VALUE);
assertThat(e.getCause())
.hasMessageContaining(StreamListenerErrorMessages.CONDITION_ON_METHOD_RETURNING_VALUE);
}
}
@@ -89,11 +92,13 @@ public class StreamListenerWithConditionsTest {
@SuppressWarnings("unchecked")
public void testConditionalFailsWithDeclarativeMethod() throws Exception {
try {
ConfigurableApplicationContext context = SpringApplication.run(TestConditionalOnDeclarativeMethodFails.class,
ConfigurableApplicationContext context = SpringApplication.run(
TestConditionalOnDeclarativeMethodFails.class,
"--server.port=0");
context.close();
fail("Context creation failure expected");
} catch (BeanCreationException e) {
}
catch (BeanCreationException e) {
assertThat(e).hasRootCauseInstanceOf(IllegalArgumentException.class);
assertThat(e.getCause()).hasMessageContaining(StreamListenerErrorMessages.CONDITION_ON_DECLARATIVE_METHOD);
}

View File

@@ -43,8 +43,7 @@ import static org.assertj.core.api.Assertions.assertThat;
* @since 1.2
*/
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = TextPlainConversionTest.FooProcessor.class,
webEnvironment = SpringBootTest.WebEnvironment.NONE)
@SpringBootTest(classes = TextPlainConversionTest.FooProcessor.class, webEnvironment = SpringBootTest.WebEnvironment.NONE)
public class TextPlainConversionTest {
@Autowired
@@ -83,7 +82,6 @@ public class TextPlainConversionTest {
assertThat(received.getPayload()).isEqualTo("Foo{name='Foo{name='Bar'}'}");
}
@EnableBinding(Processor.class)
@EnableAutoConfiguration
@PropertySource("classpath:/org/springframework/cloud/stream/config/textplain/text-plain.properties")

View File

@@ -44,10 +44,13 @@ public class AggregateApplicationTests {
@Test
@SuppressWarnings("unchecked")
public void testAggregateApplication() throws Exception {
ConfigurableApplicationContext context = new AggregateApplicationBuilder(TestSupportBinderAutoConfiguration.class).from(TestSource.class).to(TestProcessor.class).run();
TestSupportBinder testSupportBinder = (TestSupportBinder) context.getBean(BinderFactory.class).getBinder(null, MessageChannel.class);
ConfigurableApplicationContext context = new AggregateApplicationBuilder(
TestSupportBinderAutoConfiguration.class).from(TestSource.class).to(TestProcessor.class).run();
TestSupportBinder testSupportBinder = (TestSupportBinder) context.getBean(BinderFactory.class).getBinder(null,
MessageChannel.class);
MessageChannel processorOutput = testSupportBinder.getChannelForName("output");
Message<String> received = (Message<String>) (testSupportBinder.messageCollector().forChannel(processorOutput).poll(5, TimeUnit.SECONDS));
Message<String> received = (Message<String>) (testSupportBinder.messageCollector().forChannel(processorOutput)
.poll(5, TimeUnit.SECONDS));
Assert.assertThat(received, notNullValue());
Assert.assertTrue(received.getPayload().endsWith("processed"));
}

View File

@@ -35,7 +35,7 @@ public class ApplicationMetrics {
private final Date createdTime;
private String name;
private Collection<Metric<?>> metrics;
private Map<String, Object> properties;

View File

@@ -44,6 +44,8 @@ import org.springframework.util.PatternMatchUtils;
public class ApplicationMetricsProperties
implements ApplicationListener<ContextRefreshedEvent> {
private final MetricExportProperties metricExportProperties;
private String prefix = "";
@Value("${spring.application.name:${vcap.application.name:${spring.config.name:application}}}")
@@ -53,17 +55,23 @@ public class ApplicationMetricsProperties
private String[] properties;
private final MetricExportProperties metricExportProperties;
public TriggerProperties getTrigger() {
return metricExportProperties.findTrigger(BinderMetricsAutoConfiguration.APPLICATION_METRICS_EXPORTER_TRIGGER_NAME);
}
/**
* List of properties that are going to be appended to each message. This gets
* populate by onApplicationEvent, once the context refreshes to avoid overhead of
* doing per message basis.
*/
private Map<String, Object> exportProperties = new HashMap<>();
public ApplicationMetricsProperties(MetricExportProperties metricExportProperties) {
Assert.notNull(metricExportProperties, "'metricsExportProperties' cannot be null");
this.metricExportProperties = metricExportProperties;
}
public TriggerProperties getTrigger() {
return metricExportProperties
.findTrigger(BinderMetricsAutoConfiguration.APPLICATION_METRICS_EXPORTER_TRIGGER_NAME);
}
public String getPrefix() {
return prefix;
}
@@ -91,13 +99,6 @@ public class ApplicationMetricsProperties
this.properties = properties;
}
/**
* List of properties that are going to be appended to each message. This gets
* populate by onApplicationEvent, once the context refreshes to avoid overhead of
* doing per message basis.
*/
private Map<String, Object> exportProperties = new HashMap<>();
public Map<String, Object> getExportProperties() {
return exportProperties;
}
@@ -137,7 +138,7 @@ public class ApplicationMetricsProperties
relaxedLoop: for (String relaxedPropertyName : relaxedNames) {
if (isMatch(relaxedPropertyName, this.properties, null)) {
Object value = source.getProperty(propertyName);
String stringValue = ObjectUtils.nullSafeToString(value);
String stringValue = ObjectUtils.nullSafeToString(value);
Object exportedValue = null;
if (value != null) {
exportedValue = stringValue.startsWith("#{")

View File

@@ -40,8 +40,8 @@ import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;
/**
* Autoconfiguration registering an {@link Exporter} that publishes application metrics over
* the {@link Emitter#applicationMetrics()} channel.
* Autoconfiguration registering an {@link Exporter} that publishes application metrics
* over the {@link Emitter#applicationMetrics()} channel.
*
* @author Vinicius Carvalho
* @author Marius Bogoevici
@@ -56,19 +56,15 @@ import org.springframework.context.annotation.Lazy;
+ ".destination")
public class BinderMetricsAutoConfiguration {
public static Log log = LogFactory.getLog(BinderMetricsAutoConfiguration.class);
public static final String APPLICATION_METRICS_EXPORTER_TRIGGER_NAME = "application";
@Bean
public MetricJsonSerializer metricJsonSerializer() {
return new MetricJsonSerializer();
}
public static Log log = LogFactory.getLog(BinderMetricsAutoConfiguration.class);
/**
* Postprocessor for installing the {@link ApplicationMetricsExporter} as an
* exporter under the name {@code application}.
* @param endpoint the metrics endpoint (lazy reference to prevent early initialization)
* Postprocessor for installing the {@link ApplicationMetricsExporter} as an exporter
* under the name {@code application}.
* @param endpoint the metrics endpoint (lazy reference to prevent early
* initialization)
* @param emitter the emitter bound interface
* @param properties application metrics properties
* @return
@@ -101,4 +97,9 @@ public class BinderMetricsAutoConfiguration {
};
}
@Bean
public MetricJsonSerializer metricJsonSerializer() {
return new MetricJsonSerializer();
}
}

View File

@@ -46,6 +46,12 @@ public class MetricJsonSerializer {
private static final BlockingQueue<DateFormat> formatters = new LinkedBlockingQueue<DateFormat>();
private static DateFormat defaultDateFormat() {
DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSX");
df.setTimeZone(TimeZone.getTimeZone("GMT"));
return df;
}
public static class Serializer extends JsonSerializer<Metric<?>> {
@Override
@@ -95,10 +101,4 @@ public class MetricJsonSerializer {
}
}
private static DateFormat defaultDateFormat() {
DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSX");
df.setTimeZone(TimeZone.getTimeZone("GMT"));
return df;
}
}

View File

@@ -101,7 +101,8 @@ public class ApplicationMetricsExporterTests {
.poll(10, TimeUnit.SECONDS);
Assert.assertNotNull(message);
ObjectMapper mapper = applicationContext.getBean(ObjectMapper.class);
ApplicationMetrics applicationMetrics = mapper.readValue((String) message.getPayload(), ApplicationMetrics.class);
ApplicationMetrics applicationMetrics = mapper.readValue((String) message.getPayload(),
ApplicationMetrics.class);
Assert.assertTrue(contains("integration.channel.errorChannel.errorRate.mean",
applicationMetrics.getMetrics()));
Assert.assertTrue(contains("mem", applicationMetrics.getMetrics()));
@@ -171,7 +172,8 @@ public class ApplicationMetricsExporterTests {
.poll(10, TimeUnit.SECONDS);
Assert.assertNotNull(message);
ObjectMapper mapper = applicationContext.getBean(ObjectMapper.class);
ApplicationMetrics applicationMetrics = mapper.readValue((String) message.getPayload(), ApplicationMetrics.class);
ApplicationMetrics applicationMetrics = mapper.readValue((String) message.getPayload(),
ApplicationMetrics.class);
Assert.assertFalse(contains("integration.channel.errorChannel.errorRate.mean",
applicationMetrics.getMetrics()));
Assert.assertTrue(contains("mem", applicationMetrics.getMetrics()));
@@ -193,7 +195,8 @@ public class ApplicationMetricsExporterTests {
.poll(10, TimeUnit.SECONDS);
Assert.assertNotNull(message);
ObjectMapper mapper = applicationContext.getBean(ObjectMapper.class);
ApplicationMetrics applicationMetrics = mapper.readValue((String) message.getPayload(), ApplicationMetrics.class);
ApplicationMetrics applicationMetrics = mapper.readValue((String) message.getPayload(),
ApplicationMetrics.class);
Assert.assertFalse(contains("mem", applicationMetrics.getMetrics()));
Assert.assertTrue(contains("integration.channel.errorChannel.errorRate.mean",
applicationMetrics.getMetrics()));
@@ -225,7 +228,8 @@ public class ApplicationMetricsExporterTests {
.poll(10, TimeUnit.SECONDS);
Assert.assertNotNull(message);
ObjectMapper mapper = applicationContext.getBean(ObjectMapper.class);
ApplicationMetrics applicationMetrics = mapper.readValue((String) message.getPayload(), ApplicationMetrics.class);
ApplicationMetrics applicationMetrics = mapper.readValue((String) message.getPayload(),
ApplicationMetrics.class);
Assert.assertTrue(contains("integration.channel.errorChannel.errorRate.mean",
applicationMetrics.getMetrics()));
Assertions.assertThat(applicationMetrics.getProperties().get("spring.cloud.application.guid"))
@@ -260,13 +264,15 @@ public class ApplicationMetricsExporterTests {
.poll(10, TimeUnit.SECONDS);
Assert.assertNotNull(message);
ObjectMapper mapper = applicationContext.getBean(ObjectMapper.class);
ApplicationMetrics applicationMetrics = mapper.readValue((String) message.getPayload(), ApplicationMetrics.class);
ApplicationMetrics applicationMetrics = mapper.readValue((String) message.getPayload(),
ApplicationMetrics.class);
Assert.assertTrue(contains("integration.channel.errorChannel.errorRate.mean",
applicationMetrics.getMetrics()));
Assertions.assertThat(applicationMetrics.getProperties().get("spring.cloud.application.guid.test.metrics"))
.isEqualTo("highPriority");
applicationContext.close();
} finally {
}
finally {
System.clearProperty("spring.cloud.application.guid.test.metrics");
}
}
@@ -285,7 +291,8 @@ public class ApplicationMetricsExporterTests {
.poll(10, TimeUnit.SECONDS);
Assert.assertNotNull(message);
ObjectMapper mapper = applicationContext.getBean(ObjectMapper.class);
ApplicationMetrics applicationMetrics = mapper.readValue((String) message.getPayload(), ApplicationMetrics.class);
ApplicationMetrics applicationMetrics = mapper.readValue((String) message.getPayload(),
ApplicationMetrics.class);
Assert.assertTrue(contains("integration.channel.errorChannel.errorRate.mean",
applicationMetrics.getMetrics()));
Assert.assertTrue(contains("mem", applicationMetrics.getMetrics()));

View File

@@ -33,8 +33,10 @@ public class RelaxedPropertiesUtilsTests {
RelaxedNames springEnv = new RelaxedNames("SPRING_APPLICATION_NAME");
RelaxedNames springDot = new RelaxedNames("spring.application.name");
RelaxedNames springCamel = new RelaxedNames("springApplicationName");
RelaxedNames contentType = new RelaxedNames("spring.cloud.stream.bindings.applicationMetricsChannel.contentType");
RelaxedNames contentTypeEnv = new RelaxedNames("SPRING_CLOUD_STREAM_BINDINGS_APPLICATION-METRICS-CHANNEL_CONTENT-TYPE");
RelaxedNames contentType = new RelaxedNames(
"spring.cloud.stream.bindings.applicationMetricsChannel.contentType");
RelaxedNames contentTypeEnv = new RelaxedNames(
"SPRING_CLOUD_STREAM_BINDINGS_APPLICATION-METRICS-CHANNEL_CONTENT-TYPE");
RelaxedNames xyz = new RelaxedNames("My.X.Is");
RelaxedNames springMetrics = new RelaxedNames("spring.cloud.stream.applicationMetricsChannel");
RelaxedNames springMetricsEnv = new RelaxedNames("spring.cloud.stream.application-metrics-channel");

View File

@@ -21,7 +21,6 @@ import java.util.Date;
import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonGenerator;
import org.json.JSONObject;
import org.junit.Test;
@@ -36,17 +35,17 @@ import static org.junit.Assert.assertEquals;
public class MetricJsonSerializerTests {
@Test
public void validateAlwaysGMTDateAndFormat() throws Exception {
public void validateAlwaysGMTDateAndFormat() throws Exception {
Date date = new Date(1493060197188L); // Mon Apr 24 14:56:37 EDT 2017
Metric<Number> metric = new Metric<Number>("Hello", 123, date);
Metric<Number> metric = new Metric<Number>("Hello", 123, date);
JsonFactory factory = new JsonFactory();
StringWriter writer = new StringWriter();
StringWriter writer = new StringWriter();
JsonGenerator jsonGenerator = factory.createGenerator(writer);
Serializer ser = new Serializer();
Serializer ser = new Serializer();
ser.serialize(metric, jsonGenerator, null);
jsonGenerator.flush();
JSONObject json = new JSONObject(writer.toString());
String serializedTimestamp = json.getString("timestamp");
assertEquals("2017-04-24T18:56:37.188Z", serializedTimestamp);

View File

@@ -26,8 +26,8 @@ import org.springframework.messaging.Message;
import org.springframework.messaging.MessageChannel;
/**
* A {@link org.springframework.cloud.stream.binding.StreamListenerResultAdapter} from a {@link Flux}
* return type to a bound {@link MessageChannel}.
* A {@link org.springframework.cloud.stream.binding.StreamListenerResultAdapter} from a
* {@link Flux} return type to a bound {@link MessageChannel}.
* @author Marius Bogoevici
*/
public class FluxToMessageChannelResultAdapter

View File

@@ -53,8 +53,9 @@ public class MessageChannelToFluxSenderParameterAdapter
.doOnError(e -> this.log.error("Error during processing: ", e))
.retry()
.subscribe(
result -> bindingTarget.send(result instanceof Message<?> ? (Message<?>) result :
MessageBuilder.withPayload(result).build()), e -> sendResult.onError(e),
result -> bindingTarget.send(result instanceof Message<?> ? (Message<?>) result
: MessageBuilder.withPayload(result).build()),
e -> sendResult.onError(e),
() -> sendResult.onComplete());
return sendResult;
};

View File

@@ -55,8 +55,7 @@ public class MessageChannelToObservableSenderParameterAdapter implements
public ObservableSender adapt(MessageChannel bindingTarget, MethodParameter parameter) {
return new ObservableSender() {
private FluxSender fluxSender = MessageChannelToObservableSenderParameterAdapter.this
.messageChannelToFluxSenderArgumentAdapter
private FluxSender fluxSender = MessageChannelToObservableSenderParameterAdapter.this.messageChannelToFluxSenderArgumentAdapter
.adapt(bindingTarget, parameter);
@Override

View File

@@ -26,8 +26,8 @@ import org.springframework.messaging.MessageChannel;
import org.springframework.util.Assert;
/**
* A {@link StreamListenerResultAdapter} from an {@link Observable}
* return type to a bound {@link MessageChannel}.
* A {@link StreamListenerResultAdapter} from an {@link Observable} return type to a bound
* {@link MessageChannel}.
*
* @author Marius Bogoevici
*/

View File

@@ -71,8 +71,7 @@ public class ReactiveSupportAutoConfiguration {
@Bean
@ConditionalOnMissingBean(ObservableToMessageChannelResultAdapter.class)
public ObservableToMessageChannelResultAdapter
observableToMessageChannelResultAdapter(
public ObservableToMessageChannelResultAdapter observableToMessageChannelResultAdapter(
FluxToMessageChannelResultAdapter fluxToMessageChannelResultAdapter) {
return new ObservableToMessageChannelResultAdapter(fluxToMessageChannelResultAdapter);
}

View File

@@ -44,9 +44,21 @@ import static org.springframework.cloud.stream.binding.StreamListenerErrorMessag
@SuppressWarnings("unchecked")
public class StreamListenerGenericFluxInputOutputArgsWithMessageTests {
@SuppressWarnings("unchecked")
private static void sendMessageAndValidate(ConfigurableApplicationContext context) throws InterruptedException {
Processor processor = context.getBean(Processor.class);
String sentPayload = "hello " + UUID.randomUUID().toString();
processor.input().send(MessageBuilder.withPayload(sentPayload).setHeader("contentType", "text/plain").build());
MessageCollector messageCollector = context.getBean(MessageCollector.class);
Message<?> result = messageCollector.forChannel(processor.output()).poll(1000, TimeUnit.MILLISECONDS);
assertThat(result).isNotNull();
assertThat(result.getPayload()).isEqualTo(sentPayload.toUpperCase());
}
@Test
public void testGenericFluxInputOutputArgsWithMessage() throws Exception {
ConfigurableApplicationContext context = SpringApplication.run(TestGenericStringFluxInputOutputArgsWithMessageImpl1.class, "--server.port=0");
ConfigurableApplicationContext context = SpringApplication
.run(TestGenericStringFluxInputOutputArgsWithMessageImpl1.class, "--server.port=0");
sendMessageAndValidate(context);
context.close();
}
@@ -62,21 +74,12 @@ public class StreamListenerGenericFluxInputOutputArgsWithMessageTests {
}
}
@SuppressWarnings("unchecked")
private static void sendMessageAndValidate(ConfigurableApplicationContext context) throws InterruptedException {
Processor processor = context.getBean(Processor.class);
String sentPayload = "hello " + UUID.randomUUID().toString();
processor.input().send(MessageBuilder.withPayload(sentPayload).setHeader("contentType", "text/plain").build());
MessageCollector messageCollector = context.getBean(MessageCollector.class);
Message<?> result = messageCollector.forChannel(processor.output()).poll(1000, TimeUnit.MILLISECONDS);
assertThat(result).isNotNull();
assertThat(result.getPayload()).isEqualTo(sentPayload.toUpperCase());
public static class TestGenericStringFluxInputOutputArgsWithMessageImpl1
extends TestGenericFluxInputOutputArgsWithMessage1<String> {
}
public static class TestGenericStringFluxInputOutputArgsWithMessageImpl1 extends TestGenericFluxInputOutputArgsWithMessage1<String> {
}
public static class TestGenericStringFluxInputOutputArgsWithMessageImpl2 extends TestGenericFluxInputOutputArgsWithMessage2<String> {
public static class TestGenericStringFluxInputOutputArgsWithMessageImpl2
extends TestGenericFluxInputOutputArgsWithMessage2<String> {
}
@EnableBinding(Processor.class)

View File

@@ -35,8 +35,8 @@ import org.springframework.messaging.support.MessageBuilder;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Test validating that a fix for <a href="https://github.com/reactor/reactor-core/issues/159"/>
* is present.
* Test validating that a fix for
* <a href="https://github.com/reactor/reactor-core/issues/159"/> is present.
*
* @author Marius Bogoevici
*/

View File

@@ -56,14 +56,7 @@ public class StreamListenerReactiveInputOutputArgsTests {
@Parameterized.Parameters
public static Collection InputConfigs() {
return Arrays.asList(new Class[]{ReactorTestInputOutputArgs.class, RxJava1TestInputOutputArgs.class});
}
@Test
public void testInputOutputArgs() throws Exception {
ConfigurableApplicationContext context = SpringApplication.run(this.configClass, "--server.port=0");
sendMessageAndValidate(context);
context.close();
return Arrays.asList(new Class[] { ReactorTestInputOutputArgs.class, RxJava1TestInputOutputArgs.class });
}
private static void sendMessageAndValidate(ConfigurableApplicationContext context) throws InterruptedException {
@@ -77,6 +70,13 @@ public class StreamListenerReactiveInputOutputArgsTests {
assertThat(result.getPayload()).isEqualTo(sentPayload.toUpperCase());
}
@Test
public void testInputOutputArgs() throws Exception {
ConfigurableApplicationContext context = SpringApplication.run(this.configClass, "--server.port=0");
sendMessageAndValidate(context);
context.close();
}
@EnableBinding(Processor.class)
@EnableAutoConfiguration
public static class ReactorTestInputOutputArgs {
@@ -92,7 +92,8 @@ public class StreamListenerReactiveInputOutputArgsTests {
public static class RxJava1TestInputOutputArgs {
@StreamListener
public void receive(@Input(Processor.INPUT) Observable<String> input, @Output(Processor.OUTPUT) ObservableSender output) {
public void receive(@Input(Processor.INPUT) Observable<String> input,
@Output(Processor.OUTPUT) ObservableSender output) {
output.send(input.map(m -> m.toUpperCase()));
}
}

View File

@@ -56,14 +56,8 @@ public class StreamListenerReactiveInputOutputArgsWithMessageTests {
@Parameterized.Parameters
public static Collection InputConfigs() {
return Arrays.asList(new Class[]{ReactorTestInputOutputArgsWithMessage.class, RxJava1TestInputOutputArgsWithMessage.class});
}
@Test
public void testInputOutputArgs() throws Exception {
ConfigurableApplicationContext context = SpringApplication.run(this.configClass, "--server.port=0");
sendMessageAndValidate(context);
context.close();
return Arrays.asList(new Class[] { ReactorTestInputOutputArgsWithMessage.class,
RxJava1TestInputOutputArgsWithMessage.class });
}
private static void sendMessageAndValidate(ConfigurableApplicationContext context) throws InterruptedException {
@@ -77,6 +71,13 @@ public class StreamListenerReactiveInputOutputArgsWithMessageTests {
assertThat(result.getPayload()).isEqualTo(sentPayload.toUpperCase());
}
@Test
public void testInputOutputArgs() throws Exception {
ConfigurableApplicationContext context = SpringApplication.run(this.configClass, "--server.port=0");
sendMessageAndValidate(context);
context.close();
}
@EnableBinding(Processor.class)
@EnableAutoConfiguration
public static class ReactorTestInputOutputArgsWithMessage {

View File

@@ -56,19 +56,10 @@ public class StreamListenerReactiveInputOutputArgsWithSenderAndFailureTests {
@Parameterized.Parameters
public static Collection InputConfigs() {
return Arrays.asList(new Class[]{TestInputOutputArgsWithFluxSenderAndFailure.class, TestInputOutputArgsWithObservableSenderAndFailure.class});
return Arrays.asList(new Class[] { TestInputOutputArgsWithFluxSenderAndFailure.class,
TestInputOutputArgsWithObservableSenderAndFailure.class });
}
@Test
public void testInputOutputArgsWithFluxSenderAndFailure() throws Exception {
ConfigurableApplicationContext context = SpringApplication.run(this.configClass, "--server.port=0");
sendMessageAndValidate(context);
sendFailingMessage(context);
sendMessageAndValidate(context);
context.close();
}
private static void sendMessageAndValidate(ConfigurableApplicationContext context) throws InterruptedException {
@SuppressWarnings("unchecked")
Processor processor = context.getBean(Processor.class);
@@ -86,11 +77,21 @@ public class StreamListenerReactiveInputOutputArgsWithSenderAndFailureTests {
processor.input().send(MessageBuilder.withPayload("fail").setHeader("contentType", "text/plain").build());
}
@Test
public void testInputOutputArgsWithFluxSenderAndFailure() throws Exception {
ConfigurableApplicationContext context = SpringApplication.run(this.configClass, "--server.port=0");
sendMessageAndValidate(context);
sendFailingMessage(context);
sendMessageAndValidate(context);
context.close();
}
@EnableBinding(Processor.class)
@EnableAutoConfiguration
public static class TestInputOutputArgsWithFluxSenderAndFailure {
@StreamListener
public void receive(@Input(Processor.INPUT) Flux<Message<String>> input, @Output(Processor.OUTPUT) FluxSender output) {
public void receive(@Input(Processor.INPUT) Flux<Message<String>> input,
@Output(Processor.OUTPUT) FluxSender output) {
output.send(input
.map(m -> m.getPayload().toString())
.map(m -> {
@@ -109,7 +110,8 @@ public class StreamListenerReactiveInputOutputArgsWithSenderAndFailureTests {
@EnableAutoConfiguration
public static class TestInputOutputArgsWithObservableSenderAndFailure {
@StreamListener
public void receive(@Input(Processor.INPUT) Observable<Message<String>> input, @Output(Processor.OUTPUT) ObservableSender output) {
public void receive(@Input(Processor.INPUT) Observable<Message<String>> input,
@Output(Processor.OUTPUT) ObservableSender output) {
output.send(input
.map(m -> m.getPayload().toString())
.map(m -> {

View File

@@ -56,7 +56,19 @@ public class StreamListenerReactiveInputOutputArgsWithSenderTests {
@Parameterized.Parameters
public static Collection InputConfigs() {
return Arrays.asList(new Class[]{ReactorTestInputOutputArgsWithFluxSender.class, RxJava1TestInputOutputArgsWithObservableSender.class});
return Arrays.asList(new Class[] { ReactorTestInputOutputArgsWithFluxSender.class,
RxJava1TestInputOutputArgsWithObservableSender.class });
}
private static void sendMessageAndValidate(ConfigurableApplicationContext context) throws InterruptedException {
@SuppressWarnings("unchecked")
Processor processor = context.getBean(Processor.class);
String sentPayload = "hello " + UUID.randomUUID().toString();
processor.input().send(MessageBuilder.withPayload(sentPayload).setHeader("contentType", "text/plain").build());
MessageCollector messageCollector = context.getBean(MessageCollector.class);
Message<?> result = messageCollector.forChannel(processor.output()).poll(1000, TimeUnit.MILLISECONDS);
assertThat(result).isNotNull();
assertThat(result.getPayload()).isEqualTo(sentPayload.toUpperCase());
}
@Test
@@ -70,23 +82,12 @@ public class StreamListenerReactiveInputOutputArgsWithSenderTests {
context.close();
}
private static void sendMessageAndValidate(ConfigurableApplicationContext context) throws InterruptedException {
@SuppressWarnings("unchecked")
Processor processor = context.getBean(Processor.class);
String sentPayload = "hello " + UUID.randomUUID().toString();
processor.input().send(MessageBuilder.withPayload(sentPayload).setHeader("contentType", "text/plain").build());
MessageCollector messageCollector = context.getBean(MessageCollector.class);
Message<?> result = messageCollector.forChannel(processor.output()).poll(1000, TimeUnit.MILLISECONDS);
assertThat(result).isNotNull();
assertThat(result.getPayload()).isEqualTo(sentPayload.toUpperCase());
}
@EnableBinding(Processor.class)
@EnableAutoConfiguration
public static class ReactorTestInputOutputArgsWithFluxSender {
@StreamListener
public void receive(@Input(Processor.INPUT) Flux<Message<String>> input, @Output(Processor.OUTPUT) FluxSender output) {
public void receive(@Input(Processor.INPUT) Flux<Message<String>> input,
@Output(Processor.OUTPUT) FluxSender output) {
output.send(input
.map(m -> m.getPayload().toString().toUpperCase())
.map(o -> MessageBuilder.withPayload(o).build()));
@@ -97,8 +98,8 @@ public class StreamListenerReactiveInputOutputArgsWithSenderTests {
@EnableAutoConfiguration
public static class RxJava1TestInputOutputArgsWithObservableSender {
@StreamListener
public void receive(@Input(Processor.INPUT) Observable<Message<?>> input, @Output(Processor.OUTPUT)
ObservableSender output) {
public void receive(@Input(Processor.INPUT) Observable<Message<?>> input,
@Output(Processor.OUTPUT) ObservableSender output) {
output.send(input
.map(m -> m.getPayload().toString().toUpperCase())
.map(o -> MessageBuilder.withPayload(o).build()));

View File

@@ -49,16 +49,6 @@ public class StreamListenerReactiveMethodTests {
}
}
@EnableBinding(Processor.class)
@EnableAutoConfiguration
public static class ReactorTestInputOutputArgs {
@StreamListener(Processor.INPUT)
public void receive(Flux<String> input, @Output(Processor.OUTPUT) FluxSender output) {
output.send(input.map(m -> m.toUpperCase()));
}
}
@Test
public void testRxJava1InvalidInputValueWithOutputMethodParameters() {
try {
@@ -70,16 +60,6 @@ public class StreamListenerReactiveMethodTests {
}
}
@EnableBinding(Processor.class)
@EnableAutoConfiguration
public static class RxJava1TestInputOutputArgs {
@StreamListener(Processor.INPUT)
public void receive(Observable<String> input, @Output(Processor.OUTPUT) ObservableSender output) {
output.send(input.map(m -> m.toUpperCase()));
}
}
@Test
public void testMethodReturnTypeWithNoOutboundSpecified() {
try {
@@ -91,6 +71,26 @@ public class StreamListenerReactiveMethodTests {
}
}
@EnableBinding(Processor.class)
@EnableAutoConfiguration
public static class ReactorTestInputOutputArgs {
@StreamListener(Processor.INPUT)
public void receive(Flux<String> input, @Output(Processor.OUTPUT) FluxSender output) {
output.send(input.map(m -> m.toUpperCase()));
}
}
@EnableBinding(Processor.class)
@EnableAutoConfiguration
public static class RxJava1TestInputOutputArgs {
@StreamListener(Processor.INPUT)
public void receive(Observable<String> input, @Output(Processor.OUTPUT) ObservableSender output) {
output.send(input.map(m -> m.toUpperCase()));
}
}
@EnableBinding(Processor.class)
@EnableAutoConfiguration
public static class ReactorTestReturn5 {

View File

@@ -57,17 +57,10 @@ public class StreamListenerReactiveMethodWithReturnTypeTests {
@Parameterized.Parameters
public static Collection InputConfigs() {
return Arrays.asList(new Class[]{ReactorTestReturn1.class, ReactorTestReturn2.class, ReactorTestReturn3.class, ReactorTestReturn4.class,
RxJava1TestReturn1.class, RxJava1TestReturn2.class, RxJava1TestReturn3.class, RxJava1TestReturn4.class});
}
@Test
public void testReturn() throws Exception {
ConfigurableApplicationContext context = SpringApplication.run(this.configClass, "--server.port=0");
sendMessageAndValidate(context);
sendMessageAndValidate(context);
sendMessageAndValidate(context);
context.close();
return Arrays.asList(new Class[] { ReactorTestReturn1.class, ReactorTestReturn2.class, ReactorTestReturn3.class,
ReactorTestReturn4.class,
RxJava1TestReturn1.class, RxJava1TestReturn2.class, RxJava1TestReturn3.class,
RxJava1TestReturn4.class });
}
private static void sendMessageAndValidate(ConfigurableApplicationContext context) throws InterruptedException {
@@ -81,14 +74,21 @@ public class StreamListenerReactiveMethodWithReturnTypeTests {
assertThat(result.getPayload()).isEqualTo(sentPayload.toUpperCase());
}
@Test
public void testReturn() throws Exception {
ConfigurableApplicationContext context = SpringApplication.run(this.configClass, "--server.port=0");
sendMessageAndValidate(context);
sendMessageAndValidate(context);
sendMessageAndValidate(context);
context.close();
}
@EnableBinding(Processor.class)
@EnableAutoConfiguration
public static class ReactorTestReturn1 {
@StreamListener
public
@Output(Processor.OUTPUT)
Flux<String> receive(@Input(Processor.INPUT) Flux<String> input) {
public @Output(Processor.OUTPUT) Flux<String> receive(@Input(Processor.INPUT) Flux<String> input) {
return input.map(m -> m.toUpperCase());
}
}
@@ -131,9 +131,7 @@ public class StreamListenerReactiveMethodWithReturnTypeTests {
public static class RxJava1TestReturn1 {
@StreamListener
public
@Output(Processor.OUTPUT)
Observable<String> receive(@Input(Processor.INPUT) Observable<String> input) {
public @Output(Processor.OUTPUT) Observable<String> receive(@Input(Processor.INPUT) Observable<String> input) {
return input.map(m -> m.toUpperCase());
}
}
@@ -143,9 +141,7 @@ public class StreamListenerReactiveMethodWithReturnTypeTests {
public static class RxJava1TestReturn2 {
@StreamListener(Processor.INPUT)
public
@Output(Processor.OUTPUT)
Observable<String> receive(Observable<String> input) {
public @Output(Processor.OUTPUT) Observable<String> receive(Observable<String> input) {
return input.map(m -> m.toUpperCase());
}
}
@@ -155,9 +151,7 @@ public class StreamListenerReactiveMethodWithReturnTypeTests {
public static class RxJava1TestReturn3 {
@StreamListener(Processor.INPUT)
public
@SendTo(Processor.OUTPUT)
Observable<String> receive(Observable<String> input) {
public @SendTo(Processor.OUTPUT) Observable<String> receive(Observable<String> input) {
return input.map(m -> m.toUpperCase());
}
}
@@ -167,9 +161,7 @@ public class StreamListenerReactiveMethodWithReturnTypeTests {
public static class RxJava1TestReturn4 {
@StreamListener
public
@SendTo(Processor.OUTPUT)
Observable<String> receive(@Input(Processor.INPUT) Observable<String> input) {
public @SendTo(Processor.OUTPUT) Observable<String> receive(@Input(Processor.INPUT) Observable<String> input) {
return input.map(m -> m.toUpperCase());
}
}

View File

@@ -57,20 +57,11 @@ public class StreamListenerReactiveReturnWithFailureTests {
@Parameterized.Parameters
public static Collection InputConfigs() {
return Arrays.asList(new Class[] {ReactorTestReturnWithFailure1.class, ReactorTestReturnWithFailure2.class,
ReactorTestReturnWithFailure3.class, ReactorTestReturnWithFailure4.class, RxJava1TestReturnWithFailure1.class,
RxJava1TestReturnWithFailure2.class, RxJava1TestReturnWithFailure3.class, RxJava1TestReturnWithFailure4.class});
}
@Test
public void testReturnWithFailure() throws Exception {
ConfigurableApplicationContext context = SpringApplication.run(this.configClass, "--server.port=0");
sendMessageAndValidate(context);
sendFailingMessage(context);
sendMessageAndValidate(context);
sendFailingMessage(context);
sendMessageAndValidate(context);
context.close();
return Arrays.asList(new Class[] { ReactorTestReturnWithFailure1.class, ReactorTestReturnWithFailure2.class,
ReactorTestReturnWithFailure3.class, ReactorTestReturnWithFailure4.class,
RxJava1TestReturnWithFailure1.class,
RxJava1TestReturnWithFailure2.class, RxJava1TestReturnWithFailure3.class,
RxJava1TestReturnWithFailure4.class });
}
private static void sendMessageAndValidate(ConfigurableApplicationContext context) throws InterruptedException {
@@ -90,14 +81,23 @@ public class StreamListenerReactiveReturnWithFailureTests {
processor.input().send(MessageBuilder.withPayload("fail").setHeader("contentType", "text/plain").build());
}
@Test
public void testReturnWithFailure() throws Exception {
ConfigurableApplicationContext context = SpringApplication.run(this.configClass, "--server.port=0");
sendMessageAndValidate(context);
sendFailingMessage(context);
sendMessageAndValidate(context);
sendFailingMessage(context);
sendMessageAndValidate(context);
context.close();
}
@EnableBinding(Processor.class)
@EnableAutoConfiguration
public static class ReactorTestReturnWithFailure1 {
@StreamListener
public
@Output(Processor.OUTPUT)
Flux<String> receive(@Input(Processor.INPUT) Flux<String> input) {
public @Output(Processor.OUTPUT) Flux<String> receive(@Input(Processor.INPUT) Flux<String> input) {
return input.map(m -> {
if (!m.equals("fail")) {
return m.toUpperCase();
@@ -114,9 +114,7 @@ public class StreamListenerReactiveReturnWithFailureTests {
public static class ReactorTestReturnWithFailure2 {
@StreamListener(Processor.INPUT)
public
@Output(Processor.OUTPUT)
Flux<String> receive(Flux<String> input) {
public @Output(Processor.OUTPUT) Flux<String> receive(Flux<String> input) {
return input.map(m -> {
if (!m.equals("fail")) {
return m.toUpperCase();
@@ -133,9 +131,7 @@ public class StreamListenerReactiveReturnWithFailureTests {
public static class ReactorTestReturnWithFailure3 {
@StreamListener(Processor.INPUT)
public
@SendTo(Processor.OUTPUT)
Flux<String> receive(Flux<String> input) {
public @SendTo(Processor.OUTPUT) Flux<String> receive(Flux<String> input) {
return input.map(m -> {
if (!m.equals("fail")) {
return m.toUpperCase();
@@ -152,9 +148,7 @@ public class StreamListenerReactiveReturnWithFailureTests {
public static class ReactorTestReturnWithFailure4 {
@StreamListener
public
@SendTo(Processor.OUTPUT)
Flux<String> receive(@Input(Processor.INPUT) Flux<String> input) {
public @SendTo(Processor.OUTPUT) Flux<String> receive(@Input(Processor.INPUT) Flux<String> input) {
return input.map(m -> {
if (!m.equals("fail")) {
return m.toUpperCase();
@@ -171,9 +165,7 @@ public class StreamListenerReactiveReturnWithFailureTests {
public static class RxJava1TestReturnWithFailure1 {
@StreamListener
public
@Output(Processor.OUTPUT)
Observable<String> receive(@Input(Processor.INPUT) Observable<String> input) {
public @Output(Processor.OUTPUT) Observable<String> receive(@Input(Processor.INPUT) Observable<String> input) {
return input.map(m -> {
if (!m.equals("fail")) {
return m.toUpperCase();
@@ -190,9 +182,7 @@ public class StreamListenerReactiveReturnWithFailureTests {
public static class RxJava1TestReturnWithFailure2 {
@StreamListener
public
@SendTo(Processor.OUTPUT)
Observable<String> receive(@Input(Processor.INPUT) Observable<String> input) {
public @SendTo(Processor.OUTPUT) Observable<String> receive(@Input(Processor.INPUT) Observable<String> input) {
return input.map(m -> {
if (!m.equals("fail")) {
return m.toUpperCase();
@@ -209,9 +199,7 @@ public class StreamListenerReactiveReturnWithFailureTests {
public static class RxJava1TestReturnWithFailure3 {
@StreamListener(Processor.INPUT)
public
@SendTo(Processor.OUTPUT)
Observable<String> receive(Observable<String> input) {
public @SendTo(Processor.OUTPUT) Observable<String> receive(Observable<String> input) {
return input.map(m -> {
if (!m.equals("fail")) {
return m.toUpperCase();
@@ -228,9 +216,7 @@ public class StreamListenerReactiveReturnWithFailureTests {
public static class RxJava1TestReturnWithFailure4 {
@StreamListener(Processor.INPUT)
public
@Output(Processor.OUTPUT)
Observable<String> receive(Observable<String> input) {
public @Output(Processor.OUTPUT) Observable<String> receive(Observable<String> input) {
return input.map(m -> {
if (!m.equals("fail")) {
return m.toUpperCase();

View File

@@ -57,16 +57,11 @@ public class StreamListenerReactiveReturnWithMessageTests {
@Parameterized.Parameters
public static Collection InputConfigs() {
return Arrays.asList(new Class[] {ReactorTestReturnWithMessage1.class, ReactorTestReturnWithMessage2.class,
ReactorTestReturnWithMessage3.class, ReactorTestReturnWithMessage4.class, RxJava1TestReturnWithMessage1.class,
RxJava1TestReturnWithMessage2.class, RxJava1TestReturnWithMessage3.class, RxJava1TestReturnWithMessage4.class});
}
@Test
public void testReturnWithMessage() throws Exception {
ConfigurableApplicationContext context = SpringApplication.run(this.configClass, "--server.port=0");
sendMessageAndValidate(context);
context.close();
return Arrays.asList(new Class[] { ReactorTestReturnWithMessage1.class, ReactorTestReturnWithMessage2.class,
ReactorTestReturnWithMessage3.class, ReactorTestReturnWithMessage4.class,
RxJava1TestReturnWithMessage1.class,
RxJava1TestReturnWithMessage2.class, RxJava1TestReturnWithMessage3.class,
RxJava1TestReturnWithMessage4.class });
}
private static void sendMessageAndValidate(ConfigurableApplicationContext context) throws InterruptedException {
@@ -80,14 +75,19 @@ public class StreamListenerReactiveReturnWithMessageTests {
assertThat(result.getPayload()).isEqualTo(sentPayload.toUpperCase());
}
@Test
public void testReturnWithMessage() throws Exception {
ConfigurableApplicationContext context = SpringApplication.run(this.configClass, "--server.port=0");
sendMessageAndValidate(context);
context.close();
}
@EnableBinding(Processor.class)
@EnableAutoConfiguration
public static class ReactorTestReturnWithMessage1 {
@StreamListener
public
@Output(Processor.OUTPUT)
Flux<String> receive(@Input(Processor.INPUT) Flux<Message<String>> input) {
public @Output(Processor.OUTPUT) Flux<String> receive(@Input(Processor.INPUT) Flux<Message<String>> input) {
return input.map(m -> m.getPayload().toUpperCase());
}
}
@@ -97,9 +97,7 @@ public class StreamListenerReactiveReturnWithMessageTests {
public static class ReactorTestReturnWithMessage2 {
@StreamListener(Processor.INPUT)
public
@Output(Processor.OUTPUT)
Flux<String> receive(Flux<Message<String>> input) {
public @Output(Processor.OUTPUT) Flux<String> receive(Flux<Message<String>> input) {
return input.map(m -> m.getPayload().toUpperCase());
}
}
@@ -109,22 +107,17 @@ public class StreamListenerReactiveReturnWithMessageTests {
public static class ReactorTestReturnWithMessage3 {
@StreamListener(Processor.INPUT)
public
@SendTo(Processor.OUTPUT)
Flux<String> receive(Flux<Message<String>> input) {
public @SendTo(Processor.OUTPUT) Flux<String> receive(Flux<Message<String>> input) {
return input.map(m -> m.getPayload().toUpperCase());
}
}
@EnableBinding(Processor.class)
@EnableAutoConfiguration
public static class ReactorTestReturnWithMessage4 {
@StreamListener
public
@SendTo(Processor.OUTPUT)
Flux<String> receive(@Input(Processor.INPUT) Flux<Message<String>> input) {
public @SendTo(Processor.OUTPUT) Flux<String> receive(@Input(Processor.INPUT) Flux<Message<String>> input) {
return input.map(m -> m.getPayload().toUpperCase());
}
}
@@ -134,9 +127,8 @@ public class StreamListenerReactiveReturnWithMessageTests {
public static class RxJava1TestReturnWithMessage1 {
@StreamListener
public
@Output(Processor.OUTPUT)
Observable<String> receive(@Input(Processor.INPUT) Observable<Message<String>> input) {
public @Output(Processor.OUTPUT) Observable<String> receive(
@Input(Processor.INPUT) Observable<Message<String>> input) {
return input.map(m -> m.getPayload().toUpperCase());
}
}
@@ -146,9 +138,8 @@ public class StreamListenerReactiveReturnWithMessageTests {
public static class RxJava1TestReturnWithMessage2 {
@StreamListener
public
@SendTo(Processor.OUTPUT)
Observable<String> receive(@Input(Processor.INPUT) Observable<Message<String>> input) {
public @SendTo(Processor.OUTPUT) Observable<String> receive(
@Input(Processor.INPUT) Observable<Message<String>> input) {
return input.map(m -> m.getPayload().toUpperCase());
}
}
@@ -158,9 +149,7 @@ public class StreamListenerReactiveReturnWithMessageTests {
public static class RxJava1TestReturnWithMessage3 {
@StreamListener(Processor.INPUT)
public
@Output(Processor.OUTPUT)
Observable<String> receive(Observable<Message<String>> input) {
public @Output(Processor.OUTPUT) Observable<String> receive(Observable<Message<String>> input) {
return input.map(m -> m.getPayload().toUpperCase());
}
}
@@ -170,9 +159,7 @@ public class StreamListenerReactiveReturnWithMessageTests {
public static class RxJava1TestReturnWithMessage4 {
@StreamListener(Processor.INPUT)
public
@SendTo(Processor.OUTPUT)
Observable<String> receive(Observable<Message<String>> input) {
public @SendTo(Processor.OUTPUT) Observable<String> receive(Observable<Message<String>> input) {
return input.map(m -> m.getPayload().toUpperCase());
}
}

View File

@@ -56,9 +56,9 @@ public class StreamListenerReactiveReturnWithPojoTests {
@Parameterized.Parameters
public static Collection InputConfigs() {
return Arrays.asList(new Class[] {ReactorTestReturnWithPojo1.class, ReactorTestReturnWithPojo2.class,
return Arrays.asList(new Class[] { ReactorTestReturnWithPojo1.class, ReactorTestReturnWithPojo2.class,
ReactorTestReturnWithPojo3.class, ReactorTestReturnWithPojo4.class, RxJava1TestReturnWithPojo1.class,
RxJava1TestReturnWithPojo2.class, RxJava1TestReturnWithPojo3.class, RxJava1TestReturnWithPojo4.class});
RxJava1TestReturnWithPojo2.class, RxJava1TestReturnWithPojo3.class, RxJava1TestReturnWithPojo4.class });
}
@Test
@@ -81,9 +81,7 @@ public class StreamListenerReactiveReturnWithPojoTests {
public static class ReactorTestReturnWithPojo1 {
@StreamListener
public
@Output(Processor.OUTPUT)
Flux<BarPojo> receive(@Input(Processor.INPUT) Flux<FooPojo> input) {
public @Output(Processor.OUTPUT) Flux<BarPojo> receive(@Input(Processor.INPUT) Flux<FooPojo> input) {
return input.map(m -> new BarPojo(m.getMessage()));
}
}
@@ -93,9 +91,7 @@ public class StreamListenerReactiveReturnWithPojoTests {
public static class ReactorTestReturnWithPojo2 {
@StreamListener(Processor.INPUT)
public
@Output(Processor.OUTPUT)
Flux<BarPojo> receive(Flux<FooPojo> input) {
public @Output(Processor.OUTPUT) Flux<BarPojo> receive(Flux<FooPojo> input) {
return input.map(m -> new BarPojo(m.getMessage()));
}
}
@@ -105,9 +101,7 @@ public class StreamListenerReactiveReturnWithPojoTests {
public static class ReactorTestReturnWithPojo3 {
@StreamListener(Processor.INPUT)
public
@SendTo(Processor.OUTPUT)
Flux<BarPojo> receive(Flux<FooPojo> input) {
public @SendTo(Processor.OUTPUT) Flux<BarPojo> receive(Flux<FooPojo> input) {
return input.map(m -> new BarPojo(m.getMessage()));
}
}
@@ -117,9 +111,7 @@ public class StreamListenerReactiveReturnWithPojoTests {
public static class ReactorTestReturnWithPojo4 {
@StreamListener
public
@SendTo(Processor.OUTPUT)
Flux<BarPojo> receive(@Input(Processor.INPUT) Flux<FooPojo> input) {
public @SendTo(Processor.OUTPUT) Flux<BarPojo> receive(@Input(Processor.INPUT) Flux<FooPojo> input) {
return input.map(m -> new BarPojo(m.getMessage()));
}
}
@@ -129,9 +121,8 @@ public class StreamListenerReactiveReturnWithPojoTests {
public static class RxJava1TestReturnWithPojo1 {
@StreamListener
public
@Output(Processor.OUTPUT)
Observable<BarPojo> receive(@Input(Processor.INPUT) Observable<FooPojo> input) {
public @Output(Processor.OUTPUT) Observable<BarPojo> receive(
@Input(Processor.INPUT) Observable<FooPojo> input) {
return input.map(m -> new BarPojo(m.getMessage()));
}
}
@@ -141,9 +132,8 @@ public class StreamListenerReactiveReturnWithPojoTests {
public static class RxJava1TestReturnWithPojo2 {
@StreamListener
public
@SendTo(Processor.OUTPUT)
Observable<BarPojo> receive(@Input(Processor.INPUT) Observable<FooPojo> input) {
public @SendTo(Processor.OUTPUT) Observable<BarPojo> receive(
@Input(Processor.INPUT) Observable<FooPojo> input) {
return input.map(m -> new BarPojo(m.getMessage()));
}
}
@@ -153,9 +143,7 @@ public class StreamListenerReactiveReturnWithPojoTests {
public static class RxJava1TestReturnWithPojo3 {
@StreamListener(Processor.INPUT)
public
@Output(Processor.OUTPUT)
Observable<BarPojo> receive(Observable<FooPojo> input) {
public @Output(Processor.OUTPUT) Observable<BarPojo> receive(Observable<FooPojo> input) {
return input.map(m -> new BarPojo(m.getMessage()));
}
}
@@ -165,9 +153,7 @@ public class StreamListenerReactiveReturnWithPojoTests {
public static class RxJava1TestReturnWithPojo4 {
@StreamListener(Processor.INPUT)
public
@SendTo(Processor.OUTPUT)
Observable<BarPojo> receive(Observable<FooPojo> input) {
public @SendTo(Processor.OUTPUT) Observable<BarPojo> receive(Observable<FooPojo> input) {
return input.map(m -> new BarPojo(m.getMessage()));
}
}

View File

@@ -45,9 +45,21 @@ import static org.springframework.cloud.stream.binding.StreamListenerErrorMessag
*/
public class StreamListenerWildCardFluxInputOutputArgsWithMessageTests {
private static void sendMessageAndValidate(ConfigurableApplicationContext context) throws InterruptedException {
@SuppressWarnings("unchecked")
Processor processor = context.getBean(Processor.class);
String sentPayload = "hello " + UUID.randomUUID().toString();
processor.input().send(MessageBuilder.withPayload(sentPayload).setHeader("contentType", "text/plain").build());
MessageCollector messageCollector = context.getBean(MessageCollector.class);
Message<?> result = messageCollector.forChannel(processor.output()).poll(1000, TimeUnit.MILLISECONDS);
assertThat(result).isNotNull();
assertThat(result.getPayload()).isEqualTo(sentPayload.toUpperCase());
}
@Test
public void testWildCardFluxInputOutputArgsWithMessage() throws Exception {
ConfigurableApplicationContext context = SpringApplication.run(TestWildCardFluxInputOutputArgsWithMessage1.class, "--server.port=0");
ConfigurableApplicationContext context = SpringApplication
.run(TestWildCardFluxInputOutputArgsWithMessage1.class, "--server.port=0");
sendMessageAndValidate(context);
context.close();
}
@@ -74,17 +86,6 @@ public class StreamListenerWildCardFluxInputOutputArgsWithMessageTests {
}
}
private static void sendMessageAndValidate(ConfigurableApplicationContext context) throws InterruptedException {
@SuppressWarnings("unchecked")
Processor processor = context.getBean(Processor.class);
String sentPayload = "hello " + UUID.randomUUID().toString();
processor.input().send(MessageBuilder.withPayload(sentPayload).setHeader("contentType", "text/plain").build());
MessageCollector messageCollector = context.getBean(MessageCollector.class);
Message<?> result = messageCollector.forChannel(processor.output()).poll(1000, TimeUnit.MILLISECONDS);
assertThat(result).isNotNull();
assertThat(result.getPayload()).isEqualTo(sentPayload.toUpperCase());
}
@EnableBinding(Processor.class)
@EnableAutoConfiguration
public static class TestWildCardFluxInputOutputArgsWithMessage1 {

View File

@@ -28,11 +28,13 @@ import org.springframework.cloud.stream.messaging.Processor;
import org.springframework.context.annotation.Import;
/**
* Annotation that identifies the class as RxJava processor module. The class that has {@link EnableRxJavaProcessor}
* annotated is expected to provide a bean that implements {@link RxJavaProcessor}.
* Annotation that identifies the class as RxJava processor module. The class that has
* {@link EnableRxJavaProcessor} annotated is expected to provide a bean that implements
* {@link RxJavaProcessor}.
*
* @author Ilayaperumal Gopinathan
* @deprecated in favor of {@link org.springframework.cloud.stream.annotation.StreamListener} with reactive types
* @deprecated in favor of
* {@link org.springframework.cloud.stream.annotation.StreamListener} with reactive types
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)

View File

@@ -23,7 +23,8 @@ import rx.Observable;
*
* @author Mark Pollack
* @author Ilayaperumal Gopinathan
* @deprecated in favor of {@link org.springframework.cloud.stream.annotation.StreamListener} with reactive types
* @deprecated in favor of
* {@link org.springframework.cloud.stream.annotation.StreamListener} with reactive types
*/
@Deprecated
public interface RxJavaProcessor<I, O> {

View File

@@ -34,34 +34,39 @@ import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
/**
* Adapts the item at a time delivery of a {@link org.springframework.messaging.MessageHandler}
* by delegating processing to a {@link Observable}.
* Adapts the item at a time delivery of a
* {@link org.springframework.messaging.MessageHandler} by delegating processing to a
* {@link Observable}.
* <p/>
* The outputStream of the processor is used to create a message and send it to the output channel. If the
* input channel and output channel are connected to the {@link org.springframework.cloud.stream.binder.Binder},
* then data delivered to the input stream via a call to onNext is invoked on the dispatcher thread of the binder
* and sending a message to the output channel will involve IO operations on the binder.
* The outputStream of the processor is used to create a message and send it to the output
* channel. If the input channel and output channel are connected to the
* {@link org.springframework.cloud.stream.binder.Binder}, then data delivered to the
* input stream via a call to onNext is invoked on the dispatcher thread of the binder and
* sending a message to the output channel will involve IO operations on the binder.
* <p/>
* The implementation uses a SerializedSubject. This has the advantage that the state of the Observabale
* can be shared across all the incoming dispatcher threads that are invoking onNext. It has the disadvantage
* that processing and sending to the output channel will execute serially on one of the dispatcher threads.
* The implementation uses a SerializedSubject. This has the advantage that the state of
* the Observabale can be shared across all the incoming dispatcher threads that are
* invoking onNext. It has the disadvantage that processing and sending to the output
* channel will execute serially on one of the dispatcher threads.
* <p/>
* The use of this handler makes for a very natural first experience when processing data. For example given
* the stream <code></code>http | rxjava-processor | log</code> where the <code>rxjava-processor</code> does a
* <code>buffer(5)</code> and then produces a single value. Sending 10 messages to the http source will
* result in 2 messages in the log, no matter how many dispatcher threads are used.
* The use of this handler makes for a very natural first experience when processing data.
* For example given the stream <code></code>http | rxjava-processor | log</code> where
* the <code>rxjava-processor</code> does a <code>buffer(5)</code> and then produces a
* single value. Sending 10 messages to the http source will result in 2 messages in the
* log, no matter how many dispatcher threads are used.
* <p/>
* You can modify what thread the outputStream subscriber, which does the send to the output channel,
* will use by explicitly calling <code>observeOn</code> before returning the outputStream from your processor.
* You can modify what thread the outputStream subscriber, which does the send to the
* output channel, will use by explicitly calling <code>observeOn</code> before returning
* the outputStream from your processor.
* <p/>
*
* All error handling is the responsibility of the processor implementation.
*
* @author Mark Pollack
* @author Ilayaperumal Gopinathan
* @author Marius Bogoevici
*/
@SuppressWarnings({"unchecked", "rawtypes"})
@SuppressWarnings({ "unchecked", "rawtypes" })
@Deprecated
public class SubjectMessageHandler extends AbstractMessageProducingHandler implements SmartLifecycle {
@@ -76,7 +81,7 @@ public class SubjectMessageHandler extends AbstractMessageProducingHandler imple
private volatile boolean running;
@SuppressWarnings({"unchecked", "rawtypes"})
@SuppressWarnings({ "unchecked", "rawtypes" })
public SubjectMessageHandler(RxJavaProcessor processor) {
Assert.notNull(processor, "RxJava processor must not be null.");
this.processor = processor;

View File

@@ -48,17 +48,18 @@ public class SchemaServerConfiguration {
return new BeanFactoryPostProcessor() {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws
BeansException {
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
if (beanFactory instanceof BeanDefinitionRegistry) {
EntityScanPackages.register((BeanDefinitionRegistry) beanFactory, Collections.singletonList(Schema.class.getPackage().getName()));
EntityScanPackages.register((BeanDefinitionRegistry) beanFactory,
Collections.singletonList(Schema.class.getPackage().getName()));
}
}
};
}
@Bean
public ServerController serverController(SchemaRepository repository, SchemaServerProperties schemeServerProperties) {
public ServerController serverController(SchemaRepository repository,
SchemaServerProperties schemeServerProperties) {
return new ServerController(repository, schemaValidators(), schemeServerProperties);
}

View File

@@ -14,7 +14,6 @@
* limitations under the License.
*/
package org.springframework.cloud.stream.schema.server.config;
import org.springframework.boot.context.properties.ConfigurationProperties;

View File

@@ -14,7 +14,6 @@
* limitations under the License.
*/
package org.springframework.cloud.stream.schema.server.controllers;
import java.util.List;
@@ -134,10 +133,12 @@ public class ServerController {
}
@RequestMapping(method = RequestMethod.GET, produces = "application/json", path = "/{subject}/{format}")
public ResponseEntity<List<Schema>> findBySubjectAndVersion(@PathVariable("subject") String subject, @PathVariable("format") String format) {
public ResponseEntity<List<Schema>> findBySubjectAndVersion(@PathVariable("subject") String subject,
@PathVariable("format") String format) {
List<Schema> schemas = repository.findBySubjectAndFormatOrderByVersion(subject, format);
if (schemas == null || schemas.size() == 0) {
throw new SchemaNotFoundException(String.format("No schemas found for subject %s and format %s", subject, format));
throw new SchemaNotFoundException(
String.format("No schemas found for subject %s and format %s", subject, format));
}
return new ResponseEntity<List<Schema>>(schemas, HttpStatus.OK);
}

View File

@@ -14,12 +14,14 @@
* limitations under the License.
*/
package org.springframework.cloud.stream.schema.server.model;
/**
* @author Vinicius Carvalho
*/
public enum Compatibility {
BACKWARD, FORWARD, FULL, INCOMPATIBLE;
BACKWARD,
FORWARD,
FULL,
INCOMPATIBLE;
}

View File

@@ -207,7 +207,8 @@ public class SchemaRegistryServerAvroTests {
ResponseEntity<Schema> response1 = client.postForEntity("http://localhost:8990/",
schema1, Schema.class);
Assert.assertTrue(response1.getStatusCode().is2xxSuccessful());
Assert.assertEquals(HttpStatus.OK, client.getForEntity("http://localhost:8990/test/avro/v1", Schema.class).getStatusCode());
Assert.assertEquals(HttpStatus.OK,
client.getForEntity("http://localhost:8990/test/avro/v1", Schema.class).getStatusCode());
client.getForEntity("http://localhost:8990/test/avro/1", Schema.class);
Schema schema2 = new Schema();
schema2.setFormat("avro");
@@ -216,7 +217,8 @@ public class SchemaRegistryServerAvroTests {
ResponseEntity<Schema> response2 = client.postForEntity("http://localhost:8990/",
schema2, Schema.class);
Assert.assertTrue(response2.getStatusCode().is2xxSuccessful());
Assert.assertEquals(HttpStatus.OK, client.getForEntity("http://localhost:8990/test/avro/v2", Schema.class).getStatusCode());
Assert.assertEquals(HttpStatus.OK,
client.getForEntity("http://localhost:8990/test/avro/v2", Schema.class).getStatusCode());
schemaServerProperties.setAllowSchemaDeletion(true);
client.delete("http://localhost:8990/test");
ResponseEntity<Schema> response4 = client
@@ -236,7 +238,8 @@ public class SchemaRegistryServerAvroTests {
ResponseEntity<Schema> response1 = client.postForEntity("http://localhost:8990/",
schema, Schema.class);
Assert.assertTrue(response1.getStatusCode().is2xxSuccessful());
ResponseEntity<Object> deleteBySubjectFormatVersion = client.exchange("http://localhost:8990/test/avro/v1", HttpMethod.DELETE,
ResponseEntity<Object> deleteBySubjectFormatVersion = client.exchange("http://localhost:8990/test/avro/v1",
HttpMethod.DELETE,
null, Object.class);
assertThat(deleteBySubjectFormatVersion.getStatusCode()).isEqualTo(HttpStatus.METHOD_NOT_ALLOWED);
ResponseEntity<Object> deleteBySubject = client.exchange("http://localhost:8990/test", HttpMethod.DELETE,
@@ -266,8 +269,9 @@ public class SchemaRegistryServerAvroTests {
v2, Schema.class);
Assert.assertTrue(response2.getStatusCode().is2xxSuccessful());
ResponseEntity<List<Schema>> schemaResponse = client.exchange("http://localhost:8990/test/avro", HttpMethod.GET, null, new ParameterizedTypeReference<List<Schema>>() {
});
ResponseEntity<List<Schema>> schemaResponse = client.exchange("http://localhost:8990/test/avro", HttpMethod.GET,
null, new ParameterizedTypeReference<List<Schema>>() {
});
Assert.assertTrue(schemaResponse.getStatusCode().is2xxSuccessful());
Assert.assertEquals(2, schemaResponse.getBody().size());

View File

@@ -30,7 +30,8 @@ public class EntityScanningTests {
@Test
public void testApplicationWithEmbeddedSchemaRegistryServerOutsideOfRootPackage() throws Exception {
final ConfigurableApplicationContext context = SpringApplication.run(CustomApplicationEmbeddingSchemaServer.class, "--server.port=0");
final ConfigurableApplicationContext context = SpringApplication
.run(CustomApplicationEmbeddingSchemaServer.class, "--server.port=0");
context.close();
}

View File

@@ -31,7 +31,8 @@ public class EntityScanningTestsWithEntityScan {
@Test
public void testApplicationWithEmbeddedSchemaRegistryServerOutsideOfRootPackage() throws Exception {
final ConfigurableApplicationContext context = SpringApplication.run(CustomApplicationEmbeddingSchemaServer.class, "--server.port=0");
final ConfigurableApplicationContext context = SpringApplication
.run(CustomApplicationEmbeddingSchemaServer.class, "--server.port=0");
context.close();
}

View File

@@ -21,13 +21,14 @@ import org.apache.avro.Schema;
/**
* Stores a {@link Schema} together with its String representation.
*
* Helps to avoid unnecessary parsing of schema textual representation,
* as well as calls to {@link org.apache.avro.Schema} toString method which is very
* expensive due the utilization of {@link com.fasterxml.jackson.databind.ObjectMapper}
* to output a JSON representation of the schema.
* Helps to avoid unnecessary parsing of schema textual representation, as well as calls
* to {@link org.apache.avro.Schema} toString method which is very expensive due the
* utilization of {@link com.fasterxml.jackson.databind.ObjectMapper} to output a JSON
* representation of the schema.
*
* Once a schema is found for any Class, be it a POJO or a {@link org.apache.avro.generic.GenericContainer},
* both textual representation as well as the {@link org.apache.avro.Schema} will be stored within this class.
* Once a schema is found for any Class, be it a POJO or a
* {@link org.apache.avro.generic.GenericContainer}, both textual representation as well
* as the {@link org.apache.avro.Schema} will be stored within this class.
*
* @author Vinicius Carvalho
*
@@ -40,7 +41,7 @@ public class ParsedSchema {
private SchemaRegistrationResponse registration;
public ParsedSchema(Schema schema){
public ParsedSchema(Schema schema) {
this.schema = schema;
this.representation = schema.toString();
}

View File

@@ -45,12 +45,12 @@ import org.springframework.messaging.converter.MessageConversionException;
import org.springframework.util.MimeType;
/**
* Base class for Apache Avro {@link org.springframework.messaging.converter.MessageConverter} implementations.
* Base class for Apache Avro
* {@link org.springframework.messaging.converter.MessageConverter} implementations.
* @author Marius Bogoevici
*/
public abstract class AbstractAvroMessageConverter extends AbstractMessageConverter {
protected AbstractAvroMessageConverter(MimeType supportedMimeType) {
super(supportedMimeType);
}

View File

@@ -38,19 +38,17 @@ import org.springframework.util.ObjectUtils;
@ConditionalOnClass(name = "org.apache.avro.Schema")
@ConditionalOnProperty(value = "spring.cloud.stream.schemaRegistryClient.enabled", matchIfMissing = true)
@ConditionalOnBean(type = "org.springframework.cloud.stream.schema.client.SchemaRegistryClient")
@EnableConfigurationProperties({AvroMessageConverterProperties.class})
@EnableConfigurationProperties({ AvroMessageConverterProperties.class })
public class AvroMessageConverterAutoConfiguration {
@Autowired
private AvroMessageConverterProperties avroMessageConverterProperties;
@Bean
@ConditionalOnMissingBean(AvroSchemaRegistryClientMessageConverter.class)
public AvroSchemaRegistryClientMessageConverter avroSchemaMessageConverter(
SchemaRegistryClient schemaRegistryClient) {
AvroSchemaRegistryClientMessageConverter
avroSchemaRegistryClientMessageConverter = new AvroSchemaRegistryClientMessageConverter(
AvroSchemaRegistryClientMessageConverter avroSchemaRegistryClientMessageConverter = new AvroSchemaRegistryClientMessageConverter(
schemaRegistryClient);
avroSchemaRegistryClientMessageConverter.setDynamicSchemaGenerationEnabled(
this.avroMessageConverterProperties.isDynamicSchemaGenerationEnabled());
@@ -70,7 +68,7 @@ public class AvroMessageConverterAutoConfiguration {
@Bean
@ConditionalOnMissingBean
public CacheManager cacheManager(){
public CacheManager cacheManager() {
return new ConcurrentMapCacheManager();
}
}

View File

@@ -27,14 +27,11 @@ import org.springframework.util.Assert;
import org.springframework.util.MimeType;
/**
* A {@link org.springframework.messaging.converter.MessageConverter}
* using Apache Avro.
* The schema for serializing and deserializing will be automatically inferred
* from the class for {@link org.apache.avro.specific.SpecificRecord} and regular
* classes, unless a specific schema is set, case in which that schema will be used
* instead.
* For converting to {@link org.apache.avro.generic.GenericRecord} targets,
* a schema must be set.s
* A {@link org.springframework.messaging.converter.MessageConverter} using Apache Avro.
* The schema for serializing and deserializing will be automatically inferred from the
* class for {@link org.apache.avro.specific.SpecificRecord} and regular classes, unless a
* specific schema is set, case in which that schema will be used instead. For converting
* to {@link org.apache.avro.generic.GenericRecord} targets, a schema must be set.s
* @author Marius Bogoevici
*/
@@ -43,24 +40,24 @@ public class AvroSchemaMessageConverter extends AbstractAvroMessageConverter {
private Schema schema;
/**
* Create a {@link AvroSchemaMessageConverter}.
* Uses the default {@link MimeType} of {@code "application/avro"}.
* Create a {@link AvroSchemaMessageConverter}. Uses the default {@link MimeType} of
* {@code "application/avro"}.
*/
public AvroSchemaMessageConverter() {
super(new MimeType("application", "avro"));
}
/**
* Create a {@link AvroSchemaMessageConverter}.
* The converter will be used for the provided {@link MimeType}.
* Create a {@link AvroSchemaMessageConverter}. The converter will be used for the
* provided {@link MimeType}.
*/
public AvroSchemaMessageConverter(MimeType supportedMimeType) {
super(supportedMimeType);
}
/**
* Create a {@link AvroSchemaMessageConverter}.
* The converter will be used for the provided {@link MimeType}s.
* Create a {@link AvroSchemaMessageConverter}. The converter will be used for the
* provided {@link MimeType}s.
* @param supportedMimeTypes the mime types supported by this converter
*/
public AvroSchemaMessageConverter(Collection<MimeType> supportedMimeTypes) {

View File

@@ -110,13 +110,15 @@ public class AvroSchemaRegistryClientMessageConverter extends AbstractAvroMessag
}
/**
* Creates a new instance, configuring it with {@link SchemaRegistryClient} and {@link CacheManager}.
* Creates a new instance, configuring it with {@link SchemaRegistryClient} and
* {@link CacheManager}.
* @param schemaRegistryClient the {@link SchemaRegistryClient} used to interact with
* the schema registry server.
* @param cacheManager instance of {@link CacheManager} to cache parsed schemas. If caching
* is not required use {@link NoOpCacheManager}
* @param cacheManager instance of {@link CacheManager} to cache parsed schemas. If
* caching is not required use {@link NoOpCacheManager}
*/
public AvroSchemaRegistryClientMessageConverter(SchemaRegistryClient schemaRegistryClient, CacheManager cacheManager) {
public AvroSchemaRegistryClientMessageConverter(SchemaRegistryClient schemaRegistryClient,
CacheManager cacheManager) {
super(Arrays.asList(new MimeType("application", "*+avro")));
Assert.notNull(schemaRegistryClient, "cannot be null");
Assert.notNull(cacheManager, "'cacheManager' cannot be null");
@@ -194,7 +196,7 @@ public class AvroSchemaRegistryClientMessageConverter extends AbstractAvroMessag
}
}
}
if (this.cacheManager instanceof NoOpCacheManager){
if (this.cacheManager instanceof NoOpCacheManager) {
logger.warn("Schema caching is effectively disabled "
+ "since configured cache manager is a NoOpCacheManager. If this was not "
+ "the intention, please provide the appropriate instance of CacheManager "
@@ -337,7 +339,6 @@ public class AvroSchemaRegistryClientMessageConverter extends AbstractAvroMessag
return schema;
}
/**
* @deprecated as of release 1.0.4. Please use the constructor to inject CacheManager
*/

View File

@@ -46,9 +46,9 @@ public class CachingRegistryClient implements SchemaRegistryClient {
@Override
public SchemaRegistrationResponse register(String subject, String format, String schema) {
SchemaRegistrationResponse response = delegate.register(subject,format,schema);
cacheManager.getCache(ID_CACHE).put(response.getSchemaReference(),schema);
cacheManager.getCache(REF_CACHE).put(response.getId(),schema);
SchemaRegistrationResponse response = delegate.register(subject, format, schema);
cacheManager.getCache(ID_CACHE).put(response.getSchemaReference(), schema);
cacheManager.getCache(REF_CACHE).put(response.getId(), schema);
return response;
}

View File

@@ -31,7 +31,6 @@ import org.springframework.web.client.RestTemplate;
*/
public class DefaultSchemaRegistryClient implements SchemaRegistryClient {
private RestTemplate template;
private String endpoint = "http://localhost:8990";
@@ -69,7 +68,8 @@ public class DefaultSchemaRegistryClient implements SchemaRegistryClient {
ResponseEntity<Map> responseEntity = this.template.getForEntity(
this.endpoint + "/" + schemaReference.getSubject() + "/" + schemaReference
.getFormat() + "/v" + schemaReference
.getVersion(), Map.class);
.getVersion(),
Map.class);
if (!responseEntity.getStatusCode().is2xxSuccessful()) {
throw new RuntimeException("Failed to fetch schema: " + responseEntity.toString());
}

View File

@@ -30,7 +30,7 @@ import org.springframework.context.annotation.Import;
/**
* @author Marius Bogoevici
*/
@Target({ElementType.TYPE, ElementType.ANNOTATION_TYPE})
@Target({ ElementType.TYPE, ElementType.ANNOTATION_TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited

View File

@@ -26,16 +26,19 @@ import org.springframework.cloud.stream.schema.SchemaRegistrationResponse;
public interface SchemaRegistryClient {
/**
* Registers a schema with the remote repository returning the unique identifier associated with this schema.
* Registers a schema with the remote repository returning the unique identifier
* associated with this schema.
* @param subject the full name of the schema
* @param schema
* @return a {@link SchemaRegistrationResponse} representing the result of the operation
* @return a {@link SchemaRegistrationResponse} representing the result of the
* operation
*/
SchemaRegistrationResponse register(String subject, String format, String schema);
/**
* Retrieves a schema by its reference (subject and version).
* @param schemaReference a {@link SchemaReference} used to identify the target schema.
* @param schemaReference a {@link SchemaReference} used to identify the target
* schema.
* @return
*/
String fetch(SchemaReference schemaReference);

View File

@@ -44,7 +44,8 @@ public class SchemaRegistryClientConfiguration {
defaultSchemaRegistryClient.setEndpoint(schemaRegistryClientProperties.getEndpoint());
}
SchemaRegistryClient client = (schemaRegistryClientProperties.isCached()) ? new CachingRegistryClient(defaultSchemaRegistryClient) : defaultSchemaRegistryClient;
SchemaRegistryClient client = (schemaRegistryClientProperties.isCached())
? new CachingRegistryClient(defaultSchemaRegistryClient) : defaultSchemaRegistryClient;
return client;
}

View File

@@ -53,12 +53,12 @@ public class AvroMessageConverterSerializationTests {
Pattern versionedSchema = Pattern.compile(
"application/" + "vnd" + "\\.([\\p{Alnum}\\$\\.]+)\\.v(\\p{Digit}+)\\+avro");
private ConfigurableApplicationContext schemaRegistryServerContext;
Log logger = LogFactory.getLog(getClass());
private ConfigurableApplicationContext schemaRegistryServerContext;
@Before
public void setup(){
public void setup() {
schemaRegistryServerContext = SpringApplication.run(
SchemaRegistryServerApplication.class);
}
@@ -72,9 +72,10 @@ public class AvroMessageConverterSerializationTests {
public void sourceWriteSameVersion() throws Exception {
User specificRecord = new User();
specificRecord.setName("joe");
Schema v1 = new Schema.Parser().parse(AvroMessageConverterSerializationTests.class.getClassLoader().getResourceAsStream("schemas/user.avsc"));
Schema v1 = new Schema.Parser().parse(
AvroMessageConverterSerializationTests.class.getClassLoader().getResourceAsStream("schemas/user.avsc"));
GenericRecord genericRecord = new GenericData.Record(v1);
genericRecord.put("name","joe");
genericRecord.put("name", "joe");
SchemaRegistryClient client = new DefaultSchemaRegistryClient();
AvroSchemaRegistryClientMessageConverter converter = new AvroSchemaRegistryClientMessageConverter(client);
converter.setDynamicSchemaGenerationEnabled(false);
@@ -82,13 +83,19 @@ public class AvroMessageConverterSerializationTests {
converter.setCacheManager(new ConcurrentMapCacheManager());
converter.afterPropertiesSet();
Message specificMessage = converter.toMessage(specificRecord,new MutableMessageHeaders(Collections.<String,Object>emptyMap()), MimeTypeUtils.parseMimeType("application/*+avro"));
SchemaReference specificRef = extractSchemaReference( MimeTypeUtils.parseMimeType(specificMessage.getHeaders().get("contentType").toString()));
Message specificMessage = converter.toMessage(specificRecord,
new MutableMessageHeaders(Collections.<String, Object>emptyMap()),
MimeTypeUtils.parseMimeType("application/*+avro"));
SchemaReference specificRef = extractSchemaReference(
MimeTypeUtils.parseMimeType(specificMessage.getHeaders().get("contentType").toString()));
Message genericMessage = converter.toMessage(genericRecord,new MutableMessageHeaders(Collections.<String,Object>emptyMap()), MimeTypeUtils.parseMimeType("application/*+avro"));
SchemaReference genericRef = extractSchemaReference( MimeTypeUtils.parseMimeType(genericMessage.getHeaders().get("contentType").toString()));
Message genericMessage = converter.toMessage(genericRecord,
new MutableMessageHeaders(Collections.<String, Object>emptyMap()),
MimeTypeUtils.parseMimeType("application/*+avro"));
SchemaReference genericRef = extractSchemaReference(
MimeTypeUtils.parseMimeType(genericMessage.getHeaders().get("contentType").toString()));
Assert.assertEquals(genericRef,specificRef);
Assert.assertEquals(genericRef, specificRef);
Assert.assertEquals(1, genericRef.getVersion());
}
@@ -98,7 +105,8 @@ public class AvroMessageConverterSerializationTests {
if (schemaMatcher.find()) {
String subject = schemaMatcher.group(1);
Integer version = Integer.parseInt(schemaMatcher.group(2));
schemaReference = new SchemaReference(subject, version, AvroSchemaRegistryClientMessageConverter.AVRO_FORMAT);
schemaReference = new SchemaReference(subject, version,
AvroSchemaRegistryClientMessageConverter.AVRO_FORMAT);
}
return schemaReference;
}

View File

@@ -68,7 +68,6 @@ public class AvroSchemaMessageConverterTests {
Message<?> outboundMessage = sourceMessageCollector.forChannel(source.output()).poll(1000,
TimeUnit.MILLISECONDS);
ConfigurableApplicationContext barSourceContext = SpringApplication.run(AvroSourceApplication.class,
"--server.port=0",
"--spring.jmx.enabled=false",
@@ -87,7 +86,6 @@ public class AvroSchemaMessageConverterTests {
assertThat(barOutboundMessage).isNotNull();
User2 secondUser2OutboundPojo = new User2();
secondUser2OutboundPojo.setFavoriteColor("foo" + UUID.randomUUID().toString());
secondUser2OutboundPojo.setFavoritePlace("foo" + UUID.randomUUID().toString());
@@ -96,7 +94,6 @@ public class AvroSchemaMessageConverterTests {
Message<?> secondBarOutboundMessage = sourceMessageCollector.forChannel(source.output()).poll(1000,
TimeUnit.MILLISECONDS);
ConfigurableApplicationContext sinkContext = SpringApplication.run(AvroSinkApplication.class,
"--server.port=0",
"--spring.jmx.enabled=false",
@@ -139,7 +136,6 @@ public class AvroSchemaMessageConverterTests {
Message<?> outboundMessage = sourceMessageCollector.forChannel(source.output()).poll(1000,
TimeUnit.MILLISECONDS);
ConfigurableApplicationContext barSourceContext = SpringApplication.run(AvroSourceApplication.class,
"--server.port=0",
"--spring.jmx.enabled=false",
@@ -157,7 +153,6 @@ public class AvroSchemaMessageConverterTests {
assertThat(barOutboundMessage).isNotNull();
User2 secondUser2OutboundPojo = new User2();
secondUser2OutboundPojo.setFavoriteColor("foo" + UUID.randomUUID().toString());
secondUser2OutboundPojo.setFavoritePlace("foo" + UUID.randomUUID().toString());
@@ -166,7 +161,6 @@ public class AvroSchemaMessageConverterTests {
Message<?> secondBarOutboundMessage = sourceMessageCollector.forChannel(source.output()).poll(1000,
TimeUnit.MILLISECONDS);
ConfigurableApplicationContext sinkContext = SpringApplication.run(AvroSinkApplication.class,
"--server.port=0",
"--spring.jmx.enabled=false",
@@ -192,19 +186,18 @@ public class AvroSchemaMessageConverterTests {
sourceContext.close();
}
@EnableBinding(Source.class)
@EnableAutoConfiguration
@ConfigurationProperties
public static class AvroSourceApplication {
private Resource schemaLocation;
@Bean
public SchemaRegistryClient schemaRegistryClient() {
return stubSchemaRegistryClient;
}
private Resource schemaLocation;
public void setSchemaLocation(Resource schemaLocation) {
this.schemaLocation = schemaLocation;
}
@@ -227,13 +220,13 @@ public class AvroSchemaMessageConverterTests {
public List<User1> receivedUsers = new ArrayList<>();
private Resource schemaLocation;
@StreamListener(Sink.INPUT)
public void listen(User1 user) {
receivedUsers.add(user);
}
private Resource schemaLocation;
public void setSchemaLocation(Resource schemaLocation) {
this.schemaLocation = schemaLocation;
}

View File

@@ -44,6 +44,7 @@ import org.springframework.messaging.Message;
import org.springframework.messaging.support.MessageBuilder;
import static org.assertj.core.api.Assertions.assertThat;
/**
* @author Marius Bogoevici
* @author Oleg Zhurakousky
@@ -72,7 +73,6 @@ public class AvroSchemaRegistryClientMessageConverterTests {
Message<?> outboundMessage = sourceMessageCollector.forChannel(source.output()).poll(1000,
TimeUnit.MILLISECONDS);
ConfigurableApplicationContext barSourceContext = SpringApplication.run(AvroSourceApplication.class,
"--server.port=0",
"--spring.jmx.enabled=false",
@@ -89,7 +89,6 @@ public class AvroSchemaRegistryClientMessageConverterTests {
assertThat(barOutboundMessage).isNotNull();
User2 secondBarOutboundPojo = new User2();
secondBarOutboundPojo.setFavoriteColor("foo" + UUID.randomUUID().toString());
secondBarOutboundPojo.setName("foo" + UUID.randomUUID().toString());
@@ -97,7 +96,6 @@ public class AvroSchemaRegistryClientMessageConverterTests {
Message<?> secondBarOutboundMessage = sourceMessageCollector.forChannel(source.output()).poll(1000,
TimeUnit.MILLISECONDS);
ConfigurableApplicationContext sinkContext = SpringApplication.run(AvroSinkApplication.class,
"--server.port=0", "--spring.jmx.enabled=false");
Sink sink = sinkContext.getBean(Sink.class);
@@ -116,7 +114,6 @@ public class AvroSchemaRegistryClientMessageConverterTests {
assertThat(receivedPojos.get(1).getName()).isEqualTo(firstOutboundUser2.getName());
assertThat(receivedPojos.get(1).getFavoritePlace()).isEqualTo("Boston");
assertThat(receivedPojos.get(2)).isNotSameAs(secondBarOutboundPojo);
assertThat(receivedPojos.get(2).getFavoriteColor()).isEqualTo(secondBarOutboundPojo.getFavoriteColor());
assertThat(receivedPojos.get(2).getName()).isEqualTo(secondBarOutboundPojo.getName());
@@ -128,6 +125,16 @@ public class AvroSchemaRegistryClientMessageConverterTests {
schemaRegistryServerContext.close();
}
@Test
public void testNoCacheConfiguration() {
ConfigurableApplicationContext sourceContext = SpringApplication.run(NoCacheConfiguration.class,
"--spring.main.web-environment=false");
AvroSchemaRegistryClientMessageConverter converter = sourceContext
.getBean(AvroSchemaRegistryClientMessageConverter.class);
DirectFieldAccessor accessor = new DirectFieldAccessor(converter);
assertThat(accessor.getPropertyValue("cacheManager")).isInstanceOf(NoOpCacheManager.class);
}
@EnableBinding(Source.class)
@EnableAutoConfiguration
@EnableSchemaRegistryClient
@@ -149,14 +156,6 @@ public class AvroSchemaRegistryClientMessageConverterTests {
}
@Test
public void testNoCacheConfiguration (){
ConfigurableApplicationContext sourceContext = SpringApplication.run(NoCacheConfiguration.class, "--spring.main.web-environment=false");
AvroSchemaRegistryClientMessageConverter converter = sourceContext.getBean(AvroSchemaRegistryClientMessageConverter.class);
DirectFieldAccessor accessor = new DirectFieldAccessor(converter);
assertThat(accessor.getPropertyValue("cacheManager")).isInstanceOf(NoOpCacheManager.class);
}
@Configuration
public static class NoCacheConfiguration {
@SuppressWarnings("deprecation")

View File

@@ -62,7 +62,6 @@ public class AvroStubSchemaRegistryClientMessageConverterTests {
Message<?> outboundMessage = sourceMessageCollector.forChannel(source.output()).poll(1000,
TimeUnit.MILLISECONDS);
ConfigurableApplicationContext barSourceContext = SpringApplication.run(AvroSourceApplication.class,
"--server.port=0",
"--spring.jmx.enabled=false",
@@ -79,7 +78,6 @@ public class AvroStubSchemaRegistryClientMessageConverterTests {
assertThat(barOutboundMessage).isNotNull();
User2 secondBarOutboundPojo = new User2();
secondBarOutboundPojo.setFavoriteColor("foo" + UUID.randomUUID().toString());
secondBarOutboundPojo.setName("foo" + UUID.randomUUID().toString());
@@ -87,7 +85,6 @@ public class AvroStubSchemaRegistryClientMessageConverterTests {
Message<?> secondBarOutboundMessage = sourceMessageCollector.forChannel(source.output()).poll(1000,
TimeUnit.MILLISECONDS);
ConfigurableApplicationContext sinkContext = SpringApplication.run(AvroSinkApplication.class,
"--server.port=0", "--spring.jmx.enabled=false");
Sink sink = sinkContext.getBean(Sink.class);
@@ -106,7 +103,6 @@ public class AvroStubSchemaRegistryClientMessageConverterTests {
assertThat(receivedPojos.get(1).getName()).isEqualTo(firstOutboundUser2.getName());
assertThat(receivedPojos.get(1).getFavoritePlace()).isEqualTo("Boston");
assertThat(receivedPojos.get(2)).isNotSameAs(secondBarOutboundPojo);
assertThat(receivedPojos.get(2).getFavoriteColor()).isEqualTo(secondBarOutboundPojo.getFavoriteColor());
assertThat(receivedPojos.get(2).getName()).isEqualTo(secondBarOutboundPojo.getName());

View File

@@ -42,12 +42,12 @@ public abstract class AbstractExternalResourceTestSupport<R> implements TestRule
public static final String SCS_EXTERNAL_SERVERS_REQUIRED = "SCS_EXTERNAL_SERVERS_REQUIRED";
protected final Log logger = LogFactory.getLog(getClass());
protected R resource;
private String resourceDescription;
protected final Log logger = LogFactory.getLog(getClass());
protected AbstractExternalResourceTestSupport(String resourceDescription) {
Assert.hasText(resourceDescription, "resourceDescription is required");
this.resourceDescription = resourceDescription;

View File

@@ -22,8 +22,8 @@ import org.springframework.messaging.Message;
import org.springframework.messaging.MessageChannel;
/**
* Maintains a map between (output) channels and messages received (in FIFO order). To be injected in tests that
* can then run assertions on the enqueued messages.
* Maintains a map between (output) channels and messages received (in FIFO order). To be
* injected in tests that can then run assertions on the enqueued messages.
*
* @author Eric Bottard
*/

View File

@@ -25,7 +25,8 @@ import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.MapPropertySource;
/**
* An {@link EnvironmentPostProcessor} that sets some configuration properties for {@link TestSupportBinder}.
* An {@link EnvironmentPostProcessor} that sets some configuration properties for
* {@link TestSupportBinder}.
*
* @author Ilayaperumal Gopinathan
*/

View File

@@ -36,9 +36,12 @@ import org.springframework.messaging.SubscribableChannel;
import org.springframework.util.Assert;
/**
* A minimal binder that<ul>
* <li>does nothing about binding consumers, leaving the channel as-is, so that a test author can interact with it directly,</li>
* <li>registers a queue channel on the producer side, so that it is easy to assert what is received.</li>
* A minimal binder that
* <ul>
* <li>does nothing about binding consumers, leaving the channel as-is, so that a test
* author can interact with it directly,</li>
* <li>registers a queue channel on the producer side, so that it is easy to assert what
* is received.</li>
* </ul>
*
* @author Eric Bottard
@@ -53,12 +56,14 @@ public class TestSupportBinder implements Binder<MessageChannel, ConsumerPropert
private final ConcurrentMap<String, MessageChannel> messageChannels = new ConcurrentHashMap<>();
@Override
public Binding<MessageChannel> bindConsumer(String name, String group, MessageChannel inboundBindTarget, ConsumerProperties properties) {
public Binding<MessageChannel> bindConsumer(String name, String group, MessageChannel inboundBindTarget,
ConsumerProperties properties) {
return new TestBinding(inboundBindTarget, null);
}
/**
* Registers a single subscriber to the channel, that enqueues messages for later retrieval and assertion in tests.
* Registers a single subscriber to the channel, that enqueues messages for later
* retrieval and assertion in tests.
*/
@Override
public Binding<MessageChannel> bindProducer(String name, MessageChannel outboundBindTarget,
@@ -99,7 +104,8 @@ public class TestSupportBinder implements Binder<MessageChannel, ConsumerPropert
}
private void unregister(MessageChannel channel) {
Assert.notNull(results.remove(channel), "Trying to unregister a mapping for an unknown channel [" + channel + "]");
Assert.notNull(results.remove(channel),
"Trying to unregister a mapping for an unknown channel [" + channel + "]");
}
@Override

View File

@@ -27,12 +27,12 @@ import org.springframework.core.Ordered;
import org.springframework.messaging.MessageChannel;
/**
* Installs the {@link TestSupportBinder} and exposes {@link TestSupportBinder.MessageCollectorImpl} to be injected in
* tests.
* Installs the {@link TestSupportBinder} and exposes
* {@link TestSupportBinder.MessageCollectorImpl} to be injected in tests.
*
* Note that this auto-configuration has higher priority than regular binder configuration, so adding
* this on the classpath in test scope is sufficient to have support kick in and replace all binders
* with the test binder.
* Note that this auto-configuration has higher priority than regular binder
* configuration, so adding this on the classpath in test scope is sufficient to have
* support kick in and replace all binders with the test binder.
*
* @author Eric Bottard
* @author Marius Bogoevici
@@ -47,7 +47,8 @@ public class TestSupportBinderAutoConfiguration {
public BinderFactory binderFactory() {
return new BinderFactory() {
@Override
public <T> Binder<T, ? extends ConsumerProperties, ? extends ProducerProperties> getBinder(String configurationName, Class<? extends T> bindableType) {
public <T> Binder<T, ? extends ConsumerProperties, ? extends ProducerProperties> getBinder(
String configurationName, Class<? extends T> bindableType) {
return (Binder<T, ? extends ConsumerProperties, ? extends ProducerProperties>) messageChannelBinder;
}
};

View File

@@ -33,7 +33,9 @@ import org.springframework.messaging.Message;
/**
* A Hamcrest Matcher meant to be used in conjunction with {@link TestSupportBinder}.
*
* <p>Expected usage is of the form (with appropriate static imports):
* <p>
* Expected usage is of the form (with appropriate static imports):
*
* <pre>
* public class TransformProcessorApplicationTests {
*
@@ -51,7 +53,8 @@ import org.springframework.messaging.Message;
* assertThat(messageCollector.forChannel(processor.output()), receivesPayloadThat(is("hellofoo")).within(10));
* }
*
* }</pre>
* }
* </pre>
* </p>
*
* @author Eric Bottard
@@ -62,12 +65,12 @@ public class MessageQueueMatcher<T> extends BaseMatcher<BlockingQueue<Message<?>
private final long timeout;
private final TimeUnit unit;
private Extractor<Message<?>, T> extractor;
private Map<BlockingQueue<Message<?>>, T> actuallyReceived = new HashMap<>();
private final TimeUnit unit;
public MessageQueueMatcher(Matcher<T> delegate, long timeout, TimeUnit unit, Extractor<Message<?>, T> extractor) {
this.delegate = delegate;
this.timeout = timeout;
@@ -75,6 +78,28 @@ public class MessageQueueMatcher<T> extends BaseMatcher<BlockingQueue<Message<?>
this.extractor = extractor;
}
@SuppressWarnings({ "unchecked", "rawtypes" })
public static <P> MessageQueueMatcher<P> receivesMessageThat(Matcher<Message<P>> messageMatcher) {
return new MessageQueueMatcher(messageMatcher, 5, TimeUnit.SECONDS,
new Extractor<Message<P>, Message<P>>("a message that ") {
@Override
public Message<P> apply(Message<P> m) {
return m;
}
});
}
@SuppressWarnings({ "unchecked", "rawtypes" })
public static <P> MessageQueueMatcher<P> receivesPayloadThat(Matcher<P> payloadMatcher) {
return new MessageQueueMatcher(payloadMatcher, 5, TimeUnit.SECONDS,
new Extractor<Message<P>, P>("a message whose payload ") {
@Override
public P apply(Message<P> m) {
return m.getPayload();
}
});
}
@Override
public boolean matches(Object item) {
@SuppressWarnings("unchecked")
@@ -129,28 +154,9 @@ public class MessageQueueMatcher<T> extends BaseMatcher<BlockingQueue<Message<?>
description.appendText("Channel to receive ").appendDescriptionOf(extractor).appendDescriptionOf(delegate);
}
@SuppressWarnings({"unchecked", "rawtypes"})
public static <P> MessageQueueMatcher<P> receivesMessageThat(Matcher<Message<P>> messageMatcher) {
return new MessageQueueMatcher(messageMatcher, 5, TimeUnit.SECONDS, new Extractor<Message<P>, Message<P>>("a message that ") {
@Override
public Message<P> apply(Message<P> m) {
return m;
}
});
}
@SuppressWarnings({"unchecked", "rawtypes"})
public static <P> MessageQueueMatcher<P> receivesPayloadThat(Matcher<P> payloadMatcher) {
return new MessageQueueMatcher(payloadMatcher, 5, TimeUnit.SECONDS, new Extractor<Message<P>, P>("a message whose payload ") {
@Override
public P apply(Message<P> m) {
return m.getPayload();
}
});
}
/**
* A transformation to be applied to a received message before asserting, <i>e.g.</i> to only inspect the payload.
* A transformation to be applied to a received message before asserting, <i>e.g.</i>
* to only inspect the payload.
*/
public static abstract class Extractor<R, T> implements Function<R, T>, SelfDescribing {
@@ -166,6 +172,4 @@ public class MessageQueueMatcher<T> extends BaseMatcher<BlockingQueue<Message<?>
}
}
}

View File

@@ -42,7 +42,7 @@ import static org.assertj.core.api.Assertions.assertThat;
* @author Marius Bogoevici
*/
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = AggregateWithBeanTest.ChainedProcessors.class, properties = {"server.port=-1"})
@SpringBootTest(classes = AggregateWithBeanTest.ChainedProcessors.class, properties = { "server.port=-1" })
public class AggregateWithBeanTest {
@Autowired

View File

@@ -43,8 +43,9 @@ public class AggregateWithMainTest {
@Test
public void testAggregateApplication() throws InterruptedException {
// emulate a main method
ConfigurableApplicationContext context = new AggregateApplicationBuilder(TestSupportBinderAutoConfiguration.class).from(UppercaseProcessor.class)
.namespace("upper").to(SuffixProcessor.class).namespace("suffix").run();
ConfigurableApplicationContext context = new AggregateApplicationBuilder(
TestSupportBinderAutoConfiguration.class).from(UppercaseProcessor.class)
.namespace("upper").to(SuffixProcessor.class).namespace("suffix").run();
AggregateApplication aggregateAccessor = context.getBean(AggregateApplication.class);
MessageCollector messageCollector = context.getBean(MessageCollector.class);
@@ -61,7 +62,6 @@ public class AggregateWithMainTest {
@EnableBinding(Processor.class)
public static class UppercaseProcessor {
@Autowired
Processor processor;

View File

@@ -36,11 +36,12 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Integration test that validates that {@link org.springframework.cloud.stream.test.binder.TestSupportBinder} applies
* Integration test that validates that
* {@link org.springframework.cloud.stream.test.binder.TestSupportBinder} applies
* correctly.
*/
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = ExampleTest.MyProcessor.class, properties = {"server.port=-1"})
@SpringBootTest(classes = ExampleTest.MyProcessor.class, properties = { "server.port=-1" })
@DirtiesContext
public class ExampleTest {
@@ -63,7 +64,6 @@ public class ExampleTest {
assertThat(received.getPayload()).isEqualTo("hello world");
}
@SpringBootApplication
@EnableBinding(Processor.class)
public static class MyProcessor {

View File

@@ -17,15 +17,16 @@
package org.springframework.cloud.stream.aggregate;
/**
* Handle to an aggregate application, providing access to the underlying
* components of the aggregate (e.g. bindable instances).
* Handle to an aggregate application, providing access to the underlying components of
* the aggregate (e.g. bindable instances).
*
* @author Marius Bogoevici
*/
public interface AggregateApplication {
/**
* Retrieves the bindable proxy instance (e.g. {@link org.springframework.cloud.stream.messaging.Processor},
* Retrieves the bindable proxy instance (e.g.
* {@link org.springframework.cloud.stream.messaging.Processor},
* {@link org.springframework.cloud.stream.messaging.Source},
* {@link org.springframework.cloud.stream.messaging.Sink} or custom interface) from
* the given namespace.

View File

@@ -61,7 +61,7 @@ import org.springframework.util.StringUtils;
*/
@EnableBinding
public class AggregateApplicationBuilder implements AggregateApplication, ApplicationContextAware,
SmartInitializingSingleton {
SmartInitializingSingleton {
private static final String CHILD_CONTEXT_SUFFIX = ".spring.cloud.stream.context";
@@ -84,11 +84,11 @@ public class AggregateApplicationBuilder implements AggregateApplication, Applic
private boolean webEnvironment = true;
public AggregateApplicationBuilder(String... args) {
this(new Object[]{ParentConfiguration.class}, args);
this(new Object[] { ParentConfiguration.class }, args);
}
public AggregateApplicationBuilder(Object source, String... args) {
this(new Object[]{source}, args);
this(new Object[] { source }, args);
}
public AggregateApplicationBuilder(Object[] sources, String[] args) {
@@ -108,7 +108,7 @@ public class AggregateApplicationBuilder implements AggregateApplication, Applic
}
public AggregateApplicationBuilder parent(Object source, String... args) {
return parent(new Object[]{source}, args);
return parent(new Object[] { source }, args);
}
public AggregateApplicationBuilder parent(Object[] sources, String[] args) {
@@ -194,16 +194,18 @@ public class AggregateApplicationBuilder implements AggregateApplication, Applic
Class<?> appToEmbed = appConfigurer.getApp();
// Always update namespace before preparing SharedChannelRegistry
if (appConfigurer.namespace == null) {
appConfigurer.namespace = AggregateApplicationUtils.getDefaultNamespace(appConfigurer.getApp().getName(), i);
appConfigurer.namespace = AggregateApplicationUtils
.getDefaultNamespace(appConfigurer.getApp().getName(), i);
}
appsToEmbed.put(appToEmbed, appConfigurer.namespace);
appConfigurers.put(appConfigurer, appConfigurer.namespace);
}
if (this.parentContext == null) {
if (Boolean.TRUE.equals(this.webEnvironment)) {
this.addParentSources(new Object[]{EmbeddedServletContainerAutoConfiguration.class});
this.addParentSources(new Object[] { EmbeddedServletContainerAutoConfiguration.class });
}
this.parentContext = AggregateApplicationUtils.createParentContext(this.parentSources.toArray(new Object[0]),
this.parentContext = AggregateApplicationUtils.createParentContext(
this.parentSources.toArray(new Object[0]),
this.parentArgs.toArray(new String[0]), selfContained(), this.webEnvironment, this.headless);
}
else {
@@ -216,7 +218,8 @@ public class AggregateApplicationBuilder implements AggregateApplication, Applic
new SharedChannelRegistry(sharedBindingTargetRegistry));
}
}
SharedBindingTargetRegistry sharedBindingTargetRegistry = this.parentContext.getBean(SharedBindingTargetRegistry.class);
SharedBindingTargetRegistry sharedBindingTargetRegistry = this.parentContext
.getBean(SharedBindingTargetRegistry.class);
AggregateApplicationUtils.prepareSharedBindingTargetRegistry(sharedBindingTargetRegistry, appsToEmbed);
PropertySources propertySources = this.parentContext.getEnvironment()
.getPropertySources();
@@ -291,6 +294,36 @@ public class AggregateApplicationBuilder implements AggregateApplication, Applic
return new ChildContextBuilder(AggregateApplicationUtils.embedApp(parentContext, namespace, app));
}
private static class ChildContextHolder {
private final ConfigurableApplicationContext childContext;
ChildContextHolder(ConfigurableApplicationContext childContext) {
Assert.notNull(childContext, "cannot be null");
this.childContext = childContext;
}
public ConfigurableApplicationContext getChildContext() {
return childContext;
}
}
@ImportAutoConfiguration({ ChannelBindingAutoConfiguration.class, EndpointAutoConfiguration.class })
@EnableBinding
public static class ParentConfiguration {
@Bean
@ConditionalOnMissingBean(SharedBindingTargetRegistry.class)
public SharedBindingTargetRegistry sharedBindingTargetRegistry() {
return new SharedBindingTargetRegistry();
}
@Bean
@ConditionalOnMissingBean(SharedChannelRegistry.class)
public SharedChannelRegistry sharedChannelRegistry(SharedBindingTargetRegistry sharedBindingTargetRegistry) {
return new SharedChannelRegistry(sharedBindingTargetRegistry);
}
}
public class SourceConfigurer extends AppConfigurer<SourceConfigurer> {
public SourceConfigurer(Class<?> app) {
@@ -382,7 +415,7 @@ public class AggregateApplicationBuilder implements AggregateApplication, Applic
void embed() {
final ConfigurableApplicationContext childContext = childContext(this.app,
AggregateApplicationBuilder.this.parentContext, this.namespace).args(this.args).config(this.names)
.profiles(this.profiles).run();
.profiles(this.profiles).run();
// Register bindable proxies as beans so they can be queried for later
Map<String, BindableProxyFactory> bindableProxies = BeanFactoryUtils
.beansOfTypeIncludingAncestors(childContext.getBeanFactory(), BindableProxyFactory.class);
@@ -402,7 +435,8 @@ public class AggregateApplicationBuilder implements AggregateApplication, Applic
if (BeanFactoryUtils.beansOfTypeIncludingAncestors(AggregateApplicationBuilder.this.parentContext,
IntegrationMBeanExporter.class).size() > 0) {
BeanFactoryUtils
.beanOfTypeIncludingAncestors(AggregateApplicationBuilder.this.parentContext, MetricsEndpoint.class)
.beanOfTypeIncludingAncestors(AggregateApplicationBuilder.this.parentContext,
MetricsEndpoint.class)
.registerPublicMetrics(
new MetricReaderPublicMetrics(new NamespaceAwareSpringIntegrationMetricReader(
this.namespace, childContext.getBean(IntegrationMBeanExporter.class))));
@@ -413,7 +447,6 @@ public class AggregateApplicationBuilder implements AggregateApplication, Applic
return applicationBuilder;
}
public String[] getArgs() {
return this.args;
}
@@ -467,34 +500,4 @@ public class AggregateApplicationBuilder implements AggregateApplication, Applic
}
private static class ChildContextHolder {
private final ConfigurableApplicationContext childContext;
ChildContextHolder(ConfigurableApplicationContext childContext) {
Assert.notNull(childContext, "cannot be null");
this.childContext = childContext;
}
public ConfigurableApplicationContext getChildContext() {
return childContext;
}
}
@ImportAutoConfiguration({ChannelBindingAutoConfiguration.class, EndpointAutoConfiguration.class})
@EnableBinding
public static class ParentConfiguration {
@Bean
@ConditionalOnMissingBean(SharedBindingTargetRegistry.class)
public SharedBindingTargetRegistry sharedBindingTargetRegistry() {
return new SharedBindingTargetRegistry();
}
@Bean
@ConditionalOnMissingBean(SharedChannelRegistry.class)
public SharedChannelRegistry sharedChannelRegistry(SharedBindingTargetRegistry sharedBindingTargetRegistry) {
return new SharedChannelRegistry(sharedBindingTargetRegistry);
}
}
}

View File

@@ -27,11 +27,13 @@ import org.springframework.integration.support.management.Statistics;
import org.springframework.util.Assert;
/**
* A customized version of {@link org.springframework.boot.actuate.metrics.integration.SpringIntegrationMetricReader} that
* provides support for customizing channels with a namespace prefix.
* A customized version of
* {@link org.springframework.boot.actuate.metrics.integration.SpringIntegrationMetricReader}
* that provides support for customizing channels with a namespace prefix.
*
* @author Marius Bogoevici
* @see org.springframework.boot.actuate.metrics.integration.SpringIntegrationMetricReader for original implementation
* @see org.springframework.boot.actuate.metrics.integration.SpringIntegrationMetricReader
* for original implementation
*/
public class NamespaceAwareSpringIntegrationMetricReader implements MetricReader {
@@ -101,4 +103,3 @@ public class NamespaceAwareSpringIntegrationMetricReader implements MetricReader
}
}

View File

@@ -26,13 +26,13 @@ import java.lang.annotation.Target;
import org.springframework.beans.factory.annotation.Qualifier;
/**
* Indicates an instance of an interface containing methods returning bound
* inputs and outputs.
* Indicates an instance of an interface containing methods returning bound inputs and
* outputs.
*
* @author Dave Syer
* @author Marius Bogoevici
* @deprecated As of 1.1 for being redundant (beans qualified by it are already
* uniquely identified by their type)
* @deprecated As of 1.1 for being redundant (beans qualified by it are already uniquely
* identified by their type)
*/
@Qualifier

View File

@@ -34,7 +34,7 @@ import org.springframework.beans.factory.annotation.Qualifier;
@Qualifier
@Target({ ElementType.FIELD, ElementType.METHOD,
ElementType.ANNOTATION_TYPE, ElementType.PARAMETER })
ElementType.ANNOTATION_TYPE, ElementType.PARAMETER })
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented

View File

@@ -141,7 +141,7 @@ public @interface StreamListener {
* @return the name of the binding target.
*/
@AliasFor("value")
String target() default "";
String target() default "";
/**
* A condition that must be met by all items that are dispatched to this method.

View File

@@ -68,12 +68,12 @@ public abstract class AbstractBinder<T, C extends ConsumerProperties, P extends
protected final Log logger = LogFactory.getLog(getClass());
private final StringConvertingContentTypeResolver contentTypeResolver = new StringConvertingContentTypeResolver();
private volatile AbstractApplicationContext applicationContext;
private volatile Codec codec;
private final StringConvertingContentTypeResolver contentTypeResolver = new StringConvertingContentTypeResolver();
private volatile EvaluationContext evaluationContext;
private volatile Map<String, Class<?>> payloadTypeCache = new ConcurrentHashMap<>();
@@ -82,7 +82,7 @@ public abstract class AbstractBinder<T, C extends ConsumerProperties, P extends
* For binder implementations that support a prefix, apply the prefix to the name.
*
* @param prefix the prefix.
* @param name the name.
* @param name the name.
*/
public static String applyPrefix(String prefix, String name) {
return prefix + name;
@@ -98,16 +98,16 @@ public abstract class AbstractBinder<T, C extends ConsumerProperties, P extends
return name + ".dlq";
}
protected AbstractApplicationContext getApplicationContext() {
return this.applicationContext;
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
Assert.isInstanceOf(AbstractApplicationContext.class, applicationContext);
this.applicationContext = (AbstractApplicationContext) applicationContext;
}
protected AbstractApplicationContext getApplicationContext() {
return this.applicationContext;
}
protected ConfigurableListableBeanFactory getBeanFactory() {
return this.applicationContext.getBeanFactory();
}
@@ -157,7 +157,7 @@ public abstract class AbstractBinder<T, C extends ConsumerProperties, P extends
/**
* Construct a name comprised of the name and group.
*
* @param name the name.
* @param name the name.
* @param group the group.
* @return the constructed name.
*/
@@ -243,7 +243,8 @@ public abstract class AbstractBinder<T, C extends ConsumerProperties, P extends
return new String(bytes, "UTF-8");
}
catch (UnsupportedEncodingException e) {
String errorMessage = "unable to deserialize [java.lang.String]. Encoding not supported. " + e.getMessage();
String errorMessage = "unable to deserialize [java.lang.String]. Encoding not supported. "
+ e.getMessage();
logger.error(errorMessage);
throw new SerializationFailedException(errorMessage, e);
}
@@ -258,9 +259,10 @@ public abstract class AbstractBinder<T, C extends ConsumerProperties, P extends
this.payloadTypeCache.put(className, targetType);
}
return this.codec.decode(bytes, targetType);
}// catch all exceptions that could occur during de-serialization
} // catch all exceptions that could occur during de-serialization
catch (Exception e) {
String errorMessage = "Unable to deserialize [" + className + "] using the contentType [" + contentType + "] " + e.getMessage();
String errorMessage = "Unable to deserialize [" + className + "] using the contentType [" + contentType
+ "] " + e.getMessage();
logger.error(errorMessage);
throw new SerializationFailedException(errorMessage, e);
}

View File

@@ -39,15 +39,16 @@ import org.springframework.util.Assert;
import org.springframework.util.MimeType;
/**
* {@link AbstractBinder} that serves as base class for {@link MessageChannel}
* binders. Implementors must implement the following methods:
* {@link AbstractBinder} that serves as base class for {@link MessageChannel} binders.
* Implementors must implement the following methods:
* <ul>
* <li>{@link #createProducerMessageHandler(ProducerDestination, ProducerProperties)} </li>
* <li>{@link #createConsumerEndpoint(ConsumerDestination, String, ConsumerProperties)} </li>
* <li>{@link #createProducerMessageHandler(ProducerDestination, ProducerProperties)}</li>
* <li>{@link #createConsumerEndpoint(ConsumerDestination, String, ConsumerProperties)}
* </li>
* </ul>
*
* @param <C> the consumer properties type
* @param <P> the producer properties type
* @param <C> the consumer properties type
* @param <P> the producer properties type
* @author Marius Bogoevici
* @author Ilayaperumal Gopinathan
* @author Soby Chacko
@@ -59,9 +60,13 @@ public abstract class AbstractMessageChannelBinder<C extends ConsumerProperties,
protected static final ExpressionParser EXPRESSION_PARSER = new SpelExpressionParser();
/**
* Indicates whether the implementation and the message broker have
* native support for message headers. If false, headers will be
* embedded in the message payloads.
* {@link ProvisioningProvider} delegated by the downstream binder implementations.
*/
protected final PP provisioningProvider;
/**
* Indicates whether the implementation and the message broker have native support for
* message headers. If false, headers will be embedded in the message payloads.
*/
private final boolean supportsHeadersNatively;
@@ -71,13 +76,8 @@ public abstract class AbstractMessageChannelBinder<C extends ConsumerProperties,
*/
private final String[] headersToEmbed;
/**
* {@link ProvisioningProvider} delegated by the downstream binder implementations.
*/
protected final PP provisioningProvider;
public AbstractMessageChannelBinder(boolean supportsHeadersNatively, String[] headersToEmbed,
PP provisioningProvider) {
PP provisioningProvider) {
this.supportsHeadersNatively = supportsHeadersNatively;
this.headersToEmbed = headersToEmbed == null ? new String[0] : headersToEmbed;
this.provisioningProvider = provisioningProvider;
@@ -86,14 +86,15 @@ public abstract class AbstractMessageChannelBinder<C extends ConsumerProperties,
/**
* Binds an outbound channel to a given destination. The implementation delegates to
* {@link ProvisioningProvider#provisionProducerDestination(String, ProducerProperties)}
* and {@link #createProducerMessageHandler(ProducerDestination, ProducerProperties)} for
* handling the middleware specific logic. If the returned producer message handler is an
* {@link InitializingBean} then {@link InitializingBean#afterPropertiesSet()} will be
* called on it. Similarly, if the returned producer message handler e ndpoint is a
* {@link Lifecycle}, then {@link Lifecycle#start()} will be called on it.
* and {@link #createProducerMessageHandler(ProducerDestination, ProducerProperties)}
* for handling the middleware specific logic. If the returned producer message
* handler is an {@link InitializingBean} then
* {@link InitializingBean#afterPropertiesSet()} will be called on it. Similarly, if
* the returned producer message handler e ndpoint is a {@link Lifecycle}, then
* {@link Lifecycle#start()} will be called on it.
*
* @param destination the name of the destination
* @param outputChannel the channel to be bound
* @param destination the name of the destination
* @param outputChannel the channel to be bound
* @param producerProperties the {@link ProducerProperties} of the binding
* @return the Binding for the channel
* @throws BinderException on internal errors during binding
@@ -106,7 +107,8 @@ public abstract class AbstractMessageChannelBinder<C extends ConsumerProperties,
final MessageHandler producerMessageHandler;
final ProducerDestination producerDestination;
try {
producerDestination = this.provisioningProvider.provisionProducerDestination(destination, producerProperties);
producerDestination = this.provisioningProvider.provisionProducerDestination(destination,
producerProperties);
producerMessageHandler = createProducerMessageHandler(producerDestination, producerProperties);
if (producerMessageHandler instanceof InitializingBean) {
((InitializingBean) producerMessageHandler).afterPropertiesSet();
@@ -128,7 +130,8 @@ public abstract class AbstractMessageChannelBinder<C extends ConsumerProperties,
}
((SubscribableChannel) outputChannel).subscribe(
new SendingHandler(producerMessageHandler, !this.supportsHeadersNatively && HeaderMode.embeddedHeaders
.equals(producerProperties.getHeaderMode()), this.headersToEmbed, producerProperties.isUseNativeEncoding()));
.equals(producerProperties.getHeaderMode()), this.headersToEmbed,
producerProperties.isUseNativeEncoding()));
return new DefaultBinding<MessageChannel>(destination, null, outputChannel,
producerMessageHandler instanceof Lifecycle ? (Lifecycle) producerMessageHandler : null) {
@@ -139,8 +142,10 @@ public abstract class AbstractMessageChannelBinder<C extends ConsumerProperties,
if (producerMessageHandler instanceof DisposableBean) {
((DisposableBean) producerMessageHandler).destroy();
}
} catch (Exception e) {
AbstractMessageChannelBinder.this.logger.error("Exception thrown while unbinding " + this.toString(), e);
}
catch (Exception e) {
AbstractMessageChannelBinder.this.logger
.error("Exception thrown while unbinding " + this.toString(), e);
}
afterUnbindProducer(producerDestination, producerProperties);
}
@@ -148,31 +153,32 @@ public abstract class AbstractMessageChannelBinder<C extends ConsumerProperties,
}
/**
* Creates a {@link MessageHandler} with the ability to send data to the
* target middleware. If the returned instance is also a {@link Lifecycle},
* it will be stopped automatically by the binder.
* Creates a {@link MessageHandler} with the ability to send data to the target
* middleware. If the returned instance is also a {@link Lifecycle}, it will be
* stopped automatically by the binder.
* <p>
* In order to be fully compliant, the {@link MessageHandler} of the binder
* must observe the following headers:
* In order to be fully compliant, the {@link MessageHandler} of the binder must
* observe the following headers:
* <ul>
* <li>{@link BinderHeaders#PARTITION_HEADER} - indicates the target
* partition where the message must be sent</li>
* <li>{@link BinderHeaders#PARTITION_HEADER} - indicates the target partition where
* the message must be sent</li>
* </ul>
* <p>
*
* @param destination the name of the target destination
* @param destination the name of the target destination
* @param producerProperties the producer properties
* @return the message handler for sending data to the target middleware
* @throws Exception
*/
protected abstract MessageHandler createProducerMessageHandler(ProducerDestination destination, P producerProperties)
protected abstract MessageHandler createProducerMessageHandler(ProducerDestination destination,
P producerProperties)
throws Exception;
/**
* Invoked after the unbinding of a producer. Subclasses may override this to provide
* their own logic for dealing with unbinding.
*
* @param destination the bound destination
* @param destination the bound destination
* @param producerProperties the producer properties
*/
protected void afterUnbindProducer(ProducerDestination destination, P producerProperties) {
@@ -181,16 +187,17 @@ public abstract class AbstractMessageChannelBinder<C extends ConsumerProperties,
/**
* Binds an inbound channel to a given destination. The implementation delegates to
* {@link ProvisioningProvider#provisionConsumerDestination(String, String, ConsumerProperties)}
* and {@link #createConsumerEndpoint(ConsumerDestination, String, ConsumerProperties)}
* and
* {@link #createConsumerEndpoint(ConsumerDestination, String, ConsumerProperties)}
* for handling middleware-specific logic. If the returned consumer endpoint is an
* {@link InitializingBean} then {@link InitializingBean#afterPropertiesSet()} will be
* called on it. Similarly, if the returned consumer endpoint is a {@link Lifecycle},
* then {@link Lifecycle#start()} will be called on it.
*
* @param name the name of the destination
* @param group the consumer group
* @param name the name of the destination
* @param group the consumer group
* @param inputChannel the channel to be bound
* @param properties the {@link ConsumerProperties} of the binding
* @param properties the {@link ConsumerProperties} of the binding
* @return the Binding for the channel
* @throws BinderException on internal errors during binding
*/
@@ -199,7 +206,8 @@ public abstract class AbstractMessageChannelBinder<C extends ConsumerProperties,
final C properties) throws BinderException {
MessageProducer consumerEndpoint = null;
try {
final ConsumerDestination destination = this.provisioningProvider.provisionConsumerDestination(name, group, properties);
final ConsumerDestination destination = this.provisioningProvider.provisionConsumerDestination(name, group,
properties);
final boolean extractEmbeddedHeaders = HeaderMode.embeddedHeaders.equals(
properties.getHeaderMode()) && !this.supportsHeadersNatively;
ReceivingHandler rh = new ReceivingHandler(extractEmbeddedHeaders);
@@ -256,9 +264,9 @@ public abstract class AbstractMessageChannelBinder<C extends ConsumerProperties,
* Creates {@link MessageProducer} that receives data from the consumer destination.
* will be started and stopped by the binder.
*
* @param group the consumer group
* @param group the consumer group
* @param destination reference to the consumer destination
* @param properties the consumer properties
* @param properties the consumer properties
* @return the consumer endpoint.
*/
protected abstract MessageProducer createConsumerEndpoint(ConsumerDestination destination, String group,
@@ -268,8 +276,8 @@ public abstract class AbstractMessageChannelBinder<C extends ConsumerProperties,
* Invoked after the unbinding of a consumer. The binder implementation can override
* this method to provide their own logic (e.g. for cleaning up destinations).
*
* @param destination the consumer destination
* @param group the consumer group
* @param destination the consumer destination
* @param group the consumer group
* @param consumerProperties the consumer properties
*/
protected void afterUnbindConsumer(ConsumerDestination destination, String group, C consumerProperties) {
@@ -299,7 +307,8 @@ public abstract class AbstractMessageChannelBinder<C extends ConsumerProperties,
catch (Exception e) {
AbstractMessageChannelBinder.this.logger.error(
EmbeddedHeaderUtils.decodeExceptionMessage(
requestMessage), e);
requestMessage),
e);
messageValues = new MessageValues(requestMessage);
}
messageValues = deserializePayloadIfNecessary(messageValues);
@@ -338,8 +347,8 @@ public abstract class AbstractMessageChannelBinder<C extends ConsumerProperties,
@Override
protected void handleMessageInternal(Message<?> message) throws Exception {
Message<?> messageToSend = (this.useNativeEncoding) ?
message : serializeAndEmbedHeadersIfApplicable(message);
Message<?> messageToSend = (this.useNativeEncoding) ? message
: serializeAndEmbedHeadersIfApplicable(message);
this.delegate.handleMessage(messageToSend);
}
@@ -348,7 +357,8 @@ public abstract class AbstractMessageChannelBinder<C extends ConsumerProperties,
byte[] payload;
if (this.embedHeaders) {
Object contentType = transformed.get(MessageHeaders.CONTENT_TYPE);
// transform content type headers to String, so that they can be properly embedded in JSON
// transform content type headers to String, so that they can be properly
// embedded in JSON
if (contentType instanceof MimeType) {
transformed.put(MessageHeaders.CONTENT_TYPE, contentType.toString());
}

View File

@@ -16,10 +16,8 @@
package org.springframework.cloud.stream.binder;
/**
* Exception thrown to indicate a binder error (most
* likely a configuration error).
* Exception thrown to indicate a binder error (most likely a configuration error).
*
* @author Gary Russell
* @author Marius Bogoevici

View File

@@ -19,7 +19,6 @@ package org.springframework.cloud.stream.binder;
import org.springframework.integration.IntegrationMessageHeaderAccessor;
import org.springframework.messaging.MessageHeaders;
/**
* Spring Integration message headers for Spring Cloud Stream.
* @author Gary Russell
@@ -27,34 +26,15 @@ import org.springframework.messaging.MessageHeaders;
*/
public final class BinderHeaders {
private static final String PREFIX = "scst_";
/**
* Indicates the original content type of a message that has been
* transformed in a native transport format.
* Indicates the original content type of a message that has been transformed in a
* native transport format.
*/
public static final String BINDER_ORIGINAL_CONTENT_TYPE = "originalContentType";
/**
* Indicates the target partition of an outbound message.
* Binders must observe this value when sending data on the transport.
* This header is internally set by the framework when partitioning is
* configured.
* It may be overridden by {@link BinderHeaders#PARTITION_OVERRIDE} if set
* by the user.
*/
public static final String PARTITION_HEADER = PREFIX + "partition";
/**
* Indicates the target partition of an outbound message.
* Overrides any partition selected by the binder.
* This header takes precedence over {@link BinderHeaders#PARTITION_HEADER}.
*/
public static final String PARTITION_OVERRIDE = PREFIX + "partitionOverride";
/**
* The headers that will be propagated, by default, by binder implementations
* that have no inherent header support (by embedding the headers in the payload).
* The headers that will be propagated, by default, by binder implementations that
* have no inherent header support (by embedding the headers in the payload).
*/
public static final String[] STANDARD_HEADERS = new String[] {
IntegrationMessageHeaderAccessor.CORRELATION_ID,
@@ -64,6 +44,23 @@ public final class BinderHeaders {
BINDER_ORIGINAL_CONTENT_TYPE
};
private static final String PREFIX = "scst_";
/**
* Indicates the target partition of an outbound message. Binders must observe this
* value when sending data on the transport. This header is internally set by the
* framework when partitioning is configured. It may be overridden by
* {@link BinderHeaders#PARTITION_OVERRIDE} if set by the user.
*/
public static final String PARTITION_HEADER = PREFIX + "partition";
/**
* Indicates the target partition of an outbound message. Overrides any partition
* selected by the binder. This header takes precedence over
* {@link BinderHeaders#PARTITION_HEADER}.
*/
public static final String PARTITION_OVERRIDE = PREFIX + "partitionOverride";
private BinderHeaders() {
}

Some files were not shown because too many files have changed in this diff Show More