diff --git a/docs/pom.xml b/docs/pom.xml index 34af9a8fe..b097b6326 100644 --- a/docs/pom.xml +++ b/docs/pom.xml @@ -1,44 +1,43 @@ - + 4.0.0 - org.springframework.cloud - spring-cloud-netflix-docs - 1.0.0.BUILD-SNAPSHOT org.springframework.cloud spring-cloud-build 1.0.0.BUILD-SNAPSHOT - + + spring-cloud-netflix-docs pom Spring Cloud Netflix Docs Spring Cloud Docs - spring-cloud-netflix + spring-cloud-netflix ${basedir}/.. - + docs - - - - org.asciidoctor - asciidoctor-maven-plugin - false - - - org.apache.maven.plugins - maven-antrun-plugin - false - - - org.codehaus.mojo - build-helper-maven-plugin - false - - - + + + + org.asciidoctor + asciidoctor-maven-plugin + false + + + org.apache.maven.plugins + maven-antrun-plugin + false + + + org.codehaus.mojo + build-helper-maven-plugin + false + + + - + diff --git a/eclipse/eclipse-code-formatter.xml b/eclipse/eclipse-code-formatter.xml new file mode 100644 index 000000000..4694d7f2c --- /dev/null +++ b/eclipse/eclipse-code-formatter.xml @@ -0,0 +1,295 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/eclipse/org.eclipse.jdt.core.prefs b/eclipse/org.eclipse.jdt.core.prefs new file mode 100644 index 000000000..63d59166b --- /dev/null +++ b/eclipse/org.eclipse.jdt.core.prefs @@ -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 diff --git a/eclipse/org.eclipse.jdt.ui.prefs b/eclipse/org.eclipse.jdt.ui.prefs new file mode 100644 index 000000000..fb4753fe3 --- /dev/null +++ b/eclipse/org.eclipse.jdt.ui.prefs @@ -0,0 +1,125 @@ +cleanup.add_default_serial_version_id=true +cleanup.add_generated_serial_version_id=false +cleanup.add_missing_annotations=true +cleanup.add_missing_deprecated_annotations=true +cleanup.add_missing_methods=false +cleanup.add_missing_nls_tags=false +cleanup.add_missing_override_annotations=true +cleanup.add_missing_override_annotations_interface_methods=true +cleanup.add_serial_version_id=false +cleanup.always_use_blocks=true +cleanup.always_use_parentheses_in_expressions=false +cleanup.always_use_this_for_non_static_field_access=true +cleanup.always_use_this_for_non_static_method_access=false +cleanup.convert_functional_interfaces=false +cleanup.convert_to_enhanced_for_loop=false +cleanup.correct_indentation=false +cleanup.format_source_code=true +cleanup.format_source_code_changes_only=false +cleanup.insert_inferred_type_arguments=false +cleanup.make_local_variable_final=false +cleanup.make_parameters_final=false +cleanup.make_private_fields_final=false +cleanup.make_type_abstract_if_missing_method=false +cleanup.make_variable_declarations_final=false +cleanup.never_use_blocks=false +cleanup.never_use_parentheses_in_expressions=true +cleanup.organize_imports=true +cleanup.qualify_static_field_accesses_with_declaring_class=false +cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true +cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true +cleanup.qualify_static_member_accesses_with_declaring_class=true +cleanup.qualify_static_method_accesses_with_declaring_class=false +cleanup.remove_private_constructors=true +cleanup.remove_redundant_type_arguments=true +cleanup.remove_trailing_whitespaces=true +cleanup.remove_trailing_whitespaces_all=true +cleanup.remove_trailing_whitespaces_ignore_empty=false +cleanup.remove_unnecessary_casts=true +cleanup.remove_unnecessary_nls_tags=false +cleanup.remove_unused_imports=true +cleanup.remove_unused_local_variables=false +cleanup.remove_unused_private_fields=true +cleanup.remove_unused_private_members=false +cleanup.remove_unused_private_methods=true +cleanup.remove_unused_private_types=true +cleanup.sort_members=false +cleanup.sort_members_all=false +cleanup.use_anonymous_class_creation=false +cleanup.use_blocks=true +cleanup.use_blocks_only_for_return_and_throw=false +cleanup.use_lambda=true +cleanup.use_parentheses_in_expressions=false +cleanup.use_this_for_non_static_field_access=true +cleanup.use_this_for_non_static_field_access_only_if_necessary=false +cleanup.use_this_for_non_static_method_access=false +cleanup.use_this_for_non_static_method_access_only_if_necessary=true +cleanup.use_type_arguments=false +cleanup_profile=_Spring Cloud Cleanup Conventions +cleanup_settings_version=2 +eclipse.preferences.version=1 +editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true +formatter_profile=_Spring Cloud Java Conventions +formatter_settings_version=12 +org.eclipse.jdt.ui.exception.name=e +org.eclipse.jdt.ui.gettersetter.use.is=false +org.eclipse.jdt.ui.ignorelowercasenames=true +org.eclipse.jdt.ui.importorder=java;javax;org;com;\#; +org.eclipse.jdt.ui.javadoc=true +org.eclipse.jdt.ui.keywordthis=false +org.eclipse.jdt.ui.ondemandthreshold=9999 +org.eclipse.jdt.ui.overrideannotation=true +org.eclipse.jdt.ui.staticondemandthreshold=9999 +org.eclipse.jdt.ui.text.custom_code_templates= +sp_cleanup.add_default_serial_version_id=true +sp_cleanup.add_generated_serial_version_id=false +sp_cleanup.add_missing_annotations=true +sp_cleanup.add_missing_deprecated_annotations=true +sp_cleanup.add_missing_methods=false +sp_cleanup.add_missing_nls_tags=false +sp_cleanup.add_missing_override_annotations=true +sp_cleanup.add_missing_override_annotations_interface_methods=true +sp_cleanup.add_serial_version_id=false +sp_cleanup.always_use_blocks=true +sp_cleanup.always_use_parentheses_in_expressions=true +sp_cleanup.always_use_this_for_non_static_field_access=true +sp_cleanup.always_use_this_for_non_static_method_access=false +sp_cleanup.convert_to_enhanced_for_loop=false +sp_cleanup.correct_indentation=false +sp_cleanup.format_source_code=true +sp_cleanup.format_source_code_changes_only=false +sp_cleanup.make_local_variable_final=false +sp_cleanup.make_parameters_final=false +sp_cleanup.make_private_fields_final=false +sp_cleanup.make_type_abstract_if_missing_method=false +sp_cleanup.make_variable_declarations_final=false +sp_cleanup.never_use_blocks=false +sp_cleanup.never_use_parentheses_in_expressions=false +sp_cleanup.on_save_use_additional_actions=true +sp_cleanup.organize_imports=true +sp_cleanup.qualify_static_field_accesses_with_declaring_class=false +sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true +sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true +sp_cleanup.qualify_static_member_accesses_with_declaring_class=true +sp_cleanup.qualify_static_method_accesses_with_declaring_class=false +sp_cleanup.remove_private_constructors=true +sp_cleanup.remove_trailing_whitespaces=true +sp_cleanup.remove_trailing_whitespaces_all=true +sp_cleanup.remove_trailing_whitespaces_ignore_empty=false +sp_cleanup.remove_unnecessary_casts=true +sp_cleanup.remove_unnecessary_nls_tags=false +sp_cleanup.remove_unused_imports=true +sp_cleanup.remove_unused_local_variables=false +sp_cleanup.remove_unused_private_fields=true +sp_cleanup.remove_unused_private_members=false +sp_cleanup.remove_unused_private_methods=true +sp_cleanup.remove_unused_private_types=true +sp_cleanup.sort_members=false +sp_cleanup.sort_members_all=false +sp_cleanup.use_blocks=true +sp_cleanup.use_blocks_only_for_return_and_throw=false +sp_cleanup.use_parentheses_in_expressions=false +sp_cleanup.use_this_for_non_static_field_access=true +sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=false +sp_cleanup.use_this_for_non_static_method_access=false +sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true diff --git a/pom.xml b/pom.xml index fa80ac575..4622459f5 100644 --- a/pom.xml +++ b/pom.xml @@ -1,295 +1,299 @@ - 4.0.0 - - org.springframework.cloud - spring-cloud-netflix - 1.0.0.BUILD-SNAPSHOT - pom - Spring Cloud Netflix - Spring Cloud Netflix - - - org.springframework.cloud - spring-cloud-build - 1.0.0.BUILD-SNAPSHOT - - - - + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + 4.0.0 + + org.springframework.cloud + spring-cloud-build + 1.0.0.BUILD-SNAPSHOT + + + spring-cloud-netflix + 1.0.0.BUILD-SNAPSHOT + pom + Spring Cloud Netflix + Spring Cloud Netflix https://github.com/spring-cloud/spring-cloud-netflix scm:git:git://github.com/spring-cloud/spring-cloud-netflix.git scm:git:ssh://git@github.com/spring-cloud/spring-cloud-netflix.git HEAD - - - spring-cloud-netflix-core - spring-cloud-netflix-hystrix-dashboard - spring-cloud-netflix-hystrix-amqp - spring-cloud-netflix-eureka-server - spring-cloud-netflix-turbine - spring-cloud-netflix-turbine-amqp - spring-cloud-netflix-sidecar - docs - - - - - - org.springframework.cloud - spring-cloud-commons - 1.0.0.BUILD-SNAPSHOT - - - org.springframework.cloud - spring-cloud-config-client - 1.0.0.BUILD-SNAPSHOT - - - org.springframework.cloud - spring-cloud-config-server - 1.0.0.BUILD-SNAPSHOT - - - org.springframework.cloud - spring-cloud-netflix-core - 1.0.0.BUILD-SNAPSHOT - - - org.springframework.cloud - spring-cloud-netflix-eureka-server - 1.0.0.BUILD-SNAPSHOT - - - org.springframework.cloud - spring-cloud-netflix-hystrix-dashboard - 1.0.0.BUILD-SNAPSHOT - - - org.springframework.cloud - spring-cloud-netflix-hystrix-amqp - 1.0.0.BUILD-SNAPSHOT - - - org.springframework.cloud - spring-cloud-netflix-turbine - 1.0.0.BUILD-SNAPSHOT - - - org.springframework.cloud - spring-cloud-netflix-turbine-amqp - 1.0.0.BUILD-SNAPSHOT - - - org.springframework.cloud - spring-cloud-netflix-zuul-server - 1.0.0.BUILD-SNAPSHOT - - - com.netflix.archaius - archaius-core - ${archaius.version} - - - commons-logging - commons-logging - - - - - com.netflix.eureka - eureka-client - ${eureka.version} - - - javax.servlet - servlet-api - - - - - com.netflix.eureka - eureka-core - ${eureka.version} - - - javax.servlet - servlet-api - - - commons-logging - commons-logging - - - log4j - log4j - - - - - com.netflix.feign - feign-core - ${feign.version} - - - com.netflix.feign - feign-ribbon - ${feign.version} - - - com.netflix.ribbon - ribbon-loadbalancer - - - - - - com.netflix.hystrix - hystrix-core - ${hystrix.version} - - - com.netflix.hystrix - hystrix-metrics-event-stream - ${hystrix.version} - - - com.netflix.hystrix - hystrix-javanica - ${hystrix.version} - - - com.netflix.ribbon - ribbon - ${ribbon.version} - - - com.netflix.ribbon - ribbon-core - ${ribbon.version} - - - com.netflix.ribbon - ribbon-httpclient - ${ribbon.version} - - - com.netflix.ribbon - ribbon-eureka - ${ribbon.version} - - - javax.servlet - servlet-api - - - - - com.netflix.rxjava - rxjava-core - ${netflix.rxjava.version} - - - com.netflix.zuul - zuul-core - ${zuul.version} - - - groovy-all - org.codehaus.groovy - - - - - org.springframework.integration - spring-integration-java-dsl - ${spring-integration-dsl.version} - - - org.projectlombok - lombok - 1.12.6 - provided - - - com.google.guava - guava - 18.0 - - - com.sun.jersey - jersey-servlet - 1.13 - - - com.sun.jersey - jersey-core - 1.13 - - - com.sun.jersey - jersey-client - 1.13 - - - com.sun.jersey - jersey-server - 1.13 - - - org.webjars - d3js - 3.4.11 - - - org.webjars - jquery - 2.1.1 - - - org.webjars - bootstrap - 3.2.0 - - - javax.inject - javax.inject - 1 - - - - - - 0.6.3 - 1.1.145 - 6.1.3 - 1.4.0-RC5 - 2.0-RC13 - 1.0.28 - 0.20.7 - 1.7 - 1.0.0.RELEASE - 1.1.1.BUILD-SNAPSHOT - - - - - - maven-compiler-plugin - 3.1 - - 1.7 - 1.7 - - - - - + + ${basedir} + 0.6.3 + 1.1.145 + 6.1.3 + 1.4.0-RC5 + 2.0-RC13 + 1.0.28 + 0.20.7 + 1.7 + 1.0.0.RELEASE + 1.1.1.BUILD-SNAPSHOT + + + + + org.apache.maven.plugins + maven-eclipse-plugin + + false + + + .settings/org.eclipse.jdt.ui.prefs + ${main.basedir}/eclipse/org.eclipse.jdt.ui.prefs + + + .settings/org.eclipse.jdt.core.prefs + ${main.basedir}/eclipse/org.eclipse.jdt.core.prefs + + + + + + maven-compiler-plugin + + 1.7 + 1.7 + + + + + + + + org.springframework.cloud + spring-cloud-commons + 1.0.0.BUILD-SNAPSHOT + + + org.springframework.cloud + spring-cloud-config-client + 1.0.0.BUILD-SNAPSHOT + + + org.springframework.cloud + spring-cloud-config-server + 1.0.0.BUILD-SNAPSHOT + + + org.springframework.cloud + spring-cloud-netflix-core + 1.0.0.BUILD-SNAPSHOT + + + org.springframework.cloud + spring-cloud-netflix-eureka-server + 1.0.0.BUILD-SNAPSHOT + + + org.springframework.cloud + spring-cloud-netflix-hystrix-dashboard + 1.0.0.BUILD-SNAPSHOT + + + org.springframework.cloud + spring-cloud-netflix-hystrix-amqp + 1.0.0.BUILD-SNAPSHOT + + + org.springframework.cloud + spring-cloud-netflix-turbine + 1.0.0.BUILD-SNAPSHOT + + + org.springframework.cloud + spring-cloud-netflix-turbine-amqp + 1.0.0.BUILD-SNAPSHOT + + + org.springframework.cloud + spring-cloud-netflix-zuul-server + 1.0.0.BUILD-SNAPSHOT + + + com.netflix.archaius + archaius-core + ${archaius.version} + + + commons-logging + commons-logging + + + + + com.netflix.eureka + eureka-client + ${eureka.version} + + + javax.servlet + servlet-api + + + + + com.netflix.eureka + eureka-core + ${eureka.version} + + + javax.servlet + servlet-api + + + commons-logging + commons-logging + + + log4j + log4j + + + + + com.netflix.feign + feign-core + ${feign.version} + + + com.netflix.feign + feign-ribbon + ${feign.version} + + + com.netflix.ribbon + ribbon-loadbalancer + + + + + + com.netflix.hystrix + hystrix-core + ${hystrix.version} + + + com.netflix.hystrix + hystrix-metrics-event-stream + ${hystrix.version} + + + com.netflix.hystrix + hystrix-javanica + ${hystrix.version} + + + com.netflix.ribbon + ribbon + ${ribbon.version} + + + com.netflix.ribbon + ribbon-core + ${ribbon.version} + + + com.netflix.ribbon + ribbon-httpclient + ${ribbon.version} + + + com.netflix.ribbon + ribbon-eureka + ${ribbon.version} + + + javax.servlet + servlet-api + + + + + com.netflix.rxjava + rxjava-core + ${netflix.rxjava.version} + + + com.netflix.zuul + zuul-core + ${zuul.version} + + + groovy-all + org.codehaus.groovy + + + + + org.springframework.integration + spring-integration-java-dsl + ${spring-integration-dsl.version} + + + org.projectlombok + lombok + 1.12.6 + provided + + + com.google.guava + guava + 18.0 + + + com.sun.jersey + jersey-servlet + 1.13 + + + com.sun.jersey + jersey-core + 1.13 + + + com.sun.jersey + jersey-client + 1.13 + + + com.sun.jersey + jersey-server + 1.13 + + + org.webjars + d3js + 3.4.11 + + + org.webjars + jquery + 2.1.1 + + + org.webjars + bootstrap + 3.2.0 + + + javax.inject + javax.inject + 1 + + + + + spring-cloud-netflix-core + spring-cloud-netflix-hystrix-dashboard + spring-cloud-netflix-hystrix-amqp + spring-cloud-netflix-eureka-server + spring-cloud-netflix-turbine + spring-cloud-netflix-turbine-amqp + spring-cloud-netflix-sidecar + docs + diff --git a/spring-cloud-netflix-core/pom.xml b/spring-cloud-netflix-core/pom.xml index ba0347e11..5e24719af 100644 --- a/spring-cloud-netflix-core/pom.xml +++ b/spring-cloud-netflix-core/pom.xml @@ -2,19 +2,19 @@ 4.0.0 - - spring-cloud-netflix-core - jar - Spring Cloud Netflix Core - Spring Cloud Netflix Core - org.springframework.cloud spring-cloud-netflix 1.0.0.BUILD-SNAPSHOT .. - + spring-cloud-netflix-core + jar + Spring Cloud Netflix Core + Spring Cloud Netflix Core + + ${basedir}/.. + org.springframework.boot @@ -24,11 +24,11 @@ org.springframework.boot spring-boot-autoconfigure - - org.springframework.cloud - spring-cloud-commons - true - + + org.springframework.cloud + spring-cloud-commons + true + org.springframework.cloud spring-cloud-config-client @@ -68,10 +68,8 @@ com.netflix.feign feign-ribbon - true + true - com.netflix.hystrix hystrix-core @@ -87,11 +85,11 @@ hystrix-javanica true - - com.netflix.ribbon - ribbon - true - + + com.netflix.ribbon + ribbon + true + com.netflix.ribbon ribbon-core @@ -102,27 +100,27 @@ ribbon-eureka true - - com.netflix.ribbon - ribbon-httpclient - true - - - com.netflix.zuul - zuul-core - true - - - groovy-all - org.codehaus.groovy - - - - - com.netflix.rxjava - rxjava-core - true - + + com.netflix.ribbon + ribbon-httpclient + true + + + com.netflix.zuul + zuul-core + true + + + groovy-all + org.codehaus.groovy + + + + + com.netflix.rxjava + rxjava-core + true + org.projectlombok lombok @@ -139,11 +137,9 @@ javax.inject javax.inject - - com.google.guava - guava - - + + com.google.guava + guava + - diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/Constants.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/Constants.java index 77d7bef4e..b0e2d6a51 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/Constants.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/Constants.java @@ -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"; + } diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/archaius/ArchaiusAutoConfiguration.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/archaius/ArchaiusAutoConfiguration.java index 43b7d8af3..bf2633573 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/archaius/ArchaiusAutoConfiguration.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/archaius/ArchaiusAutoConfiguration.java @@ -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? diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/archaius/ArchaiusDelegatingProxyUtils.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/archaius/ArchaiusDelegatingProxyUtils.java index a74de871c..a28507b98 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/archaius/ArchaiusDelegatingProxyUtils.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/archaius/ArchaiusDelegatingProxyUtils.java @@ -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 getNamedInstance(Class 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 getInstanceWithPrefix(Class 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); } diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/archaius/ArchaiusEndpoint.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/archaius/ArchaiusEndpoint.java index 8b4f763fc..d3a478bd7 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/archaius/ArchaiusEndpoint.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/archaius/ArchaiusEndpoint.java @@ -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> { diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/archaius/ConfigurableEnvironmentConfiguration.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/archaius/ConfigurableEnvironmentConfiguration.java index 03fba36d0..a2419d780 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/archaius/ConfigurableEnvironmentConfiguration.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/archaius/ConfigurableEnvironmentConfiguration.java @@ -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 getKeys() { - List result = new ArrayList<>(); - for (Map.Entry> 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> getPropertySources() { - Map> 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 getKeys() { + List result = new ArrayList<>(); + for (Map.Entry> 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> 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> getPropertySources() { + Map> 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> 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); + } + } } diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/config/DiscoveryClientConfigServiceBootstrapConfiguration.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/config/DiscoveryClientConfigServiceBootstrapConfiguration.java index 8bff7d167..7d751d683 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/config/DiscoveryClientConfigServiceBootstrapConfiguration.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/config/DiscoveryClientConfigServiceBootstrapConfiguration.java @@ -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); } } diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/config/EurekaClientConfigServerAutoConfiguration.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/config/EurekaClientConfigServerAutoConfiguration.java index f5e26ba25..5fe44d695 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/config/EurekaClientConfigServerAutoConfiguration.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/config/EurekaClientConfigServerAutoConfiguration.java @@ -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); } } - + } diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/endpoint/ServletWrappingEndpoint.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/endpoint/ServletWrappingEndpoint.java index f2ac2f453..751d637fd 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/endpoint/ServletWrappingEndpoint.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/endpoint/ServletWrappingEndpoint.java @@ -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> getEndpointType() { + return null; + } - @Override - public Class> getEndpointType() { - return null; - } } diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka/DataCenterAwareMarshallingStrategy.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka/DataCenterAwareMarshallingStrategy.java index 372adc69f..e781fb2e5 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka/DataCenterAwareMarshallingStrategy.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka/DataCenterAwareMarshallingStrategy.java @@ -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) { diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka/DiscoveryManagerInitializer.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka/DiscoveryManagerInitializer.java index 972cd5a90..5307b086f 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka/DiscoveryManagerInitializer.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka/DiscoveryManagerInitializer.java @@ -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); - } - } } diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka/EnableEurekaClient.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka/EnableEurekaClient.java index 5e14de65e..4a4ad36d4 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka/EnableEurekaClient.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka/EnableEurekaClient.java @@ -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 { + } diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka/EurekaClientAutoConfiguration.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka/EurekaClientAutoConfiguration.java index 14853a7d1..abd0c0254 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka/EurekaClientAutoConfiguration.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka/EurekaClientAutoConfiguration.java @@ -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(); } - } diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka/EurekaClientConfigBean.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka/EurekaClientConfigBean.java index e47828093..ead95e2ff 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka/EurekaClientConfigBean.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka/EurekaClientConfigBean.java @@ -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 serviceUrl = new HashMap(); - + private Map serviceUrl = new HashMap(); { - 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 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; } } diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka/EurekaDiscoveryClient.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka/EurekaDiscoveryClient.java index 91c79588b..44ec7ed92 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka/EurekaDiscoveryClient.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka/EurekaDiscoveryClient.java @@ -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 getInstances(String serviceId) { - List infos = discovery.getInstancesByVipAddress(serviceId, false); - Iterable instances = transform(infos, new Function() { - @Nullable - @Override - public ServiceInstance apply(@Nullable InstanceInfo info) { - return new EurekaServiceInstance(info); - } - }); - return Lists.newArrayList(instances); - } + @Override + public List getInstances(String serviceId) { + List infos = this.discovery.getInstancesByVipAddress(serviceId, + false); + Iterable instances = transform(infos, + new Function() { + @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 getServices() { - Applications applications = discovery.getApplications(); - if (applications == null) { - return Collections.emptyList(); - } - return Lists.newArrayList(filter(transform(applications.getRegisteredApplications(), new Function() { - @Nullable - @Override - public String apply(@Nullable Application app) { - if (app.getInstances().isEmpty()) { - return null; - } - return app.getName().toLowerCase(); - } - }), Predicates.notNull())); - } + @Override + public List getServices() { + Applications applications = this.discovery.getApplications(); + if (applications == null) { + return Collections.emptyList(); + } + return Lists.newArrayList(filter( + transform(applications.getRegisteredApplications(), + new Function() { + @Nullable + @Override + public String apply(@Nullable Application app) { + if (app.getInstances().isEmpty()) { + return null; + } + return app.getName().toLowerCase(); + } + }), Predicates.notNull())); + } + + @Override + public List getAllInstances() { + Applications applications = this.discovery.getApplications(); + if (applications == null) { + return Collections.emptyList(); + } + Iterable instances = transform( + concat(transform(applications.getRegisteredApplications(), + new Function>() { + @Override + public List apply(@Nullable Application app) { + return app.getInstances(); + } + })), new Function() { + @Nullable + @Override + public ServiceInstance apply(@Nullable InstanceInfo info) { + return new EurekaServiceInstance(info); + } + }); + return Lists.newArrayList(instances); + } - @Override - public List getAllInstances() { - Applications applications = discovery.getApplications(); - if (applications == null) { - return Collections.emptyList(); - } - Iterable instances = transform(concat(transform(applications.getRegisteredApplications(), new Function>() { - public List apply(@Nullable Application app) { - return app.getInstances(); - } - })), new Function() { - @Nullable - @Override - public ServiceInstance apply(@Nullable InstanceInfo info) { - return new EurekaServiceInstance(info); - } - }); - return Lists.newArrayList(instances); - } } diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka/EurekaDiscoveryClientConfiguration.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka/EurekaDiscoveryClientConfiguration.java index 9a982d467..0f485543c 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka/EurekaDiscoveryClientConfiguration.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka/EurekaDiscoveryClientConfiguration.java @@ -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); } } + } diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka/EurekaHealthIndicator.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka/EurekaHealthIndicator.java index 626e3cf4c..2be627ea2 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka/EurekaHealthIndicator.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka/EurekaHealthIndicator.java @@ -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 value = (Metric) metrics + Metric value = (Metric) 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 getApplications() { - Applications applications = discovery.getApplications(); + Applications applications = this.discovery.getApplications(); if (applications == null) { return Collections.emptyMap(); } diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka/EurekaInstanceConfigBean.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka/EurekaInstanceConfigBean.java index f2d52a634..3676cd576 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka/EurekaInstanceConfigBean.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka/EurekaInstanceConfigBean.java @@ -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 metadataMap = new HashMap<>(); + private Map 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(); } - + } } diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka/EurekaServerConfigBean.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka/EurekaServerConfigBean.java index 2df464231..f63215081 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka/EurekaServerConfigBean.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka/EurekaServerConfigBean.java @@ -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 remoteRegionUrlsWithName = new HashMap(); - private String[] remoteRegionUrls; + private String[] remoteRegionUrls; private Map> remoteRegionAppWhitelist; - @Override - public Set 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 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 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 rateLimiterPrivilegedClients = Collections.emptySet(); - - private int rateLimiterBurstSize = 10; - - private int rateLimiterRegistryFetchAverageRate = 500; - - private int rateLimiterFullFetchAverageRate = 100; } diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignAutoConfiguration.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignAutoConfiguration.java index 3ba3bbf68..15c5c34ea 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignAutoConfiguration.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignAutoConfiguration.java @@ -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); } } + } diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignClient.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignClient.java index b0c9bcebd..8daa1b04e 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignClient.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignClient.java @@ -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; + } diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignClientFactoryBean.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignClientFactoryBean.java index e023d64f4..ef0db78b0 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignClientFactoryBean.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignClientFactoryBean.java @@ -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 { 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; } + } diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignClientScan.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignClientScan.java index 5db1536ec..74b485fe9 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignClientScan.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignClientScan.java @@ -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 * @Configuration} 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 {}; -} \ No newline at end of file +} diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignClientScanRegistrar.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignClientScanRegistrar.java index 0b6bd20d3..43acd0cc4 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignClientScanRegistrar.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignClientScanRegistrar.java @@ -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 basePackages = getBasePackages(importingClassMetadata); ClassPathScanningCandidateComponentProvider scanner = getScanner(); scanner.addIncludeFilter(new AnnotationTypeFilter(FeignClient.class)); - scanner.setResourceLoader(resourceLoader); + scanner.setResourceLoader(this.resourceLoader); for (String basePackage : basePackages) { - Set candidateComponents = scanner.findCandidateComponents(basePackage); + Set 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 attributes = annotationMetadata.getAnnotationAttributes(FeignClient.class.getCanonicalName()); + Map 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 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; } diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignConfiguration.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignConfiguration.java index 281d12118..2d5d8109e 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignConfiguration.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignConfiguration.java @@ -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 loadBalance(Class type, String schemeName) { - return loadBalance(feign(), type, schemeName); - } + protected T loadBalance(Class type, String schemeName) { + return loadBalance(feign(), type, schemeName); + } - protected T loadBalance(Feign.Builder builder, Class type, String schemeName) { - if(ribbonClient != null) { - return builder.client(ribbonClient).target(type, schemeName); - } else { - return builder.target(LoadBalancingTarget.create(type, schemeName)); - } - } + protected T loadBalance(Feign.Builder builder, Class type, String schemeName) { + if (this.ribbonClient != null) { + return builder.client(this.ribbonClient).target(type, schemeName); + } + else { + return builder.target(LoadBalancingTarget.create(type, schemeName)); + } + } } diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignUtils.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignUtils.java index 3be7c0350..2c7dadb98 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignUtils.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignUtils.java @@ -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> headers) { - HttpHeaders httpHeaders = new HttpHeaders(); - for (Map.Entry> entry : headers.entrySet()) { - httpHeaders.put(entry.getKey(), new ArrayList<>(entry.getValue())); - } - return httpHeaders; - } + + static HttpHeaders getHttpHeaders(Map> headers) { + HttpHeaders httpHeaders = new HttpHeaders(); + for (Map.Entry> entry : headers.entrySet()) { + httpHeaders.put(entry.getKey(), new ArrayList<>(entry.getValue())); + } + return httpHeaders; + } + } diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/SpringDecoder.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/SpringDecoder.java index 0992188f6..c9a811922 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/SpringDecoder.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/SpringDecoder.java @@ -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 messageConverters; + @Autowired + Provider 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()); } } + } diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/SpringEncoder.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/SpringEncoder.java index 68fd5a604..eb63e4608 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/SpringEncoder.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/SpringEncoder.java @@ -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 messageConverters; - - public SpringEncoder() { - } + @Autowired + Provider 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 copy = (HttpMessageConverter) 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; } + } + } diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/SpringMvcContract.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/SpringMvcContract.java index 1ad2a1832..c2695176c 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/SpringMvcContract.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/SpringMvcContract.java @@ -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 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 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 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 boolean searchMapValues(Map> map, V search) { - Collection> 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 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 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 header = addTemplatedParam(data.template().headers() + .get(name), name); + data.template().header(name, header); + nameParam(data, name, paramIndex); + isHttpAnnotation = true; + } - for (Collection 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 boolean searchMapValues(Map> map, V search) { + Collection> values = map.values(); + if (values == null) { + return false; + } + for (Collection entry : values) { + if (entry.contains(search)) { + return true; + } + } + return false; + } - return false; - } } diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/ribbon/FeignRibbonClient.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/ribbon/FeignRibbonClient.java index d8d1207ad..b98d608f0 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/ribbon/FeignRibbonClient.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/ribbon/FeignRibbonClient.java @@ -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() { - @Override - public SSLSocketFactory get() { - return (SSLSocketFactory) SSLSocketFactory.getDefault(); - } - }, new Lazy() { - @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 { + + @Override + public SSLSocketFactory get() { + return (SSLSocketFactory) SSLSocketFactory.getDefault(); + } + + } + + private static class LazyHostnameVerifier implements Lazy { + + @Override + public HostnameVerifier get() { + return HttpsURLConnection.getDefaultHostnameVerifier(); + } + + } - public void setDefaultClient(Client defaultClient) { - this.defaultClient = defaultClient; - } } diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/ribbon/RibbonLoadBalancer.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/ribbon/RibbonLoadBalancer.java index 3d8ab9a56..52562872d 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/ribbon/RibbonLoadBalancer.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/ribbon/RibbonLoadBalancer.java @@ -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 { +public class RibbonLoadBalancer + extends + AbstractLoadBalancerAwareClient { - 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> 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> 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(); + } + } + + } + +} diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/hystrix/EnableHystrix.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/hystrix/EnableHystrix.java index a97553c2a..eecebe161 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/hystrix/EnableHystrix.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/hystrix/EnableHystrix.java @@ -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 { + } diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/hystrix/HystrixAutoConfiguration.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/hystrix/HystrixAutoConfiguration.java index 489c84d84..c5e2c71c9 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/hystrix/HystrixAutoConfiguration.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/hystrix/HystrixAutoConfiguration.java @@ -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 diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/hystrix/HystrixCircuitBreakerConfiguration.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/hystrix/HystrixCircuitBreakerConfiguration.java index 72f7a48be..d449d97d9 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/hystrix/HystrixCircuitBreakerConfiguration.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/hystrix/HystrixCircuitBreakerConfiguration.java @@ -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 map = mapper.readValue(json, Map.class); + Map 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 { } } + } diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/hystrix/HystrixHealthIndicator.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/hystrix/HystrixHealthIndicator.java index 7f6a7eae8..59e60dd0a 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/hystrix/HystrixHealthIndicator.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/hystrix/HystrixHealthIndicator.java @@ -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. *

