Merge branch 'polish' of https://github.com/philwebb/spring-cloud-netflix into philwebb-polish
Conflicts: spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignClient.java spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignClientScan.java spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/RibbonRoutingFilter.java spring-cloud-netflix-turbine-amqp/src/test/java/org/springframework/cloud/netflix/turbine/amqp/AggregatorTest.java
This commit is contained in:
53
docs/pom.xml
53
docs/pom.xml
@@ -1,44 +1,43 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-netflix-docs</artifactId>
|
||||
<version>1.0.0.BUILD-SNAPSHOT</version>
|
||||
<parent>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-build</artifactId>
|
||||
<version>1.0.0.BUILD-SNAPSHOT</version>
|
||||
<relativePath/>
|
||||
<relativePath />
|
||||
</parent>
|
||||
<artifactId>spring-cloud-netflix-docs</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
<name>Spring Cloud Netflix Docs</name>
|
||||
<description>Spring Cloud Docs</description>
|
||||
<properties>
|
||||
<docs.main>spring-cloud-netflix</docs.main>
|
||||
<docs.main>spring-cloud-netflix</docs.main>
|
||||
<main.basedir>${basedir}/..</main.basedir>
|
||||
</properties>
|
||||
<profiles>
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>docs</id>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.asciidoctor</groupId>
|
||||
<artifactId>asciidoctor-maven-plugin</artifactId>
|
||||
<inherited>false</inherited>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-antrun-plugin</artifactId>
|
||||
<inherited>false</inherited>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>build-helper-maven-plugin</artifactId>
|
||||
<inherited>false</inherited>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.asciidoctor</groupId>
|
||||
<artifactId>asciidoctor-maven-plugin</artifactId>
|
||||
<inherited>false</inherited>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-antrun-plugin</artifactId>
|
||||
<inherited>false</inherited>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>build-helper-maven-plugin</artifactId>
|
||||
<inherited>false</inherited>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
</profiles>
|
||||
</profiles>
|
||||
</project>
|
||||
|
||||
295
eclipse/eclipse-code-formatter.xml
Normal file
295
eclipse/eclipse-code-formatter.xml
Normal file
@@ -0,0 +1,295 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<profiles version="12">
|
||||
<profile kind="CodeFormatterProfile" name="Spring Cloud 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="8"/>
|
||||
<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="0"/>
|
||||
<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="false"/>
|
||||
<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="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="true"/>
|
||||
<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="0"/>
|
||||
<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="90"/>
|
||||
<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>
|
||||
389
eclipse/org.eclipse.jdt.core.prefs
Normal file
389
eclipse/org.eclipse.jdt.core.prefs
Normal file
@@ -0,0 +1,389 @@
|
||||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.core.codeComplete.argumentPrefixes=
|
||||
org.eclipse.jdt.core.codeComplete.argumentSuffixes=
|
||||
org.eclipse.jdt.core.codeComplete.fieldPrefixes=
|
||||
org.eclipse.jdt.core.codeComplete.fieldSuffixes=
|
||||
org.eclipse.jdt.core.codeComplete.localPrefixes=
|
||||
org.eclipse.jdt.core.codeComplete.localSuffixes=
|
||||
org.eclipse.jdt.core.codeComplete.staticFieldPrefixes=
|
||||
org.eclipse.jdt.core.codeComplete.staticFieldSuffixes=
|
||||
org.eclipse.jdt.core.codeComplete.staticFinalFieldPrefixes=
|
||||
org.eclipse.jdt.core.codeComplete.staticFinalFieldSuffixes=
|
||||
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
|
||||
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
|
||||
org.eclipse.jdt.core.compiler.compliance=1.6
|
||||
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
|
||||
org.eclipse.jdt.core.compiler.debug.localVariable=generate
|
||||
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
|
||||
org.eclipse.jdt.core.compiler.doc.comment.support=enabled
|
||||
org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
|
||||
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning
|
||||
org.eclipse.jdt.core.compiler.problem.deadCode=warning
|
||||
org.eclipse.jdt.core.compiler.problem.deprecation=warning
|
||||
org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
|
||||
org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.fatalOptionalError=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning
|
||||
org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
|
||||
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
|
||||
org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning
|
||||
org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
|
||||
org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.invalidJavadoc=warning
|
||||
org.eclipse.jdt.core.compiler.problem.invalidJavadocTags=enabled
|
||||
org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsDeprecatedRef=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsNotVisibleRef=enabled
|
||||
org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsVisibility=default
|
||||
org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning
|
||||
org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.missingJavadocComments=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsOverriding=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsVisibility=public
|
||||
org.eclipse.jdt.core.compiler.problem.missingJavadocTagDescription=return_tag
|
||||
org.eclipse.jdt.core.compiler.problem.missingJavadocTags=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.missingJavadocTagsMethodTypeParameters=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.missingJavadocTagsVisibility=private
|
||||
org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled
|
||||
org.eclipse.jdt.core.compiler.problem.missingSerialVersion=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning
|
||||
org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
|
||||
org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.nullReference=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
|
||||
org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning
|
||||
org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
|
||||
org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
|
||||
org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
|
||||
org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=enabled
|
||||
org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
|
||||
org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
|
||||
org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=warning
|
||||
org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled
|
||||
org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled
|
||||
org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.unusedImport=warning
|
||||
org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
|
||||
org.eclipse.jdt.core.compiler.problem.unusedLocal=warning
|
||||
org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled
|
||||
org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning
|
||||
org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
|
||||
org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
|
||||
org.eclipse.jdt.core.compiler.source=1.6
|
||||
org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
|
||||
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0
|
||||
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_assignment=0
|
||||
org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_compact_if=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80
|
||||
org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0
|
||||
org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0
|
||||
org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=80
|
||||
org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch=16
|
||||
org.eclipse.jdt.core.formatter.blank_lines_after_imports=1
|
||||
org.eclipse.jdt.core.formatter.blank_lines_after_package=1
|
||||
org.eclipse.jdt.core.formatter.blank_lines_before_field=0
|
||||
org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0
|
||||
org.eclipse.jdt.core.formatter.blank_lines_before_imports=1
|
||||
org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1
|
||||
org.eclipse.jdt.core.formatter.blank_lines_before_method=1
|
||||
org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1
|
||||
org.eclipse.jdt.core.formatter.blank_lines_before_package=0
|
||||
org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1
|
||||
org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_lambda_body=end_of_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line
|
||||
org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false
|
||||
org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false
|
||||
org.eclipse.jdt.core.formatter.comment.format_block_comments=true
|
||||
org.eclipse.jdt.core.formatter.comment.format_header=false
|
||||
org.eclipse.jdt.core.formatter.comment.format_html=true
|
||||
org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true
|
||||
org.eclipse.jdt.core.formatter.comment.format_line_comments=true
|
||||
org.eclipse.jdt.core.formatter.comment.format_source_code=false
|
||||
org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true
|
||||
org.eclipse.jdt.core.formatter.comment.indent_root_tags=false
|
||||
org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=do not insert
|
||||
org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=do not insert
|
||||
org.eclipse.jdt.core.formatter.comment.line_length=90
|
||||
org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries=true
|
||||
org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries=true
|
||||
org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments=false
|
||||
org.eclipse.jdt.core.formatter.compact_else_if=true
|
||||
org.eclipse.jdt.core.formatter.continuation_indentation=2
|
||||
org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2
|
||||
org.eclipse.jdt.core.formatter.disabling_tag=@formatter\:off
|
||||
org.eclipse.jdt.core.formatter.enabling_tag=@formatter\:on
|
||||
org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false
|
||||
org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column=true
|
||||
org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true
|
||||
org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true
|
||||
org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true
|
||||
org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true
|
||||
org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true
|
||||
org.eclipse.jdt.core.formatter.indent_empty_lines=false
|
||||
org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true
|
||||
org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true
|
||||
org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true
|
||||
org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false
|
||||
org.eclipse.jdt.core.formatter.indentation.size=8
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_after_label=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_after_type_annotation=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_lambda_arrow=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_lambda_arrow=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert
|
||||
org.eclipse.jdt.core.formatter.join_lines_in_comments=true
|
||||
org.eclipse.jdt.core.formatter.join_wrapped_lines=true
|
||||
org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false
|
||||
org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false
|
||||
org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false
|
||||
org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false
|
||||
org.eclipse.jdt.core.formatter.lineSplit=90
|
||||
org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false
|
||||
org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false
|
||||
org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0
|
||||
org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1
|
||||
org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true
|
||||
org.eclipse.jdt.core.formatter.tabulation.char=tab
|
||||
org.eclipse.jdt.core.formatter.tabulation.size=4
|
||||
org.eclipse.jdt.core.formatter.use_on_off_tags=false
|
||||
org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false
|
||||
org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true
|
||||
org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=true
|
||||
org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true
|
||||
125
eclipse/org.eclipse.jdt.ui.prefs
Normal file
125
eclipse/org.eclipse.jdt.ui.prefs
Normal file
File diff suppressed because one or more lines are too long
576
pom.xml
576
pom.xml
@@ -1,295 +1,299 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-netflix</artifactId>
|
||||
<version>1.0.0.BUILD-SNAPSHOT</version>
|
||||
<packaging>pom</packaging>
|
||||
<name>Spring Cloud Netflix</name>
|
||||
<description>Spring Cloud Netflix</description>
|
||||
|
||||
<parent>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-build</artifactId>
|
||||
<version>1.0.0.BUILD-SNAPSHOT</version>
|
||||
<relativePath/>
|
||||
<!-- lookup parent from repository -->
|
||||
</parent>
|
||||
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-build</artifactId>
|
||||
<version>1.0.0.BUILD-SNAPSHOT</version>
|
||||
<relativePath />
|
||||
</parent>
|
||||
<artifactId>spring-cloud-netflix</artifactId>
|
||||
<version>1.0.0.BUILD-SNAPSHOT</version>
|
||||
<packaging>pom</packaging>
|
||||
<name>Spring Cloud Netflix</name>
|
||||
<description>Spring Cloud Netflix</description>
|
||||
<scm>
|
||||
<url>https://github.com/spring-cloud/spring-cloud-netflix</url>
|
||||
<connection>scm:git:git://github.com/spring-cloud/spring-cloud-netflix.git</connection>
|
||||
<developerConnection>scm:git:ssh://git@github.com/spring-cloud/spring-cloud-netflix.git</developerConnection>
|
||||
<tag>HEAD</tag>
|
||||
</scm>
|
||||
|
||||
<modules>
|
||||
<module>spring-cloud-netflix-core</module>
|
||||
<module>spring-cloud-netflix-hystrix-dashboard</module>
|
||||
<module>spring-cloud-netflix-hystrix-amqp</module>
|
||||
<module>spring-cloud-netflix-eureka-server</module>
|
||||
<module>spring-cloud-netflix-turbine</module>
|
||||
<module>spring-cloud-netflix-turbine-amqp</module>
|
||||
<module>spring-cloud-netflix-sidecar</module>
|
||||
<module>docs</module>
|
||||
</modules>
|
||||
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-commons</artifactId>
|
||||
<version>1.0.0.BUILD-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-config-client</artifactId>
|
||||
<version>1.0.0.BUILD-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-config-server</artifactId>
|
||||
<version>1.0.0.BUILD-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-netflix-core</artifactId>
|
||||
<version>1.0.0.BUILD-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-netflix-eureka-server</artifactId>
|
||||
<version>1.0.0.BUILD-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-netflix-hystrix-dashboard</artifactId>
|
||||
<version>1.0.0.BUILD-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-netflix-hystrix-amqp</artifactId>
|
||||
<version>1.0.0.BUILD-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-netflix-turbine</artifactId>
|
||||
<version>1.0.0.BUILD-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-netflix-turbine-amqp</artifactId>
|
||||
<version>1.0.0.BUILD-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-netflix-zuul-server</artifactId>
|
||||
<version>1.0.0.BUILD-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.archaius</groupId>
|
||||
<artifactId>archaius-core</artifactId>
|
||||
<version>${archaius.version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>commons-logging</artifactId>
|
||||
<groupId>commons-logging</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.eureka</groupId>
|
||||
<artifactId>eureka-client</artifactId>
|
||||
<version>${eureka.version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>servlet-api</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.eureka</groupId>
|
||||
<artifactId>eureka-core</artifactId>
|
||||
<version>${eureka.version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>servlet-api</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<artifactId>commons-logging</artifactId>
|
||||
<groupId>commons-logging</groupId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<artifactId>log4j</artifactId>
|
||||
<groupId>log4j</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.feign</groupId>
|
||||
<artifactId>feign-core</artifactId>
|
||||
<version>${feign.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.feign</groupId>
|
||||
<artifactId>feign-ribbon</artifactId>
|
||||
<version>${feign.version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>com.netflix.ribbon</groupId>
|
||||
<artifactId>ribbon-loadbalancer</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<!--<dependency>
|
||||
<groupId>com.netflix.feign</groupId>
|
||||
<artifactId>feign-slf4j</artifactId>
|
||||
<version>${feign.version}</version>
|
||||
</dependency>-->
|
||||
<dependency>
|
||||
<groupId>com.netflix.hystrix</groupId>
|
||||
<artifactId>hystrix-core</artifactId>
|
||||
<version>${hystrix.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.hystrix</groupId>
|
||||
<artifactId>hystrix-metrics-event-stream</artifactId>
|
||||
<version>${hystrix.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.hystrix</groupId>
|
||||
<artifactId>hystrix-javanica</artifactId>
|
||||
<version>${hystrix.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.ribbon</groupId>
|
||||
<artifactId>ribbon</artifactId>
|
||||
<version>${ribbon.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.ribbon</groupId>
|
||||
<artifactId>ribbon-core</artifactId>
|
||||
<version>${ribbon.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.ribbon</groupId>
|
||||
<artifactId>ribbon-httpclient</artifactId>
|
||||
<version>${ribbon.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.ribbon</groupId>
|
||||
<artifactId>ribbon-eureka</artifactId>
|
||||
<version>${ribbon.version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>servlet-api</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.rxjava</groupId>
|
||||
<artifactId>rxjava-core</artifactId>
|
||||
<version>${netflix.rxjava.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.zuul</groupId>
|
||||
<artifactId>zuul-core</artifactId>
|
||||
<version>${zuul.version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>groovy-all</artifactId>
|
||||
<groupId>org.codehaus.groovy</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.integration</groupId>
|
||||
<artifactId>spring-integration-java-dsl</artifactId>
|
||||
<version>${spring-integration-dsl.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>1.12.6</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
<version>18.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.sun.jersey</groupId>
|
||||
<artifactId>jersey-servlet</artifactId>
|
||||
<version>1.13</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.sun.jersey</groupId>
|
||||
<artifactId>jersey-core</artifactId>
|
||||
<version>1.13</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.sun.jersey</groupId>
|
||||
<artifactId>jersey-client</artifactId>
|
||||
<version>1.13</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.sun.jersey</groupId>
|
||||
<artifactId>jersey-server</artifactId>
|
||||
<version>1.13</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.webjars</groupId>
|
||||
<artifactId>d3js</artifactId>
|
||||
<version>3.4.11</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.webjars</groupId>
|
||||
<artifactId>jquery</artifactId>
|
||||
<version>2.1.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.webjars</groupId>
|
||||
<artifactId>bootstrap</artifactId>
|
||||
<version>3.2.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.inject</groupId>
|
||||
<artifactId>javax.inject</artifactId>
|
||||
<version>1</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
<properties>
|
||||
<archaius.version>0.6.3</archaius.version>
|
||||
<eureka.version>1.1.145</eureka.version>
|
||||
<feign.version>6.1.3</feign.version>
|
||||
<hystrix.version>1.4.0-RC5</hystrix.version>
|
||||
<ribbon.version>2.0-RC13</ribbon.version>
|
||||
<zuul.version>1.0.28</zuul.version>
|
||||
<netflix.rxjava.version>0.20.7</netflix.rxjava.version>
|
||||
<java.version>1.7</java.version>
|
||||
<spring-integration-dsl.version>1.0.0.RELEASE</spring-integration-dsl.version>
|
||||
<cloud-connectors.version>1.1.1.BUILD-SNAPSHOT</cloud-connectors.version>
|
||||
</properties>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.1</version>
|
||||
<configuration>
|
||||
<source>1.7</source>
|
||||
<target>1.7</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<properties>
|
||||
<main.basedir>${basedir}</main.basedir>
|
||||
<archaius.version>0.6.3</archaius.version>
|
||||
<eureka.version>1.1.145</eureka.version>
|
||||
<feign.version>6.1.3</feign.version>
|
||||
<hystrix.version>1.4.0-RC5</hystrix.version>
|
||||
<ribbon.version>2.0-RC13</ribbon.version>
|
||||
<zuul.version>1.0.28</zuul.version>
|
||||
<netflix.rxjava.version>0.20.7</netflix.rxjava.version>
|
||||
<java.version>1.7</java.version>
|
||||
<spring-integration-dsl.version>1.0.0.RELEASE</spring-integration-dsl.version>
|
||||
<cloud-connectors.version>1.1.1.BUILD-SNAPSHOT</cloud-connectors.version>
|
||||
</properties>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-eclipse-plugin</artifactId>
|
||||
<configuration>
|
||||
<useProjectReferences>false</useProjectReferences>
|
||||
<additionalConfig>
|
||||
<file>
|
||||
<name>.settings/org.eclipse.jdt.ui.prefs</name>
|
||||
<location>${main.basedir}/eclipse/org.eclipse.jdt.ui.prefs</location>
|
||||
</file>
|
||||
<file>
|
||||
<name>.settings/org.eclipse.jdt.core.prefs</name>
|
||||
<location>${main.basedir}/eclipse/org.eclipse.jdt.core.prefs</location>
|
||||
</file>
|
||||
</additionalConfig>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<source>1.7</source>
|
||||
<target>1.7</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-commons</artifactId>
|
||||
<version>1.0.0.BUILD-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-config-client</artifactId>
|
||||
<version>1.0.0.BUILD-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-config-server</artifactId>
|
||||
<version>1.0.0.BUILD-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-netflix-core</artifactId>
|
||||
<version>1.0.0.BUILD-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-netflix-eureka-server</artifactId>
|
||||
<version>1.0.0.BUILD-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-netflix-hystrix-dashboard</artifactId>
|
||||
<version>1.0.0.BUILD-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-netflix-hystrix-amqp</artifactId>
|
||||
<version>1.0.0.BUILD-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-netflix-turbine</artifactId>
|
||||
<version>1.0.0.BUILD-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-netflix-turbine-amqp</artifactId>
|
||||
<version>1.0.0.BUILD-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-netflix-zuul-server</artifactId>
|
||||
<version>1.0.0.BUILD-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.archaius</groupId>
|
||||
<artifactId>archaius-core</artifactId>
|
||||
<version>${archaius.version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>commons-logging</artifactId>
|
||||
<groupId>commons-logging</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.eureka</groupId>
|
||||
<artifactId>eureka-client</artifactId>
|
||||
<version>${eureka.version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>servlet-api</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.eureka</groupId>
|
||||
<artifactId>eureka-core</artifactId>
|
||||
<version>${eureka.version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>servlet-api</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<artifactId>commons-logging</artifactId>
|
||||
<groupId>commons-logging</groupId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<artifactId>log4j</artifactId>
|
||||
<groupId>log4j</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.feign</groupId>
|
||||
<artifactId>feign-core</artifactId>
|
||||
<version>${feign.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.feign</groupId>
|
||||
<artifactId>feign-ribbon</artifactId>
|
||||
<version>${feign.version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>com.netflix.ribbon</groupId>
|
||||
<artifactId>ribbon-loadbalancer</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<!--<dependency> <groupId>com.netflix.feign</groupId> <artifactId>feign-slf4j</artifactId>
|
||||
<version>${feign.version}</version> </dependency> -->
|
||||
<dependency>
|
||||
<groupId>com.netflix.hystrix</groupId>
|
||||
<artifactId>hystrix-core</artifactId>
|
||||
<version>${hystrix.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.hystrix</groupId>
|
||||
<artifactId>hystrix-metrics-event-stream</artifactId>
|
||||
<version>${hystrix.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.hystrix</groupId>
|
||||
<artifactId>hystrix-javanica</artifactId>
|
||||
<version>${hystrix.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.ribbon</groupId>
|
||||
<artifactId>ribbon</artifactId>
|
||||
<version>${ribbon.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.ribbon</groupId>
|
||||
<artifactId>ribbon-core</artifactId>
|
||||
<version>${ribbon.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.ribbon</groupId>
|
||||
<artifactId>ribbon-httpclient</artifactId>
|
||||
<version>${ribbon.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.ribbon</groupId>
|
||||
<artifactId>ribbon-eureka</artifactId>
|
||||
<version>${ribbon.version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>servlet-api</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.rxjava</groupId>
|
||||
<artifactId>rxjava-core</artifactId>
|
||||
<version>${netflix.rxjava.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.zuul</groupId>
|
||||
<artifactId>zuul-core</artifactId>
|
||||
<version>${zuul.version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>groovy-all</artifactId>
|
||||
<groupId>org.codehaus.groovy</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.integration</groupId>
|
||||
<artifactId>spring-integration-java-dsl</artifactId>
|
||||
<version>${spring-integration-dsl.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>1.12.6</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
<version>18.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.sun.jersey</groupId>
|
||||
<artifactId>jersey-servlet</artifactId>
|
||||
<version>1.13</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.sun.jersey</groupId>
|
||||
<artifactId>jersey-core</artifactId>
|
||||
<version>1.13</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.sun.jersey</groupId>
|
||||
<artifactId>jersey-client</artifactId>
|
||||
<version>1.13</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.sun.jersey</groupId>
|
||||
<artifactId>jersey-server</artifactId>
|
||||
<version>1.13</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.webjars</groupId>
|
||||
<artifactId>d3js</artifactId>
|
||||
<version>3.4.11</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.webjars</groupId>
|
||||
<artifactId>jquery</artifactId>
|
||||
<version>2.1.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.webjars</groupId>
|
||||
<artifactId>bootstrap</artifactId>
|
||||
<version>3.2.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.inject</groupId>
|
||||
<artifactId>javax.inject</artifactId>
|
||||
<version>1</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
<modules>
|
||||
<module>spring-cloud-netflix-core</module>
|
||||
<module>spring-cloud-netflix-hystrix-dashboard</module>
|
||||
<module>spring-cloud-netflix-hystrix-amqp</module>
|
||||
<module>spring-cloud-netflix-eureka-server</module>
|
||||
<module>spring-cloud-netflix-turbine</module>
|
||||
<module>spring-cloud-netflix-turbine-amqp</module>
|
||||
<module>spring-cloud-netflix-sidecar</module>
|
||||
<module>docs</module>
|
||||
</modules>
|
||||
</project>
|
||||
|
||||
@@ -2,19 +2,19 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>spring-cloud-netflix-core</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<name>Spring Cloud Netflix Core</name>
|
||||
<description>Spring Cloud Netflix Core</description>
|
||||
|
||||
<parent>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-netflix</artifactId>
|
||||
<version>1.0.0.BUILD-SNAPSHOT</version>
|
||||
<relativePath>..</relativePath>
|
||||
</parent>
|
||||
|
||||
<artifactId>spring-cloud-netflix-core</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<name>Spring Cloud Netflix Core</name>
|
||||
<description>Spring Cloud Netflix Core</description>
|
||||
<properties>
|
||||
<main.basedir>${basedir}/..</main.basedir>
|
||||
</properties>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
@@ -24,11 +24,11 @@
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-autoconfigure</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-commons</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-commons</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-config-client</artifactId>
|
||||
@@ -68,10 +68,8 @@
|
||||
<dependency>
|
||||
<groupId>com.netflix.feign</groupId>
|
||||
<artifactId>feign-ribbon</artifactId>
|
||||
<optional>true</optional>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<!--<dependency> <groupId>com.netflix.feign</groupId> <artifactId>feign-slf4j</artifactId>
|
||||
</dependency> -->
|
||||
<dependency>
|
||||
<groupId>com.netflix.hystrix</groupId>
|
||||
<artifactId>hystrix-core</artifactId>
|
||||
@@ -87,11 +85,11 @@
|
||||
<artifactId>hystrix-javanica</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.ribbon</groupId>
|
||||
<artifactId>ribbon</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.ribbon</groupId>
|
||||
<artifactId>ribbon</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.ribbon</groupId>
|
||||
<artifactId>ribbon-core</artifactId>
|
||||
@@ -102,27 +100,27 @@
|
||||
<artifactId>ribbon-eureka</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.ribbon</groupId>
|
||||
<artifactId>ribbon-httpclient</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.zuul</groupId>
|
||||
<artifactId>zuul-core</artifactId>
|
||||
<optional>true</optional>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>groovy-all</artifactId>
|
||||
<groupId>org.codehaus.groovy</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.rxjava</groupId>
|
||||
<artifactId>rxjava-core</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.ribbon</groupId>
|
||||
<artifactId>ribbon-httpclient</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.zuul</groupId>
|
||||
<artifactId>zuul-core</artifactId>
|
||||
<optional>true</optional>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>groovy-all</artifactId>
|
||||
<groupId>org.codehaus.groovy</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.rxjava</groupId>
|
||||
<artifactId>rxjava-core</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
@@ -139,11 +137,9 @@
|
||||
<groupId>javax.inject</groupId>
|
||||
<artifactId>javax.inject</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
|
||||
@@ -1,8 +1,26 @@
|
||||
/*
|
||||
* Copyright 2013-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
public interface Constants {
|
||||
|
||||
String HYSTRIX_STREAM_NAME = "spring.cloud.hystrix.stream";
|
||||
|
||||
}
|
||||
|
||||
@@ -1,12 +1,20 @@
|
||||
package org.springframework.cloud.netflix.archaius;
|
||||
/*
|
||||
* Copyright 2013-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import static com.netflix.config.ConfigurationBasedDeploymentContext.DEPLOYMENT_APPLICATION_ID_PROPERTY;
|
||||
import static com.netflix.config.ConfigurationManager.APPLICATION_PROPERTIES;
|
||||
import static com.netflix.config.ConfigurationManager.DISABLE_DEFAULT_ENV_CONFIG;
|
||||
import static com.netflix.config.ConfigurationManager.DISABLE_DEFAULT_SYS_CONFIG;
|
||||
import static com.netflix.config.ConfigurationManager.ENV_CONFIG_NAME;
|
||||
import static com.netflix.config.ConfigurationManager.SYS_CONFIG_NAME;
|
||||
import static com.netflix.config.ConfigurationManager.URL_CONFIG_NAME;
|
||||
package org.springframework.cloud.netflix.archaius;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
@@ -31,6 +39,14 @@ import com.netflix.config.ConfigurationManager;
|
||||
import com.netflix.config.DynamicPropertyFactory;
|
||||
import com.netflix.config.DynamicURLConfiguration;
|
||||
|
||||
import static com.netflix.config.ConfigurationBasedDeploymentContext.DEPLOYMENT_APPLICATION_ID_PROPERTY;
|
||||
import static com.netflix.config.ConfigurationManager.APPLICATION_PROPERTIES;
|
||||
import static com.netflix.config.ConfigurationManager.DISABLE_DEFAULT_ENV_CONFIG;
|
||||
import static com.netflix.config.ConfigurationManager.DISABLE_DEFAULT_SYS_CONFIG;
|
||||
import static com.netflix.config.ConfigurationManager.ENV_CONFIG_NAME;
|
||||
import static com.netflix.config.ConfigurationManager.SYS_CONFIG_NAME;
|
||||
import static com.netflix.config.ConfigurationManager.URL_CONFIG_NAME;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
@@ -40,6 +56,7 @@ public class ArchaiusAutoConfiguration {
|
||||
|
||||
private static final Logger logger = LoggerFactory
|
||||
.getLogger(ArchaiusAutoConfiguration.class);
|
||||
|
||||
private static final AtomicBoolean initialized = new AtomicBoolean(false);
|
||||
|
||||
@Autowired
|
||||
@@ -57,7 +74,7 @@ public class ArchaiusAutoConfiguration {
|
||||
@Bean
|
||||
public ConfigurableEnvironmentConfiguration configurableEnvironmentConfiguration() {
|
||||
ConfigurableEnvironmentConfiguration envConfig = new ConfigurableEnvironmentConfiguration(
|
||||
env);
|
||||
this.env);
|
||||
configureArchaius(envConfig);
|
||||
return envConfig;
|
||||
}
|
||||
@@ -74,7 +91,7 @@ public class ArchaiusAutoConfiguration {
|
||||
@SuppressWarnings("deprecation")
|
||||
protected void configureArchaius(ConfigurableEnvironmentConfiguration envConfig) {
|
||||
if (initialized.compareAndSet(false, true)) {
|
||||
String appName = env.getProperty("spring.application.name");
|
||||
String appName = this.env.getProperty("spring.application.name");
|
||||
if (appName == null) {
|
||||
appName = "application";
|
||||
logger.warn("No spring.application.name found, defaulting to 'application'");
|
||||
@@ -101,8 +118,8 @@ public class ArchaiusAutoConfiguration {
|
||||
try {
|
||||
config.addConfiguration(defaultURLConfig, URL_CONFIG_NAME);
|
||||
}
|
||||
catch (Throwable e) {
|
||||
logger.error("Cannot create config from " + defaultURLConfig, e);
|
||||
catch (Throwable ex) {
|
||||
logger.error("Cannot create config from " + defaultURLConfig, ex);
|
||||
}
|
||||
|
||||
// TODO: sys/env above urls?
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.archaius;
|
||||
|
||||
import org.apache.commons.configuration.AbstractConfiguration;
|
||||
@@ -23,15 +24,16 @@ import com.netflix.config.ConfigurationManager;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
public class ArchaiusDelegatingProxyUtils {
|
||||
|
||||
|
||||
public static String APPLICATION_CONTEXT = ApplicationContext.class.getName();
|
||||
|
||||
public static <T> T getNamedInstance(Class<T> type, String name) {
|
||||
ApplicationContext context = (ApplicationContext) ConfigurationManager.getConfigInstance().getProperty(APPLICATION_CONTEXT);
|
||||
return context!=null && context.containsBean(name) ? context.getBean(name, type) : null;
|
||||
ApplicationContext context = (ApplicationContext) ConfigurationManager
|
||||
.getConfigInstance().getProperty(APPLICATION_CONTEXT);
|
||||
return context != null && context.containsBean(name) ? context
|
||||
.getBean(name, type) : null;
|
||||
}
|
||||
|
||||
public static <T> T getInstanceWithPrefix(Class<T> type, String prefix) {
|
||||
@@ -41,7 +43,7 @@ public class ArchaiusDelegatingProxyUtils {
|
||||
|
||||
public static void addApplicationContext(ConfigurableApplicationContext context) {
|
||||
AbstractConfiguration config = ConfigurationManager.getConfigInstance();
|
||||
config .clearProperty(APPLICATION_CONTEXT);
|
||||
config.clearProperty(APPLICATION_CONTEXT);
|
||||
config.setProperty(APPLICATION_CONTEXT, context);
|
||||
}
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.archaius;
|
||||
|
||||
import java.util.Iterator;
|
||||
@@ -30,7 +31,6 @@ import com.netflix.config.ConfigurationManager;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
public class ArchaiusEndpoint extends AbstractEndpoint<Map<String, Object>> {
|
||||
|
||||
|
||||
@@ -1,3 +1,19 @@
|
||||
/*
|
||||
* Copyright 2013-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.archaius;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -18,73 +34,69 @@ import org.springframework.core.env.StandardEnvironment;
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
public class ConfigurableEnvironmentConfiguration extends AbstractConfiguration {
|
||||
ConfigurableEnvironment environment;
|
||||
|
||||
public ConfigurableEnvironmentConfiguration(ConfigurableEnvironment environment) {
|
||||
this.environment = environment;
|
||||
}
|
||||
private final ConfigurableEnvironment environment;
|
||||
|
||||
@Override
|
||||
protected void addPropertyDirect(String key, Object value) {
|
||||
public ConfigurableEnvironmentConfiguration(ConfigurableEnvironment environment) {
|
||||
this.environment = environment;
|
||||
}
|
||||
|
||||
}
|
||||
@Override
|
||||
protected void addPropertyDirect(String key, Object value) {
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return !getKeys().hasNext(); //TODO: find a better way to do this
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean containsKey(String key) {
|
||||
return environment.containsProperty(key);
|
||||
}
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return !getKeys().hasNext(); // TODO: find a better way to do this
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getProperty(String key) {
|
||||
return environment.getProperty(key);
|
||||
}
|
||||
@Override
|
||||
public boolean containsKey(String key) {
|
||||
return this.environment.containsProperty(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<String> getKeys() {
|
||||
List<String> result = new ArrayList<>();
|
||||
for (Map.Entry<String, PropertySource<?>> entry : getPropertySources().entrySet()) {
|
||||
PropertySource<?> source = entry.getValue();
|
||||
if (source instanceof EnumerablePropertySource) {
|
||||
EnumerablePropertySource<?> enumerable = (EnumerablePropertySource<?>) source;
|
||||
for (String name : enumerable.getPropertyNames()) {
|
||||
result.add(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result.iterator();
|
||||
}
|
||||
@Override
|
||||
public Object getProperty(String key) {
|
||||
return this.environment.getProperty(key);
|
||||
}
|
||||
|
||||
private Map<String, PropertySource<?>> getPropertySources() {
|
||||
Map<String, PropertySource<?>> map = new LinkedHashMap<>();
|
||||
MutablePropertySources sources;
|
||||
if (this.environment != null
|
||||
&& this.environment instanceof ConfigurableEnvironment) {
|
||||
sources = this.environment.getPropertySources();
|
||||
}
|
||||
else {
|
||||
sources = new StandardEnvironment().getPropertySources();
|
||||
}
|
||||
for (PropertySource<?> source : sources) {
|
||||
extract("", map, source);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
@Override
|
||||
public Iterator<String> getKeys() {
|
||||
List<String> result = new ArrayList<>();
|
||||
for (Map.Entry<String, PropertySource<?>> entry : getPropertySources().entrySet()) {
|
||||
PropertySource<?> source = entry.getValue();
|
||||
if (source instanceof EnumerablePropertySource) {
|
||||
EnumerablePropertySource<?> enumerable = (EnumerablePropertySource<?>) source;
|
||||
for (String name : enumerable.getPropertyNames()) {
|
||||
result.add(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result.iterator();
|
||||
}
|
||||
|
||||
private void extract(String root, Map<String, PropertySource<?>> map,
|
||||
PropertySource<?> source) {
|
||||
if (source instanceof CompositePropertySource) {
|
||||
for (PropertySource<?> nest : ((CompositePropertySource) source).getPropertySources()) {
|
||||
extract(source.getName() + ":", map, nest);
|
||||
}
|
||||
}
|
||||
else {
|
||||
map.put(root + source.getName(), source);
|
||||
}
|
||||
}
|
||||
private Map<String, PropertySource<?>> getPropertySources() {
|
||||
Map<String, PropertySource<?>> map = new LinkedHashMap<>();
|
||||
MutablePropertySources sources = (this.environment != null ? this.environment
|
||||
.getPropertySources() : new StandardEnvironment().getPropertySources());
|
||||
for (PropertySource<?> source : sources) {
|
||||
extract("", map, source);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
private void extract(String root, Map<String, PropertySource<?>> map,
|
||||
PropertySource<?> source) {
|
||||
if (source instanceof CompositePropertySource) {
|
||||
for (PropertySource<?> nest : ((CompositePropertySource) source)
|
||||
.getPropertySources()) {
|
||||
extract(source.getName() + ":", map, nest);
|
||||
}
|
||||
}
|
||||
else {
|
||||
map.put(root + source.getName(), source);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.config;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@@ -37,9 +38,8 @@ import com.netflix.discovery.DiscoveryClient;
|
||||
/**
|
||||
* Bootstrap configuration for a config client that wants to lookup the config server via
|
||||
* discovery.
|
||||
*
|
||||
* @author Dave Syer
|
||||
*
|
||||
* @author Dave Syer
|
||||
*/
|
||||
@ConditionalOnClass({ DiscoveryClient.class, ConfigServicePropertySourceLocator.class })
|
||||
@ConditionalOnExpression("${spring.cloud.config.discovery.enabled:false}")
|
||||
@@ -65,27 +65,27 @@ public class DiscoveryClientConfigServiceBootstrapConfiguration implements
|
||||
log.info("Environment is not ConfigurableEnvironment so cannot look up configserver");
|
||||
return;
|
||||
}
|
||||
InstanceInfo server = client.getNextServerFromEureka(config.getDiscovery()
|
||||
.getServiceId(), false);
|
||||
InstanceInfo server = this.client.getNextServerFromEureka(this.config
|
||||
.getDiscovery().getServiceId(), false);
|
||||
String url = server.getHomePageUrl();
|
||||
if (server.getMetadata().containsKey("password")) {
|
||||
String user = server.getMetadata().get("user");
|
||||
user = user == null ? "user" : user;
|
||||
config.setUsername(user);
|
||||
this.config.setUsername(user);
|
||||
String password = server.getMetadata().get("password");
|
||||
config.setPassword(password);
|
||||
this.config.setPassword(password);
|
||||
}
|
||||
if (server.getMetadata().containsKey("configPath")) {
|
||||
String path = server.getMetadata().get("configPath");
|
||||
if (url.endsWith("/") && path.startsWith("/")) {
|
||||
url = url.substring(0, url.length()-1);
|
||||
url = url.substring(0, url.length() - 1);
|
||||
}
|
||||
url = url + path;
|
||||
}
|
||||
config.setUri(url);
|
||||
this.config.setUri(url);
|
||||
}
|
||||
catch (Exception e) {
|
||||
log.warn("Could not locate configserver via discovery", e);
|
||||
catch (Exception ex) {
|
||||
log.warn("Could not locate configserver via discovery", ex);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.config;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
@@ -29,29 +30,30 @@ import com.netflix.discovery.DiscoveryClient;
|
||||
|
||||
/**
|
||||
* Extra configuration for config server if it happens to be a Eureka instance.
|
||||
* @author Dave Syer
|
||||
*
|
||||
* @author Dave Syer
|
||||
*/
|
||||
@Configuration
|
||||
@EnableConfigurationProperties
|
||||
@ConditionalOnClass({EurekaInstanceConfigBean.class, DiscoveryClient.class, ConfigServerProperties.class})
|
||||
@ConditionalOnClass({ EurekaInstanceConfigBean.class, DiscoveryClient.class,
|
||||
ConfigServerProperties.class })
|
||||
public class EurekaClientConfigServerAutoConfiguration {
|
||||
|
||||
@Autowired(required=false)
|
||||
@Autowired(required = false)
|
||||
private EurekaInstanceConfigBean instance;
|
||||
|
||||
@Autowired(required=false)
|
||||
@Autowired(required = false)
|
||||
private ConfigServerProperties server;
|
||||
|
||||
@PostConstruct
|
||||
public void init() {
|
||||
if (instance==null || server==null) {
|
||||
if (this.instance == null || this.server == null) {
|
||||
return;
|
||||
}
|
||||
String prefix = server.getPrefix();
|
||||
String prefix = this.server.getPrefix();
|
||||
if (StringUtils.hasText(prefix)) {
|
||||
instance.getMetadataMap().put("configPath", prefix);
|
||||
this.instance.getMetadataMap().put("configPath", prefix);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,25 @@
|
||||
/*
|
||||
* Copyright 2013-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.endpoint;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.boot.actuate.endpoint.Endpoint;
|
||||
@@ -11,66 +31,63 @@ import org.springframework.web.context.ServletContextAware;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
import org.springframework.web.servlet.mvc.ServletWrappingController;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
/**
|
||||
* TODO: move to spring-boot?
|
||||
* User: spencergibb
|
||||
* Date: 4/24/14
|
||||
* Time: 9:13 PM
|
||||
*/
|
||||
public abstract class ServletWrappingEndpoint implements InitializingBean,
|
||||
ApplicationContextAware, ServletContextAware, MvcEndpoint {
|
||||
ApplicationContextAware, ServletContextAware, MvcEndpoint {
|
||||
|
||||
protected String path;
|
||||
protected boolean sensitive;
|
||||
protected boolean enabled = true;
|
||||
// TODO: move to spring-boot?
|
||||
|
||||
protected final ServletWrappingController controller = new ServletWrappingController();
|
||||
protected String path;
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
this.controller.afterPropertiesSet();
|
||||
}
|
||||
protected boolean sensitive;
|
||||
|
||||
@Override
|
||||
public void setServletContext(ServletContext servletContext) {
|
||||
this.controller.setServletContext(servletContext);
|
||||
}
|
||||
protected boolean enabled = true;
|
||||
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
||||
this.controller.setApplicationContext(applicationContext);
|
||||
}
|
||||
protected final ServletWrappingController controller = new ServletWrappingController();
|
||||
|
||||
protected ServletWrappingEndpoint(Class<?> servletClass, String servletName, String path,
|
||||
boolean sensitive, boolean enabled) {
|
||||
controller.setServletClass(servletClass);
|
||||
controller.setServletName(servletName);
|
||||
this.path = path;
|
||||
this.sensitive = sensitive;
|
||||
this.enabled = enabled;
|
||||
}
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
this.controller.afterPropertiesSet();
|
||||
}
|
||||
|
||||
@RequestMapping("**")
|
||||
public ModelAndView handle(HttpServletRequest request, HttpServletResponse response) throws Exception {
|
||||
return this.controller.handleRequest(request, response);
|
||||
}
|
||||
@Override
|
||||
public void setServletContext(ServletContext servletContext) {
|
||||
this.controller.setServletContext(servletContext);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPath() {
|
||||
return path;
|
||||
}
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext applicationContext)
|
||||
throws BeansException {
|
||||
this.controller.setApplicationContext(applicationContext);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSensitive() {
|
||||
return sensitive;
|
||||
}
|
||||
protected ServletWrappingEndpoint(Class<?> servletClass, String servletName,
|
||||
String path, boolean sensitive, boolean enabled) {
|
||||
this.controller.setServletClass(servletClass);
|
||||
this.controller.setServletName(servletName);
|
||||
this.path = path;
|
||||
this.sensitive = sensitive;
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
@RequestMapping("**")
|
||||
public ModelAndView handle(HttpServletRequest request, HttpServletResponse response)
|
||||
throws Exception {
|
||||
return this.controller.handleRequest(request, response);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPath() {
|
||||
return this.path;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSensitive() {
|
||||
return this.sensitive;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends Endpoint<?>> getEndpointType() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends Endpoint<?>> getEndpointType() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,8 +13,17 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.eureka;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import org.aopalliance.intercept.MethodInterceptor;
|
||||
import org.aopalliance.intercept.MethodInvocation;
|
||||
import org.springframework.aop.framework.ProxyFactory;
|
||||
import org.springframework.cloud.client.discovery.DiscoveryHeartbeatEvent;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
|
||||
import com.netflix.appinfo.DataCenterInfo;
|
||||
import com.netflix.appinfo.DataCenterInfo.Name;
|
||||
import com.netflix.appinfo.InstanceInfo;
|
||||
@@ -23,17 +32,15 @@ import com.netflix.discovery.converters.Converters.ApplicationsConverter;
|
||||
import com.netflix.discovery.converters.Converters.InstanceInfoConverter;
|
||||
import com.netflix.discovery.shared.Applications;
|
||||
import com.thoughtworks.xstream.MarshallingStrategy;
|
||||
import com.thoughtworks.xstream.converters.*;
|
||||
import com.thoughtworks.xstream.converters.Converter;
|
||||
import com.thoughtworks.xstream.converters.ConverterLookup;
|
||||
import com.thoughtworks.xstream.converters.DataHolder;
|
||||
import com.thoughtworks.xstream.converters.MarshallingContext;
|
||||
import com.thoughtworks.xstream.converters.UnmarshallingContext;
|
||||
import com.thoughtworks.xstream.core.TreeMarshallingStrategy;
|
||||
import com.thoughtworks.xstream.io.HierarchicalStreamReader;
|
||||
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
|
||||
import com.thoughtworks.xstream.mapper.Mapper;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.aopalliance.intercept.MethodInterceptor;
|
||||
import org.aopalliance.intercept.MethodInvocation;
|
||||
import org.springframework.aop.framework.ProxyFactory;
|
||||
import org.springframework.cloud.client.discovery.DiscoveryHeartbeatEvent;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
|
||||
/**
|
||||
* A special purpose wrapper for an XStream TreeMarshallingStrategy that is aware of the
|
||||
@@ -44,13 +51,13 @@ import org.springframework.context.ApplicationContext;
|
||||
* is useful when not running Eureka in bare EC2 VMs, so the EC2 metadata is not available
|
||||
* for uniquely identifying the InstanceInfo (the default is to just use the hostname, but
|
||||
* that isn't very useful when sitting behind a proxy).
|
||||
*
|
||||
* @author Dave Syer
|
||||
*
|
||||
* @author Dave Syer
|
||||
*/
|
||||
public class DataCenterAwareMarshallingStrategy implements MarshallingStrategy {
|
||||
|
||||
private TreeMarshallingStrategy delegate = new TreeMarshallingStrategy();
|
||||
|
||||
private ApplicationContext context;
|
||||
|
||||
public DataCenterAwareMarshallingStrategy(ApplicationContext context) {
|
||||
@@ -60,15 +67,17 @@ public class DataCenterAwareMarshallingStrategy implements MarshallingStrategy {
|
||||
@Override
|
||||
public Object unmarshal(Object root, HierarchicalStreamReader reader,
|
||||
DataHolder dataHolder, ConverterLookup converterLookup, Mapper mapper) {
|
||||
ConverterLookup wrapped = new DataCenterAwareConverterLookup(converterLookup, context);
|
||||
return delegate.unmarshal(root, reader, dataHolder, wrapped, mapper);
|
||||
ConverterLookup wrapped = new DataCenterAwareConverterLookup(converterLookup,
|
||||
this.context);
|
||||
return this.delegate.unmarshal(root, reader, dataHolder, wrapped, mapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void marshal(HierarchicalStreamWriter writer, Object obj,
|
||||
ConverterLookup converterLookup, Mapper mapper, DataHolder dataHolder) {
|
||||
ConverterLookup wrapped = new DataCenterAwareConverterLookup(converterLookup, context);
|
||||
delegate.marshal(writer, obj, wrapped, mapper, dataHolder);
|
||||
ConverterLookup wrapped = new DataCenterAwareConverterLookup(converterLookup,
|
||||
this.context);
|
||||
this.delegate.marshal(writer, obj, wrapped, mapper, dataHolder);
|
||||
}
|
||||
|
||||
public static class InstanceIdDataCenterInfo implements DataCenterInfo,
|
||||
@@ -87,7 +96,7 @@ public class DataCenterAwareMarshallingStrategy implements MarshallingStrategy {
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return instanceId;
|
||||
return this.instanceId;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -95,20 +104,23 @@ public class DataCenterAwareMarshallingStrategy implements MarshallingStrategy {
|
||||
private static class DataCenterAwareConverterLookup implements ConverterLookup {
|
||||
|
||||
private ConverterLookup delegate;
|
||||
|
||||
private ApplicationContext context;
|
||||
|
||||
public DataCenterAwareConverterLookup(ConverterLookup delegate, ApplicationContext context) {
|
||||
public DataCenterAwareConverterLookup(ConverterLookup delegate,
|
||||
ApplicationContext context) {
|
||||
this.delegate = delegate;
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Converter lookupConverterForType(@SuppressWarnings("rawtypes") Class type) {
|
||||
Converter converter = delegate.lookupConverterForType(type);
|
||||
Converter converter = this.delegate.lookupConverterForType(type);
|
||||
if (InstanceInfo.class == type) {
|
||||
return new DataCenterAwareConverter();
|
||||
} else if (Applications.class == type) {
|
||||
return new PublishingApplicationsConverter(context);
|
||||
}
|
||||
else if (Applications.class == type) {
|
||||
return new PublishingApplicationsConverter(this.context);
|
||||
}
|
||||
return converter;
|
||||
}
|
||||
@@ -124,7 +136,8 @@ public class DataCenterAwareMarshallingStrategy implements MarshallingStrategy {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext unmarshallingContext) {
|
||||
public Object unmarshal(HierarchicalStreamReader reader,
|
||||
UnmarshallingContext unmarshallingContext) {
|
||||
Object obj = super.unmarshal(reader, unmarshallingContext);
|
||||
|
||||
ProxyFactory factory = new ProxyFactory(obj);
|
||||
@@ -135,6 +148,7 @@ public class DataCenterAwareMarshallingStrategy implements MarshallingStrategy {
|
||||
|
||||
@Slf4j
|
||||
private static class SetVersionInterceptor implements MethodInterceptor {
|
||||
|
||||
private ApplicationContext context;
|
||||
|
||||
public SetVersionInterceptor(ApplicationContext context) {
|
||||
@@ -147,14 +161,16 @@ public class DataCenterAwareMarshallingStrategy implements MarshallingStrategy {
|
||||
if ("setVersion".equals(invocation.getMethod().getName())) {
|
||||
Long version = Long.class.cast(invocation.getArguments()[0]);
|
||||
log.debug("Applications.setVersion() called with version: " + version);
|
||||
context.publishEvent(new DiscoveryHeartbeatEvent(invocation.getThis(), version));
|
||||
this.context.publishEvent(new DiscoveryHeartbeatEvent(invocation
|
||||
.getThis(), version));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class DataCenterAwareConverter extends InstanceInfoConverter {
|
||||
|
||||
|
||||
@Override
|
||||
public void marshal(Object source, HierarchicalStreamWriter writer,
|
||||
MarshallingContext context) {
|
||||
|
||||
@@ -1,3 +1,19 @@
|
||||
/*
|
||||
* Copyright 2013-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.eureka;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -11,16 +27,17 @@ import com.netflix.discovery.EurekaClientConfig;
|
||||
*/
|
||||
public class DiscoveryManagerInitializer {
|
||||
|
||||
@Autowired
|
||||
private EurekaClientConfig clientConfig;
|
||||
@Autowired
|
||||
private EurekaClientConfig clientConfig;
|
||||
|
||||
@Autowired
|
||||
private EurekaInstanceConfig instanceConfig;
|
||||
@Autowired
|
||||
private EurekaInstanceConfig instanceConfig;
|
||||
|
||||
public synchronized void init() {
|
||||
if (DiscoveryManager.getInstance().getDiscoveryClient() == null) {
|
||||
DiscoveryManager.getInstance().initComponent(this.instanceConfig,
|
||||
this.clientConfig);
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void init() {
|
||||
if (DiscoveryManager.getInstance().getDiscoveryClient() == null) {
|
||||
DiscoveryManager.getInstance().initComponent(instanceConfig, clientConfig);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,21 @@
|
||||
package org.springframework.cloud.netflix.eureka;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
/*
|
||||
* Copyright 2013-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.eureka;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Inherited;
|
||||
@@ -19,9 +31,9 @@ import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
|
||||
* it is Eureka you want. All it does is turn on discovery and let the autoconfiguration
|
||||
* find the eureka classes if they are available (i.e. you need Eureka on the classpath as
|
||||
* well).
|
||||
*
|
||||
* @author Dave Syer
|
||||
*
|
||||
* @author Dave Syer
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@@ -29,4 +41,5 @@ import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
|
||||
@Inherited
|
||||
@EnableDiscoveryClient
|
||||
public @interface EnableEurekaClient {
|
||||
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.eureka;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
@@ -33,7 +34,6 @@ import com.netflix.discovery.converters.XmlXStream;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
@Configuration
|
||||
@EnableConfigurationProperties
|
||||
@@ -47,9 +47,9 @@ public class EurekaClientAutoConfiguration {
|
||||
@PostConstruct
|
||||
public void init() {
|
||||
XmlXStream.getInstance().setMarshallingStrategy(
|
||||
new DataCenterAwareMarshallingStrategy(context));
|
||||
new DataCenterAwareMarshallingStrategy(this.context));
|
||||
JsonXStream.getInstance().setMarshallingStrategy(
|
||||
new DataCenterAwareMarshallingStrategy(context));
|
||||
new DataCenterAwareMarshallingStrategy(this.context));
|
||||
}
|
||||
|
||||
@Bean
|
||||
@@ -64,5 +64,4 @@ public class EurekaClientAutoConfiguration {
|
||||
return new EurekaInstanceConfigBean();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.eureka;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -29,18 +30,18 @@ import com.netflix.discovery.EurekaClientConfig;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
@Data
|
||||
@ConfigurationProperties("eureka.client")
|
||||
public class EurekaClientConfigBean implements EurekaClientConfig {
|
||||
|
||||
public static final String DEFAULT_URL = "http://localhost:8761" + EurekaServerConfigBean.DEFAULT_PREFIX + "/";
|
||||
public static final String DEFAULT_URL = "http://localhost:8761"
|
||||
+ EurekaServerConfigBean.DEFAULT_PREFIX + "/";
|
||||
|
||||
public static final String DEFAULT_ZONE = "defaultZone";
|
||||
|
||||
|
||||
private static final int MINUTES = 60;
|
||||
|
||||
|
||||
private boolean enabled = true;
|
||||
|
||||
private int registryFetchIntervalSeconds = 30;
|
||||
@@ -55,9 +56,9 @@ public class EurekaClientConfigBean implements EurekaClientConfig {
|
||||
|
||||
private String proxyHost;
|
||||
|
||||
private String proxyUserName;
|
||||
private String proxyUserName;
|
||||
|
||||
private String proxyPassword;
|
||||
private String proxyPassword;
|
||||
|
||||
private int eurekaServerReadTimeoutSeconds = 8;
|
||||
|
||||
@@ -83,16 +84,15 @@ public class EurekaClientConfigBean implements EurekaClientConfig {
|
||||
|
||||
private int heartbeatExecutorThreadPoolSize = 2;
|
||||
|
||||
private int heartbeatExecutorExponentialBackOffBound = 10;
|
||||
private int heartbeatExecutorExponentialBackOffBound = 10;
|
||||
|
||||
private int cacheRefreshExecutorThreadPoolSize = 2;
|
||||
|
||||
private int cacheRefreshExecutorExponentialBackOffBound = 10;
|
||||
private int cacheRefreshExecutorExponentialBackOffBound = 10;
|
||||
|
||||
private Map<String,String> serviceUrl = new HashMap<String, String>();
|
||||
|
||||
private Map<String, String> serviceUrl = new HashMap<String, String>();
|
||||
{
|
||||
serviceUrl.put(DEFAULT_ZONE, DEFAULT_URL);
|
||||
this.serviceUrl.put(DEFAULT_ZONE, DEFAULT_URL);
|
||||
}
|
||||
|
||||
private boolean gZipContent = true;
|
||||
@@ -117,43 +117,43 @@ public class EurekaClientConfigBean implements EurekaClientConfig {
|
||||
|
||||
@Override
|
||||
public boolean shouldGZipContent() {
|
||||
return gZipContent;
|
||||
return this.gZipContent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldUseDnsForFetchingServiceUrls() {
|
||||
return useDnsForFetchingServiceUrls;
|
||||
return this.useDnsForFetchingServiceUrls;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldRegisterWithEureka() {
|
||||
return registerWithEureka;
|
||||
return this.registerWithEureka;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldPreferSameZoneEureka() {
|
||||
return preferSameZoneEureka;
|
||||
return this.preferSameZoneEureka;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldLogDeltaDiff() {
|
||||
return logDeltaDiff;
|
||||
return this.logDeltaDiff;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldDisableDelta() {
|
||||
return disableDelta;
|
||||
return this.disableDelta;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String fetchRegistryForRemoteRegions() {
|
||||
return fetchRemoteRegionsRegistry;
|
||||
return this.fetchRemoteRegionsRegistry;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getAvailabilityZones(String region) {
|
||||
String value = availabilityZones.get(region);
|
||||
if (value==null) {
|
||||
String value = this.availabilityZones.get(region);
|
||||
if (value == null) {
|
||||
value = DEFAULT_ZONE;
|
||||
}
|
||||
return value.split(",");
|
||||
@@ -161,25 +161,25 @@ public class EurekaClientConfigBean implements EurekaClientConfig {
|
||||
|
||||
@Override
|
||||
public List<String> getEurekaServerServiceUrls(String myZone) {
|
||||
String serviceUrls = serviceUrl.get(myZone);
|
||||
if (serviceUrls == null || serviceUrls.isEmpty()) {
|
||||
serviceUrls = serviceUrl.get(DEFAULT_ZONE);
|
||||
}
|
||||
if (serviceUrls != null) {
|
||||
return Arrays.asList(serviceUrls.split(","));
|
||||
}
|
||||
String serviceUrls = this.serviceUrl.get(myZone);
|
||||
if (serviceUrls == null || serviceUrls.isEmpty()) {
|
||||
serviceUrls = this.serviceUrl.get(DEFAULT_ZONE);
|
||||
}
|
||||
if (serviceUrls != null) {
|
||||
return Arrays.asList(serviceUrls.split(","));
|
||||
}
|
||||
|
||||
return new ArrayList<>();
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldFilterOnlyUpInstances() {
|
||||
return filterOnlyUpInstances;
|
||||
return this.filterOnlyUpInstances;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldFetchRegistry() {
|
||||
return fetchRegistry;
|
||||
return this.fetchRegistry;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,20 +1,40 @@
|
||||
/*
|
||||
* Copyright 2013-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.eureka;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.cloud.client.ServiceInstance;
|
||||
import org.springframework.cloud.client.discovery.DiscoveryClient;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Predicates;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.netflix.appinfo.InstanceInfo;
|
||||
import com.netflix.discovery.shared.Application;
|
||||
import com.netflix.discovery.shared.Applications;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.cloud.client.ServiceInstance;
|
||||
import org.springframework.cloud.client.discovery.DiscoveryClient;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static com.google.common.collect.Iterables.*;
|
||||
import static com.google.common.collect.Iterables.concat;
|
||||
import static com.google.common.collect.Iterables.filter;
|
||||
import static com.google.common.collect.Iterables.transform;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
@@ -24,10 +44,10 @@ public class EurekaDiscoveryClient implements DiscoveryClient {
|
||||
public static final String DESCRIPTION = "Spring Cloud Eureka Discovery Client";
|
||||
|
||||
@Autowired
|
||||
private EurekaInstanceConfigBean config;
|
||||
private EurekaInstanceConfigBean config;
|
||||
|
||||
@Autowired
|
||||
private com.netflix.discovery.DiscoveryClient discovery;
|
||||
@Autowired
|
||||
private com.netflix.discovery.DiscoveryClient discovery;
|
||||
|
||||
@Override
|
||||
public String description() {
|
||||
@@ -35,96 +55,104 @@ public class EurekaDiscoveryClient implements DiscoveryClient {
|
||||
}
|
||||
|
||||
@Override
|
||||
public ServiceInstance getLocalServiceInstance() {
|
||||
return new ServiceInstance() {
|
||||
@Override
|
||||
public String getServiceId() {
|
||||
return config.getAppname();
|
||||
}
|
||||
public ServiceInstance getLocalServiceInstance() {
|
||||
return new ServiceInstance() {
|
||||
@Override
|
||||
public String getServiceId() {
|
||||
return EurekaDiscoveryClient.this.config.getAppname();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHost() {
|
||||
return config.getHostname();
|
||||
}
|
||||
@Override
|
||||
public String getHost() {
|
||||
return EurekaDiscoveryClient.this.config.getHostname();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPort() {
|
||||
return config.getNonSecurePort();
|
||||
}
|
||||
};
|
||||
}
|
||||
@Override
|
||||
public int getPort() {
|
||||
return EurekaDiscoveryClient.this.config.getNonSecurePort();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ServiceInstance> getInstances(String serviceId) {
|
||||
List<InstanceInfo> infos = discovery.getInstancesByVipAddress(serviceId, false);
|
||||
Iterable<ServiceInstance> instances = transform(infos, new Function<InstanceInfo, ServiceInstance>() {
|
||||
@Nullable
|
||||
@Override
|
||||
public ServiceInstance apply(@Nullable InstanceInfo info) {
|
||||
return new EurekaServiceInstance(info);
|
||||
}
|
||||
});
|
||||
return Lists.newArrayList(instances);
|
||||
}
|
||||
@Override
|
||||
public List<ServiceInstance> getInstances(String serviceId) {
|
||||
List<InstanceInfo> infos = this.discovery.getInstancesByVipAddress(serviceId,
|
||||
false);
|
||||
Iterable<ServiceInstance> instances = transform(infos,
|
||||
new Function<InstanceInfo, ServiceInstance>() {
|
||||
@Nullable
|
||||
@Override
|
||||
public ServiceInstance apply(@Nullable InstanceInfo info) {
|
||||
return new EurekaServiceInstance(info);
|
||||
}
|
||||
});
|
||||
return Lists.newArrayList(instances);
|
||||
}
|
||||
|
||||
static class EurekaServiceInstance implements ServiceInstance {
|
||||
InstanceInfo instance;
|
||||
static class EurekaServiceInstance implements ServiceInstance {
|
||||
InstanceInfo instance;
|
||||
|
||||
EurekaServiceInstance(InstanceInfo instance) {
|
||||
this.instance = instance;
|
||||
}
|
||||
EurekaServiceInstance(InstanceInfo instance) {
|
||||
this.instance = instance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getServiceId() {
|
||||
return instance.getAppName();
|
||||
}
|
||||
@Override
|
||||
public String getServiceId() {
|
||||
return this.instance.getAppName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHost() {
|
||||
return instance.getHostName();
|
||||
}
|
||||
@Override
|
||||
public String getHost() {
|
||||
return this.instance.getHostName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPort() {
|
||||
return instance.getPort();
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public int getPort() {
|
||||
return this.instance.getPort();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getServices() {
|
||||
Applications applications = discovery.getApplications();
|
||||
if (applications == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return Lists.newArrayList(filter(transform(applications.getRegisteredApplications(), new Function<Application, String>() {
|
||||
@Nullable
|
||||
@Override
|
||||
public String apply(@Nullable Application app) {
|
||||
if (app.getInstances().isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
return app.getName().toLowerCase();
|
||||
}
|
||||
}), Predicates.notNull()));
|
||||
}
|
||||
@Override
|
||||
public List<String> getServices() {
|
||||
Applications applications = this.discovery.getApplications();
|
||||
if (applications == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return Lists.newArrayList(filter(
|
||||
transform(applications.getRegisteredApplications(),
|
||||
new Function<Application, String>() {
|
||||
@Nullable
|
||||
@Override
|
||||
public String apply(@Nullable Application app) {
|
||||
if (app.getInstances().isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
return app.getName().toLowerCase();
|
||||
}
|
||||
}), Predicates.notNull()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ServiceInstance> getAllInstances() {
|
||||
Applications applications = this.discovery.getApplications();
|
||||
if (applications == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
Iterable<ServiceInstance> instances = transform(
|
||||
concat(transform(applications.getRegisteredApplications(),
|
||||
new Function<Application, List<InstanceInfo>>() {
|
||||
@Override
|
||||
public List<InstanceInfo> apply(@Nullable Application app) {
|
||||
return app.getInstances();
|
||||
}
|
||||
})), new Function<InstanceInfo, ServiceInstance>() {
|
||||
@Nullable
|
||||
@Override
|
||||
public ServiceInstance apply(@Nullable InstanceInfo info) {
|
||||
return new EurekaServiceInstance(info);
|
||||
}
|
||||
});
|
||||
return Lists.newArrayList(instances);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ServiceInstance> getAllInstances() {
|
||||
Applications applications = discovery.getApplications();
|
||||
if (applications == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
Iterable<ServiceInstance> instances = transform(concat(transform(applications.getRegisteredApplications(), new Function<Application, List<InstanceInfo>>() {
|
||||
public List<InstanceInfo> apply(@Nullable Application app) {
|
||||
return app.getInstances();
|
||||
}
|
||||
})), new Function<InstanceInfo, ServiceInstance>() {
|
||||
@Nullable
|
||||
@Override
|
||||
public ServiceInstance apply(@Nullable InstanceInfo info) {
|
||||
return new EurekaServiceInstance(info);
|
||||
}
|
||||
});
|
||||
return Lists.newArrayList(instances);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.eureka;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
@@ -55,7 +56,6 @@ import com.netflix.discovery.shared.EurekaJerseyClient;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
@Configuration
|
||||
@EnableConfigurationProperties
|
||||
@@ -84,7 +84,8 @@ public class EurekaDiscoveryClientConfiguration implements SmartLifecycle, Order
|
||||
@PreDestroy
|
||||
public void close() {
|
||||
closeDiscoveryClientJersey();
|
||||
logger.info("Removing application {} from eureka", instanceConfig.getAppname());
|
||||
logger.info("Removing application {} from eureka",
|
||||
this.instanceConfig.getAppname());
|
||||
DiscoveryManager.getInstance().shutdownComponent();
|
||||
}
|
||||
|
||||
@@ -103,8 +104,8 @@ public class EurekaDiscoveryClientConfiguration implements SmartLifecycle, Order
|
||||
jerseyClient.destroyResources();
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
logger.error("Error closing DiscoveryClient.jerseyClient", e);
|
||||
catch (Exception ex) {
|
||||
logger.error("Error closing DiscoveryClient.jerseyClient", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -112,25 +113,27 @@ public class EurekaDiscoveryClientConfiguration implements SmartLifecycle, Order
|
||||
@Override
|
||||
public void start() {
|
||||
// only set the port if the nonSecurePort is 0 and this.port != 0
|
||||
if (port.get() != 0 && instanceConfig.getNonSecurePort() == 0) {
|
||||
instanceConfig.setNonSecurePort(port.get());
|
||||
if (this.port.get() != 0 && this.instanceConfig.getNonSecurePort() == 0) {
|
||||
this.instanceConfig.setNonSecurePort(this.port.get());
|
||||
}
|
||||
// only initialize if nonSecurePort is greater than 0 and it isn't already running
|
||||
// because of containerPortInitializer below
|
||||
if (!running.get() && instanceConfig.getNonSecurePort() > 0) {
|
||||
if (!this.running.get() && this.instanceConfig.getNonSecurePort() > 0) {
|
||||
discoveryManagerIntitializer().init();
|
||||
|
||||
logger.info("Registering application {} with eureka with status {}",
|
||||
instanceConfig.getAppname(), instanceConfig.getInitialStatus());
|
||||
this.instanceConfig.getAppname(),
|
||||
this.instanceConfig.getInitialStatus());
|
||||
ApplicationInfoManager.getInstance().setInstanceStatus(
|
||||
instanceConfig.getInitialStatus());
|
||||
this.instanceConfig.getInitialStatus());
|
||||
|
||||
if (healthCheckHandler != null) {
|
||||
if (this.healthCheckHandler != null) {
|
||||
DiscoveryManager.getInstance().getDiscoveryClient()
|
||||
.registerHealthCheck(healthCheckHandler);
|
||||
.registerHealthCheck(this.healthCheckHandler);
|
||||
}
|
||||
context.publishEvent(new InstanceRegisteredEvent<>(this, instanceConfig));
|
||||
running.set(true);
|
||||
this.context.publishEvent(new InstanceRegisteredEvent<>(this,
|
||||
this.instanceConfig));
|
||||
this.running.set(true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -138,15 +141,15 @@ public class EurekaDiscoveryClientConfiguration implements SmartLifecycle, Order
|
||||
public void stop() {
|
||||
logger.info(
|
||||
"Unregistering application {} with eureka with status OUT_OF_SERVICE",
|
||||
instanceConfig.getAppname());
|
||||
this.instanceConfig.getAppname());
|
||||
ApplicationInfoManager.getInstance().setInstanceStatus(
|
||||
InstanceStatus.OUT_OF_SERVICE);
|
||||
running.set(false);
|
||||
this.running.set(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRunning() {
|
||||
return running.get();
|
||||
return this.running.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -166,7 +169,7 @@ public class EurekaDiscoveryClientConfiguration implements SmartLifecycle, Order
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return order;
|
||||
return this.order;
|
||||
}
|
||||
|
||||
@Bean
|
||||
@@ -214,4 +217,5 @@ public class EurekaDiscoveryClientConfiguration implements SmartLifecycle, Order
|
||||
return new EurekaHealthIndicator(eurekaDiscoveryClient, metrics, config);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.eureka;
|
||||
|
||||
import java.util.Collections;
|
||||
@@ -24,27 +25,26 @@ import org.springframework.boot.actuate.health.Health.Builder;
|
||||
import org.springframework.boot.actuate.health.Status;
|
||||
import org.springframework.boot.actuate.metrics.Metric;
|
||||
import org.springframework.boot.actuate.metrics.reader.MetricReader;
|
||||
import org.springframework.cloud.client.discovery.DiscoveryHealthIndicator;
|
||||
|
||||
import com.netflix.appinfo.EurekaInstanceConfig;
|
||||
import com.netflix.discovery.DiscoveryClient;
|
||||
import com.netflix.discovery.shared.Application;
|
||||
import com.netflix.discovery.shared.Applications;
|
||||
import org.springframework.cloud.client.discovery.DiscoveryHealthIndicator;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
public class EurekaHealthIndicator implements DiscoveryHealthIndicator {
|
||||
|
||||
private EurekaInstanceConfig instanceConfig;
|
||||
private final DiscoveryClient discovery;
|
||||
|
||||
private MetricReader metrics;
|
||||
private final MetricReader metrics;
|
||||
|
||||
private final EurekaInstanceConfig instanceConfig;
|
||||
|
||||
private int failCount = 0;
|
||||
|
||||
private DiscoveryClient discovery;
|
||||
|
||||
public EurekaHealthIndicator(DiscoveryClient discovery, MetricReader metrics,
|
||||
EurekaInstanceConfig instanceConfig) {
|
||||
super();
|
||||
@@ -67,28 +67,29 @@ public class EurekaHealthIndicator implements DiscoveryHealthIndicator {
|
||||
}
|
||||
|
||||
private Status getStatus(Builder builder) {
|
||||
Status status = new Status(discovery.getInstanceRemoteStatus().toString(),
|
||||
Status status = new Status(this.discovery.getInstanceRemoteStatus().toString(),
|
||||
"Remote status from Eureka server");
|
||||
@SuppressWarnings("unchecked")
|
||||
Metric<Number> value = (Metric<Number>) metrics
|
||||
Metric<Number> value = (Metric<Number>) this.metrics
|
||||
.findOne("counter.servo.discoveryclient_failed");
|
||||
if (value != null) {
|
||||
int renewalPeriod = instanceConfig.getLeaseRenewalIntervalInSeconds();
|
||||
int renewalPeriod = this.instanceConfig.getLeaseRenewalIntervalInSeconds();
|
||||
int latest = value.getValue().intValue();
|
||||
builder.withDetail("failCount", latest);
|
||||
builder.withDetail("renewalPeriod", renewalPeriod);
|
||||
if (failCount < latest) {
|
||||
if (this.failCount < latest) {
|
||||
status = new Status("UP", "Eureka discovery client is reporting failures");
|
||||
failCount = latest;
|
||||
} else {
|
||||
status = new Status("UP", "No new failures in Eureka discovery client");
|
||||
this.failCount = latest;
|
||||
}
|
||||
else {
|
||||
status = new Status("UP", "No new failures in Eureka discovery client");
|
||||
}
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
private Map<String, Object> getApplications() {
|
||||
Applications applications = discovery.getApplications();
|
||||
Applications applications = this.discovery.getApplications();
|
||||
if (applications == null) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.eureka;
|
||||
|
||||
import java.net.InetAddress;
|
||||
@@ -37,104 +38,109 @@ import com.netflix.appinfo.UniqueIdentifier;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
@Data
|
||||
@ConfigurationProperties("eureka.instance")
|
||||
public class EurekaInstanceConfigBean implements EurekaInstanceConfig {
|
||||
|
||||
|
||||
private static final Log logger = LogFactory.getLog(EurekaInstanceConfigBean.class);
|
||||
|
||||
@Getter(AccessLevel.PRIVATE) @Setter(AccessLevel.PRIVATE)
|
||||
|
||||
@Getter(AccessLevel.PRIVATE)
|
||||
@Setter(AccessLevel.PRIVATE)
|
||||
private String[] hostInfo = initHostInfo();
|
||||
|
||||
@Value("${spring.application.name:unknown}")
|
||||
private String appname = "unknown";
|
||||
private String appname = "unknown";
|
||||
|
||||
private String appGroupName;
|
||||
|
||||
private boolean instanceEnabledOnit;
|
||||
private String appGroupName;
|
||||
|
||||
private boolean instanceEnabledOnit;
|
||||
|
||||
@Value("${server.port:${SERVER_PORT:${PORT:8080}}}")
|
||||
private int nonSecurePort = 80;
|
||||
private int nonSecurePort = 80;
|
||||
|
||||
private int securePort = 443;
|
||||
private int securePort = 443;
|
||||
|
||||
private boolean nonSecurePortEnabled = true;
|
||||
private boolean nonSecurePortEnabled = true;
|
||||
|
||||
private boolean securePortEnabled;
|
||||
private boolean securePortEnabled;
|
||||
|
||||
private int leaseRenewalIntervalInSeconds = 30;
|
||||
private int leaseRenewalIntervalInSeconds = 30;
|
||||
|
||||
private int leaseExpirationDurationInSeconds = 90;
|
||||
private int leaseExpirationDurationInSeconds = 90;
|
||||
|
||||
@Value("${spring.application.name:unknown}")
|
||||
private String virtualHostName;
|
||||
private String virtualHostName;
|
||||
|
||||
private String secureVirtualHostName;
|
||||
private String secureVirtualHostName;
|
||||
|
||||
private String aSGName;
|
||||
private String aSGName;
|
||||
|
||||
private Map<String, String> metadataMap = new HashMap<>();
|
||||
private Map<String, String> metadataMap = new HashMap<>();
|
||||
|
||||
private DataCenterInfo dataCenterInfo = new IdentifyingDataCenterInfo();
|
||||
private DataCenterInfo dataCenterInfo = new IdentifyingDataCenterInfo();
|
||||
|
||||
private String ipAddress = hostInfo[0];
|
||||
private String ipAddress = this.hostInfo[0];
|
||||
|
||||
private String statusPageUrlPath = "/info";
|
||||
private String statusPageUrlPath = "/info";
|
||||
|
||||
private String statusPageUrl;
|
||||
private String statusPageUrl;
|
||||
|
||||
private String homePageUrlPath = "/";
|
||||
private String homePageUrlPath = "/";
|
||||
|
||||
private String homePageUrl;
|
||||
private String homePageUrl;
|
||||
|
||||
private String healthCheckUrlPath = "/health";
|
||||
private String healthCheckUrlPath = "/health";
|
||||
|
||||
private String healthCheckUrl;
|
||||
private String healthCheckUrl;
|
||||
|
||||
private String secureHealthCheckUrl;
|
||||
private String secureHealthCheckUrl;
|
||||
|
||||
private String namespace = "eureka";
|
||||
private String namespace = "eureka";
|
||||
|
||||
private String hostname = this.hostInfo[1];
|
||||
|
||||
private String hostname = hostInfo[1];
|
||||
|
||||
private boolean preferIpAddress = false;
|
||||
|
||||
private InstanceStatus initialStatus = InstanceStatus.UP;
|
||||
|
||||
private InstanceStatus initialStatus = InstanceStatus.UP;
|
||||
|
||||
public String getHostname() {
|
||||
return preferIpAddress ? ipAddress : hostname;
|
||||
return this.preferIpAddress ? this.ipAddress : this.hostname;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getSecurePortEnabled() {
|
||||
return securePortEnabled;
|
||||
return this.securePortEnabled;
|
||||
}
|
||||
|
||||
private String[] initHostInfo() {
|
||||
String[] info = new String[2];
|
||||
try {
|
||||
info[0] = InetAddress.getLocalHost().getHostAddress();
|
||||
info[1] = InetAddress.getLocalHost().getHostName();
|
||||
} catch (UnknownHostException e) {
|
||||
logger.error("Cannot get host info", e);
|
||||
}
|
||||
return info ;
|
||||
info[1] = InetAddress.getLocalHost().getHostName();
|
||||
}
|
||||
catch (UnknownHostException ex) {
|
||||
logger.error("Cannot get host info", ex);
|
||||
}
|
||||
return info;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHostName(boolean refresh) {
|
||||
return preferIpAddress ? ipAddress : hostname;
|
||||
return this.preferIpAddress ? this.ipAddress : this.hostname;
|
||||
}
|
||||
|
||||
private final class IdentifyingDataCenterInfo implements DataCenterInfo, UniqueIdentifier {
|
||||
@Getter @Setter
|
||||
private Name name = Name.MyOwn;
|
||||
|
||||
private final class IdentifyingDataCenterInfo implements DataCenterInfo,
|
||||
UniqueIdentifier {
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
private Name name = Name.MyOwn;
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
String instanceId = metadataMap.get("instanceId");
|
||||
String instanceId = EurekaInstanceConfigBean.this.metadataMap
|
||||
.get("instanceId");
|
||||
if (instanceId != null) {
|
||||
String old = getHostname();
|
||||
String id = old.endsWith(instanceId) ? old : old + ":" + instanceId;
|
||||
@@ -142,7 +148,7 @@ public class EurekaInstanceConfigBean implements EurekaInstanceConfig {
|
||||
}
|
||||
return getHostname();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.eureka;
|
||||
|
||||
import java.util.Collections;
|
||||
@@ -20,15 +21,14 @@ import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
|
||||
import com.netflix.eureka.EurekaServerConfig;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
@Data
|
||||
@ConfigurationProperties("eureka.server")
|
||||
@@ -46,11 +46,7 @@ public class EurekaServerConfigBean implements EurekaServerConfig {
|
||||
|
||||
private int eIPBindingRetryIntervalMs = 5 * MINUTES;
|
||||
|
||||
private boolean enableSelfPreservation = true;
|
||||
@Override
|
||||
public boolean shouldEnableSelfPreservation() {
|
||||
return enableSelfPreservation;
|
||||
}
|
||||
private boolean enableSelfPreservation = true;
|
||||
|
||||
private double renewalPercentThreshold = 0.85;
|
||||
|
||||
@@ -88,11 +84,7 @@ public class EurekaServerConfigBean implements EurekaServerConfig {
|
||||
|
||||
private long responseCacheUpdateIntervalMs = 30 * 1000;
|
||||
|
||||
private boolean disableDelta;
|
||||
@Override
|
||||
public boolean shouldDisableDelta() {
|
||||
return disableDelta;
|
||||
}
|
||||
private boolean disableDelta;
|
||||
|
||||
private long maxIdleThreadInMinutesAgeForStatusReplication = 10;
|
||||
|
||||
@@ -102,11 +94,7 @@ public class EurekaServerConfigBean implements EurekaServerConfig {
|
||||
|
||||
private int maxElementsInStatusReplicationPool = 10000;
|
||||
|
||||
private boolean syncWhenTimestampDiffers = true;
|
||||
@Override
|
||||
public boolean shouldSyncWhenTimestampDiffers() {
|
||||
return syncWhenTimestampDiffers;
|
||||
}
|
||||
private boolean syncWhenTimestampDiffers = true;
|
||||
|
||||
private int registrySyncRetries = 5;
|
||||
|
||||
@@ -120,17 +108,9 @@ public class EurekaServerConfigBean implements EurekaServerConfig {
|
||||
|
||||
private int maxTimeForReplication = 30000;
|
||||
|
||||
private boolean primeAwsReplicaConnections = true;
|
||||
@Override
|
||||
public boolean shouldPrimeAwsReplicaConnections() {
|
||||
return primeAwsReplicaConnections;
|
||||
}
|
||||
private boolean primeAwsReplicaConnections = true;
|
||||
|
||||
private boolean disableDeltaForRemoteRegions;
|
||||
@Override
|
||||
public boolean shouldDisableDeltaForRemoteRegions() {
|
||||
return disableDeltaForRemoteRegions;
|
||||
}
|
||||
private boolean disableDeltaForRemoteRegions;
|
||||
|
||||
private int remoteRegionConnectTimeoutMs = 1000;
|
||||
|
||||
@@ -142,26 +122,13 @@ public class EurekaServerConfigBean implements EurekaServerConfig {
|
||||
|
||||
private int remoteRegionConnectionIdleTimeoutSeconds = 30;
|
||||
|
||||
private boolean gZipContentFromRemoteRegion = true;
|
||||
@Override
|
||||
public boolean shouldGZipContentFromRemoteRegion() {
|
||||
return gZipContentFromRemoteRegion;
|
||||
}
|
||||
private boolean gZipContentFromRemoteRegion = true;
|
||||
|
||||
private Map<String, String> remoteRegionUrlsWithName = new HashMap<String, String>();
|
||||
|
||||
private String[] remoteRegionUrls;
|
||||
private String[] remoteRegionUrls;
|
||||
|
||||
private Map<String, Set<String>> remoteRegionAppWhitelist;
|
||||
@Override
|
||||
public Set<String> getRemoteRegionAppWhitelist(String regionName) {
|
||||
if (null == regionName) {
|
||||
regionName = "global";
|
||||
} else {
|
||||
regionName = regionName.trim().toLowerCase();
|
||||
}
|
||||
return remoteRegionAppWhitelist.get(regionName);
|
||||
}
|
||||
|
||||
private int remoteRegionRegistryFetchInterval = 30;
|
||||
|
||||
@@ -170,34 +137,72 @@ public class EurekaServerConfigBean implements EurekaServerConfig {
|
||||
private String remoteRegionTrustStorePassword = "changeit";
|
||||
|
||||
private boolean disableTransparentFallbackToOtherRegion;
|
||||
|
||||
private boolean batchReplication;
|
||||
|
||||
private boolean rateLimiterEnabled = false;
|
||||
|
||||
private boolean rateLimiterThrottleStandardClients = false;
|
||||
|
||||
private Set<String> rateLimiterPrivilegedClients = Collections.emptySet();
|
||||
|
||||
private int rateLimiterBurstSize = 10;
|
||||
|
||||
private int rateLimiterRegistryFetchAverageRate = 500;
|
||||
|
||||
private int rateLimiterFullFetchAverageRate = 100;
|
||||
|
||||
private boolean logIdentityHeaders = true;
|
||||
|
||||
@Override
|
||||
public boolean disableTransparentFallbackToOtherRegion() {
|
||||
return disableTransparentFallbackToOtherRegion;
|
||||
public boolean shouldEnableSelfPreservation() {
|
||||
return this.enableSelfPreservation;
|
||||
}
|
||||
|
||||
private boolean batchReplication;
|
||||
@Override
|
||||
public boolean shouldDisableDelta() {
|
||||
return this.disableDelta;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldSyncWhenTimestampDiffers() {
|
||||
return this.syncWhenTimestampDiffers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldPrimeAwsReplicaConnections() {
|
||||
return this.primeAwsReplicaConnections;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldDisableDeltaForRemoteRegions() {
|
||||
return this.disableDeltaForRemoteRegions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldGZipContentFromRemoteRegion() {
|
||||
return this.gZipContentFromRemoteRegion;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getRemoteRegionAppWhitelist(String regionName) {
|
||||
return this.remoteRegionAppWhitelist.get(regionName == null ? "global"
|
||||
: regionName.trim().toLowerCase());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean disableTransparentFallbackToOtherRegion() {
|
||||
return this.disableTransparentFallbackToOtherRegion;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldBatchReplication() {
|
||||
return batchReplication;
|
||||
return this.batchReplication;
|
||||
}
|
||||
|
||||
private boolean logIdentityHeaders = true;
|
||||
@Override
|
||||
public boolean shouldLogIdentityHeaders() {
|
||||
return this.logIdentityHeaders;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldLogIdentityHeaders() {
|
||||
return logIdentityHeaders;
|
||||
}
|
||||
|
||||
private boolean rateLimiterEnabled = false;
|
||||
|
||||
private boolean rateLimiterThrottleStandardClients = false;
|
||||
|
||||
private Set<String> rateLimiterPrivilegedClients = Collections.emptySet();
|
||||
|
||||
private int rateLimiterBurstSize = 10;
|
||||
|
||||
private int rateLimiterRegistryFetchAverageRate = 500;
|
||||
|
||||
private int rateLimiterFullFetchAverageRate = 100;
|
||||
}
|
||||
|
||||
@@ -1,20 +1,36 @@
|
||||
/*
|
||||
* Copyright 2013-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.feign;
|
||||
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.cloud.netflix.archaius.ArchaiusAutoConfiguration;
|
||||
import org.springframework.cloud.netflix.feign.ribbon.FeignRibbonClient;
|
||||
import org.springframework.cloud.netflix.ribbon.SpringClientFactory;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import com.netflix.loadbalancer.ILoadBalancer;
|
||||
|
||||
import feign.Client;
|
||||
import feign.Contract;
|
||||
import feign.Feign;
|
||||
import feign.Logger;
|
||||
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.cloud.netflix.feign.ribbon.FeignRibbonClient;
|
||||
import org.springframework.cloud.netflix.ribbon.SpringClientFactory;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.cloud.netflix.archaius.ArchaiusAutoConfiguration;
|
||||
|
||||
import com.netflix.loadbalancer.ILoadBalancer;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
* @author Julien Roy
|
||||
@@ -23,13 +39,14 @@ import com.netflix.loadbalancer.ILoadBalancer;
|
||||
@ConditionalOnClass(Feign.class)
|
||||
@AutoConfigureAfter(ArchaiusAutoConfiguration.class)
|
||||
public class FeignAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
SpringDecoder feignDecoder() {
|
||||
public SpringDecoder feignDecoder() {
|
||||
return new SpringDecoder();
|
||||
}
|
||||
|
||||
@Bean
|
||||
SpringEncoder feignEncoder() {
|
||||
public SpringEncoder feignEncoder() {
|
||||
return new SpringEncoder();
|
||||
}
|
||||
|
||||
@@ -52,4 +69,5 @@ public class FeignAutoConfiguration {
|
||||
return new FeignRibbonClient(factory);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,6 +1,26 @@
|
||||
/*
|
||||
* Copyright 2013-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.feign;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Annotation for interfaces declaring that a REST client with that interface should be
|
||||
@@ -11,6 +31,7 @@ import java.lang.annotation.*;
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
public @interface FeignClient {
|
||||
|
||||
/**
|
||||
* @return serviceId if loadbalance is true, url otherwise There is no need to prefix
|
||||
* serviceId with http://.
|
||||
@@ -22,4 +43,5 @@ public @interface FeignClient {
|
||||
* available).
|
||||
*/
|
||||
boolean loadbalance() default true;
|
||||
|
||||
}
|
||||
|
||||
@@ -1,3 +1,19 @@
|
||||
/*
|
||||
* Copyright 2013-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.feign;
|
||||
|
||||
import lombok.Data;
|
||||
@@ -6,34 +22,37 @@ import lombok.EqualsAndHashCode;
|
||||
import org.springframework.beans.factory.FactoryBean;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper=false)
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
class FeignClientFactoryBean extends FeignConfiguration implements FactoryBean<Object> {
|
||||
|
||||
private boolean loadbalance;
|
||||
|
||||
private Class<?> type;
|
||||
|
||||
private String schemeName;
|
||||
|
||||
@Override
|
||||
public Object getObject() throws Exception {
|
||||
if (!schemeName.startsWith("http")) {
|
||||
schemeName = "http://"+schemeName;
|
||||
if (!this.schemeName.startsWith("http")) {
|
||||
this.schemeName = "http://" + this.schemeName;
|
||||
}
|
||||
if (loadbalance) {
|
||||
return loadBalance(type, schemeName);
|
||||
if (this.loadbalance) {
|
||||
return loadBalance(this.type, this.schemeName);
|
||||
}
|
||||
return feign().target(type, schemeName);
|
||||
return feign().target(this.type, this.schemeName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> getObjectType() {
|
||||
return type;
|
||||
return this.type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSingleton() {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,3 +1,19 @@
|
||||
/*
|
||||
* Copyright 2013-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.feign;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
@@ -14,7 +30,8 @@ import org.springframework.context.annotation.Import;
|
||||
* {@link org.springframework.context.annotation.Configuration
|
||||
* <code>@Configuration</code>} classes.
|
||||
*
|
||||
* @author Artem Bilan
|
||||
* @author Spencer Gibb
|
||||
* @author Dave Syer
|
||||
* @since 1.0
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@@ -27,7 +44,6 @@ public @interface FeignClientScan {
|
||||
* Alias for the {@link #basePackages()} attribute. Allows for more concise annotation
|
||||
* declarations e.g.: {@code @ComponentScan("org.my.pkg")} instead of
|
||||
* {@code @ComponentScan(basePackages="org.my.pkg")}.
|
||||
*
|
||||
* @return the array of 'basePackages'.
|
||||
*/
|
||||
String[] value() default {};
|
||||
@@ -55,4 +71,4 @@ public @interface FeignClientScan {
|
||||
*/
|
||||
Class<?>[] basePackageClasses() default {};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,19 @@
|
||||
/*
|
||||
* Copyright 2013-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.feign;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
@@ -24,10 +40,11 @@ import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
* patterned after Spring Integration IntegrationComponentScanRegistrar
|
||||
*/
|
||||
public class FeignClientScanRegistrar extends FeignConfiguration
|
||||
implements ImportBeanDefinitionRegistrar, ResourceLoaderAware, BeanClassLoaderAware {
|
||||
public class FeignClientScanRegistrar extends FeignConfiguration implements
|
||||
ImportBeanDefinitionRegistrar, ResourceLoaderAware, BeanClassLoaderAware {
|
||||
|
||||
// patterned after Spring Integration IntegrationComponentScanRegistrar
|
||||
|
||||
private ResourceLoader resourceLoader;
|
||||
|
||||
@@ -47,22 +64,25 @@ public class FeignClientScanRegistrar extends FeignConfiguration
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
|
||||
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata,
|
||||
BeanDefinitionRegistry registry) {
|
||||
|
||||
Set<String> basePackages = getBasePackages(importingClassMetadata);
|
||||
|
||||
ClassPathScanningCandidateComponentProvider scanner = getScanner();
|
||||
scanner.addIncludeFilter(new AnnotationTypeFilter(FeignClient.class));
|
||||
scanner.setResourceLoader(resourceLoader);
|
||||
scanner.setResourceLoader(this.resourceLoader);
|
||||
|
||||
for (String basePackage : basePackages) {
|
||||
Set<BeanDefinition> candidateComponents = scanner.findCandidateComponents(basePackage);
|
||||
Set<BeanDefinition> candidateComponents = scanner
|
||||
.findCandidateComponents(basePackage);
|
||||
for (BeanDefinition candidateComponent : candidateComponents) {
|
||||
if (candidateComponent instanceof AnnotatedBeanDefinition) {
|
||||
//verify annotated class is an interface
|
||||
// verify annotated class is an interface
|
||||
AnnotatedBeanDefinition beanDefinition = (AnnotatedBeanDefinition) candidateComponent;
|
||||
AnnotationMetadata annotationMetadata = beanDefinition.getMetadata();
|
||||
Assert.isTrue(annotationMetadata.isInterface(), "@FeignClient can only be specified on an interface");
|
||||
Assert.isTrue(annotationMetadata.isInterface(),
|
||||
"@FeignClient can only be specified on an interface");
|
||||
|
||||
BeanDefinitionHolder holder = createBeanDefinition(annotationMetadata);
|
||||
BeanDefinitionReaderUtils.registerBeanDefinition(holder, registry);
|
||||
@@ -72,42 +92,50 @@ public class FeignClientScanRegistrar extends FeignConfiguration
|
||||
}
|
||||
|
||||
public BeanDefinitionHolder createBeanDefinition(AnnotationMetadata annotationMetadata) {
|
||||
Map<String, Object> attributes = annotationMetadata.getAnnotationAttributes(FeignClient.class.getCanonicalName());
|
||||
Map<String, Object> attributes = annotationMetadata
|
||||
.getAnnotationAttributes(FeignClient.class.getCanonicalName());
|
||||
|
||||
String className = annotationMetadata.getClassName();
|
||||
BeanDefinitionBuilder definition = BeanDefinitionBuilder.genericBeanDefinition(FeignClientFactoryBean.class);
|
||||
BeanDefinitionBuilder definition = BeanDefinitionBuilder
|
||||
.genericBeanDefinition(FeignClientFactoryBean.class);
|
||||
definition.addPropertyValue("loadbalance", attributes.get("loadbalance"));
|
||||
definition.addPropertyValue("type", className);
|
||||
definition.addPropertyValue("schemeName", attributes.get("value"));
|
||||
|
||||
String beanName = StringUtils.uncapitalize(className.substring(className.lastIndexOf(".") + 1));
|
||||
String beanName = StringUtils.uncapitalize(className.substring(className
|
||||
.lastIndexOf(".") + 1));
|
||||
return new BeanDefinitionHolder(definition.getBeanDefinition(), beanName);
|
||||
}
|
||||
|
||||
protected ClassPathScanningCandidateComponentProvider getScanner() {
|
||||
return new ClassPathScanningCandidateComponentProvider(false) {
|
||||
|
||||
@Override
|
||||
protected boolean isCandidateComponent(AnnotatedBeanDefinition beanDefinition) {
|
||||
if (beanDefinition.getMetadata().isIndependent()) {
|
||||
// TODO until SPR-11711 will be resolved
|
||||
if (beanDefinition.getMetadata().isInterface() &&
|
||||
beanDefinition.getMetadata().getInterfaceNames().length == 1 &&
|
||||
Annotation.class.getName().equals(beanDefinition.getMetadata().getInterfaceNames()[0])) {
|
||||
try {
|
||||
Class<?> target = ClassUtils.forName(beanDefinition.getMetadata().getClassName(), classLoader);
|
||||
return !target.isAnnotation();
|
||||
}
|
||||
catch (Exception e) {
|
||||
logger.error("Could not load target class: " + beanDefinition.getMetadata().getClassName(), e);
|
||||
|
||||
}
|
||||
@Override
|
||||
protected boolean isCandidateComponent(AnnotatedBeanDefinition beanDefinition) {
|
||||
if (beanDefinition.getMetadata().isIndependent()) {
|
||||
// TODO until SPR-11711 will be resolved
|
||||
if (beanDefinition.getMetadata().isInterface()
|
||||
&& beanDefinition.getMetadata().getInterfaceNames().length == 1
|
||||
&& Annotation.class.getName().equals(
|
||||
beanDefinition.getMetadata().getInterfaceNames()[0])) {
|
||||
try {
|
||||
Class<?> target = ClassUtils.forName(beanDefinition
|
||||
.getMetadata().getClassName(),
|
||||
FeignClientScanRegistrar.this.classLoader);
|
||||
return !target.isAnnotation();
|
||||
}
|
||||
catch (Exception ex) {
|
||||
this.logger.error("Could not load target class: "
|
||||
+ beanDefinition.getMetadata().getClassName(), ex);
|
||||
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
return false;
|
||||
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
protected Set<String> getBasePackages(AnnotationMetadata importingClassMetadata) {
|
||||
@@ -130,7 +158,8 @@ public class FeignClientScanRegistrar extends FeignConfiguration
|
||||
}
|
||||
|
||||
if (basePackages.isEmpty()) {
|
||||
basePackages.add(ClassUtils.getPackageName(importingClassMetadata.getClassName()));
|
||||
basePackages.add(ClassUtils.getPackageName(importingClassMetadata
|
||||
.getClassName()));
|
||||
}
|
||||
return basePackages;
|
||||
}
|
||||
|
||||
@@ -1,3 +1,19 @@
|
||||
/*
|
||||
* Copyright 2013-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.feign;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -20,20 +36,21 @@ import feign.ribbon.LoadBalancingTarget;
|
||||
*/
|
||||
@Configuration
|
||||
public class FeignConfiguration {
|
||||
@Autowired
|
||||
ConfigurableEnvironmentConfiguration envConfig; //FIXME: howto enforce this?
|
||||
|
||||
@Autowired
|
||||
Decoder decoder;
|
||||
@Autowired
|
||||
ConfigurableEnvironmentConfiguration envConfig; // FIXME: howto enforce this?
|
||||
|
||||
@Autowired
|
||||
Encoder encoder;
|
||||
@Autowired
|
||||
Decoder decoder;
|
||||
|
||||
@Autowired
|
||||
Logger logger;
|
||||
@Autowired
|
||||
Encoder encoder;
|
||||
|
||||
@Autowired
|
||||
Contract contract;
|
||||
@Autowired
|
||||
Logger logger;
|
||||
|
||||
@Autowired
|
||||
Contract contract;
|
||||
|
||||
@Autowired(required = false)
|
||||
Logger.Level logLevel;
|
||||
@@ -47,40 +64,43 @@ public class FeignConfiguration {
|
||||
@Autowired(required = false)
|
||||
Request.Options options;
|
||||
|
||||
@Autowired(required = false)
|
||||
Client ribbonClient;
|
||||
@Autowired(required = false)
|
||||
Client ribbonClient;
|
||||
|
||||
protected Feign.Builder feign() {
|
||||
protected Feign.Builder feign() {
|
||||
Feign.Builder builder = Feign.builder()
|
||||
//required values
|
||||
.logger(logger)
|
||||
.encoder(encoder)
|
||||
.decoder(decoder)
|
||||
.contract(contract);
|
||||
// required values
|
||||
.logger(this.logger).encoder(this.encoder).decoder(this.decoder)
|
||||
.contract(this.contract);
|
||||
|
||||
//optional values
|
||||
if (logLevel != null)
|
||||
builder.logLevel(logLevel);
|
||||
if (retryer != null)
|
||||
builder.retryer(retryer);
|
||||
if (errorDecoder != null)
|
||||
builder.errorDecoder(errorDecoder);
|
||||
if (options != null)
|
||||
builder.options(options);
|
||||
// optional values
|
||||
if (this.logLevel != null) {
|
||||
builder.logLevel(this.logLevel);
|
||||
}
|
||||
if (this.retryer != null) {
|
||||
builder.retryer(this.retryer);
|
||||
}
|
||||
if (this.errorDecoder != null) {
|
||||
builder.errorDecoder(this.errorDecoder);
|
||||
}
|
||||
if (this.options != null) {
|
||||
builder.options(this.options);
|
||||
}
|
||||
|
||||
return builder;
|
||||
}
|
||||
}
|
||||
|
||||
protected <T> T loadBalance(Class<T> type, String schemeName) {
|
||||
return loadBalance(feign(), type, schemeName);
|
||||
}
|
||||
protected <T> T loadBalance(Class<T> type, String schemeName) {
|
||||
return loadBalance(feign(), type, schemeName);
|
||||
}
|
||||
|
||||
protected <T> T loadBalance(Feign.Builder builder, Class<T> type, String schemeName) {
|
||||
if(ribbonClient != null) {
|
||||
return builder.client(ribbonClient).target(type, schemeName);
|
||||
} else {
|
||||
return builder.target(LoadBalancingTarget.create(type, schemeName));
|
||||
}
|
||||
}
|
||||
protected <T> T loadBalance(Feign.Builder builder, Class<T> type, String schemeName) {
|
||||
if (this.ribbonClient != null) {
|
||||
return builder.client(this.ribbonClient).target(type, schemeName);
|
||||
}
|
||||
else {
|
||||
return builder.target(LoadBalancingTarget.create(type, schemeName));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,20 +1,38 @@
|
||||
package org.springframework.cloud.netflix.feign;
|
||||
/*
|
||||
* Copyright 2013-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import org.springframework.http.HttpHeaders;
|
||||
package org.springframework.cloud.netflix.feign;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.http.HttpHeaders;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
public class FeignUtils {
|
||||
static HttpHeaders getHttpHeaders(Map<String, Collection<String>> headers) {
|
||||
HttpHeaders httpHeaders = new HttpHeaders();
|
||||
for (Map.Entry<String, Collection<String>> entry : headers.entrySet()) {
|
||||
httpHeaders.put(entry.getKey(), new ArrayList<>(entry.getValue()));
|
||||
}
|
||||
return httpHeaders;
|
||||
}
|
||||
|
||||
static HttpHeaders getHttpHeaders(Map<String, Collection<String>> headers) {
|
||||
HttpHeaders httpHeaders = new HttpHeaders();
|
||||
for (Map.Entry<String, Collection<String>> entry : headers.entrySet()) {
|
||||
httpHeaders.put(entry.getKey(), new ArrayList<>(entry.getValue()));
|
||||
}
|
||||
return httpHeaders;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,3 +1,19 @@
|
||||
/*
|
||||
* Copyright 2013-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.feign;
|
||||
|
||||
import java.io.IOException;
|
||||
@@ -5,6 +21,8 @@ import java.io.InputStream;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
import javax.inject.Provider;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.web.HttpMessageConverters;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
@@ -17,8 +35,6 @@ import feign.Response;
|
||||
import feign.codec.DecodeException;
|
||||
import feign.codec.Decoder;
|
||||
|
||||
import javax.inject.Provider;
|
||||
|
||||
import static org.springframework.cloud.netflix.feign.FeignUtils.getHttpHeaders;
|
||||
|
||||
/**
|
||||
@@ -26,25 +42,28 @@ import static org.springframework.cloud.netflix.feign.FeignUtils.getHttpHeaders;
|
||||
*/
|
||||
public class SpringDecoder implements Decoder {
|
||||
|
||||
@Autowired
|
||||
Provider<HttpMessageConverters> messageConverters;
|
||||
@Autowired
|
||||
Provider<HttpMessageConverters> messageConverters;
|
||||
|
||||
public SpringDecoder() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object decode(final Response response, Type type) throws IOException, FeignException {
|
||||
public Object decode(final Response response, Type type) throws IOException,
|
||||
FeignException {
|
||||
if (type instanceof Class || type instanceof ParameterizedType) {
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
HttpMessageConverterExtractor<?> extractor = new HttpMessageConverterExtractor(
|
||||
type, messageConverters.get().getConverters());
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
HttpMessageConverterExtractor<?> extractor = new HttpMessageConverterExtractor(
|
||||
type, this.messageConverters.get().getConverters());
|
||||
|
||||
return extractor.extractData(new FeignResponseAdapter(response));
|
||||
}
|
||||
throw new DecodeException("type is not an instance of Class or ParameterizedType: " + type);
|
||||
return extractor.extractData(new FeignResponseAdapter(response));
|
||||
}
|
||||
throw new DecodeException(
|
||||
"type is not an instance of Class or ParameterizedType: " + type);
|
||||
}
|
||||
|
||||
private class FeignResponseAdapter implements ClientHttpResponse {
|
||||
private class FeignResponseAdapter implements ClientHttpResponse {
|
||||
|
||||
private final Response response;
|
||||
|
||||
private FeignResponseAdapter(Response response) {
|
||||
@@ -53,38 +72,39 @@ public class SpringDecoder implements Decoder {
|
||||
|
||||
@Override
|
||||
public HttpStatus getStatusCode() throws IOException {
|
||||
return HttpStatus.valueOf(response.status());
|
||||
return HttpStatus.valueOf(this.response.status());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRawStatusCode() throws IOException {
|
||||
return response.status();
|
||||
return this.response.status();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getStatusText() throws IOException {
|
||||
return response.reason();
|
||||
return this.response.reason();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
try {
|
||||
response.body().close();
|
||||
this.response.body().close();
|
||||
}
|
||||
catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
catch (IOException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream getBody() throws IOException {
|
||||
return response.body().asInputStream();
|
||||
return this.response.body().asInputStream();
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpHeaders getHeaders() {
|
||||
return getHttpHeaders(response.headers());
|
||||
return getHttpHeaders(this.response.headers());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,10 +1,27 @@
|
||||
/*
|
||||
* Copyright 2013-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.feign;
|
||||
|
||||
import com.google.common.base.Charsets;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Collection;
|
||||
|
||||
import feign.RequestTemplate;
|
||||
import feign.codec.EncodeException;
|
||||
import feign.codec.Encoder;
|
||||
import javax.inject.Provider;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@@ -15,11 +32,11 @@ import org.springframework.http.HttpOutputMessage;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.converter.HttpMessageConverter;
|
||||
|
||||
import javax.inject.Provider;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Collection;
|
||||
import com.google.common.base.Charsets;
|
||||
|
||||
import feign.RequestTemplate;
|
||||
import feign.codec.EncodeException;
|
||||
import feign.codec.Encoder;
|
||||
|
||||
import static org.springframework.cloud.netflix.feign.FeignUtils.getHttpHeaders;
|
||||
|
||||
@@ -27,13 +44,11 @@ import static org.springframework.cloud.netflix.feign.FeignUtils.getHttpHeaders;
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
public class SpringEncoder implements Encoder {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(SpringEncoder.class);
|
||||
|
||||
@Autowired
|
||||
Provider<HttpMessageConverters> messageConverters;
|
||||
|
||||
public SpringEncoder() {
|
||||
}
|
||||
@Autowired
|
||||
Provider<HttpMessageConverters> messageConverters;
|
||||
|
||||
@Override
|
||||
public void encode(Object requestBody, RequestTemplate request)
|
||||
@@ -49,7 +64,8 @@ public class SpringEncoder implements Encoder {
|
||||
requestContentType = MediaType.valueOf(type);
|
||||
}
|
||||
|
||||
for (HttpMessageConverter<?> messageConverter : messageConverters.get().getConverters()) {
|
||||
for (HttpMessageConverter<?> messageConverter : this.messageConverters.get()
|
||||
.getConverters()) {
|
||||
if (messageConverter.canWrite(requestType, requestContentType)) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
if (requestContentType != null) {
|
||||
@@ -70,16 +86,16 @@ public class SpringEncoder implements Encoder {
|
||||
HttpMessageConverter<Object> copy = (HttpMessageConverter<Object>) messageConverter;
|
||||
copy.write(requestBody, requestContentType, outputMessage);
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new EncodeException("Error converting request body", e);
|
||||
catch (IOException ex) {
|
||||
throw new EncodeException("Error converting request body", ex);
|
||||
}
|
||||
request.body(outputMessage.getOutputStream().toByteArray(),
|
||||
Charsets.UTF_8); // TODO: set charset
|
||||
return;
|
||||
}
|
||||
}
|
||||
String message = "Could not write request: no suitable HttpMessageConverter found for request type ["
|
||||
+ requestType.getName() + "]";
|
||||
String message = "Could not write request: no suitable HttpMessageConverter "
|
||||
+ "found for request type [" + requestType.getName() + "]";
|
||||
if (requestContentType != null) {
|
||||
message += " and content type [" + requestContentType + "]";
|
||||
}
|
||||
@@ -88,8 +104,10 @@ public class SpringEncoder implements Encoder {
|
||||
}
|
||||
|
||||
private class FeignOutputMessage implements HttpOutputMessage {
|
||||
|
||||
final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||
RequestTemplate request;
|
||||
|
||||
private final RequestTemplate request;
|
||||
|
||||
private FeignOutputMessage(RequestTemplate request) {
|
||||
this.request = request;
|
||||
@@ -97,16 +115,18 @@ public class SpringEncoder implements Encoder {
|
||||
|
||||
@Override
|
||||
public OutputStream getBody() throws IOException {
|
||||
return outputStream;
|
||||
return this.outputStream;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpHeaders getHeaders() {
|
||||
return getHttpHeaders(request.headers());
|
||||
return getHttpHeaders(this.request.headers());
|
||||
}
|
||||
|
||||
public ByteArrayOutputStream getOutputStream() {
|
||||
return outputStream;
|
||||
return this.outputStream;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,7 +1,20 @@
|
||||
package org.springframework.cloud.netflix.feign;
|
||||
/*
|
||||
* Copyright 2013-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import static feign.Util.checkState;
|
||||
import static feign.Util.emptyToNull;
|
||||
package org.springframework.cloud.netflix.feign;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Method;
|
||||
@@ -12,128 +25,155 @@ import java.util.Map;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestHeader;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
|
||||
import feign.Contract;
|
||||
import feign.MethodMetadata;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
|
||||
import static feign.Util.checkState;
|
||||
import static feign.Util.emptyToNull;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
public class SpringMvcContract extends Contract.BaseContract {
|
||||
static final String ACCEPT = "Accept";
|
||||
static final String CONTENT_TYPE = "Content-Type";
|
||||
|
||||
@Override
|
||||
protected void processAnnotationOnMethod(MethodMetadata data, Annotation methodAnnotation, Method method) {
|
||||
RequestMapping mapping = RequestMapping.class.cast(methodAnnotation);
|
||||
if (mapping != null) {
|
||||
//HTTP Method
|
||||
checkOne(method, mapping.method(), "method");
|
||||
data.template().method(mapping.method()[0].name());
|
||||
private static final String ACCEPT = "Accept";
|
||||
|
||||
//path
|
||||
checkOne(method, mapping.value(), "value");
|
||||
private static final String CONTENT_TYPE = "Content-Type";
|
||||
|
||||
String methodAnnotationValue = mapping.value()[0];
|
||||
String pathValue = emptyToNull(methodAnnotationValue);
|
||||
checkState(pathValue != null, "value was empty on method %s", method.getName());
|
||||
if (!methodAnnotationValue.startsWith("/") && !data.template().toString().endsWith("/")) {
|
||||
methodAnnotationValue = "/" + methodAnnotationValue;
|
||||
}
|
||||
data.template().append(methodAnnotationValue);
|
||||
@Override
|
||||
protected void processAnnotationOnMethod(MethodMetadata data,
|
||||
Annotation methodAnnotation, Method method) {
|
||||
RequestMapping mapping = RequestMapping.class.cast(methodAnnotation);
|
||||
if (mapping != null) {
|
||||
// HTTP Method
|
||||
checkOne(method, mapping.method(), "method");
|
||||
data.template().method(mapping.method()[0].name());
|
||||
|
||||
//produces
|
||||
checkAtMostOne(method, mapping.produces(), "produces");
|
||||
String[] serverProduces = mapping.produces();
|
||||
String clientAccepts = serverProduces.length == 0 ? null: emptyToNull(serverProduces[0]);
|
||||
if (clientAccepts != null) {
|
||||
data.template().header(ACCEPT, clientAccepts);
|
||||
}
|
||||
// path
|
||||
checkOne(method, mapping.value(), "value");
|
||||
|
||||
//consumes
|
||||
checkAtMostOne(method, mapping.consumes(), "consumes");
|
||||
String[] serverConsumes = mapping.consumes();
|
||||
String clientProduces = serverConsumes.length == 0 ? null: emptyToNull(serverConsumes[0]);
|
||||
if (clientProduces != null) {
|
||||
data.template().header(CONTENT_TYPE, clientProduces);
|
||||
}
|
||||
String methodAnnotationValue = mapping.value()[0];
|
||||
String pathValue = emptyToNull(methodAnnotationValue);
|
||||
checkState(pathValue != null, "value was empty on method %s",
|
||||
method.getName());
|
||||
if (!methodAnnotationValue.startsWith("/")
|
||||
&& !data.template().toString().endsWith("/")) {
|
||||
methodAnnotationValue = "/" + methodAnnotationValue;
|
||||
}
|
||||
data.template().append(methodAnnotationValue);
|
||||
|
||||
//headers
|
||||
//TODO: only supports one header value per key
|
||||
if (mapping.headers() != null && mapping.headers().length > 0)
|
||||
for (String header : mapping.headers()) {
|
||||
int colon = header.indexOf(':');
|
||||
data.template().header(header.substring(0, colon), header.substring(colon + 2));
|
||||
}
|
||||
}
|
||||
}
|
||||
// produces
|
||||
checkAtMostOne(method, mapping.produces(), "produces");
|
||||
String[] serverProduces = mapping.produces();
|
||||
String clientAccepts = serverProduces.length == 0 ? null
|
||||
: emptyToNull(serverProduces[0]);
|
||||
if (clientAccepts != null) {
|
||||
data.template().header(ACCEPT, clientAccepts);
|
||||
}
|
||||
|
||||
private void checkAtMostOne(Method method, Object[] values, String fieldName) {
|
||||
checkState(values != null && (values.length == 0 || values.length == 1),
|
||||
"Method %s can only contain at most 1 %s field. Found: %s", method.getName(), fieldName,
|
||||
values == null ? null : Arrays.asList(values));
|
||||
}
|
||||
// consumes
|
||||
checkAtMostOne(method, mapping.consumes(), "consumes");
|
||||
String[] serverConsumes = mapping.consumes();
|
||||
String clientProduces = serverConsumes.length == 0 ? null
|
||||
: emptyToNull(serverConsumes[0]);
|
||||
if (clientProduces != null) {
|
||||
data.template().header(CONTENT_TYPE, clientProduces);
|
||||
}
|
||||
|
||||
private void checkOne(Method method, Object[] values, String fieldName) {
|
||||
checkState(values != null && values.length == 1,
|
||||
"Method %s can only contain 1 %s field. Found: %s", method.getName(), fieldName,
|
||||
values == null ? null : Arrays.asList(values));
|
||||
}
|
||||
// headers
|
||||
// TODO: only supports one header value per key
|
||||
if (mapping.headers() != null && mapping.headers().length > 0) {
|
||||
for (String header : mapping.headers()) {
|
||||
int colon = header.indexOf(':');
|
||||
data.template().header(header.substring(0, colon),
|
||||
header.substring(colon + 2));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean processAnnotationsOnParameter(MethodMetadata data, Annotation[] annotations, int paramIndex) {
|
||||
boolean isHttpAnnotation = false;
|
||||
//TODO: support spring parameter annotations?
|
||||
for (Annotation parameterAnnotation : annotations) {
|
||||
Class<? extends Annotation> annotationType = parameterAnnotation.annotationType();
|
||||
if (annotationType == PathVariable.class) {
|
||||
String name = PathVariable.class.cast(parameterAnnotation).value();
|
||||
checkState(emptyToNull(name) != null, "PathVariable annotation was empty on param %s.", paramIndex);
|
||||
nameParam(data, name, paramIndex);
|
||||
isHttpAnnotation = true;
|
||||
String varName = '{' + name + '}';
|
||||
if (data.template().url().indexOf(varName) == -1 &&
|
||||
!searchMapValues(data.template().queries(), varName) &&
|
||||
!searchMapValues(data.template().headers(), varName)) {
|
||||
data.formParams().add(name);
|
||||
}
|
||||
} else if (annotationType == RequestParam.class) {
|
||||
String name = RequestParam.class.cast(parameterAnnotation).value();
|
||||
checkState(emptyToNull(name) != null, "QueryParam.value() was empty on parameter %s", paramIndex);
|
||||
Collection<String> query = addTemplatedParam(data.template().queries().get(name), name);
|
||||
data.template().query(name, query);
|
||||
nameParam(data, name, paramIndex);
|
||||
isHttpAnnotation = true;
|
||||
} else if (annotationType == RequestHeader.class) {
|
||||
String name = RequestHeader.class.cast(parameterAnnotation).value();
|
||||
checkState(emptyToNull(name) != null, "HeaderParam.value() was empty on parameter %s", paramIndex);
|
||||
Collection<String> header = addTemplatedParam(data.template().headers().get(name), name);
|
||||
data.template().header(name, header);
|
||||
nameParam(data, name, paramIndex);
|
||||
isHttpAnnotation = true;
|
||||
}/* else if (annotationType == FormParam.class) {
|
||||
String name = FormParam.class.cast(parameterAnnotation).value();
|
||||
checkState(emptyToNull(name) != null, "FormParam.value() was empty on parameter %s", paramIndex);
|
||||
data.formParams().add(name);
|
||||
nameParam(data, name, paramIndex);
|
||||
isHttpAnnotation = true;
|
||||
}*/
|
||||
private void checkAtMostOne(Method method, Object[] values, String fieldName) {
|
||||
checkState(values != null && (values.length == 0 || values.length == 1),
|
||||
"Method %s can only contain at most 1 %s field. Found: %s",
|
||||
method.getName(), fieldName,
|
||||
values == null ? null : Arrays.asList(values));
|
||||
}
|
||||
|
||||
}
|
||||
return isHttpAnnotation;
|
||||
}
|
||||
private void checkOne(Method method, Object[] values, String fieldName) {
|
||||
checkState(values != null && values.length == 1,
|
||||
"Method %s can only contain 1 %s field. Found: %s", method.getName(),
|
||||
fieldName, values == null ? null : Arrays.asList(values));
|
||||
}
|
||||
|
||||
private <K, V> boolean searchMapValues(Map<K, Collection<V>> map, V search) {
|
||||
Collection<Collection<V>> values = map.values();
|
||||
if (values == null)
|
||||
return false;
|
||||
@Override
|
||||
protected boolean processAnnotationsOnParameter(MethodMetadata data,
|
||||
Annotation[] annotations, int paramIndex) {
|
||||
boolean isHttpAnnotation = false;
|
||||
// TODO: support spring parameter annotations?
|
||||
for (Annotation parameterAnnotation : annotations) {
|
||||
Class<? extends Annotation> annotationType = parameterAnnotation
|
||||
.annotationType();
|
||||
if (annotationType == PathVariable.class) {
|
||||
String name = PathVariable.class.cast(parameterAnnotation).value();
|
||||
checkState(emptyToNull(name) != null,
|
||||
"PathVariable annotation was empty on param %s.", paramIndex);
|
||||
nameParam(data, name, paramIndex);
|
||||
isHttpAnnotation = true;
|
||||
String varName = '{' + name + '}';
|
||||
if (data.template().url().indexOf(varName) == -1
|
||||
&& !searchMapValues(data.template().queries(), varName)
|
||||
&& !searchMapValues(data.template().headers(), varName)) {
|
||||
data.formParams().add(name);
|
||||
}
|
||||
}
|
||||
else if (annotationType == RequestParam.class) {
|
||||
String name = RequestParam.class.cast(parameterAnnotation).value();
|
||||
checkState(emptyToNull(name) != null,
|
||||
"QueryParam.value() was empty on parameter %s", paramIndex);
|
||||
Collection<String> query = addTemplatedParam(data.template().queries()
|
||||
.get(name), name);
|
||||
data.template().query(name, query);
|
||||
nameParam(data, name, paramIndex);
|
||||
isHttpAnnotation = true;
|
||||
}
|
||||
else if (annotationType == RequestHeader.class) {
|
||||
String name = RequestHeader.class.cast(parameterAnnotation).value();
|
||||
checkState(emptyToNull(name) != null,
|
||||
"HeaderParam.value() was empty on parameter %s", paramIndex);
|
||||
Collection<String> header = addTemplatedParam(data.template().headers()
|
||||
.get(name), name);
|
||||
data.template().header(name, header);
|
||||
nameParam(data, name, paramIndex);
|
||||
isHttpAnnotation = true;
|
||||
}
|
||||
|
||||
for (Collection<V> entry : values) {
|
||||
if (entry.contains(search))
|
||||
return true;
|
||||
}
|
||||
// TODO
|
||||
/*
|
||||
* else if (annotationType == FormParam.class) { String name =
|
||||
* FormParam.class.cast(parameterAnnotation).value();
|
||||
* checkState(emptyToNull(name) != null,
|
||||
* "FormParam.value() was empty on parameter %s", paramIndex);
|
||||
* data.formParams().add(name); nameParam(data, name, paramIndex);
|
||||
* isHttpAnnotation = true; }
|
||||
*/
|
||||
|
||||
}
|
||||
return isHttpAnnotation;
|
||||
}
|
||||
|
||||
private <K, V> boolean searchMapValues(Map<K, Collection<V>> map, V search) {
|
||||
Collection<Collection<V>> values = map.values();
|
||||
if (values == null) {
|
||||
return false;
|
||||
}
|
||||
for (Collection<V> entry : values) {
|
||||
if (entry.contains(search)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,19 @@
|
||||
/*
|
||||
* Copyright 2013-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.feign.ribbon;
|
||||
|
||||
import java.io.IOException;
|
||||
@@ -25,18 +41,9 @@ import feign.Response;
|
||||
*/
|
||||
public class FeignRibbonClient implements Client {
|
||||
|
||||
private Client defaultClient = new Default(
|
||||
new Lazy<SSLSocketFactory>() {
|
||||
@Override
|
||||
public SSLSocketFactory get() {
|
||||
return (SSLSocketFactory) SSLSocketFactory.getDefault();
|
||||
}
|
||||
}, new Lazy<HostnameVerifier>() {
|
||||
@Override
|
||||
public HostnameVerifier get() {
|
||||
return HttpsURLConnection.getDefaultHostnameVerifier();
|
||||
}
|
||||
});
|
||||
private Client defaultClient = new Default(new LazySSLSocketFactory(),
|
||||
new LazyHostnameVerifier());
|
||||
|
||||
private SpringClientFactory factory;
|
||||
|
||||
public FeignRibbonClient(SpringClientFactory factory) {
|
||||
@@ -44,30 +51,51 @@ public class FeignRibbonClient implements Client {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Response execute(Request request, Request.Options options) throws IOException {
|
||||
try {
|
||||
public Response execute(Request request, Request.Options options) throws IOException {
|
||||
try {
|
||||
URI asUri = URI.create(request.url());
|
||||
String clientName = asUri.getHost();
|
||||
URI uriWithoutSchemeAndPort = URI.create(request.url().replace(
|
||||
asUri.getScheme() + "://" + asUri.getHost(), ""));
|
||||
RibbonLoadBalancer.RibbonRequest ribbonRequest = new RibbonLoadBalancer.RibbonRequest(
|
||||
request, uriWithoutSchemeAndPort);
|
||||
return lbClient(clientName).executeWithLoadBalancer(ribbonRequest)
|
||||
.toResponse();
|
||||
}
|
||||
catch (ClientException ex) {
|
||||
if (ex.getCause() instanceof IOException) {
|
||||
throw IOException.class.cast(ex.getCause());
|
||||
}
|
||||
throw Throwables.propagate(ex);
|
||||
}
|
||||
}
|
||||
|
||||
URI asUri = URI.create(request.url());
|
||||
String clientName = asUri.getHost();
|
||||
URI uriWithoutSchemeAndPort = URI.create(request.url().replace(asUri.getScheme() + "://" + asUri.getHost(), ""));
|
||||
RibbonLoadBalancer.RibbonRequest ribbonRequest = new RibbonLoadBalancer.RibbonRequest(request, uriWithoutSchemeAndPort);
|
||||
return lbClient(clientName).executeWithLoadBalancer(ribbonRequest).toResponse();
|
||||
private RibbonLoadBalancer lbClient(String clientName) {
|
||||
IClientConfig config = this.factory.getClientConfig(clientName);
|
||||
ILoadBalancer lb = this.factory.getLoadBalancer(clientName);
|
||||
return new RibbonLoadBalancer(this.defaultClient, lb, config);
|
||||
}
|
||||
|
||||
} catch (ClientException e) {
|
||||
if (e.getCause() instanceof IOException) {
|
||||
throw IOException.class.cast(e.getCause());
|
||||
}
|
||||
throw Throwables.propagate(e);
|
||||
}
|
||||
}
|
||||
public void setDefaultClient(Client defaultClient) {
|
||||
this.defaultClient = defaultClient;
|
||||
}
|
||||
|
||||
private RibbonLoadBalancer lbClient(String clientName) {
|
||||
IClientConfig config = factory.getClientConfig(clientName);
|
||||
ILoadBalancer lb = factory.getLoadBalancer(clientName);
|
||||
return new RibbonLoadBalancer(defaultClient, lb, config);
|
||||
}
|
||||
private static class LazySSLSocketFactory implements Lazy<SSLSocketFactory> {
|
||||
|
||||
@Override
|
||||
public SSLSocketFactory get() {
|
||||
return (SSLSocketFactory) SSLSocketFactory.getDefault();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class LazyHostnameVerifier implements Lazy<HostnameVerifier> {
|
||||
|
||||
@Override
|
||||
public HostnameVerifier get() {
|
||||
return HttpsURLConnection.getDefaultHostnameVerifier();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void setDefaultClient(Client defaultClient) {
|
||||
this.defaultClient = defaultClient;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,19 @@
|
||||
/*
|
||||
* Copyright 2013-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.feign.ribbon;
|
||||
|
||||
import java.io.IOException;
|
||||
@@ -20,115 +36,129 @@ import feign.Request;
|
||||
import feign.RequestTemplate;
|
||||
import feign.Response;
|
||||
|
||||
public class RibbonLoadBalancer extends AbstractLoadBalancerAwareClient<RibbonLoadBalancer.RibbonRequest, RibbonLoadBalancer.RibbonResponse> {
|
||||
public class RibbonLoadBalancer
|
||||
extends
|
||||
AbstractLoadBalancerAwareClient<RibbonLoadBalancer.RibbonRequest, RibbonLoadBalancer.RibbonResponse> {
|
||||
|
||||
private final Client delegate;
|
||||
private final int connectTimeout;
|
||||
private final int readTimeout;
|
||||
private final IClientConfig clientConfig;
|
||||
private final Client delegate;
|
||||
|
||||
public RibbonLoadBalancer(Client delegate, ILoadBalancer lb, IClientConfig clientConfig) {
|
||||
super(lb, clientConfig);
|
||||
this.setRetryHandler(RetryHandler.DEFAULT);
|
||||
this.clientConfig = clientConfig;
|
||||
this.delegate = delegate;
|
||||
connectTimeout = clientConfig.get(CommonClientConfigKey.ConnectTimeout);
|
||||
readTimeout = clientConfig.get(CommonClientConfigKey.ReadTimeout);
|
||||
}
|
||||
private final int connectTimeout;
|
||||
|
||||
@Override
|
||||
public RibbonResponse execute(RibbonRequest request, IClientConfig configOverride) throws IOException {
|
||||
Request.Options options;
|
||||
if (configOverride != null) {
|
||||
options = new Request.Options(configOverride.get(CommonClientConfigKey.ConnectTimeout, connectTimeout), (configOverride.get(CommonClientConfigKey.ReadTimeout, readTimeout)));
|
||||
} else {
|
||||
options = new Request.Options(connectTimeout, readTimeout);
|
||||
}
|
||||
Response response = delegate.execute(request.toRequest(), options);
|
||||
return new RibbonResponse(request.getUri(), response);
|
||||
}
|
||||
private final int readTimeout;
|
||||
|
||||
@Override
|
||||
public RequestSpecificRetryHandler getRequestSpecificRetryHandler(
|
||||
RibbonRequest request, IClientConfig requestConfig) {
|
||||
if (clientConfig.get(CommonClientConfigKey.OkToRetryOnAllOperations, false)) {
|
||||
return new RequestSpecificRetryHandler(true, true, this.getRetryHandler(), requestConfig);
|
||||
}
|
||||
if (!request.toRequest().method().equals("GET")) {
|
||||
return new RequestSpecificRetryHandler(true, false, this.getRetryHandler(), requestConfig);
|
||||
} else {
|
||||
return new RequestSpecificRetryHandler(true, true, this.getRetryHandler(), requestConfig);
|
||||
}
|
||||
}
|
||||
private final IClientConfig clientConfig;
|
||||
|
||||
static class RibbonRequest extends ClientRequest implements Cloneable {
|
||||
public RibbonLoadBalancer(Client delegate, ILoadBalancer lb,
|
||||
IClientConfig clientConfig) {
|
||||
super(lb, clientConfig);
|
||||
this.setRetryHandler(RetryHandler.DEFAULT);
|
||||
this.clientConfig = clientConfig;
|
||||
this.delegate = delegate;
|
||||
this.connectTimeout = clientConfig.get(CommonClientConfigKey.ConnectTimeout);
|
||||
this.readTimeout = clientConfig.get(CommonClientConfigKey.ReadTimeout);
|
||||
}
|
||||
|
||||
private final Request request;
|
||||
@Override
|
||||
public RibbonResponse execute(RibbonRequest request, IClientConfig configOverride)
|
||||
throws IOException {
|
||||
Request.Options options;
|
||||
if (configOverride != null) {
|
||||
options = new Request.Options(configOverride.get(
|
||||
CommonClientConfigKey.ConnectTimeout, this.connectTimeout),
|
||||
(configOverride.get(CommonClientConfigKey.ReadTimeout,
|
||||
this.readTimeout)));
|
||||
}
|
||||
else {
|
||||
options = new Request.Options(this.connectTimeout, this.readTimeout);
|
||||
}
|
||||
Response response = this.delegate.execute(request.toRequest(), options);
|
||||
return new RibbonResponse(request.getUri(), response);
|
||||
}
|
||||
|
||||
RibbonRequest(Request request, URI uri) {
|
||||
this.request = request;
|
||||
setUri(uri);
|
||||
}
|
||||
@Override
|
||||
public RequestSpecificRetryHandler getRequestSpecificRetryHandler(
|
||||
RibbonRequest request, IClientConfig requestConfig) {
|
||||
if (this.clientConfig.get(CommonClientConfigKey.OkToRetryOnAllOperations, false)) {
|
||||
return new RequestSpecificRetryHandler(true, true, this.getRetryHandler(),
|
||||
requestConfig);
|
||||
}
|
||||
if (!request.toRequest().method().equals("GET")) {
|
||||
return new RequestSpecificRetryHandler(true, false, this.getRetryHandler(),
|
||||
requestConfig);
|
||||
}
|
||||
else {
|
||||
return new RequestSpecificRetryHandler(true, true, this.getRetryHandler(),
|
||||
requestConfig);
|
||||
}
|
||||
}
|
||||
|
||||
Request toRequest() {
|
||||
return new RequestTemplate()
|
||||
.method(request.method())
|
||||
.append(getUri().toASCIIString())
|
||||
.headers(request.headers())
|
||||
.body(request.body(), request.charset())
|
||||
.request();
|
||||
}
|
||||
static class RibbonRequest extends ClientRequest implements Cloneable {
|
||||
|
||||
public Object clone() {
|
||||
return new RibbonRequest(request, getUri());
|
||||
}
|
||||
}
|
||||
private final Request request;
|
||||
|
||||
static class RibbonResponse implements IResponse {
|
||||
RibbonRequest(Request request, URI uri) {
|
||||
this.request = request;
|
||||
setUri(uri);
|
||||
}
|
||||
|
||||
private final URI uri;
|
||||
private final Response response;
|
||||
Request toRequest() {
|
||||
return new RequestTemplate().method(this.request.method())
|
||||
.append(getUri().toASCIIString()).headers(this.request.headers())
|
||||
.body(this.request.body(), this.request.charset()).request();
|
||||
}
|
||||
|
||||
RibbonResponse(URI uri, Response response) {
|
||||
this.uri = uri;
|
||||
this.response = response;
|
||||
}
|
||||
@Override
|
||||
public Object clone() {
|
||||
return new RibbonRequest(this.request, getUri());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getPayload() throws ClientException {
|
||||
return response.body();
|
||||
}
|
||||
static class RibbonResponse implements IResponse {
|
||||
|
||||
@Override
|
||||
public boolean hasPayload() {
|
||||
return response.body() != null;
|
||||
}
|
||||
private final URI uri;
|
||||
private final Response response;
|
||||
|
||||
@Override
|
||||
public boolean isSuccess() {
|
||||
return response.status() == 200;
|
||||
}
|
||||
RibbonResponse(URI uri, Response response) {
|
||||
this.uri = uri;
|
||||
this.response = response;
|
||||
}
|
||||
|
||||
@Override
|
||||
public URI getRequestedURI() {
|
||||
return uri;
|
||||
}
|
||||
@Override
|
||||
public Object getPayload() throws ClientException {
|
||||
return this.response.body();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Collection<String>> getHeaders() {
|
||||
return response.headers();
|
||||
}
|
||||
@Override
|
||||
public boolean hasPayload() {
|
||||
return this.response.body() != null;
|
||||
}
|
||||
|
||||
Response toResponse() {
|
||||
return response;
|
||||
}
|
||||
@Override
|
||||
public boolean isSuccess() {
|
||||
return this.response.status() == 200;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
if (response != null && response.body() != null) {
|
||||
response.body().close();
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public URI getRequestedURI() {
|
||||
return this.uri;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public Map<String, Collection<String>> getHeaders() {
|
||||
return this.response.headers();
|
||||
}
|
||||
|
||||
Response toResponse() {
|
||||
return this.response;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
if (this.response != null && this.response.body() != null) {
|
||||
this.response.body().close();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,9 +1,21 @@
|
||||
package org.springframework.cloud.netflix.hystrix;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
/*
|
||||
* Copyright 2013-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.hystrix;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Inherited;
|
||||
@@ -19,9 +31,9 @@ import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
|
||||
* you want. All it does is turn on circuit breakers and let the autoconfiguration find
|
||||
* the Hystrix classes if they are available (i.e. you need Hystrix on the classpath as
|
||||
* well).
|
||||
*
|
||||
* @author Dave Syer
|
||||
*
|
||||
* @author Dave Syer
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@@ -29,4 +41,5 @@ import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
|
||||
@Inherited
|
||||
@EnableCircuitBreaker
|
||||
public @interface EnableHystrix {
|
||||
|
||||
}
|
||||
|
||||
@@ -27,7 +27,8 @@ import org.springframework.context.annotation.Configuration;
|
||||
import com.netflix.hystrix.Hystrix;
|
||||
|
||||
/**
|
||||
* Auto configuration for Hystrix
|
||||
* Auto configuration for Hystrix.
|
||||
*
|
||||
* @author Christian Dupuis
|
||||
*/
|
||||
@Configuration
|
||||
|
||||
@@ -64,7 +64,7 @@ public class HystrixCircuitBreakerConfiguration {
|
||||
@Configuration
|
||||
@ConditionalOnProperty(value = "hystrix.stream.endpoint.enabled", matchIfMissing = true)
|
||||
@ConditionalOnWebApplication
|
||||
@ConditionalOnClass({Endpoint.class, HystrixMetricsStreamServlet.class})
|
||||
@ConditionalOnClass({ Endpoint.class, HystrixMetricsStreamServlet.class })
|
||||
protected static class HystrixWebConfiguration {
|
||||
|
||||
@Bean
|
||||
@@ -75,13 +75,13 @@ public class HystrixCircuitBreakerConfiguration {
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnClass({HystrixMetricsPoller.class, GaugeService.class})
|
||||
@ConditionalOnClass({ HystrixMetricsPoller.class, GaugeService.class })
|
||||
protected static class HystrixMetricsPollerConfiguration implements SmartLifecycle {
|
||||
|
||||
private static Log logger = LogFactory
|
||||
.getLog(HystrixMetricsPollerConfiguration.class);
|
||||
|
||||
@Autowired(required=false)
|
||||
@Autowired(required = false)
|
||||
private GaugeService gauges;
|
||||
|
||||
private ObjectMapper mapper = new ObjectMapper();
|
||||
@@ -93,7 +93,7 @@ public class HystrixCircuitBreakerConfiguration {
|
||||
|
||||
@Override
|
||||
public void start() {
|
||||
if (gauges==null) {
|
||||
if (this.gauges == null) {
|
||||
return;
|
||||
}
|
||||
MetricsAsJsonPollerListener listener = new MetricsAsJsonPollerListener() {
|
||||
@@ -101,20 +101,21 @@ public class HystrixCircuitBreakerConfiguration {
|
||||
public void handleJsonMetric(String json) {
|
||||
try {
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, Object> map = mapper.readValue(json, Map.class);
|
||||
Map<String, Object> map = HystrixMetricsPollerConfiguration.this.mapper
|
||||
.readValue(json, Map.class);
|
||||
if (map != null && map.containsKey("type")) {
|
||||
addMetrics(map, "hystrix.");
|
||||
}
|
||||
}
|
||||
catch (IOException e) {
|
||||
catch (IOException ex) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
poller = new HystrixMetricsPoller(listener, 2000);
|
||||
this.poller = new HystrixMetricsPoller(listener, 2000);
|
||||
// start polling and it will write directly to the listener
|
||||
poller.start();
|
||||
this.poller.start();
|
||||
logger.info("Starting poller");
|
||||
}
|
||||
|
||||
@@ -130,10 +131,10 @@ public class HystrixCircuitBreakerConfiguration {
|
||||
String prefix = prefixBuilder.toString();
|
||||
for (String key : map.keySet()) {
|
||||
Object value = map.get(key);
|
||||
if (!reserved.contains(key)) {
|
||||
if (!this.reserved.contains(key)) {
|
||||
if (value instanceof Number) {
|
||||
String name = prefix + "." + key;
|
||||
gauges.submit(name, ((Number) value).doubleValue());
|
||||
this.gauges.submit(name, ((Number) value).doubleValue());
|
||||
}
|
||||
else if (value instanceof Map) {
|
||||
@SuppressWarnings("unchecked")
|
||||
@@ -146,14 +147,14 @@ public class HystrixCircuitBreakerConfiguration {
|
||||
|
||||
@Override
|
||||
public void stop() {
|
||||
if (poller != null) {
|
||||
poller.shutdown();
|
||||
if (this.poller != null) {
|
||||
this.poller.shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRunning() {
|
||||
return poller != null ? poller.isRunning() : false;
|
||||
return this.poller != null ? this.poller.isRunning() : false;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -168,8 +169,8 @@ public class HystrixCircuitBreakerConfiguration {
|
||||
|
||||
@Override
|
||||
public void stop(Runnable callback) {
|
||||
if (poller != null) {
|
||||
poller.shutdown();
|
||||
if (this.poller != null) {
|
||||
this.poller.shutdown();
|
||||
}
|
||||
callback.run();
|
||||
}
|
||||
@@ -189,4 +190,5 @@ public class HystrixCircuitBreakerConfiguration {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -28,34 +28,37 @@ import com.netflix.hystrix.HystrixCircuitBreaker;
|
||||
import com.netflix.hystrix.HystrixCommandMetrics;
|
||||
|
||||
/**
|
||||
* A {@link HealthIndicator} implementation for Hystrix circuit breakers.
|
||||
* A {@link HealthIndicator} implementation for Hystrix circuit breakers.
|
||||
* <p>
|
||||
* This default implementation will set the system to <code>OUT_OF_SERVICE</code> and
|
||||
* include all open circuits by name.
|
||||
*
|
||||
* This default implementation will set the system to <code>OUT_OF_SERVICE</code> and
|
||||
* include all open circuits by name.
|
||||
*
|
||||
* @author Christian Dupuis
|
||||
*/
|
||||
public class HystrixHealthIndicator extends AbstractHealthIndicator {
|
||||
|
||||
/** Status code for open circuits */
|
||||
private static final Status CIRCUIT_OPEN = new Status("CIRCUIT_OPEN");
|
||||
|
||||
private static final Status CIRCUIT_OPEN = new Status("CIRCUIT_OPEN");
|
||||
|
||||
@Override
|
||||
protected void doHealthCheck(Builder builder) throws Exception {
|
||||
List<String> openCircuitBreakers = new ArrayList<String>();
|
||||
|
||||
|
||||
// Collect all open circuit breakers from Hystrix
|
||||
for (HystrixCommandMetrics metrics : HystrixCommandMetrics.getInstances()) {
|
||||
HystrixCircuitBreaker circuitBreaker = HystrixCircuitBreaker.Factory.getInstance(metrics.getCommandKey());
|
||||
HystrixCircuitBreaker circuitBreaker = HystrixCircuitBreaker.Factory
|
||||
.getInstance(metrics.getCommandKey());
|
||||
if (circuitBreaker.isOpen()) {
|
||||
openCircuitBreakers.add(metrics.getCommandGroup().name() + "::" + metrics.getCommandKey().name());
|
||||
openCircuitBreakers.add(metrics.getCommandGroup().name() + "::"
|
||||
+ metrics.getCommandKey().name());
|
||||
}
|
||||
}
|
||||
|
||||
// If there is at least one open circuit report OUT_OF_SERVICE adding the command group
|
||||
|
||||
// If there is at least one open circuit report OUT_OF_SERVICE adding the command
|
||||
// group
|
||||
// and key name
|
||||
if (openCircuitBreakers.size() > 0) {
|
||||
builder.status(CIRCUIT_OPEN).withDetail("openCircuitBreakers", openCircuitBreakers);
|
||||
builder.status(CIRCUIT_OPEN).withDetail("openCircuitBreakers",
|
||||
openCircuitBreakers);
|
||||
}
|
||||
else {
|
||||
builder.up();
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.hystrix;
|
||||
|
||||
import org.springframework.cloud.netflix.endpoint.ServletWrappingEndpoint;
|
||||
@@ -24,7 +25,9 @@ import com.netflix.hystrix.contrib.metrics.eventstream.HystrixMetricsStreamServl
|
||||
*/
|
||||
public class HystrixStreamEndpoint extends ServletWrappingEndpoint {
|
||||
|
||||
public HystrixStreamEndpoint() {
|
||||
super(HystrixMetricsStreamServlet.class, "hystrixStream", "/hystrix.stream", false, true);
|
||||
}
|
||||
public HystrixStreamEndpoint() {
|
||||
super(HystrixMetricsStreamServlet.class, "hystrixStream", "/hystrix.stream",
|
||||
false, true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,3 +1,19 @@
|
||||
/*
|
||||
* Copyright 2013-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.ribbon;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -17,27 +33,28 @@ import org.springframework.web.client.RestTemplate;
|
||||
import com.netflix.client.IClient;
|
||||
|
||||
/**
|
||||
* Auto configuration for Ribbon (client side load balancing)
|
||||
* Auto configuration for Ribbon (client side load balancing).
|
||||
*
|
||||
* @author Spencer Gibb
|
||||
* @author Dave Syer
|
||||
*/
|
||||
@Configuration
|
||||
@ConditionalOnClass({IClient.class, RestTemplate.class})
|
||||
@ConditionalOnClass({ IClient.class, RestTemplate.class })
|
||||
@RibbonClients
|
||||
@AutoConfigureAfter(EurekaClientAutoConfiguration.class)
|
||||
public class RibbonAutoConfiguration {
|
||||
|
||||
@Autowired(required=false)
|
||||
private List<RibbonClientSpecification> configurations = new ArrayList<>();
|
||||
@Autowired(required = false)
|
||||
private List<RibbonClientSpecification> configurations = new ArrayList<>();
|
||||
|
||||
@Bean
|
||||
public SpringClientFactory springClientFactory() {
|
||||
SpringClientFactory factory = new SpringClientFactory();
|
||||
factory.setConfigurations(configurations);
|
||||
public SpringClientFactory springClientFactory() {
|
||||
SpringClientFactory factory = new SpringClientFactory();
|
||||
factory.setConfigurations(this.configurations);
|
||||
return factory;
|
||||
}
|
||||
}
|
||||
|
||||
@Bean
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(RestTemplate.class)
|
||||
public RestTemplate restTemplate(RibbonInterceptor ribbonInterceptor) {
|
||||
RestTemplate restTemplate = new RestTemplate();
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.ribbon;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
@@ -26,7 +27,6 @@ import org.springframework.context.annotation.Import;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
@Configuration
|
||||
@Import(RibbonClientConfigurationRegistrar.class)
|
||||
@@ -34,7 +34,11 @@ import org.springframework.context.annotation.Import;
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
public @interface RibbonClient {
|
||||
|
||||
String value() default "";
|
||||
|
||||
String name() default "";
|
||||
|
||||
Class<?>[] configuration() default {};
|
||||
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.ribbon;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
@@ -36,7 +37,6 @@ import com.netflix.servo.monitor.Monitors;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
@Configuration
|
||||
@@ -51,12 +51,12 @@ public class RibbonClientConfiguration {
|
||||
|
||||
// TODO: maybe re-instate autowired load balancers: identified by name they could be
|
||||
// associated with ribbon clients
|
||||
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public IClientConfig ribbonClientConfig() {
|
||||
DefaultClientConfigImpl config = new DefaultClientConfigImpl();
|
||||
config.loadProperties(name);
|
||||
config.loadProperties(this.name);
|
||||
return config;
|
||||
}
|
||||
|
||||
@@ -65,20 +65,21 @@ public class RibbonClientConfiguration {
|
||||
public RestClient ribbonRestClient(IClientConfig config, ILoadBalancer loadBalancer) {
|
||||
RestClient client = new RestClient(config);
|
||||
client.setLoadBalancer(loadBalancer);
|
||||
Monitors.registerObject("Client_" + name, client);
|
||||
Monitors.registerObject("Client_" + this.name, client);
|
||||
return client;
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
//TODO: move to ribbon.eureka package
|
||||
public ILoadBalancer ribbonLoadBalancer(IClientConfig config, ServerListFilter<Server> filter) {
|
||||
// TODO: move to ribbon.eureka package
|
||||
public ILoadBalancer ribbonLoadBalancer(IClientConfig config,
|
||||
ServerListFilter<Server> filter) {
|
||||
ZoneAwareLoadBalancer<Server> balancer = new ZoneAwareLoadBalancer<>(config);
|
||||
wrapServerList(balancer);
|
||||
balancer.setFilter(filter);
|
||||
return balancer;
|
||||
}
|
||||
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public ServerListFilter<Server> ribbonServerListFilter(IClientConfig config) {
|
||||
@@ -86,10 +87,11 @@ public class RibbonClientConfiguration {
|
||||
filter.initWithNiwsConfig(config);
|
||||
return filter;
|
||||
}
|
||||
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public RibbonLoadBalancerContext ribbonLoadBalancerContext(ILoadBalancer loadBalancer, IClientConfig config) {
|
||||
public RibbonLoadBalancerContext ribbonLoadBalancerContext(
|
||||
ILoadBalancer loadBalancer, IClientConfig config) {
|
||||
return new RibbonLoadBalancerContext(loadBalancer, config);
|
||||
}
|
||||
|
||||
@@ -104,7 +106,7 @@ public class RibbonClientConfiguration {
|
||||
// metadata *is* available.
|
||||
// @see com.netflix.appinfo.AmazonInfo.Builder
|
||||
dynamic.setServerListImpl(new DomainExtractingServerList(list, dynamic
|
||||
.getClientConfig(), approximateZoneFromHostname));
|
||||
.getClientConfig(), this.approximateZoneFromHostname));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.ribbon;
|
||||
|
||||
import java.util.Map;
|
||||
@@ -26,7 +27,6 @@ import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
public class RibbonClientConfigurationRegistrar implements ImportBeanDefinitionRegistrar {
|
||||
|
||||
@@ -56,7 +56,7 @@ public class RibbonClientConfigurationRegistrar implements ImportBeanDefinitionR
|
||||
}
|
||||
|
||||
private String getClientName(Map<String, Object> client) {
|
||||
if (client==null) {
|
||||
if (client == null) {
|
||||
return null;
|
||||
}
|
||||
String value = (String) client.get("value");
|
||||
@@ -67,7 +67,8 @@ public class RibbonClientConfigurationRegistrar implements ImportBeanDefinitionR
|
||||
if (value != null && StringUtils.hasText(value)) {
|
||||
return value;
|
||||
}
|
||||
throw new IllegalStateException("Either 'name' or 'value' must be provided in @RibbonClient");
|
||||
throw new IllegalStateException(
|
||||
"Either 'name' or 'value' must be provided in @RibbonClient");
|
||||
}
|
||||
|
||||
private void registerClientConfiguration(BeanDefinitionRegistry registry,
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.ribbon;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
@@ -20,13 +21,13 @@ import lombok.Data;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
public class RibbonClientSpecification {
|
||||
|
||||
private String name;
|
||||
|
||||
private Class<?>[] configuration;
|
||||
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.ribbon;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
@@ -27,9 +28,8 @@ import org.springframework.context.annotation.Import;
|
||||
/**
|
||||
* Convenience annotation that allows user to combine multiple <code>@RibbonClient</code>
|
||||
* annotations on a single class (including in Java 7).
|
||||
*
|
||||
* @author Dave Syer
|
||||
*
|
||||
* @author Dave Syer
|
||||
*/
|
||||
@Configuration
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
|
||||
@@ -1,5 +1,24 @@
|
||||
/*
|
||||
* Copyright 2013-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.ribbon;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
|
||||
import org.springframework.cloud.client.ServiceInstance;
|
||||
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
|
||||
import org.springframework.cloud.client.loadbalancer.LoadBalancerRequest;
|
||||
@@ -9,36 +28,52 @@ import org.springframework.http.client.ClientHttpRequestInterceptor;
|
||||
import org.springframework.http.client.ClientHttpResponse;
|
||||
import org.springframework.http.client.support.HttpRequestWrapper;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
public class RibbonInterceptor implements ClientHttpRequestInterceptor {
|
||||
|
||||
private LoadBalancerClient loadBalancer;
|
||||
private LoadBalancerClient loadBalancer;
|
||||
|
||||
public RibbonInterceptor(LoadBalancerClient loadBalancer) {
|
||||
this.loadBalancer = loadBalancer;
|
||||
}
|
||||
public RibbonInterceptor(LoadBalancerClient loadBalancer) {
|
||||
this.loadBalancer = loadBalancer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClientHttpResponse intercept(final HttpRequest request, final byte[] body,
|
||||
final ClientHttpRequestExecution execution) throws IOException {
|
||||
final URI originalUri = request.getURI();
|
||||
String serviceName = originalUri.getHost();
|
||||
return this.loadBalancer.execute(serviceName,
|
||||
new LoadBalancerRequest<ClientHttpResponse>() {
|
||||
|
||||
@Override
|
||||
public ClientHttpResponse apply(final ServiceInstance instance)
|
||||
throws Exception {
|
||||
HttpRequest serviceRequest = new ServiceRequestWrapper(request,
|
||||
instance);
|
||||
return execution.execute(serviceRequest, body);
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
private class ServiceRequestWrapper extends HttpRequestWrapper {
|
||||
|
||||
private final ServiceInstance instance;
|
||||
|
||||
public ServiceRequestWrapper(HttpRequest request, ServiceInstance instance) {
|
||||
super(request);
|
||||
this.instance = instance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public URI getURI() {
|
||||
URI uri = RibbonInterceptor.this.loadBalancer.reconstructURI(this.instance,
|
||||
getRequest().getURI());
|
||||
return uri;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClientHttpResponse intercept(final HttpRequest request, final byte[] body, final ClientHttpRequestExecution execution) throws IOException {
|
||||
final URI originalUri = request.getURI();
|
||||
String serviceName = originalUri.getHost();
|
||||
return loadBalancer.execute(serviceName, new LoadBalancerRequest<ClientHttpResponse>() {
|
||||
@Override
|
||||
public ClientHttpResponse apply(final ServiceInstance instance) throws Exception {
|
||||
HttpRequestWrapper wrapper = new HttpRequestWrapper(request) {
|
||||
@Override
|
||||
public URI getURI() {
|
||||
URI uri = loadBalancer.reconstructURI(instance, originalUri);
|
||||
return uri;
|
||||
}
|
||||
};
|
||||
return execution.execute(wrapper, body);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,19 @@
|
||||
/*
|
||||
* Copyright 2013-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.ribbon;
|
||||
|
||||
import java.net.URI;
|
||||
@@ -19,72 +35,75 @@ import com.netflix.servo.monitor.Stopwatch;
|
||||
*/
|
||||
public class RibbonLoadBalancerClient implements LoadBalancerClient {
|
||||
|
||||
private SpringClientFactory clientFactory;
|
||||
private SpringClientFactory clientFactory;
|
||||
|
||||
public RibbonLoadBalancerClient(SpringClientFactory clientFactory) {
|
||||
this.clientFactory = clientFactory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public URI reconstructURI(ServiceInstance instance, URI original) {
|
||||
String serviceId = instance.getServiceId();
|
||||
RibbonLoadBalancerContext context = clientFactory.getLoadBalancerContext(serviceId);
|
||||
Server server = new Server(instance.getHost(), instance.getPort());
|
||||
return context.reconstructURIWithServer(server, original);
|
||||
}
|
||||
@Override
|
||||
public URI reconstructURI(ServiceInstance instance, URI original) {
|
||||
String serviceId = instance.getServiceId();
|
||||
RibbonLoadBalancerContext context = this.clientFactory
|
||||
.getLoadBalancerContext(serviceId);
|
||||
Server server = new Server(instance.getHost(), instance.getPort());
|
||||
return context.reconstructURIWithServer(server, original);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Override
|
||||
public ServiceInstance choose(String serviceId) {
|
||||
return new RibbonServer(serviceId, getServer(serviceId));
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T execute(String serviceId, LoadBalancerRequest<T> request) {
|
||||
ILoadBalancer loadBalancer = getLoadBalancer(serviceId);
|
||||
RibbonLoadBalancerContext context = clientFactory.getLoadBalancerContext(serviceId);
|
||||
Server server = getServer(serviceId, loadBalancer);
|
||||
RibbonServer ribbonServer = new RibbonServer(serviceId, server);
|
||||
@Override
|
||||
public <T> T execute(String serviceId, LoadBalancerRequest<T> request) {
|
||||
ILoadBalancer loadBalancer = getLoadBalancer(serviceId);
|
||||
RibbonLoadBalancerContext context = this.clientFactory
|
||||
.getLoadBalancerContext(serviceId);
|
||||
Server server = getServer(serviceId, loadBalancer);
|
||||
RibbonServer ribbonServer = new RibbonServer(serviceId, server);
|
||||
|
||||
ServerStats serverStats = context.getServerStats(server);
|
||||
context.noteOpenConnection(serverStats);
|
||||
Stopwatch tracer = context.getExecuteTracer().start();
|
||||
ServerStats serverStats = context.getServerStats(server);
|
||||
context.noteOpenConnection(serverStats);
|
||||
Stopwatch tracer = context.getExecuteTracer().start();
|
||||
|
||||
try {
|
||||
try {
|
||||
T returnVal = request.apply(ribbonServer);
|
||||
recordStats(context, tracer, serverStats, returnVal, null);
|
||||
return returnVal;
|
||||
}
|
||||
catch (Exception ex) {
|
||||
recordStats(context, tracer, serverStats, null, ex);
|
||||
Throwables.propagate(ex);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
T returnVal = request.apply(ribbonServer);
|
||||
recordStats(context, tracer, serverStats, returnVal, null);
|
||||
return returnVal;
|
||||
} catch (Exception e) {
|
||||
recordStats(context, tracer, serverStats, null, e);
|
||||
Throwables.propagate(e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
private void recordStats(RibbonLoadBalancerContext context, Stopwatch tracer,
|
||||
ServerStats serverStats, Object entity, Throwable exception) {
|
||||
tracer.stop();
|
||||
long duration = tracer.getDuration(TimeUnit.MILLISECONDS);
|
||||
context.noteRequestCompletion(serverStats, entity, exception, duration, null/* errorHandler */);
|
||||
}
|
||||
|
||||
private void recordStats(RibbonLoadBalancerContext context, Stopwatch tracer, ServerStats serverStats, Object entity, Throwable exception) {
|
||||
tracer.stop();
|
||||
long duration = tracer.getDuration(TimeUnit.MILLISECONDS);
|
||||
context.noteRequestCompletion(serverStats, entity, exception, duration, null/*errorHandler*/);
|
||||
}
|
||||
protected Server getServer(String serviceId) {
|
||||
return getServer(serviceId, getLoadBalancer(serviceId));
|
||||
}
|
||||
|
||||
protected Server getServer(String serviceId) {
|
||||
return getServer(serviceId, getLoadBalancer(serviceId));
|
||||
}
|
||||
protected Server getServer(String serviceId, ILoadBalancer loadBalancer) {
|
||||
Server server = loadBalancer.chooseServer("default");
|
||||
if (server == null) {
|
||||
throw new IllegalStateException(
|
||||
"Unable to locate ILoadBalancer for service: " + serviceId);
|
||||
}
|
||||
return server;
|
||||
}
|
||||
|
||||
protected Server getServer(String serviceId, ILoadBalancer loadBalancer) {
|
||||
Server server = loadBalancer.chooseServer("default");
|
||||
if (server == null) {
|
||||
throw new IllegalStateException(
|
||||
"Unable to locate ILoadBalancer for service: " + serviceId);
|
||||
}
|
||||
return server;
|
||||
}
|
||||
protected ILoadBalancer getLoadBalancer(String serviceId) {
|
||||
return this.clientFactory.getLoadBalancer(serviceId);
|
||||
}
|
||||
|
||||
protected ILoadBalancer getLoadBalancer(String serviceId) {
|
||||
return clientFactory.getLoadBalancer(serviceId);
|
||||
}
|
||||
|
||||
protected static class RibbonServer implements ServiceInstance {
|
||||
protected static class RibbonServer implements ServiceInstance {
|
||||
protected String serviceId;
|
||||
protected Server server;
|
||||
|
||||
@@ -95,17 +114,19 @@ public class RibbonLoadBalancerClient implements LoadBalancerClient {
|
||||
|
||||
@Override
|
||||
public String getServiceId() {
|
||||
return serviceId;
|
||||
return this.serviceId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHost() {
|
||||
return server.getHost();
|
||||
return this.server.getHost();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPort() {
|
||||
return server.getPort();
|
||||
return this.server.getPort();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,3 +1,19 @@
|
||||
/*
|
||||
* Copyright 2013-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.ribbon;
|
||||
|
||||
import com.netflix.client.RetryHandler;
|
||||
@@ -11,35 +27,39 @@ import com.netflix.servo.monitor.Timer;
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
public class RibbonLoadBalancerContext extends LoadBalancerContext {
|
||||
public RibbonLoadBalancerContext(ILoadBalancer lb) {
|
||||
super(lb);
|
||||
}
|
||||
public RibbonLoadBalancerContext(ILoadBalancer lb) {
|
||||
super(lb);
|
||||
}
|
||||
|
||||
public RibbonLoadBalancerContext(ILoadBalancer lb, IClientConfig clientConfig) {
|
||||
super(lb, clientConfig);
|
||||
}
|
||||
public RibbonLoadBalancerContext(ILoadBalancer lb, IClientConfig clientConfig) {
|
||||
super(lb, clientConfig);
|
||||
}
|
||||
|
||||
public RibbonLoadBalancerContext(ILoadBalancer lb, IClientConfig clientConfig, RetryHandler handler) {
|
||||
super(lb, clientConfig, handler);
|
||||
}
|
||||
public RibbonLoadBalancerContext(ILoadBalancer lb, IClientConfig clientConfig,
|
||||
RetryHandler handler) {
|
||||
super(lb, clientConfig, handler);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void noteOpenConnection(ServerStats serverStats) {
|
||||
super.noteOpenConnection(serverStats);
|
||||
}
|
||||
@Override
|
||||
public void noteOpenConnection(ServerStats serverStats) {
|
||||
super.noteOpenConnection(serverStats);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Timer getExecuteTracer() {
|
||||
return super.getExecuteTracer();
|
||||
}
|
||||
@Override
|
||||
public Timer getExecuteTracer() {
|
||||
return super.getExecuteTracer();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void noteRequestCompletion(ServerStats stats, Object response, Throwable e, long responseTime) {
|
||||
super.noteRequestCompletion(stats, response, e, responseTime);
|
||||
}
|
||||
@Override
|
||||
public void noteRequestCompletion(ServerStats stats, Object response, Throwable e,
|
||||
long responseTime) {
|
||||
super.noteRequestCompletion(stats, response, e, responseTime);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void noteRequestCompletion(ServerStats stats, Object response, Throwable e,
|
||||
long responseTime, RetryHandler errorHandler) {
|
||||
super.noteRequestCompletion(stats, response, e, responseTime, errorHandler);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void noteRequestCompletion(ServerStats stats, Object response, Throwable e, long responseTime, RetryHandler errorHandler) {
|
||||
super.noteRequestCompletion(stats, response, e, responseTime, errorHandler);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,19 @@
|
||||
/*
|
||||
* Copyright 2013-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.ribbon;
|
||||
|
||||
import java.util.Collection;
|
||||
@@ -27,18 +43,22 @@ import com.netflix.loadbalancer.ILoadBalancer;
|
||||
* creates a Spring ApplicationContext per client name, and extracts the beans that it
|
||||
* needs from there.
|
||||
*
|
||||
* @author Spencer Gibb
|
||||
* @author Dave Syer
|
||||
*/
|
||||
public class SpringClientFactory implements DisposableBean, ApplicationContextAware {
|
||||
|
||||
private Map<String, AnnotationConfigApplicationContext> contexts = new ConcurrentHashMap<>();
|
||||
|
||||
private Map<String, RibbonClientSpecification> configurations = new ConcurrentHashMap<>();
|
||||
|
||||
private ApplicationContext parent;
|
||||
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext parent) throws BeansException {
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
|
||||
public void setConfigurations(List<RibbonClientSpecification> configurations) {
|
||||
for (RibbonClientSpecification client : configurations) {
|
||||
this.configurations.put(client.getName(), client);
|
||||
@@ -47,8 +67,8 @@ public class SpringClientFactory implements DisposableBean, ApplicationContextAw
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
Collection<AnnotationConfigApplicationContext> values = contexts.values();
|
||||
contexts.clear();
|
||||
Collection<AnnotationConfigApplicationContext> values = this.contexts.values();
|
||||
this.contexts.clear();
|
||||
for (AnnotationConfigApplicationContext context : values) {
|
||||
context.close();
|
||||
}
|
||||
@@ -56,7 +76,6 @@ public class SpringClientFactory implements DisposableBean, ApplicationContextAw
|
||||
|
||||
/**
|
||||
* Get the rest client associated with the name.
|
||||
*
|
||||
* @throws RuntimeException if any error occurs
|
||||
*/
|
||||
public <C extends IClient<?, ?>> C getClient(String name, Class<C> clientClass) {
|
||||
@@ -65,7 +84,6 @@ public class SpringClientFactory implements DisposableBean, ApplicationContextAw
|
||||
|
||||
/**
|
||||
* Get the load balancer associated with the name.
|
||||
*
|
||||
* @throws RuntimeException if any error occurs
|
||||
*/
|
||||
public ILoadBalancer getLoadBalancer(String name) {
|
||||
@@ -74,7 +92,6 @@ public class SpringClientFactory implements DisposableBean, ApplicationContextAw
|
||||
|
||||
/**
|
||||
* Get the client config associated with the name.
|
||||
*
|
||||
* @throws RuntimeException if any error occurs
|
||||
*/
|
||||
public IClientConfig getClientConfig(String name) {
|
||||
@@ -83,7 +100,6 @@ public class SpringClientFactory implements DisposableBean, ApplicationContextAw
|
||||
|
||||
/**
|
||||
* Get the load balancer context associated with the name.
|
||||
*
|
||||
* @throws RuntimeException if any error occurs
|
||||
*/
|
||||
public RibbonLoadBalancerContext getLoadBalancerContext(String serviceId) {
|
||||
@@ -91,28 +107,30 @@ public class SpringClientFactory implements DisposableBean, ApplicationContextAw
|
||||
}
|
||||
|
||||
private AnnotationConfigApplicationContext getContext(String name) {
|
||||
if (!contexts.containsKey(name)) {
|
||||
synchronized (contexts) {
|
||||
if (!contexts.containsKey(name)) {
|
||||
contexts.put(name, createContext(name));
|
||||
if (!this.contexts.containsKey(name)) {
|
||||
synchronized (this.contexts) {
|
||||
if (!this.contexts.containsKey(name)) {
|
||||
this.contexts.put(name, createContext(name));
|
||||
}
|
||||
}
|
||||
}
|
||||
return contexts.get(name);
|
||||
return this.contexts.get(name);
|
||||
}
|
||||
|
||||
private AnnotationConfigApplicationContext createContext(String name) {
|
||||
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
|
||||
if (configurations.containsKey(name)) {
|
||||
for (Class<?> configuration : configurations.get(name).getConfiguration()) {
|
||||
if (this.configurations.containsKey(name)) {
|
||||
for (Class<?> configuration : this.configurations.get(name)
|
||||
.getConfiguration()) {
|
||||
context.register(configuration);
|
||||
}
|
||||
}
|
||||
for (Entry<String, RibbonClientSpecification> entry : configurations.entrySet()) {
|
||||
for (Entry<String, RibbonClientSpecification> entry : this.configurations
|
||||
.entrySet()) {
|
||||
if (entry.getKey().startsWith("default.")) {
|
||||
for (Class<?> configuration : entry.getValue().getConfiguration()) {
|
||||
context.register(configuration);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
context.register(PropertyPlaceholderAutoConfiguration.class,
|
||||
@@ -123,9 +141,9 @@ public class SpringClientFactory implements DisposableBean, ApplicationContextAw
|
||||
new MapPropertySource("ribbon",
|
||||
Collections.<String, Object> singletonMap(
|
||||
"ribbon.client.name", name)));
|
||||
if (parent != null) {
|
||||
if (this.parent != null) {
|
||||
// Uses Environment from parent as well as beans
|
||||
context.setParent(parent);
|
||||
context.setParent(this.parent);
|
||||
}
|
||||
context.refresh();
|
||||
return context;
|
||||
@@ -151,7 +169,8 @@ public class SpringClientFactory implements DisposableBean, ApplicationContextAw
|
||||
result = BeanUtils.instantiate(clazz);
|
||||
}
|
||||
}
|
||||
catch (Throwable e) { // NOPMD
|
||||
catch (Throwable ex) {
|
||||
// NOPMD
|
||||
}
|
||||
}
|
||||
context.getAutowireCapableBeanFactory().autowireBean(result);
|
||||
|
||||
@@ -13,111 +13,117 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.ribbon.eureka;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.netflix.client.config.CommonClientConfigKey;
|
||||
import com.netflix.client.config.IClientConfig;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import com.netflix.appinfo.InstanceInfo;
|
||||
import com.netflix.client.config.CommonClientConfigKey;
|
||||
import com.netflix.client.config.IClientConfig;
|
||||
import com.netflix.loadbalancer.Server;
|
||||
import com.netflix.loadbalancer.ServerList;
|
||||
import com.netflix.niws.loadbalancer.DiscoveryEnabledServer;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
public class DomainExtractingServerList implements ServerList<Server> {
|
||||
|
||||
private ServerList<Server> list;
|
||||
private IClientConfig clientConfig;
|
||||
private ServerList<Server> list;
|
||||
|
||||
private IClientConfig clientConfig;
|
||||
|
||||
private boolean approximateZoneFromHostname;
|
||||
|
||||
public DomainExtractingServerList(ServerList<Server> list, IClientConfig clientConfig, boolean approximateZoneFromHostname) {
|
||||
this.list = list;
|
||||
this.clientConfig = clientConfig;
|
||||
public DomainExtractingServerList(ServerList<Server> list,
|
||||
IClientConfig clientConfig, boolean approximateZoneFromHostname) {
|
||||
this.list = list;
|
||||
this.clientConfig = clientConfig;
|
||||
this.approximateZoneFromHostname = approximateZoneFromHostname;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Server> getInitialListOfServers() {
|
||||
List<Server> servers = setZones(list.getInitialListOfServers());
|
||||
return servers;
|
||||
}
|
||||
@Override
|
||||
public List<Server> getInitialListOfServers() {
|
||||
List<Server> servers = setZones(this.list.getInitialListOfServers());
|
||||
return servers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Server> getUpdatedListOfServers() {
|
||||
List<Server> servers = setZones(list.getUpdatedListOfServers());
|
||||
return servers;
|
||||
}
|
||||
@Override
|
||||
public List<Server> getUpdatedListOfServers() {
|
||||
List<Server> servers = setZones(this.list.getUpdatedListOfServers());
|
||||
return servers;
|
||||
}
|
||||
|
||||
private List<Server> setZones(List<Server> servers) {
|
||||
List<Server> result = new ArrayList<>();
|
||||
boolean isSecure = clientConfig.getPropertyAsBoolean(CommonClientConfigKey.IsSecure, Boolean.TRUE);
|
||||
boolean shouldUseIpAddr = clientConfig.getPropertyAsBoolean(CommonClientConfigKey.UseIPAddrForServer, Boolean.FALSE);
|
||||
for (Server server : servers) {
|
||||
if (server instanceof DiscoveryEnabledServer) {
|
||||
result.add(new DomainExtractingServer((DiscoveryEnabledServer) server,
|
||||
isSecure, shouldUseIpAddr, approximateZoneFromHostname));
|
||||
}
|
||||
else {
|
||||
result.add(server);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
private List<Server> setZones(List<Server> servers) {
|
||||
List<Server> result = new ArrayList<>();
|
||||
boolean isSecure = this.clientConfig.getPropertyAsBoolean(
|
||||
CommonClientConfigKey.IsSecure, Boolean.TRUE);
|
||||
boolean shouldUseIpAddr = this.clientConfig.getPropertyAsBoolean(
|
||||
CommonClientConfigKey.UseIPAddrForServer, Boolean.FALSE);
|
||||
for (Server server : servers) {
|
||||
if (server instanceof DiscoveryEnabledServer) {
|
||||
result.add(new DomainExtractingServer((DiscoveryEnabledServer) server,
|
||||
isSecure, shouldUseIpAddr, this.approximateZoneFromHostname));
|
||||
}
|
||||
else {
|
||||
result.add(server);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class DomainExtractingServer extends DiscoveryEnabledServer {
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
private String id;
|
||||
@Getter
|
||||
@Setter
|
||||
private String id;
|
||||
|
||||
public DomainExtractingServer(DiscoveryEnabledServer server, boolean useSecurePort, boolean useIpAddr, boolean approximateZoneFromHostname) {
|
||||
//host and port are set in super()
|
||||
super(server.getInstanceInfo(), useSecurePort, useIpAddr);
|
||||
public DomainExtractingServer(DiscoveryEnabledServer server, boolean useSecurePort,
|
||||
boolean useIpAddr, boolean approximateZoneFromHostname) {
|
||||
// host and port are set in super()
|
||||
super(server.getInstanceInfo(), useSecurePort, useIpAddr);
|
||||
if (approximateZoneFromHostname) {
|
||||
setZone(extractApproximateZone(server));
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
setZone(server.getZone());
|
||||
}
|
||||
setId(extractId(server));
|
||||
setId(extractId(server));
|
||||
setAlive(server.isAlive());
|
||||
setReadyToServe(server.isReadyToServe());
|
||||
}
|
||||
}
|
||||
|
||||
private String extractId(Server server) {
|
||||
if (server instanceof DiscoveryEnabledServer) {
|
||||
DiscoveryEnabledServer enabled = (DiscoveryEnabledServer) server;
|
||||
InstanceInfo instance = enabled.getInstanceInfo();
|
||||
if (instance.getMetadata().containsKey("instanceId")) {
|
||||
return instance.getMetadata().get("instanceId");
|
||||
}
|
||||
}
|
||||
return super.getId();
|
||||
}
|
||||
private String extractId(Server server) {
|
||||
if (server instanceof DiscoveryEnabledServer) {
|
||||
DiscoveryEnabledServer enabled = (DiscoveryEnabledServer) server;
|
||||
InstanceInfo instance = enabled.getInstanceInfo();
|
||||
if (instance.getMetadata().containsKey("instanceId")) {
|
||||
return instance.getMetadata().get("instanceId");
|
||||
}
|
||||
}
|
||||
return super.getId();
|
||||
}
|
||||
|
||||
private String extractApproximateZone(Server server) {
|
||||
String host = server.getHost();
|
||||
if (!host.contains(".")) {
|
||||
return host;
|
||||
}
|
||||
String[] split = StringUtils.split(host, ".");
|
||||
StringBuilder builder = new StringBuilder(split[1]);
|
||||
for (int i = 2; i < split.length; i++) {
|
||||
builder.append(".").append(split[i]);
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
private String extractApproximateZone(Server server) {
|
||||
String host = server.getHost();
|
||||
if (!host.contains(".")) {
|
||||
return host;
|
||||
}
|
||||
String[] split = StringUtils.split(host, ".");
|
||||
StringBuilder builder = new StringBuilder(split[1]);
|
||||
for (int i = 2; i < split.length; i++) {
|
||||
builder.append(".").append(split[i]);
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,10 +1,20 @@
|
||||
package org.springframework.cloud.netflix.ribbon.eureka;
|
||||
/*
|
||||
* Copyright 2013-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import static com.netflix.client.config.CommonClientConfigKey.DeploymentContextBasedVipAddresses;
|
||||
import static com.netflix.client.config.CommonClientConfigKey.EnableZoneAffinity;
|
||||
import static com.netflix.client.config.CommonClientConfigKey.NFLoadBalancerRuleClassName;
|
||||
import static com.netflix.client.config.CommonClientConfigKey.NIWSServerListClassName;
|
||||
import static com.netflix.client.config.CommonClientConfigKey.NIWSServerListFilterClassName;
|
||||
package org.springframework.cloud.netflix.ribbon.eureka;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
|
||||
@@ -20,11 +30,17 @@ import com.netflix.discovery.EurekaClientConfig;
|
||||
import com.netflix.loadbalancer.ZoneAvoidanceRule;
|
||||
import com.netflix.niws.loadbalancer.DiscoveryEnabledNIWSServerList;
|
||||
|
||||
import static com.netflix.client.config.CommonClientConfigKey.DeploymentContextBasedVipAddresses;
|
||||
import static com.netflix.client.config.CommonClientConfigKey.EnableZoneAffinity;
|
||||
import static com.netflix.client.config.CommonClientConfigKey.NFLoadBalancerRuleClassName;
|
||||
import static com.netflix.client.config.CommonClientConfigKey.NIWSServerListClassName;
|
||||
import static com.netflix.client.config.CommonClientConfigKey.NIWSServerListFilterClassName;
|
||||
|
||||
/**
|
||||
* Preprocessor that configures defaults for eureka-discovered ribbon clients. Such as:
|
||||
* <code>@zone</code>, NIWSServerListClassName, DeploymentContextBasedVipAddresses,
|
||||
* NFLoadBalancerRuleClassName, NIWSServerListFilterClassName and more
|
||||
*
|
||||
*
|
||||
* @author Spencer Gibb
|
||||
* @author Dave Syer
|
||||
*/
|
||||
@@ -35,6 +51,7 @@ public class EurekaRibbonClientConfiguration {
|
||||
private String serviceId = "client";
|
||||
|
||||
protected static final String VALUE_NOT_SET = "__not__set__";
|
||||
|
||||
protected static final String DEFAULT_NAMESPACE = "ribbon";
|
||||
|
||||
@Autowired(required = false)
|
||||
@@ -51,9 +68,10 @@ public class EurekaRibbonClientConfiguration {
|
||||
|
||||
@PostConstruct
|
||||
public void preprocess() {
|
||||
if (clientConfig != null
|
||||
if (this.clientConfig != null
|
||||
&& ConfigurationManager.getDeploymentContext().getValue(ContextKey.zone) == null) {
|
||||
String[] zones = clientConfig.getAvailabilityZones(clientConfig.getRegion());
|
||||
String[] zones = this.clientConfig.getAvailabilityZones(this.clientConfig
|
||||
.getRegion());
|
||||
String zone = zones != null && zones.length > 0 ? zones[0] : null;
|
||||
if (zone != null) {
|
||||
// You can set this with archaius.deployment.* (maybe requires
|
||||
@@ -63,15 +81,15 @@ public class EurekaRibbonClientConfiguration {
|
||||
}
|
||||
}
|
||||
// TODO: should this look more like hibernate spring boot props?
|
||||
setProp(serviceId, NIWSServerListClassName.key(),
|
||||
setProp(this.serviceId, NIWSServerListClassName.key(),
|
||||
DiscoveryEnabledNIWSServerList.class.getName());
|
||||
// FIXME: what should this be?
|
||||
setProp(serviceId, DeploymentContextBasedVipAddresses.key(), serviceId);
|
||||
setProp(serviceId, NFLoadBalancerRuleClassName.key(),
|
||||
setProp(this.serviceId, DeploymentContextBasedVipAddresses.key(), this.serviceId);
|
||||
setProp(this.serviceId, NFLoadBalancerRuleClassName.key(),
|
||||
ZoneAvoidanceRule.class.getName());
|
||||
setProp(serviceId, NIWSServerListFilterClassName.key(),
|
||||
setProp(this.serviceId, NIWSServerListFilterClassName.key(),
|
||||
ZonePreferenceServerListFilter.class.getName());
|
||||
setProp(serviceId, EnableZoneAffinity.key(), "true");
|
||||
setProp(this.serviceId, EnableZoneAffinity.key(), "true");
|
||||
}
|
||||
|
||||
protected void setProp(String serviceId, String suffix, String value) {
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.ribbon.eureka;
|
||||
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
|
||||
@@ -29,7 +30,6 @@ import com.netflix.niws.loadbalancer.DiscoveryEnabledNIWSServerList;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
@Configuration
|
||||
@EnableConfigurationProperties
|
||||
@@ -39,4 +39,5 @@ import com.netflix.niws.loadbalancer.DiscoveryEnabledNIWSServerList;
|
||||
@AutoConfigureAfter(RibbonAutoConfiguration.class)
|
||||
@RibbonClients(defaultConfiguration = EurekaRibbonClientConfiguration.class)
|
||||
public class RibbonEurekaAutoConfiguration {
|
||||
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.ribbon.eureka;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -30,32 +31,33 @@ import com.netflix.loadbalancer.ZoneAffinityServerListFilter;
|
||||
/**
|
||||
* A filter that actively prefers the local zone (as defined by the deployment context, or
|
||||
* the Eureka instance metadata).
|
||||
*
|
||||
* @author Dave Syer
|
||||
*
|
||||
* TODO: move out of ribbon.eureka package since it has nothing specific to eureka
|
||||
* @author Dave Syer
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper=false)
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
public class ZonePreferenceServerListFilter extends ZoneAffinityServerListFilter<Server> {
|
||||
|
||||
// TODO: move out of ribbon.eureka package since it has nothing specific to eureka
|
||||
|
||||
private String zone;
|
||||
|
||||
@Override
|
||||
public void initWithNiwsConfig(IClientConfig niwsClientConfig) {
|
||||
super.initWithNiwsConfig(niwsClientConfig);
|
||||
if (ConfigurationManager.getDeploymentContext() != null) {
|
||||
zone = ConfigurationManager.getDeploymentContext().getValue(ContextKey.zone);
|
||||
this.zone = ConfigurationManager.getDeploymentContext().getValue(
|
||||
ContextKey.zone);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Server> getFilteredListOfServers(List<Server> servers) {
|
||||
List<Server> output = super.getFilteredListOfServers(servers);
|
||||
if (zone != null && output.size() == servers.size()) {
|
||||
if (this.zone != null && output.size() == servers.size()) {
|
||||
List<Server> local = new ArrayList<Server>();
|
||||
for (Server server : output) {
|
||||
if (zone.equalsIgnoreCase(server.getZone())) {
|
||||
if (this.zone.equalsIgnoreCase(server.getZone())) {
|
||||
local.add(server);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import org.springframework.beans.factory.DisposableBean;
|
||||
import org.springframework.boot.actuate.metrics.Metric;
|
||||
import org.springframework.boot.actuate.metrics.reader.MetricReader;
|
||||
@@ -38,7 +39,7 @@ import com.netflix.servo.publish.PollScheduler;
|
||||
/**
|
||||
* {@link MetricReader} implementation that registers a {@link MetricObserver} with the
|
||||
* Netflix Servo library and exposes Servo metrics to the <code>/metric</code> endpoint.
|
||||
*
|
||||
*
|
||||
* @author Dave Syer
|
||||
* @author Christian Dupuis
|
||||
*/
|
||||
@@ -88,11 +89,13 @@ public class ServoMetricCollector implements DisposableBean {
|
||||
.append(config.getName()).toString().toLowerCase();
|
||||
|
||||
if (servoMetric.hasNumberValue()) {
|
||||
metrics.set(new Metric<Number>(key, servoMetric.getNumberValue(),
|
||||
new Date(servoMetric.getTimestamp())));
|
||||
this.metrics.set(new Metric<Number>(key,
|
||||
servoMetric.getNumberValue(), new Date(servoMetric
|
||||
.getTimestamp())));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -31,8 +31,8 @@ import org.springframework.context.annotation.Configuration;
|
||||
import com.netflix.servo.monitor.Monitors;
|
||||
|
||||
/**
|
||||
* Auto configuration to configure Servo support.
|
||||
*
|
||||
* Auto configuration to configure Servo support.
|
||||
*
|
||||
* @author Dave Syer
|
||||
* @author Christian Dupuis
|
||||
*/
|
||||
@@ -40,12 +40,13 @@ import com.netflix.servo.monitor.Monitors;
|
||||
@ConditionalOnClass({ Monitors.class, MetricReader.class })
|
||||
@ConditionalOnBean(MetricReader.class)
|
||||
@AutoConfigureBefore(EndpointAutoConfiguration.class)
|
||||
@AutoConfigureAfter({MetricRepositoryAutoConfiguration.class})
|
||||
@AutoConfigureAfter({ MetricRepositoryAutoConfiguration.class })
|
||||
public class ServoMetricsAutoConfiguration {
|
||||
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public ServoMetricCollector servoMetricCollector(MetricWriter metrics) {
|
||||
return new ServoMetricCollector(metrics);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,21 +1,37 @@
|
||||
package org.springframework.cloud.netflix.zuul;
|
||||
/*
|
||||
* Copyright 2013-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
|
||||
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
|
||||
import org.springframework.context.annotation.Import;
|
||||
package org.springframework.cloud.netflix.zuul;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
|
||||
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
/**
|
||||
* Sets up a Zuul server endpoint and installs some reverse proxy filters in it, so it can
|
||||
* forward requests to backend servers. The backends can be registered manually through
|
||||
* configuration or via Eureka.
|
||||
*
|
||||
*
|
||||
* @see EnableZuulServer for how to get a Zuul server without any proxying
|
||||
*
|
||||
*
|
||||
* @author Spencer Gibb
|
||||
* @author Dave Syer
|
||||
*/
|
||||
@@ -25,4 +41,5 @@ import java.lang.annotation.Target;
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Import(ZuulProxyConfiguration.class)
|
||||
public @interface EnableZuulProxy {
|
||||
|
||||
}
|
||||
|
||||
@@ -1,3 +1,19 @@
|
||||
/*
|
||||
* Copyright 2013-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.zuul;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
@@ -12,9 +28,9 @@ import org.springframework.context.annotation.Import;
|
||||
* Set up the application to act as a generic Zuul server without any built-in reverse
|
||||
* proxy features. The routes into the Zuul server can be configured through
|
||||
* {@link ZuulProperties} (by default there are none).
|
||||
*
|
||||
*
|
||||
* @see EnableZuulProxy to see how to get reverse proxy out of the box
|
||||
*
|
||||
*
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
@Target(ElementType.TYPE)
|
||||
@@ -22,4 +38,5 @@ import org.springframework.context.annotation.Import;
|
||||
@Documented
|
||||
@Import(ZuulConfiguration.class)
|
||||
public @interface EnableZuulServer {
|
||||
|
||||
}
|
||||
|
||||
@@ -1,3 +1,19 @@
|
||||
/*
|
||||
* Copyright 2013-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.zuul;
|
||||
|
||||
import java.util.Collection;
|
||||
@@ -41,12 +57,12 @@ public class ProxyRouteLocator implements RouteLocator {
|
||||
}
|
||||
|
||||
public void addRoute(String path, String location) {
|
||||
staticRoutes.put(path, new ZuulRoute(path, location));
|
||||
this.staticRoutes.put(path, new ZuulRoute(path, location));
|
||||
resetRoutes();
|
||||
}
|
||||
|
||||
public void addRoute(ZuulRoute route) {
|
||||
staticRoutes.put(route.getPath(), route);
|
||||
this.staticRoutes.put(route.getPath(), route);
|
||||
resetRoutes();
|
||||
}
|
||||
|
||||
@@ -56,34 +72,30 @@ public class ProxyRouteLocator implements RouteLocator {
|
||||
}
|
||||
|
||||
public Map<String, String> getRoutes() {
|
||||
|
||||
if (routes.get() == null) {
|
||||
routes.set(locateRoutes());
|
||||
if (this.routes.get() == null) {
|
||||
this.routes.set(locateRoutes());
|
||||
}
|
||||
|
||||
Map<String, String> values = new LinkedHashMap<>();
|
||||
|
||||
for (String key : routes.get().keySet()) {
|
||||
for (String key : this.routes.get().keySet()) {
|
||||
String url = key;
|
||||
values.put(url, routes.get().get(key).getLocation());
|
||||
values.put(url, this.routes.get().get(key).getLocation());
|
||||
}
|
||||
return values;
|
||||
|
||||
}
|
||||
|
||||
public ProxyRouteSpec getMatchingRoute(String path) {
|
||||
String location = null;
|
||||
String targetPath = null;
|
||||
String id = null;
|
||||
String prefix = properties.getPrefix();
|
||||
for (Entry<String, ZuulRoute> entry : routes.get().entrySet()) {
|
||||
String prefix = this.properties.getPrefix();
|
||||
for (Entry<String, ZuulRoute> entry : this.routes.get().entrySet()) {
|
||||
String pattern = entry.getKey();
|
||||
if (pathMatcher.match(pattern, path)) {
|
||||
if (this.pathMatcher.match(pattern, path)) {
|
||||
ZuulRoute route = entry.getValue();
|
||||
id = route.getId();
|
||||
location = route.getLocation();
|
||||
targetPath = path;
|
||||
if (path.startsWith(prefix) && properties.isStripPrefix()) {
|
||||
if (path.startsWith(prefix) && this.properties.isStripPrefix()) {
|
||||
targetPath = path.substring(prefix.length());
|
||||
}
|
||||
if (route.isStripPrefix()) {
|
||||
@@ -97,68 +109,57 @@ public class ProxyRouteLocator implements RouteLocator {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return location == null ? null : new ProxyRouteSpec(id, targetPath, location,
|
||||
prefix);
|
||||
return (location == null ? null : new ProxyRouteSpec(id, targetPath, location,
|
||||
prefix));
|
||||
}
|
||||
|
||||
public void resetRoutes() {
|
||||
routes.set(locateRoutes());
|
||||
this.routes.set(locateRoutes());
|
||||
}
|
||||
|
||||
protected LinkedHashMap<String, ZuulRoute> locateRoutes() {
|
||||
|
||||
LinkedHashMap<String, ZuulRoute> routesMap = new LinkedHashMap<>();
|
||||
|
||||
addConfiguredRoutes(routesMap);
|
||||
routesMap.putAll(staticRoutes);
|
||||
|
||||
if (discovery != null) {
|
||||
routesMap.putAll(this.staticRoutes);
|
||||
if (this.discovery != null) {
|
||||
// Add routes for discovery services by default
|
||||
List<String> services = discovery.getServices();
|
||||
List<String> services = this.discovery.getServices();
|
||||
for (String serviceId : services) {
|
||||
// Ignore specifically ignored services and those that were manually
|
||||
// configured
|
||||
String key = "/" + serviceId + "/**";
|
||||
if (!properties.getIgnoredServices().contains(serviceId)
|
||||
if (!this.properties.getIgnoredServices().contains(serviceId)
|
||||
&& !routesMap.containsKey(key)) {
|
||||
routesMap.put(key, new ZuulRoute(key, serviceId));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (routesMap.get(DEFAULT_ROUTE) != null) {
|
||||
ZuulRoute defaultRoute = routesMap.get(DEFAULT_ROUTE);
|
||||
// Move the defaultServiceId to the end
|
||||
routesMap.remove(DEFAULT_ROUTE);
|
||||
routesMap.put(DEFAULT_ROUTE, defaultRoute);
|
||||
}
|
||||
|
||||
LinkedHashMap<String, ZuulRoute> values = new LinkedHashMap<>();
|
||||
for (Entry<String, ZuulRoute> entry : routesMap.entrySet()) {
|
||||
|
||||
String path = entry.getKey();
|
||||
// Prepend with slash if not already present.
|
||||
if (!path.startsWith("/")) {
|
||||
path = "/" + path;
|
||||
}
|
||||
|
||||
if (StringUtils.hasText(properties.getPrefix())) {
|
||||
path = properties.getPrefix() + path;
|
||||
if (StringUtils.hasText(this.properties.getPrefix())) {
|
||||
path = this.properties.getPrefix() + path;
|
||||
if (!path.startsWith("/")) {
|
||||
path = "/" + path;
|
||||
}
|
||||
}
|
||||
|
||||
values.put(path, entry.getValue());
|
||||
|
||||
}
|
||||
|
||||
return values;
|
||||
|
||||
}
|
||||
|
||||
protected void addConfiguredRoutes(Map<String, ZuulRoute> routes) {
|
||||
Map<String, ZuulRoute> routeEntries = properties.getRoutes();
|
||||
Map<String, ZuulRoute> routeEntries = this.properties.getRoutes();
|
||||
for (ZuulRoute entry : routeEntries.values()) {
|
||||
String route = entry.getPath();
|
||||
if (routes.containsKey(route)) {
|
||||
@@ -171,23 +172,22 @@ public class ProxyRouteLocator implements RouteLocator {
|
||||
|
||||
public String getTargetPath(String matchingRoute, String requestURI) {
|
||||
String path = getRoutes().get(matchingRoute);
|
||||
if (path == null) {
|
||||
path = requestURI;
|
||||
}
|
||||
else {
|
||||
|
||||
}
|
||||
return path;
|
||||
return (path != null ? path : requestURI);
|
||||
|
||||
}
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
public static class ProxyRouteSpec {
|
||||
|
||||
private String id;
|
||||
|
||||
private String path;
|
||||
|
||||
private String location;
|
||||
|
||||
private String prefix;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -13,13 +13,13 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.zuul;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
public interface RouteLocator {
|
||||
|
||||
|
||||
@@ -1,3 +1,19 @@
|
||||
/*
|
||||
* Copyright 2013-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.zuul;
|
||||
|
||||
import java.util.Map;
|
||||
@@ -16,7 +32,7 @@ import org.springframework.web.bind.annotation.ResponseBody;
|
||||
|
||||
/**
|
||||
* Endpoint to display and reset the zuul proxy routes
|
||||
*
|
||||
*
|
||||
* @author Spencer Gibb
|
||||
* @author Dave Syer
|
||||
*/
|
||||
@@ -24,6 +40,7 @@ import org.springframework.web.bind.annotation.ResponseBody;
|
||||
public class RoutesEndpoint implements MvcEndpoint, ApplicationEventPublisherAware {
|
||||
|
||||
private ProxyRouteLocator routes;
|
||||
|
||||
private ApplicationEventPublisher publisher;
|
||||
|
||||
@Override
|
||||
@@ -40,7 +57,7 @@ public class RoutesEndpoint implements MvcEndpoint, ApplicationEventPublisherAwa
|
||||
@ResponseBody
|
||||
@ManagedOperation
|
||||
public Map<String, String> reset() {
|
||||
publisher.publishEvent(new RoutesRefreshedEvent(routes));
|
||||
this.publisher.publishEvent(new RoutesRefreshedEvent(this.routes));
|
||||
return getRoutes();
|
||||
}
|
||||
|
||||
@@ -48,7 +65,7 @@ public class RoutesEndpoint implements MvcEndpoint, ApplicationEventPublisherAwa
|
||||
@ResponseBody
|
||||
@ManagedAttribute
|
||||
public Map<String, String> getRoutes() {
|
||||
return routes.getRoutes();
|
||||
return this.routes.getRoutes();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -13,13 +13,13 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.zuul;
|
||||
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
public class RoutesRefreshedEvent extends ApplicationEvent {
|
||||
@@ -32,7 +32,7 @@ public class RoutesRefreshedEvent extends ApplicationEvent {
|
||||
}
|
||||
|
||||
public RouteLocator getLocator() {
|
||||
return locator;
|
||||
return this.locator;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.zuul;
|
||||
|
||||
import java.util.Collection;
|
||||
@@ -22,7 +23,6 @@ import org.springframework.cloud.netflix.zuul.ZuulProperties.ZuulRoute;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
public class SimpleRouteLocator implements RouteLocator {
|
||||
|
||||
@@ -35,7 +35,7 @@ public class SimpleRouteLocator implements RouteLocator {
|
||||
@Override
|
||||
public Collection<String> getRoutePaths() {
|
||||
Collection<String> paths = new LinkedHashSet<String>();
|
||||
for (ZuulRoute route : properties.getRoutes().values()) {
|
||||
for (ZuulRoute route : this.properties.getRoutes().values()) {
|
||||
paths.add(route.getPath());
|
||||
}
|
||||
return paths;
|
||||
|
||||
@@ -1,3 +1,19 @@
|
||||
/*
|
||||
* Copyright 2013-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.zuul;
|
||||
|
||||
import java.util.Map;
|
||||
@@ -34,7 +50,7 @@ public class ZuulConfiguration {
|
||||
|
||||
@Bean
|
||||
public RouteLocator routeLocator() {
|
||||
return new SimpleRouteLocator(zuulProperties);
|
||||
return new SimpleRouteLocator(this.zuulProperties);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@@ -47,40 +63,13 @@ public class ZuulConfiguration {
|
||||
return new ZuulHandlerMapping(routes, zuulController());
|
||||
}
|
||||
|
||||
@Configuration
|
||||
protected static class ZuulFilterConfiguration {
|
||||
|
||||
@Autowired
|
||||
private Map<String, ZuulFilter> filters;
|
||||
|
||||
@Bean
|
||||
public ZuulFilterInitializer zuulFilterInitializer() {
|
||||
return new ZuulFilterInitializer(filters);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ApplicationListener<ApplicationEvent> zuulRefreshRoutesListener() {
|
||||
return new ZuulRefreshListener();
|
||||
}
|
||||
|
||||
private static class ZuulRefreshListener implements
|
||||
ApplicationListener<ApplicationEvent> {
|
||||
|
||||
@Autowired
|
||||
private ZuulHandlerMapping zuulHandlerMapping;
|
||||
|
||||
@Override
|
||||
public void onApplicationEvent(ApplicationEvent event) {
|
||||
if (event instanceof ContextRefreshedEvent
|
||||
|| event instanceof RefreshScopeRefreshedEvent)
|
||||
zuulHandlerMapping.registerHandlers();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// pre filters
|
||||
|
||||
@Bean
|
||||
public FormBodyWrapperFilter formBodyWrapperFilter() {
|
||||
return new FormBodyWrapperFilter();
|
||||
@@ -97,6 +86,7 @@ public class ZuulConfiguration {
|
||||
}
|
||||
|
||||
// post filters
|
||||
|
||||
@Bean
|
||||
public SendResponseFilter sendResponseFilter() {
|
||||
return new SendResponseFilter();
|
||||
@@ -107,4 +97,33 @@ public class ZuulConfiguration {
|
||||
return new SendErrorFilter();
|
||||
}
|
||||
|
||||
@Configuration
|
||||
protected static class ZuulFilterConfiguration {
|
||||
|
||||
@Autowired
|
||||
private Map<String, ZuulFilter> filters;
|
||||
|
||||
@Bean
|
||||
public ZuulFilterInitializer zuulFilterInitializer() {
|
||||
return new ZuulFilterInitializer(this.filters);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class ZuulRefreshListener implements
|
||||
ApplicationListener<ApplicationEvent> {
|
||||
|
||||
@Autowired
|
||||
private ZuulHandlerMapping zuulHandlerMapping;
|
||||
|
||||
@Override
|
||||
public void onApplicationEvent(ApplicationEvent event) {
|
||||
if (event instanceof ContextRefreshedEvent
|
||||
|| event instanceof RefreshScopeRefreshedEvent) {
|
||||
this.zuulHandlerMapping.registerHandlers();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,31 +1,51 @@
|
||||
package org.springframework.cloud.netflix.zuul;
|
||||
/*
|
||||
* Copyright 2013-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import com.netflix.zuul.context.RequestContext;
|
||||
import com.netflix.zuul.http.ZuulServlet;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
import org.springframework.web.servlet.mvc.ServletWrappingController;
|
||||
package org.springframework.cloud.netflix.zuul;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
import org.springframework.web.servlet.mvc.ServletWrappingController;
|
||||
|
||||
import com.netflix.zuul.context.RequestContext;
|
||||
import com.netflix.zuul.http.ZuulServlet;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
public class ZuulController extends ServletWrappingController {
|
||||
|
||||
public ZuulController() {
|
||||
setServletClass(ZuulServlet.class);
|
||||
setServletName("zuul");
|
||||
setSupportedMethods((String[])null); // Allow all
|
||||
}
|
||||
public ZuulController() {
|
||||
setServletClass(ZuulServlet.class);
|
||||
setServletName("zuul");
|
||||
setSupportedMethods((String[]) null); // Allow all
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ModelAndView handleRequestInternal(HttpServletRequest request,
|
||||
HttpServletResponse response) throws Exception {
|
||||
try {
|
||||
return super.handleRequestInternal(request, response);
|
||||
}
|
||||
finally {
|
||||
// @see com.netflix.zuul.context.ContextLifecycleFilter.doFilter
|
||||
RequestContext.getCurrentContext().unset();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception {
|
||||
try {
|
||||
return super.handleRequestInternal(request, response);
|
||||
} finally {
|
||||
// @see com.netflix.zuul.context.ContextLifecycleFilter.doFilter
|
||||
RequestContext.getCurrentContext().unset();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,19 @@
|
||||
/*
|
||||
* Copyright 2013-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.zuul;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
@@ -17,43 +33,44 @@ import com.netflix.zuul.monitoring.MonitoringHelper;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*
|
||||
* TODO: .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
|
||||
*
|
||||
* TODO: .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
|
||||
*/
|
||||
public class ZuulFilterInitializer implements ServletContextListener {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(ZuulFilterInitializer.class);
|
||||
private static final Logger LOGGER = LoggerFactory
|
||||
.getLogger(ZuulFilterInitializer.class);
|
||||
|
||||
private Map<String, ZuulFilter> filters;
|
||||
private Map<String, ZuulFilter> filters;
|
||||
|
||||
public ZuulFilterInitializer(Map<String, ZuulFilter> filters) {
|
||||
this.filters = filters;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void contextInitialized(ServletContextEvent sce) {
|
||||
public void contextInitialized(ServletContextEvent sce) {
|
||||
|
||||
LOGGER.info("Starting filter initializer context listener");
|
||||
LOGGER.info("Starting filter initializer context listener");
|
||||
|
||||
//FIXME: mocks monitoring infrastructure as we don't need it for this simple app
|
||||
MonitoringHelper.initMocks();
|
||||
// FIXME: mocks monitoring infrastructure as we don't need it for this simple app
|
||||
MonitoringHelper.initMocks();
|
||||
|
||||
FilterRegistry registry = FilterRegistry.instance();
|
||||
FilterRegistry registry = FilterRegistry.instance();
|
||||
|
||||
for (Map.Entry<String, ZuulFilter> entry : filters.entrySet()) {
|
||||
registry.put(entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
for (Map.Entry<String, ZuulFilter> entry : this.filters.entrySet()) {
|
||||
registry.put(entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void contextDestroyed(ServletContextEvent sce) {
|
||||
LOGGER.info("Stopping filter initializer context listener");
|
||||
FilterRegistry registry = FilterRegistry.instance();
|
||||
for (Map.Entry<String, ZuulFilter> entry : filters.entrySet()) {
|
||||
registry.remove(entry.getKey());
|
||||
}
|
||||
clearLoaderCache();
|
||||
}
|
||||
@Override
|
||||
public void contextDestroyed(ServletContextEvent sce) {
|
||||
LOGGER.info("Stopping filter initializer context listener");
|
||||
FilterRegistry registry = FilterRegistry.instance();
|
||||
for (Map.Entry<String, ZuulFilter> entry : this.filters.entrySet()) {
|
||||
registry.remove(entry.getKey());
|
||||
}
|
||||
clearLoaderCache();
|
||||
}
|
||||
|
||||
private void clearLoaderCache() {
|
||||
FilterLoader instance = FilterLoader.getInstance();
|
||||
@@ -64,24 +81,17 @@ public class ZuulFilterInitializer implements ServletContextListener {
|
||||
cache.clear();
|
||||
}
|
||||
|
||||
/*private void initGroovyFilterManager() {
|
||||
|
||||
//TODO: support groovy filters loaded from filesystem in proxy
|
||||
FilterLoader.getInstance().setCompiler(new GroovyCompiler());
|
||||
|
||||
final String scriptRoot = props.getFilterRoot();
|
||||
LOGGER.info("Using file system script: " + scriptRoot);
|
||||
|
||||
try {
|
||||
FilterFileManager.setFilenameFilter(new GroovyFileFilter());
|
||||
FilterFileManager.init(5,
|
||||
scriptRoot + "/pre",
|
||||
scriptRoot + "/route",
|
||||
scriptRoot + "/post"
|
||||
);
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}*/
|
||||
/*
|
||||
* private void initGroovyFilterManager() {
|
||||
*
|
||||
* //TODO: support groovy filters loaded from filesystem in proxy
|
||||
* FilterLoader.getInstance().setCompiler(new GroovyCompiler());
|
||||
*
|
||||
* final String scriptRoot = props.getFilterRoot();
|
||||
* LOGGER.info("Using file system script: " + scriptRoot);
|
||||
*
|
||||
* try { FilterFileManager.setFilenameFilter(new GroovyFileFilter());
|
||||
* FilterFileManager.init(5, scriptRoot + "/pre", scriptRoot + "/route", scriptRoot +
|
||||
* "/post" ); } catch (Exception e) { throw new RuntimeException(e); } }
|
||||
*/
|
||||
}
|
||||
|
||||
@@ -1,3 +1,19 @@
|
||||
/*
|
||||
* Copyright 2013-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.zuul;
|
||||
|
||||
import java.util.Collection;
|
||||
@@ -7,15 +23,15 @@ import org.springframework.web.servlet.handler.AbstractUrlHandlerMapping;
|
||||
|
||||
/**
|
||||
* MVC HandlerMapping that maps incoming request paths to remote services.
|
||||
*
|
||||
*
|
||||
* @author Spencer Gibb
|
||||
* @author Dave Syer
|
||||
*/
|
||||
public class ZuulHandlerMapping extends AbstractUrlHandlerMapping {
|
||||
|
||||
private RouteLocator routeLocator;
|
||||
private final RouteLocator routeLocator;
|
||||
|
||||
private ZuulController zuul;
|
||||
private final ZuulController zuul;
|
||||
|
||||
@Autowired
|
||||
public ZuulHandlerMapping(RouteLocator routeLocator, ZuulController zuul) {
|
||||
@@ -25,13 +41,13 @@ public class ZuulHandlerMapping extends AbstractUrlHandlerMapping {
|
||||
}
|
||||
|
||||
protected void registerHandlers() {
|
||||
Collection<String> routes = routeLocator.getRoutePaths();
|
||||
Collection<String> routes = this.routeLocator.getRoutePaths();
|
||||
if (routes.isEmpty()) {
|
||||
logger.warn("No routes found from ProxyRouteLocator");
|
||||
this.logger.warn("No routes found from ProxyRouteLocator");
|
||||
}
|
||||
else {
|
||||
for (String url : routes) {
|
||||
registerHandler(url, zuul);
|
||||
registerHandler(url, this.zuul);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,19 @@
|
||||
/*
|
||||
* Copyright 2013-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.zuul;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -22,10 +38,15 @@ import org.springframework.util.StringUtils;
|
||||
@Data
|
||||
@ConfigurationProperties("zuul")
|
||||
public class ZuulProperties {
|
||||
|
||||
private String prefix = "";
|
||||
|
||||
private boolean stripPrefix = true;
|
||||
|
||||
private Map<String, ZuulRoute> routes = new LinkedHashMap<String, ZuulRoute>();
|
||||
|
||||
private boolean addProxyHeaders = true;
|
||||
|
||||
private List<String> ignoredServices = new ArrayList<String>();
|
||||
|
||||
@PostConstruct
|
||||
@@ -48,10 +69,15 @@ public class ZuulProperties {
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public static class ZuulRoute {
|
||||
|
||||
private String id;
|
||||
|
||||
private String path;
|
||||
|
||||
private String serviceId;
|
||||
|
||||
private String url;
|
||||
|
||||
private boolean stripPrefix = true;
|
||||
|
||||
public ZuulRoute(String text) {
|
||||
@@ -78,19 +104,19 @@ public class ZuulProperties {
|
||||
}
|
||||
|
||||
public String getLocation() {
|
||||
if (StringUtils.hasText(url)) {
|
||||
return url;
|
||||
if (StringUtils.hasText(this.url)) {
|
||||
return this.url;
|
||||
}
|
||||
return serviceId;
|
||||
return this.serviceId;
|
||||
}
|
||||
|
||||
public void setLocation(String location) {
|
||||
if (location != null
|
||||
&& (location.startsWith("http:") || location.startsWith("https:"))) {
|
||||
url = location;
|
||||
this.url = location;
|
||||
}
|
||||
else {
|
||||
serviceId = location;
|
||||
this.serviceId = location;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -99,6 +125,7 @@ public class ZuulProperties {
|
||||
path = path.replace("/*", "").replace("*", "");
|
||||
return path;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,3 +1,19 @@
|
||||
/*
|
||||
* Copyright 2013-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.zuul;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
@@ -42,44 +58,31 @@ public class ZuulProxyConfiguration extends ZuulConfiguration {
|
||||
@Bean
|
||||
@Override
|
||||
public ProxyRouteLocator routeLocator() {
|
||||
return new ProxyRouteLocator(discovery, zuulProperties);
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnClass(Endpoint.class)
|
||||
protected static class RoutesEndpointConfuguration {
|
||||
@Autowired
|
||||
private ProxyRouteLocator routeLocator;
|
||||
|
||||
@Bean
|
||||
// @RefreshScope
|
||||
public RoutesEndpoint zuulEndpoint() {
|
||||
return new RoutesEndpoint(routeLocator);
|
||||
}
|
||||
return new ProxyRouteLocator(this.discovery, this.zuulProperties);
|
||||
}
|
||||
|
||||
// pre filters
|
||||
@Bean
|
||||
public PreDecorationFilter preDecorationFilter() {
|
||||
return new PreDecorationFilter(routeLocator(), zuulProperties);
|
||||
return new PreDecorationFilter(routeLocator(), this.zuulProperties);
|
||||
}
|
||||
|
||||
// route filters
|
||||
@Bean
|
||||
public RibbonRoutingFilter ribbonRoutingFilter() {
|
||||
ProxyRequestHelper helper = new ProxyRequestHelper();
|
||||
if (traces != null) {
|
||||
helper.setTraces(traces);
|
||||
if (this.traces != null) {
|
||||
helper.setTraces(this.traces);
|
||||
}
|
||||
RibbonRoutingFilter filter = new RibbonRoutingFilter(helper, clientFactory);
|
||||
RibbonRoutingFilter filter = new RibbonRoutingFilter(helper, this.clientFactory);
|
||||
return filter;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public SimpleHostRoutingFilter simpleHostRoutingFilter() {
|
||||
ProxyRequestHelper helper = new ProxyRequestHelper();
|
||||
if (traces != null) {
|
||||
helper.setTraces(traces);
|
||||
if (this.traces != null) {
|
||||
helper.setTraces(this.traces);
|
||||
}
|
||||
return new SimpleHostRoutingFilter(helper);
|
||||
}
|
||||
@@ -90,6 +93,21 @@ public class ZuulProxyConfiguration extends ZuulConfiguration {
|
||||
return new ZuulRefreshListener();
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnClass(Endpoint.class)
|
||||
protected static class RoutesEndpointConfuguration {
|
||||
|
||||
@Autowired
|
||||
private ProxyRouteLocator routeLocator;
|
||||
|
||||
@Bean
|
||||
// @RefreshScope
|
||||
public RoutesEndpoint zuulEndpoint() {
|
||||
return new RoutesEndpoint(this.routeLocator);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class ZuulRefreshListener implements
|
||||
ApplicationListener<ApplicationEvent> {
|
||||
|
||||
@@ -110,9 +128,9 @@ public class ZuulProxyConfiguration extends ZuulConfiguration {
|
||||
}
|
||||
else if (event instanceof DiscoveryHeartbeatEvent) {
|
||||
DiscoveryHeartbeatEvent e = (DiscoveryHeartbeatEvent) event;
|
||||
if (latestHeartbeat.get() == null
|
||||
|| !latestHeartbeat.get().equals(e.getValue())) {
|
||||
latestHeartbeat.set(e.getValue());
|
||||
if (this.latestHeartbeat.get() == null
|
||||
|| !this.latestHeartbeat.get().equals(e.getValue())) {
|
||||
this.latestHeartbeat.set(e.getValue());
|
||||
reset();
|
||||
}
|
||||
}
|
||||
@@ -120,8 +138,8 @@ public class ZuulProxyConfiguration extends ZuulConfiguration {
|
||||
}
|
||||
|
||||
private void reset() {
|
||||
routeLocator.resetRoutes();
|
||||
zuulHandlerMapping.registerHandlers();
|
||||
this.routeLocator.resetRoutes();
|
||||
this.zuulHandlerMapping.registerHandlers();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.zuul.filters;
|
||||
|
||||
import java.io.IOException;
|
||||
@@ -39,7 +40,6 @@ import com.netflix.zuul.util.HTTPRequestUtils;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
public class ProxyRequestHelper {
|
||||
|
||||
@@ -59,15 +59,12 @@ public class ProxyRequestHelper {
|
||||
|
||||
public MultiValueMap<String, String> buildZuulRequestQueryParams(
|
||||
HttpServletRequest request) {
|
||||
|
||||
Map<String, List<String>> map = HTTPRequestUtils.getInstance().getQueryParams();
|
||||
|
||||
MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
|
||||
if (map == null)
|
||||
if (map == null) {
|
||||
return params;
|
||||
|
||||
}
|
||||
for (String key : map.keySet()) {
|
||||
|
||||
for (String value : map.get(key)) {
|
||||
params.add(key, value);
|
||||
}
|
||||
@@ -77,41 +74,34 @@ public class ProxyRequestHelper {
|
||||
|
||||
public MultiValueMap<String, String> buildZuulRequestHeaders(
|
||||
HttpServletRequest request) {
|
||||
|
||||
RequestContext context = RequestContext.getCurrentContext();
|
||||
|
||||
MultiValueMap<String, String> headers = new LinkedMultiValueMap<>();
|
||||
Enumeration<?> headerNames = request.getHeaderNames();
|
||||
if (headerNames != null) {
|
||||
while (headerNames.hasMoreElements()) {
|
||||
String name = (String) headerNames.nextElement();
|
||||
String value = request.getHeader(name);
|
||||
if (isIncludedHeader(name))
|
||||
if (isIncludedHeader(name)) {
|
||||
headers.set(name, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
Map<String, String> zuulRequestHeaders = context.getZuulRequestHeaders();
|
||||
|
||||
for (String header : zuulRequestHeaders.keySet()) {
|
||||
headers.set(header, zuulRequestHeaders.get(header));
|
||||
}
|
||||
|
||||
headers.set("accept-encoding", "deflate, gzip");
|
||||
|
||||
return headers;
|
||||
}
|
||||
|
||||
public void setResponse(int status, InputStream entity,
|
||||
MultiValueMap<String, String> headers) throws IOException {
|
||||
RequestContext context = RequestContext.getCurrentContext();
|
||||
|
||||
RequestContext.getCurrentContext().setResponseStatusCode(status);
|
||||
if (entity != null) {
|
||||
RequestContext.getCurrentContext().setResponseDataStream(entity);
|
||||
}
|
||||
|
||||
boolean isOriginResponseGzipped = false;
|
||||
|
||||
if (headers.containsKey(CONTENT_ENCODING)) {
|
||||
Collection<String> collection = headers.get(CONTENT_ENCODING);
|
||||
for (String header : collection) {
|
||||
@@ -122,22 +112,19 @@ public class ProxyRequestHelper {
|
||||
}
|
||||
}
|
||||
context.setResponseGZipped(isOriginResponseGzipped);
|
||||
|
||||
for (Entry<String, List<String>> header : headers.entrySet()) {
|
||||
RequestContext ctx = RequestContext.getCurrentContext();
|
||||
String name = header.getKey();
|
||||
for (String value : header.getValue()) {
|
||||
ctx.addOriginResponseHeader(name, value);
|
||||
|
||||
if (name.equalsIgnoreCase("content-length"))
|
||||
if (name.equalsIgnoreCase("content-length")) {
|
||||
ctx.setOriginContentLength(value);
|
||||
|
||||
}
|
||||
if (isIncludedHeader(name)) {
|
||||
ctx.addZuulResponseHeader(name, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void addIgnoredHeaders(String... names) {
|
||||
@@ -177,10 +164,8 @@ public class ProxyRequestHelper {
|
||||
public Map<String, Object> debug(String verb, String uri,
|
||||
MultiValueMap<String, String> headers, MultiValueMap<String, String> params,
|
||||
InputStream requestEntity) throws IOException {
|
||||
|
||||
Map<String, Object> info = new LinkedHashMap<String, Object>();
|
||||
if (traces != null) {
|
||||
|
||||
if (this.traces != null) {
|
||||
RequestContext context = RequestContext.getCurrentContext();
|
||||
StringBuilder query = new StringBuilder();
|
||||
for (String param : params.keySet()) {
|
||||
@@ -196,7 +181,6 @@ public class ProxyRequestHelper {
|
||||
info.put("query", query.toString());
|
||||
info.put("remote", true);
|
||||
info.put("proxy", context.get("proxy"));
|
||||
|
||||
Map<String, Object> trace = new LinkedHashMap<String, Object>();
|
||||
Map<String, Object> input = new LinkedHashMap<String, Object>();
|
||||
trace.put("request", input);
|
||||
@@ -209,14 +193,13 @@ public class ProxyRequestHelper {
|
||||
}
|
||||
input.put(entry.getKey(), value);
|
||||
}
|
||||
|
||||
RequestContext ctx = RequestContext.getCurrentContext();
|
||||
if (!ctx.isChunkedRequestBody()) {
|
||||
if (requestEntity != null) {
|
||||
debugRequestEntity(info, ctx.getRequest().getInputStream());
|
||||
}
|
||||
}
|
||||
traces.add(info);
|
||||
this.traces.add(info);
|
||||
return info;
|
||||
}
|
||||
return info;
|
||||
@@ -224,7 +207,7 @@ public class ProxyRequestHelper {
|
||||
|
||||
public void appendDebug(Map<String, Object> info, int status,
|
||||
MultiValueMap<String, String> headers) {
|
||||
if (traces != null) {
|
||||
if (this.traces != null) {
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, Object> trace = (Map<String, Object>) info.get("headers");
|
||||
Map<String, Object> output = new LinkedHashMap<String, Object>();
|
||||
@@ -249,4 +232,4 @@ public class ProxyRequestHelper {
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,30 @@
|
||||
/*
|
||||
* Copyright 2013-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.zuul.filters.post;
|
||||
|
||||
import javax.servlet.RequestDispatcher;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
|
||||
import com.google.common.base.Throwables;
|
||||
import com.netflix.zuul.ZuulFilter;
|
||||
import com.netflix.zuul.context.RequestContext;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
|
||||
import javax.servlet.RequestDispatcher;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
@@ -14,53 +32,57 @@ import javax.servlet.RequestDispatcher;
|
||||
@Slf4j
|
||||
public class SendErrorFilter extends ZuulFilter {
|
||||
|
||||
protected static final String SEND_ERROR_FILTER_RAN = "sendErrorFilter.ran";
|
||||
protected static final String SEND_ERROR_FILTER_RAN = "sendErrorFilter.ran";
|
||||
|
||||
@Value("${error.path:/error}")
|
||||
private String errorPath;
|
||||
@Value("${error.path:/error}")
|
||||
private String errorPath;
|
||||
|
||||
@Override
|
||||
public String filterType() {
|
||||
return "post";
|
||||
}
|
||||
@Override
|
||||
public String filterType() {
|
||||
return "post";
|
||||
}
|
||||
|
||||
@Override
|
||||
public int filterOrder() {
|
||||
return 0;
|
||||
}
|
||||
@Override
|
||||
public int filterOrder() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldFilter() {
|
||||
RequestContext ctx = RequestContext.getCurrentContext();
|
||||
//only forward to errorPath if it hasn't been forwarded to already
|
||||
return ctx.containsKey("error.status_code") && !ctx.getBoolean(SEND_ERROR_FILTER_RAN, false);
|
||||
}
|
||||
@Override
|
||||
public boolean shouldFilter() {
|
||||
RequestContext ctx = RequestContext.getCurrentContext();
|
||||
// only forward to errorPath if it hasn't been forwarded to already
|
||||
return ctx.containsKey("error.status_code")
|
||||
&& !ctx.getBoolean(SEND_ERROR_FILTER_RAN, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object run() {
|
||||
try {
|
||||
RequestContext ctx = RequestContext.getCurrentContext();
|
||||
int statusCode = (Integer)ctx.get("error.status_code");
|
||||
if (ctx.containsKey("error.exception")) {
|
||||
Object e = ctx.get("error.exception");
|
||||
log.warn("Error during filtering", Throwable.class.cast(e));
|
||||
ctx.getRequest().setAttribute("javax.servlet.error.exception", e);
|
||||
}
|
||||
ctx.getRequest().setAttribute("javax.servlet.error.status_code", statusCode);
|
||||
RequestDispatcher dispatcher = ctx.getRequest().getRequestDispatcher(errorPath);
|
||||
@Override
|
||||
public Object run() {
|
||||
try {
|
||||
RequestContext ctx = RequestContext.getCurrentContext();
|
||||
int statusCode = (Integer) ctx.get("error.status_code");
|
||||
if (ctx.containsKey("error.exception")) {
|
||||
Object e = ctx.get("error.exception");
|
||||
log.warn("Error during filtering", Throwable.class.cast(e));
|
||||
ctx.getRequest().setAttribute("javax.servlet.error.exception", e);
|
||||
}
|
||||
ctx.getRequest().setAttribute("javax.servlet.error.status_code", statusCode);
|
||||
RequestDispatcher dispatcher = ctx.getRequest().getRequestDispatcher(
|
||||
this.errorPath);
|
||||
if (dispatcher != null) {
|
||||
ctx.set(SEND_ERROR_FILTER_RAN, true);
|
||||
if (!ctx.getResponse().isCommitted()) {
|
||||
dispatcher.forward(ctx.getRequest(), ctx.getResponse());
|
||||
}
|
||||
if (!ctx.getResponse().isCommitted()) {
|
||||
dispatcher.forward(ctx.getRequest(), ctx.getResponse());
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Throwables.propagate(e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
catch (Exception ex) {
|
||||
Throwables.propagate(ex);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void setErrorPath(String errorPath) {
|
||||
this.errorPath = errorPath;
|
||||
}
|
||||
|
||||
public void setErrorPath(String errorPath) {
|
||||
this.errorPath = errorPath;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,19 @@
|
||||
/*
|
||||
* Copyright 2013-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.zuul.filters.post;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
@@ -19,17 +35,20 @@ import com.netflix.zuul.constants.ZuulConstants;
|
||||
import com.netflix.zuul.constants.ZuulHeaders;
|
||||
import com.netflix.zuul.context.RequestContext;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
public class SendResponseFilter extends ZuulFilter {
|
||||
|
||||
static DynamicBooleanProperty INCLUDE_DEBUG_HEADER = DynamicPropertyFactory
|
||||
private static DynamicBooleanProperty INCLUDE_DEBUG_HEADER = DynamicPropertyFactory
|
||||
.getInstance().getBooleanProperty(ZuulConstants.ZUUL_INCLUDE_DEBUG_HEADER,
|
||||
false);
|
||||
|
||||
static DynamicIntProperty INITIAL_STREAM_BUFFER_SIZE = DynamicPropertyFactory
|
||||
private static DynamicIntProperty INITIAL_STREAM_BUFFER_SIZE = DynamicPropertyFactory
|
||||
.getInstance().getIntProperty(ZuulConstants.ZUUL_INITIAL_STREAM_BUFFER_SIZE,
|
||||
1024);
|
||||
|
||||
static DynamicBooleanProperty SET_CONTENT_LENGTH = DynamicPropertyFactory
|
||||
private static DynamicBooleanProperty SET_CONTENT_LENGTH = DynamicPropertyFactory
|
||||
.getInstance().getBooleanProperty(ZuulConstants.ZUUL_SET_CONTENT_LENGTH,
|
||||
false);
|
||||
|
||||
@@ -43,33 +62,33 @@ public class SendResponseFilter extends ZuulFilter {
|
||||
return 1000;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldFilter() {
|
||||
return !RequestContext.getCurrentContext().getZuulResponseHeaders().isEmpty()
|
||||
|| RequestContext.getCurrentContext().getResponseDataStream() != null
|
||||
|| RequestContext.getCurrentContext().getResponseBody() != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object run() {
|
||||
try {
|
||||
addResponseHeaders();
|
||||
writeResponse();
|
||||
}
|
||||
catch (Exception e) {
|
||||
Throwables.propagate(e);
|
||||
catch (Exception ex) {
|
||||
Throwables.propagate(ex);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
void writeResponse() throws Exception {
|
||||
private void writeResponse() throws Exception {
|
||||
RequestContext context = RequestContext.getCurrentContext();
|
||||
|
||||
// there is no body to send
|
||||
if (context.getResponseBody() == null && context.getResponseDataStream() == null)
|
||||
if (context.getResponseBody() == null && context.getResponseDataStream() == null) {
|
||||
return;
|
||||
|
||||
}
|
||||
HttpServletResponse servletResponse = context.getResponse();
|
||||
servletResponse.setCharacterEncoding("UTF-8");
|
||||
|
||||
OutputStream outStream = servletResponse.getOutputStream();
|
||||
InputStream is = null;
|
||||
try {
|
||||
@@ -78,13 +97,12 @@ public class SendResponseFilter extends ZuulFilter {
|
||||
writeResponse(new ByteArrayInputStream(body.getBytes()), outStream);
|
||||
return;
|
||||
}
|
||||
|
||||
boolean isGzipRequested = false;
|
||||
final String requestEncoding = context.getRequest().getHeader(
|
||||
ZuulHeaders.ACCEPT_ENCODING);
|
||||
if (requestEncoding != null && requestEncoding.equals("gzip"))
|
||||
if (requestEncoding != null && requestEncoding.equals("gzip")) {
|
||||
isGzipRequested = true;
|
||||
|
||||
}
|
||||
is = context.getResponseDataStream();
|
||||
InputStream inputStream = is;
|
||||
if (is != null) {
|
||||
@@ -93,36 +111,34 @@ public class SendResponseFilter extends ZuulFilter {
|
||||
// decompress stream
|
||||
// before sending to client
|
||||
// else, stream gzip directly to client
|
||||
if (context.getResponseGZipped() && !isGzipRequested)
|
||||
if (context.getResponseGZipped() && !isGzipRequested) {
|
||||
try {
|
||||
inputStream = new GZIPInputStream(is);
|
||||
|
||||
}
|
||||
catch (java.util.zip.ZipException e) {
|
||||
System.out
|
||||
.println("gzip expected but not received assuming unencoded response"
|
||||
+ RequestContext.getCurrentContext()
|
||||
.getRequest().getRequestURL()
|
||||
.toString());
|
||||
catch (java.util.zip.ZipException ex) {
|
||||
System.out.println("gzip expected but not "
|
||||
+ "received assuming unencoded response"
|
||||
+ RequestContext.getCurrentContext().getRequest()
|
||||
.getRequestURL().toString());
|
||||
inputStream = is;
|
||||
}
|
||||
else if (context.getResponseGZipped() && isGzipRequested)
|
||||
}
|
||||
else if (context.getResponseGZipped() && isGzipRequested) {
|
||||
servletResponse.setHeader(ZuulHeaders.CONTENT_ENCODING, "gzip");
|
||||
}
|
||||
writeResponse(inputStream, outStream);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
finally {
|
||||
try {
|
||||
if (is != null)
|
||||
if (is != null) {
|
||||
is.close();
|
||||
|
||||
}
|
||||
outStream.flush();
|
||||
outStream.close();
|
||||
}
|
||||
catch (IOException e) {
|
||||
|
||||
catch (IOException ex) {
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -131,19 +147,18 @@ public class SendResponseFilter extends ZuulFilter {
|
||||
byte[] bytes = new byte[INITIAL_STREAM_BUFFER_SIZE.get()];
|
||||
int bytesRead = -1;
|
||||
while ((bytesRead = zin.read(bytes)) != -1) {
|
||||
// TODO
|
||||
// if (Debug.debugRequest() && !Debug.debugRequestHeadersOnly()) {
|
||||
// Debug.addRequestDebug("OUTBOUND: < " + new String(bytes, 0, bytesRead));
|
||||
// }
|
||||
|
||||
try {
|
||||
out.write(bytes, 0, bytesRead);
|
||||
out.flush();
|
||||
}
|
||||
catch (IOException e) {
|
||||
catch (IOException ex) {
|
||||
// ignore
|
||||
e.printStackTrace();
|
||||
ex.printStackTrace();
|
||||
}
|
||||
|
||||
// doubles buffer size if previous read filled it
|
||||
if (bytesRead == bytes.length) {
|
||||
bytes = new byte[bytes.length * 2];
|
||||
@@ -155,7 +170,6 @@ public class SendResponseFilter extends ZuulFilter {
|
||||
RequestContext context = RequestContext.getCurrentContext();
|
||||
HttpServletResponse servletResponse = context.getResponse();
|
||||
List<Pair<String, String>> zuulResponseHeaders = context.getZuulResponseHeaders();
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
List<String> rd = (List<String>) RequestContext.getCurrentContext().get(
|
||||
"routingDebug");
|
||||
@@ -164,25 +178,24 @@ public class SendResponseFilter extends ZuulFilter {
|
||||
for (String it : rd) {
|
||||
debugHeader.append("[[[" + it + "]]]");
|
||||
}
|
||||
if (INCLUDE_DEBUG_HEADER.get())
|
||||
if (INCLUDE_DEBUG_HEADER.get()) {
|
||||
servletResponse.addHeader("X-Zuul-Debug-Header", debugHeader.toString());
|
||||
}
|
||||
}
|
||||
|
||||
if (zuulResponseHeaders != null) {
|
||||
for (Pair<String, String> it : zuulResponseHeaders) {
|
||||
servletResponse.addHeader(it.first(), it.second());
|
||||
}
|
||||
}
|
||||
|
||||
RequestContext ctx = RequestContext.getCurrentContext();
|
||||
Integer contentLength = ctx.getOriginContentLength();
|
||||
|
||||
// Only inserts Content-Length if origin provides it and origin response is not
|
||||
// gzipped
|
||||
if (SET_CONTENT_LENGTH.get()) {
|
||||
if (contentLength != null && !ctx.getResponseGZipped())
|
||||
if (contentLength != null && !ctx.getResponseGZipped()) {
|
||||
servletResponse.setContentLength(contentLength);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,23 @@
|
||||
/*
|
||||
* Copyright 2013-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.zuul.filters.pre;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import com.netflix.config.DynamicBooleanProperty;
|
||||
import com.netflix.config.DynamicPropertyFactory;
|
||||
import com.netflix.config.DynamicStringProperty;
|
||||
@@ -7,42 +25,42 @@ import com.netflix.zuul.ZuulFilter;
|
||||
import com.netflix.zuul.constants.ZuulConstants;
|
||||
import com.netflix.zuul.context.RequestContext;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
public class DebugFilter extends ZuulFilter {
|
||||
|
||||
static final DynamicBooleanProperty routingDebug = DynamicPropertyFactory.getInstance()
|
||||
.getBooleanProperty(ZuulConstants.ZUUL_DEBUG_REQUEST, false);
|
||||
static final DynamicStringProperty debugParameter = DynamicPropertyFactory.getInstance()
|
||||
.getStringProperty(ZuulConstants.ZUUL_DEBUG_PARAMETER, "debug");
|
||||
private static final DynamicBooleanProperty ROUTING_DEBUG = DynamicPropertyFactory
|
||||
.getInstance().getBooleanProperty(ZuulConstants.ZUUL_DEBUG_REQUEST, false);
|
||||
|
||||
@Override
|
||||
public String filterType() {
|
||||
return "pre";
|
||||
}
|
||||
private static final DynamicStringProperty DEBUG_PARAMETER = DynamicPropertyFactory
|
||||
.getInstance().getStringProperty(ZuulConstants.ZUUL_DEBUG_PARAMETER, "debug");
|
||||
|
||||
@Override
|
||||
public int filterOrder() {
|
||||
return 1;
|
||||
}
|
||||
@Override
|
||||
public String filterType() {
|
||||
return "pre";
|
||||
}
|
||||
|
||||
public boolean shouldFilter() {
|
||||
HttpServletRequest request = RequestContext.getCurrentContext().getRequest();
|
||||
if ("true".equals(request.getParameter(debugParameter.get())))
|
||||
return true;
|
||||
@Override
|
||||
public int filterOrder() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return routingDebug.get();
|
||||
}
|
||||
|
||||
public Object run() {
|
||||
RequestContext ctx = RequestContext.getCurrentContext();
|
||||
ctx.setDebugRouting(true);
|
||||
ctx.setDebugRequest(true);
|
||||
return null;
|
||||
}
|
||||
@Override
|
||||
public boolean shouldFilter() {
|
||||
HttpServletRequest request = RequestContext.getCurrentContext().getRequest();
|
||||
if ("true".equals(request.getParameter(DEBUG_PARAMETER.get()))) {
|
||||
return true;
|
||||
}
|
||||
return ROUTING_DEBUG.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object run() {
|
||||
RequestContext ctx = RequestContext.getCurrentContext();
|
||||
ctx.setDebugRouting(true);
|
||||
ctx.setDebugRequest(true);
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,3 +1,19 @@
|
||||
/*
|
||||
* Copyright 2013-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.zuul.filters.pre;
|
||||
|
||||
import java.io.IOException;
|
||||
@@ -23,13 +39,14 @@ import com.netflix.zuul.http.ServletInputStreamWrapper;
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
public class FormBodyWrapperFilter extends ZuulFilter {
|
||||
protected Field requestField = null;
|
||||
|
||||
private Field requestField;
|
||||
|
||||
public FormBodyWrapperFilter() {
|
||||
requestField = ReflectionUtils.findField(HttpServletRequestWrapper.class, "req",
|
||||
HttpServletRequest.class);
|
||||
Assert.notNull(requestField, "HttpServletRequestWrapper.req field not found");
|
||||
requestField.setAccessible(true);
|
||||
this.requestField = ReflectionUtils.findField(HttpServletRequestWrapper.class,
|
||||
"req", HttpServletRequest.class);
|
||||
Assert.notNull(this.requestField, "HttpServletRequestWrapper.req field not found");
|
||||
this.requestField.setAccessible(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -47,16 +64,16 @@ public class FormBodyWrapperFilter extends ZuulFilter {
|
||||
RequestContext ctx = RequestContext.getCurrentContext();
|
||||
HttpServletRequest request = ctx.getRequest();
|
||||
String contentType = request.getContentType();
|
||||
|
||||
//Don't use this filter on GET method
|
||||
if(contentType == null) {
|
||||
// Don't use this filter on GET method
|
||||
if (contentType == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//Only use this filter for MediaType : application/x-www-form-urlencoded
|
||||
// Only use this filter for MediaType : application/x-www-form-urlencoded
|
||||
try {
|
||||
return MediaType.APPLICATION_FORM_URLENCODED.includes(MediaType.valueOf(contentType));
|
||||
} catch (InvalidMediaTypeException imte) {
|
||||
return MediaType.APPLICATION_FORM_URLENCODED.includes(MediaType
|
||||
.valueOf(contentType));
|
||||
}
|
||||
catch (InvalidMediaTypeException ex) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -67,11 +84,12 @@ public class FormBodyWrapperFilter extends ZuulFilter {
|
||||
HttpServletRequest request = ctx.getRequest();
|
||||
if (request instanceof HttpServletRequestWrapper) {
|
||||
try {
|
||||
HttpServletRequest wrapped = (HttpServletRequest) requestField.get(request);
|
||||
requestField.set(request, new FormBodyRequestWrapper(wrapped));
|
||||
HttpServletRequest wrapped = (HttpServletRequest) this.requestField
|
||||
.get(request);
|
||||
this.requestField.set(request, new FormBodyRequestWrapper(wrapped));
|
||||
}
|
||||
catch (IllegalAccessException e) {
|
||||
Throwables.propagate(e);
|
||||
catch (IllegalAccessException ex) {
|
||||
Throwables.propagate(ex);
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -83,6 +101,7 @@ public class FormBodyWrapperFilter extends ZuulFilter {
|
||||
private class FormBodyRequestWrapper extends HttpServletRequestWrapper {
|
||||
|
||||
private HttpServletRequest request;
|
||||
|
||||
private byte[] contentData;
|
||||
|
||||
public FormBodyRequestWrapper(HttpServletRequest request) {
|
||||
@@ -92,28 +111,29 @@ public class FormBodyWrapperFilter extends ZuulFilter {
|
||||
|
||||
@Override
|
||||
public int getContentLength() {
|
||||
if (contentData == null) {
|
||||
contentData = buildContentData();
|
||||
if (this.contentData == null) {
|
||||
this.contentData = buildContentData();
|
||||
}
|
||||
return contentData.length;
|
||||
return this.contentData.length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ServletInputStream getInputStream() throws IOException {
|
||||
if (RequestContext.getCurrentContext().isChunkedRequestBody()) {
|
||||
return request.getInputStream();
|
||||
return this.request.getInputStream();
|
||||
}
|
||||
else {
|
||||
if (contentData == null) {
|
||||
contentData = buildContentData();
|
||||
if (this.contentData == null) {
|
||||
this.contentData = buildContentData();
|
||||
}
|
||||
return new ServletInputStreamWrapper(contentData);
|
||||
return new ServletInputStreamWrapper(this.contentData);
|
||||
}
|
||||
}
|
||||
|
||||
private byte[] buildContentData() {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
for (Entry<String, String[]> entry : request.getParameterMap().entrySet()) {
|
||||
for (Entry<String, String[]> entry : this.request.getParameterMap()
|
||||
.entrySet()) {
|
||||
for (String value : entry.getValue()) {
|
||||
if (builder.length() != 0) {
|
||||
builder.append("&");
|
||||
@@ -125,4 +145,5 @@ public class FormBodyWrapperFilter extends ZuulFilter {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,3 +1,19 @@
|
||||
/*
|
||||
* Copyright 2013-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.zuul.filters.pre;
|
||||
|
||||
import java.net.MalformedURLException;
|
||||
@@ -16,6 +32,7 @@ import com.netflix.zuul.ZuulFilter;
|
||||
import com.netflix.zuul.context.RequestContext;
|
||||
|
||||
public class PreDecorationFilter extends ZuulFilter {
|
||||
|
||||
private static Logger LOG = LoggerFactory.getLogger(PreDecorationFilter.class);
|
||||
|
||||
private ProxyRouteLocator routeLocator;
|
||||
@@ -45,20 +62,13 @@ public class PreDecorationFilter extends ZuulFilter {
|
||||
@Override
|
||||
public Object run() {
|
||||
RequestContext ctx = RequestContext.getCurrentContext();
|
||||
|
||||
final String requestURI = ctx.getRequest().getRequestURI();
|
||||
|
||||
ProxyRouteSpec route = routeLocator.getMatchingRoute(requestURI);
|
||||
|
||||
ProxyRouteSpec route = this.routeLocator.getMatchingRoute(requestURI);
|
||||
if (route != null) {
|
||||
|
||||
String location = route.getLocation();
|
||||
|
||||
if (location != null) {
|
||||
|
||||
ctx.put("requestURI", route.getPath());
|
||||
ctx.put("proxy", route.getId());
|
||||
|
||||
if (location.startsWith("http:") || location.startsWith("https:")) {
|
||||
ctx.setRouteHost(getUrl(location));
|
||||
ctx.addOriginResponseHeader("X-Zuul-Service", location);
|
||||
@@ -69,8 +79,7 @@ public class PreDecorationFilter extends ZuulFilter {
|
||||
ctx.setRouteHost(null);
|
||||
ctx.addOriginResponseHeader("X-Zuul-ServiceId", location);
|
||||
}
|
||||
|
||||
if (properties.isAddProxyHeaders()) {
|
||||
if (this.properties.isAddProxyHeaders()) {
|
||||
ctx.addZuulRequestHeader(
|
||||
"X-Forwarded-Host",
|
||||
ctx.getRequest().getServerName() + ":"
|
||||
@@ -92,8 +101,8 @@ public class PreDecorationFilter extends ZuulFilter {
|
||||
try {
|
||||
return new URL(target);
|
||||
}
|
||||
catch (MalformedURLException e) {
|
||||
throw new IllegalStateException("Target URL is malformed", e);
|
||||
catch (MalformedURLException ex) {
|
||||
throw new IllegalStateException("Target URL is malformed", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,130 +1,161 @@
|
||||
/*
|
||||
* Copyright 2013-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.zuul.filters.pre;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Collection;
|
||||
|
||||
import javax.servlet.AsyncContext;
|
||||
import javax.servlet.DispatcherType;
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.ServletRequest;
|
||||
import javax.servlet.ServletResponse;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.servlet.http.Part;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
|
||||
import com.google.common.base.Throwables;
|
||||
import com.netflix.zuul.ZuulFilter;
|
||||
import com.netflix.zuul.context.RequestContext;
|
||||
import com.netflix.zuul.http.HttpServletRequestWrapper;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
|
||||
import javax.servlet.*;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.servlet.http.Part;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
public class Servlet30WrapperFilter extends ZuulFilter {
|
||||
protected Field requestField = null;
|
||||
|
||||
public Servlet30WrapperFilter() {
|
||||
requestField = ReflectionUtils.findField(HttpServletRequestWrapper.class, "req",
|
||||
HttpServletRequest.class);
|
||||
Assert.notNull(requestField, "HttpServletRequestWrapper.req field not found");
|
||||
requestField.setAccessible(true);
|
||||
}
|
||||
protected Field requestField = null;
|
||||
|
||||
@Override
|
||||
public String filterType() {
|
||||
return "pre";
|
||||
}
|
||||
public Servlet30WrapperFilter() {
|
||||
this.requestField = ReflectionUtils.findField(HttpServletRequestWrapper.class,
|
||||
"req", HttpServletRequest.class);
|
||||
Assert.notNull(this.requestField, "HttpServletRequestWrapper.req field not found");
|
||||
this.requestField.setAccessible(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int filterOrder() {
|
||||
return 0;
|
||||
}
|
||||
@Override
|
||||
public String filterType() {
|
||||
return "pre";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldFilter() {
|
||||
return true; //TODO: only if in servlet 3.0 env
|
||||
}
|
||||
@Override
|
||||
public int filterOrder() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object run() {
|
||||
RequestContext ctx = RequestContext.getCurrentContext();
|
||||
HttpServletRequest request = ctx.getRequest();
|
||||
if (request instanceof HttpServletRequestWrapper) {
|
||||
try {
|
||||
request = (HttpServletRequest) requestField.get(request);
|
||||
} catch (IllegalAccessException e) {
|
||||
Throwables.propagate(e);
|
||||
}
|
||||
}
|
||||
ctx.setRequest(new Servlet30RequestWrapper(request));
|
||||
//ctx.setResponse(new HttpServletResponseWrapper(ctx.getResponse()));
|
||||
return null;
|
||||
}
|
||||
@Override
|
||||
public boolean shouldFilter() {
|
||||
return true; // TODO: only if in servlet 3.0 env
|
||||
}
|
||||
|
||||
private class Servlet30RequestWrapper extends HttpServletRequestWrapper {
|
||||
private HttpServletRequest request;
|
||||
@Override
|
||||
public Object run() {
|
||||
RequestContext ctx = RequestContext.getCurrentContext();
|
||||
HttpServletRequest request = ctx.getRequest();
|
||||
if (request instanceof HttpServletRequestWrapper) {
|
||||
try {
|
||||
request = (HttpServletRequest) this.requestField.get(request);
|
||||
}
|
||||
catch (IllegalAccessException ex) {
|
||||
Throwables.propagate(ex);
|
||||
}
|
||||
}
|
||||
ctx.setRequest(new Servlet30RequestWrapper(request));
|
||||
// ctx.setResponse(new HttpServletResponseWrapper(ctx.getResponse()));
|
||||
return null;
|
||||
}
|
||||
|
||||
Servlet30RequestWrapper(HttpServletRequest request) {
|
||||
super(request);
|
||||
this.request = request;
|
||||
}
|
||||
private class Servlet30RequestWrapper extends HttpServletRequestWrapper {
|
||||
private HttpServletRequest request;
|
||||
|
||||
@Override
|
||||
public boolean authenticate(HttpServletResponse response) throws IOException, ServletException {
|
||||
return request.authenticate(response);
|
||||
}
|
||||
Servlet30RequestWrapper(HttpServletRequest request) {
|
||||
super(request);
|
||||
this.request = request;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void login(String username, String password) throws ServletException {
|
||||
request.login(username, password);
|
||||
}
|
||||
@Override
|
||||
public boolean authenticate(HttpServletResponse response) throws IOException,
|
||||
ServletException {
|
||||
return this.request.authenticate(response);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void logout() throws ServletException {
|
||||
request.logout();
|
||||
}
|
||||
@Override
|
||||
public void login(String username, String password) throws ServletException {
|
||||
this.request.login(username, password);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Part> getParts() throws IOException, IllegalStateException, ServletException {
|
||||
return request.getParts();
|
||||
}
|
||||
@Override
|
||||
public void logout() throws ServletException {
|
||||
this.request.logout();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Part getPart(String name) throws IOException, IllegalStateException, ServletException {
|
||||
return request.getPart(name);
|
||||
}
|
||||
@Override
|
||||
public Collection<Part> getParts() throws IOException, IllegalStateException,
|
||||
ServletException {
|
||||
return this.request.getParts();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ServletContext getServletContext() {
|
||||
return request.getServletContext();
|
||||
}
|
||||
@Override
|
||||
public Part getPart(String name) throws IOException, IllegalStateException,
|
||||
ServletException {
|
||||
return this.request.getPart(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AsyncContext startAsync() {
|
||||
return request.startAsync();
|
||||
}
|
||||
@Override
|
||||
public ServletContext getServletContext() {
|
||||
return this.request.getServletContext();
|
||||
}
|
||||
|
||||
@Override
|
||||
public AsyncContext startAsync(ServletRequest servletRequest, ServletResponse servletResponse) {
|
||||
return request.startAsync(servletRequest, servletResponse);
|
||||
}
|
||||
@Override
|
||||
public AsyncContext startAsync() {
|
||||
return this.request.startAsync();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAsyncStarted() {
|
||||
return request.isAsyncStarted();
|
||||
}
|
||||
@Override
|
||||
public AsyncContext startAsync(ServletRequest servletRequest,
|
||||
ServletResponse servletResponse) {
|
||||
return this.request.startAsync(servletRequest, servletResponse);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAsyncSupported() {
|
||||
return request.isAsyncSupported();
|
||||
}
|
||||
@Override
|
||||
public boolean isAsyncStarted() {
|
||||
return this.request.isAsyncStarted();
|
||||
}
|
||||
|
||||
@Override
|
||||
public AsyncContext getAsyncContext() {
|
||||
return request.getAsyncContext();
|
||||
}
|
||||
@Override
|
||||
public boolean isAsyncSupported() {
|
||||
return this.request.isAsyncSupported();
|
||||
}
|
||||
|
||||
@Override
|
||||
public AsyncContext getAsyncContext() {
|
||||
return this.request.getAsyncContext();
|
||||
}
|
||||
|
||||
@Override
|
||||
public DispatcherType getDispatcherType() {
|
||||
return this.request.getDispatcherType();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public DispatcherType getDispatcherType() {
|
||||
return request.getDispatcherType();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,19 @@
|
||||
/*
|
||||
* Copyright 2013-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.zuul.filters.route;
|
||||
|
||||
import java.io.InputStream;
|
||||
@@ -11,10 +27,12 @@ import com.netflix.client.http.HttpRequest;
|
||||
import com.netflix.client.http.HttpRequest.Builder;
|
||||
import com.netflix.client.http.HttpRequest.Verb;
|
||||
import com.netflix.client.http.HttpResponse;
|
||||
import com.netflix.config.DynamicIntProperty;
|
||||
import com.netflix.config.DynamicPropertyFactory;
|
||||
import com.netflix.hystrix.HystrixCommand;
|
||||
import com.netflix.hystrix.HystrixCommandGroupKey;
|
||||
import com.netflix.hystrix.HystrixCommandProperties;
|
||||
import com.netflix.hystrix.HystrixCommandProperties.ExecutionIsolationStrategy;
|
||||
import com.netflix.niws.client.http.RestClient;
|
||||
import com.netflix.zuul.constants.ZuulConstants;
|
||||
import com.netflix.zuul.context.RequestContext;
|
||||
@@ -22,87 +40,83 @@ import com.netflix.zuul.context.RequestContext;
|
||||
/**
|
||||
* Hystrix wrapper around Eureka Ribbon command
|
||||
*
|
||||
* see original https://github.com/Netflix/zuul/blob/master/zuul-netflix/src/main/java/com/netflix/zuul/dependency/ribbon/hystrix/RibbonCommand.java
|
||||
* see original
|
||||
* https://github.com/Netflix/zuul/blob/master/zuul-netflix/src/main/java/com/
|
||||
* netflix/zuul/dependency/ribbon/hystrix/RibbonCommand.java
|
||||
*/
|
||||
public class RibbonCommand extends HystrixCommand<HttpResponse> {
|
||||
|
||||
private RestClient restClient;
|
||||
private Verb verb;
|
||||
private URI uri;
|
||||
private MultivaluedMap<String, String> headers;
|
||||
private MultivaluedMap<String, String> params;
|
||||
private InputStream requestEntity;
|
||||
private RestClient restClient;
|
||||
|
||||
public RibbonCommand(RestClient restClient,
|
||||
Verb verb,
|
||||
String uri,
|
||||
MultivaluedMap<String, String> headers,
|
||||
MultivaluedMap<String, String> params,
|
||||
InputStream requestEntity) throws URISyntaxException {
|
||||
this("default", restClient, verb, uri, headers, params, requestEntity);
|
||||
}
|
||||
private Verb verb;
|
||||
|
||||
public RibbonCommand(String commandKey,
|
||||
RestClient restClient,
|
||||
Verb verb,
|
||||
String uri,
|
||||
MultivaluedMap<String, String> headers,
|
||||
MultivaluedMap<String, String> params,
|
||||
InputStream requestEntity) throws URISyntaxException {
|
||||
private URI uri;
|
||||
|
||||
super(Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey(commandKey)).andCommandPropertiesDefaults(
|
||||
// we want to default to semaphore-isolation since this wraps
|
||||
// 2 others commands that are already thread isolated
|
||||
HystrixCommandProperties.Setter().withExecutionIsolationStrategy(HystrixCommandProperties.ExecutionIsolationStrategy.SEMAPHORE)
|
||||
.withExecutionIsolationSemaphoreMaxConcurrentRequests(DynamicPropertyFactory.getInstance().
|
||||
getIntProperty(ZuulConstants.ZUUL_EUREKA + commandKey + ".semaphore.maxSemaphores", 100).get())));
|
||||
private MultivaluedMap<String, String> headers;
|
||||
|
||||
this.restClient = restClient;
|
||||
this.verb = verb;
|
||||
this.uri = new URI(uri);
|
||||
this.headers = headers;
|
||||
this.params = params;
|
||||
this.requestEntity = requestEntity;
|
||||
}
|
||||
private MultivaluedMap<String, String> params;
|
||||
|
||||
@Override
|
||||
protected HttpResponse run() throws Exception {
|
||||
try {
|
||||
return forward();
|
||||
} catch (Exception e) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
private InputStream requestEntity;
|
||||
|
||||
private HttpResponse forward() throws Exception {
|
||||
public RibbonCommand(RestClient restClient, Verb verb, String uri,
|
||||
MultivaluedMap<String, String> headers,
|
||||
MultivaluedMap<String, String> params, InputStream requestEntity)
|
||||
throws URISyntaxException {
|
||||
this("default", restClient, verb, uri, headers, params, requestEntity);
|
||||
}
|
||||
|
||||
RequestContext context = RequestContext.getCurrentContext();
|
||||
public RibbonCommand(String commandKey, RestClient restClient, Verb verb, String uri,
|
||||
MultivaluedMap<String, String> headers,
|
||||
MultivaluedMap<String, String> params, InputStream requestEntity)
|
||||
throws URISyntaxException {
|
||||
super(getSetter(commandKey));
|
||||
this.restClient = restClient;
|
||||
this.verb = verb;
|
||||
this.uri = new URI(uri);
|
||||
this.headers = headers;
|
||||
this.params = params;
|
||||
this.requestEntity = requestEntity;
|
||||
}
|
||||
|
||||
Builder builder = HttpRequest.newBuilder().
|
||||
verb(verb).
|
||||
uri(uri).
|
||||
entity(requestEntity);
|
||||
private static HystrixCommand.Setter getSetter(String commandKey) {
|
||||
// we want to default to semaphore-isolation since this wraps
|
||||
// 2 others commands that are already thread isolated
|
||||
String name = ZuulConstants.ZUUL_EUREKA + commandKey + ".semaphore.maxSemaphores";
|
||||
DynamicIntProperty value = DynamicPropertyFactory.getInstance().getIntProperty(
|
||||
name, 100);
|
||||
HystrixCommandProperties.Setter setter = HystrixCommandProperties.Setter()
|
||||
.withExecutionIsolationStrategy(ExecutionIsolationStrategy.SEMAPHORE)
|
||||
.withExecutionIsolationSemaphoreMaxConcurrentRequests(value.get());
|
||||
return Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey(commandKey))
|
||||
.andCommandPropertiesDefaults(setter);
|
||||
}
|
||||
|
||||
for (String name : headers.keySet()) {
|
||||
List<String> values = headers.get(name);
|
||||
for (String value : values) {
|
||||
builder.header(name, value);
|
||||
}
|
||||
}
|
||||
@Override
|
||||
protected HttpResponse run() throws Exception {
|
||||
return forward();
|
||||
}
|
||||
|
||||
for (String name : params.keySet()) {
|
||||
List<String> values = params.get(name);
|
||||
for (String value : values) {
|
||||
builder.queryParams(name, value);
|
||||
}
|
||||
}
|
||||
private HttpResponse forward() throws Exception {
|
||||
RequestContext context = RequestContext.getCurrentContext();
|
||||
Builder builder = HttpRequest.newBuilder().verb(this.verb).uri(this.uri)
|
||||
.entity(this.requestEntity);
|
||||
for (String name : this.headers.keySet()) {
|
||||
List<String> values = this.headers.get(name);
|
||||
for (String value : values) {
|
||||
builder.header(name, value);
|
||||
}
|
||||
}
|
||||
for (String name : this.params.keySet()) {
|
||||
List<String> values = this.params.get(name);
|
||||
for (String value : values) {
|
||||
builder.queryParams(name, value);
|
||||
}
|
||||
}
|
||||
HttpRequest httpClientRequest = builder.build();
|
||||
HttpResponse response = this.restClient
|
||||
.executeWithLoadBalancer(httpClientRequest);
|
||||
context.set("ribbonResponse", response);
|
||||
return response;
|
||||
}
|
||||
|
||||
HttpRequest httpClientRequest = builder.build();
|
||||
|
||||
HttpResponse response = restClient.executeWithLoadBalancer(httpClientRequest);
|
||||
context.set("ribbonResponse", response);
|
||||
return response;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,19 @@
|
||||
/*
|
||||
* Copyright 2013-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.zuul.filters.route;
|
||||
|
||||
import java.io.IOException;
|
||||
@@ -59,25 +75,28 @@ public class RibbonRoutingFilter extends ZuulFilter {
|
||||
return 10;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldFilter() {
|
||||
RequestContext ctx = RequestContext.getCurrentContext();
|
||||
return (ctx.getRouteHost() == null && ctx.get("serviceId") != null && ctx
|
||||
.sendZuulResponse());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object run() {
|
||||
RequestContext context = RequestContext.getCurrentContext();
|
||||
HttpServletRequest request = context.getRequest();
|
||||
|
||||
MultiValueMap<String, String> headers = helper.buildZuulRequestHeaders(request);
|
||||
MultiValueMap<String, String> params = helper
|
||||
MultiValueMap<String, String> headers = this.helper
|
||||
.buildZuulRequestHeaders(request);
|
||||
MultiValueMap<String, String> params = this.helper
|
||||
.buildZuulRequestQueryParams(request);
|
||||
Verb verb = getVerb(request);
|
||||
InputStream requestEntity = getRequestBody(request);
|
||||
|
||||
String serviceId = (String) context.get("serviceId");
|
||||
|
||||
RestClient restClient = clientFactory.getClient(serviceId, RestClient.class);
|
||||
RestClient restClient = this.clientFactory.getClient(serviceId, RestClient.class);
|
||||
|
||||
String uri = request.getRequestURI();
|
||||
if (context.get("requestURI") != null) {
|
||||
@@ -92,9 +111,9 @@ public class RibbonRoutingFilter extends ZuulFilter {
|
||||
setResponse(response);
|
||||
return response;
|
||||
}
|
||||
catch (Exception e) {
|
||||
catch (Exception ex) {
|
||||
context.set("error.status_code", HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
|
||||
context.set("error.exception", e);
|
||||
context.set("error.exception", ex);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -102,29 +121,27 @@ public class RibbonRoutingFilter extends ZuulFilter {
|
||||
private HttpResponse forward(RestClient restClient, Verb verb, String uri,
|
||||
MultiValueMap<String, String> headers, MultiValueMap<String, String> params,
|
||||
InputStream requestEntity) throws Exception {
|
||||
|
||||
Map<String, Object> info = helper.debug(verb.verb(), uri, headers, params,
|
||||
Map<String, Object> info = this.helper.debug(verb.verb(), uri, headers, params,
|
||||
requestEntity);
|
||||
|
||||
RibbonCommand command = new RibbonCommand(restClient, verb, uri,
|
||||
convertHeaders(headers), convertHeaders(params), requestEntity);
|
||||
try {
|
||||
HttpResponse response = command.execute();
|
||||
helper.appendDebug(info, response.getStatus(),
|
||||
this.helper.appendDebug(info, response.getStatus(),
|
||||
revertHeaders(response.getHeaders()));
|
||||
return response;
|
||||
}
|
||||
catch (HystrixRuntimeException e) {
|
||||
catch (HystrixRuntimeException ex) {
|
||||
info.put("status", "500");
|
||||
if (e.getFallbackException() != null
|
||||
&& e.getFallbackException().getCause() != null
|
||||
&& e.getFallbackException().getCause() instanceof ClientException) {
|
||||
ClientException ex = (ClientException) e.getFallbackException()
|
||||
if (ex.getFallbackException() != null
|
||||
&& ex.getFallbackException().getCause() != null
|
||||
&& ex.getFallbackException().getCause() instanceof ClientException) {
|
||||
ClientException cause = (ClientException) ex.getFallbackException()
|
||||
.getCause();
|
||||
throw new ZuulException(ex, "Forwarding error", 500, ex.getErrorType()
|
||||
.toString());
|
||||
throw new ZuulException(cause, "Forwarding error", 500, cause
|
||||
.getErrorType().toString());
|
||||
}
|
||||
throw new ZuulException(e, "Forwarding error", 500, e.getFailureType()
|
||||
throw new ZuulException(ex, "Forwarding error", 500, ex.getFailureType()
|
||||
.toString());
|
||||
}
|
||||
|
||||
@@ -161,10 +178,9 @@ public class RibbonRoutingFilter extends ZuulFilter {
|
||||
requestEntity = request.getInputStream();
|
||||
}
|
||||
}
|
||||
catch (IOException e) {
|
||||
LOG.error("Error during getRequestBody", e);
|
||||
catch (IOException ex) {
|
||||
LOG.error("Error during getRequestBody", ex);
|
||||
}
|
||||
|
||||
return requestEntity;
|
||||
}
|
||||
|
||||
@@ -185,7 +201,7 @@ public class RibbonRoutingFilter extends ZuulFilter {
|
||||
}
|
||||
|
||||
private void setResponse(HttpResponse resp) throws ClientException, IOException {
|
||||
helper.setResponse(resp.getStatus(),
|
||||
this.helper.setResponse(resp.getStatus(),
|
||||
!resp.hasEntity() ? null : resp.getInputStream(),
|
||||
revertHeaders(resp.getHeaders()));
|
||||
}
|
||||
|
||||
@@ -1,3 +1,19 @@
|
||||
/*
|
||||
* Copyright 2013-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.zuul.filters.route;
|
||||
|
||||
import java.io.IOException;
|
||||
@@ -78,6 +94,7 @@ public class SimpleHostRoutingFilter extends ZuulFilter {
|
||||
private static final DynamicIntProperty SOCKET_TIMEOUT = DynamicPropertyFactory
|
||||
.getInstance().getIntProperty(ZuulConstants.ZUUL_HOST_SOCKET_TIMEOUT_MILLIS,
|
||||
10000);
|
||||
|
||||
private static final DynamicIntProperty CONNECTION_TIMEOUT = DynamicPropertyFactory
|
||||
.getInstance().getIntProperty(ZuulConstants.ZUUL_HOST_CONNECT_TIMEOUT_MILLIS,
|
||||
2000);
|
||||
@@ -85,7 +102,8 @@ public class SimpleHostRoutingFilter extends ZuulFilter {
|
||||
private static final AtomicReference<HttpClient> CLIENT = new AtomicReference<HttpClient>(
|
||||
newClient());
|
||||
|
||||
private static final Timer CONNECTION_MANAGER_TIMER = new Timer("SimpleHostRoutingFilter.CONNECTION_MANAGER_TIMER", true);
|
||||
private static final Timer CONNECTION_MANAGER_TIMER = new Timer(
|
||||
"SimpleHostRoutingFilter.CONNECTION_MANAGER_TIMER", true);
|
||||
|
||||
// cleans expired connections at an interval
|
||||
static {
|
||||
@@ -96,38 +114,18 @@ public class SimpleHostRoutingFilter extends ZuulFilter {
|
||||
public void run() {
|
||||
try {
|
||||
final HttpClient hc = CLIENT.get();
|
||||
if (hc == null)
|
||||
if (hc == null) {
|
||||
return;
|
||||
}
|
||||
hc.getConnectionManager().closeExpiredConnections();
|
||||
}
|
||||
catch (Throwable t) {
|
||||
LOG.error("error closing expired connections", t);
|
||||
catch (Throwable ex) {
|
||||
LOG.error("error closing expired connections", ex);
|
||||
}
|
||||
}
|
||||
}, 30000, 5000);
|
||||
}
|
||||
|
||||
private static final ClientConnectionManager newConnectionManager() throws Exception {
|
||||
|
||||
KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
|
||||
trustStore.load(null, null);
|
||||
|
||||
SSLSocketFactory sf = new MySSLSocketFactory(trustStore);
|
||||
sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
|
||||
|
||||
SchemeRegistry registry = new SchemeRegistry();
|
||||
registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
|
||||
registry.register(new Scheme("https", sf, 443));
|
||||
registry.register(new Scheme("https", sf, 8443));
|
||||
|
||||
ThreadSafeClientConnManager cm = new ThreadSafeClientConnManager(registry);
|
||||
cm.setMaxTotal(Integer.parseInt(System.getProperty("zuul.max.host.connections",
|
||||
"200")));
|
||||
cm.setDefaultMaxPerRoute(Integer.parseInt(System.getProperty(
|
||||
"zuul.max.host.connections", "20")));
|
||||
return cm;
|
||||
}
|
||||
|
||||
private ProxyRequestHelper helper;
|
||||
|
||||
public SimpleHostRoutingFilter() {
|
||||
@@ -153,71 +151,19 @@ public class SimpleHostRoutingFilter extends ZuulFilter {
|
||||
return 100;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldFilter() {
|
||||
return RequestContext.getCurrentContext().getRouteHost() != null
|
||||
&& RequestContext.getCurrentContext().sendZuulResponse();
|
||||
}
|
||||
|
||||
private static final void loadClient() {
|
||||
final HttpClient oldClient = CLIENT.get();
|
||||
CLIENT.set(newClient());
|
||||
if (oldClient != null) {
|
||||
CONNECTION_MANAGER_TIMER.schedule(new TimerTask() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
oldClient.getConnectionManager().shutdown();
|
||||
}
|
||||
catch (Throwable t) {
|
||||
LOG.error("error shutting down old connection manager", t);
|
||||
}
|
||||
}
|
||||
}, 30000);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static final HttpClient newClient() {
|
||||
// I could statically cache the connection manager but we will probably want to
|
||||
// make some of its properties
|
||||
// dynamic in the near future also
|
||||
try {
|
||||
DefaultHttpClient httpclient = new DefaultHttpClient(newConnectionManager());
|
||||
HttpParams httpParams = httpclient.getParams();
|
||||
httpParams.setIntParameter(CoreConnectionPNames.SO_TIMEOUT,
|
||||
SOCKET_TIMEOUT.get());
|
||||
httpParams.setIntParameter(CoreConnectionPNames.CONNECTION_TIMEOUT,
|
||||
CONNECTION_TIMEOUT.get());
|
||||
httpclient.setHttpRequestRetryHandler(new DefaultHttpRequestRetryHandler(0,
|
||||
false));
|
||||
httpParams.setParameter(ClientPNames.COOKIE_POLICY,
|
||||
org.apache.http.client.params.CookiePolicy.IGNORE_COOKIES);
|
||||
httpclient.setRedirectStrategy(new org.apache.http.client.RedirectStrategy() {
|
||||
@Override
|
||||
public boolean isRedirected(HttpRequest httpRequest,
|
||||
HttpResponse httpResponse, HttpContext httpContext) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public org.apache.http.client.methods.HttpUriRequest getRedirect(
|
||||
HttpRequest httpRequest, HttpResponse httpResponse,
|
||||
HttpContext httpContext) {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
return httpclient;
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object run() {
|
||||
RequestContext context = RequestContext.getCurrentContext();
|
||||
HttpServletRequest request = context.getRequest();
|
||||
MultiValueMap<String, String> headers = helper.buildZuulRequestHeaders(request);
|
||||
MultiValueMap<String, String> params = helper
|
||||
MultiValueMap<String, String> headers = this.helper
|
||||
.buildZuulRequestHeaders(request);
|
||||
MultiValueMap<String, String> params = this.helper
|
||||
.buildZuulRequestQueryParams(request);
|
||||
String verb = getVerb(request);
|
||||
InputStream requestEntity = getRequestBody(request);
|
||||
@@ -233,9 +179,9 @@ public class SimpleHostRoutingFilter extends ZuulFilter {
|
||||
params, requestEntity);
|
||||
setResponse(response);
|
||||
}
|
||||
catch (Exception e) {
|
||||
catch (Exception ex) {
|
||||
context.set("error.status_code", HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
|
||||
context.set("error.exception", e);
|
||||
context.set("error.exception", ex);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -244,16 +190,12 @@ public class SimpleHostRoutingFilter extends ZuulFilter {
|
||||
HttpServletRequest request, MultiValueMap<String, String> headers,
|
||||
MultiValueMap<String, String> params, InputStream requestEntity)
|
||||
throws Exception {
|
||||
|
||||
Map<String, Object> info = helper
|
||||
.debug(verb, uri, headers, params, requestEntity);
|
||||
|
||||
Map<String, Object> info = this.helper.debug(verb, uri, headers, params,
|
||||
requestEntity);
|
||||
URL host = RequestContext.getCurrentContext().getRouteHost();
|
||||
HttpHost httpHost = getHttpHost(host);
|
||||
uri = StringUtils.cleanPath(host.getPath() + uri);
|
||||
|
||||
HttpRequest httpRequest;
|
||||
|
||||
switch (verb.toUpperCase()) {
|
||||
case "POST":
|
||||
HttpPost httpPost = new HttpPost(uri + getQueryString());
|
||||
@@ -271,13 +213,12 @@ public class SimpleHostRoutingFilter extends ZuulFilter {
|
||||
httpRequest = new BasicHttpRequest(verb, uri + getQueryString());
|
||||
LOG.debug(uri + getQueryString());
|
||||
}
|
||||
|
||||
try {
|
||||
httpRequest.setHeaders(convertHeaders(headers));
|
||||
LOG.debug(httpHost.getHostName() + " " + httpHost.getPort() + " "
|
||||
+ httpHost.getSchemeName());
|
||||
HttpResponse zuulResponse = forwardRequest(httpclient, httpHost, httpRequest);
|
||||
helper.appendDebug(info, zuulResponse.getStatusLine().getStatusCode(),
|
||||
this.helper.appendDebug(info, zuulResponse.getStatusLine().getStatusCode(),
|
||||
revertHeaders(zuulResponse.getAllHeaders()));
|
||||
return zuulResponse;
|
||||
}
|
||||
@@ -287,7 +228,6 @@ public class SimpleHostRoutingFilter extends ZuulFilter {
|
||||
// immediate deallocation of all system resources
|
||||
// httpclient.getConnectionManager().shutdown();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private MultiValueMap<String, String> revertHeaders(Header[] headers) {
|
||||
@@ -334,7 +274,7 @@ public class SimpleHostRoutingFilter extends ZuulFilter {
|
||||
try {
|
||||
requestEntity = request.getInputStream();
|
||||
}
|
||||
catch (IOException e) {
|
||||
catch (IOException ex) {
|
||||
// no requestBody is ok.
|
||||
}
|
||||
return requestEntity;
|
||||
@@ -346,47 +286,123 @@ public class SimpleHostRoutingFilter extends ZuulFilter {
|
||||
}
|
||||
|
||||
private void setResponse(HttpResponse response) throws IOException {
|
||||
helper.setResponse(response.getStatusLine().getStatusCode(),
|
||||
this.helper.setResponse(response.getStatusLine().getStatusCode(),
|
||||
response.getEntity() == null ? null : response.getEntity().getContent(),
|
||||
revertHeaders(response.getAllHeaders()));
|
||||
}
|
||||
|
||||
private static ClientConnectionManager newConnectionManager() throws Exception {
|
||||
KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
|
||||
trustStore.load(null, null);
|
||||
SSLSocketFactory sf = new MySSLSocketFactory(trustStore);
|
||||
sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
|
||||
SchemeRegistry registry = new SchemeRegistry();
|
||||
registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
|
||||
registry.register(new Scheme("https", sf, 443));
|
||||
registry.register(new Scheme("https", sf, 8443));
|
||||
ThreadSafeClientConnManager cm = new ThreadSafeClientConnManager(registry);
|
||||
cm.setMaxTotal(Integer.parseInt(System.getProperty("zuul.max.host.connections",
|
||||
"200")));
|
||||
cm.setDefaultMaxPerRoute(Integer.parseInt(System.getProperty(
|
||||
"zuul.max.host.connections", "20")));
|
||||
return cm;
|
||||
}
|
||||
|
||||
private static void loadClient() {
|
||||
final HttpClient oldClient = CLIENT.get();
|
||||
CLIENT.set(newClient());
|
||||
if (oldClient != null) {
|
||||
CONNECTION_MANAGER_TIMER.schedule(new TimerTask() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
oldClient.getConnectionManager().shutdown();
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
LOG.error("error shutting down old connection manager", ex);
|
||||
}
|
||||
}
|
||||
}, 30000);
|
||||
}
|
||||
}
|
||||
|
||||
private static HttpClient newClient() {
|
||||
// I could statically cache the connection manager but we will probably want to
|
||||
// make some of its properties
|
||||
// dynamic in the near future also
|
||||
try {
|
||||
DefaultHttpClient httpclient = new DefaultHttpClient(newConnectionManager());
|
||||
HttpParams httpParams = httpclient.getParams();
|
||||
httpParams.setIntParameter(CoreConnectionPNames.SO_TIMEOUT,
|
||||
SOCKET_TIMEOUT.get());
|
||||
httpParams.setIntParameter(CoreConnectionPNames.CONNECTION_TIMEOUT,
|
||||
CONNECTION_TIMEOUT.get());
|
||||
httpclient.setHttpRequestRetryHandler(new DefaultHttpRequestRetryHandler(0,
|
||||
false));
|
||||
httpParams.setParameter(ClientPNames.COOKIE_POLICY,
|
||||
org.apache.http.client.params.CookiePolicy.IGNORE_COOKIES);
|
||||
httpclient.setRedirectStrategy(new org.apache.http.client.RedirectStrategy() {
|
||||
@Override
|
||||
public boolean isRedirected(HttpRequest httpRequest,
|
||||
HttpResponse httpResponse, HttpContext httpContext) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public org.apache.http.client.methods.HttpUriRequest getRedirect(
|
||||
HttpRequest httpRequest, HttpResponse httpResponse,
|
||||
HttpContext httpContext) {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
return httpclient;
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public static class MySSLSocketFactory extends SSLSocketFactory {
|
||||
SSLContext sslContext = SSLContext.getInstance("TLS");
|
||||
|
||||
public MySSLSocketFactory(KeyStore truststore) throws NoSuchAlgorithmException,
|
||||
KeyManagementException, KeyStoreException, UnrecoverableKeyException {
|
||||
super(truststore);
|
||||
|
||||
TrustManager tm = new X509TrustManager() {
|
||||
|
||||
@Override
|
||||
public void checkClientTrusted(X509Certificate[] chain, String authType)
|
||||
throws CertificateException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkServerTrusted(X509Certificate[] chain, String authType)
|
||||
throws CertificateException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public X509Certificate[] getAcceptedIssuers() {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
TrustManager[] tms = new TrustManager[1];
|
||||
tms[0] = tm;
|
||||
sslContext.init(null, tms, null);
|
||||
this.sslContext.init(null, tms, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Socket createSocket(Socket socket, String host, int port, boolean autoClose)
|
||||
throws IOException, UnknownHostException {
|
||||
return sslContext.getSocketFactory().createSocket(socket, host, port,
|
||||
return this.sslContext.getSocketFactory().createSocket(socket, host, port,
|
||||
autoClose);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Socket createSocket() throws IOException {
|
||||
return sslContext.getSocketFactory().createSocket();
|
||||
return this.sslContext.getSocketFactory().createSocket();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -29,7 +29,8 @@ import org.springframework.cloud.netflix.zuul.SimpleZuulServerApplicationTests;
|
||||
* @author Dave Syer
|
||||
*/
|
||||
@RunWith(Suite.class)
|
||||
@SuiteClasses({ SimpleZuulServerApplicationTests.class, SampleZuulProxyApplicationTests.class })
|
||||
@SuiteClasses({ SimpleZuulServerApplicationTests.class,
|
||||
SampleZuulProxyApplicationTests.class })
|
||||
@Ignore
|
||||
public class AdhocTestSuite {
|
||||
|
||||
|
||||
@@ -13,34 +13,36 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.cloud.netflix.archaius;
|
||||
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
package org.springframework.cloud.netflix.archaius;
|
||||
|
||||
import org.apache.commons.configuration.AbstractConfiguration;
|
||||
import org.junit.After;
|
||||
import org.junit.Test;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
public class ArchaiusAutoConfigurationTests {
|
||||
|
||||
private AnnotationConfigApplicationContext context;
|
||||
|
||||
|
||||
@After
|
||||
public void close() {
|
||||
if (context!=null) {
|
||||
context.close();
|
||||
if (this.context != null) {
|
||||
this.context.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void configurationCreated() {
|
||||
context = new AnnotationConfigApplicationContext(ArchaiusAutoConfiguration.class);
|
||||
AbstractConfiguration config = context.getBean(ConfigurableEnvironmentConfiguration.class);
|
||||
this.context = new AnnotationConfigApplicationContext(
|
||||
ArchaiusAutoConfiguration.class);
|
||||
AbstractConfiguration config = this.context
|
||||
.getBean(ConfigurableEnvironmentConfiguration.class);
|
||||
assertNotNull(config.getString("java.io.tmpdir"));
|
||||
}
|
||||
|
||||
|
||||
@@ -13,10 +13,8 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.cloud.netflix.archaius;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
package org.springframework.cloud.netflix.archaius;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@@ -26,9 +24,11 @@ import org.springframework.core.env.StandardEnvironment;
|
||||
import com.netflix.config.ConcurrentCompositeConfiguration;
|
||||
import com.netflix.config.ConfigurationManager;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
public class ArchaiusEndpointTests {
|
||||
|
||||
@@ -37,17 +37,19 @@ public class ArchaiusEndpointTests {
|
||||
@Test
|
||||
public void detectsPropertiesWhenSet() {
|
||||
ConfigurationManager.getConfigInstance().setProperty("foo", "bar");
|
||||
assertTrue(endpoint.invoke().containsKey("foo"));
|
||||
assertTrue(this.endpoint.invoke().containsKey("foo"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void doesNotIncludeSpringEnvironment() {
|
||||
ConcurrentCompositeConfiguration composite = new ConcurrentCompositeConfiguration(ConfigurationManager.getConfigInstance());
|
||||
ConfigurableEnvironmentConfiguration config = new ConfigurableEnvironmentConfiguration(new StandardEnvironment());
|
||||
ConcurrentCompositeConfiguration composite = new ConcurrentCompositeConfiguration(
|
||||
ConfigurationManager.getConfigInstance());
|
||||
ConfigurableEnvironmentConfiguration config = new ConfigurableEnvironmentConfiguration(
|
||||
new StandardEnvironment());
|
||||
assertTrue(config.containsKey("user.dir"));
|
||||
composite.addConfiguration(config);
|
||||
ConfigurationManager.getConfigInstance().setProperty("foo", "bar");
|
||||
Map<String, Object> map = endpoint.invoke();
|
||||
Map<String, Object> map = this.endpoint.invoke();
|
||||
assertTrue(map.containsKey("foo"));
|
||||
assertFalse(map.containsKey("user.dir"));
|
||||
}
|
||||
|
||||
@@ -13,9 +13,8 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.cloud.netflix.config;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
package org.springframework.cloud.netflix.config;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Test;
|
||||
@@ -28,9 +27,11 @@ import org.springframework.context.annotation.AnnotationConfigApplicationContext
|
||||
import com.netflix.appinfo.InstanceInfo;
|
||||
import com.netflix.discovery.DiscoveryClient;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
public class DiscoveryClientConfigServiceBootstrapConfigurationTests {
|
||||
|
||||
@@ -43,41 +44,45 @@ public class DiscoveryClientConfigServiceBootstrapConfigurationTests {
|
||||
|
||||
@After
|
||||
public void close() {
|
||||
if (context != null) {
|
||||
context.close();
|
||||
if (this.context != null) {
|
||||
this.context.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void offByDefault() throws Exception {
|
||||
context = new AnnotationConfigApplicationContext(
|
||||
this.context = new AnnotationConfigApplicationContext(
|
||||
DiscoveryClientConfigServiceBootstrapConfiguration.class);
|
||||
assertEquals(0, context.getBeanNamesForType(DiscoveryClient.class).length);
|
||||
assertEquals(0, this.context.getBeanNamesForType(DiscoveryClient.class).length);
|
||||
assertEquals(
|
||||
0,
|
||||
context.getBeanNamesForType(DiscoveryClientConfigServiceBootstrapConfiguration.class).length);
|
||||
this.context
|
||||
.getBeanNamesForType(DiscoveryClientConfigServiceBootstrapConfiguration.class).length);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onWhenRequested() throws Exception {
|
||||
Mockito.when(client.getNextServerFromEureka("CONFIGSERVER", false)).thenReturn(
|
||||
info);
|
||||
given(this.client.getNextServerFromEureka("CONFIGSERVER", false)).willReturn(
|
||||
this.info);
|
||||
setup("spring.cloud.config.discovery.enabled=true");
|
||||
assertEquals(
|
||||
1,
|
||||
context.getBeanNamesForType(DiscoveryClientConfigServiceBootstrapConfiguration.class).length);
|
||||
Mockito.verify(client).getNextServerFromEureka("CONFIGSERVER", false);
|
||||
ConfigClientProperties locator = context.getBean(ConfigClientProperties.class);
|
||||
this.context
|
||||
.getBeanNamesForType(DiscoveryClientConfigServiceBootstrapConfiguration.class).length);
|
||||
Mockito.verify(this.client).getNextServerFromEureka("CONFIGSERVER", false);
|
||||
ConfigClientProperties locator = this.context
|
||||
.getBean(ConfigClientProperties.class);
|
||||
assertEquals("http://foo:7001/", locator.getUri());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setsPasssword() throws Exception {
|
||||
info.getMetadata().put("password", "bar");
|
||||
Mockito.when(client.getNextServerFromEureka("CONFIGSERVER", false)).thenReturn(
|
||||
info);
|
||||
this.info.getMetadata().put("password", "bar");
|
||||
given(this.client.getNextServerFromEureka("CONFIGSERVER", false)).willReturn(
|
||||
this.info);
|
||||
setup("spring.cloud.config.discovery.enabled=true");
|
||||
ConfigClientProperties locator = context.getBean(ConfigClientProperties.class);
|
||||
ConfigClientProperties locator = this.context
|
||||
.getBean(ConfigClientProperties.class);
|
||||
assertEquals("http://foo:7001/", locator.getUri());
|
||||
assertEquals("bar", locator.getPassword());
|
||||
assertEquals("user", locator.getUsername());
|
||||
@@ -85,23 +90,24 @@ public class DiscoveryClientConfigServiceBootstrapConfigurationTests {
|
||||
|
||||
@Test
|
||||
public void setsPath() throws Exception {
|
||||
info.getMetadata().put("configPath", "/bar");
|
||||
Mockito.when(client.getNextServerFromEureka("CONFIGSERVER", false)).thenReturn(
|
||||
info);
|
||||
this.info.getMetadata().put("configPath", "/bar");
|
||||
given(this.client.getNextServerFromEureka("CONFIGSERVER", false)).willReturn(
|
||||
this.info);
|
||||
setup("spring.cloud.config.discovery.enabled=true");
|
||||
ConfigClientProperties locator = context.getBean(ConfigClientProperties.class);
|
||||
ConfigClientProperties locator = this.context
|
||||
.getBean(ConfigClientProperties.class);
|
||||
assertEquals("http://foo:7001/bar", locator.getUri());
|
||||
}
|
||||
|
||||
private void setup(String... env) {
|
||||
context = new AnnotationConfigApplicationContext();
|
||||
EnvironmentTestUtils.addEnvironment(context, env);
|
||||
context.getDefaultListableBeanFactory().registerSingleton("mockDiscoveryClient",
|
||||
client);
|
||||
context.register(PropertyPlaceholderAutoConfiguration.class,
|
||||
this.context = new AnnotationConfigApplicationContext();
|
||||
EnvironmentTestUtils.addEnvironment(this.context, env);
|
||||
this.context.getDefaultListableBeanFactory().registerSingleton(
|
||||
"mockDiscoveryClient", this.client);
|
||||
this.context.register(PropertyPlaceholderAutoConfiguration.class,
|
||||
DiscoveryClientConfigServiceBootstrapConfiguration.class,
|
||||
ConfigClientProperties.class);
|
||||
context.refresh();
|
||||
this.context.refresh();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -13,9 +13,8 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.cloud.netflix.config;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
package org.springframework.cloud.netflix.config;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Test;
|
||||
@@ -28,9 +27,10 @@ import org.springframework.context.annotation.AnnotationConfigApplicationContext
|
||||
|
||||
import com.netflix.appinfo.EurekaInstanceConfig;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
public class EurekaClientConfigServerAutoConfigurationTests {
|
||||
|
||||
@@ -38,29 +38,30 @@ public class EurekaClientConfigServerAutoConfigurationTests {
|
||||
|
||||
@After
|
||||
public void close() {
|
||||
if (context != null) {
|
||||
context.close();
|
||||
if (this.context != null) {
|
||||
this.context.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void offByDefault() throws Exception {
|
||||
context = new AnnotationConfigApplicationContext(
|
||||
this.context = new AnnotationConfigApplicationContext(
|
||||
EurekaClientConfigServerAutoConfiguration.class);
|
||||
assertEquals(0,
|
||||
context.getBeanNamesForType(EurekaInstanceConfigBean.class).length);
|
||||
this.context.getBeanNamesForType(EurekaInstanceConfigBean.class).length);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onWhenRequested() throws Exception {
|
||||
setup("spring.cloud.config.server.prefix=/config");
|
||||
assertEquals(1, context.getBeanNamesForType(EurekaInstanceConfig.class).length);
|
||||
EurekaInstanceConfig instance = context.getBean(EurekaInstanceConfig.class);
|
||||
assertEquals(1,
|
||||
this.context.getBeanNamesForType(EurekaInstanceConfig.class).length);
|
||||
EurekaInstanceConfig instance = this.context.getBean(EurekaInstanceConfig.class);
|
||||
assertEquals("/config", instance.getMetadataMap().get("configPath"));
|
||||
}
|
||||
|
||||
private void setup(String... env) {
|
||||
context = new SpringApplicationBuilder(
|
||||
this.context = new SpringApplicationBuilder(
|
||||
PropertyPlaceholderAutoConfiguration.class,
|
||||
EurekaClientConfigServerAutoConfiguration.class,
|
||||
ConfigServerProperties.class, EurekaInstanceConfigBean.class).web(false)
|
||||
|
||||
@@ -13,9 +13,8 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.cloud.netflix.eureka;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
package org.springframework.cloud.netflix.eureka;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
@@ -29,9 +28,10 @@ import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.env.CompositePropertySource;
|
||||
import org.springframework.core.env.MapPropertySource;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
public class EurekaClientConfigBeanTests {
|
||||
|
||||
@@ -39,65 +39,64 @@ public class EurekaClientConfigBeanTests {
|
||||
|
||||
@After
|
||||
public void init() {
|
||||
if (context != null) {
|
||||
context.close();
|
||||
if (this.context != null) {
|
||||
this.context.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void basicBinding() {
|
||||
EnvironmentTestUtils.addEnvironment(context,
|
||||
EnvironmentTestUtils.addEnvironment(this.context,
|
||||
"eureka.client.proxyHost=example.com");
|
||||
context.register(PropertyPlaceholderAutoConfiguration.class,
|
||||
this.context.register(PropertyPlaceholderAutoConfiguration.class,
|
||||
TestConfiguration.class);
|
||||
context.refresh();
|
||||
assertEquals("example.com", context.getBean(EurekaClientConfigBean.class)
|
||||
this.context.refresh();
|
||||
assertEquals("example.com", this.context.getBean(EurekaClientConfigBean.class)
|
||||
.getProxyHost());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void serviceUrl() {
|
||||
EnvironmentTestUtils.addEnvironment(context,
|
||||
EnvironmentTestUtils.addEnvironment(this.context,
|
||||
"eureka.client.serviceUrl.defaultZone:http://example.com");
|
||||
context.register(PropertyPlaceholderAutoConfiguration.class,
|
||||
this.context.register(PropertyPlaceholderAutoConfiguration.class,
|
||||
TestConfiguration.class);
|
||||
context.refresh();
|
||||
this.context.refresh();
|
||||
assertEquals("{defaultZone=http://example.com}",
|
||||
context.getBean(EurekaClientConfigBean.class).getServiceUrl().toString());
|
||||
assertEquals(
|
||||
"[http://example.com]",
|
||||
context.getBean(EurekaClientConfigBean.class)
|
||||
this.context.getBean(EurekaClientConfigBean.class).getServiceUrl()
|
||||
.toString());
|
||||
assertEquals("[http://example.com]",
|
||||
this.context.getBean(EurekaClientConfigBean.class)
|
||||
.getEurekaServerServiceUrls("defaultZone").toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void serviceUrlWithCompositePropertySource() {
|
||||
CompositePropertySource source = new CompositePropertySource("composite");
|
||||
context.getEnvironment().getPropertySources().addFirst(source);
|
||||
this.context.getEnvironment().getPropertySources().addFirst(source);
|
||||
source.addPropertySource(new MapPropertySource("config", Collections
|
||||
.<String, Object> singletonMap("eureka.client.serviceUrl.defaultZone",
|
||||
"http://example.com")));
|
||||
context.register(PropertyPlaceholderAutoConfiguration.class,
|
||||
this.context.register(PropertyPlaceholderAutoConfiguration.class,
|
||||
TestConfiguration.class);
|
||||
context.refresh();
|
||||
this.context.refresh();
|
||||
assertEquals("{defaultZone=http://example.com}",
|
||||
context.getBean(EurekaClientConfigBean.class).getServiceUrl().toString());
|
||||
assertEquals(
|
||||
"[http://example.com]",
|
||||
context.getBean(EurekaClientConfigBean.class)
|
||||
this.context.getBean(EurekaClientConfigBean.class).getServiceUrl()
|
||||
.toString());
|
||||
assertEquals("[http://example.com]",
|
||||
this.context.getBean(EurekaClientConfigBean.class)
|
||||
.getEurekaServerServiceUrls("defaultZone").toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void serviceUrlWithDefault() {
|
||||
EnvironmentTestUtils.addEnvironment(context,
|
||||
EnvironmentTestUtils.addEnvironment(this.context,
|
||||
"eureka.client.serviceUrl.defaultZone:http://example.com");
|
||||
context.register(PropertyPlaceholderAutoConfiguration.class,
|
||||
this.context.register(PropertyPlaceholderAutoConfiguration.class,
|
||||
TestConfiguration.class);
|
||||
context.refresh();
|
||||
assertEquals(
|
||||
"[http://example.com]",
|
||||
context.getBean(EurekaClientConfigBean.class)
|
||||
this.context.refresh();
|
||||
assertEquals("[http://example.com]",
|
||||
this.context.getBean(EurekaClientConfigBean.class)
|
||||
.getEurekaServerServiceUrls("defaultZone").toString());
|
||||
}
|
||||
|
||||
|
||||
@@ -13,11 +13,8 @@
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
package org.springframework.cloud.netflix.eureka;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.springframework.boot.test.EnvironmentTestUtils.addEnvironment;
|
||||
package org.springframework.cloud.netflix.eureka;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Test;
|
||||
@@ -30,9 +27,12 @@ import org.springframework.context.annotation.Configuration;
|
||||
import com.netflix.appinfo.InstanceInfo.InstanceStatus;
|
||||
import com.netflix.appinfo.UniqueIdentifier;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.springframework.boot.test.EnvironmentTestUtils.addEnvironment;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
public class EurekaInstanceConfigBeanTests {
|
||||
|
||||
@@ -40,8 +40,8 @@ public class EurekaInstanceConfigBeanTests {
|
||||
|
||||
@After
|
||||
public void init() {
|
||||
if (context != null) {
|
||||
context.close();
|
||||
if (this.context != null) {
|
||||
this.context.close();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@ public class EurekaInstanceConfigBeanTests {
|
||||
|
||||
@Test
|
||||
public void basicBinding() {
|
||||
addEnvironment(context, "eureka.instance.appGroupName=mygroup");
|
||||
addEnvironment(this.context, "eureka.instance.appGroupName=mygroup");
|
||||
setupContext();
|
||||
assertEquals("mygroup", getInstanceConfig().getAppGroupName());
|
||||
}
|
||||
@@ -81,7 +81,7 @@ public class EurekaInstanceConfigBeanTests {
|
||||
}
|
||||
|
||||
private void testNonSecurePort(String propName) {
|
||||
addEnvironment(context, propName + ":8888");
|
||||
addEnvironment(this.context, propName + ":8888");
|
||||
setupContext();
|
||||
assertEquals(8888, getInstanceConfig().getNonSecurePort());
|
||||
}
|
||||
@@ -95,13 +95,13 @@ public class EurekaInstanceConfigBeanTests {
|
||||
|
||||
@Test(expected = BeanCreationException.class)
|
||||
public void testBadInitialStatus() {
|
||||
addEnvironment(context, "eureka.instance.initial-status:FOO");
|
||||
addEnvironment(this.context, "eureka.instance.initial-status:FOO");
|
||||
setupContext();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCustomInitialStatus() {
|
||||
addEnvironment(context, "eureka.instance.initial-status:STARTING");
|
||||
addEnvironment(this.context, "eureka.instance.initial-status:STARTING");
|
||||
setupContext();
|
||||
assertEquals("initialStatus wrong", InstanceStatus.STARTING, getInstanceConfig()
|
||||
.getInitialStatus());
|
||||
@@ -109,17 +109,17 @@ public class EurekaInstanceConfigBeanTests {
|
||||
|
||||
@Test
|
||||
public void testPerferIpAddress() throws Exception {
|
||||
addEnvironment(context, "eureka.instance.preferIpAddress:true");
|
||||
addEnvironment(this.context, "eureka.instance.preferIpAddress:true");
|
||||
setupContext();
|
||||
EurekaInstanceConfigBean instance = getInstanceConfig();
|
||||
assertTrue("Wrong hostname: " + instance.getHostname(),
|
||||
getInstanceConfig().getHostname().equals(instance.getIpAddress()));
|
||||
assertTrue("Wrong hostname: " + instance.getHostname(), getInstanceConfig()
|
||||
.getHostname().equals(instance.getIpAddress()));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPerferIpAddressInDatacenter() throws Exception {
|
||||
addEnvironment(context, "eureka.instance.preferIpAddress:true");
|
||||
addEnvironment(this.context, "eureka.instance.preferIpAddress:true");
|
||||
setupContext();
|
||||
EurekaInstanceConfigBean instance = getInstanceConfig();
|
||||
String id = ((UniqueIdentifier) instance.getDataCenterInfo()).getId();
|
||||
@@ -128,13 +128,13 @@ public class EurekaInstanceConfigBeanTests {
|
||||
}
|
||||
|
||||
private void setupContext() {
|
||||
context.register(PropertyPlaceholderAutoConfiguration.class,
|
||||
this.context.register(PropertyPlaceholderAutoConfiguration.class,
|
||||
TestConfiguration.class);
|
||||
context.refresh();
|
||||
this.context.refresh();
|
||||
}
|
||||
|
||||
protected EurekaInstanceConfigBean getInstanceConfig() {
|
||||
return context.getBean(EurekaInstanceConfigBean.class);
|
||||
return this.context.getBean(EurekaInstanceConfigBean.class);
|
||||
}
|
||||
|
||||
@Configuration
|
||||
|
||||
@@ -1,3 +1,19 @@
|
||||
/*
|
||||
* Copyright 2013-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.eureka.sample;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
@@ -1,3 +1,19 @@
|
||||
/*
|
||||
* Copyright 2013-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.eureka.sample;
|
||||
|
||||
import org.springframework.boot.actuate.metrics.repository.InMemoryMetricRepository;
|
||||
@@ -25,21 +41,22 @@ public class EurekaSampleApplication {
|
||||
return new InMemoryMetricRepository();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public HealthCheckHandler healthCheckHandler() {
|
||||
return new HealthCheckHandler() {
|
||||
@Override
|
||||
public InstanceInfo.InstanceStatus getStatus(InstanceInfo.InstanceStatus currentStatus) {
|
||||
return InstanceInfo.InstanceStatus.UP;
|
||||
}
|
||||
};
|
||||
}
|
||||
@Bean
|
||||
public HealthCheckHandler healthCheckHandler() {
|
||||
return new HealthCheckHandler() {
|
||||
@Override
|
||||
public InstanceInfo.InstanceStatus getStatus(
|
||||
InstanceInfo.InstanceStatus currentStatus) {
|
||||
return InstanceInfo.InstanceStatus.UP;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@RequestMapping("/")
|
||||
public String home() {
|
||||
return "Hello world";
|
||||
}
|
||||
|
||||
|
||||
public static void main(String[] args) {
|
||||
new SpringApplicationBuilder(EurekaSampleApplication.class).web(true).run(args);
|
||||
}
|
||||
|
||||
@@ -1,7 +1,20 @@
|
||||
package org.springframework.cloud.netflix.feign;
|
||||
/*
|
||||
* Copyright 2013-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
package org.springframework.cloud.netflix.feign;
|
||||
|
||||
import java.lang.reflect.InvocationHandler;
|
||||
import java.lang.reflect.Proxy;
|
||||
@@ -28,6 +41,9 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
@@ -38,74 +54,75 @@ import org.springframework.web.bind.annotation.RestController;
|
||||
@DirtiesContext
|
||||
public class FeignClientTests extends FeignConfiguration {
|
||||
|
||||
@Value("${local.server.port}")
|
||||
private int port = 0;
|
||||
@Value("${local.server.port}")
|
||||
private int port = 0;
|
||||
|
||||
@Autowired
|
||||
TestClient testClient;
|
||||
TestClient testClient;
|
||||
|
||||
//@FeignClient(value = "http://localhost:9876", loadbalance = false)
|
||||
// @FeignClient(value = "http://localhost:9876", loadbalance = false)
|
||||
@FeignClient("feignclienttest")
|
||||
protected static interface TestClient {
|
||||
@RequestMapping(method = RequestMethod.GET, value = "/hello")
|
||||
public Hello getHello();
|
||||
|
||||
@RequestMapping(method = RequestMethod.GET, value = "/hellos")
|
||||
public List<Hello> getHellos();
|
||||
|
||||
@RequestMapping(method = RequestMethod.GET, value = "/hellostrings")
|
||||
public List<String> getHelloStrings();
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableAutoConfiguration
|
||||
@RestController
|
||||
@FeignClientScan
|
||||
protected static class Application {
|
||||
|
||||
protected static interface TestClient {
|
||||
@RequestMapping(method = RequestMethod.GET, value = "/hello")
|
||||
public Hello getHello() {
|
||||
return new Hello("hello world 1");
|
||||
}
|
||||
public Hello getHello();
|
||||
|
||||
@RequestMapping(method = RequestMethod.GET, value = "/hellos")
|
||||
public List<Hello> getHellos() {
|
||||
ArrayList<Hello> hellos = new ArrayList<>();
|
||||
hellos.add(new Hello("hello world 1"));
|
||||
hellos.add(new Hello("oi terra 2"));
|
||||
return hellos;
|
||||
}
|
||||
public List<Hello> getHellos();
|
||||
|
||||
@RequestMapping(method = RequestMethod.GET, value = "/hellostrings")
|
||||
public List<String> getHelloStrings() {
|
||||
ArrayList<String> hellos = new ArrayList<>();
|
||||
hellos.add("hello world 1");
|
||||
hellos.add("oi terra 2");
|
||||
return hellos;
|
||||
}
|
||||
public List<String> getHelloStrings();
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
new SpringApplicationBuilder(Application.class).properties(
|
||||
"spring.application.name=feignclienttest", "management.contextPath=/admin")
|
||||
.run(args);
|
||||
}
|
||||
}
|
||||
@Configuration
|
||||
@EnableAutoConfiguration
|
||||
@RestController
|
||||
@FeignClientScan
|
||||
protected static class Application {
|
||||
|
||||
@Test
|
||||
public void testClient() {
|
||||
assertNotNull("testClient was null", testClient);
|
||||
assertTrue("testClient is not a java Proxy", Proxy.isProxyClass(testClient.getClass()));
|
||||
InvocationHandler invocationHandler = Proxy.getInvocationHandler(testClient);
|
||||
@RequestMapping(method = RequestMethod.GET, value = "/hello")
|
||||
public Hello getHello() {
|
||||
return new Hello("hello world 1");
|
||||
}
|
||||
|
||||
@RequestMapping(method = RequestMethod.GET, value = "/hellos")
|
||||
public List<Hello> getHellos() {
|
||||
ArrayList<Hello> hellos = new ArrayList<>();
|
||||
hellos.add(new Hello("hello world 1"));
|
||||
hellos.add(new Hello("oi terra 2"));
|
||||
return hellos;
|
||||
}
|
||||
|
||||
@RequestMapping(method = RequestMethod.GET, value = "/hellostrings")
|
||||
public List<String> getHelloStrings() {
|
||||
ArrayList<String> hellos = new ArrayList<>();
|
||||
hellos.add("hello world 1");
|
||||
hellos.add("oi terra 2");
|
||||
return hellos;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
new SpringApplicationBuilder(Application.class).properties(
|
||||
"spring.application.name=feignclienttest",
|
||||
"management.contextPath=/admin").run(args);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testClient() {
|
||||
assertNotNull("testClient was null", this.testClient);
|
||||
assertTrue("testClient is not a java Proxy",
|
||||
Proxy.isProxyClass(this.testClient.getClass()));
|
||||
InvocationHandler invocationHandler = Proxy.getInvocationHandler(this.testClient);
|
||||
assertNotNull("invocationHandler was null", invocationHandler);
|
||||
}
|
||||
|
||||
//TODO: only works if port is hardcoded cant resolve ${local.server.port} in annotation
|
||||
/*@Test
|
||||
public void testSimpleType() {
|
||||
Hello hello = testClient.getHello();
|
||||
assertNotNull("hello was null", hello);
|
||||
assertEquals("first hello didn't match", new Hello("hello world 1"), hello);
|
||||
}*/
|
||||
// TODO: only works if port is hardcoded cant resolve ${local.server.port} in
|
||||
// annotation
|
||||
/*
|
||||
* @Test public void testSimpleType() { Hello hello = testClient.getHello();
|
||||
* assertNotNull("hello was null", hello); assertEquals("first hello didn't match",
|
||||
* new Hello("hello world 1"), hello); }
|
||||
*/
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
|
||||
@@ -1,6 +1,24 @@
|
||||
/*
|
||||
* Copyright 2013-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.feign;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
@@ -20,8 +38,8 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
@@ -29,85 +47,91 @@ import java.util.List;
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@SpringApplicationConfiguration(classes = SpringDecoderTests.Application.class)
|
||||
@WebAppConfiguration
|
||||
@IntegrationTest({ "server.port=0", "spring.application.name=springdecodertest", "spring.jmx.enabled=true" })
|
||||
@IntegrationTest({ "server.port=0", "spring.application.name=springdecodertest",
|
||||
"spring.jmx.enabled=true" })
|
||||
@DirtiesContext
|
||||
public class SpringDecoderTests extends FeignConfiguration {
|
||||
|
||||
@Value("${local.server.port}")
|
||||
private int port = 0;
|
||||
@Value("${local.server.port}")
|
||||
private int port = 0;
|
||||
|
||||
public TestClient testClient() {
|
||||
return feign().target(TestClient.class, "http://localhost:"+port);
|
||||
}
|
||||
public TestClient testClient() {
|
||||
return feign().target(TestClient.class, "http://localhost:" + this.port);
|
||||
}
|
||||
|
||||
protected static interface TestClient {
|
||||
@RequestMapping(method = RequestMethod.GET, value = "/hello")
|
||||
public Hello getHello();
|
||||
@Test
|
||||
public void testSimpleType() {
|
||||
Hello hello = testClient().getHello();
|
||||
assertNotNull("hello was null", hello);
|
||||
assertEquals("first hello didn't match", new Hello("hello world 1"), hello);
|
||||
}
|
||||
|
||||
@RequestMapping(method = RequestMethod.GET, value = "/hellos")
|
||||
public List<Hello> getHellos();
|
||||
@Test
|
||||
public void testUserParameterizedTypeDecode() {
|
||||
List<Hello> hellos = testClient().getHellos();
|
||||
assertNotNull("hellos was null", hellos);
|
||||
assertEquals("hellos was not the right size", 2, hellos.size());
|
||||
assertEquals("first hello didn't match", new Hello("hello world 1"),
|
||||
hellos.get(0));
|
||||
}
|
||||
|
||||
@RequestMapping(method = RequestMethod.GET, value = "/hellostrings")
|
||||
public List<String> getHelloStrings();
|
||||
}
|
||||
@Test
|
||||
public void testSimpleParameterizedTypeDecode() {
|
||||
List<String> hellos = testClient().getHelloStrings();
|
||||
assertNotNull("hellos was null", hellos);
|
||||
assertEquals("hellos was not the right size", 2, hellos.size());
|
||||
assertEquals("first hello didn't match", "hello world 1", hellos.get(0));
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableAutoConfiguration
|
||||
@RestController
|
||||
protected static class Application implements TestClient {
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public static class Hello {
|
||||
private String message;
|
||||
}
|
||||
|
||||
public Hello getHello() {
|
||||
return new Hello("hello world 1");
|
||||
}
|
||||
protected static interface TestClient {
|
||||
@RequestMapping(method = RequestMethod.GET, value = "/hello")
|
||||
public Hello getHello();
|
||||
|
||||
public List<Hello> getHellos() {
|
||||
ArrayList<Hello> hellos = new ArrayList<>();
|
||||
hellos.add(new Hello("hello world 1"));
|
||||
hellos.add(new Hello("oi terra 2"));
|
||||
return hellos;
|
||||
}
|
||||
@RequestMapping(method = RequestMethod.GET, value = "/hellos")
|
||||
public List<Hello> getHellos();
|
||||
|
||||
public List<String> getHelloStrings() {
|
||||
ArrayList<String> hellos = new ArrayList<>();
|
||||
hellos.add("hello world 1");
|
||||
hellos.add("oi terra 2");
|
||||
return hellos;
|
||||
}
|
||||
@RequestMapping(method = RequestMethod.GET, value = "/hellostrings")
|
||||
public List<String> getHelloStrings();
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
new SpringApplicationBuilder(Application.class).properties(
|
||||
"spring.application.name=springdecodertest", "management.contextPath=/admin")
|
||||
.run(args);
|
||||
}
|
||||
}
|
||||
@Configuration
|
||||
@EnableAutoConfiguration
|
||||
@RestController
|
||||
protected static class Application implements TestClient {
|
||||
|
||||
@Test
|
||||
public void testSimpleType() {
|
||||
Hello hello = testClient().getHello();
|
||||
assertNotNull("hello was null", hello);
|
||||
assertEquals("first hello didn't match", new Hello("hello world 1"), hello);
|
||||
}
|
||||
@Override
|
||||
public Hello getHello() {
|
||||
return new Hello("hello world 1");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUserParameterizedTypeDecode() {
|
||||
List<Hello> hellos = testClient().getHellos();
|
||||
assertNotNull("hellos was null", hellos);
|
||||
assertEquals("hellos was not the right size", 2, hellos.size());
|
||||
assertEquals("first hello didn't match", new Hello("hello world 1"), hellos.get(0));
|
||||
}
|
||||
@Override
|
||||
public List<Hello> getHellos() {
|
||||
ArrayList<Hello> hellos = new ArrayList<>();
|
||||
hellos.add(new Hello("hello world 1"));
|
||||
hellos.add(new Hello("oi terra 2"));
|
||||
return hellos;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSimpleParameterizedTypeDecode() {
|
||||
List<String> hellos = testClient().getHelloStrings();
|
||||
assertNotNull("hellos was null", hellos);
|
||||
assertEquals("hellos was not the right size", 2, hellos.size());
|
||||
assertEquals("first hello didn't match", "hello world 1", hellos.get(0));
|
||||
}
|
||||
@Override
|
||||
public List<String> getHelloStrings() {
|
||||
ArrayList<String> hellos = new ArrayList<>();
|
||||
hellos.add("hello world 1");
|
||||
hellos.add("oi terra 2");
|
||||
return hellos;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
new SpringApplicationBuilder(Application.class).properties(
|
||||
"spring.application.name=springdecodertest",
|
||||
"management.contextPath=/admin").run(args);
|
||||
}
|
||||
}
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public static class Hello {
|
||||
private String message;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.hystrix;
|
||||
|
||||
import org.junit.Test;
|
||||
@@ -20,13 +21,13 @@ import org.springframework.boot.builder.SpringApplicationBuilder;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
public class HystrixConfigurationTests {
|
||||
|
||||
@Test
|
||||
public void nonWebAppStartsUp() {
|
||||
new SpringApplicationBuilder(HystrixCircuitBreakerConfiguration.class).web(false).run().close();
|
||||
new SpringApplicationBuilder(HystrixCircuitBreakerConfiguration.class).web(false)
|
||||
.run().close();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,6 +1,23 @@
|
||||
/*
|
||||
* Copyright 2013-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.hystrix;
|
||||
|
||||
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -19,9 +36,11 @@ import org.springframework.test.context.web.WebAppConfiguration;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.Map;
|
||||
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
@@ -38,13 +57,15 @@ public class HystrixOnlyTests {
|
||||
|
||||
@Test
|
||||
public void testNormalExecution() {
|
||||
String s = new TestRestTemplate().getForObject("http://localhost:" + port + "/", String.class);
|
||||
String s = new TestRestTemplate().getForObject("http://localhost:" + this.port
|
||||
+ "/", String.class);
|
||||
assertEquals("incorrect response", "Hello world", s);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFailureFallback() {
|
||||
String s = new TestRestTemplate().getForObject("http://localhost:" + port + "/fail", String.class);
|
||||
String s = new TestRestTemplate().getForObject("http://localhost:" + this.port
|
||||
+ "/fail", String.class);
|
||||
assertEquals("incorrect fallback", "Fallback Hello world", s);
|
||||
}
|
||||
|
||||
@@ -59,12 +80,14 @@ public class HystrixOnlyTests {
|
||||
@Test
|
||||
public void testNoDiscoveryHealth() {
|
||||
Map map = getHealth();
|
||||
//There is explicitly no discovery, so there should be no discovery health key
|
||||
assertFalse("Incorrect existing discovery health key", map.containsKey("discovery"));
|
||||
// There is explicitly no discovery, so there should be no discovery health key
|
||||
assertFalse("Incorrect existing discovery health key",
|
||||
map.containsKey("discovery"));
|
||||
}
|
||||
|
||||
private Map getHealth() {
|
||||
return new TestRestTemplate().getForObject("http://localhost:" + port + "/admin/health", Map.class);
|
||||
return new TestRestTemplate().getForObject("http://localhost:" + this.port
|
||||
+ "/admin/health", Map.class);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -84,7 +107,7 @@ class Service {
|
||||
}
|
||||
}
|
||||
|
||||
//Don't use @SpringBootApplication because we don't want to component scan
|
||||
// Don't use @SpringBootApplication because we don't want to component scan
|
||||
@Configuration
|
||||
@EnableAutoConfiguration
|
||||
@EnableCircuitBreaker
|
||||
@@ -101,15 +124,16 @@ class HystrixOnlyApplication {
|
||||
|
||||
@RequestMapping("/")
|
||||
public String home() {
|
||||
return service.hello();
|
||||
return this.service.hello();
|
||||
}
|
||||
|
||||
@RequestMapping("/fail")
|
||||
public String fail() {
|
||||
return service.fail();
|
||||
return this.service.fail();
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(HystrixOnlyApplication.class, args);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -13,15 +13,15 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.cloud.netflix.hystrix;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
package org.springframework.cloud.netflix.hystrix;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
public class HystrixStreamEndpointTests {
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.ribbon;
|
||||
|
||||
import org.junit.Test;
|
||||
@@ -33,7 +34,6 @@ import com.netflix.loadbalancer.ZoneAwareLoadBalancer;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@SpringApplicationConfiguration(classes = TestConfiguration.class)
|
||||
@@ -46,7 +46,7 @@ public class PlainRibbonClientPreprocessorIntegrationTests {
|
||||
@Test
|
||||
public void serverListIsWrapped() throws Exception {
|
||||
@SuppressWarnings("unchecked")
|
||||
ZoneAwareLoadBalancer<Server> loadBalancer = (ZoneAwareLoadBalancer<Server>) factory
|
||||
ZoneAwareLoadBalancer<Server> loadBalancer = (ZoneAwareLoadBalancer<Server>) this.factory
|
||||
.getLoadBalancer("foo");
|
||||
DomainExtractingServerList.class.cast(loadBalancer.getServerListImpl());
|
||||
}
|
||||
|
||||
@@ -13,9 +13,8 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.cloud.netflix.ribbon;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
package org.springframework.cloud.netflix.ribbon;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
@@ -36,9 +35,10 @@ import com.netflix.loadbalancer.AvailabilityFilteringRule;
|
||||
import com.netflix.loadbalancer.Server;
|
||||
import com.netflix.loadbalancer.ZoneAwareLoadBalancer;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@SpringApplicationConfiguration(classes = TestConfiguration.class)
|
||||
@@ -51,7 +51,7 @@ public class RibbonClientPreprocessorIntegrationTests {
|
||||
@Test
|
||||
public void serverListIsWrapped() throws Exception {
|
||||
@SuppressWarnings("unchecked")
|
||||
ZoneAwareLoadBalancer<Server> loadBalancer = (ZoneAwareLoadBalancer<Server>) factory
|
||||
ZoneAwareLoadBalancer<Server> loadBalancer = (ZoneAwareLoadBalancer<Server>) this.factory
|
||||
.getLoadBalancer("foo");
|
||||
DomainExtractingServerList.class.cast(loadBalancer.getServerListImpl());
|
||||
}
|
||||
@@ -59,7 +59,7 @@ public class RibbonClientPreprocessorIntegrationTests {
|
||||
@Test
|
||||
public void ruleDefaultsToAvailability() throws Exception {
|
||||
@SuppressWarnings("unchecked")
|
||||
ZoneAwareLoadBalancer<Server> loadBalancer = (ZoneAwareLoadBalancer<Server>) factory
|
||||
ZoneAwareLoadBalancer<Server> loadBalancer = (ZoneAwareLoadBalancer<Server>) this.factory
|
||||
.getLoadBalancer("foo");
|
||||
AvailabilityFilteringRule.class.cast(loadBalancer.getRule());
|
||||
}
|
||||
@@ -67,7 +67,7 @@ public class RibbonClientPreprocessorIntegrationTests {
|
||||
@Test
|
||||
public void serverListFilterOverride() throws Exception {
|
||||
@SuppressWarnings("unchecked")
|
||||
ZoneAwareLoadBalancer<Server> loadBalancer = (ZoneAwareLoadBalancer<Server>) factory
|
||||
ZoneAwareLoadBalancer<Server> loadBalancer = (ZoneAwareLoadBalancer<Server>) this.factory
|
||||
.getLoadBalancer("foo");
|
||||
assertEquals("myTestZone",
|
||||
ZonePreferenceServerListFilter.class.cast(loadBalancer.getFilter())
|
||||
|
||||
@@ -13,9 +13,8 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.cloud.netflix.ribbon;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
package org.springframework.cloud.netflix.ribbon;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
@@ -24,10 +23,6 @@ import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfigurati
|
||||
import org.springframework.boot.test.SpringApplicationConfiguration;
|
||||
import org.springframework.cloud.netflix.archaius.ArchaiusAutoConfiguration;
|
||||
import org.springframework.cloud.netflix.eureka.EurekaClientAutoConfiguration;
|
||||
import org.springframework.cloud.netflix.ribbon.RibbonClients;
|
||||
import org.springframework.cloud.netflix.ribbon.RibbonAutoConfiguration;
|
||||
import org.springframework.cloud.netflix.ribbon.RibbonClient;
|
||||
import org.springframework.cloud.netflix.ribbon.SpringClientFactory;
|
||||
import org.springframework.cloud.netflix.ribbon.RibbonClientsPreprocessorIntegrationTests.TestConfiguration;
|
||||
import org.springframework.cloud.netflix.ribbon.eureka.DomainExtractingServerList;
|
||||
import org.springframework.cloud.netflix.ribbon.eureka.RibbonEurekaAutoConfiguration;
|
||||
@@ -42,9 +37,10 @@ import com.netflix.loadbalancer.Server;
|
||||
import com.netflix.loadbalancer.ZoneAvoidanceRule;
|
||||
import com.netflix.loadbalancer.ZoneAwareLoadBalancer;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@SpringApplicationConfiguration(classes = TestConfiguration.class)
|
||||
@@ -57,7 +53,7 @@ public class RibbonClientsPreprocessorIntegrationTests {
|
||||
@Test
|
||||
public void serverListIsWrapped() throws Exception {
|
||||
@SuppressWarnings("unchecked")
|
||||
ZoneAwareLoadBalancer<Server> loadBalancer = (ZoneAwareLoadBalancer<Server>) factory
|
||||
ZoneAwareLoadBalancer<Server> loadBalancer = (ZoneAwareLoadBalancer<Server>) this.factory
|
||||
.getLoadBalancer("foo");
|
||||
DomainExtractingServerList.class.cast(loadBalancer.getServerListImpl());
|
||||
}
|
||||
@@ -65,7 +61,7 @@ public class RibbonClientsPreprocessorIntegrationTests {
|
||||
@Test
|
||||
public void ruleDefaultsToZoneAvoidance() throws Exception {
|
||||
@SuppressWarnings("unchecked")
|
||||
ZoneAwareLoadBalancer<Server> loadBalancer = (ZoneAwareLoadBalancer<Server>) factory
|
||||
ZoneAwareLoadBalancer<Server> loadBalancer = (ZoneAwareLoadBalancer<Server>) this.factory
|
||||
.getLoadBalancer("foo");
|
||||
ZoneAvoidanceRule.class.cast(loadBalancer.getRule());
|
||||
}
|
||||
@@ -73,10 +69,11 @@ public class RibbonClientsPreprocessorIntegrationTests {
|
||||
@Test
|
||||
public void serverListFilterOverride() throws Exception {
|
||||
@SuppressWarnings("unchecked")
|
||||
ZoneAwareLoadBalancer<Server> loadBalancer = (ZoneAwareLoadBalancer<Server>) factory
|
||||
ZoneAwareLoadBalancer<Server> loadBalancer = (ZoneAwareLoadBalancer<Server>) this.factory
|
||||
.getLoadBalancer("foo");
|
||||
assertEquals("myTestZone",
|
||||
ZonePreferenceServerListFilter.class.cast(loadBalancer.getFilter()).getZone());
|
||||
ZonePreferenceServerListFilter.class.cast(loadBalancer.getFilter())
|
||||
.getZone());
|
||||
}
|
||||
|
||||
@Configuration
|
||||
|
||||
@@ -1,7 +1,24 @@
|
||||
/*
|
||||
* Copyright 2013-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.ribbon;
|
||||
|
||||
import com.google.common.base.Throwables;
|
||||
import com.netflix.loadbalancer.Server;
|
||||
import java.net.URI;
|
||||
import java.net.URL;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
@@ -17,77 +34,82 @@ import org.springframework.http.client.ClientHttpResponse;
|
||||
import org.springframework.http.client.support.HttpRequestWrapper;
|
||||
import org.springframework.web.util.UriComponentsBuilder;
|
||||
|
||||
import java.net.URI;
|
||||
import java.net.URL;
|
||||
import com.google.common.base.Throwables;
|
||||
import com.netflix.loadbalancer.Server;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.mockito.Matchers.isA;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
public class RibbonInterceptorTests {
|
||||
|
||||
@Mock
|
||||
HttpRequest request;
|
||||
@Mock
|
||||
HttpRequest request;
|
||||
|
||||
@Mock
|
||||
ClientHttpRequestExecution execution;
|
||||
@Mock
|
||||
ClientHttpRequestExecution execution;
|
||||
|
||||
@Mock
|
||||
ClientHttpResponse response;
|
||||
@Mock
|
||||
ClientHttpResponse response;
|
||||
|
||||
@Before
|
||||
public void init() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
}
|
||||
@Before
|
||||
public void init() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIntercept() throws Exception {
|
||||
RibbonServer server = new RibbonServer("myservice", new Server("myhost", 8080));
|
||||
RibbonInterceptor interceptor = new RibbonInterceptor(new MyClient(server));
|
||||
@Test
|
||||
public void testIntercept() throws Exception {
|
||||
RibbonServer server = new RibbonServer("myservice", new Server("myhost", 8080));
|
||||
RibbonInterceptor interceptor = new RibbonInterceptor(new MyClient(server));
|
||||
given(this.request.getURI()).willReturn(new URL("http://myservice").toURI());
|
||||
given(this.execution.execute(isA(HttpRequest.class), isA(byte[].class)))
|
||||
.willReturn(this.response);
|
||||
ArgumentCaptor<HttpRequestWrapper> argument = ArgumentCaptor
|
||||
.forClass(HttpRequestWrapper.class);
|
||||
ClientHttpResponse response = interceptor.intercept(this.request, new byte[0],
|
||||
this.execution);
|
||||
assertNotNull("response was null", response);
|
||||
verify(this.execution).execute(argument.capture(), isA(byte[].class));
|
||||
HttpRequestWrapper wrapper = argument.getValue();
|
||||
assertEquals("wrong constructed uri", new URL("http://myhost:8080").toURI(),
|
||||
wrapper.getURI());
|
||||
}
|
||||
|
||||
when(request.getURI()).thenReturn(new URL("http://myservice").toURI());
|
||||
when(execution.execute(isA(HttpRequest.class), isA(byte[].class))).thenReturn(response);
|
||||
ArgumentCaptor<HttpRequestWrapper> argument = ArgumentCaptor.forClass(HttpRequestWrapper.class);
|
||||
protected static class MyClient implements LoadBalancerClient {
|
||||
|
||||
ClientHttpResponse response = interceptor.intercept(request, new byte[0], execution);
|
||||
private ServiceInstance instance;
|
||||
|
||||
assertNotNull("response was null", response);
|
||||
verify(execution).execute(argument.capture(), isA(byte[].class));
|
||||
HttpRequestWrapper wrapper = argument.getValue();
|
||||
assertEquals("wrong constructed uri", new URL("http://myhost:8080").toURI(), wrapper.getURI());
|
||||
}
|
||||
public MyClient(ServiceInstance instance) {
|
||||
this.instance = instance;
|
||||
}
|
||||
|
||||
protected static class MyClient implements LoadBalancerClient {
|
||||
ServiceInstance instance;
|
||||
@Override
|
||||
public ServiceInstance choose(String serviceId) {
|
||||
return this.instance;
|
||||
}
|
||||
|
||||
public MyClient(ServiceInstance instance) {
|
||||
this.instance = instance;
|
||||
}
|
||||
@Override
|
||||
public <T> T execute(String serviceId, LoadBalancerRequest<T> request) {
|
||||
try {
|
||||
return request.apply(this.instance);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
Throwables.propagate(ex);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ServiceInstance choose(String serviceId) {
|
||||
return instance;
|
||||
}
|
||||
@Override
|
||||
public URI reconstructURI(ServiceInstance instance, URI original) {
|
||||
return UriComponentsBuilder.fromUri(original).host(instance.getHost())
|
||||
.port(instance.getPort()).build().toUri();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T execute(String serviceId, LoadBalancerRequest<T> request) {
|
||||
try {
|
||||
return request.apply(instance);
|
||||
} catch (Exception e) {
|
||||
Throwables.propagate(e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public URI reconstructURI(ServiceInstance instance, URI original) {
|
||||
return UriComponentsBuilder.fromUri(original)
|
||||
.host(instance.getHost())
|
||||
.port(instance.getPort())
|
||||
.build()
|
||||
.toUri();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,20 @@
|
||||
package org.springframework.cloud.netflix.ribbon;
|
||||
/*
|
||||
* Copyright 2013-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.fail;
|
||||
import static org.mockito.Matchers.anyDouble;
|
||||
import static org.mockito.Matchers.anyString;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
package org.springframework.cloud.netflix.ribbon;
|
||||
|
||||
import java.net.URI;
|
||||
import java.net.URL;
|
||||
@@ -14,7 +22,6 @@ import java.net.URL;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.springframework.cloud.client.ServiceInstance;
|
||||
import org.springframework.cloud.client.loadbalancer.LoadBalancerRequest;
|
||||
@@ -25,113 +32,126 @@ import com.netflix.loadbalancer.LoadBalancerStats;
|
||||
import com.netflix.loadbalancer.Server;
|
||||
import com.netflix.loadbalancer.ServerStats;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.fail;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.mockito.Matchers.anyDouble;
|
||||
import static org.mockito.Matchers.anyString;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
public class RibbonLoadBalancerClientTests {
|
||||
|
||||
@Mock
|
||||
SpringClientFactory clientFactory;
|
||||
@Mock
|
||||
private SpringClientFactory clientFactory;
|
||||
|
||||
@Mock
|
||||
BaseLoadBalancer loadBalancer;
|
||||
@Mock
|
||||
private BaseLoadBalancer loadBalancer;
|
||||
|
||||
@Mock
|
||||
LoadBalancerStats loadBalancerStats;
|
||||
@Mock
|
||||
private LoadBalancerStats loadBalancerStats;
|
||||
|
||||
@Mock
|
||||
ServerStats serverStats;
|
||||
@Mock
|
||||
private ServerStats serverStats;
|
||||
|
||||
@Before
|
||||
public void init() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
Mockito.when(clientFactory.getLoadBalancerContext(anyString())).thenReturn(new RibbonLoadBalancerContext(loadBalancer));
|
||||
}
|
||||
@Before
|
||||
public void init() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
given(this.clientFactory.getLoadBalancerContext(anyString())).willReturn(
|
||||
new RibbonLoadBalancerContext(this.loadBalancer));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void reconstructURI() throws Exception {
|
||||
RibbonServer server = getRibbonServer();
|
||||
RibbonLoadBalancerClient client = getRibbonLoadBalancerClient(server);
|
||||
ServiceInstance serviceInstance = client.choose(server.getServiceId());
|
||||
URI uri = client.reconstructURI(serviceInstance, new URL("http://" + server.serviceId).toURI());
|
||||
assertEquals(server.getHost(), uri.getHost());
|
||||
assertEquals(server.getPort(), uri.getPort());
|
||||
}
|
||||
@Test
|
||||
public void reconstructURI() throws Exception {
|
||||
RibbonServer server = getRibbonServer();
|
||||
RibbonLoadBalancerClient client = getRibbonLoadBalancerClient(server);
|
||||
ServiceInstance serviceInstance = client.choose(server.getServiceId());
|
||||
URI uri = client.reconstructURI(serviceInstance, new URL("http://"
|
||||
+ server.serviceId).toURI());
|
||||
assertEquals(server.getHost(), uri.getHost());
|
||||
assertEquals(server.getPort(), uri.getPort());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testChoose() {
|
||||
RibbonServer server = getRibbonServer();
|
||||
RibbonLoadBalancerClient client = getRibbonLoadBalancerClient(server);
|
||||
ServiceInstance serviceInstance = client.choose(server.getServiceId());
|
||||
assertServiceInstance(server, serviceInstance);
|
||||
}
|
||||
@Test
|
||||
public void testChoose() {
|
||||
RibbonServer server = getRibbonServer();
|
||||
RibbonLoadBalancerClient client = getRibbonLoadBalancerClient(server);
|
||||
ServiceInstance serviceInstance = client.choose(server.getServiceId());
|
||||
assertServiceInstance(server, serviceInstance);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExecute() {
|
||||
final RibbonServer server = getRibbonServer();
|
||||
RibbonLoadBalancerClient client = getRibbonLoadBalancerClient(server);
|
||||
@Test
|
||||
public void testExecute() {
|
||||
final RibbonServer server = getRibbonServer();
|
||||
RibbonLoadBalancerClient client = getRibbonLoadBalancerClient(server);
|
||||
final String returnVal = "myval";
|
||||
Object actualReturn = client.execute(server.getServiceId(),
|
||||
new LoadBalancerRequest<Object>() {
|
||||
@Override
|
||||
public Object apply(ServiceInstance instance) throws Exception {
|
||||
assertServiceInstance(server, instance);
|
||||
return returnVal;
|
||||
}
|
||||
});
|
||||
verifyServerStats();
|
||||
assertEquals("retVal was wrong", returnVal, actualReturn);
|
||||
}
|
||||
|
||||
final String returnVal = "myval";
|
||||
Object actualReturn = client.execute(server.getServiceId(), new LoadBalancerRequest<Object>() {
|
||||
@Override
|
||||
public Object apply(ServiceInstance instance) throws Exception {
|
||||
assertServiceInstance(server, instance);
|
||||
return returnVal;
|
||||
}
|
||||
});
|
||||
@Test
|
||||
public void testExecuteException() {
|
||||
final RibbonServer ribbonServer = getRibbonServer();
|
||||
RibbonLoadBalancerClient client = getRibbonLoadBalancerClient(ribbonServer);
|
||||
try {
|
||||
client.execute(ribbonServer.getServiceId(),
|
||||
new LoadBalancerRequest<Object>() {
|
||||
@Override
|
||||
public Object apply(ServiceInstance instance) throws Exception {
|
||||
assertServiceInstance(ribbonServer, instance);
|
||||
throw new RuntimeException();
|
||||
}
|
||||
});
|
||||
fail("Should have thrown exception");
|
||||
}
|
||||
catch (Exception ex) {
|
||||
assertNotNull(ex);
|
||||
}
|
||||
verifyServerStats();
|
||||
}
|
||||
|
||||
verifyServerStats();
|
||||
protected RibbonServer getRibbonServer() {
|
||||
return new RibbonServer("testService", new Server("myhost", 9080));
|
||||
}
|
||||
|
||||
assertEquals("retVal was wrong", returnVal, actualReturn);
|
||||
}
|
||||
protected void verifyServerStats() {
|
||||
verify(this.serverStats).incrementActiveRequestsCount();
|
||||
verify(this.serverStats).decrementActiveRequestsCount();
|
||||
verify(this.serverStats).incrementNumRequests();
|
||||
verify(this.serverStats).noteResponseTime(anyDouble());
|
||||
}
|
||||
|
||||
protected void assertServiceInstance(RibbonServer ribbonServer,
|
||||
ServiceInstance instance) {
|
||||
assertNotNull("instance was null", instance);
|
||||
assertEquals("serviceId was wrong", ribbonServer.getServiceId(),
|
||||
instance.getServiceId());
|
||||
assertEquals("host was wrong", ribbonServer.getHost(), instance.getHost());
|
||||
assertEquals("port was wrong", ribbonServer.getPort(), instance.getPort());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExecuteException() {
|
||||
final RibbonServer ribbonServer = getRibbonServer();
|
||||
RibbonLoadBalancerClient client = getRibbonLoadBalancerClient(ribbonServer);
|
||||
|
||||
try {
|
||||
client.execute(ribbonServer.getServiceId(), new LoadBalancerRequest<Object>() {
|
||||
@Override
|
||||
public Object apply(ServiceInstance instance) throws Exception {
|
||||
assertServiceInstance(ribbonServer, instance);
|
||||
throw new RuntimeException();
|
||||
}
|
||||
});
|
||||
fail("Should have thrown exception");
|
||||
} catch (Exception e) {
|
||||
assertNotNull(e);
|
||||
}
|
||||
|
||||
verifyServerStats();
|
||||
}
|
||||
|
||||
protected RibbonServer getRibbonServer() {
|
||||
return new RibbonServer("testService", new Server("myhost", 9080));
|
||||
}
|
||||
|
||||
protected void verifyServerStats() {
|
||||
verify(serverStats).incrementActiveRequestsCount();
|
||||
verify(serverStats).decrementActiveRequestsCount();
|
||||
verify(serverStats).incrementNumRequests();
|
||||
verify(serverStats).noteResponseTime(anyDouble());
|
||||
}
|
||||
|
||||
protected void assertServiceInstance(RibbonServer ribbonServer, ServiceInstance instance) {
|
||||
assertNotNull("instance was null", instance);
|
||||
assertEquals("serviceId was wrong", ribbonServer.getServiceId(), instance.getServiceId());
|
||||
assertEquals("host was wrong", ribbonServer.getHost(), instance.getHost());
|
||||
assertEquals("port was wrong", ribbonServer.getPort(), instance.getPort());
|
||||
}
|
||||
|
||||
protected RibbonLoadBalancerClient getRibbonLoadBalancerClient(RibbonServer ribbonServer) {
|
||||
when(loadBalancer.getName()).thenReturn(ribbonServer.getServiceId());
|
||||
when(loadBalancer.chooseServer(anyString())).thenReturn(ribbonServer.server);
|
||||
when(loadBalancer.getLoadBalancerStats()).thenReturn(loadBalancerStats);
|
||||
when(loadBalancerStats.getSingleServerStat(ribbonServer.server)).thenReturn(serverStats);
|
||||
when(clientFactory.getLoadBalancer(loadBalancer.getName())).thenReturn(loadBalancer);
|
||||
|
||||
return new RibbonLoadBalancerClient(clientFactory);
|
||||
}
|
||||
protected RibbonLoadBalancerClient getRibbonLoadBalancerClient(
|
||||
RibbonServer ribbonServer) {
|
||||
given(this.loadBalancer.getName()).willReturn(ribbonServer.getServiceId());
|
||||
given(this.loadBalancer.chooseServer(anyString()))
|
||||
.willReturn(ribbonServer.server);
|
||||
given(this.loadBalancer.getLoadBalancerStats())
|
||||
.willReturn(this.loadBalancerStats);
|
||||
given(this.loadBalancerStats.getSingleServerStat(ribbonServer.server))
|
||||
.willReturn(this.serverStats);
|
||||
given(this.clientFactory.getLoadBalancer(this.loadBalancer.getName()))
|
||||
.willReturn(this.loadBalancer);
|
||||
return new RibbonLoadBalancerClient(this.clientFactory);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,9 +13,8 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.cloud.netflix.ribbon;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
package org.springframework.cloud.netflix.ribbon;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.boot.test.EnvironmentTestUtils;
|
||||
@@ -24,6 +23,8 @@ import org.springframework.context.annotation.AnnotationConfigApplicationContext
|
||||
|
||||
import com.netflix.client.DefaultLoadBalancerRetryHandler;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*
|
||||
@@ -34,14 +35,15 @@ public class SpringClientFactoryTests {
|
||||
|
||||
@Test
|
||||
public void testConfigureRetry() {
|
||||
AnnotationConfigApplicationContext parent = new AnnotationConfigApplicationContext(ArchaiusAutoConfiguration.class);
|
||||
AnnotationConfigApplicationContext parent = new AnnotationConfigApplicationContext(
|
||||
ArchaiusAutoConfiguration.class);
|
||||
EnvironmentTestUtils.addEnvironment(parent, "foo.ribbon.MaxAutoRetries:2");
|
||||
factory.setApplicationContext(parent);
|
||||
DefaultLoadBalancerRetryHandler retryHandler = (DefaultLoadBalancerRetryHandler) factory
|
||||
this.factory.setApplicationContext(parent);
|
||||
DefaultLoadBalancerRetryHandler retryHandler = (DefaultLoadBalancerRetryHandler) this.factory
|
||||
.getLoadBalancerContext("foo").getRetryHandler();
|
||||
assertEquals(2, retryHandler.getMaxRetriesOnSameServer());
|
||||
parent.close();
|
||||
factory.destroy();
|
||||
this.factory.destroy();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user