- * This default implementation will set the system to OUT_OF_SERVICE and - * include all open circuits by name. - * + * This default implementation will set the system to OUT_OF_SERVICE 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 openCircuitBreakers = new ArrayList(); - + // 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(); diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/hystrix/HystrixStreamEndpoint.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/hystrix/HystrixStreamEndpoint.java index fdb74d36e..ebd9c3625 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/hystrix/HystrixStreamEndpoint.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/hystrix/HystrixStreamEndpoint.java @@ -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); + } + } diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonAutoConfiguration.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonAutoConfiguration.java index 15e4e3f07..744ea4282 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonAutoConfiguration.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonAutoConfiguration.java @@ -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 configurations = new ArrayList<>(); + @Autowired(required = false) + private List 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(); diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonClient.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonClient.java index 0ee35f810..2ad16d05b 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonClient.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonClient.java @@ -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 {}; + } diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonClientConfiguration.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonClientConfiguration.java index 6db877652..bedd87fb9 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonClientConfiguration.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonClientConfiguration.java @@ -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 filter) { + // TODO: move to ribbon.eureka package + public ILoadBalancer ribbonLoadBalancer(IClientConfig config, + ServerListFilter filter) { ZoneAwareLoadBalancer balancer = new ZoneAwareLoadBalancer<>(config); wrapServerList(balancer); balancer.setFilter(filter); return balancer; } - + @Bean @ConditionalOnMissingBean public ServerListFilter 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)); } } } diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonClientConfigurationRegistrar.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonClientConfigurationRegistrar.java index f0c7f5190..44a2ff96f 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonClientConfigurationRegistrar.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonClientConfigurationRegistrar.java @@ -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 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, diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonClientSpecification.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonClientSpecification.java index 7f2afcc2c..7c492a5c4 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonClientSpecification.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonClientSpecification.java @@ -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; } diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonClients.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonClients.java index c673f63b3..f623eab0a 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonClients.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonClients.java @@ -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 @RibbonClient * annotations on a single class (including in Java 7). - * - * @author Dave Syer * + * @author Dave Syer */ @Configuration @Retention(RetentionPolicy.RUNTIME) diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonInterceptor.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonInterceptor.java index 07b461330..d82c3d57b 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonInterceptor.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonInterceptor.java @@ -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() { + + @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() { - @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); - } - }); - } } diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonLoadBalancerClient.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonLoadBalancerClient.java index e53e75988..d3ce0588a 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonLoadBalancerClient.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonLoadBalancerClient.java @@ -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 execute(String serviceId, LoadBalancerRequest request) { - ILoadBalancer loadBalancer = getLoadBalancer(serviceId); - RibbonLoadBalancerContext context = clientFactory.getLoadBalancerContext(serviceId); - Server server = getServer(serviceId, loadBalancer); - RibbonServer ribbonServer = new RibbonServer(serviceId, server); + @Override + public T execute(String serviceId, LoadBalancerRequest 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(); } + } + } diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonLoadBalancerContext.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonLoadBalancerContext.java index 46ce932b1..72eb2471b 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonLoadBalancerContext.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonLoadBalancerContext.java @@ -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); - } } diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/SpringClientFactory.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/SpringClientFactory.java index 4b9d2c5f0..1c1b5f8aa 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/SpringClientFactory.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/SpringClientFactory.java @@ -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 contexts = new ConcurrentHashMap<>(); + private Map configurations = new ConcurrentHashMap<>(); + private ApplicationContext parent; @Override public void setApplicationContext(ApplicationContext parent) throws BeansException { this.parent = parent; } - + public void setConfigurations(List 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 values = contexts.values(); - contexts.clear(); + Collection 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 getClient(String name, Class 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 entry : configurations.entrySet()) { + for (Entry 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. 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); diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/eureka/DomainExtractingServerList.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/eureka/DomainExtractingServerList.java index 4084798a6..c0edd5a67 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/eureka/DomainExtractingServerList.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/eureka/DomainExtractingServerList.java @@ -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 { - private ServerList list; - private IClientConfig clientConfig; + private ServerList list; + + private IClientConfig clientConfig; + private boolean approximateZoneFromHostname; - public DomainExtractingServerList(ServerList list, IClientConfig clientConfig, boolean approximateZoneFromHostname) { - this.list = list; - this.clientConfig = clientConfig; + public DomainExtractingServerList(ServerList list, + IClientConfig clientConfig, boolean approximateZoneFromHostname) { + this.list = list; + this.clientConfig = clientConfig; this.approximateZoneFromHostname = approximateZoneFromHostname; } - @Override - public List getInitialListOfServers() { - List servers = setZones(list.getInitialListOfServers()); - return servers; - } + @Override + public List getInitialListOfServers() { + List servers = setZones(this.list.getInitialListOfServers()); + return servers; + } - @Override - public List getUpdatedListOfServers() { - List servers = setZones(list.getUpdatedListOfServers()); - return servers; - } + @Override + public List getUpdatedListOfServers() { + List servers = setZones(this.list.getUpdatedListOfServers()); + return servers; + } - private List setZones(List servers) { - List 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 setZones(List servers) { + List 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(); + } } - diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/eureka/EurekaRibbonClientConfiguration.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/eureka/EurekaRibbonClientConfiguration.java index 4fbeb96ee..d4bfc7e29 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/eureka/EurekaRibbonClientConfiguration.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/eureka/EurekaRibbonClientConfiguration.java @@ -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: * @zone, 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) { diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/eureka/RibbonEurekaAutoConfiguration.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/eureka/RibbonEurekaAutoConfiguration.java index ce9f8618b..a6b07fc77 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/eureka/RibbonEurekaAutoConfiguration.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/eureka/RibbonEurekaAutoConfiguration.java @@ -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 { + } diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/eureka/ZonePreferenceServerListFilter.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/eureka/ZonePreferenceServerListFilter.java index e770a2afc..389304b50 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/eureka/ZonePreferenceServerListFilter.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/eureka/ZonePreferenceServerListFilter.java @@ -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 { + // 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 getFilteredListOfServers(List servers) { List output = super.getFilteredListOfServers(servers); - if (zone != null && output.size() == servers.size()) { + if (this.zone != null && output.size() == servers.size()) { List local = new ArrayList(); for (Server server : output) { - if (zone.equalsIgnoreCase(server.getZone())) { + if (this.zone.equalsIgnoreCase(server.getZone())) { local.add(server); } } diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/servo/ServoMetricCollector.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/servo/ServoMetricCollector.java index 8de0b7f0c..15daf7822 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/servo/ServoMetricCollector.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/servo/ServoMetricCollector.java @@ -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 /metric 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(key, servoMetric.getNumberValue(), - new Date(servoMetric.getTimestamp()))); + this.metrics.set(new Metric(key, + servoMetric.getNumberValue(), new Date(servoMetric + .getTimestamp()))); } } } + } } diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/servo/ServoMetricsAutoConfiguration.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/servo/ServoMetricsAutoConfiguration.java index 6cb131e25..5af9bd5a1 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/servo/ServoMetricsAutoConfiguration.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/servo/ServoMetricsAutoConfiguration.java @@ -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); } + } diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/EnableZuulProxy.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/EnableZuulProxy.java index 4c636788c..3d86c700b 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/EnableZuulProxy.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/EnableZuulProxy.java @@ -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 { + } diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/EnableZuulServer.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/EnableZuulServer.java index 6cdb2fc66..76522fd0e 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/EnableZuulServer.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/EnableZuulServer.java @@ -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 { + } diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/ProxyRouteLocator.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/ProxyRouteLocator.java index dbb490f5b..91f1363b6 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/ProxyRouteLocator.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/ProxyRouteLocator.java @@ -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 getRoutes() { - - if (routes.get() == null) { - routes.set(locateRoutes()); + if (this.routes.get() == null) { + this.routes.set(locateRoutes()); } - Map 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 entry : routes.get().entrySet()) { + String prefix = this.properties.getPrefix(); + for (Entry 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 locateRoutes() { - LinkedHashMap 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 services = discovery.getServices(); + List 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 values = new LinkedHashMap<>(); for (Entry 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 routes) { - Map routeEntries = properties.getRoutes(); + Map 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; + } } diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/RouteLocator.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/RouteLocator.java index 3c67ce200..83c3baf44 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/RouteLocator.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/RouteLocator.java @@ -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 { diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/RoutesEndpoint.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/RoutesEndpoint.java index 5d36880d0..7e371efcb 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/RoutesEndpoint.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/RoutesEndpoint.java @@ -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 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 getRoutes() { - return routes.getRoutes(); + return this.routes.getRoutes(); } @Override diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/RoutesRefreshedEvent.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/RoutesRefreshedEvent.java index 4560d1c37..580109720 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/RoutesRefreshedEvent.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/RoutesRefreshedEvent.java @@ -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; } } diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/SimpleRouteLocator.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/SimpleRouteLocator.java index 87c4f011c..348796232 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/SimpleRouteLocator.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/SimpleRouteLocator.java @@ -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 getRoutePaths() { Collection paths = new LinkedHashSet(); - for (ZuulRoute route : properties.getRoutes().values()) { + for (ZuulRoute route : this.properties.getRoutes().values()) { paths.add(route.getPath()); } return paths; diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/ZuulConfiguration.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/ZuulConfiguration.java index 6a22dfaea..948def798 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/ZuulConfiguration.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/ZuulConfiguration.java @@ -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 filters; - - @Bean - public ZuulFilterInitializer zuulFilterInitializer() { - return new ZuulFilterInitializer(filters); - } - - } - @Bean public ApplicationListener zuulRefreshRoutesListener() { return new ZuulRefreshListener(); } - private static class ZuulRefreshListener implements - ApplicationListener { - - @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 filters; + + @Bean + public ZuulFilterInitializer zuulFilterInitializer() { + return new ZuulFilterInitializer(this.filters); + } + + } + + private static class ZuulRefreshListener implements + ApplicationListener { + + @Autowired + private ZuulHandlerMapping zuulHandlerMapping; + + @Override + public void onApplicationEvent(ApplicationEvent event) { + if (event instanceof ContextRefreshedEvent + || event instanceof RefreshScopeRefreshedEvent) { + this.zuulHandlerMapping.registerHandlers(); + } + } + + } + } diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/ZuulController.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/ZuulController.java index 23f1fdacb..1b8c00cfb 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/ZuulController.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/ZuulController.java @@ -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(); - } - } } diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/ZuulFilterInitializer.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/ZuulFilterInitializer.java index a8418df58..f6c44f041 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/ZuulFilterInitializer.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/ZuulFilterInitializer.java @@ -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 filters; + private Map filters; public ZuulFilterInitializer(Map 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 entry : filters.entrySet()) { - registry.put(entry.getKey(), entry.getValue()); - } - } + for (Map.Entry 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 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 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); } } + */ } diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/ZuulHandlerMapping.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/ZuulHandlerMapping.java index 05d0fea0d..4e48a099a 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/ZuulHandlerMapping.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/ZuulHandlerMapping.java @@ -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 routes = routeLocator.getRoutePaths(); + Collection 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); } } } diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/ZuulProperties.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/ZuulProperties.java index c15172c88..738af9c13 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/ZuulProperties.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/ZuulProperties.java @@ -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 routes = new LinkedHashMap(); + private boolean addProxyHeaders = true; + private List ignoredServices = new ArrayList(); @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; } + } } diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/ZuulProxyConfiguration.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/ZuulProxyConfiguration.java index 546a95733..ef30c9e28 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/ZuulProxyConfiguration.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/ZuulProxyConfiguration.java @@ -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 { @@ -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(); } } diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/filters/ProxyRequestHelper.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/filters/ProxyRequestHelper.java index 77e8f3743..0b702a00b 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/filters/ProxyRequestHelper.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/filters/ProxyRequestHelper.java @@ -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 buildZuulRequestQueryParams( HttpServletRequest request) { - Map> map = HTTPRequestUtils.getInstance().getQueryParams(); - MultiValueMap 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 buildZuulRequestHeaders( HttpServletRequest request) { - RequestContext context = RequestContext.getCurrentContext(); - MultiValueMap 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 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 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 collection = headers.get(CONTENT_ENCODING); for (String header : collection) { @@ -122,22 +112,19 @@ public class ProxyRequestHelper { } } context.setResponseGZipped(isOriginResponseGzipped); - for (Entry> 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 debug(String verb, String uri, MultiValueMap headers, MultiValueMap params, InputStream requestEntity) throws IOException { - Map info = new LinkedHashMap(); - 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 trace = new LinkedHashMap(); Map input = new LinkedHashMap(); 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 info, int status, MultiValueMap headers) { - if (traces != null) { + if (this.traces != null) { @SuppressWarnings("unchecked") Map trace = (Map) info.get("headers"); Map output = new LinkedHashMap(); @@ -249,4 +232,4 @@ public class ProxyRequestHelper { } } -} \ No newline at end of file +} diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/filters/post/SendErrorFilter.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/filters/post/SendErrorFilter.java index 213518e5d..773542a61 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/filters/post/SendErrorFilter.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/filters/post/SendErrorFilter.java @@ -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; - } } diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/filters/post/SendResponseFilter.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/filters/post/SendResponseFilter.java index 541d47f7a..b75affe25 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/filters/post/SendResponseFilter.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/filters/post/SendResponseFilter.java @@ -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> zuulResponseHeaders = context.getZuulResponseHeaders(); - @SuppressWarnings("unchecked") List rd = (List) 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 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); + } } } -} \ No newline at end of file +} diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/filters/pre/DebugFilter.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/filters/pre/DebugFilter.java index 1a68867c6..3c9e22288 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/filters/pre/DebugFilter.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/filters/pre/DebugFilter.java @@ -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; + } } - - - diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/filters/pre/FormBodyWrapperFilter.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/filters/pre/FormBodyWrapperFilter.java index 18becc75d..d96eeb391 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/filters/pre/FormBodyWrapperFilter.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/filters/pre/FormBodyWrapperFilter.java @@ -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 entry : request.getParameterMap().entrySet()) { + for (Entry 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 { } } + } diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/filters/pre/PreDecorationFilter.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/filters/pre/PreDecorationFilter.java index b9fb96c73..5e9c3bb27 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/filters/pre/PreDecorationFilter.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/filters/pre/PreDecorationFilter.java @@ -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); } } } diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/filters/pre/Servlet30WrapperFilter.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/filters/pre/Servlet30WrapperFilter.java index 558b414cf..07742bb52 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/filters/pre/Servlet30WrapperFilter.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/filters/pre/Servlet30WrapperFilter.java @@ -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 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 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(); - } - } } diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/RibbonCommand.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/RibbonCommand.java index d33f80377..50f5886b2 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/RibbonCommand.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/RibbonCommand.java @@ -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 { - private RestClient restClient; - private Verb verb; - private URI uri; - private MultivaluedMap headers; - private MultivaluedMap params; - private InputStream requestEntity; + private RestClient restClient; - public RibbonCommand(RestClient restClient, - Verb verb, - String uri, - MultivaluedMap headers, - MultivaluedMap 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 headers, - MultivaluedMap 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 headers; - this.restClient = restClient; - this.verb = verb; - this.uri = new URI(uri); - this.headers = headers; - this.params = params; - this.requestEntity = requestEntity; - } + private MultivaluedMap 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 headers, + MultivaluedMap 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 headers, + MultivaluedMap 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 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 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 values = this.headers.get(name); + for (String value : values) { + builder.header(name, value); + } + } + for (String name : this.params.keySet()) { + List 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; - } - - -} \ No newline at end of file +} diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/RibbonRoutingFilter.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/RibbonRoutingFilter.java index 5404534d9..f34de87f9 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/RibbonRoutingFilter.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/RibbonRoutingFilter.java @@ -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 headers = helper.buildZuulRequestHeaders(request); - MultiValueMap params = helper + MultiValueMap headers = this.helper + .buildZuulRequestHeaders(request); + MultiValueMap 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 headers, MultiValueMap params, InputStream requestEntity) throws Exception { - - Map info = helper.debug(verb.verb(), uri, headers, params, + Map 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())); } diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/SimpleHostRoutingFilter.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/SimpleHostRoutingFilter.java index 2d3be0cd9..e97c567ad 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/SimpleHostRoutingFilter.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/SimpleHostRoutingFilter.java @@ -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 CLIENT = new AtomicReference( 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 headers = helper.buildZuulRequestHeaders(request); - MultiValueMap params = helper + MultiValueMap headers = this.helper + .buildZuulRequestHeaders(request); + MultiValueMap 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 headers, MultiValueMap params, InputStream requestEntity) throws Exception { - - Map info = helper - .debug(verb, uri, headers, params, requestEntity); - + Map 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 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(); } + } -} \ No newline at end of file + +} diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/AdhocTestSuite.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/AdhocTestSuite.java index df1673a66..1c0135b94 100644 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/AdhocTestSuite.java +++ b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/AdhocTestSuite.java @@ -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 { diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/archaius/ArchaiusAutoConfigurationTests.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/archaius/ArchaiusAutoConfigurationTests.java index b5887be63..a6759087f 100644 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/archaius/ArchaiusAutoConfigurationTests.java +++ b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/archaius/ArchaiusAutoConfigurationTests.java @@ -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")); } diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/archaius/ArchaiusEndpointTests.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/archaius/ArchaiusEndpointTests.java index 79c2cf2c5..50b883d2b 100644 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/archaius/ArchaiusEndpointTests.java +++ b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/archaius/ArchaiusEndpointTests.java @@ -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 map = endpoint.invoke(); + Map map = this.endpoint.invoke(); assertTrue(map.containsKey("foo")); assertFalse(map.containsKey("user.dir")); } diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/config/DiscoveryClientConfigServiceBootstrapConfigurationTests.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/config/DiscoveryClientConfigServiceBootstrapConfigurationTests.java index 42af96b99..b85a2e746 100644 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/config/DiscoveryClientConfigServiceBootstrapConfigurationTests.java +++ b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/config/DiscoveryClientConfigServiceBootstrapConfigurationTests.java @@ -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(); } } diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/config/EurekaClientConfigServerAutoConfigurationTests.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/config/EurekaClientConfigServerAutoConfigurationTests.java index 018cb4db6..145faf8a7 100644 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/config/EurekaClientConfigServerAutoConfigurationTests.java +++ b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/config/EurekaClientConfigServerAutoConfigurationTests.java @@ -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) diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/eureka/EurekaClientConfigBeanTests.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/eureka/EurekaClientConfigBeanTests.java index 8f0a34991..af33fe14a 100644 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/eureka/EurekaClientConfigBeanTests.java +++ b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/eureka/EurekaClientConfigBeanTests.java @@ -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 . 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()); } diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/eureka/EurekaInstanceConfigBeanTests.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/eureka/EurekaInstanceConfigBeanTests.java index fbb8705c5..556a98cd3 100644 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/eureka/EurekaInstanceConfigBeanTests.java +++ b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/eureka/EurekaInstanceConfigBeanTests.java @@ -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 diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/eureka/sample/ApplicationTests.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/eureka/sample/ApplicationTests.java index 4385aa12d..eae13e526 100644 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/eureka/sample/ApplicationTests.java +++ b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/eureka/sample/ApplicationTests.java @@ -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; diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/eureka/sample/EurekaSampleApplication.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/eureka/sample/EurekaSampleApplication.java index 3464933a5..c9f2a181e 100644 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/eureka/sample/EurekaSampleApplication.java +++ b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/eureka/sample/EurekaSampleApplication.java @@ -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); } diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/FeignClientTests.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/FeignClientTests.java index 41c9d15c6..0e58a5738 100644 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/FeignClientTests.java +++ b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/FeignClientTests.java @@ -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 getHellos(); - - @RequestMapping(method = RequestMethod.GET, value = "/hellostrings") - public List 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 getHellos() { - ArrayList hellos = new ArrayList<>(); - hellos.add(new Hello("hello world 1")); - hellos.add(new Hello("oi terra 2")); - return hellos; - } + public List getHellos(); @RequestMapping(method = RequestMethod.GET, value = "/hellostrings") - public List getHelloStrings() { - ArrayList hellos = new ArrayList<>(); - hellos.add("hello world 1"); - hellos.add("oi terra 2"); - return hellos; - } + public List 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 getHellos() { + ArrayList 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 getHelloStrings() { + ArrayList 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 diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/SpringDecoderTests.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/SpringDecoderTests.java index 5907e5cd7..a63c584fa 100644 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/SpringDecoderTests.java +++ b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/SpringDecoderTests.java @@ -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 getHellos(); + @Test + public void testUserParameterizedTypeDecode() { + List 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 getHelloStrings(); - } + @Test + public void testSimpleParameterizedTypeDecode() { + List 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 getHellos() { - ArrayList 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 getHellos(); - public List getHelloStrings() { - ArrayList hellos = new ArrayList<>(); - hellos.add("hello world 1"); - hellos.add("oi terra 2"); - return hellos; - } + @RequestMapping(method = RequestMethod.GET, value = "/hellostrings") + public List 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 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 getHellos() { + ArrayList hellos = new ArrayList<>(); + hellos.add(new Hello("hello world 1")); + hellos.add(new Hello("oi terra 2")); + return hellos; + } - @Test - public void testSimpleParameterizedTypeDecode() { - List 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 getHelloStrings() { + ArrayList 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; - } } diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/hystrix/HystrixConfigurationTests.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/hystrix/HystrixConfigurationTests.java index e7ab601b6..3982bfc08 100644 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/hystrix/HystrixConfigurationTests.java +++ b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/hystrix/HystrixConfigurationTests.java @@ -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(); } } diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/hystrix/HystrixOnlyTests.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/hystrix/HystrixOnlyTests.java index 58a280724..c40b8e2c2 100644 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/hystrix/HystrixOnlyTests.java +++ b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/hystrix/HystrixOnlyTests.java @@ -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); } + } diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/hystrix/HystrixStreamEndpointTests.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/hystrix/HystrixStreamEndpointTests.java index 02d8c020b..e03d51356 100644 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/hystrix/HystrixStreamEndpointTests.java +++ b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/hystrix/HystrixStreamEndpointTests.java @@ -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 { diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/ribbon/PlainRibbonClientPreprocessorIntegrationTests.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/ribbon/PlainRibbonClientPreprocessorIntegrationTests.java index ce9db950d..6233ac758 100644 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/ribbon/PlainRibbonClientPreprocessorIntegrationTests.java +++ b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/ribbon/PlainRibbonClientPreprocessorIntegrationTests.java @@ -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 loadBalancer = (ZoneAwareLoadBalancer) factory + ZoneAwareLoadBalancer loadBalancer = (ZoneAwareLoadBalancer) this.factory .getLoadBalancer("foo"); DomainExtractingServerList.class.cast(loadBalancer.getServerListImpl()); } diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonClientPreprocessorIntegrationTests.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonClientPreprocessorIntegrationTests.java index 753169ea8..62ea4c5a9 100644 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonClientPreprocessorIntegrationTests.java +++ b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonClientPreprocessorIntegrationTests.java @@ -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 loadBalancer = (ZoneAwareLoadBalancer) factory + ZoneAwareLoadBalancer loadBalancer = (ZoneAwareLoadBalancer) 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 loadBalancer = (ZoneAwareLoadBalancer) factory + ZoneAwareLoadBalancer loadBalancer = (ZoneAwareLoadBalancer) 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 loadBalancer = (ZoneAwareLoadBalancer) factory + ZoneAwareLoadBalancer loadBalancer = (ZoneAwareLoadBalancer) this.factory .getLoadBalancer("foo"); assertEquals("myTestZone", ZonePreferenceServerListFilter.class.cast(loadBalancer.getFilter()) diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonClientsPreprocessorIntegrationTests.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonClientsPreprocessorIntegrationTests.java index 73e40c785..4d3fb2395 100644 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonClientsPreprocessorIntegrationTests.java +++ b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonClientsPreprocessorIntegrationTests.java @@ -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 loadBalancer = (ZoneAwareLoadBalancer) factory + ZoneAwareLoadBalancer loadBalancer = (ZoneAwareLoadBalancer) 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 loadBalancer = (ZoneAwareLoadBalancer) factory + ZoneAwareLoadBalancer loadBalancer = (ZoneAwareLoadBalancer) 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 loadBalancer = (ZoneAwareLoadBalancer) factory + ZoneAwareLoadBalancer loadBalancer = (ZoneAwareLoadBalancer) this.factory .getLoadBalancer("foo"); assertEquals("myTestZone", - ZonePreferenceServerListFilter.class.cast(loadBalancer.getFilter()).getZone()); + ZonePreferenceServerListFilter.class.cast(loadBalancer.getFilter()) + .getZone()); } @Configuration diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonInterceptorTests.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonInterceptorTests.java index 10a64c409..adb75d4b3 100644 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonInterceptorTests.java +++ b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonInterceptorTests.java @@ -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 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 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 execute(String serviceId, LoadBalancerRequest 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 execute(String serviceId, LoadBalancerRequest 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(); - } - } } diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonLoadBalancerClientTests.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonLoadBalancerClientTests.java index 718cf713b..fd1f2cfac 100644 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonLoadBalancerClientTests.java +++ b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonLoadBalancerClientTests.java @@ -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() { + @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() { - @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() { + @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() { - @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); + } } diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/ribbon/SpringClientFactoryTests.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/ribbon/SpringClientFactoryTests.java index dd49c27e7..c94318c59 100644 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/ribbon/SpringClientFactoryTests.java +++ b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/ribbon/SpringClientFactoryTests.java @@ -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(); } } diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/ribbon/eureka/DomainExtractingServerListTests.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/ribbon/eureka/DomainExtractingServerListTests.java index d2f08ac76..9cd532d8c 100644 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/ribbon/eureka/DomainExtractingServerListTests.java +++ b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/ribbon/eureka/DomainExtractingServerListTests.java @@ -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 org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; +package org.springframework.cloud.netflix.ribbon.eureka; import java.util.Arrays; import java.util.List; @@ -19,81 +29,91 @@ import com.netflix.loadbalancer.Server; import com.netflix.loadbalancer.ServerList; import com.netflix.niws.loadbalancer.DiscoveryEnabledServer; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.mockito.BDDMockito.given; +import static org.mockito.Mockito.mock; + /** * @author Spencer Gibb */ public class DomainExtractingServerListTests { - static final String IP_ADDR = "10.0.0.2"; - static final int PORT = 8080; - static final String ZONE = "myzone.mydomain.com"; - static final String HOST_NAME = "myHostName."+ZONE; - static final String INSTANCE_ID = "myInstanceId"; + static final String IP_ADDR = "10.0.0.2"; - @Test - public void testDomainExtractingServer() { - DomainExtractingServerList serverList = getDomainExtractingServerList(new DefaultClientConfigImpl(), true); + static final int PORT = 8080; - List servers = serverList.getInitialListOfServers(); - assertNotNull("servers was null", servers); - assertEquals("servers was not size 1", 1, servers.size()); + static final String ZONE = "myzone.mydomain.com"; - DomainExtractingServer des = assertDomainExtractingServer(servers, ZONE); - assertEquals("hostPort was wrong", HOST_NAME+":"+PORT, des.getHostPort()); - } + static final String HOST_NAME = "myHostName." + ZONE; + + static final String INSTANCE_ID = "myInstanceId"; @Test - public void testDomainExtractingServerDontApproximateZone() { - DomainExtractingServerList serverList = getDomainExtractingServerList(new DefaultClientConfigImpl(), false); - + public void testDomainExtractingServer() { + DomainExtractingServerList serverList = getDomainExtractingServerList( + new DefaultClientConfigImpl(), true); List servers = serverList.getInitialListOfServers(); assertNotNull("servers was null", servers); assertEquals("servers was not size 1", 1, servers.size()); - - DomainExtractingServer des = assertDomainExtractingServer(servers, null); - assertEquals("hostPort was wrong", HOST_NAME+":"+PORT, des.getHostPort()); + DomainExtractingServer des = assertDomainExtractingServer(servers, ZONE); + assertEquals("hostPort was wrong", HOST_NAME + ":" + PORT, des.getHostPort()); } - protected DomainExtractingServer assertDomainExtractingServer(List servers, String zone) { - Server actualServer = servers.get(0); - assertTrue("server was not a DomainExtractingServer", actualServer instanceof DomainExtractingServer); - DomainExtractingServer des = DomainExtractingServer.class.cast(actualServer); - assertEquals("zone was wrong", zone, des.getZone()); - assertEquals("instanceId was wrong", INSTANCE_ID, des.getId()); - return des; - } + @Test + public void testDomainExtractingServerDontApproximateZone() { + DomainExtractingServerList serverList = getDomainExtractingServerList( + new DefaultClientConfigImpl(), false); + List servers = serverList.getInitialListOfServers(); + assertNotNull("servers was null", servers); + assertEquals("servers was not size 1", 1, servers.size()); + DomainExtractingServer des = assertDomainExtractingServer(servers, null); + assertEquals("hostPort was wrong", HOST_NAME + ":" + PORT, des.getHostPort()); + } - @Test - public void testDomainExtractingServerUseIpAddress() { - DefaultClientConfigImpl config = new DefaultClientConfigImpl(); - config.setProperty(CommonClientConfigKey.UseIPAddrForServer, true); - DomainExtractingServerList serverList = getDomainExtractingServerList(config, true); + protected DomainExtractingServer assertDomainExtractingServer(List servers, + String zone) { + Server actualServer = servers.get(0); + assertTrue("server was not a DomainExtractingServer", + actualServer instanceof DomainExtractingServer); + DomainExtractingServer des = DomainExtractingServer.class.cast(actualServer); + assertEquals("zone was wrong", zone, des.getZone()); + assertEquals("instanceId was wrong", INSTANCE_ID, des.getId()); + return des; + } - List servers = serverList.getInitialListOfServers(); - assertNotNull("servers was null", servers); - assertEquals("servers was not size 1", 1, servers.size()); + @Test + public void testDomainExtractingServerUseIpAddress() { + DefaultClientConfigImpl config = new DefaultClientConfigImpl(); + config.setProperty(CommonClientConfigKey.UseIPAddrForServer, true); + DomainExtractingServerList serverList = getDomainExtractingServerList(config, + true); + List servers = serverList.getInitialListOfServers(); + assertNotNull("servers was null", servers); + assertEquals("servers was not size 1", 1, servers.size()); + DomainExtractingServer des = assertDomainExtractingServer(servers, ZONE); + assertEquals("hostPort was wrong", IP_ADDR + ":" + PORT, des.getHostPort()); + } - DomainExtractingServer des = assertDomainExtractingServer(servers, ZONE); - assertEquals("hostPort was wrong", IP_ADDR+":"+PORT, des.getHostPort()); - } - - protected DomainExtractingServerList getDomainExtractingServerList(DefaultClientConfigImpl config, boolean approximateZoneFromHostname) { - DiscoveryEnabledServer server = mock(DiscoveryEnabledServer.class); + protected DomainExtractingServerList getDomainExtractingServerList( + DefaultClientConfigImpl config, boolean approximateZoneFromHostname) { + DiscoveryEnabledServer server = mock(DiscoveryEnabledServer.class); @SuppressWarnings("unchecked") ServerList originalServerList = mock(ServerList.class); - InstanceInfo instanceInfo = mock(InstanceInfo.class); - - when(server.getInstanceInfo()).thenReturn(instanceInfo); - when(server.getHost()).thenReturn(HOST_NAME); - - when(instanceInfo.getMetadata()).thenReturn(ImmutableMap.builder().put("instanceId", INSTANCE_ID).build()); - when(instanceInfo.getHostName()).thenReturn(HOST_NAME); - when(instanceInfo.getIPAddr()).thenReturn(IP_ADDR); - when(instanceInfo.getPort()).thenReturn(PORT); - - when(originalServerList.getInitialListOfServers()).thenReturn(Arrays.asList(server)); - - return new DomainExtractingServerList(originalServerList, config, approximateZoneFromHostname); - } + InstanceInfo instanceInfo = mock(InstanceInfo.class); + given(server.getInstanceInfo()).willReturn(instanceInfo); + given(server.getHost()).willReturn(HOST_NAME); + given(instanceInfo.getMetadata()).willReturn( + ImmutableMap. builder().put("instanceId", INSTANCE_ID) + .build()); + given(instanceInfo.getHostName()).willReturn(HOST_NAME); + given(instanceInfo.getIPAddr()).willReturn(IP_ADDR); + given(instanceInfo.getPort()).willReturn(PORT); + given(originalServerList.getInitialListOfServers()).willReturn( + Arrays. asList(server)); + return new DomainExtractingServerList(originalServerList, config, + approximateZoneFromHostname); + } } diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/ribbon/eureka/EurekaRibbonClientConfigurationTests.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/ribbon/eureka/EurekaRibbonClientConfigurationTests.java index d0dc336e8..0aeaaed77 100644 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/ribbon/eureka/EurekaRibbonClientConfigurationTests.java +++ b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/ribbon/eureka/EurekaRibbonClientConfigurationTests.java @@ -13,12 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.cloud.netflix.ribbon.eureka; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; -import static org.springframework.cloud.netflix.ribbon.eureka.EurekaRibbonClientConfiguration.VALUE_NOT_SET; +package org.springframework.cloud.netflix.ribbon.eureka; import org.junit.After; import org.junit.Ignore; @@ -33,9 +29,13 @@ import com.netflix.loadbalancer.ILoadBalancer; import com.netflix.loadbalancer.Server; import com.netflix.loadbalancer.ZoneAwareLoadBalancer; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.springframework.cloud.netflix.ribbon.eureka.EurekaRibbonClientConfiguration.VALUE_NOT_SET; + /** * @author Dave Syer - * */ public class EurekaRibbonClientConfigurationTests { @@ -67,22 +67,15 @@ public class EurekaRibbonClientConfigurationTests { EurekaClientConfigBean client = new EurekaClientConfigBean(); EurekaRibbonClientConfiguration preprocessor = new EurekaRibbonClientConfiguration( client, "myService"); - String serviceId = "myService"; String suffix = "mySuffix"; String value = "myValue"; - DynamicStringProperty property = preprocessor.getProperty(preprocessor.getKey( serviceId, suffix)); - assertEquals("property doesn't have default value", VALUE_NOT_SET, property.get()); - preprocessor.setProp(serviceId, suffix, value); - assertEquals("property has wrong value", value, property.get()); - preprocessor.setProp(serviceId, suffix, value); - assertEquals("property has wrong value", value, property.get()); } diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/ribbon/eureka/EurekaRibbonClientPreprocessorIntegrationTests.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/ribbon/eureka/EurekaRibbonClientPreprocessorIntegrationTests.java index 1a36d6100..1849c16f5 100644 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/ribbon/eureka/EurekaRibbonClientPreprocessorIntegrationTests.java +++ b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/ribbon/eureka/EurekaRibbonClientPreprocessorIntegrationTests.java @@ -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.junit.Test; @@ -37,7 +38,6 @@ import com.netflix.loadbalancer.ZoneAwareLoadBalancer; /** * @author Dave Syer - * */ @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = TestConfiguration.class) @@ -50,7 +50,7 @@ public class EurekaRibbonClientPreprocessorIntegrationTests { @Test public void ruleDefaultsToZoneAvoidance() throws Exception { @SuppressWarnings("unchecked") - ZoneAwareLoadBalancer loadBalancer = (ZoneAwareLoadBalancer) factory + ZoneAwareLoadBalancer loadBalancer = (ZoneAwareLoadBalancer) this.factory .getLoadBalancer("foo"); ZoneAvoidanceRule.class.cast(loadBalancer.getRule()); } @@ -61,6 +61,7 @@ public class EurekaRibbonClientPreprocessorIntegrationTests { ArchaiusAutoConfiguration.class, RibbonAutoConfiguration.class, EurekaClientAutoConfiguration.class, RibbonEurekaAutoConfiguration.class }) protected static class TestConfiguration { + } } diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/ribbon/eureka/ZonePreferenceServerListFilterTests.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/ribbon/eureka/ZonePreferenceServerListFilterTests.java index 2ed523844..357b6dc30 100644 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/ribbon/eureka/ZonePreferenceServerListFilterTests.java +++ b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/ribbon/eureka/ZonePreferenceServerListFilterTests.java @@ -13,9 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.cloud.netflix.ribbon.eureka; -import static org.junit.Assert.assertEquals; +package org.springframework.cloud.netflix.ribbon.eureka; import java.util.Arrays; import java.util.List; @@ -26,25 +25,27 @@ import org.springframework.test.util.ReflectionTestUtils; import com.netflix.loadbalancer.Server; +import static org.junit.Assert.assertEquals; + /** * @author Dave Syer - * */ public class ZonePreferenceServerListFilterTests { private Server dsyer = new Server("dsyer", 8080); private Server localhost = new Server("localhost", 8080); - + @Before public void init() { - dsyer.setZone("dsyer"); - localhost.setZone("localhost"); + this.dsyer.setZone("dsyer"); + this.localhost.setZone("localhost"); } @Test public void noZoneSet() { ZonePreferenceServerListFilter filter = new ZonePreferenceServerListFilter(); - List result = filter.getFilteredListOfServers(Arrays.asList(localhost)); + List result = filter.getFilteredListOfServers(Arrays + .asList(this.localhost)); assertEquals(1, result.size()); } @@ -52,7 +53,8 @@ public class ZonePreferenceServerListFilterTests { public void withZoneSetAndNoMatches() { ZonePreferenceServerListFilter filter = new ZonePreferenceServerListFilter(); ReflectionTestUtils.setField(filter, "zone", "dsyer"); - List result = filter.getFilteredListOfServers(Arrays.asList(localhost)); + List result = filter.getFilteredListOfServers(Arrays + .asList(this.localhost)); assertEquals(1, result.size()); } @@ -60,7 +62,8 @@ public class ZonePreferenceServerListFilterTests { public void withZoneSetAndMatches() { ZonePreferenceServerListFilter filter = new ZonePreferenceServerListFilter(); ReflectionTestUtils.setField(filter, "zone", "dsyer"); - List result = filter.getFilteredListOfServers(Arrays.asList(dsyer, localhost)); + List result = filter.getFilteredListOfServers(Arrays.asList(this.dsyer, + this.localhost)); assertEquals(1, result.size()); } diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/zuul/FormZuulProxyApplicationTests.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/zuul/FormZuulProxyApplicationTests.java index 77eb0fb65..cd6af3cf2 100644 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/zuul/FormZuulProxyApplicationTests.java +++ b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/zuul/FormZuulProxyApplicationTests.java @@ -1,6 +1,20 @@ -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 static org.junit.Assert.assertEquals; +package org.springframework.cloud.netflix.zuul; import java.util.Arrays; @@ -38,11 +52,12 @@ import com.netflix.loadbalancer.ILoadBalancer; import com.netflix.loadbalancer.Server; import com.netflix.zuul.ZuulFilter; +import static org.junit.Assert.assertEquals; + @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = FormZuulProxyApplication.class) @WebAppConfiguration -@IntegrationTest({ "server.port: 0", - "zuul.routes.simple: /simple/**" }) +@IntegrationTest({ "server.port: 0", "zuul.routes.simple: /simple/**" }) @DirtiesContext public class FormZuulProxyApplicationTests { @@ -62,8 +77,9 @@ public class FormZuulProxyApplicationTests { HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); ResponseEntity result = new TestRestTemplate().exchange( - "http://localhost:" + port + "/simple", HttpMethod.POST, - new HttpEntity>(form, headers), String.class); + "http://localhost:" + this.port + "/simple", HttpMethod.POST, + new HttpEntity>(form, headers), + String.class); assertEquals(HttpStatus.OK, result.getStatusCode()); assertEquals("Posted! {foo=[bar]}", result.getBody()); } @@ -73,16 +89,18 @@ public class FormZuulProxyApplicationTests { MultiValueMap form = new LinkedMultiValueMap(); form.set("foo", "bar"); HttpHeaders headers = new HttpHeaders(); - headers.setContentType(MediaType.valueOf(MediaType.APPLICATION_FORM_URLENCODED_VALUE+"; charset=UTF-8")); + headers.setContentType(MediaType + .valueOf(MediaType.APPLICATION_FORM_URLENCODED_VALUE + "; charset=UTF-8")); ResponseEntity result = new TestRestTemplate().exchange( - "http://localhost:" + port + "/simple", HttpMethod.POST, - new HttpEntity>(form, headers), String.class); + "http://localhost:" + this.port + "/simple", HttpMethod.POST, + new HttpEntity>(form, headers), + String.class); assertEquals(HttpStatus.OK, result.getStatusCode()); assertEquals("Posted! {foo=[bar]}", result.getBody()); } } -//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 @RestController @@ -98,6 +116,7 @@ class FormZuulProxyApplication { @Bean public ZuulFilter sampleFilter() { return new ZuulFilter() { + @Override public String filterType() { return "pre"; @@ -117,6 +136,7 @@ class FormZuulProxyApplication { public int filterOrder() { return 0; } + }; } @@ -126,9 +146,10 @@ class FormZuulProxyApplication { } -//Load balancer with fixed server list for "simple" pointing to localhost +// Load balancer with fixed server list for "simple" pointing to localhost @Configuration class FormRibbonClientConfiguration { + @Bean public ILoadBalancer ribbonLoadBalancer(EurekaInstanceConfig instance) { BaseLoadBalancer balancer = new BaseLoadBalancer(); @@ -136,4 +157,5 @@ class FormRibbonClientConfiguration { .getNonSecurePort()))); return balancer; } + } diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/zuul/ProxyRouteLocatorTests.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/zuul/ProxyRouteLocatorTests.java index 610b29e7b..067f1d958 100644 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/zuul/ProxyRouteLocatorTests.java +++ b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/zuul/ProxyRouteLocatorTests.java @@ -1,11 +1,20 @@ -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 static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.mockito.Mockito.when; -import static org.mockito.MockitoAnnotations.initMocks; +package org.springframework.cloud.netflix.zuul; import java.util.Map; @@ -19,6 +28,13 @@ import org.springframework.core.env.ConfigurableEnvironment; import com.google.common.collect.Lists; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.mockito.BDDMockito.given; +import static org.mockito.MockitoAnnotations.initMocks; + /** * @author Spencer Gibb * @author Dave Syer @@ -26,14 +42,16 @@ import com.google.common.collect.Lists; public class ProxyRouteLocatorTests { public static final String IGNOREDSERVICE = "ignoredservice"; + public static final String ASERVICE = "aservice"; + public static final String MYSERVICE = "myservice"; @Mock - ConfigurableEnvironment env; + private ConfigurableEnvironment env; @Mock - DiscoveryClient discovery; + private DiscoveryClient discovery; private ZuulProperties properties = new ZuulProperties(); @@ -41,12 +59,13 @@ public class ProxyRouteLocatorTests { public void init() { initMocks(this); } - + @Test public void testGetMatchingPath() throws Exception { - ProxyRouteLocator routeLocator = new ProxyRouteLocator(this.discovery, this.properties); + ProxyRouteLocator routeLocator = new ProxyRouteLocator(this.discovery, + this.properties); this.properties.getRoutes().put("foo", new ZuulRoute("/foo/**")); - properties.init(); + this.properties.init(); routeLocator.getRoutes(); // force refresh ProxyRouteSpec route = routeLocator.getMatchingRoute("/foo/1"); assertEquals("foo", route.getLocation()); @@ -55,10 +74,11 @@ public class ProxyRouteLocatorTests { @Test public void testGetMatchingPathWithPrefix() throws Exception { - ProxyRouteLocator routeLocator = new ProxyRouteLocator(this.discovery, this.properties); + ProxyRouteLocator routeLocator = new ProxyRouteLocator(this.discovery, + this.properties); this.properties.getRoutes().put("foo", new ZuulRoute("/foo/**")); this.properties.setPrefix("/proxy"); - properties.init(); + this.properties.init(); routeLocator.getRoutes(); // force refresh ProxyRouteSpec route = routeLocator.getMatchingRoute("/proxy/foo/1"); assertEquals("foo", route.getLocation()); @@ -67,8 +87,10 @@ public class ProxyRouteLocatorTests { @Test public void testGetMatchingPathWithNoPrefixStripping() throws Exception { - ProxyRouteLocator routeLocator = new ProxyRouteLocator(this.discovery, this.properties); - this.properties.getRoutes().put("foo", new ZuulRoute("foo", "/foo/**", "foo", null, false)); + ProxyRouteLocator routeLocator = new ProxyRouteLocator(this.discovery, + this.properties); + this.properties.getRoutes().put("foo", + new ZuulRoute("foo", "/foo/**", "foo", null, false)); this.properties.setStripPrefix(false); this.properties.setPrefix("/proxy"); routeLocator.getRoutes(); // force refresh @@ -79,7 +101,8 @@ public class ProxyRouteLocatorTests { @Test public void testGetMatchingPathWithLocalPrefixStripping() throws Exception { - ProxyRouteLocator routeLocator = new ProxyRouteLocator(this.discovery, this.properties); + ProxyRouteLocator routeLocator = new ProxyRouteLocator(this.discovery, + this.properties); this.properties.getRoutes().put("foo", new ZuulRoute("/foo/**", "foo")); this.properties.setStripPrefix(false); this.properties.setPrefix("/proxy"); @@ -91,8 +114,10 @@ public class ProxyRouteLocatorTests { @Test public void testGetMatchingPathWithGlobalPrefixStripping() throws Exception { - ProxyRouteLocator routeLocator = new ProxyRouteLocator(this.discovery, this.properties); - this.properties.getRoutes().put("foo", new ZuulRoute("foo", "/foo/**", "foo", null, false)); + ProxyRouteLocator routeLocator = new ProxyRouteLocator(this.discovery, + this.properties); + this.properties.getRoutes().put("foo", + new ZuulRoute("foo", "/foo/**", "foo", null, false)); this.properties.setPrefix("/proxy"); routeLocator.getRoutes(); // force refresh ProxyRouteSpec route = routeLocator.getMatchingRoute("/proxy/foo/1"); @@ -102,11 +127,12 @@ public class ProxyRouteLocatorTests { @Test public void testGetMatchingPathWithRoutePrefixStripping() throws Exception { - ProxyRouteLocator routeLocator = new ProxyRouteLocator(this.discovery, this.properties); + ProxyRouteLocator routeLocator = new ProxyRouteLocator(this.discovery, + this.properties); ZuulRoute zuulRoute = new ZuulRoute("/foo/**"); zuulRoute.setStripPrefix(true); this.properties.getRoutes().put("foo", zuulRoute); - properties.init(); + this.properties.init(); routeLocator.getRoutes(); // force refresh ProxyRouteSpec route = routeLocator.getMatchingRoute("/foo/1"); assertEquals("foo", route.getLocation()); @@ -115,12 +141,11 @@ public class ProxyRouteLocatorTests { @Test public void testGetRoutes() { - ProxyRouteLocator routeLocator = new ProxyRouteLocator(this.discovery, this.properties); - this.properties.getRoutes().put(ASERVICE, new ZuulRoute("/"+ASERVICE + "/**")); - properties.init(); - + ProxyRouteLocator routeLocator = new ProxyRouteLocator(this.discovery, + this.properties); + this.properties.getRoutes().put(ASERVICE, new ZuulRoute("/" + ASERVICE + "/**")); + this.properties.init(); Map routesMap = routeLocator.getRoutes(); - assertNotNull("routesMap was null", routesMap); assertFalse("routesMap was empty", routesMap.isEmpty()); assertMapping(routesMap, ASERVICE); @@ -128,8 +153,10 @@ public class ProxyRouteLocatorTests { @Test public void testGetRoutesWithMapping() { - ProxyRouteLocator routeLocator = new ProxyRouteLocator(this.discovery, this.properties); - this.properties.getRoutes().put(ASERVICE, new ZuulRoute("/"+ASERVICE + "/**", ASERVICE)); + ProxyRouteLocator routeLocator = new ProxyRouteLocator(this.discovery, + this.properties); + this.properties.getRoutes().put(ASERVICE, + new ZuulRoute("/" + ASERVICE + "/**", ASERVICE)); this.properties.setPrefix("/foo"); Map routesMap = routeLocator.getRoutes(); @@ -138,11 +165,11 @@ public class ProxyRouteLocatorTests { @Test public void testGetPhysicalRoutes() { - ProxyRouteLocator routeLocator = new ProxyRouteLocator(this.discovery, this.properties); - this.properties.getRoutes().put(ASERVICE, new ZuulRoute("/"+ASERVICE + "/**", "http://" + ASERVICE)); - + ProxyRouteLocator routeLocator = new ProxyRouteLocator(this.discovery, + this.properties); + this.properties.getRoutes().put(ASERVICE, + new ZuulRoute("/" + ASERVICE + "/**", "http://" + ASERVICE)); Map routesMap = routeLocator.getRoutes(); - assertNotNull("routesMap was null", routesMap); assertFalse("routesMap was empty", routesMap.isEmpty()); assertMapping(routesMap, "http://" + ASERVICE, ASERVICE); @@ -150,11 +177,10 @@ public class ProxyRouteLocatorTests { @Test public void testGetDefaultRoute() { - ProxyRouteLocator routeLocator = new ProxyRouteLocator(this.discovery, this.properties); + ProxyRouteLocator routeLocator = new ProxyRouteLocator(this.discovery, + this.properties); this.properties.getRoutes().put(ASERVICE, new ZuulRoute("/**", ASERVICE)); - Map routesMap = routeLocator.getRoutes(); - assertNotNull("routesMap was null", routesMap); assertFalse("routesMap was empty", routesMap.isEmpty()); assertDefaultMapping(routesMap, ASERVICE); @@ -162,11 +188,11 @@ public class ProxyRouteLocatorTests { @Test public void testGetDefaultPhysicalRoute() { - ProxyRouteLocator routeLocator = new ProxyRouteLocator(this.discovery, this.properties); - this.properties.getRoutes().put(ASERVICE, new ZuulRoute("/**", "http://" + ASERVICE)); - + ProxyRouteLocator routeLocator = new ProxyRouteLocator(this.discovery, + this.properties); + this.properties.getRoutes().put(ASERVICE, + new ZuulRoute("/**", "http://" + ASERVICE)); Map routesMap = routeLocator.getRoutes(); - assertNotNull("routesMap was null", routesMap); assertFalse("routesMap was empty", routesMap.isEmpty()); assertDefaultMapping(routesMap, "http://" + ASERVICE); @@ -174,12 +200,11 @@ public class ProxyRouteLocatorTests { @Test public void testIgnoreRoutes() { - ProxyRouteLocator routeLocator = new ProxyRouteLocator(this.discovery, this.properties); + ProxyRouteLocator routeLocator = new ProxyRouteLocator(this.discovery, + this.properties); this.properties.setIgnoredServices(Lists.newArrayList(IGNOREDSERVICE)); - - when(discovery.getServices()).thenReturn( - Lists.newArrayList(IGNOREDSERVICE)); - + given(this.discovery.getServices()) + .willReturn(Lists.newArrayList(IGNOREDSERVICE)); Map routesMap = routeLocator.getRoutes(); String serviceId = routesMap.get(getMapping(IGNOREDSERVICE)); assertNull("routes did not ignore " + IGNOREDSERVICE, serviceId); @@ -187,13 +212,10 @@ public class ProxyRouteLocatorTests { @Test public void testAutoRoutes() { - ProxyRouteLocator routeLocator = new ProxyRouteLocator(this.discovery, this.properties); - - when(discovery.getServices()).thenReturn( - Lists.newArrayList(MYSERVICE)); - + ProxyRouteLocator routeLocator = new ProxyRouteLocator(this.discovery, + this.properties); + given(this.discovery.getServices()).willReturn(Lists.newArrayList(MYSERVICE)); Map routesMap = routeLocator.getRoutes(); - assertNotNull("routesMap was null", routesMap); assertFalse("routesMap was empty", routesMap.isEmpty()); assertMapping(routesMap, MYSERVICE); @@ -201,14 +223,13 @@ public class ProxyRouteLocatorTests { @Test public void testAutoRoutesCanBeOverridden() { - this.properties.getRoutes().put(MYSERVICE, new ZuulRoute("/"+MYSERVICE + "/**", "http://example.com/" + MYSERVICE)); - ProxyRouteLocator routeLocator = new ProxyRouteLocator(this.discovery, this.properties); - - when(discovery.getServices()).thenReturn( - Lists.newArrayList(MYSERVICE)); - + ZuulRoute route = new ZuulRoute("/" + MYSERVICE + "/**", "http://example.com/" + + MYSERVICE); + this.properties.getRoutes().put(MYSERVICE, route); + ProxyRouteLocator routeLocator = new ProxyRouteLocator(this.discovery, + this.properties); + given(this.discovery.getServices()).willReturn(Lists.newArrayList(MYSERVICE)); Map routesMap = routeLocator.getRoutes(); - assertNotNull("routesMap was null", routesMap); assertFalse("routesMap was empty", routesMap.isEmpty()); assertMapping(routesMap, "http://example.com/" + MYSERVICE, MYSERVICE); @@ -217,22 +238,22 @@ public class ProxyRouteLocatorTests { protected void assertMapping(Map routesMap, String serviceId) { assertMapping(routesMap, serviceId, serviceId); } - - protected void assertMapping(Map routesMap, String expectedRoute, String key) { + + protected void assertMapping(Map routesMap, String expectedRoute, + String key) { String mapping = getMapping(key); String route = routesMap.get(mapping); - assertEquals("routesMap had wrong value for " + mapping, expectedRoute, - route); + assertEquals("routesMap had wrong value for " + mapping, expectedRoute, route); } private String getMapping(String serviceId) { return "/" + serviceId + "/**"; } - protected void assertDefaultMapping(Map routesMap, String expectedRoute) { + protected void assertDefaultMapping(Map routesMap, + String expectedRoute) { String mapping = "/**"; String route = routesMap.get(mapping); - assertEquals("routesMap had wrong value for " + mapping, expectedRoute, - route); + assertEquals("routesMap had wrong value for " + mapping, expectedRoute, route); } } diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/zuul/SampleZuulProxyApplicationTests.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/zuul/SampleZuulProxyApplicationTests.java index bea894f7f..3aa6b1438 100644 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/zuul/SampleZuulProxyApplicationTests.java +++ b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/zuul/SampleZuulProxyApplicationTests.java @@ -1,6 +1,20 @@ -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 static org.junit.Assert.assertEquals; +package org.springframework.cloud.netflix.zuul; import java.util.Arrays; @@ -34,13 +48,14 @@ import com.netflix.loadbalancer.ILoadBalancer; import com.netflix.loadbalancer.Server; import com.netflix.zuul.ZuulFilter; +import static org.junit.Assert.assertEquals; + @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = SampleZuulProxyApplication.class) @WebAppConfiguration @IntegrationTest({ "server.port: 0", "zuul.routes.other: /test/**=http://localhost:7777/local", - "zuul.routes.another: /another/twolevel/**", - "zuul.routes.simple: /simple/**" }) + "zuul.routes.another: /another/twolevel/**", "zuul.routes.simple: /simple/**" }) @DirtiesContext public class SampleZuulProxyApplicationTests { @@ -55,18 +70,19 @@ public class SampleZuulProxyApplicationTests { @Test public void bindRouteUsingPhysicalRoute() { - assertEquals("http://localhost:7777/local", routes.getRoutes().get("/test/**")); + assertEquals("http://localhost:7777/local", + this.routes.getRoutes().get("/test/**")); } @Test public void bindRouteUsingOnlyPath() { - assertEquals("simple", routes.getRoutes().get("/simple/**")); + assertEquals("simple", this.routes.getRoutes().get("/simple/**")); } @Test public void getOnSelfViaRibbonRoutingFilter() { ResponseEntity result = new TestRestTemplate().exchange( - "http://localhost:" + port + "/simple/local/1", HttpMethod.GET, + "http://localhost:" + this.port + "/simple/local/1", HttpMethod.GET, new HttpEntity<>((Void) null), String.class); assertEquals(HttpStatus.OK, result.getStatusCode()); assertEquals("Gotten!", result.getBody()); @@ -74,10 +90,10 @@ public class SampleZuulProxyApplicationTests { @Test public void deleteOnSelfViaSimpleHostRoutingFilter() { - routes.addRoute("/self/**", "http://localhost:" + port + "/local"); - endpoint.reset(); + this.routes.addRoute("/self/**", "http://localhost:" + this.port + "/local"); + this.endpoint.reset(); ResponseEntity result = new TestRestTemplate().exchange( - "http://localhost:" + port + "/self/1", HttpMethod.DELETE, + "http://localhost:" + this.port + "/self/1", HttpMethod.DELETE, new HttpEntity<>((Void) null), String.class); assertEquals(HttpStatus.OK, result.getStatusCode()); assertEquals("Deleted!", result.getBody()); @@ -86,7 +102,7 @@ public class SampleZuulProxyApplicationTests { @Test public void testNotFound() { ResponseEntity result = new TestRestTemplate().exchange( - "http://localhost:" + port + "/myinvalidpath", HttpMethod.GET, + "http://localhost:" + this.port + "/myinvalidpath", HttpMethod.GET, new HttpEntity<>((Void) null), String.class); assertEquals(HttpStatus.NOT_FOUND, result.getStatusCode()); } @@ -94,22 +110,22 @@ public class SampleZuulProxyApplicationTests { @Test public void getSecondLevel() { ResponseEntity result = new TestRestTemplate().exchange( - "http://localhost:" + port + "/another/twolevel/local/1", HttpMethod.GET, - new HttpEntity<>((Void) null), String.class); + "http://localhost:" + this.port + "/another/twolevel/local/1", + HttpMethod.GET, new HttpEntity<>((Void) null), String.class); assertEquals(HttpStatus.OK, result.getStatusCode()); assertEquals("Gotten!", result.getBody()); } + } -//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 @RestController @EnableZuulProxy @RibbonClients({ - @RibbonClient(name = "simple", configuration = SimpleRibbonClientConfiguration.class), - @RibbonClient(name = "another", configuration = AnotherRibbonClientConfiguration.class) -}) + @RibbonClient(name = "simple", configuration = SimpleRibbonClientConfiguration.class), + @RibbonClient(name = "another", configuration = AnotherRibbonClientConfiguration.class) }) class SampleZuulProxyApplication { @RequestMapping("/testing123") @@ -168,9 +184,10 @@ class SampleZuulProxyApplication { } -//Load balancer with fixed server list for "simple" pointing to localhost +// Load balancer with fixed server list for "simple" pointing to localhost @Configuration class SimpleRibbonClientConfiguration { + @Bean public ILoadBalancer ribbonLoadBalancer(EurekaInstanceConfig instance) { BaseLoadBalancer balancer = new BaseLoadBalancer(); @@ -178,9 +195,12 @@ class SimpleRibbonClientConfiguration { .getNonSecurePort()))); return balancer; } + } + @Configuration class AnotherRibbonClientConfiguration { + @Bean public ILoadBalancer ribbonLoadBalancer(EurekaInstanceConfig instance) { BaseLoadBalancer balancer = new BaseLoadBalancer(); @@ -188,4 +208,5 @@ class AnotherRibbonClientConfiguration { .getNonSecurePort()))); return balancer; } + } diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/zuul/SimpleZuulServerApplicationTests.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/zuul/SimpleZuulServerApplicationTests.java index ffcfb05d2..3ffb0d8be 100644 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/zuul/SimpleZuulServerApplicationTests.java +++ b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/zuul/SimpleZuulServerApplicationTests.java @@ -1,7 +1,20 @@ -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 static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; +package org.springframework.cloud.netflix.zuul; import org.junit.Test; import org.junit.runner.RunWith; @@ -26,10 +39,13 @@ import org.springframework.web.bind.annotation.RestController; import com.netflix.zuul.ZuulFilter; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = SimpleZuulServerApplication.class) @WebAppConfiguration -@IntegrationTest({ "server.port: 0"}) +@IntegrationTest({ "server.port: 0" }) @DirtiesContext public class SimpleZuulServerApplicationTests { @@ -41,13 +57,13 @@ public class SimpleZuulServerApplicationTests { @Test public void bindRoute() { - assertTrue(routes.getRoutePaths().contains("/testing123/**")); + assertTrue(this.routes.getRoutePaths().contains("/testing123/**")); } @Test public void getOnSelf() { ResponseEntity result = new TestRestTemplate().exchange( - "http://localhost:" + port + "/", HttpMethod.GET, + "http://localhost:" + this.port + "/", HttpMethod.GET, new HttpEntity((Void) null), String.class); assertEquals(HttpStatus.OK, result.getStatusCode()); assertEquals("Hello world", result.getBody()); @@ -56,14 +72,14 @@ public class SimpleZuulServerApplicationTests { @Test public void getOnSelfViaFilter() { ResponseEntity result = new TestRestTemplate().exchange( - "http://localhost:" + port + "/testing123/1", HttpMethod.GET, + "http://localhost:" + this.port + "/testing123/1", HttpMethod.GET, new HttpEntity((Void) null), String.class); assertEquals(HttpStatus.OK, result.getStatusCode()); } } -//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 @RestController diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/zuul/filters/post/SendErrorFilterTests.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/zuul/filters/post/SendErrorFilterTests.java index dd3abd301..f134d8532 100644 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/zuul/filters/post/SendErrorFilterTests.java +++ b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/zuul/filters/post/SendErrorFilterTests.java @@ -1,16 +1,34 @@ +/* + * 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 com.netflix.zuul.context.RequestContext; +import javax.servlet.http.HttpServletRequest; + import org.junit.After; import org.junit.Test; import org.springframework.http.HttpStatus; import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletResponse; -import javax.servlet.http.HttpServletRequest; +import com.netflix.zuul.context.RequestContext; -import static org.junit.Assert.*; -import static org.mockito.Mockito.*; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.mock; /** * @author Spencer Gibb @@ -25,7 +43,6 @@ public class SendErrorFilterTests { @Test public void runsNormally() { SendErrorFilter filter = createSendErrorFilter(new MockHttpServletRequest()); - assertTrue("shouldFilter returned false", filter.shouldFilter()); filter.run(); } @@ -44,7 +61,6 @@ public class SendErrorFilterTests { @Test public void noRequestDispatcher() { SendErrorFilter filter = createSendErrorFilter(mock(HttpServletRequest.class)); - assertTrue("shouldFilter returned false", filter.shouldFilter()); filter.run(); } @@ -52,7 +68,6 @@ public class SendErrorFilterTests { @Test public void doesNotRunTwice() { SendErrorFilter filter = createSendErrorFilter(new MockHttpServletRequest()); - assertTrue("shouldFilter returned false", filter.shouldFilter()); filter.run(); assertFalse("shouldFilter returned true", filter.shouldFilter()); diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/zuul/filters/pre/PreDecorationFilterTests.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/zuul/filters/pre/PreDecorationFilterTests.java index 3d1aa4534..c0780f6f2 100644 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/zuul/filters/pre/PreDecorationFilterTests.java +++ b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/zuul/filters/pre/PreDecorationFilterTests.java @@ -1,7 +1,20 @@ -package org.springframework.cloud.netflix.zuul.filters.pre; +/* + * 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.mockito.MockitoAnnotations.initMocks; +package org.springframework.cloud.netflix.zuul.filters.pre; import java.util.List; @@ -17,12 +30,14 @@ import org.springframework.mock.web.MockHttpServletRequest; import com.netflix.util.Pair; import com.netflix.zuul.context.RequestContext; +import static org.junit.Assert.assertEquals; +import static org.mockito.MockitoAnnotations.initMocks; + /** * @author Dave Syer - * */ public class PreDecorationFilterTests { - + private PreDecorationFilter filter; @Mock @@ -31,32 +46,32 @@ public class PreDecorationFilterTests { private ZuulProperties properties = new ZuulProperties(); private ProxyRouteLocator routeLocator; - + private MockHttpServletRequest request = new MockHttpServletRequest(); @Before public void init() { initMocks(this); - routeLocator = new ProxyRouteLocator(discovery, properties); - filter = new PreDecorationFilter(routeLocator, properties); + this.routeLocator = new ProxyRouteLocator(this.discovery, this.properties); + this.filter = new PreDecorationFilter(this.routeLocator, this.properties); RequestContext ctx = RequestContext.getCurrentContext(); - ctx.setRequest(request); + ctx.setRequest(this.request); } - + @Test public void basicProperties() throws Exception { - assertEquals(5, filter.filterOrder()); - assertEquals(true, filter.shouldFilter()); - assertEquals("pre", filter.filterType()); + assertEquals(5, this.filter.filterOrder()); + assertEquals(true, this.filter.shouldFilter()); + assertEquals("pre", this.filter.filterType()); } @Test public void prefixRouteAddsHeader() throws Exception { - properties.setPrefix("/api"); - properties.setStripPrefix(true); - request.setRequestURI("/api/foo/1"); - routeLocator.addRoute(new ZuulRoute("foo", "/foo/**", "foo", null, false)); - filter.run(); + this.properties.setPrefix("/api"); + this.properties.setStripPrefix(true); + this.request.setRequestURI("/api/foo/1"); + this.routeLocator.addRoute(new ZuulRoute("foo", "/foo/**", "foo", null, false)); + this.filter.run(); RequestContext ctx = RequestContext.getCurrentContext(); assertEquals("/foo/1", ctx.get("requestURI")); assertEquals("localhost:80", ctx.getZuulRequestHeaders().get("x-forwarded-host")); @@ -66,11 +81,11 @@ public class PreDecorationFilterTests { @Test public void prefixRouteWithRouteStrippingAddsHeader() throws Exception { - properties.setPrefix("/api"); - properties.setStripPrefix(true); - request.setRequestURI("/api/foo/1"); - routeLocator.addRoute("/foo/**", "foo"); - filter.run(); + this.properties.setPrefix("/api"); + this.properties.setStripPrefix(true); + this.request.setRequestURI("/api/foo/1"); + this.routeLocator.addRoute("/foo/**", "foo"); + this.filter.run(); RequestContext ctx = RequestContext.getCurrentContext(); assertEquals("/1", ctx.get("requestURI")); assertEquals("localhost:80", ctx.getZuulRequestHeaders().get("x-forwarded-host")); @@ -78,8 +93,7 @@ public class PreDecorationFilterTests { assertEquals("foo", getHeader(ctx.getOriginResponseHeaders(), "x-zuul-serviceid")); } - private Object getHeader(List> headers, - String key) { + private Object getHeader(List> headers, String key) { String value = null; for (Pair pair : headers) { if (pair.first().toLowerCase().equals(key.toLowerCase())) { diff --git a/spring-cloud-netflix-eureka-server/pom.xml b/spring-cloud-netflix-eureka-server/pom.xml index 24115530b..9c491024c 100644 --- a/spring-cloud-netflix-eureka-server/pom.xml +++ b/spring-cloud-netflix-eureka-server/pom.xml @@ -2,21 +2,20 @@ 4.0.0 - spring-cloud-netflix-eureka-server - Spring Cloud Netflix Eureka Server - http://projects.spring.io/spring-cloud/ org.springframework.cloud spring-cloud-netflix 1.0.0.BUILD-SNAPSHOT .. - + spring-cloud-netflix-eureka-server + Spring Cloud Netflix Eureka Server + http://projects.spring.io/spring-cloud/ + ${basedir}/.. 1.0.0.BUILD-SNAPSHOT 1.7.6 - org.springframework.boot @@ -46,10 +45,10 @@ - - org.springframework.cloud - spring-cloud-commons - + + org.springframework.cloud + spring-cloud-commons + org.springframework.cloud spring-cloud-netflix-core @@ -84,7 +83,6 @@ test - @@ -99,7 +97,8 @@ maven-resources-plugin - + copy-resources validate diff --git a/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/EnableEurekaServer.java b/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/EnableEurekaServer.java index 7def4a0fc..0dd671613 100644 --- a/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/EnableEurekaServer.java +++ b/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/EnableEurekaServer.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.cloud.netflix.eureka.server; import java.lang.annotation.Documented; diff --git a/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/EurekaController.java b/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/EurekaController.java index d9d8dd658..a269ede09 100644 --- a/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/EurekaController.java +++ b/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/EurekaController.java @@ -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.server; import java.net.URI; @@ -35,213 +51,203 @@ import com.netflix.eureka.util.StatusInfo; @RequestMapping("${eureka.dashboard.path:/}") public class EurekaController { - @Value("${eureka.dashboard.path:/}") - private String dashboardPath = ""; + @Value("${eureka.dashboard.path:/}") + private String dashboardPath = ""; - @RequestMapping(method = RequestMethod.GET) - public String status(HttpServletRequest request, Map model) { - populateBase(request, model); + @RequestMapping(method = RequestMethod.GET) + public String status(HttpServletRequest request, Map model) { + populateBase(request, model); + populateApps(model); + StatusInfo statusInfo = new StatusResource().getStatusInfo(); + model.put("statusInfo", statusInfo); + populateInstanceInfo(model, statusInfo); + return "eureka/status"; + } - populateApps(model); + @RequestMapping(value = "/lastn", method = RequestMethod.GET) + public String lastn(HttpServletRequest request, Map model) { + populateBase(request, model); + PeerAwareInstanceRegistry registery = PeerAwareInstanceRegistry.getInstance(); + ArrayList> lastNCanceled = new ArrayList<>(); + List> list = registery.getLastNCanceledInstances(); + for (Pair entry : list) { + lastNCanceled.add(registeredInstance(entry.second(), entry.first() + .longValue())); + } + model.put("lastNCanceled", lastNCanceled); + list = registery.getLastNRegisteredInstances(); + ArrayList> lastNRegistered = new ArrayList<>(); + for (Pair entry : list) { + lastNRegistered.add(registeredInstance(entry.second(), entry.first() + .longValue())); + } + model.put("lastNRegistered", lastNRegistered); + return "eureka/lastn"; + } - StatusInfo statusInfo = new StatusResource().getStatusInfo(); - model.put("statusInfo", statusInfo); + private Map registeredInstance(String id, long date) { + HashMap map = new HashMap<>(); + map.put("id", id); + map.put("date", new Date(date)); + return map; + } - populateInstanceInfo(model, statusInfo); + protected void populateBase(HttpServletRequest request, Map model) { + model.put("time", new Date()); + model.put("basePath", "/"); + model.put("dashboardPath", this.dashboardPath.equals("/") ? "" + : this.dashboardPath); + populateHeader(model); + populateNavbar(request, model); + } - return "eureka/status"; - } + private void populateHeader(Map model) { + model.put("currentTime", StatusResource.getCurrentTimeAsString()); + model.put("upTime", StatusInfo.getUpTime()); + model.put("environment", ConfigurationManager.getDeploymentContext() + .getDeploymentEnvironment()); + model.put("datacenter", ConfigurationManager.getDeploymentContext() + .getDeploymentDatacenter()); + model.put("registry", PeerAwareInstanceRegistry.getInstance()); + model.put("isBelowRenewThresold", PeerAwareInstanceRegistry.getInstance() + .isBelowRenewThresold() == 1); + DataCenterInfo info = ApplicationInfoManager.getInstance().getInfo() + .getDataCenterInfo(); + if (info.getName() == DataCenterInfo.Name.Amazon) { + AmazonInfo amazonInfo = (AmazonInfo) info; + model.put("amazonInfo", amazonInfo); + model.put("amiId", amazonInfo.get(AmazonInfo.MetaDataKey.amiId)); + model.put("availabilityZone", + amazonInfo.get(AmazonInfo.MetaDataKey.availabilityZone)); + model.put("instanceId", amazonInfo.get(AmazonInfo.MetaDataKey.instanceId)); + } + } - @RequestMapping(value = "/lastn", method = RequestMethod.GET) - public String lastn(HttpServletRequest request, Map model) { - populateBase(request, model); - PeerAwareInstanceRegistry registery = PeerAwareInstanceRegistry.getInstance(); + private void populateNavbar(HttpServletRequest request, Map model) { + Map replicas = new LinkedHashMap<>(); + List list = PeerAwareInstanceRegistry.getInstance() + .getReplicaNodes(); + for (PeerEurekaNode node : list) { + try { + URI uri = new URI(node.getServiceUrl()); + String href = node.getServiceUrl(); + replicas.put(uri.getHost(), href); + } + catch (Exception ex) { + // ignore? + } + } + model.put("replicas", replicas.entrySet()); + } - ArrayList> lastNCanceled = new ArrayList<>(); - List> list = registery.getLastNCanceledInstances(); - for (Pair entry : list) { - lastNCanceled.add(registeredInstance(entry.second(), entry.first().longValue())); - } - model.put("lastNCanceled", lastNCanceled); + private void populateApps(Map model) { + List sortedApplications = PeerAwareInstanceRegistry + .getInstance().getSortedApplications(); + ArrayList> apps = new ArrayList<>(); + for (Application app : sortedApplications) { + LinkedHashMap appData = new LinkedHashMap<>(); + apps.add(appData); + appData.put("name", app.getName()); + Map amiCounts = new HashMap<>(); + Map>> instancesByStatus = new HashMap<>(); + Map zoneCounts = new HashMap<>(); + for (InstanceInfo info : app.getInstances()) { + String id = info.getId(); + String url = info.getStatusPageUrl(); + InstanceInfo.InstanceStatus status = info.getStatus(); + String ami = "n/a"; + String zone = ""; + if (info.getDataCenterInfo().getName() == DataCenterInfo.Name.Amazon) { + AmazonInfo dcInfo = (AmazonInfo) info.getDataCenterInfo(); + ami = dcInfo.get(AmazonInfo.MetaDataKey.amiId); + zone = dcInfo.get(AmazonInfo.MetaDataKey.availabilityZone); + } + Integer count = amiCounts.get(ami); + if (count != null) { + amiCounts.put(ami, Integer.valueOf(count.intValue() + 1)); + } + else { + amiCounts.put(ami, Integer.valueOf(1)); + } + count = zoneCounts.get(zone); + if (count != null) { + zoneCounts.put(zone, Integer.valueOf(count.intValue() + 1)); + } + else { + zoneCounts.put(zone, Integer.valueOf(1)); + } + List> list = instancesByStatus.get(status); + if (list == null) { + list = new ArrayList<>(); + instancesByStatus.put(status, list); + } + list.add(new Pair<>(id, url)); + } + appData.put("amiCounts", amiCounts.entrySet()); + appData.put("zoneCounts", zoneCounts.entrySet()); + ArrayList> instanceInfos = new ArrayList<>(); + appData.put("instanceInfos", instanceInfos); + for (Iterator>>> iter = instancesByStatus + .entrySet().iterator(); iter.hasNext();) { + Map.Entry>> entry = iter + .next(); + List> value = entry.getValue(); + InstanceInfo.InstanceStatus status = entry.getKey(); + LinkedHashMap instanceData = new LinkedHashMap<>(); + instanceInfos.add(instanceData); + instanceData.put("status", entry.getKey()); + ArrayList> instances = new ArrayList<>(); + instanceData.put("instances", instances); + instanceData.put("isNotUp", status != InstanceInfo.InstanceStatus.UP); - list = registery.getLastNRegisteredInstances(); - ArrayList> lastNRegistered = new ArrayList<>(); - for (Pair entry : list) { - lastNRegistered.add(registeredInstance(entry.second(), entry.first().longValue())); - } - model.put("lastNRegistered", lastNRegistered); + // TODO - return "eureka/lastn"; - } + /* + * if(status != InstanceInfo.InstanceStatus.UP){ + * buf.append(""); } + * buf.append("").append(status + * .name()).append(" (").append(value.size()).append(") - "); + * if(status != InstanceInfo.InstanceStatus.UP){ + * buf.append(""); } + */ - private Map registeredInstance(String id, long date) { - HashMap map = new HashMap<>(); - map.put("id", id); - map.put("date", new Date(date)); - return map; - } + for (Pair p : value) { + LinkedHashMap instance = new LinkedHashMap<>(); + instances.add(instance); + instance.put("id", p.first()); + instance.put("url", p.second()); + instance.put("isHref", p.second().startsWith("http")); + /* + * String id = p.first(); String url = p.second(); if(url != null && + * url.startsWith("http")){ + * buf.append(""); }else { url = + * null; } buf.append(id); if(url != null){ buf.append(""); } + * buf.append(", "); + */ + } + } + // out.println("" + buf.toString() + ""); + } + model.put("apps", apps); + } - protected void populateBase(HttpServletRequest request, Map model) { - model.put("time", new Date()); - model.put("basePath", "/"); - model.put("dashboardPath", dashboardPath.equals("/") ? "" : dashboardPath); - - populateHeader(model); - - populateNavbar(request, model); - } - - private void populateHeader(Map model) { - model.put("currentTime", StatusResource.getCurrentTimeAsString()); - model.put("upTime", StatusInfo.getUpTime()); - model.put("environment", ConfigurationManager.getDeploymentContext().getDeploymentEnvironment()); - model.put("datacenter", ConfigurationManager.getDeploymentContext().getDeploymentDatacenter()); - model.put("registry", PeerAwareInstanceRegistry.getInstance()); - model.put("isBelowRenewThresold", PeerAwareInstanceRegistry.getInstance().isBelowRenewThresold() == 1); - - DataCenterInfo info = ApplicationInfoManager.getInstance().getInfo().getDataCenterInfo(); - if(info.getName() == DataCenterInfo.Name.Amazon) { - AmazonInfo amazonInfo = (AmazonInfo) info; - model.put("amazonInfo", amazonInfo); - model.put("amiId", amazonInfo.get(AmazonInfo.MetaDataKey.amiId)); - model.put("availabilityZone", amazonInfo.get(AmazonInfo.MetaDataKey.availabilityZone)); - model.put("instanceId", amazonInfo.get(AmazonInfo.MetaDataKey.instanceId)); - } - } - - private void populateNavbar(HttpServletRequest request, Map model) { - Map replicas = new LinkedHashMap<>(); - List list = PeerAwareInstanceRegistry.getInstance().getReplicaNodes(); - for (PeerEurekaNode node : list) { - try { - URI uri = new URI(node.getServiceUrl()); - String href = node.getServiceUrl(); - replicas.put(uri.getHost(), href); - } catch(Exception e) { - //ignore? - } - } - model.put("replicas", replicas.entrySet()); - } - - private void populateApps(Map model) { - List sortedApplications = PeerAwareInstanceRegistry.getInstance().getSortedApplications(); - - ArrayList> apps = new ArrayList<>(); - - for(Application app : sortedApplications) { - LinkedHashMap appData = new LinkedHashMap<>(); - apps.add(appData); - - appData.put("name", app.getName()); - Map amiCounts = new HashMap<>(); - Map>> instancesByStatus = new HashMap<>(); - Map zoneCounts = new HashMap<>(); - - for(InstanceInfo info : app.getInstances()){ - String id = info.getId(); - String url = info.getStatusPageUrl(); - InstanceInfo.InstanceStatus status = info.getStatus(); - String ami = "n/a"; - String zone = ""; - if(info.getDataCenterInfo().getName() == DataCenterInfo.Name.Amazon){ - AmazonInfo dcInfo = (AmazonInfo)info.getDataCenterInfo(); - ami = dcInfo.get(AmazonInfo.MetaDataKey.amiId); - zone = dcInfo.get(AmazonInfo.MetaDataKey.availabilityZone); - } - - Integer count = amiCounts.get(ami); - if(count != null){ - amiCounts.put(ami, Integer.valueOf(count.intValue()+1)); - }else { - amiCounts.put(ami, Integer.valueOf(1)); - } - - count = zoneCounts.get(zone); - if(count != null){ - zoneCounts.put(zone, Integer.valueOf(count.intValue()+1)); - }else { - zoneCounts.put(zone, Integer.valueOf(1)); - } - List> list = instancesByStatus.get(status); - - if(list == null){ - list = new ArrayList<>(); - instancesByStatus.put(status, list); - } - list.add(new Pair<>(id, url)); - } - - appData.put("amiCounts", amiCounts.entrySet()); - appData.put("zoneCounts", zoneCounts.entrySet()); - - ArrayList> instanceInfos = new ArrayList<>(); - appData.put("instanceInfos", instanceInfos); - - for (Iterator>>> iter = - instancesByStatus.entrySet().iterator(); iter.hasNext();) { - Map.Entry>> entry = iter.next(); - List> value = entry.getValue(); - InstanceInfo.InstanceStatus status = entry.getKey(); - - LinkedHashMap instanceData = new LinkedHashMap<>(); - instanceInfos.add(instanceData); - - instanceData.put("status", entry.getKey()); - ArrayList> instances = new ArrayList<>(); - instanceData.put("instances", instances); - instanceData.put("isNotUp", status != InstanceInfo.InstanceStatus.UP); - - /*if(status != InstanceInfo.InstanceStatus.UP){ - buf.append(""); - } - buf.append("").append(status.name()).append(" (").append(value.size()).append(") - "); - if(status != InstanceInfo.InstanceStatus.UP){ - buf.append(""); - }*/ - - for(Pair p : value) { - LinkedHashMap instance = new LinkedHashMap<>(); - instances.add(instance); - instance.put("id", p.first()); - instance.put("url", p.second()); - instance.put("isHref", p.second().startsWith("http")); - /*String id = p.first(); - String url = p.second(); - if(url != null && url.startsWith("http")){ - buf.append(""); - }else { - url = null; - } - buf.append(id); - if(url != null){ - buf.append(""); - } - buf.append(", ");*/ - } - } - //out.println("" + buf.toString() + ""); - } - - model.put("apps", apps); - } - - private void populateInstanceInfo(Map model, StatusInfo statusInfo) { - InstanceInfo instanceInfo = statusInfo.getInstanceInfo(); - - Map instanceMap = new HashMap<>(); - instanceMap.put("ipAddr", instanceInfo.getIPAddr()); - instanceMap.put("status", instanceInfo.getStatus().toString()); - if(instanceInfo.getDataCenterInfo().getName() == DataCenterInfo.Name.Amazon) { - AmazonInfo info = (AmazonInfo) instanceInfo.getDataCenterInfo(); - instanceMap.put("availability-zone", info.get(AmazonInfo.MetaDataKey.availabilityZone)); - instanceMap.put("public-ipv4", info.get(AmazonInfo.MetaDataKey.publicIpv4)); - instanceMap.put("instance-id", info.get(AmazonInfo.MetaDataKey.instanceId)); - instanceMap.put("public-hostname", info.get(AmazonInfo.MetaDataKey.publicHostname)); - instanceMap.put("ami-id", info.get(AmazonInfo.MetaDataKey.amiId)); - instanceMap.put("instance-type", info.get(AmazonInfo.MetaDataKey.instanceType)); - } - - model.put("instanceInfo", instanceMap); - } + private void populateInstanceInfo(Map model, StatusInfo statusInfo) { + InstanceInfo instanceInfo = statusInfo.getInstanceInfo(); + Map instanceMap = new HashMap<>(); + instanceMap.put("ipAddr", instanceInfo.getIPAddr()); + instanceMap.put("status", instanceInfo.getStatus().toString()); + if (instanceInfo.getDataCenterInfo().getName() == DataCenterInfo.Name.Amazon) { + AmazonInfo info = (AmazonInfo) instanceInfo.getDataCenterInfo(); + instanceMap.put("availability-zone", + info.get(AmazonInfo.MetaDataKey.availabilityZone)); + instanceMap.put("public-ipv4", info.get(AmazonInfo.MetaDataKey.publicIpv4)); + instanceMap.put("instance-id", info.get(AmazonInfo.MetaDataKey.instanceId)); + instanceMap.put("public-hostname", + info.get(AmazonInfo.MetaDataKey.publicHostname)); + instanceMap.put("ami-id", info.get(AmazonInfo.MetaDataKey.amiId)); + instanceMap.put("instance-type", + info.get(AmazonInfo.MetaDataKey.instanceType)); + } + model.put("instanceInfo", instanceMap); + } } diff --git a/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/EurekaDashboardProperties.java b/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/EurekaDashboardProperties.java index b08834371..f9b983bb7 100644 --- a/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/EurekaDashboardProperties.java +++ b/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/EurekaDashboardProperties.java @@ -13,28 +13,29 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.cloud.netflix.eureka.server; -import org.springframework.boot.context.properties.ConfigurationProperties; +package org.springframework.cloud.netflix.eureka.server; import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; + /** - * Configuration properties for the Eureka dashboard (UI). - * @author Dave Syer + * Configuration properties for the Eureka dashboard (UI). * + * @author Dave Syer */ @ConfigurationProperties("eureka.dashboard") @Data public class EurekaDashboardProperties { - + /** * The path to the Eureka dashboard (relative to the servlet path). Defaults to "/". */ private String path = "/"; - + /** - * FLag to enable the Eureka dashboard. Default true. + * Flag to enable the Eureka dashboard. Default true. */ private boolean enabled = true; diff --git a/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/EurekaServerConfiguration.java b/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/EurekaServerConfiguration.java index 3aad138f2..86dde5de4 100644 --- a/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/EurekaServerConfiguration.java +++ b/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/EurekaServerConfiguration.java @@ -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.server; import javax.servlet.Filter; @@ -18,9 +34,7 @@ import com.google.common.collect.Lists; import com.sun.jersey.spi.container.servlet.ServletContainer; /** - * * @author Gunnar Hillert - * */ @Configuration @Import(EurekaServerInitializerConfiguration.class) @@ -56,4 +70,5 @@ public class EurekaServerConfiguration extends WebMvcConfigurerAdapter { bean.setOrder(Ordered.LOWEST_PRECEDENCE - 10); return bean; } + } diff --git a/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/EurekaServerInitializerConfiguration.java b/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/EurekaServerInitializerConfiguration.java index fd5493422..3b621f156 100644 --- a/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/EurekaServerInitializerConfiguration.java +++ b/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/EurekaServerInitializerConfiguration.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.cloud.netflix.eureka.server; import java.io.IOException; @@ -62,7 +63,6 @@ import com.netflix.eureka.PeerAwareInstanceRegistry; /** * @author Dave Syer - * */ @Configuration @EnableConfigurationProperties(EurekaServerConfigBean.class) @@ -113,30 +113,40 @@ public class EurekaServerInitializerConfiguration implements ServletContextAware .toString()); } } - catch (IOException e) { + catch (IOException ex) { // ignore } LoggingConfiguration.getInstance().configure(); - EurekaServerConfigurationManager.getInstance() - .setConfiguration(eurekaServerConfig); - XmlXStream.getInstance().setMarshallingStrategy( - new DataCenterAwareMarshallingStrategy(applicationContext)); - JsonXStream.getInstance().setMarshallingStrategy( - new DataCenterAwareMarshallingStrategy(applicationContext)); + EurekaServerConfigurationManager + .getInstance() + .setConfiguration( + EurekaServerInitializerConfiguration.this.eurekaServerConfig); + XmlXStream + .getInstance() + .setMarshallingStrategy( + new DataCenterAwareMarshallingStrategy( + EurekaServerInitializerConfiguration.this.applicationContext)); + JsonXStream + .getInstance() + .setMarshallingStrategy( + new DataCenterAwareMarshallingStrategy( + EurekaServerInitializerConfiguration.this.applicationContext)); // PeerAwareInstanceRegistry.getInstance(); - applicationContext + EurekaServerInitializerConfiguration.this.applicationContext .publishEvent(new EurekaRegistryAvailableEvent( - eurekaServerConfig)); + EurekaServerInitializerConfiguration.this.eurekaServerConfig)); } - }.contextInitialized(new ServletContextEvent(servletContext)); + }.contextInitialized(new ServletContextEvent( + EurekaServerInitializerConfiguration.this.servletContext)); logger.info("Started Eureka Server"); - running = true; - applicationContext.publishEvent(new EurekaServerStartedEvent( - eurekaServerConfig)); + EurekaServerInitializerConfiguration.this.running = true; + EurekaServerInitializerConfiguration.this.applicationContext + .publishEvent(new EurekaServerStartedEvent( + EurekaServerInitializerConfiguration.this.eurekaServerConfig)); } - catch (Exception e) { + catch (Exception ex) { // Help! - logger.error("Could not initialize Eureka servlet context", e); + logger.error("Could not initialize Eureka servlet context", ex); } } }).start(); @@ -144,12 +154,12 @@ public class EurekaServerInitializerConfiguration implements ServletContextAware @Override public void stop() { - running = false; + this.running = false; } @Override public boolean isRunning() { - return running; + return this.running; } @Override @@ -169,7 +179,7 @@ public class EurekaServerInitializerConfiguration implements ServletContextAware @Override public int getOrder() { - return order; + return this.order; } @Configuration @@ -189,8 +199,8 @@ public class EurekaServerInitializerConfiguration implements ServletContextAware @Override public void onApplicationEvent(EurekaRegistryAvailableEvent event) { - if (instance == null) { - instance = PeerAwareInstanceRegistry.getInstance(); + if (this.instance == null) { + this.instance = PeerAwareInstanceRegistry.getInstance(); safeInit(); replaceInstance(getProxyForInstance()); expectRegistrations(1); @@ -198,9 +208,10 @@ public class EurekaServerInitializerConfiguration implements ServletContextAware } private void safeInit() { - Method method = ReflectionUtils.findMethod(InstanceRegistry.class, "postInit"); + Method method = ReflectionUtils + .findMethod(InstanceRegistry.class, "postInit"); ReflectionUtils.makeAccessible(method); - ReflectionUtils.invokeMethod(method, instance); + ReflectionUtils.invokeMethod(method, this.instance); } private void replaceInstance(Object proxy) { @@ -214,14 +225,14 @@ public class EurekaServerInitializerConfiguration implements ServletContextAware modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL); ReflectionUtils.setField(field, null, proxy); } - catch (Exception e) { - throw new IllegalStateException("Cannot modify instance registry", e); + catch (Exception ex) { + throw new IllegalStateException("Cannot modify instance registry", ex); } } private Object getProxyForInstance() { // Wrap the instance registry... - ProxyFactory factory = new ProxyFactory(instance); + ProxyFactory factory = new ProxyFactory(this.instance); // ...with the LeaseManagerMessageBroker factory.addAdvice(new PiggybackMethodInterceptor(leaseManagerMessageBroker(), LeaseManagerLite.class)); @@ -243,14 +254,14 @@ public class EurekaServerInitializerConfiguration implements ServletContextAware try { // Awful ugly hack to work around lack of DI in eureka field.setAccessible(true); - int value = (int) ReflectionUtils.getField(field, instance); + int value = (int) ReflectionUtils.getField(field, this.instance); if (value == 0 && count > 0) { - ReflectionUtils.setField(field, instance, count); + ReflectionUtils.setField(field, this.instance, count); } } - catch (Exception e) { + catch (Exception ex) { throw new IllegalStateException( - "Cannot modify instance registry expected renews", e); + "Cannot modify instance registry expected renews", ex); } } @@ -262,9 +273,6 @@ public class EurekaServerInitializerConfiguration implements ServletContextAware * hasn't sent any renewals recently. This happens for a standalone server. It * seems like a bad default, so we set it to the smallest non-zero value we can, * so that any instances that subsequently register can bump up the threshold. - * - * @author Dave Syer - * */ private class TrafficOpener implements MethodInterceptor { @@ -278,6 +286,7 @@ public class EurekaServerInitializerConfiguration implements ServletContextAware } return invocation.proceed(); } + } } diff --git a/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/advice/LeaseManagerLite.java b/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/advice/LeaseManagerLite.java index e17356e42..0c6ec1029 100644 --- a/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/advice/LeaseManagerLite.java +++ b/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/advice/LeaseManagerLite.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.cloud.netflix.eureka.server.advice; import com.netflix.appinfo.InstanceInfo; @@ -20,10 +21,9 @@ import com.netflix.eureka.lease.LeaseManager; /** * @author Dave Syer - * */ public interface LeaseManagerLite extends LeaseManager { - + void register(InstanceInfo info, boolean isReplication); } diff --git a/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/advice/PiggybackMethodInterceptor.java b/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/advice/PiggybackMethodInterceptor.java index 46064a67f..745485a56 100644 --- a/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/advice/PiggybackMethodInterceptor.java +++ b/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/advice/PiggybackMethodInterceptor.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.cloud.netflix.eureka.server.advice; import java.lang.reflect.Method; @@ -23,11 +24,11 @@ import org.springframework.util.ReflectionUtils; /** * @author Dave Syer - * */ public class PiggybackMethodInterceptor implements MethodInterceptor { private Object delegate; + private Class[] types; public PiggybackMethodInterceptor(Object delegate, Class... types) { @@ -43,10 +44,10 @@ public class PiggybackMethodInterceptor implements MethodInterceptor { } private void invokeAfter(Method method, Object[] arguments) throws Exception { - for (Class type : types) { + for (Class type : this.types) { Method target = getTarget(type, method); if (target != null) { - target.invoke(delegate, arguments); + target.invoke(this.delegate, arguments); return; } } diff --git a/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/event/EurekaInstanceCanceledEvent.java b/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/event/EurekaInstanceCanceledEvent.java index e3661a772..bab497510 100644 --- a/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/event/EurekaInstanceCanceledEvent.java +++ b/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/event/EurekaInstanceCanceledEvent.java @@ -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.server.event; import lombok.Data; @@ -9,17 +25,22 @@ import org.springframework.context.ApplicationEvent; * @author Spencer Gibb */ @Data -@EqualsAndHashCode(callSuper=false) +@EqualsAndHashCode(callSuper = false) @SuppressWarnings("serial") public class EurekaInstanceCanceledEvent extends ApplicationEvent { - private String appName; - private String serverId; - boolean replication; - public EurekaInstanceCanceledEvent(Object source, String appName, String serverId, boolean replication) { - super(source); - this.appName = appName; - this.serverId = serverId; - this.replication = replication; - } + private String appName; + + private String serverId; + + boolean replication; + + public EurekaInstanceCanceledEvent(Object source, String appName, String serverId, + boolean replication) { + super(source); + this.appName = appName; + this.serverId = serverId; + this.replication = replication; + } + } diff --git a/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/event/EurekaInstanceRegisteredEvent.java b/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/event/EurekaInstanceRegisteredEvent.java index 455d34e56..013f3ba42 100644 --- a/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/event/EurekaInstanceRegisteredEvent.java +++ b/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/event/EurekaInstanceRegisteredEvent.java @@ -1,27 +1,48 @@ -package org.springframework.cloud.netflix.eureka.server.event; +/* + * 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.appinfo.InstanceInfo; +package org.springframework.cloud.netflix.eureka.server.event; import lombok.Data; import lombok.EqualsAndHashCode; import org.springframework.context.ApplicationEvent; +import com.netflix.appinfo.InstanceInfo; + /** * @author Spencer Gibb */ @Data -@EqualsAndHashCode(callSuper=false) +@EqualsAndHashCode(callSuper = false) @SuppressWarnings("serial") public class EurekaInstanceRegisteredEvent extends ApplicationEvent { - private InstanceInfo instanceInfo; - private int leaseDuration; - boolean replication; - public EurekaInstanceRegisteredEvent(Object source, InstanceInfo instanceInfo, int leaseDuration, boolean replication) { - super(source); - this.instanceInfo = instanceInfo; - this.leaseDuration = leaseDuration; - this.replication = replication; - } + private InstanceInfo instanceInfo; + + private int leaseDuration; + + boolean replication; + + public EurekaInstanceRegisteredEvent(Object source, InstanceInfo instanceInfo, + int leaseDuration, boolean replication) { + super(source); + this.instanceInfo = instanceInfo; + this.leaseDuration = leaseDuration; + this.replication = replication; + } + } diff --git a/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/event/EurekaInstanceRenewedEvent.java b/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/event/EurekaInstanceRenewedEvent.java index 1573314f7..e80dfea88 100644 --- a/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/event/EurekaInstanceRenewedEvent.java +++ b/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/event/EurekaInstanceRenewedEvent.java @@ -1,29 +1,51 @@ -package org.springframework.cloud.netflix.eureka.server.event; +/* + * 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.appinfo.InstanceInfo; +package org.springframework.cloud.netflix.eureka.server.event; import lombok.Data; import lombok.EqualsAndHashCode; import org.springframework.context.ApplicationEvent; +import com.netflix.appinfo.InstanceInfo; + /** * @author Spencer Gibb */ @Data -@EqualsAndHashCode(callSuper=false) +@EqualsAndHashCode(callSuper = false) @SuppressWarnings("serial") public class EurekaInstanceRenewedEvent extends ApplicationEvent { - private String appName; - private String serverId; - private InstanceInfo instanceInfo; - boolean replication; - public EurekaInstanceRenewedEvent(Object source, String appName, String serverId, InstanceInfo instanceInfo, boolean replication) { - super(source); - this.appName = appName; - this.serverId = serverId; - this.instanceInfo = instanceInfo; - this.replication = replication; - } + private String appName; + + private String serverId; + + private InstanceInfo instanceInfo; + + boolean replication; + + public EurekaInstanceRenewedEvent(Object source, String appName, String serverId, + InstanceInfo instanceInfo, boolean replication) { + super(source); + this.appName = appName; + this.serverId = serverId; + this.instanceInfo = instanceInfo; + this.replication = replication; + } + } diff --git a/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/event/EurekaRegistryAvailableEvent.java b/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/event/EurekaRegistryAvailableEvent.java index 9b174ef45..588dca22c 100644 --- a/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/event/EurekaRegistryAvailableEvent.java +++ b/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/event/EurekaRegistryAvailableEvent.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.cloud.netflix.eureka.server.event; import org.springframework.context.ApplicationEvent; @@ -21,7 +22,6 @@ import com.netflix.eureka.EurekaServerConfig; /** * @author Dave Syer - * */ @SuppressWarnings("serial") public class EurekaRegistryAvailableEvent extends ApplicationEvent { diff --git a/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/event/EurekaServerStartedEvent.java b/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/event/EurekaServerStartedEvent.java index edd8feea5..4b9f7cedc 100644 --- a/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/event/EurekaServerStartedEvent.java +++ b/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/event/EurekaServerStartedEvent.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.cloud.netflix.eureka.server.event; import org.springframework.context.ApplicationEvent; @@ -21,7 +22,6 @@ import com.netflix.eureka.EurekaServerConfig; /** * @author Dave Syer - * */ @SuppressWarnings("serial") public class EurekaServerStartedEvent extends ApplicationEvent { diff --git a/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/event/LeaseManagerMessageBroker.java b/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/event/LeaseManagerMessageBroker.java index 20d80bb8c..6867a0e9f 100644 --- a/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/event/LeaseManagerMessageBroker.java +++ b/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/event/LeaseManagerMessageBroker.java @@ -1,6 +1,20 @@ -package org.springframework.cloud.netflix.eureka.server.event; +/* + * 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.google.common.collect.Iterables.tryFind; +package org.springframework.cloud.netflix.eureka.server.event; import java.util.List; @@ -19,58 +33,70 @@ import com.netflix.discovery.shared.Application; import com.netflix.eureka.PeerAwareInstanceRegistry; import com.netflix.eureka.lease.Lease; +import static com.google.common.collect.Iterables.tryFind; + /** * @author Spencer Gibb */ public class LeaseManagerMessageBroker implements LeaseManagerLite { - private static final Logger logger = LoggerFactory.getLogger(LeaseManagerMessageBroker.class); + private static final Logger logger = LoggerFactory + .getLogger(LeaseManagerMessageBroker.class); - @Autowired - private ApplicationContext ctxt; - - @Override - public void register(InstanceInfo info, boolean isReplication) { - register(info, Lease.DEFAULT_DURATION_IN_SECS, isReplication); - } + @Autowired + private ApplicationContext ctxt; - @Override - public void register(InstanceInfo info, int leaseDuration, boolean isReplication) { - logger.debug("register {}, vip {}, leaseDuration {}, isReplication {}", - info.getAppName(), info.getVIPAddress(), leaseDuration, isReplication); - //TODO: what to publish from info (whole object?) - ctxt.publishEvent(new EurekaInstanceRegisteredEvent(this, info, leaseDuration, isReplication)); - } + @Override + public void register(InstanceInfo info, boolean isReplication) { + register(info, Lease.DEFAULT_DURATION_IN_SECS, isReplication); + } - @Override - public boolean cancel(String appName, String serverId, boolean isReplication) { - logger.debug("cancel {}, serverId {}, isReplication {}", appName, serverId, isReplication); - ctxt.publishEvent(new EurekaInstanceCanceledEvent(this, appName, serverId, isReplication)); - return false; - } + @Override + public void register(InstanceInfo info, int leaseDuration, boolean isReplication) { + logger.debug("register {}, vip {}, leaseDuration {}, isReplication {}", + info.getAppName(), info.getVIPAddress(), leaseDuration, isReplication); + // TODO: what to publish from info (whole object?) + this.ctxt.publishEvent(new EurekaInstanceRegisteredEvent(this, info, + leaseDuration, isReplication)); + } - @Override - public boolean renew(final String appName, final String serverId, boolean isReplication) { - logger.debug("renew {}, serverId {}, isReplication {}", appName, serverId, isReplication); - List applications = PeerAwareInstanceRegistry.getInstance().getSortedApplications(); - Optional app = tryFind(applications, new Predicate() { - @Override - public boolean apply(@Nullable Application input) { - return input.getName().equals(appName); - } - }); + @Override + public boolean cancel(String appName, String serverId, boolean isReplication) { + logger.debug("cancel {}, serverId {}, isReplication {}", appName, serverId, + isReplication); + this.ctxt.publishEvent(new EurekaInstanceCanceledEvent(this, appName, serverId, + isReplication)); + return false; + } - if (app.isPresent()) { - Optional info = tryFind(app.get().getInstances(), new Predicate() { - @Override - public boolean apply(@Nullable InstanceInfo input) { - return input.getHostName().equals(serverId); - } - }); - ctxt.publishEvent(new EurekaInstanceRenewedEvent(this, appName, serverId, info.orNull(), isReplication)); - } - return false; - } + @Override + public boolean renew(final String appName, final String serverId, + boolean isReplication) { + logger.debug("renew {}, serverId {}, isReplication {}", appName, serverId, + isReplication); + List applications = PeerAwareInstanceRegistry.getInstance() + .getSortedApplications(); + Optional app = tryFind(applications, new Predicate() { + @Override + public boolean apply(@Nullable Application input) { + return input.getName().equals(appName); + } + }); + if (app.isPresent()) { + Optional info = tryFind(app.get().getInstances(), + new Predicate() { + @Override + public boolean apply(@Nullable InstanceInfo input) { + return input.getHostName().equals(serverId); + } + }); + this.ctxt.publishEvent(new EurekaInstanceRenewedEvent(this, appName, + serverId, info.orNull(), isReplication)); + } + return false; + } + + @Override + public void evict() { + } - @Override - public void evict() {} } diff --git a/spring-cloud-netflix-eureka-server/src/test/java/org/springframework/cloud/netflix/eureka/server/ApplicationContextTests.java b/spring-cloud-netflix-eureka-server/src/test/java/org/springframework/cloud/netflix/eureka/server/ApplicationContextTests.java index eebee50b1..77c761f99 100644 --- a/spring-cloud-netflix-eureka-server/src/test/java/org/springframework/cloud/netflix/eureka/server/ApplicationContextTests.java +++ b/spring-cloud-netflix-eureka-server/src/test/java/org/springframework/cloud/netflix/eureka/server/ApplicationContextTests.java @@ -1,7 +1,20 @@ -package org.springframework.cloud.netflix.eureka.server; +/* + * 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.assertTrue; +package org.springframework.cloud.netflix.eureka.server; import java.util.Map; @@ -20,6 +33,9 @@ import org.springframework.http.ResponseEntity; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.web.WebAppConfiguration; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = Application.class) @WebAppConfiguration @@ -30,49 +46,41 @@ public class ApplicationContextTests { @Value("${local.server.port}") private int port = 0; - @Configuration - @EnableAutoConfiguration - @EnableEurekaServer - protected static class Application { - public static void main(String[] args) { - new SpringApplicationBuilder(Application.class).properties( - "spring.application.name=eureka", "server.contextPath=/context").run( - args); - } - } - @Test public void catalogLoads() { @SuppressWarnings("rawtypes") ResponseEntity entity = new TestRestTemplate().getForEntity( - "http://localhost:" + port + "/context/eureka/apps", Map.class); + "http://localhost:" + this.port + "/context/eureka/apps", Map.class); assertEquals(HttpStatus.OK, entity.getStatusCode()); } @Test public void dashboardLoads() { ResponseEntity entity = new TestRestTemplate().getForEntity( - "http://localhost:" + port + "/context/", String.class); + "http://localhost:" + this.port + "/context/", String.class); assertEquals(HttpStatus.OK, entity.getStatusCode()); String body = entity.getBody(); // System.err.println(body); assertTrue(body.contains("eureka/js")); assertTrue(body.contains("eureka/css")); // The "DS Replicas" - assertTrue(body.contains("localhost")); + assertTrue(body + .contains("localhost")); } @Test public void cssAvailable() { ResponseEntity entity = new TestRestTemplate().getForEntity( - "http://localhost:" + port + "/context/eureka/css/wro.css", String.class); + "http://localhost:" + this.port + "/context/eureka/css/wro.css", + String.class); assertEquals(HttpStatus.OK, entity.getStatusCode()); } @Test public void jsAvailable() { ResponseEntity entity = new TestRestTemplate().getForEntity( - "http://localhost:" + port + "/context/eureka/js/wro.js", String.class); + "http://localhost:" + this.port + "/context/eureka/js/wro.js", + String.class); assertEquals(HttpStatus.OK, entity.getStatusCode()); } @@ -80,8 +88,20 @@ public class ApplicationContextTests { public void adminLoads() { @SuppressWarnings("rawtypes") ResponseEntity entity = new TestRestTemplate().getForEntity( - "http://localhost:" + port + "/context/env", Map.class); + "http://localhost:" + this.port + "/context/env", Map.class); assertEquals(HttpStatus.OK, entity.getStatusCode()); } + @Configuration + @EnableAutoConfiguration + @EnableEurekaServer + protected static class Application { + + public static void main(String[] args) { + new SpringApplicationBuilder(Application.class).properties( + "spring.application.name=eureka", "server.contextPath=/context").run( + args); + } + + } } diff --git a/spring-cloud-netflix-eureka-server/src/test/java/org/springframework/cloud/netflix/eureka/server/ApplicationDashboardDisabledTests.java b/spring-cloud-netflix-eureka-server/src/test/java/org/springframework/cloud/netflix/eureka/server/ApplicationDashboardDisabledTests.java index 4af5fe4e4..41b13b640 100644 --- a/spring-cloud-netflix-eureka-server/src/test/java/org/springframework/cloud/netflix/eureka/server/ApplicationDashboardDisabledTests.java +++ b/spring-cloud-netflix-eureka-server/src/test/java/org/springframework/cloud/netflix/eureka/server/ApplicationDashboardDisabledTests.java @@ -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.eureka.server; +import java.util.Map; + import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Value; @@ -12,8 +30,6 @@ import org.springframework.http.ResponseEntity; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.web.WebAppConfiguration; -import java.util.Map; - import static org.junit.Assert.assertEquals; @RunWith(SpringJUnit4ClassRunner.class) @@ -30,14 +46,14 @@ public class ApplicationDashboardDisabledTests { public void catalogLoads() { @SuppressWarnings("rawtypes") ResponseEntity entity = new TestRestTemplate().getForEntity( - "http://localhost:" + port + "/eureka/apps", Map.class); + "http://localhost:" + this.port + "/eureka/apps", Map.class); assertEquals(HttpStatus.OK, entity.getStatusCode()); } @Test public void dashboardLoads() { ResponseEntity entity = new TestRestTemplate().getForEntity( - "http://localhost:" + port + "/", String.class); + "http://localhost:" + this.port + "/", String.class); assertEquals(HttpStatus.NOT_FOUND, entity.getStatusCode()); } diff --git a/spring-cloud-netflix-eureka-server/src/test/java/org/springframework/cloud/netflix/eureka/server/ApplicationDashboardPathTests.java b/spring-cloud-netflix-eureka-server/src/test/java/org/springframework/cloud/netflix/eureka/server/ApplicationDashboardPathTests.java index b4020e12a..a902c6efc 100644 --- a/spring-cloud-netflix-eureka-server/src/test/java/org/springframework/cloud/netflix/eureka/server/ApplicationDashboardPathTests.java +++ b/spring-cloud-netflix-eureka-server/src/test/java/org/springframework/cloud/netflix/eureka/server/ApplicationDashboardPathTests.java @@ -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.eureka.server; +import java.util.Map; + import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Value; @@ -12,8 +30,6 @@ import org.springframework.http.ResponseEntity; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.web.WebAppConfiguration; -import java.util.Map; - import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; @@ -31,41 +47,39 @@ public class ApplicationDashboardPathTests { public void catalogLoads() { @SuppressWarnings("rawtypes") ResponseEntity entity = new TestRestTemplate().getForEntity( - "http://localhost:" + port + "/eureka/apps", Map.class); + "http://localhost:" + this.port + "/eureka/apps", Map.class); assertEquals(HttpStatus.OK, entity.getStatusCode()); } @Test public void dashboardLoads() { ResponseEntity entity = new TestRestTemplate().getForEntity( - "http://localhost:" + port + "/dashboard", String.class); + "http://localhost:" + this.port + "/dashboard", String.class); assertEquals(HttpStatus.OK, entity.getStatusCode()); String body = entity.getBody(); // System.err.println(body); assertTrue(body.contains("eureka/js")); assertTrue(body.contains("eureka/css")); // The "DS Replicas" - assertTrue( - body.contains("localhost")); + assertTrue(body + .contains("localhost")); // The Home - assertTrue( - body.contains("Home")); + assertTrue(body.contains("Home")); // The Lastn - assertTrue( - body.contains("Last")); + assertTrue(body.contains("Last")); } @Test public void cssAvailable() { ResponseEntity entity = new TestRestTemplate().getForEntity( - "http://localhost:" + port + "/eureka/css/wro.css", String.class); + "http://localhost:" + this.port + "/eureka/css/wro.css", String.class); assertEquals(HttpStatus.OK, entity.getStatusCode()); } @Test public void jsAvailable() { ResponseEntity entity = new TestRestTemplate().getForEntity( - "http://localhost:" + port + "/eureka/js/wro.js", String.class); + "http://localhost:" + this.port + "/eureka/js/wro.js", String.class); assertEquals(HttpStatus.OK, entity.getStatusCode()); } diff --git a/spring-cloud-netflix-eureka-server/src/test/java/org/springframework/cloud/netflix/eureka/server/ApplicationServletPathTests.java b/spring-cloud-netflix-eureka-server/src/test/java/org/springframework/cloud/netflix/eureka/server/ApplicationServletPathTests.java index fa28dd602..b092b31cb 100644 --- a/spring-cloud-netflix-eureka-server/src/test/java/org/springframework/cloud/netflix/eureka/server/ApplicationServletPathTests.java +++ b/spring-cloud-netflix-eureka-server/src/test/java/org/springframework/cloud/netflix/eureka/server/ApplicationServletPathTests.java @@ -1,7 +1,20 @@ -package org.springframework.cloud.netflix.eureka.server; +/* + * 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.assertTrue; +package org.springframework.cloud.netflix.eureka.server; import java.util.Map; @@ -20,6 +33,9 @@ import org.springframework.http.ResponseEntity; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.web.WebAppConfiguration; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = Application.class) @WebAppConfiguration @@ -45,34 +61,37 @@ public class ApplicationServletPathTests { public void catalogLoads() { @SuppressWarnings("rawtypes") ResponseEntity entity = new TestRestTemplate().getForEntity( - "http://localhost:" + port + "/eureka/apps", Map.class); + "http://localhost:" + this.port + "/eureka/apps", Map.class); assertEquals(HttpStatus.OK, entity.getStatusCode()); } @Test public void dashboardLoads() { ResponseEntity entity = new TestRestTemplate().getForEntity( - "http://localhost:" + port + "/servlet/", String.class); + "http://localhost:" + this.port + "/servlet/", String.class); assertEquals(HttpStatus.OK, entity.getStatusCode()); String body = entity.getBody(); // System.err.println(body); assertTrue(body.contains("eureka/js")); assertTrue(body.contains("eureka/css")); // The "DS Replicas" - assertTrue(body.contains("localhost")); + assertTrue(body + .contains("localhost")); } @Test public void cssAvailable() { ResponseEntity entity = new TestRestTemplate().getForEntity( - "http://localhost:" + port + "/servlet/eureka/css/wro.css", String.class); + "http://localhost:" + this.port + "/servlet/eureka/css/wro.css", + String.class); assertEquals(HttpStatus.OK, entity.getStatusCode()); } @Test public void jsAvailable() { ResponseEntity entity = new TestRestTemplate().getForEntity( - "http://localhost:" + port + "/servlet/eureka/js/wro.js", String.class); + "http://localhost:" + this.port + "/servlet/eureka/js/wro.js", + String.class); assertEquals(HttpStatus.OK, entity.getStatusCode()); } @@ -80,7 +99,7 @@ public class ApplicationServletPathTests { public void adminLoads() { @SuppressWarnings("rawtypes") ResponseEntity entity = new TestRestTemplate().getForEntity( - "http://localhost:" + port + "/servlet/env", Map.class); + "http://localhost:" + this.port + "/servlet/env", Map.class); assertEquals(HttpStatus.OK, entity.getStatusCode()); } diff --git a/spring-cloud-netflix-eureka-server/src/test/java/org/springframework/cloud/netflix/eureka/server/ApplicationTests.java b/spring-cloud-netflix-eureka-server/src/test/java/org/springframework/cloud/netflix/eureka/server/ApplicationTests.java index fda544730..062d87519 100644 --- a/spring-cloud-netflix-eureka-server/src/test/java/org/springframework/cloud/netflix/eureka/server/ApplicationTests.java +++ b/spring-cloud-netflix-eureka-server/src/test/java/org/springframework/cloud/netflix/eureka/server/ApplicationTests.java @@ -1,8 +1,20 @@ -package org.springframework.cloud.netflix.eureka.server; +/* + * 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.assertFalse; -import static org.junit.Assert.assertNotNull; +package org.springframework.cloud.netflix.eureka.server; import java.util.Map; @@ -21,6 +33,10 @@ import org.springframework.http.ResponseEntity; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.web.WebAppConfiguration; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; + @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = Application.class) @WebAppConfiguration @@ -44,7 +60,7 @@ public class ApplicationTests { public void catalogLoads() { @SuppressWarnings("rawtypes") ResponseEntity entity = new TestRestTemplate().getForEntity( - "http://localhost:" + port + "/eureka/apps", Map.class); + "http://localhost:" + this.port + "/eureka/apps", Map.class); assertEquals(HttpStatus.OK, entity.getStatusCode()); } @@ -52,21 +68,19 @@ public class ApplicationTests { public void adminLoads() { @SuppressWarnings("rawtypes") ResponseEntity entity = new TestRestTemplate().getForEntity( - "http://localhost:" + port + "/env", Map.class); + "http://localhost:" + this.port + "/env", Map.class); assertEquals(HttpStatus.OK, entity.getStatusCode()); } @Test public void noDoubleSlashes() { - String basePath = "http://localhost:" + port + "/"; - ResponseEntity entity = new TestRestTemplate().getForEntity( - basePath, String.class); + String basePath = "http://localhost:" + this.port + "/"; + ResponseEntity entity = new TestRestTemplate().getForEntity(basePath, + String.class); assertEquals(HttpStatus.OK, entity.getStatusCode()); String body = entity.getBody(); assertNotNull(body); - assertFalse("basePath contains double slashes", body.contains(basePath+"/")); - + assertFalse("basePath contains double slashes", body.contains(basePath + "/")); } - } diff --git a/spring-cloud-netflix-eureka-server/src/test/java/org/springframework/cloud/netflix/eureka/server/Log4JLoggingSystemTests.java b/spring-cloud-netflix-eureka-server/src/test/java/org/springframework/cloud/netflix/eureka/server/Log4JLoggingSystemTests.java index 25c8c92c7..80860c4f0 100644 --- a/spring-cloud-netflix-eureka-server/src/test/java/org/springframework/cloud/netflix/eureka/server/Log4JLoggingSystemTests.java +++ b/spring-cloud-netflix-eureka-server/src/test/java/org/springframework/cloud/netflix/eureka/server/Log4JLoggingSystemTests.java @@ -16,9 +16,6 @@ package org.springframework.cloud.netflix.eureka.server; -import static org.hamcrest.Matchers.equalTo; -import static org.junit.Assert.assertThat; - import java.io.IOException; import org.apache.log4j.Logger; @@ -34,6 +31,9 @@ import org.springframework.util.StringUtils; import com.netflix.blitz4j.LoggingConfiguration; +import static org.hamcrest.Matchers.equalTo; +import static org.junit.Assert.assertThat; + /** * Tests for {@link Log4JLoggingSystem}. * @@ -51,8 +51,9 @@ public class Log4JLoggingSystemTests { @Before public void setup() throws IOException { - System.setProperty("log4j.configuration", new ClassPathResource("log4j.properties", Log4JLoggingSystem.class).getURL().toString()); - logger = Logger.getLogger(getClass()); + System.setProperty("log4j.configuration", new ClassPathResource( + "log4j.properties", Log4JLoggingSystem.class).getURL().toString()); + this.logger = Logger.getLogger(getClass()); LoggingConfiguration.getInstance().configure(); } diff --git a/spring-cloud-netflix-hystrix-amqp/pom.xml b/spring-cloud-netflix-hystrix-amqp/pom.xml index d496c6394..d6c7bd89e 100644 --- a/spring-cloud-netflix-hystrix-amqp/pom.xml +++ b/spring-cloud-netflix-hystrix-amqp/pom.xml @@ -2,95 +2,93 @@ 4.0.0 - - spring-cloud-netflix-hystrix-amqp - jar - - Spring Cloud Netflix Hystrix AMQP - Spring Cloud Netflix Hystrix AMQP - org.springframework.cloud spring-cloud-netflix 1.0.0.BUILD-SNAPSHOT .. - + spring-cloud-netflix-hystrix-amqp + jar + Spring Cloud Netflix Hystrix AMQP + Spring Cloud Netflix Hystrix AMQP + + ${basedir}/.. + - - org.springframework.cloud - spring-cloud-commons - - - org.springframework.cloud - spring-cloud-netflix-core - - - org.springframework.boot - spring-boot-starter-amqp - - - org.springframework.boot - spring-boot-starter-integration - - - org.springframework.cloud - spring-cloud-netflix-core - - - org.springframework.integration - spring-integration-amqp - true - - - org.springframework.integration - spring-integration-java-dsl - true - - - com.fasterxml.jackson.core - jackson-databind - - - com.netflix.hystrix - hystrix-core - - - com.netflix.hystrix - hystrix-metrics-event-stream - test - - - com.netflix.hystrix - hystrix-javanica - test - - - com.netflix.eureka - eureka-client - test - - - org.projectlombok - lombok + + org.springframework.cloud + spring-cloud-commons + + + org.springframework.cloud + spring-cloud-netflix-core + + + org.springframework.boot + spring-boot-starter-amqp + + + org.springframework.boot + spring-boot-starter-integration + + + org.springframework.cloud + spring-cloud-netflix-core + + + org.springframework.integration + spring-integration-amqp + true + + + org.springframework.integration + spring-integration-java-dsl + true + + + com.fasterxml.jackson.core + jackson-databind + + + com.netflix.hystrix + hystrix-core + + + com.netflix.hystrix + hystrix-metrics-event-stream + test + + + com.netflix.hystrix + hystrix-javanica + test + + + com.netflix.eureka + eureka-client + test + + + org.projectlombok + lombok compile true - - - org.springframework.boot - spring-boot-starter-test - test - - - org.springframework.boot - spring-boot-starter-web - test - - - org.springframework.boot - spring-boot-starter-actuator - test - + + + org.springframework.boot + spring-boot-starter-test + test + + + org.springframework.boot + spring-boot-starter-web + test + + + org.springframework.boot + spring-boot-starter-actuator + test + - diff --git a/spring-cloud-netflix-hystrix-amqp/src/main/java/org/springframework/netflix/hystrix/amqp/HystrixStreamAmqpProperties.java b/spring-cloud-netflix-hystrix-amqp/src/main/java/org/springframework/netflix/hystrix/amqp/HystrixStreamAmqpProperties.java index 9c06b5c5e..f034108ef 100644 --- a/spring-cloud-netflix-hystrix-amqp/src/main/java/org/springframework/netflix/hystrix/amqp/HystrixStreamAmqpProperties.java +++ b/spring-cloud-netflix-hystrix-amqp/src/main/java/org/springframework/netflix/hystrix/amqp/HystrixStreamAmqpProperties.java @@ -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.netflix.hystrix.amqp; import lombok.Data; + import org.springframework.boot.context.properties.ConfigurationProperties; /** @@ -9,7 +26,11 @@ import org.springframework.boot.context.properties.ConfigurationProperties; @ConfigurationProperties("hystrix.stream.amqp") @Data public class HystrixStreamAmqpProperties { + private boolean enabled = true; + private boolean prefixMetricName = true; + private boolean sendId = true; + } diff --git a/spring-cloud-netflix-hystrix-amqp/src/main/java/org/springframework/netflix/hystrix/amqp/HystrixStreamAutoConfiguration.java b/spring-cloud-netflix-hystrix-amqp/src/main/java/org/springframework/netflix/hystrix/amqp/HystrixStreamAutoConfiguration.java index d371478b8..72fcf4f96 100644 --- a/spring-cloud-netflix-hystrix-amqp/src/main/java/org/springframework/netflix/hystrix/amqp/HystrixStreamAutoConfiguration.java +++ b/spring-cloud-netflix-hystrix-amqp/src/main/java/org/springframework/netflix/hystrix/amqp/HystrixStreamAutoConfiguration.java @@ -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.netflix.hystrix.amqp; import javax.annotation.PostConstruct; @@ -39,11 +55,10 @@ public class HystrixStreamAutoConfiguration { @Autowired(required = false) private ObjectMapper objectMapper; - @PostConstruct public void init() { Jackson2JsonMessageConverter converter = messageConverter(); - amqpTemplate.setMessageConverter(converter); + this.amqpTemplate.setMessageConverter(converter); } @Bean @@ -84,8 +99,8 @@ public class HystrixStreamAutoConfiguration { private Jackson2JsonMessageConverter messageConverter() { Jackson2JsonMessageConverter converter = new Jackson2JsonMessageConverter(); - if (objectMapper != null) { - converter.setJsonObjectMapper(objectMapper); + if (this.objectMapper != null) { + converter.setJsonObjectMapper(this.objectMapper); } return converter; } diff --git a/spring-cloud-netflix-hystrix-amqp/src/main/java/org/springframework/netflix/hystrix/amqp/HystrixStreamChannel.java b/spring-cloud-netflix-hystrix-amqp/src/main/java/org/springframework/netflix/hystrix/amqp/HystrixStreamChannel.java index 95214a613..30d297d83 100644 --- a/spring-cloud-netflix-hystrix-amqp/src/main/java/org/springframework/netflix/hystrix/amqp/HystrixStreamChannel.java +++ b/spring-cloud-netflix-hystrix-amqp/src/main/java/org/springframework/netflix/hystrix/amqp/HystrixStreamChannel.java @@ -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.netflix.hystrix.amqp; import org.springframework.integration.annotation.Gateway; @@ -9,6 +25,7 @@ import org.springframework.integration.annotation.MessagingGateway; @MessagingGateway public interface HystrixStreamChannel { - @Gateway(requestChannel = "hystrixStream") - public void send(String s); + @Gateway(requestChannel = "hystrixStream") + public void send(String s); + } diff --git a/spring-cloud-netflix-hystrix-amqp/src/main/java/org/springframework/netflix/hystrix/amqp/HystrixStreamTask.java b/spring-cloud-netflix-hystrix-amqp/src/main/java/org/springframework/netflix/hystrix/amqp/HystrixStreamTask.java index 83d426848..2ca2f38c1 100644 --- a/spring-cloud-netflix-hystrix-amqp/src/main/java/org/springframework/netflix/hystrix/amqp/HystrixStreamTask.java +++ b/spring-cloud-netflix-hystrix-amqp/src/main/java/org/springframework/netflix/hystrix/amqp/HystrixStreamTask.java @@ -1,8 +1,29 @@ +/* + * 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.netflix.hystrix.amqp; -import com.netflix.hystrix.*; -import com.netflix.hystrix.util.HystrixRollingNumberEvent; +import java.io.IOException; +import java.io.StringWriter; +import java.util.ArrayList; +import java.util.Collection; +import java.util.concurrent.LinkedBlockingQueue; + import lombok.extern.slf4j.Slf4j; + import org.codehaus.jackson.JsonFactory; import org.codehaus.jackson.JsonGenerator; import org.springframework.beans.BeansException; @@ -13,242 +34,327 @@ import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.scheduling.annotation.Scheduled; -import java.io.IOException; -import java.io.StringWriter; -import java.util.ArrayList; -import java.util.Collection; -import java.util.concurrent.LinkedBlockingQueue; +import com.netflix.hystrix.HystrixCircuitBreaker; +import com.netflix.hystrix.HystrixCommandKey; +import com.netflix.hystrix.HystrixCommandMetrics; +import com.netflix.hystrix.HystrixCommandProperties; +import com.netflix.hystrix.HystrixThreadPoolKey; +import com.netflix.hystrix.HystrixThreadPoolMetrics; +import com.netflix.hystrix.util.HystrixRollingNumberEvent; /** * @author Spencer Gibb - * see com.netflix.hystrix.contrib.metrics.eventstream.HystrixMetricsPoller.MetricsPoller + * @see com.netflix.hystrix.contrib.metrics.eventstream.HystrixMetricsPoller.MetricsPoller */ @Slf4j public class HystrixStreamTask implements ApplicationContextAware { - @Autowired - private HystrixStreamChannel channel; + @Autowired + private HystrixStreamChannel channel; - @Autowired - private DiscoveryClient discoveryClient; + @Autowired + private DiscoveryClient discoveryClient; - private ApplicationContext context; + private ApplicationContext context; - @Autowired - private HystrixStreamAmqpProperties properties; + @Autowired + private HystrixStreamAmqpProperties properties; - private final LinkedBlockingQueue jsonMetrics = new LinkedBlockingQueue<>(1000); + private final LinkedBlockingQueue jsonMetrics = new LinkedBlockingQueue<>( + 1000); - private final JsonFactory jsonFactory = new JsonFactory(); + private final JsonFactory jsonFactory = new JsonFactory(); - @Override - public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { - this.context = applicationContext; - } + @Override + public void setApplicationContext(ApplicationContext applicationContext) + throws BeansException { + this.context = applicationContext; + } - //TODO: use integration to split this up? - @Scheduled(fixedRateString = "${hystrix.stream.amqp.sendRate:500}") - public void sendMetrics() { - ArrayList metrics = new ArrayList<>(); - jsonMetrics.drainTo(metrics); + // TODO: use integration to split this up? + @Scheduled(fixedRateString = "${hystrix.stream.amqp.sendRate:500}") + public void sendMetrics() { + ArrayList metrics = new ArrayList<>(); + this.jsonMetrics.drainTo(metrics); - if (!metrics.isEmpty()) { - log.trace("sending amqp metrics size: " + metrics.size()); - for (String json: metrics) { - //TODO: batch all metrics to one message - try { - channel.send(json); - } catch (Exception e) { - e.printStackTrace(); - } - } - } - } + if (!metrics.isEmpty()) { + log.trace("sending amqp metrics size: " + metrics.size()); + for (String json : metrics) { + // TODO: batch all metrics to one message + try { + this.channel.send(json); + } + catch (Exception ex) { + ex.printStackTrace(); + } + } + } + } - //@InboundChannelAdapter() - //TODO: move fixedRate to configuration - @Scheduled(fixedRateString = "${hystrix.stream.amqp.gatherRate:500}") - public void gatherMetrics() { - try { - // command metrics - Collection instances = HystrixCommandMetrics.getInstances(); - if (!instances.isEmpty()) { - log.trace("gathering metrics size: " + instances.size()); - } + // @InboundChannelAdapter() + // TODO: move fixedRate to configuration + @Scheduled(fixedRateString = "${hystrix.stream.amqp.gatherRate:500}") + public void gatherMetrics() { + try { + // command metrics + Collection instances = HystrixCommandMetrics + .getInstances(); + if (!instances.isEmpty()) { + log.trace("gathering metrics size: " + instances.size()); + } - ServiceInstance localService = discoveryClient.getLocalServiceInstance(); + ServiceInstance localService = this.discoveryClient.getLocalServiceInstance(); - for (HystrixCommandMetrics commandMetrics : instances) { - HystrixCommandKey key = commandMetrics.getCommandKey(); - HystrixCircuitBreaker circuitBreaker = HystrixCircuitBreaker.Factory.getInstance(key); + for (HystrixCommandMetrics commandMetrics : instances) { + HystrixCommandKey key = commandMetrics.getCommandKey(); + HystrixCircuitBreaker circuitBreaker = HystrixCircuitBreaker.Factory + .getInstance(key); - StringWriter jsonString = new StringWriter(); - JsonGenerator json = jsonFactory.createJsonGenerator(jsonString); + StringWriter jsonString = new StringWriter(); + JsonGenerator json = this.jsonFactory.createJsonGenerator(jsonString); + json.writeStartObject(); - json.writeStartObject(); + addServiceData(json, localService); + json.writeObjectFieldStart("data"); + json.writeStringField("type", "HystrixCommand"); + String name = key.name(); - addServiceData(json, localService); - json.writeObjectFieldStart("data"); - json.writeStringField("type", "HystrixCommand"); - String name = key.name(); + if (this.properties.isPrefixMetricName()) { + name = localService.getServiceId() + "." + name; + } - if (properties.isPrefixMetricName()) { - name = localService.getServiceId() +"."+name; - } + json.writeStringField("name", name); + json.writeStringField("group", commandMetrics.getCommandGroup().name()); + json.writeNumberField("currentTime", System.currentTimeMillis()); - json.writeStringField("name", name); - json.writeStringField("group", commandMetrics.getCommandGroup().name()); - json.writeNumberField("currentTime", System.currentTimeMillis()); + // circuit breaker + if (circuitBreaker == null) { + // circuit breaker is disabled and thus never open + json.writeBooleanField("isCircuitBreakerOpen", false); + } + else { + json.writeBooleanField("isCircuitBreakerOpen", + circuitBreaker.isOpen()); + } + HystrixCommandMetrics.HealthCounts healthCounts = commandMetrics + .getHealthCounts(); + json.writeNumberField("errorPercentage", + healthCounts.getErrorPercentage()); + json.writeNumberField("errorCount", healthCounts.getErrorCount()); + json.writeNumberField("requestCount", healthCounts.getTotalRequests()); - // circuit breaker - if (circuitBreaker == null) { - // circuit breaker is disabled and thus never open - json.writeBooleanField("isCircuitBreakerOpen", false); - } else { - json.writeBooleanField("isCircuitBreakerOpen", circuitBreaker.isOpen()); - } - HystrixCommandMetrics.HealthCounts healthCounts = commandMetrics.getHealthCounts(); - json.writeNumberField("errorPercentage", healthCounts.getErrorPercentage()); - json.writeNumberField("errorCount", healthCounts.getErrorCount()); - json.writeNumberField("requestCount", healthCounts.getTotalRequests()); + // rolling counters + json.writeNumberField("rollingCountCollapsedRequests", commandMetrics + .getRollingCount(HystrixRollingNumberEvent.COLLAPSED)); + json.writeNumberField("rollingCountExceptionsThrown", commandMetrics + .getRollingCount(HystrixRollingNumberEvent.EXCEPTION_THROWN)); + json.writeNumberField("rollingCountFailure", + commandMetrics.getRollingCount(HystrixRollingNumberEvent.FAILURE)); + json.writeNumberField("rollingCountFallbackFailure", commandMetrics + .getRollingCount(HystrixRollingNumberEvent.FALLBACK_FAILURE)); + json.writeNumberField("rollingCountFallbackRejection", commandMetrics + .getRollingCount(HystrixRollingNumberEvent.FALLBACK_REJECTION)); + json.writeNumberField("rollingCountFallbackSuccess", commandMetrics + .getRollingCount(HystrixRollingNumberEvent.FALLBACK_SUCCESS)); + json.writeNumberField("rollingCountResponsesFromCache", commandMetrics + .getRollingCount(HystrixRollingNumberEvent.RESPONSE_FROM_CACHE)); + json.writeNumberField("rollingCountSemaphoreRejected", commandMetrics + .getRollingCount(HystrixRollingNumberEvent.SEMAPHORE_REJECTED)); + json.writeNumberField("rollingCountShortCircuited", commandMetrics + .getRollingCount(HystrixRollingNumberEvent.SHORT_CIRCUITED)); + json.writeNumberField("rollingCountSuccess", + commandMetrics.getRollingCount(HystrixRollingNumberEvent.SUCCESS)); + json.writeNumberField("rollingCountThreadPoolRejected", commandMetrics + .getRollingCount(HystrixRollingNumberEvent.THREAD_POOL_REJECTED)); + json.writeNumberField("rollingCountTimeout", + commandMetrics.getRollingCount(HystrixRollingNumberEvent.TIMEOUT)); - // rolling counters - json.writeNumberField("rollingCountCollapsedRequests", commandMetrics.getRollingCount(HystrixRollingNumberEvent.COLLAPSED)); - json.writeNumberField("rollingCountExceptionsThrown", commandMetrics.getRollingCount(HystrixRollingNumberEvent.EXCEPTION_THROWN)); - json.writeNumberField("rollingCountFailure", commandMetrics.getRollingCount(HystrixRollingNumberEvent.FAILURE)); - json.writeNumberField("rollingCountFallbackFailure", commandMetrics.getRollingCount(HystrixRollingNumberEvent.FALLBACK_FAILURE)); - json.writeNumberField("rollingCountFallbackRejection", commandMetrics.getRollingCount(HystrixRollingNumberEvent.FALLBACK_REJECTION)); - json.writeNumberField("rollingCountFallbackSuccess", commandMetrics.getRollingCount(HystrixRollingNumberEvent.FALLBACK_SUCCESS)); - json.writeNumberField("rollingCountResponsesFromCache", commandMetrics.getRollingCount(HystrixRollingNumberEvent.RESPONSE_FROM_CACHE)); - json.writeNumberField("rollingCountSemaphoreRejected", commandMetrics.getRollingCount(HystrixRollingNumberEvent.SEMAPHORE_REJECTED)); - json.writeNumberField("rollingCountShortCircuited", commandMetrics.getRollingCount(HystrixRollingNumberEvent.SHORT_CIRCUITED)); - json.writeNumberField("rollingCountSuccess", commandMetrics.getRollingCount(HystrixRollingNumberEvent.SUCCESS)); - json.writeNumberField("rollingCountThreadPoolRejected", commandMetrics.getRollingCount(HystrixRollingNumberEvent.THREAD_POOL_REJECTED)); - json.writeNumberField("rollingCountTimeout", commandMetrics.getRollingCount(HystrixRollingNumberEvent.TIMEOUT)); + json.writeNumberField("currentConcurrentExecutionCount", + commandMetrics.getCurrentConcurrentExecutionCount()); - json.writeNumberField("currentConcurrentExecutionCount", commandMetrics.getCurrentConcurrentExecutionCount()); + // latency percentiles + json.writeNumberField("latencyExecute_mean", + commandMetrics.getExecutionTimeMean()); + json.writeObjectFieldStart("latencyExecute"); + json.writeNumberField("0", commandMetrics.getExecutionTimePercentile(0)); + json.writeNumberField("25", commandMetrics.getExecutionTimePercentile(25)); + json.writeNumberField("50", commandMetrics.getExecutionTimePercentile(50)); + json.writeNumberField("75", commandMetrics.getExecutionTimePercentile(75)); + json.writeNumberField("90", commandMetrics.getExecutionTimePercentile(90)); + json.writeNumberField("95", commandMetrics.getExecutionTimePercentile(95)); + json.writeNumberField("99", commandMetrics.getExecutionTimePercentile(99)); + json.writeNumberField("99.5", + commandMetrics.getExecutionTimePercentile(99.5)); + json.writeNumberField("100", + commandMetrics.getExecutionTimePercentile(100)); + json.writeEndObject(); + // + json.writeNumberField("latencyTotal_mean", + commandMetrics.getTotalTimeMean()); + json.writeObjectFieldStart("latencyTotal"); + json.writeNumberField("0", commandMetrics.getTotalTimePercentile(0)); + json.writeNumberField("25", commandMetrics.getTotalTimePercentile(25)); + json.writeNumberField("50", commandMetrics.getTotalTimePercentile(50)); + json.writeNumberField("75", commandMetrics.getTotalTimePercentile(75)); + json.writeNumberField("90", commandMetrics.getTotalTimePercentile(90)); + json.writeNumberField("95", commandMetrics.getTotalTimePercentile(95)); + json.writeNumberField("99", commandMetrics.getTotalTimePercentile(99)); + json.writeNumberField("99.5", commandMetrics.getTotalTimePercentile(99.5)); + json.writeNumberField("100", commandMetrics.getTotalTimePercentile(100)); + json.writeEndObject(); - // latency percentiles - json.writeNumberField("latencyExecute_mean", commandMetrics.getExecutionTimeMean()); - json.writeObjectFieldStart("latencyExecute"); - json.writeNumberField("0", commandMetrics.getExecutionTimePercentile(0)); - json.writeNumberField("25", commandMetrics.getExecutionTimePercentile(25)); - json.writeNumberField("50", commandMetrics.getExecutionTimePercentile(50)); - json.writeNumberField("75", commandMetrics.getExecutionTimePercentile(75)); - json.writeNumberField("90", commandMetrics.getExecutionTimePercentile(90)); - json.writeNumberField("95", commandMetrics.getExecutionTimePercentile(95)); - json.writeNumberField("99", commandMetrics.getExecutionTimePercentile(99)); - json.writeNumberField("99.5", commandMetrics.getExecutionTimePercentile(99.5)); - json.writeNumberField("100", commandMetrics.getExecutionTimePercentile(100)); - json.writeEndObject(); - // - json.writeNumberField("latencyTotal_mean", commandMetrics.getTotalTimeMean()); - json.writeObjectFieldStart("latencyTotal"); - json.writeNumberField("0", commandMetrics.getTotalTimePercentile(0)); - json.writeNumberField("25", commandMetrics.getTotalTimePercentile(25)); - json.writeNumberField("50", commandMetrics.getTotalTimePercentile(50)); - json.writeNumberField("75", commandMetrics.getTotalTimePercentile(75)); - json.writeNumberField("90", commandMetrics.getTotalTimePercentile(90)); - json.writeNumberField("95", commandMetrics.getTotalTimePercentile(95)); - json.writeNumberField("99", commandMetrics.getTotalTimePercentile(99)); - json.writeNumberField("99.5", commandMetrics.getTotalTimePercentile(99.5)); - json.writeNumberField("100", commandMetrics.getTotalTimePercentile(100)); - json.writeEndObject(); + // property values for reporting what is actually seen by the command + // rather than what was set somewhere + HystrixCommandProperties commandProperties = commandMetrics + .getProperties(); - // property values for reporting what is actually seen by the command rather than what was set somewhere - HystrixCommandProperties commandProperties = commandMetrics.getProperties(); + json.writeNumberField( + "propertyValue_circuitBreakerRequestVolumeThreshold", + commandProperties.circuitBreakerRequestVolumeThreshold().get()); + json.writeNumberField( + "propertyValue_circuitBreakerSleepWindowInMilliseconds", + commandProperties.circuitBreakerSleepWindowInMilliseconds().get()); + json.writeNumberField( + "propertyValue_circuitBreakerErrorThresholdPercentage", + commandProperties.circuitBreakerErrorThresholdPercentage().get()); + json.writeBooleanField("propertyValue_circuitBreakerForceOpen", + commandProperties.circuitBreakerForceOpen().get()); + json.writeBooleanField("propertyValue_circuitBreakerForceClosed", + commandProperties.circuitBreakerForceClosed().get()); + json.writeBooleanField("propertyValue_circuitBreakerEnabled", + commandProperties.circuitBreakerEnabled().get()); - json.writeNumberField("propertyValue_circuitBreakerRequestVolumeThreshold", commandProperties.circuitBreakerRequestVolumeThreshold().get()); - json.writeNumberField("propertyValue_circuitBreakerSleepWindowInMilliseconds", commandProperties.circuitBreakerSleepWindowInMilliseconds().get()); - json.writeNumberField("propertyValue_circuitBreakerErrorThresholdPercentage", commandProperties.circuitBreakerErrorThresholdPercentage().get()); - json.writeBooleanField("propertyValue_circuitBreakerForceOpen", commandProperties.circuitBreakerForceOpen().get()); - json.writeBooleanField("propertyValue_circuitBreakerForceClosed", commandProperties.circuitBreakerForceClosed().get()); - json.writeBooleanField("propertyValue_circuitBreakerEnabled", commandProperties.circuitBreakerEnabled().get()); + json.writeStringField("propertyValue_executionIsolationStrategy", + commandProperties.executionIsolationStrategy().get().name()); + json.writeNumberField( + "propertyValue_executionIsolationThreadTimeoutInMilliseconds", + commandProperties.executionIsolationThreadTimeoutInMilliseconds() + .get()); + json.writeBooleanField( + "propertyValue_executionIsolationThreadInterruptOnTimeout", + commandProperties.executionIsolationThreadInterruptOnTimeout() + .get()); + json.writeStringField( + "propertyValue_executionIsolationThreadPoolKeyOverride", + commandProperties.executionIsolationThreadPoolKeyOverride().get()); + json.writeNumberField( + "propertyValue_executionIsolationSemaphoreMaxConcurrentRequests", + commandProperties + .executionIsolationSemaphoreMaxConcurrentRequests().get()); + json.writeNumberField( + "propertyValue_fallbackIsolationSemaphoreMaxConcurrentRequests", + commandProperties + .fallbackIsolationSemaphoreMaxConcurrentRequests().get()); - json.writeStringField("propertyValue_executionIsolationStrategy", commandProperties.executionIsolationStrategy().get().name()); - json.writeNumberField("propertyValue_executionIsolationThreadTimeoutInMilliseconds", commandProperties.executionIsolationThreadTimeoutInMilliseconds().get()); - json.writeBooleanField("propertyValue_executionIsolationThreadInterruptOnTimeout", commandProperties.executionIsolationThreadInterruptOnTimeout().get()); - json.writeStringField("propertyValue_executionIsolationThreadPoolKeyOverride", commandProperties.executionIsolationThreadPoolKeyOverride().get()); - json.writeNumberField("propertyValue_executionIsolationSemaphoreMaxConcurrentRequests", commandProperties.executionIsolationSemaphoreMaxConcurrentRequests().get()); - json.writeNumberField("propertyValue_fallbackIsolationSemaphoreMaxConcurrentRequests", commandProperties.fallbackIsolationSemaphoreMaxConcurrentRequests().get()); + // TODO + /* + * The following are commented out as these rarely change and are verbose + * for streaming for something people don't change. We could perhaps allow + * a property or request argument to include these. + */ - /* - * The following are commented out as these rarely change and are verbose for streaming for something people don't change. - * We could perhaps allow a property or request argument to include these. - */ + // json.put("propertyValue_metricsRollingPercentileEnabled", + // commandProperties.metricsRollingPercentileEnabled().get()); + // json.put("propertyValue_metricsRollingPercentileBucketSize", + // commandProperties.metricsRollingPercentileBucketSize().get()); + // json.put("propertyValue_metricsRollingPercentileWindow", + // commandProperties.metricsRollingPercentileWindowInMilliseconds().get()); + // json.put("propertyValue_metricsRollingPercentileWindowBuckets", + // commandProperties.metricsRollingPercentileWindowBuckets().get()); + // json.put("propertyValue_metricsRollingStatisticalWindowBuckets", + // commandProperties.metricsRollingStatisticalWindowBuckets().get()); + json.writeNumberField( + "propertyValue_metricsRollingStatisticalWindowInMilliseconds", + commandProperties.metricsRollingStatisticalWindowInMilliseconds() + .get()); - // json.put("propertyValue_metricsRollingPercentileEnabled", commandProperties.metricsRollingPercentileEnabled().get()); - // json.put("propertyValue_metricsRollingPercentileBucketSize", commandProperties.metricsRollingPercentileBucketSize().get()); - // json.put("propertyValue_metricsRollingPercentileWindow", commandProperties.metricsRollingPercentileWindowInMilliseconds().get()); - // json.put("propertyValue_metricsRollingPercentileWindowBuckets", commandProperties.metricsRollingPercentileWindowBuckets().get()); - // json.put("propertyValue_metricsRollingStatisticalWindowBuckets", commandProperties.metricsRollingStatisticalWindowBuckets().get()); - json.writeNumberField("propertyValue_metricsRollingStatisticalWindowInMilliseconds", commandProperties.metricsRollingStatisticalWindowInMilliseconds().get()); + json.writeBooleanField("propertyValue_requestCacheEnabled", + commandProperties.requestCacheEnabled().get()); + json.writeBooleanField("propertyValue_requestLogEnabled", + commandProperties.requestLogEnabled().get()); - json.writeBooleanField("propertyValue_requestCacheEnabled", commandProperties.requestCacheEnabled().get()); - json.writeBooleanField("propertyValue_requestLogEnabled", commandProperties.requestLogEnabled().get()); + json.writeNumberField("reportingHosts", 1); // this will get summed across + // all instances in a cluster - json.writeNumberField("reportingHosts", 1); // this will get summed across all instances in a cluster + json.writeEndObject(); // end data attribute + json.writeEndObject(); + json.close(); - json.writeEndObject(); // end data attribute - json.writeEndObject(); - json.close(); + // output + this.jsonMetrics.add(jsonString.getBuffer().toString()); + } - // output - jsonMetrics.add(jsonString.getBuffer().toString()); - } + // thread pool metrics + for (HystrixThreadPoolMetrics threadPoolMetrics : HystrixThreadPoolMetrics + .getInstances()) { + HystrixThreadPoolKey key = threadPoolMetrics.getThreadPoolKey(); - // thread pool metrics - for (HystrixThreadPoolMetrics threadPoolMetrics : HystrixThreadPoolMetrics.getInstances()) { - HystrixThreadPoolKey key = threadPoolMetrics.getThreadPoolKey(); + StringWriter jsonString = new StringWriter(); + JsonGenerator json = this.jsonFactory.createJsonGenerator(jsonString); + json.writeStartObject(); - StringWriter jsonString = new StringWriter(); - JsonGenerator json = jsonFactory.createJsonGenerator(jsonString); - json.writeStartObject(); + addServiceData(json, localService); + json.writeObjectFieldStart("data"); - addServiceData(json, localService); - json.writeObjectFieldStart("data"); + json.writeStringField("type", "HystrixThreadPool"); + json.writeStringField("name", key.name()); + json.writeNumberField("currentTime", System.currentTimeMillis()); - json.writeStringField("type", "HystrixThreadPool"); - json.writeStringField("name", key.name()); - json.writeNumberField("currentTime", System.currentTimeMillis()); + json.writeNumberField("currentActiveCount", threadPoolMetrics + .getCurrentActiveCount().intValue()); + json.writeNumberField("currentCompletedTaskCount", threadPoolMetrics + .getCurrentCompletedTaskCount().longValue()); + json.writeNumberField("currentCorePoolSize", threadPoolMetrics + .getCurrentCorePoolSize().intValue()); + json.writeNumberField("currentLargestPoolSize", threadPoolMetrics + .getCurrentLargestPoolSize().intValue()); + json.writeNumberField("currentMaximumPoolSize", threadPoolMetrics + .getCurrentMaximumPoolSize().intValue()); + json.writeNumberField("currentPoolSize", threadPoolMetrics + .getCurrentPoolSize().intValue()); + json.writeNumberField("currentQueueSize", threadPoolMetrics + .getCurrentQueueSize().intValue()); + json.writeNumberField("currentTaskCount", threadPoolMetrics + .getCurrentTaskCount().longValue()); + json.writeNumberField("rollingCountThreadsExecuted", + threadPoolMetrics.getRollingCountThreadsExecuted()); + json.writeNumberField("rollingMaxActiveThreads", + threadPoolMetrics.getRollingMaxActiveThreads()); - json.writeNumberField("currentActiveCount", threadPoolMetrics.getCurrentActiveCount().intValue()); - json.writeNumberField("currentCompletedTaskCount", threadPoolMetrics.getCurrentCompletedTaskCount().longValue()); - json.writeNumberField("currentCorePoolSize", threadPoolMetrics.getCurrentCorePoolSize().intValue()); - json.writeNumberField("currentLargestPoolSize", threadPoolMetrics.getCurrentLargestPoolSize().intValue()); - json.writeNumberField("currentMaximumPoolSize", threadPoolMetrics.getCurrentMaximumPoolSize().intValue()); - json.writeNumberField("currentPoolSize", threadPoolMetrics.getCurrentPoolSize().intValue()); - json.writeNumberField("currentQueueSize", threadPoolMetrics.getCurrentQueueSize().intValue()); - json.writeNumberField("currentTaskCount", threadPoolMetrics.getCurrentTaskCount().longValue()); - json.writeNumberField("rollingCountThreadsExecuted", threadPoolMetrics.getRollingCountThreadsExecuted()); - json.writeNumberField("rollingMaxActiveThreads", threadPoolMetrics.getRollingMaxActiveThreads()); + json.writeNumberField("propertyValue_queueSizeRejectionThreshold", + threadPoolMetrics.getProperties().queueSizeRejectionThreshold() + .get()); + json.writeNumberField( + "propertyValue_metricsRollingStatisticalWindowInMilliseconds", + threadPoolMetrics.getProperties() + .metricsRollingStatisticalWindowInMilliseconds().get()); - json.writeNumberField("propertyValue_queueSizeRejectionThreshold", threadPoolMetrics.getProperties().queueSizeRejectionThreshold().get()); - json.writeNumberField("propertyValue_metricsRollingStatisticalWindowInMilliseconds", threadPoolMetrics.getProperties().metricsRollingStatisticalWindowInMilliseconds().get()); + json.writeNumberField("reportingHosts", 1); // this will get summed across + // all instances in a cluster - json.writeNumberField("reportingHosts", 1); // this will get summed across all instances in a cluster + json.writeEndObject(); // end of data object + json.writeEndObject(); + json.close(); + // output to stream + this.jsonMetrics.add(jsonString.getBuffer().toString()); + } + } + catch (Exception ex) { + log.error("Error adding metrics to queue", ex); + } + } - json.writeEndObject(); // end of data object - json.writeEndObject(); - json.close(); - // output to stream - jsonMetrics.add(jsonString.getBuffer().toString()); - } - } catch (Exception e) { - log.error("Error adding metrics to queue", e); - } - } + private void addServiceData(JsonGenerator json, ServiceInstance localService) + throws IOException { + json.writeObjectFieldStart("origin"); + json.writeStringField("host", localService.getHost()); + json.writeNumberField("port", localService.getPort()); + json.writeStringField("serviceId", localService.getServiceId()); + if (this.properties.isSendId()) { + json.writeStringField("id", this.context.getId()); + } + json.writeEndObject(); + } - private void addServiceData(JsonGenerator json, ServiceInstance localService) throws IOException { - - json.writeObjectFieldStart("origin"); - json.writeStringField("host", localService.getHost()); - json.writeNumberField("port", localService.getPort()); - json.writeStringField("serviceId", localService.getServiceId()); - if (properties.isSendId()) { - json.writeStringField("id", context.getId()); - } - json.writeEndObject(); - } } diff --git a/spring-cloud-netflix-hystrix-amqp/src/test/java/org/springframework/netflix/hystrix/amqp/HystrixAmqpTests.java b/spring-cloud-netflix-hystrix-amqp/src/test/java/org/springframework/netflix/hystrix/amqp/HystrixAmqpTests.java index 43e7766d9..e4958b793 100644 --- a/spring-cloud-netflix-hystrix-amqp/src/test/java/org/springframework/netflix/hystrix/amqp/HystrixAmqpTests.java +++ b/spring-cloud-netflix-hystrix-amqp/src/test/java/org/springframework/netflix/hystrix/amqp/HystrixAmqpTests.java @@ -1,6 +1,21 @@ +/* + * 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.netflix.hystrix.amqp; -import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.boot.SpringApplication; @@ -15,6 +30,8 @@ import org.springframework.test.context.web.WebAppConfiguration; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; +import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand; + /** * @author Spencer Gibb */ @@ -40,8 +57,12 @@ public class HystrixAmqpTests { public static void main(String[] args) { SpringApplication.run(Application.class, args); } + } @Test - public void contextLoads() { } + public void contextLoads() { + + } + } diff --git a/spring-cloud-netflix-hystrix-dashboard/pom.xml b/spring-cloud-netflix-hystrix-dashboard/pom.xml index eb7b71098..def4e50c0 100644 --- a/spring-cloud-netflix-hystrix-dashboard/pom.xml +++ b/spring-cloud-netflix-hystrix-dashboard/pom.xml @@ -1,49 +1,49 @@ - - 4.0.0 - spring-cloud-netflix-hystrix-dashboard - Spring Cloud Netflix Hystrix - http://projects.spring.io/spring-cloud/ - - org.springframework.cloud - spring-cloud-netflix - 1.0.0.BUILD-SNAPSHOT - .. - - - - 1.0.0.BUILD-SNAPSHOT - - - - - org.springframework.boot - spring-boot-starter-web - + + 4.0.0 + spring-cloud-netflix-hystrix-dashboard + Spring Cloud Netflix Hystrix + http://projects.spring.io/spring-cloud/ + + org.springframework.cloud + spring-cloud-netflix + 1.0.0.BUILD-SNAPSHOT + .. + + + ${basedir}/.. + 1.0.0.BUILD-SNAPSHOT + + + + org.springframework.boot + spring-boot-starter-web + org.springframework.boot spring-boot-starter-freemarker - - org.springframework.cloud - spring-cloud-commons - - - org.springframework.cloud - spring-cloud-netflix-core - - - org.apache.httpcomponents - httpclient - - - com.netflix.hystrix - hystrix-core - - - com.netflix.hystrix - hystrix-metrics-event-stream - + + org.springframework.cloud + spring-cloud-commons + + + org.springframework.cloud + spring-cloud-netflix-core + + + org.apache.httpcomponents + httpclient + + + com.netflix.hystrix + hystrix-core + + + com.netflix.hystrix + hystrix-metrics-event-stream + org.webjars jquery @@ -57,5 +57,5 @@ spring-boot-starter-test test - + diff --git a/spring-cloud-netflix-hystrix-dashboard/src/main/java/org/springframework/cloud/netflix/hystrix/dashboard/EnableHystrixDashboard.java b/spring-cloud-netflix-hystrix-dashboard/src/main/java/org/springframework/cloud/netflix/hystrix/dashboard/EnableHystrixDashboard.java index bf495cf02..d65f57f83 100644 --- a/spring-cloud-netflix-hystrix-dashboard/src/main/java/org/springframework/cloud/netflix/hystrix/dashboard/EnableHystrixDashboard.java +++ b/spring-cloud-netflix-hystrix-dashboard/src/main/java/org/springframework/cloud/netflix/hystrix/dashboard/EnableHystrixDashboard.java @@ -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.hystrix.dashboard; import java.lang.annotation.Documented; @@ -16,4 +32,5 @@ import org.springframework.context.annotation.Import; @Documented @Import(HystrixDashboardConfiguration.class) public @interface EnableHystrixDashboard { -} \ No newline at end of file + +} diff --git a/spring-cloud-netflix-hystrix-dashboard/src/main/java/org/springframework/cloud/netflix/hystrix/dashboard/HystrixDashboardConfiguration.java b/spring-cloud-netflix-hystrix-dashboard/src/main/java/org/springframework/cloud/netflix/hystrix/dashboard/HystrixDashboardConfiguration.java index 4c338016f..bff1d9989 100644 --- a/spring-cloud-netflix-hystrix-dashboard/src/main/java/org/springframework/cloud/netflix/hystrix/dashboard/HystrixDashboardConfiguration.java +++ b/spring-cloud-netflix-hystrix-dashboard/src/main/java/org/springframework/cloud/netflix/hystrix/dashboard/HystrixDashboardConfiguration.java @@ -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.hystrix.dashboard; import java.io.IOException; @@ -40,7 +56,6 @@ public class HystrixDashboardConfiguration { private static final String DEFAULT_CHARSET = "UTF-8"; - /** * Overrides Spring Boot's {@link FreeMarkerAutoConfiguration} to prefer using a * {@link SpringTemplateLoader} instead of the file system. This corrects an issue @@ -68,131 +83,160 @@ public class HystrixDashboardConfiguration { } /** - * Proxy an EventStream request (data.stream via proxy.stream) since EventStream does not yet support CORS (https://bugs.webkit.org/show_bug.cgi?id=61862) - * so that a UI can request a stream from a different server. + * Proxy an EventStream request (data.stream via proxy.stream) since EventStream does + * not yet support CORS (https://bugs.webkit.org/show_bug.cgi?id=61862) so that a UI + * can request a stream from a different server. */ public static class ProxyStreamServlet extends HttpServlet { - private static final long serialVersionUID = 1L; - private static final Logger logger = LoggerFactory.getLogger(ProxyStreamServlet.class); - public ProxyStreamServlet() { - super(); - } + private static final long serialVersionUID = 1L; - /** - * @see javax.servlet.http.HttpServlet#doGet(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) - */ - protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { - String origin = request.getParameter("origin"); - if (origin == null) { - response.setStatus(500); - response.getWriter().println("Required parameter 'origin' missing. Example: 107.20.175.135:7001"); - } - origin = origin.trim(); - - HttpGet httpget = null; - InputStream is = null; - boolean hasFirstParameter = false; - StringBuilder url = new StringBuilder(); - if (!origin.startsWith("http")) { - url.append("http://"); - } - url.append(origin); - if (origin.contains("?")) { - hasFirstParameter = true; - } - Map params = request.getParameterMap(); - for (String key : params.keySet()) { - if (!key.equals("origin")) { - String[] values = params.get(key); - String value = values[0].trim(); - if (hasFirstParameter) { - url.append("&"); - } else { - url.append("?"); - hasFirstParameter = true; - } - url.append(key).append("=").append(value); - } - } - String proxyUrl = url.toString(); - logger.info("\n\nProxy opening connection to: " + proxyUrl + "\n\n"); - try { - httpget = new HttpGet(proxyUrl); - HttpClient client = ProxyConnectionManager.httpClient; - HttpResponse httpResponse = client.execute(httpget); - int statusCode = httpResponse.getStatusLine().getStatusCode(); - if (statusCode == HttpStatus.SC_OK) { - // writeTo swallows exceptions and never quits even if outputstream is throwing IOExceptions (such as broken pipe) ... since the inputstream is infinite - // httpResponse.getEntity().writeTo(new OutputStreamWrapper(response.getOutputStream())); - // so I copy it manually ... - is = httpResponse.getEntity().getContent(); + private static final Logger logger = LoggerFactory + .getLogger(ProxyStreamServlet.class); - // set headers - for (Header header : httpResponse.getAllHeaders()) { - response.addHeader(header.getName(), header.getValue()); - } + public ProxyStreamServlet() { + super(); + } - // copy data from source to response - OutputStream os = response.getOutputStream(); - int b = -1; - while ((b = is.read()) != -1) { - try { - os.write(b); - if (b == 10 /** flush buffer on line feed */) { - os.flush(); - } - } catch (Exception e) { - if (e.getClass().getSimpleName().equalsIgnoreCase("ClientAbortException")) { - // don't throw an exception as this means the user closed the connection - logger.debug("Connection closed by client. Will stop proxying ..."); - // break out of the while loop - break; - } else { - // received unknown error while writing so throw an exception - throw new RuntimeException(e); - } - } - } - } - } catch (Exception e) { - logger.error("Error proxying request: " + url, e); - } finally { - if (httpget != null) { - try { - httpget.abort(); - } catch (Exception e) { - logger.error("failed aborting proxy connection.", e); - } - } + /** + * @see javax.servlet.http.HttpServlet#doGet(javax.servlet.http.HttpServletRequest + * request, javax.servlet.http.HttpServletResponse response) + */ + @Override + protected void doGet(HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException { + String origin = request.getParameter("origin"); + if (origin == null) { + response.setStatus(500); + response.getWriter() + .println( + "Required parameter 'origin' missing. Example: 107.20.175.135:7001"); + } + origin = origin.trim(); - // httpget.abort() MUST be called first otherwise is.close() hangs (because data is still streaming?) - if (is != null) { - // this should already be closed by httpget.abort() above - try { - is.close(); - } catch (Exception e) { - // e.printStackTrace(); - } - } - } - } + HttpGet httpget = null; + InputStream is = null; + boolean hasFirstParameter = false; + StringBuilder url = new StringBuilder(); + if (!origin.startsWith("http")) { + url.append("http://"); + } + url.append(origin); + if (origin.contains("?")) { + hasFirstParameter = true; + } + Map params = request.getParameterMap(); + for (String key : params.keySet()) { + if (!key.equals("origin")) { + String[] values = params.get(key); + String value = values[0].trim(); + if (hasFirstParameter) { + url.append("&"); + } + else { + url.append("?"); + hasFirstParameter = true; + } + url.append(key).append("=").append(value); + } + } + String proxyUrl = url.toString(); + logger.info("\n\nProxy opening connection to: " + proxyUrl + "\n\n"); + try { + httpget = new HttpGet(proxyUrl); + HttpClient client = ProxyConnectionManager.httpClient; + HttpResponse httpResponse = client.execute(httpget); + int statusCode = httpResponse.getStatusLine().getStatusCode(); + if (statusCode == HttpStatus.SC_OK) { + // writeTo swallows exceptions and never quits even if outputstream is + // throwing IOExceptions (such as broken pipe) ... since the + // inputstream is infinite + // httpResponse.getEntity().writeTo(new + // OutputStreamWrapper(response.getOutputStream())); + // so I copy it manually ... + is = httpResponse.getEntity().getContent(); - private static class ProxyConnectionManager { - private final static PoolingClientConnectionManager threadSafeConnectionManager = new PoolingClientConnectionManager(); - private final static HttpClient httpClient = new DefaultHttpClient(threadSafeConnectionManager); + // set headers + for (Header header : httpResponse.getAllHeaders()) { + response.addHeader(header.getName(), header.getValue()); + } - static { - logger.debug("Initialize ProxyConnectionManager"); - /* common settings */ - HttpParams httpParams = httpClient.getParams(); - HttpConnectionParams.setConnectionTimeout(httpParams, 5000); - HttpConnectionParams.setSoTimeout(httpParams, 10000); + // copy data from source to response + OutputStream os = response.getOutputStream(); + int b = -1; + while ((b = is.read()) != -1) { + try { + os.write(b); + if (b == 10 /** flush buffer on line feed */ + ) { + os.flush(); + } + } + catch (Exception ex) { + if (ex.getClass().getSimpleName() + .equalsIgnoreCase("ClientAbortException")) { + // don't throw an exception as this means the user closed + // the connection + logger.debug("Connection closed by client. Will stop proxying ..."); + // break out of the while loop + break; + } + else { + // received unknown error while writing so throw an + // exception + throw new RuntimeException(ex); + } + } + } + } + } + catch (Exception ex) { + logger.error("Error proxying request: " + url, ex); + } + finally { + if (httpget != null) { + try { + httpget.abort(); + } + catch (Exception ex) { + logger.error("failed aborting proxy connection.", ex); + } + } + + // httpget.abort() MUST be called first otherwise is.close() hangs + // (because data is still streaming?) + if (is != null) { + // this should already be closed by httpget.abort() above + try { + is.close(); + } + catch (Exception ex) { + // e.printStackTrace(); + } + } + } + } + + private static class ProxyConnectionManager { + + private final static PoolingClientConnectionManager threadSafeConnectionManager = new PoolingClientConnectionManager(); + + private final static HttpClient httpClient = new DefaultHttpClient( + threadSafeConnectionManager); + + static { + logger.debug("Initialize ProxyConnectionManager"); + /* common settings */ + HttpParams httpParams = httpClient.getParams(); + HttpConnectionParams.setConnectionTimeout(httpParams, 5000); + HttpConnectionParams.setSoTimeout(httpParams, 10000); + + /* number of connections to allow */ + threadSafeConnectionManager.setDefaultMaxPerRoute(400); + threadSafeConnectionManager.setMaxTotal(400); + } + + } - /* number of connections to allow */ - threadSafeConnectionManager.setDefaultMaxPerRoute(400); - threadSafeConnectionManager.setMaxTotal(400); - } - } } } diff --git a/spring-cloud-netflix-hystrix-dashboard/src/main/java/org/springframework/cloud/netflix/hystrix/dashboard/HystrixDashboardController.java b/spring-cloud-netflix-hystrix-dashboard/src/main/java/org/springframework/cloud/netflix/hystrix/dashboard/HystrixDashboardController.java index 5a4948838..9b4b972f9 100644 --- a/spring-cloud-netflix-hystrix-dashboard/src/main/java/org/springframework/cloud/netflix/hystrix/dashboard/HystrixDashboardController.java +++ b/spring-cloud-netflix-hystrix-dashboard/src/main/java/org/springframework/cloud/netflix/hystrix/dashboard/HystrixDashboardController.java @@ -13,17 +13,18 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.cloud.netflix.hystrix.dashboard; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.context.request.RequestAttributes; import org.springframework.web.context.request.WebRequest; /** * @author Dave Syer - * */ @Controller public class HystrixDashboardController { @@ -43,10 +44,9 @@ public class HystrixDashboardController { private String extractPath(WebRequest request) { String path = request.getContextPath() - + (String) request - .getAttribute( - "org.springframework.web.servlet.HandlerMapping.pathWithinHandlerMapping", - WebRequest.SCOPE_REQUEST); + + (String) request.getAttribute("org.springframework." + + "web.servlet.HandlerMapping.pathWithinHandlerMapping", + RequestAttributes.SCOPE_REQUEST); return path; } diff --git a/spring-cloud-netflix-hystrix-dashboard/src/test/java/org/springframework/cloud/netflix/hystrix/dashboard/HystrixDashboardContextTests.java b/spring-cloud-netflix-hystrix-dashboard/src/test/java/org/springframework/cloud/netflix/hystrix/dashboard/HystrixDashboardContextTests.java index fe7c529b3..6d7db75d9 100644 --- a/spring-cloud-netflix-hystrix-dashboard/src/test/java/org/springframework/cloud/netflix/hystrix/dashboard/HystrixDashboardContextTests.java +++ b/spring-cloud-netflix-hystrix-dashboard/src/test/java/org/springframework/cloud/netflix/hystrix/dashboard/HystrixDashboardContextTests.java @@ -13,9 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.cloud.netflix.hystrix.dashboard; -import static org.junit.Assert.assertEquals; +package org.springframework.cloud.netflix.hystrix.dashboard; import org.junit.Test; import org.junit.runner.RunWith; @@ -32,6 +31,8 @@ import org.springframework.http.ResponseEntity; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.web.WebAppConfiguration; +import static org.junit.Assert.assertEquals; + /** * @author Dave Syer * @@ -39,7 +40,8 @@ import org.springframework.test.context.web.WebAppConfiguration; @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = Application.class) @WebAppConfiguration -@IntegrationTest({ "server.port=0", "spring.application.name=hystrix-dashboard", "server.contextPath=/context" }) +@IntegrationTest({ "server.port=0", "spring.application.name=hystrix-dashboard", + "server.contextPath=/context" }) public class HystrixDashboardContextTests { @Value("${local.server.port}") @@ -48,28 +50,31 @@ public class HystrixDashboardContextTests { @Test public void homePage() { ResponseEntity entity = new TestRestTemplate().getForEntity( - "http://localhost:" + port + "/context/hystrix", String.class); + "http://localhost:" + this.port + "/context/hystrix", String.class); assertEquals(HttpStatus.OK, entity.getStatusCode()); } @Test public void cssAvailable() { ResponseEntity entity = new TestRestTemplate().getForEntity( - "http://localhost:" + port + "/context/hystrix/css/global.css", String.class); + "http://localhost:" + this.port + "/context/hystrix/css/global.css", + String.class); assertEquals(HttpStatus.OK, entity.getStatusCode()); } @Test public void webjarsAvailable() { ResponseEntity entity = new TestRestTemplate().getForEntity( - "http://localhost:" + port + "/context/webjars/jquery/2.1.1/jquery.min.js", String.class); + "http://localhost:" + this.port + + "/context/webjars/jquery/2.1.1/jquery.min.js", String.class); assertEquals(HttpStatus.OK, entity.getStatusCode()); } @Test public void monitorPage() { ResponseEntity entity = new TestRestTemplate().getForEntity( - "http://localhost:" + port + "/context/hystrix/monitor", String.class); + "http://localhost:" + this.port + "/context/hystrix/monitor", + String.class); assertEquals(HttpStatus.OK, entity.getStatusCode()); } @@ -79,7 +84,8 @@ public class HystrixDashboardContextTests { protected static class Application { public static void main(String[] args) { new SpringApplicationBuilder(Application.class).properties( - "spring.application.name=hystrix-dashboard", "server.contextPath=/context").run(); + "spring.application.name=hystrix-dashboard", + "server.contextPath=/context").run(); } } diff --git a/spring-cloud-netflix-hystrix-dashboard/src/test/java/org/springframework/cloud/netflix/hystrix/dashboard/HystrixDashboardHomePageTests.java b/spring-cloud-netflix-hystrix-dashboard/src/test/java/org/springframework/cloud/netflix/hystrix/dashboard/HystrixDashboardHomePageTests.java index e278ef6f1..19c51ac28 100644 --- a/spring-cloud-netflix-hystrix-dashboard/src/test/java/org/springframework/cloud/netflix/hystrix/dashboard/HystrixDashboardHomePageTests.java +++ b/spring-cloud-netflix-hystrix-dashboard/src/test/java/org/springframework/cloud/netflix/hystrix/dashboard/HystrixDashboardHomePageTests.java @@ -13,9 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.cloud.netflix.hystrix.dashboard; -import static org.junit.Assert.assertEquals; +package org.springframework.cloud.netflix.hystrix.dashboard; import org.junit.Test; import org.junit.runner.RunWith; @@ -34,6 +33,8 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.web.WebAppConfiguration; import org.springframework.web.bind.annotation.RequestMapping; +import static org.junit.Assert.assertEquals; + /** * @author Dave Syer * @@ -50,22 +51,24 @@ public class HystrixDashboardHomePageTests { @Test public void homePage() { ResponseEntity entity = new TestRestTemplate().getForEntity( - "http://localhost:" + port, String.class); + "http://localhost:" + this.port, String.class); assertEquals(HttpStatus.OK, entity.getStatusCode()); entity.getBody().contains(""); } @Test public void cssAvailable() { - ResponseEntity entity = new TestRestTemplate().getForEntity( - "http://localhost:" + port + "/hystrix/css/global.css", String.class); + ResponseEntity entity = new TestRestTemplate() + .getForEntity( + "http://localhost:" + this.port + "/hystrix/css/global.css", + String.class); assertEquals(HttpStatus.OK, entity.getStatusCode()); } @Test public void monitorPage() { ResponseEntity entity = new TestRestTemplate().getForEntity( - "http://localhost:" + port + "/hystrix/monitor", String.class); + "http://localhost:" + this.port + "/hystrix/monitor", String.class); assertEquals(HttpStatus.OK, entity.getStatusCode()); } @@ -84,6 +87,7 @@ public class HystrixDashboardHomePageTests { new SpringApplicationBuilder(Application.class).properties( "spring.application.name=hystrix-dashboard").run(); } + } } diff --git a/spring-cloud-netflix-hystrix-dashboard/src/test/java/org/springframework/cloud/netflix/hystrix/dashboard/HystrixDashboardTests.java b/spring-cloud-netflix-hystrix-dashboard/src/test/java/org/springframework/cloud/netflix/hystrix/dashboard/HystrixDashboardTests.java index 8e5cc139c..ed552320e 100644 --- a/spring-cloud-netflix-hystrix-dashboard/src/test/java/org/springframework/cloud/netflix/hystrix/dashboard/HystrixDashboardTests.java +++ b/spring-cloud-netflix-hystrix-dashboard/src/test/java/org/springframework/cloud/netflix/hystrix/dashboard/HystrixDashboardTests.java @@ -13,9 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.cloud.netflix.hystrix.dashboard; -import static org.junit.Assert.assertEquals; +package org.springframework.cloud.netflix.hystrix.dashboard; import org.junit.Test; import org.junit.runner.RunWith; @@ -32,9 +31,10 @@ import org.springframework.http.ResponseEntity; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.web.WebAppConfiguration; +import static org.junit.Assert.assertEquals; + /** * @author Dave Syer - * */ @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = Application.class) @@ -48,22 +48,24 @@ public class HystrixDashboardTests { @Test public void homePage() { ResponseEntity entity = new TestRestTemplate().getForEntity( - "http://localhost:" + port + "/hystrix", String.class); + "http://localhost:" + this.port + "/hystrix", String.class); assertEquals(HttpStatus.OK, entity.getStatusCode()); entity.getBody().contains(""); } @Test public void cssAvailable() { - ResponseEntity entity = new TestRestTemplate().getForEntity( - "http://localhost:" + port + "/hystrix/css/global.css", String.class); + ResponseEntity entity = new TestRestTemplate() + .getForEntity( + "http://localhost:" + this.port + "/hystrix/css/global.css", + String.class); assertEquals(HttpStatus.OK, entity.getStatusCode()); } @Test public void monitorPage() { ResponseEntity entity = new TestRestTemplate().getForEntity( - "http://localhost:" + port + "/hystrix/monitor", String.class); + "http://localhost:" + this.port + "/hystrix/monitor", String.class); assertEquals(HttpStatus.OK, entity.getStatusCode()); } @@ -71,10 +73,12 @@ public class HystrixDashboardTests { @EnableAutoConfiguration @EnableHystrixDashboard protected static class Application { + public static void main(String[] args) { new SpringApplicationBuilder(Application.class).properties( "spring.application.name=hystrix-dashboard").run(); } + } } diff --git a/spring-cloud-netflix-sidecar/pom.xml b/spring-cloud-netflix-sidecar/pom.xml index 578a64f22..8b7eba806 100644 --- a/spring-cloud-netflix-sidecar/pom.xml +++ b/spring-cloud-netflix-sidecar/pom.xml @@ -2,42 +2,36 @@ 4.0.0 - spring-cloud-netflix-sidecar - jar - Spring Cloud Netflix Sidecar - http://projects.spring.io/spring-cloud/ org.springframework.cloud spring-cloud-netflix 1.0.0.BUILD-SNAPSHOT .. - - - - - - + spring-cloud-netflix-sidecar + jar + Spring Cloud Netflix Sidecar + http://projects.spring.io/spring-cloud/ + ${basedir}/.. - - - org.springframework.cloud - spring-cloud-commons - - - org.springframework.boot - spring-boot-starter-web - - - org.springframework.boot - spring-boot-starter-actuator - - - org.springframework - spring-web - + + org.springframework.cloud + spring-cloud-commons + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-actuator + + + org.springframework + spring-web + org.springframework.cloud spring-cloud-netflix-core @@ -46,34 +40,34 @@ com.netflix.eureka eureka-client - - com.netflix.hystrix - hystrix-core - - - com.netflix.hystrix - hystrix-metrics-event-stream - - - com.netflix.hystrix - hystrix-javanica - - - com.netflix.ribbon - ribbon - - - com.netflix.ribbon - ribbon-core - - - com.netflix.ribbon - ribbon-eureka - - - com.netflix.ribbon - ribbon-httpclient - + + com.netflix.hystrix + hystrix-core + + + com.netflix.hystrix + hystrix-metrics-event-stream + + + com.netflix.hystrix + hystrix-javanica + + + com.netflix.ribbon + ribbon + + + com.netflix.ribbon + ribbon-core + + + com.netflix.ribbon + ribbon-eureka + + + com.netflix.ribbon + ribbon-httpclient + com.netflix.zuul zuul-core @@ -83,21 +77,21 @@ tomcat-embed-el - org.projectlombok - lombok - + org.projectlombok + lombok + compile true - - - org.springframework.boot - spring-boot-starter-test - test - - - org.springframework.cloud - spring-cloud-config-client - test - + + + org.springframework.boot + spring-boot-starter-test + test + + + org.springframework.cloud + spring-cloud-config-client + test + diff --git a/spring-cloud-netflix-sidecar/src/main/java/org/springframework/cloud/netflix/sidecar/EnableSidecar.java b/spring-cloud-netflix-sidecar/src/main/java/org/springframework/cloud/netflix/sidecar/EnableSidecar.java index 42df7f36e..805d5328f 100644 --- a/spring-cloud-netflix-sidecar/src/main/java/org/springframework/cloud/netflix/sidecar/EnableSidecar.java +++ b/spring-cloud-netflix-sidecar/src/main/java/org/springframework/cloud/netflix/sidecar/EnableSidecar.java @@ -1,12 +1,32 @@ +/* + * 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.sidecar; +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; + import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.cloud.netflix.zuul.EnableZuulProxy; import org.springframework.context.annotation.Import; -import java.lang.annotation.*; - /** * @author Spencer Gibb */ @@ -18,4 +38,5 @@ import java.lang.annotation.*; @Documented @Import(SidecarConfiguration.class) public @interface EnableSidecar { + } diff --git a/spring-cloud-netflix-sidecar/src/main/java/org/springframework/cloud/netflix/sidecar/LocalApplicationHealthIndicator.java b/spring-cloud-netflix-sidecar/src/main/java/org/springframework/cloud/netflix/sidecar/LocalApplicationHealthIndicator.java index 6e758e14d..19e1d1f13 100644 --- a/spring-cloud-netflix-sidecar/src/main/java/org/springframework/cloud/netflix/sidecar/LocalApplicationHealthIndicator.java +++ b/spring-cloud-netflix-sidecar/src/main/java/org/springframework/cloud/netflix/sidecar/LocalApplicationHealthIndicator.java @@ -1,49 +1,67 @@ +/* + * 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.sidecar; +import java.net.URI; +import java.util.Map; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.actuate.health.AbstractHealthIndicator; import org.springframework.boot.actuate.health.Health; import org.springframework.web.client.RestTemplate; -import java.net.URI; -import java.util.Map; - /** * @author Spencer Gibb */ public class LocalApplicationHealthIndicator extends AbstractHealthIndicator { - @Autowired - SidecarProperties properties; + @Autowired + private SidecarProperties properties; - @SuppressWarnings("unchecked") - @Override - protected void doHealthCheck(Health.Builder builder) throws Exception { - URI uri = properties.getHealthUri(); - if (uri == null) { - builder.up(); - return; - } + @SuppressWarnings("unchecked") + @Override + protected void doHealthCheck(Health.Builder builder) throws Exception { + URI uri = this.properties.getHealthUri(); + if (uri == null) { + builder.up(); + return; + } + Map map = new RestTemplate().getForObject(uri, Map.class); + Object status = map.get("status"); + if (status != null && status instanceof String) { + builder.status(status.toString()); + } + else if (status != null && status instanceof Map) { + Map statusMap = (Map) status; + Object code = statusMap.get("code"); + if (code != null) { + builder.status(code.toString()); + } + else { + getWarning(builder); + } + } + else { + getWarning(builder); + } + } - Map map = new RestTemplate().getForObject(uri, Map.class); - Object status = map.get("status"); + private Health.Builder getWarning(Health.Builder builder) { + return builder.unknown().withDetail("warning", "no status field in response"); + } - if (status != null && status instanceof String) { - builder.status(status.toString()); - } else if (status != null && status instanceof Map) { - Map statusMap = (Map) status; - Object code = statusMap.get("code"); - if (code != null) { - builder.status(code.toString()); - } else { - getWarning(builder); - } - } else { - getWarning(builder); - } - } - - private Health.Builder getWarning(Health.Builder builder) { - return builder.unknown().withDetail("warning", "no status field in response"); - } } diff --git a/spring-cloud-netflix-sidecar/src/main/java/org/springframework/cloud/netflix/sidecar/SidecarConfiguration.java b/spring-cloud-netflix-sidecar/src/main/java/org/springframework/cloud/netflix/sidecar/SidecarConfiguration.java index 72f39ed7a..e3f172b1a 100644 --- a/spring-cloud-netflix-sidecar/src/main/java/org/springframework/cloud/netflix/sidecar/SidecarConfiguration.java +++ b/spring-cloud-netflix-sidecar/src/main/java/org/springframework/cloud/netflix/sidecar/SidecarConfiguration.java @@ -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.sidecar; import org.springframework.beans.factory.annotation.Value; @@ -14,37 +30,38 @@ import org.springframework.context.annotation.Configuration; @EnableConfigurationProperties @ConditionalOnProperty(value = "sidecar.enabled", matchIfMissing = true) public class SidecarConfiguration { - @Value("${server.port:${SERVER_PORT:${PORT:8080}}}") - private int serverPort = 8080; - @Bean - public SidecarProperties sidecarProperties() { - return new SidecarProperties(); - } + @Value("${server.port:${SERVER_PORT:${PORT:8080}}}") + private int serverPort = 8080; - @Bean - public EurekaInstanceConfigBean eurekaInstanceConfigBean() { - EurekaInstanceConfigBean config = new EurekaInstanceConfigBean(); + @Bean + public SidecarProperties sidecarProperties() { + return new SidecarProperties(); + } - int port = sidecarProperties().getPort(); - config.setNonSecurePort(port); + @Bean + public EurekaInstanceConfigBean eurekaInstanceConfigBean() { + EurekaInstanceConfigBean config = new EurekaInstanceConfigBean(); + int port = sidecarProperties().getPort(); + config.setNonSecurePort(port); + String scheme = config.getSecurePortEnabled() ? "https" : "http"; + config.setStatusPageUrl(scheme + "://" + config.getHostname() + ":" + + this.serverPort + config.getStatusPageUrlPath()); + config.setHealthCheckUrl(scheme + "://" + config.getHostname() + ":" + + this.serverPort + config.getHealthCheckUrlPath()); + config.setHomePageUrl(scheme + "://" + config.getHostname() + ":" + port + + config.getHomePageUrlPath()); + return config; + } - String scheme = config.getSecurePortEnabled()? "https" : "http"; + @Bean + public LocalApplicationHealthIndicator localApplicationHealthIndicator() { + return new LocalApplicationHealthIndicator(); + } - config.setStatusPageUrl(scheme + "://" + config.getHostname() + ":" + serverPort + config.getStatusPageUrlPath()); - config.setHealthCheckUrl(scheme + "://" + config.getHostname() + ":" + serverPort + config.getHealthCheckUrlPath()); + @Bean + public SidecarController sidecarController() { + return new SidecarController(); + } - config.setHomePageUrl(scheme + "://" + config.getHostname() + ":" + port + config.getHomePageUrlPath()); - return config; - } - - @Bean - public LocalApplicationHealthIndicator localApplicationHealthIndicator() { - return new LocalApplicationHealthIndicator(); - } - - @Bean - public SidecarController sidecarController() { - return new SidecarController(); - } } diff --git a/spring-cloud-netflix-sidecar/src/main/java/org/springframework/cloud/netflix/sidecar/SidecarController.java b/spring-cloud-netflix-sidecar/src/main/java/org/springframework/cloud/netflix/sidecar/SidecarController.java index a4b328049..b526d0391 100644 --- a/spring-cloud-netflix-sidecar/src/main/java/org/springframework/cloud/netflix/sidecar/SidecarController.java +++ b/spring-cloud-netflix-sidecar/src/main/java/org/springframework/cloud/netflix/sidecar/SidecarController.java @@ -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.sidecar; +import java.util.List; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.cloud.client.ServiceInstance; @@ -9,42 +27,40 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; -import java.util.List; - /** * @author Spencer Gibb */ @RestController public class SidecarController { - @Autowired - DiscoveryClient discovery; + @Autowired + private DiscoveryClient discovery; - @Value("${spring.application.name}") - String appName; + @Value("${spring.application.name}") + private String appName; - @RequestMapping("/ping") - public String ping() { - return "OK"; - } + @RequestMapping("/ping") + public String ping() { + return "OK"; + } @RequestMapping("/hosts/{appName}") public List hosts(@PathVariable("appName") String appName) { return hosts2(appName); } - @RequestMapping("/hosts") - public List hosts2(@RequestParam("appName") String appName) { - List instances = discovery.getInstances(appName); - return instances; - } + @RequestMapping("/hosts") + public List hosts2(@RequestParam("appName") String appName) { + List instances = this.discovery.getInstances(appName); + return instances; + } + + @RequestMapping(value = "/", produces = "text/html") + public String home() { + return "Sidecar\n" + + "ping
\n" + + "health
\n" + "hosts/" + this.appName + "
\n" + ""; + } - @RequestMapping(value = "/", produces = "text/html") - public String home() { - return "Sidecar\n" + - "ping
\n" + - "health
\n" + - "hosts/"+appName+"
\n" + - ""; - } } diff --git a/spring-cloud-netflix-sidecar/src/main/java/org/springframework/cloud/netflix/sidecar/SidecarProperties.java b/spring-cloud-netflix-sidecar/src/main/java/org/springframework/cloud/netflix/sidecar/SidecarProperties.java index 4f519e9f5..e15edb17b 100644 --- a/spring-cloud-netflix-sidecar/src/main/java/org/springframework/cloud/netflix/sidecar/SidecarProperties.java +++ b/spring-cloud-netflix-sidecar/src/main/java/org/springframework/cloud/netflix/sidecar/SidecarProperties.java @@ -1,17 +1,38 @@ +/* + * 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.sidecar; -import lombok.Data; -import org.springframework.boot.context.properties.ConfigurationProperties; - import java.net.URI; +import lombok.Data; + +import org.springframework.boot.context.properties.ConfigurationProperties; + /** * @author Spencer Gibb */ @Data @ConfigurationProperties("sidecar") public class SidecarProperties { - private URI healthUri; - private URI homePageUri; - private int port; + + private URI healthUri; + + private URI homePageUri; + + private int port; + } diff --git a/spring-cloud-netflix-sidecar/src/test/java/org/springframework/cloud/netflix/sidecar/SidecarApplication.java b/spring-cloud-netflix-sidecar/src/test/java/org/springframework/cloud/netflix/sidecar/SidecarApplication.java index 914fb7b9d..8095a7786 100644 --- a/spring-cloud-netflix-sidecar/src/test/java/org/springframework/cloud/netflix/sidecar/SidecarApplication.java +++ b/spring-cloud-netflix-sidecar/src/test/java/org/springframework/cloud/netflix/sidecar/SidecarApplication.java @@ -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.sidecar; import org.springframework.boot.SpringApplication; @@ -17,6 +33,7 @@ public class SidecarApplication { } public static void main(String[] args) { - SpringApplication.run(SidecarApplication.class, args); + SpringApplication.run(SidecarApplication.class, args); } + } diff --git a/spring-cloud-netflix-sidecar/src/test/java/org/springframework/cloud/netflix/sidecar/SidecarApplicationTests.java b/spring-cloud-netflix-sidecar/src/test/java/org/springframework/cloud/netflix/sidecar/SidecarApplicationTests.java index f5766ce0e..5d3ce3310 100644 --- a/spring-cloud-netflix-sidecar/src/test/java/org/springframework/cloud/netflix/sidecar/SidecarApplicationTests.java +++ b/spring-cloud-netflix-sidecar/src/test/java/org/springframework/cloud/netflix/sidecar/SidecarApplicationTests.java @@ -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.sidecar; import org.junit.Test; @@ -10,7 +26,7 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @SpringApplicationConfiguration(classes = SidecarApplication.class) @IntegrationTest("server.port=0") public class SidecarApplicationTests { - + @Test public void contextLoads() { } diff --git a/spring-cloud-netflix-turbine-amqp/pom.xml b/spring-cloud-netflix-turbine-amqp/pom.xml index f4b47f4d5..d3ba0ac9b 100644 --- a/spring-cloud-netflix-turbine-amqp/pom.xml +++ b/spring-cloud-netflix-turbine-amqp/pom.xml @@ -2,117 +2,110 @@ 4.0.0 - - spring-cloud-netflix-turbine-amqp - jar - - Spring Cloud Netflix Turbine AMQP - Spring Cloud Netflix Turbine AMQP - org.springframework.cloud spring-cloud-netflix 1.0.0.BUILD-SNAPSHOT .. - - - - - org.apache.maven.plugins - maven-compiler-plugin - - 1.8 - 1.8 - - - - - - - [1.0,1.1) - 2.0.0-DP.2 - - - - - - io.reactivex - rxjava - ${rxjava.version} - - - com.netflix.turbine - turbine-core - ${turbine.version} - - - com.netflix.rxjava - rxjava-core - - - org.slf4j - slf4j-simple - - - - - - + spring-cloud-netflix-turbine-amqp + jar + Spring Cloud Netflix Turbine AMQP + Spring Cloud Netflix Turbine AMQP + + ${basedir}/.. + [1.0,1.1) + 2.0.0-DP.2 + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 1.8 + 1.8 + + + + + + + + io.reactivex + rxjava + ${rxjava.version} + + + com.netflix.turbine + turbine-core + ${turbine.version} + + + com.netflix.rxjava + rxjava-core + + + org.slf4j + slf4j-simple + + + + + - - org.springframework.cloud - spring-cloud-netflix-core - - - org.springframework.boot - spring-boot-starter-amqp - - - org.springframework.boot - spring-boot-starter-integration - - - org.springframework.integration - spring-integration-amqp - true - - - org.springframework.integration - spring-integration-java-dsl - true - - - com.fasterxml.jackson.core - jackson-databind - true - - - com.netflix.turbine - turbine-core - true - - - io.reactivex - rxjava - true - - - org.projectlombok - lombok + + org.springframework.cloud + spring-cloud-netflix-core + + + org.springframework.boot + spring-boot-starter-amqp + + + org.springframework.boot + spring-boot-starter-integration + + + org.springframework.integration + spring-integration-amqp + true + + + org.springframework.integration + spring-integration-java-dsl + true + + + com.fasterxml.jackson.core + jackson-databind + true + + + com.netflix.turbine + turbine-core + true + + + io.reactivex + rxjava + true + + + org.projectlombok + lombok compile true - - - org.springframework.boot - spring-boot-starter-web - test - - - org.springframework.boot - spring-boot-starter-test - test - + + + org.springframework.boot + spring-boot-starter-web + test + + + org.springframework.boot + spring-boot-starter-test + test + - diff --git a/spring-cloud-netflix-turbine-amqp/src/main/java/org/springframework/cloud/netflix/turbine/amqp/Aggregator.java b/spring-cloud-netflix-turbine-amqp/src/main/java/org/springframework/cloud/netflix/turbine/amqp/Aggregator.java index b71b1d4e0..fe029f71f 100644 --- a/spring-cloud-netflix-turbine-amqp/src/main/java/org/springframework/cloud/netflix/turbine/amqp/Aggregator.java +++ b/spring-cloud-netflix-turbine-amqp/src/main/java/org/springframework/cloud/netflix/turbine/amqp/Aggregator.java @@ -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.turbine.amqp; -import com.fasterxml.jackson.databind.ObjectMapper; +import java.io.IOException; +import java.util.Map; import lombok.extern.slf4j.Slf4j; @@ -11,8 +28,7 @@ import org.springframework.util.StringUtils; import rx.subjects.PublishSubject; -import java.io.IOException; -import java.util.Map; +import com.fasterxml.jackson.databind.ObjectMapper; /** * @author Spencer Gibb @@ -21,45 +37,43 @@ import java.util.Map; @Slf4j public class Aggregator { - @Autowired - private ObjectMapper objectMapper; + @Autowired + private ObjectMapper objectMapper; - @Autowired - private PublishSubject> subject; + @Autowired + private PublishSubject> subject; - @ServiceActivator(inputChannel = "hystrixStreamAggregator") - public void handle(String payload) { - try { - @SuppressWarnings("unchecked") - Map map = objectMapper.readValue(payload, Map.class); - Map data = getPayloadData(map); + @ServiceActivator(inputChannel = "hystrixStreamAggregator") + public void handle(String payload) { + try { + @SuppressWarnings("unchecked") + Map map = this.objectMapper.readValue(payload, Map.class); + Map data = getPayloadData(map); - log.debug("Received hystrix stream payload: {}", data); - subject.onNext(data); - } catch (IOException e) { - log.error("Error receiving hystrix stream payload: " + payload, e); - } - } + log.debug("Received hystrix stream payload: {}", data); + this.subject.onNext(data); + } + catch (IOException ex) { + log.error("Error receiving hystrix stream payload: " + payload, ex); + } + } - public static Map getPayloadData(Map jsonMap) { - @SuppressWarnings("unchecked") + public static Map getPayloadData(Map jsonMap) { + @SuppressWarnings("unchecked") Map origin = (Map) jsonMap.get("origin"); - - String instanceId = null; - if (origin.containsKey("id")) { - instanceId = origin.get("id").toString(); - } - - if (!StringUtils.hasText(instanceId)) { - //TODO: instanceid template - instanceId = origin.get("serviceId")+":"+origin.get("host")+":"+origin.get("port"); - } - - @SuppressWarnings("unchecked") + String instanceId = null; + if (origin.containsKey("id")) { + instanceId = origin.get("id").toString(); + } + if (!StringUtils.hasText(instanceId)) { + // TODO: instanceid template + instanceId = origin.get("serviceId") + ":" + origin.get("host") + ":" + + origin.get("port"); + } + @SuppressWarnings("unchecked") Map data = (Map) jsonMap.get("data"); - - data.put("instanceId", instanceId); - return data; - } + data.put("instanceId", instanceId); + return data; + } } diff --git a/spring-cloud-netflix-turbine-amqp/src/main/java/org/springframework/cloud/netflix/turbine/amqp/EnableTurbineAmqp.java b/spring-cloud-netflix-turbine-amqp/src/main/java/org/springframework/cloud/netflix/turbine/amqp/EnableTurbineAmqp.java index d9af015c3..aa156d38a 100644 --- a/spring-cloud-netflix-turbine-amqp/src/main/java/org/springframework/cloud/netflix/turbine/amqp/EnableTurbineAmqp.java +++ b/spring-cloud-netflix-turbine-amqp/src/main/java/org/springframework/cloud/netflix/turbine/amqp/EnableTurbineAmqp.java @@ -1,12 +1,31 @@ +/* + * 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.turbine.amqp; +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; + import org.springframework.context.annotation.Import; -import java.lang.annotation.*; - /** - * Run the RxNetty based Spring Cloud Turbine AMQP server. - * Based on Netflix Turbine 2 + * Run the RxNetty based Spring Cloud Turbine AMQP server. Based on Netflix Turbine 2 * * @author Spencer Gibb */ @@ -15,4 +34,5 @@ import java.lang.annotation.*; @Documented @Import(TurbineAmqpConfiguration.class) public @interface EnableTurbineAmqp { + } diff --git a/spring-cloud-netflix-turbine-amqp/src/main/java/org/springframework/cloud/netflix/turbine/amqp/TurbineAmqpAutoConfiguration.java b/spring-cloud-netflix-turbine-amqp/src/main/java/org/springframework/cloud/netflix/turbine/amqp/TurbineAmqpAutoConfiguration.java index 068ad3b6a..f4cf3bf5b 100644 --- a/spring-cloud-netflix-turbine-amqp/src/main/java/org/springframework/cloud/netflix/turbine/amqp/TurbineAmqpAutoConfiguration.java +++ b/spring-cloud-netflix-turbine-amqp/src/main/java/org/springframework/cloud/netflix/turbine/amqp/TurbineAmqpAutoConfiguration.java @@ -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.turbine.amqp; import java.util.HashMap; @@ -45,7 +61,7 @@ public class TurbineAmqpAutoConfiguration { @PostConstruct public void init() { Jackson2JsonMessageConverter converter = messageConverter(); - amqpTemplate.setMessageConverter(converter); + this.amqpTemplate.setMessageConverter(converter); } @Bean @@ -71,7 +87,7 @@ public class TurbineAmqpAutoConfiguration { @Bean public IntegrationFlow hystrixStreamAggregatorInboundFlow() { return IntegrationFlows - .from(Amqp.inboundAdapter(connectionFactory, hystrixStreamQueue()) + .from(Amqp.inboundAdapter(this.connectionFactory, hystrixStreamQueue()) .messageConverter(messageConverter())) .channel("hystrixStreamAggregator").get(); } @@ -83,8 +99,8 @@ public class TurbineAmqpAutoConfiguration { private Jackson2JsonMessageConverter messageConverter() { Jackson2JsonMessageConverter converter = new Jackson2JsonMessageConverter(); - if (objectMapper != null) { - converter.setJsonObjectMapper(objectMapper); + if (this.objectMapper != null) { + converter.setJsonObjectMapper(this.objectMapper); } return converter; } diff --git a/spring-cloud-netflix-turbine-amqp/src/main/java/org/springframework/cloud/netflix/turbine/amqp/TurbineAmqpConfiguration.java b/spring-cloud-netflix-turbine-amqp/src/main/java/org/springframework/cloud/netflix/turbine/amqp/TurbineAmqpConfiguration.java index a6367dfe7..bc502632b 100644 --- a/spring-cloud-netflix-turbine-amqp/src/main/java/org/springframework/cloud/netflix/turbine/amqp/TurbineAmqpConfiguration.java +++ b/spring-cloud-netflix-turbine-amqp/src/main/java/org/springframework/cloud/netflix/turbine/amqp/TurbineAmqpConfiguration.java @@ -1,6 +1,21 @@ +/* + * 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.turbine.amqp; -import static io.reactivex.netty.pipeline.PipelineConfigurators.sseServerConfigurator; import io.netty.buffer.ByteBuf; import io.reactivex.netty.RxNetty; import io.reactivex.netty.protocol.http.server.HttpServer; @@ -24,6 +39,8 @@ import com.netflix.turbine.aggregator.InstanceKey; import com.netflix.turbine.aggregator.StreamAggregator; import com.netflix.turbine.internal.JsonUtility; +import static io.reactivex.netty.pipeline.PipelineConfigurators.sseServerConfigurator; + /** * @author Spencer Gibb */ @@ -56,14 +73,14 @@ public class TurbineAmqpConfiguration implements SmartLifecycle { .doOnSubscribe(() -> log.info("Starting aggregation")).flatMap(o -> o) .publish().refCount(); - turbinePort = turbine.getPort(); + this.turbinePort = this.turbine.getPort(); - if (turbinePort <= 0) { - turbinePort = SocketUtils.findAvailableTcpPort(40000); + if (this.turbinePort <= 0) { + this.turbinePort = SocketUtils.findAvailableTcpPort(40000); } HttpServer httpServer = RxNetty.createHttpServer( - turbinePort, + this.turbinePort, (request, response) -> { log.info("SSE Request Received"); response.getHeaders().setHeader("Content-Type", "text/event-stream"); @@ -97,15 +114,15 @@ public class TurbineAmqpConfiguration implements SmartLifecycle { try { aggregatorServer().shutdown(); } - catch (InterruptedException e) { - log.error("Error shutting down", e); + catch (InterruptedException ex) { + log.error("Error shutting down", ex); } - running = false; + this.running = false; } @Override public boolean isRunning() { - return running; + return this.running; } @Override @@ -114,6 +131,7 @@ public class TurbineAmqpConfiguration implements SmartLifecycle { } public int getTurbinePort() { - return turbinePort; + return this.turbinePort; } + } diff --git a/spring-cloud-netflix-turbine-amqp/src/main/java/org/springframework/cloud/netflix/turbine/amqp/TurbineAmqpProperties.java b/spring-cloud-netflix-turbine-amqp/src/main/java/org/springframework/cloud/netflix/turbine/amqp/TurbineAmqpProperties.java index b866ab773..2bec401e6 100644 --- a/spring-cloud-netflix-turbine-amqp/src/main/java/org/springframework/cloud/netflix/turbine/amqp/TurbineAmqpProperties.java +++ b/spring-cloud-netflix-turbine-amqp/src/main/java/org/springframework/cloud/netflix/turbine/amqp/TurbineAmqpProperties.java @@ -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.turbine.amqp; import lombok.Data; diff --git a/spring-cloud-netflix-turbine-amqp/src/test/java/org/springframework/cloud/netflix/turbine/amqp/AggregatorTest.java b/spring-cloud-netflix-turbine-amqp/src/test/java/org/springframework/cloud/netflix/turbine/amqp/AggregatorTest.java index 48f9ef14c..f28dccb9c 100644 --- a/spring-cloud-netflix-turbine-amqp/src/test/java/org/springframework/cloud/netflix/turbine/amqp/AggregatorTest.java +++ b/spring-cloud-netflix-turbine-amqp/src/test/java/org/springframework/cloud/netflix/turbine/amqp/AggregatorTest.java @@ -1,63 +1,89 @@ -package org.springframework.cloud.netflix.turbine.amqp; +/* + * 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.springframework.cloud.netflix.turbine.amqp.Aggregator.getPayloadData; +package org.springframework.cloud.netflix.turbine.amqp; import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.util.Map; -import org.springframework.util.ReflectionUtils; - import rx.Observable; import rx.observables.GroupedObservable; +import org.springframework.util.ReflectionUtils; + import com.netflix.turbine.aggregator.InstanceKey; import com.netflix.turbine.aggregator.StreamAggregator; import com.netflix.turbine.aggregator.TypeAndNameKey; import com.netflix.turbine.internal.JsonUtility; +import static org.springframework.cloud.netflix.turbine.amqp.Aggregator.getPayloadData; public class AggregatorTest { - public static final String STREAM_ALL = "hystrixamqp"; + public static final String STREAM_ALL = "hystrixamqp"; - public static void main(String[] args) { - getHystrixStreamFromFile(STREAM_ALL, 1).flatMap(commandGroup -> commandGroup.take(50)).take(50).toBlocking().forEach(s -> System.out.println("s: " + s)); - } + public static void main(String[] args) { + getHystrixStreamFromFile(STREAM_ALL, 1) + .flatMap(commandGroup -> commandGroup.take(50)).take(50).toBlocking() + .forEach(s -> System.out.println("s: " + s)); + } - // a hack to simulate a stream - public static Observable>> getHystrixStreamFromFile(final String stream, final int latencyBetweenEvents) { - Observable> objectObservable = Observable.create(sub -> { - try { - while (!sub.isUnsubscribed()) { - String packagePath = AggregatorTest.class.getPackage().getName().replace('.', '/'); - InputStream file = AggregatorTest.class.getResourceAsStream("/" + packagePath + "/" + stream + ".stream"); - BufferedReader in = new BufferedReader(new InputStreamReader(file)); - String line = null; - while ((line = in.readLine()) != null && !sub.isUnsubscribed()) { - if (!line.trim().equals("")) { - if (line.trim().startsWith("{")) { - String json = line.trim(); - try { - Map jsonMap = JsonUtility.jsonToMap(json); - Map data = getPayloadData(jsonMap); - sub.onNext(data); - Thread.sleep(latencyBetweenEvents); - } catch (Exception e) { - ReflectionUtils.rethrowException(e); - } - } - } - } - } - } catch (Exception e) { - sub.onError(e); - } - }); - Observable>> observable = objectObservable.groupBy(data -> InstanceKey.create((String) data.get("instanceId"))); - return StreamAggregator.aggregateGroupedStreams(observable); - } + // a hack to simulate a stream + public static Observable>> getHystrixStreamFromFile( + final String stream, final int latencyBetweenEvents) { + Observable> objectObservable = Observable.create(sub -> { + try { + while (!sub.isUnsubscribed()) { + String packagePath = AggregatorTest.class.getPackage().getName() + .replace('.', '/'); + InputStream file = AggregatorTest.class.getResourceAsStream("/" + + packagePath + "/" + stream + ".stream"); + BufferedReader in = new BufferedReader(new InputStreamReader(file)); + String line = null; + while ((line = in.readLine()) != null && !sub.isUnsubscribed()) { + if (!line.trim().equals("")) { + if (line.trim().startsWith("{")) { + String json = line.trim(); + try { + Map jsonMap = JsonUtility + .jsonToMap(json); + Map data = getPayloadData(jsonMap); + sub.onNext(data); + Thread.sleep(latencyBetweenEvents); + } + catch (Exception ex) { + ReflectionUtils.rethrowException(ex); + } + } + } + } + } + } + catch (Exception ex) { + sub.onError(ex); + } + }); + Observable>> observable = objectObservable + .groupBy(data -> InstanceKey.create((String) data.get("instanceId"))); + return StreamAggregator.aggregateGroupedStreams(observable); + } + + // TODO /*public static GroupedObservable> getHystrixStreamFromFileEachLineScheduledEvery10Milliseconds(final String stream, final int instanceID, final TestScheduler scheduler, int maxTime) { TestSubject> scheduledOrigin = TestSubject.create(scheduler); diff --git a/spring-cloud-netflix-turbine-amqp/src/test/java/org/springframework/cloud/netflix/turbine/amqp/TurbineAmqpTests.java b/spring-cloud-netflix-turbine-amqp/src/test/java/org/springframework/cloud/netflix/turbine/amqp/TurbineAmqpTests.java index 78fc142df..ad5870feb 100644 --- a/spring-cloud-netflix-turbine-amqp/src/test/java/org/springframework/cloud/netflix/turbine/amqp/TurbineAmqpTests.java +++ b/spring-cloud-netflix-turbine-amqp/src/test/java/org/springframework/cloud/netflix/turbine/amqp/TurbineAmqpTests.java @@ -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.turbine.amqp; import org.junit.Test; @@ -22,12 +38,12 @@ public class TurbineAmqpTests { @EnableTurbineAmqp public static class Application { public static void main(String[] args) { - new SpringApplicationBuilder() - .sources(Application.class) - .run(args); + new SpringApplicationBuilder().sources(Application.class).run(args); } } @Test - public void contextLoads() { } + public void contextLoads() { + } + } diff --git a/spring-cloud-netflix-turbine-amqp/src/test/java/org/springframework/cloud/netflix/turbine/amqp/hystrixamqp.stream b/spring-cloud-netflix-turbine-amqp/src/test/resources/org/springframework/cloud/netflix/turbine/amqp/hystrixamqp.stream similarity index 100% rename from spring-cloud-netflix-turbine-amqp/src/test/java/org/springframework/cloud/netflix/turbine/amqp/hystrixamqp.stream rename to spring-cloud-netflix-turbine-amqp/src/test/resources/org/springframework/cloud/netflix/turbine/amqp/hystrixamqp.stream diff --git a/spring-cloud-netflix-turbine/pom.xml b/spring-cloud-netflix-turbine/pom.xml index d3fffc5d0..6f4d80329 100644 --- a/spring-cloud-netflix-turbine/pom.xml +++ b/spring-cloud-netflix-turbine/pom.xml @@ -2,21 +2,20 @@ 4.0.0 - spring-cloud-netflix-turbine - jar - Spring Cloud Netflix Turbine - http://projects.spring.io/spring-cloud/ org.springframework.cloud spring-cloud-netflix 1.0.0.BUILD-SNAPSHOT .. - + spring-cloud-netflix-turbine + jar + Spring Cloud Netflix Turbine + http://projects.spring.io/spring-cloud/ + ${basedir}/.. 1.0.0 - @@ -36,16 +35,15 @@ - - - org.springframework.boot - spring-boot-starter-web - - - org.springframework.cloud - spring-cloud-commons - + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.cloud + spring-cloud-commons + org.springframework.cloud spring-cloud-netflix-core @@ -62,12 +60,12 @@ com.netflix.turbine turbine-core - - org.projectlombok - lombok - + + org.projectlombok + lombok + compile true - + diff --git a/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/EnableTurbine.java b/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/EnableTurbine.java index 576cc25d0..23bd0fea3 100644 --- a/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/EnableTurbine.java +++ b/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/EnableTurbine.java @@ -13,15 +13,19 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.cloud.netflix.turbine; +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; + import org.springframework.context.annotation.Import; -import java.lang.annotation.*; - /** * @author Spencer Gibb - * */ @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) diff --git a/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/EurekaInstanceDiscovery.java b/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/EurekaInstanceDiscovery.java index a8e201e66..1adbb84d2 100644 --- a/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/EurekaInstanceDiscovery.java +++ b/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/EurekaInstanceDiscovery.java @@ -1,5 +1,33 @@ +/* + * 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.turbine; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import java.util.Map; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.expression.Expression; +import org.springframework.expression.spel.standard.SpelExpressionParser; +import org.springframework.expression.spel.support.StandardEvaluationContext; + import com.netflix.appinfo.AmazonInfo; import com.netflix.appinfo.DataCenterInfo; import com.netflix.appinfo.InstanceInfo; @@ -10,197 +38,175 @@ import com.netflix.discovery.DiscoveryManager; import com.netflix.discovery.shared.Application; import com.netflix.turbine.discovery.Instance; import com.netflix.turbine.discovery.InstanceDiscovery; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.expression.Expression; -import org.springframework.expression.spel.standard.SpelExpressionParser; -import org.springframework.expression.spel.support.StandardEvaluationContext; - -import java.util.*; /** - * Class that encapsulates an {@link com.netflix.turbine.discovery.InstanceDiscovery} implementation that uses Eureka (see https://github.com/Netflix/eureka) - * The plugin requires a list of applications configured. It then queries the set of instances for each application. - * Instance information retrieved from Eureka must be translated to something that Turbine can understand i.e the {@link com.netflix.turbine.discovery.Instance} class. + * Class that encapsulates an {@link com.netflix.turbine.discovery.InstanceDiscovery} + * implementation that uses Eureka (see https://github.com/Netflix/eureka) The plugin + * requires a list of applications configured. It then queries the set of instances for + * each application. Instance information retrieved from Eureka must be translated to + * something that Turbine can understand i.e the + * {@link com.netflix.turbine.discovery.Instance} class. + *

+ * All the logic to perform this translation can be overriden here, so that you can + * provide your own implementation if needed. * - * All the logic to perform this translation can be overriden here, so that you can provide your own implementation if needed. + * @author Spencer Gibb */ public class EurekaInstanceDiscovery implements InstanceDiscovery { - private static final Logger logger = LoggerFactory.getLogger(EurekaInstanceDiscovery.class); + private static final Logger logger = LoggerFactory + .getLogger(EurekaInstanceDiscovery.class); - // Property the controls the list of applications that are enabled in Eureka - private static final DynamicStringProperty ApplicationList = DynamicPropertyFactory.getInstance().getStringProperty("turbine.appConfig", ""); + // Property the controls the list of applications that are enabled in Eureka + private static final DynamicStringProperty ApplicationList = DynamicPropertyFactory + .getInstance().getStringProperty("turbine.appConfig", ""); - private final Expression clusterNameExpression; + private final Expression clusterNameExpression; - public EurekaInstanceDiscovery(TurbineProperties turbineProperties) { - // Eureka client should already be configured by spring-platform-netflix-core - // initialize eureka client. - //DiscoveryManager.getInstance().initComponent(new MyDataCenterInstanceConfig(), new DefaultEurekaClientConfig()); + public EurekaInstanceDiscovery(TurbineProperties turbineProperties) { + // Eureka client should already be configured by spring-platform-netflix-core + // initialize eureka client. + // DiscoveryManager.getInstance().initComponent(new MyDataCenterInstanceConfig(), + // new DefaultEurekaClientConfig()); + SpelExpressionParser parser = new SpelExpressionParser(); + this.clusterNameExpression = parser.parseExpression(turbineProperties + .getClusterNameExpression()); + } - SpelExpressionParser parser = new SpelExpressionParser(); - clusterNameExpression = parser.parseExpression(turbineProperties.getClusterNameExpression()); - } + /** + * Method that queries Eureka service for a list of configured application names + * @return Collection + */ + @Override + public Collection getInstanceList() throws Exception { + List instances = new ArrayList(); + List appNames = parseApps(); + if (appNames == null || appNames.size() == 0) { + logger.info("No apps configured, returning an empty instance list"); + return instances; + } + logger.info("Fetching instance list for apps: " + appNames); + for (String appName : appNames) { + try { + instances.addAll(getInstancesForApp(appName)); + } + catch (Exception ex) { + logger.error("Failed to fetch instances for app: " + appName + + ", retrying once more", ex); + try { + instances.addAll(getInstancesForApp(appName)); + } + catch (Exception retryException) { + logger.error("Failed again to fetch instances for app: " + appName + + ", giving up", ex); + } + } + } + return instances; + } - /** - * Method that queries Eureka service for a list of configured application names - * @return Collection - */ - @Override - public Collection getInstanceList() throws Exception { + /** + * Private helper that fetches the Instances for each application. + * @param appName + * @return List + * @throws Exception + */ + private List getInstancesForApp(String appName) throws Exception { + List instances = new ArrayList(); + logger.info("Fetching instances for app: {}", appName); + Application app = DiscoveryManager.getInstance().getDiscoveryClient() + .getApplication(appName); + if (app == null) { + logger.warn("Eureka returned null for app: {}", appName); + } + List instancesForApp = app.getInstances(); + if (instancesForApp != null) { + logger.info("Received instance list for app: {} = {}", appName, + instancesForApp.size()); + for (InstanceInfo iInfo : instancesForApp) { + Instance instance = marshallInstanceInfo(iInfo); + if (instance != null) { + instances.add(instance); + } + } + } + return instances; + } - List instances = new ArrayList(); + /** + * Private helper that marshals the information from each instance into something that + * Turbine can understand. Override this method for your own implementation for + * parsing Eureka info. + * @param instanceInfo + * @return Instance + */ + protected Instance marshallInstanceInfo(InstanceInfo instanceInfo) { + String hostname = instanceInfo.getHostName(); + String cluster = getClusterName(instanceInfo); + Boolean status = parseInstanceStatus(instanceInfo.getStatus()); + if (hostname != null && cluster != null && status != null) { + Instance instance = new Instance(hostname, cluster, status); + Map metadata = instanceInfo.getMetadata(); + if (metadata != null) { + instance.getAttributes().putAll(metadata); + } + String asgName = instanceInfo.getASGName(); + if (asgName != null) { + instance.getAttributes().put("asg", asgName); + } + instance.getAttributes().put("port", String.valueOf(instanceInfo.getPort())); + DataCenterInfo dcInfo = instanceInfo.getDataCenterInfo(); + if (dcInfo != null && dcInfo.getName().equals(DataCenterInfo.Name.Amazon)) { + AmazonInfo amznInfo = (AmazonInfo) dcInfo; + instance.getAttributes().putAll(amznInfo.getMetadata()); + } + return instance; + } + else { + return null; + } + } - List appNames = parseApps(); - if (appNames == null || appNames.size() == 0) { - logger.info("No apps configured, returning an empty instance list"); - return instances; - } + /** + * Helper that returns whether the instance is Up of Down + */ + protected Boolean parseInstanceStatus(InstanceStatus status) { + if (status == null) { + return null; + } + return status == InstanceStatus.UP; + } - logger.info("Fetching instance list for apps: " + appNames); + /** + * Helper that fetches the cluster name. Cluster is a Turbine concept and not a Eureka + * concept. By default we choose the amazon asg name as the cluster. A custom + * implementation can be plugged in by overriding this method. + */ + protected String getClusterName(InstanceInfo iInfo) { + StandardEvaluationContext context = new StandardEvaluationContext(iInfo); + Object value = this.clusterNameExpression.getValue(context); + if (value != null) { + return value.toString(); + } + return null; + } - for (String appName : appNames) { - try { - instances.addAll(getInstancesForApp(appName)); - } catch (Exception e) { - logger.error("Failed to fetch instances for app: " + appName + ", retrying once more", e); - try { - instances.addAll(getInstancesForApp(appName)); - } catch (Exception e1) { - logger.error("Failed again to fetch instances for app: " + appName + ", giving up", e); - } - } - } - return instances; - } + private List parseApps() { + // TODO: move to ConfigurationProperties Private helper that parses the list of + // application names. + String appList = ApplicationList.get(); + if (appList == null) { + return null; + } + appList = appList.trim(); + if (appList.length() == 0) { + return null; + } + String[] parts = appList.split(","); + if (parts != null && parts.length > 0) { + return Arrays.asList(parts); + } + return null; + } - /** - * Private helper that fetches the Instances for each application. - * @param appName - * @return List - * @throws Exception - */ - private List getInstancesForApp(String appName) throws Exception { - - List instances = new ArrayList(); - - logger.info("Fetching instances for app: {}", appName); - Application app = DiscoveryManager.getInstance().getDiscoveryClient().getApplication(appName); - if (app == null) { - logger.warn("Eureka returned null for app: {}", appName); - } - List instancesForApp = app.getInstances(); - - if (instancesForApp != null) { - logger.info("Received instance list for app: {} = {}", appName, instancesForApp.size()); - for (InstanceInfo iInfo : instancesForApp) { - Instance instance = marshallInstanceInfo(iInfo); - if (instance != null) { - instances.add(instance); - } - } - } - - return instances; - } - - /** - * Private helper that marshals the information from each instance into something that Turbine can understand. - * Override this method for your own implementation for parsing Eureka info. - * - * @param iInfo - * @return Instance - */ - protected Instance marshallInstanceInfo(InstanceInfo iInfo) { - - String hostname = iInfo.getHostName(); - String cluster = getClusterName(iInfo); - Boolean status = parseInstanceStatus(iInfo.getStatus()); - - if (hostname != null && cluster != null && status != null) { - Instance instance = new Instance(hostname, cluster, status); - Map metadata = iInfo.getMetadata(); - if (metadata != null) { - instance.getAttributes().putAll(metadata); - } - - String asgName = iInfo.getASGName(); - if (asgName != null) { - instance.getAttributes().put("asg", asgName); - } - instance.getAttributes().put("port", String.valueOf(iInfo.getPort())); - - DataCenterInfo dcInfo = iInfo.getDataCenterInfo(); - if (dcInfo != null && dcInfo.getName().equals(DataCenterInfo.Name.Amazon)) { - AmazonInfo amznInfo = (AmazonInfo) dcInfo; - instance.getAttributes().putAll(amznInfo.getMetadata()); - } - - return instance; - } else { - return null; - } - } - - /** - * Helper that returns whether the instance is Up of Down - * @param status - * @return - */ - protected Boolean parseInstanceStatus(InstanceStatus status) { - - if (status != null) { - if (status == InstanceStatus.UP) { - return Boolean.TRUE; - } else { - return Boolean.FALSE; - } - } else { - return null; - } - } - - - /** - * Helper that fetches the cluster name. Cluster is a Turbine concept and not a Eureka concept. - * By default we choose the amazon asg name as the cluster. A custom implementation can be plugged in by overriding this method. - * - * @param iInfo - * @return - */ - protected String getClusterName(InstanceInfo iInfo) { - StandardEvaluationContext context = new StandardEvaluationContext(iInfo); - Object value = clusterNameExpression.getValue(context); - if (value != null) { - return value.toString(); - } - return null; - } - - /** - * TODO: move to ConfigurationProperties - * Private helper that parses the list of application names. - * - * @return List - */ - private List parseApps() { - - String appList = ApplicationList.get(); - if (appList == null) { - return null; - } - - appList = appList.trim(); - if (appList.length() == 0) { - return null; - } - - String[] parts = appList.split(","); - if (parts != null && parts.length > 0) { - return Arrays.asList(parts); - } - - return null; - } -} \ No newline at end of file +} diff --git a/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/SpringAggregatorFactory.java b/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/SpringAggregatorFactory.java index 0dff27737..0c3574328 100644 --- a/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/SpringAggregatorFactory.java +++ b/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/SpringAggregatorFactory.java @@ -1,5 +1,28 @@ +/* + * 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.turbine; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.netflix.config.DynamicPropertyFactory; import com.netflix.config.DynamicStringProperty; import com.netflix.turbine.data.AggDataFromCluster; @@ -10,12 +33,6 @@ import com.netflix.turbine.monitor.TurbineDataMonitor; import com.netflix.turbine.monitor.cluster.AggregateClusterMonitor; import com.netflix.turbine.monitor.cluster.ClusterMonitor; import com.netflix.turbine.monitor.cluster.ClusterMonitorFactory; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; import static com.netflix.turbine.monitor.cluster.AggregateClusterMonitor.AggregatorClusterMonitorConsole; @@ -23,112 +40,119 @@ import static com.netflix.turbine.monitor.cluster.AggregateClusterMonitor.Aggreg * @author Spencer Gibb */ public class SpringAggregatorFactory implements ClusterMonitorFactory { - private static final Logger logger = LoggerFactory.getLogger(SpringAggregatorFactory.class); + private static final Logger logger = LoggerFactory + .getLogger(SpringAggregatorFactory.class); - private static final DynamicStringProperty aggClusters = DynamicPropertyFactory.getInstance().getStringProperty("turbine.aggregator.clusterConfig", null); + private static final DynamicStringProperty aggClusters = DynamicPropertyFactory + .getInstance().getStringProperty("turbine.aggregator.clusterConfig", null); - /** - * @return {@link com.netflix.turbine.monitor.cluster.ClusterMonitor}<{@link com.netflix.turbine.data.AggDataFromCluster}> - */ - @Override - public ClusterMonitor getClusterMonitor(String name) { - TurbineDataMonitor clusterMonitor = AggregateClusterMonitor.AggregatorClusterMonitorConsole.findMonitor(name + "_agg"); - return (ClusterMonitor) clusterMonitor; - } + /** + * @return {@link com.netflix.turbine.monitor.cluster.ClusterMonitor}< + * {@link com.netflix.turbine.data.AggDataFromCluster}> + */ + @Override + public ClusterMonitor getClusterMonitor(String name) { + TurbineDataMonitor clusterMonitor = AggregateClusterMonitor.AggregatorClusterMonitorConsole + .findMonitor(name + "_agg"); + return (ClusterMonitor) clusterMonitor; + } - public static TurbineDataMonitor findOrRegisterAggregateMonitor(String clusterName) { + public static TurbineDataMonitor findOrRegisterAggregateMonitor( + String clusterName) { + TurbineDataMonitor clusterMonitor = AggregatorClusterMonitorConsole + .findMonitor(clusterName + "_agg"); + if (clusterMonitor == null) { + logger.info("Could not find monitors: " + + AggregatorClusterMonitorConsole.toString()); + clusterMonitor = new SpringClusterMonitor(clusterName + "_agg", clusterName); + clusterMonitor = AggregatorClusterMonitorConsole + .findOrRegisterMonitor(clusterMonitor); + } + return clusterMonitor; + } - TurbineDataMonitor clusterMonitor = AggregatorClusterMonitorConsole.findMonitor(clusterName + "_agg"); + @Override + public void initClusterMonitors() { + for (String clusterName : getClusterNames()) { + ClusterMonitor clusterMonitor = (ClusterMonitor) findOrRegisterAggregateMonitor(clusterName); + clusterMonitor.registerListenertoClusterMonitor(this.StaticListener); + try { + clusterMonitor.startMonitor(); + } + catch (Exception ex) { + logger.warn("Could not init cluster monitor for: " + clusterName); + clusterMonitor.stopMonitor(); + clusterMonitor.getDispatcher().stopDispatcher(); + } + } + } - if (clusterMonitor == null) { - logger.info("Could not find monitors: " + AggregatorClusterMonitorConsole.toString()); - clusterMonitor = new SpringClusterMonitor(clusterName + "_agg", clusterName); - clusterMonitor = AggregatorClusterMonitorConsole.findOrRegisterMonitor(clusterMonitor); - } + private List getClusterNames() { + List clusters = new ArrayList(); + String clusterNames = aggClusters.get(); + if (clusterNames == null || clusterNames.trim().length() == 0) { + clusters.add("default"); + } + else { + String[] parts = aggClusters.get().split(","); + for (String s : parts) { + clusters.add(s); + } + } + return clusters; + } - return clusterMonitor; - } + /** + * shutdown all configured cluster monitors + */ + @Override + public void shutdownClusterMonitors() { + for (String clusterName : getClusterNames()) { + ClusterMonitor clusterMonitor = (ClusterMonitor) AggregateClusterMonitor + .findOrRegisterAggregateMonitor(clusterName); + clusterMonitor.stopMonitor(); + clusterMonitor.getDispatcher().stopDispatcher(); + } + } - @Override - public void initClusterMonitors() { - for(String clusterName : getClusterNames()) { - ClusterMonitor clusterMonitor = (ClusterMonitor) findOrRegisterAggregateMonitor(clusterName); - clusterMonitor.registerListenertoClusterMonitor(StaticListener); - try { - clusterMonitor.startMonitor(); - } catch (Exception e) { - logger.warn("Could not init cluster monitor for: " + clusterName); - clusterMonitor.stopMonitor(); - clusterMonitor.getDispatcher().stopDispatcher(); - } - } - } + private TurbineDataHandler StaticListener = new TurbineDataHandler() { - private List getClusterNames() { + @Override + public String getName() { + return "StaticListener_For_Aggregator"; + } - List clusters = new ArrayList(); - String clusterNames = aggClusters.get(); - if (clusterNames == null || clusterNames.trim().length() == 0) { - clusters.add("default"); - } else { - String[] parts = aggClusters.get().split(","); - for (String s : parts) { - clusters.add(s); - } - } - return clusters; - } + @Override + public void handleData(Collection stats) { + } - /** - * shutdown all configured cluster monitors - */ - @Override - public void shutdownClusterMonitors() { + @Override + public void handleHostLost(Instance host) { + } - for(String clusterName : getClusterNames()) { - ClusterMonitor clusterMonitor = (ClusterMonitor) AggregateClusterMonitor.findOrRegisterAggregateMonitor(clusterName); - clusterMonitor.stopMonitor(); - clusterMonitor.getDispatcher().stopDispatcher(); - } - } + @Override + public PerformanceCriteria getCriteria() { + return SpringAggregatorFactory.this.NonCriticalCriteria; + } - private TurbineDataHandler StaticListener = new TurbineDataHandler() { + }; - @Override - public String getName() { - return "StaticListener_For_Aggregator"; - } + private PerformanceCriteria NonCriticalCriteria = new PerformanceCriteria() { - @Override - public void handleData(Collection stats) { - } + @Override + public boolean isCritical() { + return false; + } - @Override - public void handleHostLost(Instance host) { - } + @Override + public int getMaxQueueSize() { + return 0; + } - @Override - public PerformanceCriteria getCriteria() { - return NonCriticalCriteria; - } + @Override + public int numThreads() { + return 0; + } - }; - - private PerformanceCriteria NonCriticalCriteria = new PerformanceCriteria() { - - @Override - public boolean isCritical() { - return false; - } - - @Override - public int getMaxQueueSize() { - return 0; - } - - @Override - public int numThreads() { - return 0; - } - }; + }; } diff --git a/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/SpringClusterMonitor.java b/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/SpringClusterMonitor.java index eb864190e..2c881eb72 100644 --- a/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/SpringClusterMonitor.java +++ b/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/SpringClusterMonitor.java @@ -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.turbine; import com.netflix.config.DynamicBooleanProperty; @@ -13,68 +29,73 @@ import com.netflix.turbine.monitor.instance.InstanceUrlClosure; /** * @author Spencer Gibb - * TODO: convert to ConfigurationProperties (how to do per-cluster configuration?) */ public class SpringClusterMonitor extends AggregateClusterMonitor { - public SpringClusterMonitor(String name, String clusterName) { - super(name, - new ObservationCriteria.ClusterBasedObservationCriteria(clusterName), - new PerformanceCriteria.AggClusterPerformanceCriteria(clusterName), - new MonitorConsole(), - InstanceMonitorDispatcher, - SpringClusterMonitor.ClusterConfigBasedUrlClosure); - } + // TODO: convert to ConfigurationProperties (how to do per-cluster configuration? - /** - * TODO: make this a template of some kind (secure, management port, etc...) - * Helper class that decides how to connect to a server based on injected config. - * Note that the cluster name must be provided here since one can have different configs for different clusters - */ - public static InstanceUrlClosure ClusterConfigBasedUrlClosure = new InstanceUrlClosure() { + public SpringClusterMonitor(String name, String clusterName) { + super(name, new ObservationCriteria.ClusterBasedObservationCriteria(clusterName), + new PerformanceCriteria.AggClusterPerformanceCriteria(clusterName), + new MonitorConsole(), InstanceMonitorDispatcher, + SpringClusterMonitor.ClusterConfigBasedUrlClosure); + } - private final DynamicStringProperty defaultUrlClosureConfig = DynamicPropertyFactory.getInstance().getStringProperty("turbine.instanceUrlSuffix", "hystrix.stream"); - private final DynamicBooleanProperty instanceInsertPort = DynamicPropertyFactory.getInstance().getBooleanProperty("turbine.instanceInsertPort", true); - @Override - public String getUrlPath(Instance host) { + /** + * TODO: make this a template of some kind (secure, management port, etc...) Helper + * class that decides how to connect to a server based on injected config. Note that + * the cluster name must be provided here since one can have different configs for + * different clusters + */ + public static InstanceUrlClosure ClusterConfigBasedUrlClosure = new InstanceUrlClosure() { - if (host.getCluster() == null) { - throw new RuntimeException("Host must have cluster name in order to use ClusterConfigBasedUrlClosure"); - } + private final DynamicStringProperty defaultUrlClosureConfig = DynamicPropertyFactory + .getInstance().getStringProperty("turbine.instanceUrlSuffix", + "hystrix.stream"); + private final DynamicBooleanProperty instanceInsertPort = DynamicPropertyFactory + .getInstance().getBooleanProperty("turbine.instanceInsertPort", true); - String key = "turbine.instanceUrlSuffix." + host.getCluster(); - DynamicStringProperty urlClosureConfig = DynamicPropertyFactory.getInstance().getStringProperty(key, null); + @Override + public String getUrlPath(Instance host) { + if (host.getCluster() == null) { + throw new RuntimeException( + "Host must have cluster name in order to use ClusterConfigBasedUrlClosure"); + } + String key = "turbine.instanceUrlSuffix." + host.getCluster(); + DynamicStringProperty urlClosureConfig = DynamicPropertyFactory.getInstance() + .getStringProperty(key, null); + String url = urlClosureConfig.get(); + if (url == null) { + url = this.defaultUrlClosureConfig.get(); + } + if (url == null) { + throw new RuntimeException("Config property: " + + urlClosureConfig.getName() + " or " + + this.defaultUrlClosureConfig.getName() + " must be set"); + } + String insertPortKey = "turbine.instanceInsertPort." + host.getCluster(); + DynamicStringProperty insertPortProp = DynamicPropertyFactory.getInstance() + .getStringProperty(insertPortKey, null); + boolean insertPort; + if (insertPortProp.get() == null) { + insertPort = this.instanceInsertPort.get(); + } + else { + insertPort = Boolean.parseBoolean(insertPortProp.get()); + } + if (insertPort) { + if (url.startsWith("/")) { + url = url.substring(1); + } + if (!host.getAttributes().containsKey("port")) { + throw new RuntimeException( + "Configured to use port, but port is not in host attributes"); + } + return String.format("http://%s:%s/%s", host.getHostname(), host + .getAttributes().get("port"), url); + } + return "http://" + host.getHostname() + url; + } + }; - String url = urlClosureConfig.get(); - if (url == null) { - url = defaultUrlClosureConfig.get(); - } - - if (url == null) { - throw new RuntimeException("Config property: " + urlClosureConfig.getName() + " or " + - defaultUrlClosureConfig.getName() + " must be set"); - } - - String insertPortKey = "turbine.instanceInsertPort." + host.getCluster(); - DynamicStringProperty insertPortProp = DynamicPropertyFactory.getInstance().getStringProperty(insertPortKey, null); - boolean insertPort; - if (insertPortProp.get() == null) { - insertPort = instanceInsertPort.get(); - } else { - insertPort = Boolean.parseBoolean(insertPortProp.get()); - } - - if (insertPort) { - if (url.startsWith("/")) { - url = url.substring(1); - } - if (!host.getAttributes().containsKey("port")) { - throw new RuntimeException("Configured to use port, but port is not in host attributes"); - } - return String.format("http://%s:%s/%s", host.getHostname(), host.getAttributes().get("port"), url); - } - - return "http://" + host.getHostname() + url; - } - }; } diff --git a/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/TurbineConfiguration.java b/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/TurbineConfiguration.java index 4cfcc742a..3ae895f2b 100644 --- a/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/TurbineConfiguration.java +++ b/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/TurbineConfiguration.java @@ -1,9 +1,21 @@ +/* + * 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.turbine; -import com.netflix.turbine.discovery.InstanceDiscovery; -import com.netflix.turbine.init.TurbineInit; -import com.netflix.turbine.plugins.PluginsFactory; -import com.netflix.turbine.streaming.servlet.TurbineStreamServlet; import org.springframework.boot.context.embedded.ServletRegistrationBean; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; @@ -12,6 +24,11 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.Ordered; +import com.netflix.turbine.discovery.InstanceDiscovery; +import com.netflix.turbine.init.TurbineInit; +import com.netflix.turbine.plugins.PluginsFactory; +import com.netflix.turbine.streaming.servlet.TurbineStreamServlet; + /** * @author Spencer Gibb */ @@ -20,59 +37,61 @@ import org.springframework.core.Ordered; @EnableDiscoveryClient public class TurbineConfiguration implements SmartLifecycle, Ordered { - @Bean - public ServletRegistrationBean turbineStreamServlet() { - return new ServletRegistrationBean(new TurbineStreamServlet(), "/turbine.stream"); - } + @Bean + public ServletRegistrationBean turbineStreamServlet() { + return new ServletRegistrationBean(new TurbineStreamServlet(), "/turbine.stream"); + } - @Bean - public TurbineProperties turbineProperties() { - return new TurbineProperties(); - } + @Bean + public TurbineProperties turbineProperties() { + return new TurbineProperties(); + } - @Bean - public InstanceDiscovery instanceDiscovery() { - return new EurekaInstanceDiscovery(turbineProperties()); - } + @Bean + public InstanceDiscovery instanceDiscovery() { + return new EurekaInstanceDiscovery(turbineProperties()); + } - private boolean running; + private boolean running; - @Override - public boolean isAutoStartup() { - return true; - } + @Override + public boolean isAutoStartup() { + return true; + } - @Override - public void stop(Runnable callback) { - callback.run(); - } + @Override + public void stop(Runnable callback) { + callback.run(); + } - @Override - public void start() { - //TODO: figure out ordering, so this is already run by EurekaDiscoveryClientConfiguration - //DiscoveryManager.getInstance().initComponent(instanceConfig, clientConfig); - PluginsFactory.setClusterMonitorFactory(new SpringAggregatorFactory()); - PluginsFactory.setInstanceDiscovery(instanceDiscovery()); - TurbineInit.init(); - } + @Override + public void start() { + // TODO: figure out ordering, so this is already run by + // EurekaDiscoveryClientConfiguration + // DiscoveryManager.getInstance().initComponent(instanceConfig, clientConfig); + PluginsFactory.setClusterMonitorFactory(new SpringAggregatorFactory()); + PluginsFactory.setInstanceDiscovery(instanceDiscovery()); + TurbineInit.init(); + } - @Override - public void stop() { - running = false; - } + @Override + public void stop() { + this.running = false; + } - @Override - public boolean isRunning() { - return running; - } + @Override + public boolean isRunning() { + return this.running; + } - @Override - public int getPhase() { - return 0; - } + @Override + public int getPhase() { + return 0; + } + + @Override + public int getOrder() { + return -1; + } - @Override - public int getOrder() { - return -1; - } } diff --git a/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/TurbineProperties.java b/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/TurbineProperties.java index cb4613642..c53eac180 100644 --- a/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/TurbineProperties.java +++ b/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/TurbineProperties.java @@ -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.turbine; import lombok.Data; + import org.springframework.boot.context.properties.ConfigurationProperties; /** @@ -9,5 +26,7 @@ import org.springframework.boot.context.properties.ConfigurationProperties; @Data @ConfigurationProperties("turbine") public class TurbineProperties { - private String clusterNameExpression = "appName"; + + private String clusterNameExpression = "appName"; + } diff --git a/spring-cloud-netflix-turbine/src/test/java/org/springframework/cloud/netflix/turbine/EurekaInstanceDiscoveryTest.java b/spring-cloud-netflix-turbine/src/test/java/org/springframework/cloud/netflix/turbine/EurekaInstanceDiscoveryTest.java index b2685258d..f5f3d066d 100644 --- a/spring-cloud-netflix-turbine/src/test/java/org/springframework/cloud/netflix/turbine/EurekaInstanceDiscoveryTest.java +++ b/spring-cloud-netflix-turbine/src/test/java/org/springframework/cloud/netflix/turbine/EurekaInstanceDiscoveryTest.java @@ -1,38 +1,53 @@ +/* + * 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.turbine; -import static org.junit.Assert.*; +import org.junit.Test; import com.netflix.appinfo.InstanceInfo; -import org.junit.Test; + +import static org.junit.Assert.assertEquals; /** * @author Spencer Gibb */ public class EurekaInstanceDiscoveryTest { + @Test + public void testGetClusterName() { + String appName = "testAppName"; + EurekaInstanceDiscovery discovery = new EurekaInstanceDiscovery( + new TurbineProperties()); + InstanceInfo instanceInfo = InstanceInfo.Builder.newBuilder().setAppName(appName) + .build(); + String clusterName = discovery.getClusterName(instanceInfo); + assertEquals("clusterName is wrong", appName.toUpperCase(), clusterName); + } - @Test - public void testGetClusterName() { - String appName = "testAppName"; - EurekaInstanceDiscovery discovery = new EurekaInstanceDiscovery(new TurbineProperties()); - InstanceInfo instanceInfo = InstanceInfo.Builder.newBuilder() - .setAppName(appName) - .build(); - String clusterName = discovery.getClusterName(instanceInfo); - assertEquals("clusterName is wrong", appName.toUpperCase(), clusterName); - } + @Test + public void testGetClusterNameCustomExpression() { + TurbineProperties turbineProperties = new TurbineProperties(); + turbineProperties.setClusterNameExpression("aSGName"); + EurekaInstanceDiscovery discovery = new EurekaInstanceDiscovery(turbineProperties); + String asgName = "myAsgName"; + InstanceInfo instanceInfo = InstanceInfo.Builder.newBuilder() + .setAppName("testApp").setASGName(asgName).build(); + String clusterName = discovery.getClusterName(instanceInfo); + assertEquals("clusterName is wrong", asgName, clusterName); + } - @Test - public void testGetClusterNameCustomExpression() { - TurbineProperties turbineProperties = new TurbineProperties(); - turbineProperties.setClusterNameExpression("aSGName"); - EurekaInstanceDiscovery discovery = new EurekaInstanceDiscovery(turbineProperties); - String asgName = "myAsgName"; - InstanceInfo instanceInfo = InstanceInfo.Builder.newBuilder() - .setAppName("testApp") - .setASGName(asgName) - .build(); - String clusterName = discovery.getClusterName(instanceInfo); - assertEquals("clusterName is wrong", asgName, clusterName); - } }