Formatted code
Added Eclipse formatter and cleanup configuration
This commit is contained in:
parent
ebcf32caea
commit
6ac4408ddf
43 changed files with 1196 additions and 963 deletions
56
cleanup.xml
Normal file
56
cleanup.xml
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<profiles version="2">
|
||||||
|
<profile kind="CleanUpProfile" name="ROME" version="2">
|
||||||
|
<setting id="cleanup.remove_unused_private_fields" value="true"/>
|
||||||
|
<setting id="cleanup.always_use_parentheses_in_expressions" value="false"/>
|
||||||
|
<setting id="cleanup.never_use_blocks" value="false"/>
|
||||||
|
<setting id="cleanup.remove_unused_private_methods" value="true"/>
|
||||||
|
<setting id="cleanup.add_missing_deprecated_annotations" value="true"/>
|
||||||
|
<setting id="cleanup.convert_to_enhanced_for_loop" value="true"/>
|
||||||
|
<setting id="cleanup.remove_unnecessary_nls_tags" value="true"/>
|
||||||
|
<setting id="cleanup.sort_members" value="false"/>
|
||||||
|
<setting id="cleanup.remove_unused_local_variables" value="false"/>
|
||||||
|
<setting id="cleanup.never_use_parentheses_in_expressions" value="true"/>
|
||||||
|
<setting id="cleanup.remove_unused_private_members" value="false"/>
|
||||||
|
<setting id="cleanup.remove_unnecessary_casts" value="true"/>
|
||||||
|
<setting id="cleanup.make_parameters_final" value="true"/>
|
||||||
|
<setting id="cleanup.use_this_for_non_static_field_access" value="true"/>
|
||||||
|
<setting id="cleanup.remove_private_constructors" value="true"/>
|
||||||
|
<setting id="cleanup.use_blocks" value="true"/>
|
||||||
|
<setting id="cleanup.always_use_this_for_non_static_method_access" value="false"/>
|
||||||
|
<setting id="cleanup.remove_trailing_whitespaces_all" value="true"/>
|
||||||
|
<setting id="cleanup.always_use_this_for_non_static_field_access" value="false"/>
|
||||||
|
<setting id="cleanup.use_this_for_non_static_field_access_only_if_necessary" value="true"/>
|
||||||
|
<setting id="cleanup.add_default_serial_version_id" value="true"/>
|
||||||
|
<setting id="cleanup.make_type_abstract_if_missing_method" value="false"/>
|
||||||
|
<setting id="cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class" value="true"/>
|
||||||
|
<setting id="cleanup.make_variable_declarations_final" value="true"/>
|
||||||
|
<setting id="cleanup.add_missing_nls_tags" value="false"/>
|
||||||
|
<setting id="cleanup.format_source_code" value="true"/>
|
||||||
|
<setting id="cleanup.qualify_static_method_accesses_with_declaring_class" value="false"/>
|
||||||
|
<setting id="cleanup.add_missing_override_annotations" value="true"/>
|
||||||
|
<setting id="cleanup.remove_unused_private_types" value="true"/>
|
||||||
|
<setting id="cleanup.add_missing_methods" value="false"/>
|
||||||
|
<setting id="cleanup.make_local_variable_final" value="true"/>
|
||||||
|
<setting id="cleanup.correct_indentation" value="true"/>
|
||||||
|
<setting id="cleanup.add_missing_override_annotations_interface_methods" value="true"/>
|
||||||
|
<setting id="cleanup.remove_unused_imports" value="true"/>
|
||||||
|
<setting id="cleanup.remove_trailing_whitespaces_ignore_empty" value="false"/>
|
||||||
|
<setting id="cleanup.make_private_fields_final" value="true"/>
|
||||||
|
<setting id="cleanup.add_generated_serial_version_id" value="false"/>
|
||||||
|
<setting id="cleanup.organize_imports" value="true"/>
|
||||||
|
<setting id="cleanup.remove_trailing_whitespaces" value="true"/>
|
||||||
|
<setting id="cleanup.sort_members_all" value="false"/>
|
||||||
|
<setting id="cleanup.use_blocks_only_for_return_and_throw" value="false"/>
|
||||||
|
<setting id="cleanup.add_missing_annotations" value="true"/>
|
||||||
|
<setting id="cleanup.use_parentheses_in_expressions" value="true"/>
|
||||||
|
<setting id="cleanup.qualify_static_field_accesses_with_declaring_class" value="false"/>
|
||||||
|
<setting id="cleanup.use_this_for_non_static_method_access_only_if_necessary" value="true"/>
|
||||||
|
<setting id="cleanup.use_this_for_non_static_method_access" value="true"/>
|
||||||
|
<setting id="cleanup.qualify_static_member_accesses_through_instances_with_declaring_class" value="true"/>
|
||||||
|
<setting id="cleanup.add_serial_version_id" value="false"/>
|
||||||
|
<setting id="cleanup.format_source_code_changes_only" value="false"/>
|
||||||
|
<setting id="cleanup.qualify_static_member_accesses_with_declaring_class" value="true"/>
|
||||||
|
<setting id="cleanup.always_use_blocks" value="true"/>
|
||||||
|
</profile>
|
||||||
|
</profiles>
|
291
formatter.xml
Normal file
291
formatter.xml
Normal file
|
@ -0,0 +1,291 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<profiles version="12">
|
||||||
|
<profile kind="CodeFormatterProfile" name="ROME" version="12">
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.disabling_tag" value="@formatter:off"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration" value="end_of_line"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries" value="true"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_field" value="0"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.use_on_off_tags" value="false"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line" value="false"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_ellipsis" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases" value="true"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.alignment_for_multiple_fields" value="16"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer" value="16"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.alignment_for_conditional_expression" value="80"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_binary_operator" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_array_initializer" value="end_of_line"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_package" value="1"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.continuation_indentation" value="2"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation" value="16"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk" value="1"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_binary_operator" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_package" value="0"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.compiler.source" value="1.7"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.comment.format_line_comments" value="true"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.join_wrapped_lines" value="true"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call" value="16"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_member_type" value="1"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.align_type_members_on_columns" value="false"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation" value="16"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_unary_operator" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.comment.indent_parameter_description" value="true"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment" value="true"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.lineSplit" value="160"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration" value="0"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.indentation.size" value="4"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.enabling_tag" value="@formatter:on"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration" value="16"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.alignment_for_assignment" value="0"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.compiler.problem.assertIdentifier" value="error"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.tabulation.char" value="space"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.indent_statements_compare_to_body" value="true"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_method" value="1"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested" value="true"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line" value="false"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration" value="16"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration" value="end_of_line"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.alignment_for_method_declaration" value="0"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_switch" value="end_of_line"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments" value="false"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.compiler.problem.enumIdentifier" value="error"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch" value="true"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_ellipsis" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block" value="end_of_line"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_method_declaration" value="end_of_line"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.compact_else_if" value="true"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch" value="true"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column" value="true"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.comment.indent_root_tags" value="true"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_constant" value="end_of_line"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch" value="16"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.tabulation.size" value="4"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment" value="false"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration" value="16"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.indent_empty_lines" value="false"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block_in_case" value="end_of_line"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve" value="1"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression" value="16"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.compiler.compliance" value="1.7"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer" value="2"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression" value="16"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_unary_operator" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line" value="false"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line" value="false"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration" value="16"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.alignment_for_binary_expression" value="16"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration" value="end_of_line"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode" value="enabled"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line" value="true"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_label" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant" value="16"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.comment.format_javadoc_comments" value="true"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.comment.line_length" value="80"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_import_groups" value="1"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration" value="end_of_line"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body" value="0"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header" value="true"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.wrap_before_binary_operator" value="true"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header" value="true"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations" value="1"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.indent_statements_compare_to_block" value="true"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration" value="16"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.join_lines_in_comments" value="true"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.alignment_for_compact_if" value="16"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases" value="true"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_imports" value="1"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.comment.format_html" value="true"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration" value="16"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.comment.format_source_code" value="true"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration" value="16"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.compiler.codegen.targetPlatform" value="1.7"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.alignment_for_resources_in_try" value="80"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations" value="true"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation" value="0"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.comment.format_header" value="false"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.comment.format_block_comments" value="true"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.alignment_for_enum_constants" value="0"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header" value="true"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_type_declaration" value="end_of_line"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries" value="true"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_imports" value="1"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header" value="true"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column" value="false"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column" value="false"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line" value="false"/>
|
||||||
|
</profile>
|
||||||
|
</profiles>
|
|
@ -16,7 +16,6 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
package org.rometools.certiorem;
|
package org.rometools.certiorem;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -27,13 +26,13 @@ public class HttpStatusCodeException extends RuntimeException {
|
||||||
|
|
||||||
private final int status;
|
private final int status;
|
||||||
|
|
||||||
public HttpStatusCodeException(int status, String message, Throwable cause){
|
public HttpStatusCodeException(final int status, final String message, final Throwable cause) {
|
||||||
super(message, cause);
|
super(message, cause);
|
||||||
this.status = status;
|
this.status = status;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getStatus(){
|
public int getStatus() {
|
||||||
return this.status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,13 +5,13 @@
|
||||||
package org.rometools.certiorem.hub;
|
package org.rometools.certiorem.hub;
|
||||||
|
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
|
||||||
import org.rometools.fetcher.impl.FeedFetcherCache;
|
import org.rometools.fetcher.impl.FeedFetcherCache;
|
||||||
import org.rometools.fetcher.impl.SyndFeedInfo;
|
import org.rometools.fetcher.impl.SyndFeedInfo;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Wrapper FeedFetcherCache that wraps a backing FeedFetcherCache and makes sure that
|
* Wrapper FeedFetcherCache that wraps a backing FeedFetcherCache and makes sure that any SyndFeedInfo used within it are replaced with a DeltaSyndFeedInfo
|
||||||
* any SyndFeedInfo used within it are replaced with a DeltaSyndFeedInfo which is capable of
|
* which is capable of tracking changes to entries in the underlying feed.
|
||||||
* tracking changes to entries in the underlying feed.
|
|
||||||
*
|
*
|
||||||
* @author najmi
|
* @author najmi
|
||||||
*/
|
*/
|
||||||
|
@ -19,19 +19,18 @@ public class DeltaFeedInfoCache implements FeedFetcherCache {
|
||||||
|
|
||||||
FeedFetcherCache backingCache;
|
FeedFetcherCache backingCache;
|
||||||
|
|
||||||
|
public DeltaFeedInfoCache(final FeedFetcherCache backingCache) {
|
||||||
public DeltaFeedInfoCache(FeedFetcherCache backingCache) {
|
|
||||||
this.backingCache = backingCache;
|
this.backingCache = backingCache;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SyndFeedInfo getFeedInfo(URL feedUrl) {
|
public SyndFeedInfo getFeedInfo(final URL feedUrl) {
|
||||||
return backingCache.getFeedInfo(feedUrl);
|
return backingCache.getFeedInfo(feedUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setFeedInfo(URL feedUrl, SyndFeedInfo syndFeedInfo) {
|
public void setFeedInfo(final URL feedUrl, SyndFeedInfo syndFeedInfo) {
|
||||||
//Make sure that syndFeedInfo is an instance of DeltaSyndFeedInfo
|
// Make sure that syndFeedInfo is an instance of DeltaSyndFeedInfo
|
||||||
if (!(syndFeedInfo instanceof DeltaSyndFeedInfo)) {
|
if (!(syndFeedInfo instanceof DeltaSyndFeedInfo)) {
|
||||||
syndFeedInfo = new DeltaSyndFeedInfo(syndFeedInfo);
|
syndFeedInfo = new DeltaSyndFeedInfo(syndFeedInfo);
|
||||||
}
|
}
|
||||||
|
@ -44,7 +43,7 @@ public class DeltaFeedInfoCache implements FeedFetcherCache {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SyndFeedInfo remove(URL feedUrl) {
|
public SyndFeedInfo remove(final URL feedUrl) {
|
||||||
return backingCache.remove(feedUrl);
|
return backingCache.remove(feedUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,8 +4,6 @@
|
||||||
*/
|
*/
|
||||||
package org.rometools.certiorem.hub;
|
package org.rometools.certiorem.hub;
|
||||||
|
|
||||||
import com.sun.syndication.feed.synd.SyndEntry;
|
|
||||||
import com.sun.syndication.feed.synd.SyndFeed;
|
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
import java.security.MessageDigest;
|
import java.security.MessageDigest;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
@ -13,11 +11,15 @@ import java.util.Date;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.rometools.fetcher.impl.SyndFeedInfo;
|
import org.rometools.fetcher.impl.SyndFeedInfo;
|
||||||
|
|
||||||
|
import com.sun.syndication.feed.synd.SyndEntry;
|
||||||
|
import com.sun.syndication.feed.synd.SyndFeed;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extends SyndFeedInfo to also track etags for individual entries.
|
* Extends SyndFeedInfo to also track etags for individual entries. This may be used with DeltaFeedInfoCache to only return feed with a subset of entries that
|
||||||
* This may be used with DeltaFeedInfoCache to only return feed with a subset of entries that have changed since last fetch.
|
* have changed since last fetch.
|
||||||
*
|
*
|
||||||
* @author najmi
|
* @author najmi
|
||||||
*/
|
*/
|
||||||
|
@ -28,11 +30,11 @@ public class DeltaSyndFeedInfo extends SyndFeedInfo {
|
||||||
private DeltaSyndFeedInfo() {
|
private DeltaSyndFeedInfo() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public DeltaSyndFeedInfo(SyndFeedInfo backingFeedInfo) {
|
public DeltaSyndFeedInfo(final SyndFeedInfo backingFeedInfo) {
|
||||||
this.setETag(backingFeedInfo.getETag());
|
setETag(backingFeedInfo.getETag());
|
||||||
this.setId(backingFeedInfo.getId());
|
setId(backingFeedInfo.getId());
|
||||||
this.setLastModified(backingFeedInfo.getLastModified());
|
setLastModified(backingFeedInfo.getLastModified());
|
||||||
this.setSyndFeed(backingFeedInfo.getSyndFeed());
|
setSyndFeed(backingFeedInfo.getSyndFeed());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -43,12 +45,12 @@ public class DeltaSyndFeedInfo extends SyndFeedInfo {
|
||||||
@Override
|
@Override
|
||||||
public synchronized SyndFeed getSyndFeed() {
|
public synchronized SyndFeed getSyndFeed() {
|
||||||
try {
|
try {
|
||||||
SyndFeed feed = (SyndFeed) super.getSyndFeed().clone();
|
final SyndFeed feed = (SyndFeed) super.getSyndFeed().clone();
|
||||||
|
|
||||||
List<SyndEntry> changedEntries = new ArrayList<SyndEntry>();
|
final List<SyndEntry> changedEntries = new ArrayList<SyndEntry>();
|
||||||
|
|
||||||
List<SyndEntry> entries = feed.getEntries();
|
final List<SyndEntry> entries = feed.getEntries();
|
||||||
for (SyndEntry entry : entries) {
|
for (final SyndEntry entry : entries) {
|
||||||
if (changedMap.containsKey(entry.getUri())) {
|
if (changedMap.containsKey(entry.getUri())) {
|
||||||
changedEntries.add(entry);
|
changedEntries.add(entry);
|
||||||
}
|
}
|
||||||
|
@ -57,7 +59,7 @@ public class DeltaSyndFeedInfo extends SyndFeedInfo {
|
||||||
feed.setEntries(changedEntries);
|
feed.setEntries(changedEntries);
|
||||||
|
|
||||||
return feed;
|
return feed;
|
||||||
} catch (CloneNotSupportedException ex) {
|
} catch (final CloneNotSupportedException ex) {
|
||||||
throw new RuntimeException(ex);
|
throw new RuntimeException(ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -68,54 +70,54 @@ public class DeltaSyndFeedInfo extends SyndFeedInfo {
|
||||||
* @param feed
|
* @param feed
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public final synchronized void setSyndFeed(SyndFeed feed) {
|
public final synchronized void setSyndFeed(final SyndFeed feed) {
|
||||||
super.setSyndFeed(feed);
|
super.setSyndFeed(feed);
|
||||||
|
|
||||||
changedMap.clear();
|
changedMap.clear();
|
||||||
List<SyndEntry> entries = feed.getEntries();
|
final List<SyndEntry> entries = feed.getEntries();
|
||||||
for (SyndEntry entry : entries) {
|
for (final SyndEntry entry : entries) {
|
||||||
String currentEntryTag = computeEntryTag(entry);
|
final String currentEntryTag = computeEntryTag(entry);
|
||||||
String previousEntryTag = entryTagsMap.get(entry.getUri());
|
final String previousEntryTag = entryTagsMap.get(entry.getUri());
|
||||||
|
|
||||||
if ((previousEntryTag == null) || (!(currentEntryTag.equals(previousEntryTag)))) {
|
if (previousEntryTag == null || !currentEntryTag.equals(previousEntryTag)) {
|
||||||
//Entry has changed
|
// Entry has changed
|
||||||
changedMap.put(entry.getUri(), Boolean.TRUE);
|
changedMap.put(entry.getUri(), Boolean.TRUE);
|
||||||
}
|
}
|
||||||
entryTagsMap.put(entry.getUri(), currentEntryTag);
|
entryTagsMap.put(entry.getUri(), currentEntryTag);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private String computeEntryTag(SyndEntry entry) {
|
private String computeEntryTag(final SyndEntry entry) {
|
||||||
|
|
||||||
//Following hash algorithm suggested by Robert Cooper needs to be evaluated in future.
|
// Following hash algorithm suggested by Robert Cooper needs to be evaluated in future.
|
||||||
// int hash = ( entry.getUri() != null ? entry.getUri().hashCode() : entry.getLink().hashCode() ) ^
|
// int hash = ( entry.getUri() != null ? entry.getUri().hashCode() : entry.getLink().hashCode() ) ^
|
||||||
// (entry.getUpdatedDate() != null ? entry.getUpdatedDate().hashCode() : entry.getPublishedDate().hashCode()) ^
|
// (entry.getUpdatedDate() != null ? entry.getUpdatedDate().hashCode() : entry.getPublishedDate().hashCode()) ^
|
||||||
// entry.getTitle().hashCode() ^
|
// entry.getTitle().hashCode() ^
|
||||||
// entry.getDescription().hashCode();
|
// entry.getDescription().hashCode();
|
||||||
|
|
||||||
|
final String id = entry.getUri();
|
||||||
String id = entry.getUri();
|
|
||||||
Date updateDate = entry.getUpdatedDate();
|
Date updateDate = entry.getUpdatedDate();
|
||||||
Date publishedDate = entry.getPublishedDate();
|
final Date publishedDate = entry.getPublishedDate();
|
||||||
if (updateDate == null) {
|
if (updateDate == null) {
|
||||||
if (publishedDate != null) {
|
if (publishedDate != null) {
|
||||||
updateDate = publishedDate;
|
updateDate = publishedDate;
|
||||||
} else {
|
} else {
|
||||||
//For misbehaving feeds that do not set updateDate or publishedDate we use current tiem which pretty mucg assures that it will be viewed as changed even when it is not
|
// For misbehaving feeds that do not set updateDate or publishedDate we use current tiem which pretty mucg assures that it will be viewed as
|
||||||
|
// changed even when it is not
|
||||||
updateDate = new Date();
|
updateDate = new Date();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
String key = id + ":" + entry.getUpdatedDate();
|
final String key = id + ":" + entry.getUpdatedDate();
|
||||||
return computeDigest(key);
|
return computeDigest(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
private String computeDigest(String content) {
|
private String computeDigest(final String content) {
|
||||||
try {
|
try {
|
||||||
MessageDigest md = MessageDigest.getInstance("SHA");
|
final MessageDigest md = MessageDigest.getInstance("SHA");
|
||||||
byte[] digest = md.digest(content.getBytes());
|
final byte[] digest = md.digest(content.getBytes());
|
||||||
BigInteger bi = new BigInteger(digest);
|
final BigInteger bi = new BigInteger(digest);
|
||||||
return bi.toString(16);
|
return bi.toString(16);
|
||||||
} catch (Exception e) {
|
} catch (final Exception e) {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,21 +18,9 @@
|
||||||
|
|
||||||
package org.rometools.certiorem.hub;
|
package org.rometools.certiorem.hub;
|
||||||
|
|
||||||
import com.sun.syndication.feed.synd.SyndFeed;
|
|
||||||
|
|
||||||
import org.rometools.certiorem.HttpStatusCodeException;
|
|
||||||
import org.rometools.certiorem.hub.Notifier.SubscriptionSummaryCallback;
|
|
||||||
import org.rometools.certiorem.hub.Verifier.VerificationCallback;
|
|
||||||
import org.rometools.certiorem.hub.data.HubDAO;
|
|
||||||
import org.rometools.certiorem.hub.data.Subscriber;
|
|
||||||
import org.rometools.certiorem.hub.data.SubscriptionSummary;
|
|
||||||
|
|
||||||
import org.rometools.fetcher.FeedFetcher;
|
|
||||||
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.net.URISyntaxException;
|
import java.net.URISyntaxException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -40,11 +28,19 @@ import java.util.Set;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
import org.rometools.certiorem.HttpStatusCodeException;
|
||||||
|
import org.rometools.certiorem.hub.Notifier.SubscriptionSummaryCallback;
|
||||||
|
import org.rometools.certiorem.hub.Verifier.VerificationCallback;
|
||||||
|
import org.rometools.certiorem.hub.data.HubDAO;
|
||||||
|
import org.rometools.certiorem.hub.data.Subscriber;
|
||||||
|
import org.rometools.certiorem.hub.data.SubscriptionSummary;
|
||||||
|
import org.rometools.fetcher.FeedFetcher;
|
||||||
|
|
||||||
|
import com.sun.syndication.feed.synd.SyndFeed;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The basic business logic controller for the Hub implementation. It is intended
|
* The basic business logic controller for the Hub implementation. It is intended to be usable under a very thin servlet wrapper, or other, non-HTTP
|
||||||
* to be usable under a very thin servlet wrapper, or other, non-HTTP notification
|
* notification methods you might want to use.
|
||||||
* methods you might want to use.
|
|
||||||
*
|
*
|
||||||
* @author robert.cooper
|
* @author robert.cooper
|
||||||
*/
|
*/
|
||||||
|
@ -66,6 +62,7 @@ public class Hub {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a new Hub instance
|
* Constructs a new Hub instance
|
||||||
|
*
|
||||||
* @param dao The persistence HubDAO to use
|
* @param dao The persistence HubDAO to use
|
||||||
* @param verifier The verification strategy to use.
|
* @param verifier The verification strategy to use.
|
||||||
*/
|
*/
|
||||||
|
@ -74,122 +71,111 @@ public class Hub {
|
||||||
this.verifier = verifier;
|
this.verifier = verifier;
|
||||||
this.notifier = notifier;
|
this.notifier = notifier;
|
||||||
this.fetcher = fetcher;
|
this.fetcher = fetcher;
|
||||||
this.validSchemes = STANDARD_SCHEMES;
|
validSchemes = STANDARD_SCHEMES;
|
||||||
this.validPorts = Collections.EMPTY_SET;
|
validPorts = Collections.EMPTY_SET;
|
||||||
this.validTopics = Collections.EMPTY_SET;
|
validTopics = Collections.EMPTY_SET;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a new Hub instance.
|
* Constructs a new Hub instance.
|
||||||
|
*
|
||||||
* @param dao The persistence HubDAO to use
|
* @param dao The persistence HubDAO to use
|
||||||
* @param verifier The verification strategy to use
|
* @param verifier The verification strategy to use
|
||||||
* @param validSchemes A list of valid URI schemes for callbacks (default: http, https)
|
* @param validSchemes A list of valid URI schemes for callbacks (default: http, https)
|
||||||
* @param validPorts A list of valid port numbers for callbacks (default: any)
|
* @param validPorts A list of valid port numbers for callbacks (default: any)
|
||||||
* @param validTopics A set of valid topic URIs which can be subscribed to (default: any)
|
* @param validTopics A set of valid topic URIs which can be subscribed to (default: any)
|
||||||
*/
|
*/
|
||||||
public Hub(final HubDAO dao, final Verifier verifier, final Notifier notifier, final FeedFetcher fetcher,
|
public Hub(final HubDAO dao, final Verifier verifier, final Notifier notifier, final FeedFetcher fetcher, final Set<String> validSchemes,
|
||||||
final Set<String> validSchemes, final Set<Integer> validPorts, final Set<String> validTopics) {
|
final Set<Integer> validPorts, final Set<String> validTopics) {
|
||||||
this.dao = dao;
|
this.dao = dao;
|
||||||
this.verifier = verifier;
|
this.verifier = verifier;
|
||||||
this.notifier = notifier;
|
this.notifier = notifier;
|
||||||
this.fetcher = fetcher;
|
this.fetcher = fetcher;
|
||||||
|
|
||||||
Set<String> readOnlySchemes = Collections.unmodifiableSet(validSchemes);
|
final Set<String> readOnlySchemes = Collections.unmodifiableSet(validSchemes);
|
||||||
this.validSchemes = (readOnlySchemes == null) ? STANDARD_SCHEMES : readOnlySchemes;
|
this.validSchemes = readOnlySchemes == null ? STANDARD_SCHEMES : readOnlySchemes;
|
||||||
|
|
||||||
Set<Integer> readOnlyPorts = Collections.unmodifiableSet(validPorts);
|
final Set<Integer> readOnlyPorts = Collections.unmodifiableSet(validPorts);
|
||||||
this.validPorts = (readOnlyPorts == null) ? Collections.EMPTY_SET : readOnlyPorts;
|
this.validPorts = readOnlyPorts == null ? Collections.EMPTY_SET : readOnlyPorts;
|
||||||
|
|
||||||
Set<String> readOnlyTopics = Collections.unmodifiableSet(validTopics);
|
final Set<String> readOnlyTopics = Collections.unmodifiableSet(validTopics);
|
||||||
this.validTopics = (readOnlyTopics == null) ? Collections.EMPTY_SET : readOnlyTopics;
|
this.validTopics = readOnlyTopics == null ? Collections.EMPTY_SET : readOnlyTopics;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sends a notification to the subscribers
|
* Sends a notification to the subscribers
|
||||||
|
*
|
||||||
* @param requestHost the host name the hub is running on. (Used for the user agent)
|
* @param requestHost the host name the hub is running on. (Used for the user agent)
|
||||||
* @param topic the URL of the topic that was updated.
|
* @param topic the URL of the topic that was updated.
|
||||||
* @throws HttpStatusCodeException a wrapper exception with a recommended status code for the request.
|
* @throws HttpStatusCodeException a wrapper exception with a recommended status code for the request.
|
||||||
*/
|
*/
|
||||||
public void sendNotification(String requestHost, final String topic) {
|
public void sendNotification(final String requestHost, final String topic) {
|
||||||
assert this.validTopics.isEmpty() || this.validTopics.contains(topic) : "That topic is not supported by this hub. " +
|
assert validTopics.isEmpty() || validTopics.contains(topic) : "That topic is not supported by this hub. " + topic;
|
||||||
topic;
|
|
||||||
Logger.getLogger(Hub.class.getName()).log(Level.FINE, "Sending notification for {0}", topic);
|
Logger.getLogger(Hub.class.getName()).log(Level.FINE, "Sending notification for {0}", topic);
|
||||||
try {
|
try {
|
||||||
List<?extends Subscriber> subscribers = dao.subscribersForTopic(topic);
|
final List<? extends Subscriber> subscribers = dao.subscribersForTopic(topic);
|
||||||
|
|
||||||
if (subscribers.isEmpty()) {
|
if (subscribers.isEmpty()) {
|
||||||
Logger.getLogger(Hub.class.getName()).log(Level.FINE, "No subscribers to notify for {0}", topic);
|
Logger.getLogger(Hub.class.getName()).log(Level.FINE, "No subscribers to notify for {0}", topic);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<SubscriptionSummary> summaries = (List<SubscriptionSummary>) dao.summariesForTopic(topic);
|
final List<SubscriptionSummary> summaries = (List<SubscriptionSummary>) dao.summariesForTopic(topic);
|
||||||
int total = 0;
|
int total = 0;
|
||||||
StringBuilder hosts = new StringBuilder();
|
final StringBuilder hosts = new StringBuilder();
|
||||||
|
|
||||||
for (SubscriptionSummary s : summaries) {
|
for (final SubscriptionSummary s : summaries) {
|
||||||
if (s.getSubscribers() > 0) {
|
if (s.getSubscribers() > 0) {
|
||||||
total += s.getSubscribers();
|
total += s.getSubscribers();
|
||||||
hosts.append(" (")
|
hosts.append(" (").append(s.getHost()).append("; ").append(s.getSubscribers()).append(" subscribers)");
|
||||||
.append(s.getHost())
|
|
||||||
.append("; ")
|
|
||||||
.append(s.getSubscribers())
|
|
||||||
.append(" subscribers)");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
StringBuilder userAgent = new StringBuilder("ROME-Certiorem (+http://").append(requestHost)
|
final StringBuilder userAgent = new StringBuilder("ROME-Certiorem (+http://").append(requestHost).append("; ").append(total)
|
||||||
.append("; ")
|
.append(" subscribers)").append(hosts);
|
||||||
.append(total)
|
final SyndFeed feed = fetcher.retrieveFeed(userAgent.toString(), new URL(topic));
|
||||||
.append(" subscribers)")
|
Logger.getLogger(Hub.class.getName()).log(Level.FINE, "Got feed for {0} Sending to {1} subscribers.", new Object[] { topic, subscribers.size() });
|
||||||
.append(hosts);
|
notifier.notifySubscribers((List<Subscriber>) subscribers, feed, new SubscriptionSummaryCallback() {
|
||||||
SyndFeed feed = fetcher.retrieveFeed(userAgent.toString(), new URL(topic));
|
@Override
|
||||||
Logger.getLogger(Hub.class.getName()).log(Level.FINE, "Got feed for {0} Sending to {1} subscribers.", new Object[]{topic, subscribers.size()});
|
public void onSummaryInfo(final SubscriptionSummary summary) {
|
||||||
this.notifier.notifySubscribers((List<Subscriber>) subscribers, feed,
|
dao.handleSummary(topic, summary);
|
||||||
new SubscriptionSummaryCallback() {
|
}
|
||||||
@Override
|
});
|
||||||
public void onSummaryInfo(SubscriptionSummary summary) {
|
} catch (final Exception ex) {
|
||||||
dao.handleSummary(topic, summary);
|
Logger.getLogger(Hub.class.getName()).log(Level.SEVERE, "Exception getting " + topic, ex);
|
||||||
}
|
|
||||||
});
|
|
||||||
} catch (Exception ex) {
|
|
||||||
Logger.getLogger(Hub.class.getName())
|
|
||||||
.log(Level.SEVERE, "Exception getting " + topic, ex);
|
|
||||||
throw new HttpStatusCodeException(500, ex.getMessage(), ex);
|
throw new HttpStatusCodeException(500, ex.getMessage(), ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Subscribes to a topic.
|
* Subscribes to a topic.
|
||||||
|
*
|
||||||
* @param callback Callback URI
|
* @param callback Callback URI
|
||||||
* @param topic Topic URI
|
* @param topic Topic URI
|
||||||
* @param verify Verification Type
|
* @param verify Verification Type
|
||||||
* @param lease_seconds Duration of the lease
|
* @param lease_seconds Duration of the lease
|
||||||
* @param secret Secret value
|
* @param secret Secret value
|
||||||
* @param verify_token verify_token;
|
* @param verify_token verify_token;
|
||||||
* @return Boolean.TRUE if the subscription succeeded synchronously,
|
* @return Boolean.TRUE if the subscription succeeded synchronously, Boolean.FALSE if the subscription failed synchronously, or null if the request is
|
||||||
* Boolean.FALSE if the subscription failed synchronously, or null if the request is asynchronous.
|
* asynchronous.
|
||||||
* @throws HttpStatusCodeException a wrapper exception with a recommended status code for the request.
|
* @throws HttpStatusCodeException a wrapper exception with a recommended status code for the request.
|
||||||
*/
|
*/
|
||||||
public Boolean subscribe(String callback, String topic, String verify, long lease_seconds, String secret,
|
public Boolean subscribe(final String callback, final String topic, final String verify, final long lease_seconds, final String secret,
|
||||||
String verify_token) {
|
final String verify_token) {
|
||||||
Logger.getLogger(Hub.class.getName()).log(Level.FINE, "{0} wants to subscribe to {1}", new Object[]{callback, topic});
|
Logger.getLogger(Hub.class.getName()).log(Level.FINE, "{0} wants to subscribe to {1}", new Object[] { callback, topic });
|
||||||
try {
|
try {
|
||||||
try {
|
try {
|
||||||
assert callback != null : "Callback URL is required.";
|
assert callback != null : "Callback URL is required.";
|
||||||
assert topic != null : "Topic URL is required.";
|
assert topic != null : "Topic URL is required.";
|
||||||
|
|
||||||
URI uri = new URI(callback);
|
final URI uri = new URI(callback);
|
||||||
assert this.validSchemes.contains(uri.getScheme()) : "Not a valid protocol " + uri.getScheme();
|
assert validSchemes.contains(uri.getScheme()) : "Not a valid protocol " + uri.getScheme();
|
||||||
assert this.validPorts.isEmpty() || this.validPorts.contains(uri.getPort()) : "Not a valid port " +
|
assert validPorts.isEmpty() || validPorts.contains(uri.getPort()) : "Not a valid port " + uri.getPort();
|
||||||
uri.getPort();
|
assert validTopics.isEmpty() || validTopics.contains(topic) : "Not a supported topic " + topic;
|
||||||
assert this.validTopics.isEmpty() || this.validTopics.contains(topic) : "Not a supported topic " +
|
} catch (final URISyntaxException ex) {
|
||||||
topic;
|
|
||||||
} catch (URISyntaxException ex) {
|
|
||||||
assert false : "Not a valid URI " + callback;
|
assert false : "Not a valid URI " + callback;
|
||||||
}
|
}
|
||||||
assert (verify != null) &&
|
assert verify != null && (verify.equals(Subscriber.VERIFY_ASYNC) || verify.equals(Subscriber.VERIFY_SYNC)) : "Unexpected verify value " + verify;
|
||||||
(verify.equals(Subscriber.VERIFY_ASYNC) || verify.equals(Subscriber.VERIFY_SYNC)) : "Unexpected verify value " +
|
|
||||||
verify;
|
|
||||||
|
|
||||||
final Subscriber subscriber = new Subscriber();
|
final Subscriber subscriber = new Subscriber();
|
||||||
subscriber.setCallback(callback);
|
subscriber.setCallback(callback);
|
||||||
|
@ -199,18 +185,19 @@ public class Hub {
|
||||||
subscriber.setVerify(verify);
|
subscriber.setVerify(verify);
|
||||||
subscriber.setVertifyToken(verify_token);
|
subscriber.setVertifyToken(verify_token);
|
||||||
|
|
||||||
VerificationCallback verified = new VerificationCallback() {
|
final VerificationCallback verified = new VerificationCallback() {
|
||||||
@Override
|
@Override
|
||||||
public void onVerify(boolean verified) {
|
public void onVerify(final boolean verified) {
|
||||||
if (verified) {
|
if (verified) {
|
||||||
Logger.getLogger(Hub.class.getName()).log(Level.FINE, "Verified {0} subscribed to {1}", new Object[]{subscriber.getCallback(), subscriber.getTopic()});
|
Logger.getLogger(Hub.class.getName()).log(Level.FINE, "Verified {0} subscribed to {1}",
|
||||||
dao.addSubscriber(subscriber);
|
new Object[] { subscriber.getCallback(), subscriber.getTopic() });
|
||||||
}
|
dao.addSubscriber(subscriber);
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
};
|
||||||
|
|
||||||
if (Subscriber.VERIFY_SYNC.equals(subscriber.getVerify())) {
|
if (Subscriber.VERIFY_SYNC.equals(subscriber.getVerify())) {
|
||||||
boolean result = verifier.verifySubcribeSyncronously(subscriber);
|
final boolean result = verifier.verifySubcribeSyncronously(subscriber);
|
||||||
verified.onVerify(result);
|
verified.onVerify(result);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
@ -219,33 +206,34 @@ public class Hub {
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
} catch (AssertionError ae) {
|
} catch (final AssertionError ae) {
|
||||||
throw new HttpStatusCodeException(400, ae.getMessage(), ae);
|
throw new HttpStatusCodeException(400, ae.getMessage(), ae);
|
||||||
} catch (Exception e) {
|
} catch (final Exception e) {
|
||||||
throw new HttpStatusCodeException(500, e.getMessage(), e);
|
throw new HttpStatusCodeException(500, e.getMessage(), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Boolean unsubscribe(final String callback, final String topic, String verify, String secret, String verifyToken) {
|
public Boolean unsubscribe(final String callback, final String topic, final String verify, final String secret, final String verifyToken) {
|
||||||
final Subscriber subscriber = dao.findSubscriber(topic, callback);
|
final Subscriber subscriber = dao.findSubscriber(topic, callback);
|
||||||
if(subscriber == null){
|
if (subscriber == null) {
|
||||||
throw new HttpStatusCodeException(400, "Not a valid subscription.", null);
|
throw new HttpStatusCodeException(400, "Not a valid subscription.", null);
|
||||||
}
|
}
|
||||||
subscriber.setVertifyToken(verifyToken);
|
subscriber.setVertifyToken(verifyToken);
|
||||||
subscriber.setSecret(secret);
|
subscriber.setSecret(secret);
|
||||||
if(Subscriber.VERIFY_SYNC.equals(verify)){
|
if (Subscriber.VERIFY_SYNC.equals(verify)) {
|
||||||
|
|
||||||
boolean ret = verifier.verifyUnsubcribeSyncronously(subscriber);
|
final boolean ret = verifier.verifyUnsubcribeSyncronously(subscriber);
|
||||||
if(ret){
|
if (ret) {
|
||||||
dao.removeSubscriber(topic, callback);
|
dao.removeSubscriber(topic, callback);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
verifier.verifyUnsubscribeAsyncronously(subscriber, new VerificationCallback(){
|
verifier.verifyUnsubscribeAsyncronously(subscriber, new VerificationCallback() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onVerify(boolean verified) {
|
public void onVerify(final boolean verified) {
|
||||||
Logger.getLogger(Hub.class.getName()).log(Level.FINE, "Unsubscribe for {0} at {1} verified {2}", new Object[]{subscriber.getTopic(), subscriber.getCallback(), verified});
|
Logger.getLogger(Hub.class.getName()).log(Level.FINE, "Unsubscribe for {0} at {1} verified {2}",
|
||||||
if(verified){
|
new Object[] { subscriber.getTopic(), subscriber.getCallback(), verified });
|
||||||
|
if (verified) {
|
||||||
dao.removeSubscriber(topic, callback);
|
dao.removeSubscriber(topic, callback);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,13 +18,12 @@
|
||||||
|
|
||||||
package org.rometools.certiorem.hub;
|
package org.rometools.certiorem.hub;
|
||||||
|
|
||||||
import com.sun.syndication.feed.synd.SyndFeed;
|
import java.util.List;
|
||||||
|
|
||||||
import org.rometools.certiorem.hub.data.Subscriber;
|
import org.rometools.certiorem.hub.data.Subscriber;
|
||||||
import org.rometools.certiorem.hub.data.SubscriptionSummary;
|
import org.rometools.certiorem.hub.data.SubscriptionSummary;
|
||||||
|
|
||||||
import java.util.List;
|
import com.sun.syndication.feed.synd.SyndFeed;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -41,7 +40,7 @@ public interface Notifier {
|
||||||
public void notifySubscribers(List<Subscriber> subscribers, SyndFeed value, SubscriptionSummaryCallback callback);
|
public void notifySubscribers(List<Subscriber> subscribers, SyndFeed value, SubscriptionSummaryCallback callback);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A callback that is invoked each time a subscriber is notified.
|
* A callback that is invoked each time a subscriber is notified.
|
||||||
*/
|
*/
|
||||||
public static interface SubscriptionSummaryCallback {
|
public static interface SubscriptionSummaryCallback {
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -20,9 +20,9 @@ package org.rometools.certiorem.hub;
|
||||||
|
|
||||||
import org.rometools.certiorem.hub.data.Subscriber;
|
import org.rometools.certiorem.hub.data.Subscriber;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A strategy interface for verification of subscriptions.
|
* A strategy interface for verification of subscriptions.
|
||||||
|
*
|
||||||
* @author robert.cooper
|
* @author robert.cooper
|
||||||
*/
|
*/
|
||||||
public interface Verifier {
|
public interface Verifier {
|
||||||
|
@ -38,6 +38,7 @@ public interface Verifier {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verifies a subscriber (possibly) asyncronously
|
* Verifies a subscriber (possibly) asyncronously
|
||||||
|
*
|
||||||
* @param subscriber the Subscriber to verify
|
* @param subscriber the Subscriber to verify
|
||||||
* @param callback a callback with the result of the verification.
|
* @param callback a callback with the result of the verification.
|
||||||
*/
|
*/
|
||||||
|
@ -45,26 +46,28 @@ public interface Verifier {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verifies a subscriber syncronously
|
* Verifies a subscriber syncronously
|
||||||
* @param subscriber The subscriber data
|
*
|
||||||
|
* @param subscriber The subscriber data
|
||||||
* @return boolean result;
|
* @return boolean result;
|
||||||
*/
|
*/
|
||||||
public boolean verifySubcribeSyncronously(Subscriber subscriber);
|
public boolean verifySubcribeSyncronously(Subscriber subscriber);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verifies am unsubscribe (possibly) asyncronously
|
* Verifies am unsubscribe (possibly) asyncronously
|
||||||
|
*
|
||||||
* @param subscriber The subscriber data
|
* @param subscriber The subscriber data
|
||||||
* @param callback result
|
* @param callback result
|
||||||
*/
|
*/
|
||||||
public void verifyUnsubscribeAsyncronously(Subscriber subscriber, VerificationCallback callback);
|
public void verifyUnsubscribeAsyncronously(Subscriber subscriber, VerificationCallback callback);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verifies an unsubscribe syncronously
|
* Verifies an unsubscribe syncronously
|
||||||
* @param subscriber The subscriber data
|
*
|
||||||
|
* @param subscriber The subscriber data
|
||||||
* @return boolean result;
|
* @return boolean result;
|
||||||
*/
|
*/
|
||||||
public boolean verifyUnsubcribeSyncronously(Subscriber subscriber);
|
public boolean verifyUnsubcribeSyncronously(Subscriber subscriber);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An interface for capturing the result of a verification (subscribe or unsubscribe)
|
* An interface for capturing the result of a verification (subscribe or unsubscribe)
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -16,7 +16,6 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
package org.rometools.certiorem.hub.data;
|
package org.rometools.certiorem.hub.data;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
|
@ -20,7 +20,6 @@ package org.rometools.certiorem.hub.data;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author robert.cooper
|
* @author robert.cooper
|
||||||
|
@ -41,8 +40,8 @@ public class Subscriber implements Serializable {
|
||||||
*
|
*
|
||||||
* @param newcallback new value of callback
|
* @param newcallback new value of callback
|
||||||
*/
|
*/
|
||||||
public void setCallback(String newcallback) {
|
public void setCallback(final String newcallback) {
|
||||||
this.callback = newcallback;
|
callback = newcallback;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -51,7 +50,7 @@ public class Subscriber implements Serializable {
|
||||||
* @return the value of callback
|
* @return the value of callback
|
||||||
*/
|
*/
|
||||||
public String getCallback() {
|
public String getCallback() {
|
||||||
return this.callback;
|
return callback;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -59,8 +58,8 @@ public class Subscriber implements Serializable {
|
||||||
*
|
*
|
||||||
* @param newcreationTime new value of creationTime
|
* @param newcreationTime new value of creationTime
|
||||||
*/
|
*/
|
||||||
public void setCreationTime(long newcreationTime) {
|
public void setCreationTime(final long newcreationTime) {
|
||||||
this.creationTime = newcreationTime;
|
creationTime = newcreationTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -69,7 +68,7 @@ public class Subscriber implements Serializable {
|
||||||
* @return the value of creationTime
|
* @return the value of creationTime
|
||||||
*/
|
*/
|
||||||
public long getCreationTime() {
|
public long getCreationTime() {
|
||||||
return this.creationTime;
|
return creationTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -77,8 +76,8 @@ public class Subscriber implements Serializable {
|
||||||
*
|
*
|
||||||
* @param newleaseSeconds new value of leaseSeconds
|
* @param newleaseSeconds new value of leaseSeconds
|
||||||
*/
|
*/
|
||||||
public void setLeaseSeconds(long newleaseSeconds) {
|
public void setLeaseSeconds(final long newleaseSeconds) {
|
||||||
this.leaseSeconds = newleaseSeconds;
|
leaseSeconds = newleaseSeconds;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -87,7 +86,7 @@ public class Subscriber implements Serializable {
|
||||||
* @return the value of leaseSeconds
|
* @return the value of leaseSeconds
|
||||||
*/
|
*/
|
||||||
public long getLeaseSeconds() {
|
public long getLeaseSeconds() {
|
||||||
return this.leaseSeconds;
|
return leaseSeconds;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -95,8 +94,8 @@ public class Subscriber implements Serializable {
|
||||||
*
|
*
|
||||||
* @param newsecret new value of secret
|
* @param newsecret new value of secret
|
||||||
*/
|
*/
|
||||||
public void setSecret(String newsecret) {
|
public void setSecret(final String newsecret) {
|
||||||
this.secret = newsecret;
|
secret = newsecret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -105,7 +104,7 @@ public class Subscriber implements Serializable {
|
||||||
* @return the value of secret
|
* @return the value of secret
|
||||||
*/
|
*/
|
||||||
public String getSecret() {
|
public String getSecret() {
|
||||||
return this.secret;
|
return secret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -113,8 +112,8 @@ public class Subscriber implements Serializable {
|
||||||
*
|
*
|
||||||
* @param newtopic new value of topic
|
* @param newtopic new value of topic
|
||||||
*/
|
*/
|
||||||
public void setTopic(String newtopic) {
|
public void setTopic(final String newtopic) {
|
||||||
this.topic = newtopic;
|
topic = newtopic;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -123,7 +122,7 @@ public class Subscriber implements Serializable {
|
||||||
* @return the value of topic
|
* @return the value of topic
|
||||||
*/
|
*/
|
||||||
public String getTopic() {
|
public String getTopic() {
|
||||||
return this.topic;
|
return topic;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -131,8 +130,8 @@ public class Subscriber implements Serializable {
|
||||||
*
|
*
|
||||||
* @param newverify new value of verify
|
* @param newverify new value of verify
|
||||||
*/
|
*/
|
||||||
public void setVerify(String newverify) {
|
public void setVerify(final String newverify) {
|
||||||
this.verify = newverify;
|
verify = newverify;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -141,7 +140,7 @@ public class Subscriber implements Serializable {
|
||||||
* @return the value of verify
|
* @return the value of verify
|
||||||
*/
|
*/
|
||||||
public String getVerify() {
|
public String getVerify() {
|
||||||
return this.verify;
|
return verify;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -149,8 +148,8 @@ public class Subscriber implements Serializable {
|
||||||
*
|
*
|
||||||
* @param newvertifyToken new value of vertifyToken
|
* @param newvertifyToken new value of vertifyToken
|
||||||
*/
|
*/
|
||||||
public void setVertifyToken(String newvertifyToken) {
|
public void setVertifyToken(final String newvertifyToken) {
|
||||||
this.vertifyToken = newvertifyToken;
|
vertifyToken = newvertifyToken;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -159,11 +158,11 @@ public class Subscriber implements Serializable {
|
||||||
* @return the value of vertifyToken
|
* @return the value of vertifyToken
|
||||||
*/
|
*/
|
||||||
public String getVertifyToken() {
|
public String getVertifyToken() {
|
||||||
return this.vertifyToken;
|
return vertifyToken;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object obj) {
|
public boolean equals(final Object obj) {
|
||||||
if (obj == null) {
|
if (obj == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -174,31 +173,31 @@ public class Subscriber implements Serializable {
|
||||||
|
|
||||||
final Subscriber other = (Subscriber) obj;
|
final Subscriber other = (Subscriber) obj;
|
||||||
|
|
||||||
if ((this.callback == null) ? (other.callback != null) : (!this.callback.equals(other.callback))) {
|
if (callback == null ? other.callback != null : !callback.equals(other.callback)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((this.secret == null) ? (other.secret != null) : (!this.secret.equals(other.secret))) {
|
if (secret == null ? other.secret != null : !secret.equals(other.secret)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((this.topic == null) ? (other.topic != null) : (!this.topic.equals(other.topic))) {
|
if (topic == null ? other.topic != null : !topic.equals(other.topic)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((this.verify == null) ? (other.verify != null) : (!this.verify.equals(other.verify))) {
|
if (verify == null ? other.verify != null : !verify.equals(other.verify)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((this.vertifyToken == null) ? (other.vertifyToken != null) : (!this.vertifyToken.equals(other.vertifyToken))) {
|
if (vertifyToken == null ? other.vertifyToken != null : !vertifyToken.equals(other.vertifyToken)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.creationTime != other.creationTime) {
|
if (creationTime != other.creationTime) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.leaseSeconds != other.leaseSeconds) {
|
if (leaseSeconds != other.leaseSeconds) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -208,13 +207,13 @@ public class Subscriber implements Serializable {
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
int hash = 7;
|
int hash = 7;
|
||||||
hash = (67 * hash) + ((this.callback != null) ? this.callback.hashCode() : 0);
|
hash = 67 * hash + (callback != null ? callback.hashCode() : 0);
|
||||||
hash = (67 * hash) + ((this.secret != null) ? this.secret.hashCode() : 0);
|
hash = 67 * hash + (secret != null ? secret.hashCode() : 0);
|
||||||
hash = (67 * hash) + ((this.topic != null) ? this.topic.hashCode() : 0);
|
hash = 67 * hash + (topic != null ? topic.hashCode() : 0);
|
||||||
hash = (67 * hash) + ((this.verify != null) ? this.verify.hashCode() : 0);
|
hash = 67 * hash + (verify != null ? verify.hashCode() : 0);
|
||||||
hash = (67 * hash) + ((this.vertifyToken != null) ? this.vertifyToken.hashCode() : 0);
|
hash = 67 * hash + (vertifyToken != null ? vertifyToken.hashCode() : 0);
|
||||||
hash = (67 * hash) + (int) (this.creationTime ^ (this.creationTime >>> 32));
|
hash = 67 * hash + (int) (creationTime ^ creationTime >>> 32);
|
||||||
hash = (67 * hash) + (int) (this.leaseSeconds ^ (this.leaseSeconds >>> 32));
|
hash = 67 * hash + (int) (leaseSeconds ^ leaseSeconds >>> 32);
|
||||||
|
|
||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,6 @@ package org.rometools.certiorem.hub.data;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author robert.cooper
|
* @author robert.cooper
|
||||||
|
@ -35,8 +34,8 @@ public class SubscriptionSummary implements Serializable {
|
||||||
*
|
*
|
||||||
* @param newhost new value of host
|
* @param newhost new value of host
|
||||||
*/
|
*/
|
||||||
public void setHost(String newhost) {
|
public void setHost(final String newhost) {
|
||||||
this.host = newhost;
|
host = newhost;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -45,7 +44,7 @@ public class SubscriptionSummary implements Serializable {
|
||||||
* @return the value of host
|
* @return the value of host
|
||||||
*/
|
*/
|
||||||
public String getHost() {
|
public String getHost() {
|
||||||
return this.host;
|
return host;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -53,8 +52,8 @@ public class SubscriptionSummary implements Serializable {
|
||||||
*
|
*
|
||||||
* @param newlastPublishSuccessful new value of lastPublishSuccessful
|
* @param newlastPublishSuccessful new value of lastPublishSuccessful
|
||||||
*/
|
*/
|
||||||
public void setLastPublishSuccessful(boolean newlastPublishSuccessful) {
|
public void setLastPublishSuccessful(final boolean newlastPublishSuccessful) {
|
||||||
this.lastPublishSuccessful = newlastPublishSuccessful;
|
lastPublishSuccessful = newlastPublishSuccessful;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -63,7 +62,7 @@ public class SubscriptionSummary implements Serializable {
|
||||||
* @return the value of lastPublishSuccessful
|
* @return the value of lastPublishSuccessful
|
||||||
*/
|
*/
|
||||||
public boolean isLastPublishSuccessful() {
|
public boolean isLastPublishSuccessful() {
|
||||||
return this.lastPublishSuccessful;
|
return lastPublishSuccessful;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -71,8 +70,8 @@ public class SubscriptionSummary implements Serializable {
|
||||||
*
|
*
|
||||||
* @param newsubscribers new value of subscribers
|
* @param newsubscribers new value of subscribers
|
||||||
*/
|
*/
|
||||||
public void setSubscribers(int newsubscribers) {
|
public void setSubscribers(final int newsubscribers) {
|
||||||
this.subscribers = newsubscribers;
|
subscribers = newsubscribers;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -81,6 +80,6 @@ public class SubscriptionSummary implements Serializable {
|
||||||
* @return the value of subscribers
|
* @return the value of subscribers
|
||||||
*/
|
*/
|
||||||
public int getSubscribers() {
|
public int getSubscribers() {
|
||||||
return this.subscribers;
|
return subscribers;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,12 +16,8 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
package org.rometools.certiorem.hub.data.jpa;
|
package org.rometools.certiorem.hub.data.jpa;
|
||||||
|
|
||||||
import org.rometools.certiorem.hub.data.HubDAO;
|
|
||||||
import org.rometools.certiorem.hub.data.Subscriber;
|
|
||||||
|
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
@ -31,6 +27,9 @@ import javax.persistence.EntityManagerFactory;
|
||||||
import javax.persistence.EntityTransaction;
|
import javax.persistence.EntityTransaction;
|
||||||
import javax.persistence.NoResultException;
|
import javax.persistence.NoResultException;
|
||||||
import javax.persistence.Query;
|
import javax.persistence.Query;
|
||||||
|
|
||||||
|
import org.rometools.certiorem.hub.data.HubDAO;
|
||||||
|
import org.rometools.certiorem.hub.data.Subscriber;
|
||||||
import org.rometools.certiorem.hub.data.SubscriptionSummary;
|
import org.rometools.certiorem.hub.data.SubscriptionSummary;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -48,41 +47,39 @@ public class JPADAO implements HubDAO {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<? extends Subscriber> subscribersForTopic(String topic) {
|
public List<? extends Subscriber> subscribersForTopic(final String topic) {
|
||||||
LinkedList<JPASubscriber> result = new LinkedList<JPASubscriber>();
|
final LinkedList<JPASubscriber> result = new LinkedList<JPASubscriber>();
|
||||||
EntityManager em = factory.createEntityManager();
|
final EntityManager em = factory.createEntityManager();
|
||||||
EntityTransaction tx = em.getTransaction();
|
final EntityTransaction tx = em.getTransaction();
|
||||||
tx.begin();
|
tx.begin();
|
||||||
|
|
||||||
Query query = em.createNamedQuery("Subcriber.forTopic");
|
final Query query = em.createNamedQuery("Subcriber.forTopic");
|
||||||
query.setParameter("topic", topic);
|
query.setParameter("topic", topic);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
for (JPASubscriber subscriber : (List<JPASubscriber>) query.getResultList()) {
|
for (final JPASubscriber subscriber : (List<JPASubscriber>) query.getResultList()) {
|
||||||
if (subscriber.getLeaseSeconds() == -1) {
|
if (subscriber.getLeaseSeconds() == -1) {
|
||||||
result.add(subscriber);
|
result.add(subscriber);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (subscriber.getSubscribedAt().getTime() < (System.currentTimeMillis() - (1000 * subscriber.getLeaseSeconds()))) {
|
if (subscriber.getSubscribedAt().getTime() < System.currentTimeMillis() - 1000 * subscriber.getLeaseSeconds()) {
|
||||||
subscriber.setExpired(true);
|
subscriber.setExpired(true);
|
||||||
} else {
|
} else {
|
||||||
result.add(subscriber);
|
result.add(subscriber);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (subscriber.isExpired() && this.purgeExpired) {
|
if (subscriber.isExpired() && purgeExpired) {
|
||||||
em.remove(subscriber);
|
em.remove(subscriber);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (NoResultException e) {
|
} catch (final NoResultException e) {
|
||||||
tx.rollback();
|
tx.rollback();
|
||||||
em.close();
|
em.close();
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (!tx.getRollbackOnly()) {
|
if (!tx.getRollbackOnly()) {
|
||||||
tx.commit();
|
tx.commit();
|
||||||
} else {
|
} else {
|
||||||
|
@ -95,12 +92,12 @@ public class JPADAO implements HubDAO {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Subscriber addSubscriber(Subscriber subscriber) {
|
public Subscriber addSubscriber(final Subscriber subscriber) {
|
||||||
assert subscriber != null : "Attempt to store a null subscriber";
|
assert subscriber != null : "Attempt to store a null subscriber";
|
||||||
EntityManager em = factory.createEntityManager();
|
final EntityManager em = factory.createEntityManager();
|
||||||
EntityTransaction tx = em.getTransaction();
|
final EntityTransaction tx = em.getTransaction();
|
||||||
tx.begin();
|
tx.begin();
|
||||||
JPASubscriber data = new JPASubscriber();
|
final JPASubscriber data = new JPASubscriber();
|
||||||
data.copyFrom(subscriber);
|
data.copyFrom(subscriber);
|
||||||
data.setId(UUID.randomUUID().toString());
|
data.setId(UUID.randomUUID().toString());
|
||||||
em.persist(data);
|
em.persist(data);
|
||||||
|
@ -110,22 +107,22 @@ public class JPADAO implements HubDAO {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Subscriber findSubscriber(String topic, String callbackUrl) {
|
public Subscriber findSubscriber(final String topic, final String callbackUrl) {
|
||||||
throw new UnsupportedOperationException("Not supported yet.");
|
throw new UnsupportedOperationException("Not supported yet.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void handleSummary(String topic, SubscriptionSummary summary) {
|
public void handleSummary(final String topic, final SubscriptionSummary summary) {
|
||||||
throw new UnsupportedOperationException("Not supported yet.");
|
throw new UnsupportedOperationException("Not supported yet.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<? extends SubscriptionSummary> summariesForTopic(String topic) {
|
public List<? extends SubscriptionSummary> summariesForTopic(final String topic) {
|
||||||
throw new UnsupportedOperationException("Not supported yet.");
|
throw new UnsupportedOperationException("Not supported yet.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void removeSubscriber(String topic, String callback) {
|
public void removeSubscriber(final String topic, final String callback) {
|
||||||
throw new UnsupportedOperationException("Not supported yet.");
|
throw new UnsupportedOperationException("Not supported yet.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,13 +16,9 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
package org.rometools.certiorem.hub.data.jpa;
|
package org.rometools.certiorem.hub.data.jpa;
|
||||||
|
|
||||||
import org.rometools.certiorem.hub.data.Subscriber;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
import javax.persistence.Entity;
|
import javax.persistence.Entity;
|
||||||
|
@ -32,14 +28,14 @@ import javax.persistence.NamedQuery;
|
||||||
import javax.persistence.Temporal;
|
import javax.persistence.Temporal;
|
||||||
import javax.persistence.TemporalType;
|
import javax.persistence.TemporalType;
|
||||||
|
|
||||||
|
import org.rometools.certiorem.hub.data.Subscriber;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author robert.cooper
|
* @author robert.cooper
|
||||||
*/
|
*/
|
||||||
@Entity
|
@Entity
|
||||||
@NamedQueries({@NamedQuery(name = "Subcriber.forTopic", query = "SELECT o FROM JPASubscriber o WHERE o.topic = :topic AND o.expired = false ORDER BY o.subscribedAt")
|
@NamedQueries({ @NamedQuery(name = "Subcriber.forTopic", query = "SELECT o FROM JPASubscriber o WHERE o.topic = :topic AND o.expired = false ORDER BY o.subscribedAt") })
|
||||||
})
|
|
||||||
public class JPASubscriber extends Subscriber implements Serializable {
|
public class JPASubscriber extends Subscriber implements Serializable {
|
||||||
private Date subscribedAt = new Date();
|
private Date subscribedAt = new Date();
|
||||||
private String id;
|
private String id;
|
||||||
|
@ -50,8 +46,8 @@ public class JPASubscriber extends Subscriber implements Serializable {
|
||||||
*
|
*
|
||||||
* @param newexpired new value of expired
|
* @param newexpired new value of expired
|
||||||
*/
|
*/
|
||||||
public void setExpired(boolean newexpired) {
|
public void setExpired(final boolean newexpired) {
|
||||||
this.expired = newexpired;
|
expired = newexpired;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -60,7 +56,7 @@ public class JPASubscriber extends Subscriber implements Serializable {
|
||||||
* @return the value of expired
|
* @return the value of expired
|
||||||
*/
|
*/
|
||||||
public boolean isExpired() {
|
public boolean isExpired() {
|
||||||
return this.expired;
|
return expired;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -68,8 +64,8 @@ public class JPASubscriber extends Subscriber implements Serializable {
|
||||||
*
|
*
|
||||||
* @param newid new value of id
|
* @param newid new value of id
|
||||||
*/
|
*/
|
||||||
public void setId(String newid) {
|
public void setId(final String newid) {
|
||||||
this.id = newid;
|
id = newid;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -79,7 +75,7 @@ public class JPASubscriber extends Subscriber implements Serializable {
|
||||||
*/
|
*/
|
||||||
@Id
|
@Id
|
||||||
public String getId() {
|
public String getId() {
|
||||||
return this.id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -87,8 +83,8 @@ public class JPASubscriber extends Subscriber implements Serializable {
|
||||||
*
|
*
|
||||||
* @param newsubscribedAt new value of subscribedAt
|
* @param newsubscribedAt new value of subscribedAt
|
||||||
*/
|
*/
|
||||||
public void setSubscribedAt(Date newsubscribedAt) {
|
public void setSubscribedAt(final Date newsubscribedAt) {
|
||||||
this.subscribedAt = newsubscribedAt;
|
subscribedAt = newsubscribedAt;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -98,14 +94,14 @@ public class JPASubscriber extends Subscriber implements Serializable {
|
||||||
*/
|
*/
|
||||||
@Temporal(TemporalType.TIMESTAMP)
|
@Temporal(TemporalType.TIMESTAMP)
|
||||||
public Date getSubscribedAt() {
|
public Date getSubscribedAt() {
|
||||||
return this.subscribedAt;
|
return subscribedAt;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void copyFrom(Subscriber source) {
|
public void copyFrom(final Subscriber source) {
|
||||||
this.setLeaseSeconds(source.getLeaseSeconds());
|
setLeaseSeconds(source.getLeaseSeconds());
|
||||||
this.setSecret(source.getSecret());
|
setSecret(source.getSecret());
|
||||||
this.setTopic(source.getTopic());
|
setTopic(source.getTopic());
|
||||||
this.setVerify(source.getVerify());
|
setVerify(source.getVerify());
|
||||||
this.setVertifyToken(source.getVertifyToken());
|
setVertifyToken(source.getVertifyToken());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,16 +18,15 @@
|
||||||
|
|
||||||
package org.rometools.certiorem.hub.data.ram;
|
package org.rometools.certiorem.hub.data.ram;
|
||||||
|
|
||||||
import org.rometools.certiorem.hub.data.HubDAO;
|
|
||||||
import org.rometools.certiorem.hub.data.Subscriber;
|
|
||||||
import org.rometools.certiorem.hub.data.SubscriptionSummary;
|
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.concurrent.CopyOnWriteArrayList;
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
|
|
||||||
|
import org.rometools.certiorem.hub.data.HubDAO;
|
||||||
|
import org.rometools.certiorem.hub.data.Subscriber;
|
||||||
|
import org.rometools.certiorem.hub.data.SubscriptionSummary;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A Simple In-Memory HubDAO for subscribers.
|
* A Simple In-Memory HubDAO for subscribers.
|
||||||
|
@ -35,19 +34,19 @@ import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
* @author robert.cooper
|
* @author robert.cooper
|
||||||
*/
|
*/
|
||||||
public class InMemoryHubDAO implements HubDAO {
|
public class InMemoryHubDAO implements HubDAO {
|
||||||
private ConcurrentHashMap<String, List<Subscriber>> subscribers = new ConcurrentHashMap<String, List<Subscriber>>();
|
private final ConcurrentHashMap<String, List<Subscriber>> subscribers = new ConcurrentHashMap<String, List<Subscriber>>();
|
||||||
private ConcurrentHashMap<String, ConcurrentHashMap<String, SubscriptionSummary>> summaries = new ConcurrentHashMap<String, ConcurrentHashMap<String, SubscriptionSummary>>();
|
private final ConcurrentHashMap<String, ConcurrentHashMap<String, SubscriptionSummary>> summaries = new ConcurrentHashMap<String, ConcurrentHashMap<String, SubscriptionSummary>>();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Subscriber addSubscriber(Subscriber subscriber) {
|
public Subscriber addSubscriber(final Subscriber subscriber) {
|
||||||
assert subscriber != null : "Attempt to store a null subscriber";
|
assert subscriber != null : "Attempt to store a null subscriber";
|
||||||
|
|
||||||
List<Subscriber> subList = this.subscribers.get(subscriber.getTopic());
|
List<Subscriber> subList = subscribers.get(subscriber.getTopic());
|
||||||
|
|
||||||
if (subList == null) {
|
if (subList == null) {
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
subList = new CopyOnWriteArrayList<Subscriber>();
|
subList = new CopyOnWriteArrayList<Subscriber>();
|
||||||
this.subscribers.put(subscriber.getTopic(), subList);
|
subscribers.put(subscriber.getTopic(), subList);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,13 +56,13 @@ public class InMemoryHubDAO implements HubDAO {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void handleSummary(String topic, SubscriptionSummary summary) {
|
public void handleSummary(final String topic, final SubscriptionSummary summary) {
|
||||||
ConcurrentHashMap<String, SubscriptionSummary> hostsToSummaries = this.summaries.get(topic);
|
ConcurrentHashMap<String, SubscriptionSummary> hostsToSummaries = summaries.get(topic);
|
||||||
|
|
||||||
if (hostsToSummaries == null) {
|
if (hostsToSummaries == null) {
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
hostsToSummaries = new ConcurrentHashMap<String, SubscriptionSummary>();
|
hostsToSummaries = new ConcurrentHashMap<String, SubscriptionSummary>();
|
||||||
this.summaries.put(topic, hostsToSummaries);
|
summaries.put(topic, hostsToSummaries);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,14 +70,13 @@ public class InMemoryHubDAO implements HubDAO {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<?extends Subscriber> subscribersForTopic(String topic) {
|
public List<? extends Subscriber> subscribersForTopic(final String topic) {
|
||||||
if (subscribers.containsKey(topic)) {
|
if (subscribers.containsKey(topic)) {
|
||||||
List<Subscriber> result = new LinkedList<Subscriber>();
|
final List<Subscriber> result = new LinkedList<Subscriber>();
|
||||||
LinkedList<Subscriber> expired = new LinkedList<Subscriber>();
|
final LinkedList<Subscriber> expired = new LinkedList<Subscriber>();
|
||||||
|
|
||||||
for (Subscriber s : subscribers.get(topic)) {
|
for (final Subscriber s : subscribers.get(topic)) {
|
||||||
if ((s.getLeaseSeconds() > 0) &&
|
if (s.getLeaseSeconds() > 0 && System.currentTimeMillis() >= s.getCreationTime() + s.getLeaseSeconds() * 1000L) {
|
||||||
(System.currentTimeMillis() >= (s.getCreationTime() + (s.getLeaseSeconds() * 1000L)))) {
|
|
||||||
expired.add(s);
|
expired.add(s);
|
||||||
} else {
|
} else {
|
||||||
result.add(s);
|
result.add(s);
|
||||||
|
@ -86,8 +84,7 @@ public class InMemoryHubDAO implements HubDAO {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!expired.isEmpty()) {
|
if (!expired.isEmpty()) {
|
||||||
subscribers.get(topic)
|
subscribers.get(topic).removeAll(expired);
|
||||||
.removeAll(expired);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
@ -97,41 +94,41 @@ public class InMemoryHubDAO implements HubDAO {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<?extends SubscriptionSummary> summariesForTopic(String topic) {
|
public List<? extends SubscriptionSummary> summariesForTopic(final String topic) {
|
||||||
LinkedList<SubscriptionSummary> result = new LinkedList<SubscriptionSummary>();
|
final LinkedList<SubscriptionSummary> result = new LinkedList<SubscriptionSummary>();
|
||||||
|
|
||||||
if (this.summaries.containsKey(topic)) {
|
if (summaries.containsKey(topic)) {
|
||||||
result.addAll(this.summaries.get(topic).values());
|
result.addAll(summaries.get(topic).values());
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Subscriber findSubscriber(String topic, String callbackUrl) {
|
public Subscriber findSubscriber(final String topic, final String callbackUrl) {
|
||||||
|
|
||||||
for (Subscriber s : this.subscribersForTopic(topic)) {
|
for (final Subscriber s : subscribersForTopic(topic)) {
|
||||||
if (callbackUrl.equals(s.getCallback())) {
|
if (callbackUrl.equals(s.getCallback())) {
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void removeSubscriber(String topic, String callback) {
|
public void removeSubscriber(final String topic, final String callback) {
|
||||||
List<Subscriber> subs = this.subscribers.get(topic);
|
final List<Subscriber> subs = subscribers.get(topic);
|
||||||
if(subs == null){
|
if (subs == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Subscriber match = null;
|
Subscriber match = null;
|
||||||
for(Subscriber s: subs){
|
for (final Subscriber s : subs) {
|
||||||
if(s.getCallback().equals(callback)){
|
if (s.getCallback().equals(callback)) {
|
||||||
match = s;
|
match = s;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(match != null){
|
if (match != null) {
|
||||||
subs.remove(match);
|
subs.remove(match);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,31 +16,26 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
package org.rometools.certiorem.hub.notify.standard;
|
package org.rometools.certiorem.hub.notify.standard;
|
||||||
|
|
||||||
import com.sun.syndication.feed.synd.SyndFeed;
|
|
||||||
import com.sun.syndication.io.FeedException;
|
|
||||||
import com.sun.syndication.io.SyndFeedOutput;
|
|
||||||
|
|
||||||
import org.rometools.certiorem.hub.Notifier;
|
|
||||||
import org.rometools.certiorem.hub.data.Subscriber;
|
|
||||||
import org.rometools.certiorem.hub.data.SubscriptionSummary;
|
|
||||||
|
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.io.OutputStreamWriter;
|
import java.io.OutputStreamWriter;
|
||||||
|
|
||||||
import java.net.HttpURLConnection;
|
import java.net.HttpURLConnection;
|
||||||
import java.net.MalformedURLException;
|
import java.net.MalformedURLException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
import org.rometools.certiorem.sub.data.ram.InMemorySubDAO;
|
|
||||||
|
|
||||||
|
import org.rometools.certiorem.hub.Notifier;
|
||||||
|
import org.rometools.certiorem.hub.data.Subscriber;
|
||||||
|
import org.rometools.certiorem.hub.data.SubscriptionSummary;
|
||||||
|
|
||||||
|
import com.sun.syndication.feed.synd.SyndFeed;
|
||||||
|
import com.sun.syndication.io.FeedException;
|
||||||
|
import com.sun.syndication.io.SyndFeedOutput;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -48,9 +43,9 @@ import org.rometools.certiorem.sub.data.ram.InMemorySubDAO;
|
||||||
*/
|
*/
|
||||||
public abstract class AbstractNotifier implements Notifier {
|
public abstract class AbstractNotifier implements Notifier {
|
||||||
/**
|
/**
|
||||||
* This method will serialize the synd feed and build Notifications for the
|
* This method will serialize the synd feed and build Notifications for the implementation class to handle.
|
||||||
* implementation class to handle.
|
*
|
||||||
* @see enqueueNotification
|
* @see enqueueNotification
|
||||||
*
|
*
|
||||||
* @param subscribers List of subscribers to notify
|
* @param subscribers List of subscribers to notify
|
||||||
* @param value The SyndFeed object to send
|
* @param value The SyndFeed object to send
|
||||||
|
@ -58,110 +53,103 @@ public abstract class AbstractNotifier implements Notifier {
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void notifySubscribers(List<Subscriber> subscribers, SyndFeed value, SubscriptionSummaryCallback callback) {
|
public void notifySubscribers(final List<Subscriber> subscribers, final SyndFeed value, final SubscriptionSummaryCallback callback) {
|
||||||
String mimeType = null;
|
String mimeType = null;
|
||||||
|
|
||||||
if (value.getFeedType()
|
if (value.getFeedType().startsWith("rss")) {
|
||||||
.startsWith("rss")) {
|
|
||||||
mimeType = "application/rss+xml";
|
mimeType = "application/rss+xml";
|
||||||
} else {
|
} else {
|
||||||
mimeType = "application/atom+xml";
|
mimeType = "application/atom+xml";
|
||||||
}
|
}
|
||||||
|
|
||||||
SyndFeedOutput output = new SyndFeedOutput();
|
final SyndFeedOutput output = new SyndFeedOutput();
|
||||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
output.output(value, new OutputStreamWriter(baos));
|
output.output(value, new OutputStreamWriter(baos));
|
||||||
baos.close();
|
baos.close();
|
||||||
} catch (IOException ex) {
|
} catch (final IOException ex) {
|
||||||
Logger.getLogger(AbstractNotifier.class.getName())
|
Logger.getLogger(AbstractNotifier.class.getName()).log(Level.SEVERE, null, ex);
|
||||||
.log(Level.SEVERE, null, ex);
|
|
||||||
throw new RuntimeException("Unable to output the feed.", ex);
|
throw new RuntimeException("Unable to output the feed.", ex);
|
||||||
} catch (FeedException ex) {
|
} catch (final FeedException ex) {
|
||||||
Logger.getLogger(AbstractNotifier.class.getName())
|
Logger.getLogger(AbstractNotifier.class.getName()).log(Level.SEVERE, null, ex);
|
||||||
.log(Level.SEVERE, null, ex);
|
|
||||||
throw new RuntimeException("Unable to output the feed.", ex);
|
throw new RuntimeException("Unable to output the feed.", ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
byte[] payload = baos.toByteArray();
|
final byte[] payload = baos.toByteArray();
|
||||||
|
|
||||||
for (Subscriber s : subscribers) {
|
for (final Subscriber s : subscribers) {
|
||||||
Notification not = new Notification();
|
final Notification not = new Notification();
|
||||||
not.callback = callback;
|
not.callback = callback;
|
||||||
not.lastRun = 0;
|
not.lastRun = 0;
|
||||||
not.mimeType = mimeType;
|
not.mimeType = mimeType;
|
||||||
not.payload = payload;
|
not.payload = payload;
|
||||||
not.retryCount = 0;
|
not.retryCount = 0;
|
||||||
not.subscriber = s;
|
not.subscriber = s;
|
||||||
this.enqueueNotification(not);
|
enqueueNotification(not);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/** Implementation method that queues/sends a notification
|
|
||||||
|
/**
|
||||||
|
* Implementation method that queues/sends a notification
|
||||||
*
|
*
|
||||||
* @param not notification to send.
|
* @param not notification to send.
|
||||||
*/
|
*/
|
||||||
protected abstract void enqueueNotification(Notification not);
|
protected abstract void enqueueNotification(Notification not);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* POSTs the payload to the subscriber's callback and returns a
|
* POSTs the payload to the subscriber's callback and returns a SubscriptionSummary with subscriber counts (where possible) and the success state of the
|
||||||
* SubscriptionSummary with subscriber counts (where possible) and the
|
* notification.
|
||||||
* success state of the notification.
|
*
|
||||||
* @param subscriber subscriber data.
|
* @param subscriber subscriber data.
|
||||||
* @param mimeType MIME type for the request
|
* @param mimeType MIME type for the request
|
||||||
* @param payload payload of the feed to send
|
* @param payload payload of the feed to send
|
||||||
* @return SubscriptionSummary with the returned data.
|
* @return SubscriptionSummary with the returned data.
|
||||||
*/
|
*/
|
||||||
protected SubscriptionSummary postNotification(Subscriber subscriber, String mimeType, byte[] payload) {
|
protected SubscriptionSummary postNotification(final Subscriber subscriber, final String mimeType, final byte[] payload) {
|
||||||
SubscriptionSummary result = new SubscriptionSummary();
|
final SubscriptionSummary result = new SubscriptionSummary();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
URL target = new URL(subscriber.getCallback());
|
final URL target = new URL(subscriber.getCallback());
|
||||||
Logger.getLogger(AbstractNotifier.class.getName()).log(Level.INFO, "Posting notification to subscriber {0}", subscriber.getCallback());
|
Logger.getLogger(AbstractNotifier.class.getName()).log(Level.INFO, "Posting notification to subscriber {0}", subscriber.getCallback());
|
||||||
result.setHost(target.getHost());
|
result.setHost(target.getHost());
|
||||||
|
|
||||||
HttpURLConnection connection = (HttpURLConnection) target.openConnection();
|
final HttpURLConnection connection = (HttpURLConnection) target.openConnection();
|
||||||
connection.setRequestMethod("POST");
|
connection.setRequestMethod("POST");
|
||||||
connection.setRequestProperty("Content-Type", mimeType);
|
connection.setRequestProperty("Content-Type", mimeType);
|
||||||
connection.setDoOutput(true);
|
connection.setDoOutput(true);
|
||||||
connection.connect();
|
connection.connect();
|
||||||
|
|
||||||
OutputStream os = connection.getOutputStream();
|
final OutputStream os = connection.getOutputStream();
|
||||||
os.write(payload);
|
os.write(payload);
|
||||||
os.close();
|
os.close();
|
||||||
|
|
||||||
int responseCode = connection.getResponseCode();
|
final int responseCode = connection.getResponseCode();
|
||||||
String subscribers = connection.getHeaderField("X-Hub-On-Behalf-Of");
|
final String subscribers = connection.getHeaderField("X-Hub-On-Behalf-Of");
|
||||||
connection.disconnect();
|
connection.disconnect();
|
||||||
|
|
||||||
if (responseCode != 200) {
|
if (responseCode != 200) {
|
||||||
Logger.getLogger(AbstractNotifier.class.getName())
|
Logger.getLogger(AbstractNotifier.class.getName()).log(Level.WARNING, "Got code " + responseCode + " from " + target);
|
||||||
.log(Level.WARNING, "Got code " + responseCode + " from " + target);
|
|
||||||
result.setLastPublishSuccessful(false);
|
result.setLastPublishSuccessful(false);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (subscribers != null) {
|
if (subscribers != null) {
|
||||||
try {
|
try {
|
||||||
result.setSubscribers(Integer.parseInt(subscribers));
|
result.setSubscribers(Integer.parseInt(subscribers));
|
||||||
} catch (NumberFormatException nfe) {
|
} catch (final NumberFormatException nfe) {
|
||||||
Logger.getLogger(AbstractNotifier.class.getName())
|
Logger.getLogger(AbstractNotifier.class.getName()).log(Level.WARNING, "Invalid subscriber value " + subscribers + " " + target, nfe);
|
||||||
.log(Level.WARNING, "Invalid subscriber value " + subscribers + " " + target, nfe);
|
|
||||||
result.setSubscribers(-1);
|
result.setSubscribers(-1);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
result.setSubscribers(-1);
|
result.setSubscribers(-1);
|
||||||
}
|
}
|
||||||
} catch (MalformedURLException ex) {
|
} catch (final MalformedURLException ex) {
|
||||||
Logger.getLogger(AbstractNotifier.class.getName())
|
Logger.getLogger(AbstractNotifier.class.getName()).log(Level.WARNING, null, ex);
|
||||||
.log(Level.WARNING, null, ex);
|
|
||||||
result.setLastPublishSuccessful(false);
|
result.setLastPublishSuccessful(false);
|
||||||
} catch (IOException ex) {
|
} catch (final IOException ex) {
|
||||||
Logger.getLogger(AbstractNotifier.class.getName())
|
Logger.getLogger(AbstractNotifier.class.getName()).log(Level.SEVERE, null, ex);
|
||||||
.log(Level.SEVERE, null, ex);
|
|
||||||
result.setLastPublishSuccessful(false);
|
result.setLastPublishSuccessful(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,6 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
package org.rometools.certiorem.hub.notify.standard;
|
package org.rometools.certiorem.hub.notify.standard;
|
||||||
|
|
||||||
import org.rometools.certiorem.hub.Notifier.SubscriptionSummaryCallback;
|
import org.rometools.certiorem.hub.Notifier.SubscriptionSummaryCallback;
|
||||||
|
|
|
@ -16,11 +16,8 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
package org.rometools.certiorem.hub.notify.standard;
|
package org.rometools.certiorem.hub.notify.standard;
|
||||||
|
|
||||||
import org.rometools.certiorem.hub.data.SubscriptionSummary;
|
|
||||||
|
|
||||||
import java.util.Timer;
|
import java.util.Timer;
|
||||||
import java.util.TimerTask;
|
import java.util.TimerTask;
|
||||||
import java.util.concurrent.ConcurrentSkipListSet;
|
import java.util.concurrent.ConcurrentSkipListSet;
|
||||||
|
@ -28,10 +25,10 @@ import java.util.concurrent.LinkedBlockingQueue;
|
||||||
import java.util.concurrent.ThreadPoolExecutor;
|
import java.util.concurrent.ThreadPoolExecutor;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import org.rometools.certiorem.hub.data.SubscriptionSummary;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A notifier implementation that uses a thread pool to deliver notifications to
|
* A notifier implementation that uses a thread pool to deliver notifications to subscribers
|
||||||
* subscribers
|
|
||||||
*
|
*
|
||||||
* @author robert.cooper
|
* @author robert.cooper
|
||||||
*/
|
*/
|
||||||
|
@ -45,47 +42,47 @@ public class ThreadPoolNotifier extends AbstractNotifier {
|
||||||
this(2, 5, 5);
|
this(2, 5, 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ThreadPoolNotifier(int startPoolSize, int maxPoolSize, int queueSize) {
|
public ThreadPoolNotifier(final int startPoolSize, final int maxPoolSize, final int queueSize) {
|
||||||
this.exeuctor = new ThreadPoolExecutor(startPoolSize, maxPoolSize, 300, TimeUnit.SECONDS,
|
exeuctor = new ThreadPoolExecutor(startPoolSize, maxPoolSize, 300, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(queueSize));
|
||||||
new LinkedBlockingQueue<Runnable>(queueSize));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected ThreadPoolNotifier(final ThreadPoolExecutor executor) {
|
protected ThreadPoolNotifier(final ThreadPoolExecutor executor) {
|
||||||
this.exeuctor = executor;
|
exeuctor = executor;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enqueues a notification to run. If the notification fails, it will be
|
* Enqueues a notification to run. If the notification fails, it will be retried every two minutes until 5 attempts are completed. Notifications to the same
|
||||||
* retried every two minutes until 5 attempts are completed. Notifications
|
* callback should be delivered successfully in order.
|
||||||
* to the same callback should be delivered successfully in order.
|
*
|
||||||
* @param not
|
* @param not
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected void enqueueNotification(final Notification not) {
|
protected void enqueueNotification(final Notification not) {
|
||||||
Runnable r = new Runnable() {
|
final Runnable r = new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
not.lastRun = System.currentTimeMillis();
|
not.lastRun = System.currentTimeMillis();
|
||||||
|
|
||||||
SubscriptionSummary summary = postNotification(not.subscriber, not.mimeType, not.payload);
|
final SubscriptionSummary summary = postNotification(not.subscriber, not.mimeType, not.payload);
|
||||||
|
|
||||||
if (!summary.isLastPublishSuccessful()) {
|
if (!summary.isLastPublishSuccessful()) {
|
||||||
not.retryCount++;
|
not.retryCount++;
|
||||||
|
|
||||||
if (not.retryCount <= 5) {
|
if (not.retryCount <= 5) {
|
||||||
retry(not);
|
retry(not);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
not.callback.onSummaryInfo(summary);
|
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
this.exeuctor.execute(r);
|
not.callback.onSummaryInfo(summary);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
exeuctor.execute(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Schedules a notification to retry in two minutes.
|
* Schedules a notification to retry in two minutes.
|
||||||
|
*
|
||||||
* @param not Notification to retry
|
* @param not Notification to retry
|
||||||
*/
|
*/
|
||||||
protected void retry(final Notification not) {
|
protected void retry(final Notification not) {
|
||||||
|
@ -94,21 +91,21 @@ public class ThreadPoolNotifier extends AbstractNotifier {
|
||||||
// will schedule the retry
|
// will schedule the retry
|
||||||
pendings.add(not.subscriber.getCallback());
|
pendings.add(not.subscriber.getCallback());
|
||||||
timer.schedule(new TimerTask() {
|
timer.schedule(new TimerTask() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
pendings.remove(not.subscriber.getCallback());
|
pendings.remove(not.subscriber.getCallback());
|
||||||
enqueueNotification(not);
|
enqueueNotification(not);
|
||||||
}
|
}
|
||||||
}, TWO_MINUTES);
|
}, TWO_MINUTES);
|
||||||
} else {
|
} else {
|
||||||
// There is a retry in front of this one, so we will just schedule
|
// There is a retry in front of this one, so we will just schedule
|
||||||
// it to retry again in a bit
|
// it to retry again in a bit
|
||||||
timer.schedule(new TimerTask() {
|
timer.schedule(new TimerTask() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
retry(not);
|
retry(not);
|
||||||
}
|
}
|
||||||
}, TWO_MINUTES);
|
}, TWO_MINUTES);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,10 +18,9 @@
|
||||||
|
|
||||||
package org.rometools.certiorem.hub.notify.standard;
|
package org.rometools.certiorem.hub.notify.standard;
|
||||||
|
|
||||||
import org.rometools.certiorem.hub.data.SubscriptionSummary;
|
|
||||||
|
|
||||||
import java.util.concurrent.ConcurrentSkipListSet;
|
import java.util.concurrent.ConcurrentSkipListSet;
|
||||||
|
|
||||||
|
import org.rometools.certiorem.hub.data.SubscriptionSummary;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A notifier that does not use threads. All calls are blocking and synchronous.
|
* A notifier that does not use threads. All calls are blocking and synchronous.
|
||||||
|
@ -32,17 +31,16 @@ public class UnthreadedNotifier extends AbstractNotifier {
|
||||||
private final ConcurrentSkipListSet<Notification> retries = new ConcurrentSkipListSet<Notification>();
|
private final ConcurrentSkipListSet<Notification> retries = new ConcurrentSkipListSet<Notification>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A blocking call that performs a notification.
|
* A blocking call that performs a notification. If there are pending retries that are older than two minutes old, they will be retried before the method
|
||||||
* If there are pending retries that are older than two minutes old, they will
|
* returns.
|
||||||
* be retried before the method returns.
|
|
||||||
*
|
*
|
||||||
* @param not
|
* @param not
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected void enqueueNotification(Notification not) {
|
protected void enqueueNotification(final Notification not) {
|
||||||
not.lastRun = System.currentTimeMillis();
|
not.lastRun = System.currentTimeMillis();
|
||||||
|
|
||||||
SubscriptionSummary summary = postNotification(not.subscriber, not.mimeType, not.payload);
|
final SubscriptionSummary summary = postNotification(not.subscriber, not.mimeType, not.payload);
|
||||||
|
|
||||||
not.callback.onSummaryInfo(summary);
|
not.callback.onSummaryInfo(summary);
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,91 +16,77 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
package org.rometools.certiorem.hub.verify.standard;
|
package org.rometools.certiorem.hub.verify.standard;
|
||||||
|
|
||||||
import org.rometools.certiorem.hub.Verifier;
|
|
||||||
import org.rometools.certiorem.hub.data.Subscriber;
|
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
|
|
||||||
import java.net.HttpURLConnection;
|
import java.net.HttpURLConnection;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.net.URLEncoder;
|
import java.net.URLEncoder;
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
import org.rometools.certiorem.hub.Verifier;
|
||||||
|
import org.rometools.certiorem.hub.data.Subscriber;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An abstract verifier based on the java.net HTTP classes. This implements only
|
* An abstract verifier based on the java.net HTTP classes. This implements only synchronous operations, and expects a child class to do Async ops.
|
||||||
* synchronous operations, and expects a child class to do Async ops.
|
|
||||||
*
|
*
|
||||||
* @author robert.cooper
|
* @author robert.cooper
|
||||||
*/
|
*/
|
||||||
public abstract class AbstractVerifier implements Verifier {
|
public abstract class AbstractVerifier implements Verifier {
|
||||||
@Override
|
@Override
|
||||||
public boolean verifySubcribeSyncronously(Subscriber subscriber) {
|
public boolean verifySubcribeSyncronously(final Subscriber subscriber) {
|
||||||
return doOp(Verifier.MODE_SUBSCRIBE, subscriber);
|
return doOp(Verifier.MODE_SUBSCRIBE, subscriber);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean verifyUnsubcribeSyncronously(Subscriber subscriber) {
|
public boolean verifyUnsubcribeSyncronously(final Subscriber subscriber) {
|
||||||
return doOp(Verifier.MODE_UNSUBSCRIBE, subscriber);
|
return doOp(Verifier.MODE_UNSUBSCRIBE, subscriber);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean doOp(String mode, Subscriber subscriber){
|
private boolean doOp(final String mode, final Subscriber subscriber) {
|
||||||
try {
|
try {
|
||||||
String challenge = UUID.randomUUID()
|
final String challenge = UUID.randomUUID().toString();
|
||||||
.toString();
|
final StringBuilder queryString = new StringBuilder();
|
||||||
StringBuilder queryString = new StringBuilder();
|
queryString.append("hub.mode=").append(mode).append("&hub.topic=").append(URLEncoder.encode(subscriber.getTopic(), "UTF-8"))
|
||||||
queryString.append("hub.mode=")
|
.append("&hub.challenge=").append(challenge);
|
||||||
.append(mode)
|
|
||||||
.append("&hub.topic=")
|
|
||||||
.append(URLEncoder.encode(subscriber.getTopic(), "UTF-8"))
|
|
||||||
.append("&hub.challenge=")
|
|
||||||
.append(challenge);
|
|
||||||
|
|
||||||
if (subscriber.getLeaseSeconds() != -1) {
|
if (subscriber.getLeaseSeconds() != -1) {
|
||||||
queryString.append("&hub.lease_seconds=")
|
queryString.append("&hub.lease_seconds=").append(subscriber.getLeaseSeconds());
|
||||||
.append(subscriber.getLeaseSeconds());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (subscriber.getVertifyToken() != null) {
|
if (subscriber.getVertifyToken() != null) {
|
||||||
queryString.append("&hub.verify_token=")
|
queryString.append("&hub.verify_token=").append(URLEncoder.encode(subscriber.getVertifyToken(), "UTF-8"));
|
||||||
.append(URLEncoder.encode(subscriber.getVertifyToken(), "UTF-8"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
URL url = new URL(subscriber.getCallback() + "?" + queryString.toString());
|
final URL url = new URL(subscriber.getCallback() + "?" + queryString.toString());
|
||||||
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
|
final HttpURLConnection connection = (HttpURLConnection) url.openConnection();
|
||||||
connection.setDoInput(true);
|
connection.setDoInput(true);
|
||||||
// connection.setRequestProperty("Host", url.getHost());
|
// connection.setRequestProperty("Host", url.getHost());
|
||||||
// connection.setRequestProperty("Port", Integer.toString(url.getPort()));
|
// connection.setRequestProperty("Port", Integer.toString(url.getPort()));
|
||||||
connection.setRequestProperty("User-Agent", "ROME-Certiorem");
|
connection.setRequestProperty("User-Agent", "ROME-Certiorem");
|
||||||
connection.connect();
|
connection.connect();
|
||||||
int rc = connection.getResponseCode();
|
final int rc = connection.getResponseCode();
|
||||||
InputStream is = connection.getInputStream();
|
final InputStream is = connection.getInputStream();
|
||||||
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
|
final BufferedReader reader = new BufferedReader(new InputStreamReader(is));
|
||||||
String result = reader.readLine();
|
final String result = reader.readLine();
|
||||||
reader.close();
|
reader.close();
|
||||||
connection.disconnect();
|
connection.disconnect();
|
||||||
if ((rc != 200) || !challenge.equals(result.trim())) {
|
if (rc != 200 || !challenge.equals(result.trim())) {
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} catch (UnsupportedEncodingException ex) {
|
} catch (final UnsupportedEncodingException ex) {
|
||||||
Logger.getLogger(AbstractVerifier.class.getName())
|
Logger.getLogger(AbstractVerifier.class.getName()).log(Level.SEVERE, null, ex);
|
||||||
.log(Level.SEVERE, null, ex);
|
|
||||||
throw new RuntimeException("Should not happen. UTF-8 threw unsupported encoding", ex);
|
throw new RuntimeException("Should not happen. UTF-8 threw unsupported encoding", ex);
|
||||||
} catch (IOException ex) {
|
} catch (final IOException ex) {
|
||||||
Logger.getLogger(AbstractVerifier.class.getName())
|
Logger.getLogger(AbstractVerifier.class.getName()).log(Level.SEVERE, null, ex);
|
||||||
.log(Level.SEVERE, null, ex);
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,53 +16,51 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
package org.rometools.certiorem.hub.verify.standard;
|
package org.rometools.certiorem.hub.verify.standard;
|
||||||
|
|
||||||
import org.rometools.certiorem.hub.data.Subscriber;
|
|
||||||
|
|
||||||
import java.util.concurrent.LinkedBlockingQueue;
|
import java.util.concurrent.LinkedBlockingQueue;
|
||||||
import java.util.concurrent.ThreadPoolExecutor;
|
import java.util.concurrent.ThreadPoolExecutor;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import org.rometools.certiorem.hub.data.Subscriber;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Uses a ThreadPoolExecutor to do async verifications.
|
* Uses a ThreadPoolExecutor to do async verifications.
|
||||||
|
*
|
||||||
* @author robert.cooper
|
* @author robert.cooper
|
||||||
*/
|
*/
|
||||||
public class ThreadPoolVerifier extends AbstractVerifier {
|
public class ThreadPoolVerifier extends AbstractVerifier {
|
||||||
protected final ThreadPoolExecutor exeuctor;
|
protected final ThreadPoolExecutor exeuctor;
|
||||||
|
|
||||||
protected ThreadPoolVerifier(final ThreadPoolExecutor executor){
|
protected ThreadPoolVerifier(final ThreadPoolExecutor executor) {
|
||||||
this.exeuctor = executor;
|
exeuctor = executor;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ThreadPoolVerifier() {
|
public ThreadPoolVerifier() {
|
||||||
this(2, 5, 5);
|
this(2, 5, 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ThreadPoolVerifier(int startPoolSize, int maxPoolSize, int queueSize) {
|
public ThreadPoolVerifier(final int startPoolSize, final int maxPoolSize, final int queueSize) {
|
||||||
this.exeuctor = new ThreadPoolExecutor(startPoolSize, maxPoolSize, 300, TimeUnit.SECONDS,
|
exeuctor = new ThreadPoolExecutor(startPoolSize, maxPoolSize, 300, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(queueSize));
|
||||||
new LinkedBlockingQueue<Runnable>(queueSize));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void verifySubscribeAsyncronously(final Subscriber subscriber, final VerificationCallback callback) {
|
public void verifySubscribeAsyncronously(final Subscriber subscriber, final VerificationCallback callback) {
|
||||||
this.exeuctor.execute(new Runnable() {
|
exeuctor.execute(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
callback.onVerify(verifySubcribeSyncronously(subscriber));
|
callback.onVerify(verifySubcribeSyncronously(subscriber));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void verifyUnsubscribeAsyncronously(final Subscriber subscriber, final VerificationCallback callback) {
|
public void verifyUnsubscribeAsyncronously(final Subscriber subscriber, final VerificationCallback callback) {
|
||||||
this.exeuctor.execute(new Runnable() {
|
exeuctor.execute(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
callback.onVerify(verifyUnsubcribeSyncronously(subscriber));
|
callback.onVerify(verifyUnsubcribeSyncronously(subscriber));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,9 +24,9 @@ import java.util.concurrent.ThreadPoolExecutor;
|
||||||
*
|
*
|
||||||
* @author robert.cooper
|
* @author robert.cooper
|
||||||
*/
|
*/
|
||||||
public class ThreadpoolVerifierAdvanced extends ThreadPoolVerifier{
|
public class ThreadpoolVerifierAdvanced extends ThreadPoolVerifier {
|
||||||
|
|
||||||
public ThreadpoolVerifierAdvanced(ThreadPoolExecutor executor){
|
public ThreadpoolVerifierAdvanced(final ThreadPoolExecutor executor) {
|
||||||
super(executor);
|
super(executor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,25 +16,24 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
package org.rometools.certiorem.hub.verify.standard;
|
package org.rometools.certiorem.hub.verify.standard;
|
||||||
|
|
||||||
import org.rometools.certiorem.hub.data.Subscriber;
|
import org.rometools.certiorem.hub.data.Subscriber;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A verifier that does not use threads. Suitable for Google App Engine.
|
* A verifier that does not use threads. Suitable for Google App Engine.
|
||||||
|
*
|
||||||
* @author robert.cooper
|
* @author robert.cooper
|
||||||
*/
|
*/
|
||||||
public class UnthreadedVerifier extends AbstractVerifier{
|
public class UnthreadedVerifier extends AbstractVerifier {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void verifySubscribeAsyncronously(Subscriber subscriber, VerificationCallback callback) {
|
public void verifySubscribeAsyncronously(final Subscriber subscriber, final VerificationCallback callback) {
|
||||||
callback.onVerify(verifySubcribeSyncronously(subscriber));
|
callback.onVerify(verifySubcribeSyncronously(subscriber));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void verifyUnsubscribeAsyncronously(Subscriber subscriber, VerificationCallback callback) {
|
public void verifyUnsubscribeAsyncronously(final Subscriber subscriber, final VerificationCallback callback) {
|
||||||
callback.onVerify(verifyUnsubcribeSyncronously(subscriber));
|
callback.onVerify(verifyUnsubcribeSyncronously(subscriber));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,6 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
package org.rometools.certiorem.pub;
|
package org.rometools.certiorem.pub;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -25,11 +24,11 @@ package org.rometools.certiorem.pub;
|
||||||
*/
|
*/
|
||||||
public class NotificationException extends Exception {
|
public class NotificationException extends Exception {
|
||||||
|
|
||||||
public NotificationException(String message){
|
public NotificationException(final String message) {
|
||||||
super(message);
|
super(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
public NotificationException(String message, Throwable cause){
|
public NotificationException(final String message, final Throwable cause) {
|
||||||
super(message, cause);
|
super(message, cause);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,28 +16,24 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
package org.rometools.certiorem.pub;
|
package org.rometools.certiorem.pub;
|
||||||
|
|
||||||
import com.sun.syndication.feed.synd.SyndFeed;
|
|
||||||
import com.sun.syndication.feed.synd.SyndLink;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
|
|
||||||
import java.net.HttpURLConnection;
|
import java.net.HttpURLConnection;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.net.URLEncoder;
|
import java.net.URLEncoder;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.concurrent.ThreadPoolExecutor;
|
import java.util.concurrent.ThreadPoolExecutor;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
import com.sun.syndication.feed.synd.SyndFeed;
|
||||||
|
import com.sun.syndication.feed.synd.SyndLink;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A class for sending update notifications to a hub.
|
* A class for sending update notifications to a hub.
|
||||||
|
*
|
||||||
* @author robert.cooper
|
* @author robert.cooper
|
||||||
*/
|
*/
|
||||||
public class Publisher {
|
public class Publisher {
|
||||||
|
@ -52,61 +48,57 @@ public class Publisher {
|
||||||
/**
|
/**
|
||||||
* Constructs a new publisher with an optional ThreadPoolExector for sending updates.
|
* Constructs a new publisher with an optional ThreadPoolExector for sending updates.
|
||||||
*/
|
*/
|
||||||
public Publisher(ThreadPoolExecutor executor) {
|
public Publisher(final ThreadPoolExecutor executor) {
|
||||||
this.executor = executor;
|
this.executor = executor;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sends the HUB url a notification of a change in topic
|
* Sends the HUB url a notification of a change in topic
|
||||||
|
*
|
||||||
* @param hub URL of the hub to notify.
|
* @param hub URL of the hub to notify.
|
||||||
* @param topic The Topic that has changed
|
* @param topic The Topic that has changed
|
||||||
* @throws NotificationException Any failure
|
* @throws NotificationException Any failure
|
||||||
*/
|
*/
|
||||||
public void sendUpdateNotification(String hub, String topic)
|
public void sendUpdateNotification(final String hub, final String topic) throws NotificationException {
|
||||||
throws NotificationException {
|
|
||||||
try {
|
try {
|
||||||
StringBuilder sb = new StringBuilder("hub.mode=publish&hub.url=").append(URLEncoder.encode(topic, "UTF-8"));
|
final StringBuilder sb = new StringBuilder("hub.mode=publish&hub.url=").append(URLEncoder.encode(topic, "UTF-8"));
|
||||||
URL hubUrl = new URL(hub);
|
final URL hubUrl = new URL(hub);
|
||||||
HttpURLConnection connection = (HttpURLConnection) hubUrl.openConnection();
|
final HttpURLConnection connection = (HttpURLConnection) hubUrl.openConnection();
|
||||||
// connection.setRequestProperty("Host", hubUrl.getHost());
|
// connection.setRequestProperty("Host", hubUrl.getHost());
|
||||||
connection.setRequestProperty("User-Agent", "ROME-Certiorem");
|
connection.setRequestProperty("User-Agent", "ROME-Certiorem");
|
||||||
connection.setRequestProperty("ContentType", "application/x-www-form-urlencoded");
|
connection.setRequestProperty("ContentType", "application/x-www-form-urlencoded");
|
||||||
connection.setDoOutput(true);
|
connection.setDoOutput(true);
|
||||||
connection.connect();
|
connection.connect();
|
||||||
|
|
||||||
OutputStream os = connection.getOutputStream();
|
final OutputStream os = connection.getOutputStream();
|
||||||
os.write(sb.toString().getBytes("UTF-8"));
|
os.write(sb.toString().getBytes("UTF-8"));
|
||||||
os.close();
|
os.close();
|
||||||
|
|
||||||
int rc = connection.getResponseCode();
|
final int rc = connection.getResponseCode();
|
||||||
connection.disconnect();
|
connection.disconnect();
|
||||||
|
|
||||||
if (rc != 204) {
|
if (rc != 204) {
|
||||||
throw new NotificationException("Server returned an unexcepted response code: " + rc + " " +
|
throw new NotificationException("Server returned an unexcepted response code: " + rc + " " + connection.getResponseMessage());
|
||||||
connection.getResponseMessage());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} catch (final UnsupportedEncodingException ex) {
|
||||||
} catch (UnsupportedEncodingException ex) {
|
Logger.getLogger(Publisher.class.getName()).log(Level.SEVERE, null, ex);
|
||||||
Logger.getLogger(Publisher.class.getName())
|
|
||||||
.log(Level.SEVERE, null, ex);
|
|
||||||
throw new NotificationException("Could not encode URL", ex);
|
throw new NotificationException("Could not encode URL", ex);
|
||||||
} catch (IOException ex) {
|
} catch (final IOException ex) {
|
||||||
Logger.getLogger(Publisher.class.getName())
|
Logger.getLogger(Publisher.class.getName()).log(Level.SEVERE, null, ex);
|
||||||
.log(Level.SEVERE, null, ex);
|
|
||||||
throw new NotificationException("Unable to communicate with " + hub, ex);
|
throw new NotificationException("Unable to communicate with " + hub, ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sends a notification for a feed located at "topic". The feed MUST contain rel="hub".
|
* Sends a notification for a feed located at "topic". The feed MUST contain rel="hub".
|
||||||
|
*
|
||||||
* @param topic URL for the feed
|
* @param topic URL for the feed
|
||||||
* @param feed The feed itself
|
* @param feed The feed itself
|
||||||
* @throws NotificationException Any failure
|
* @throws NotificationException Any failure
|
||||||
*/
|
*/
|
||||||
public void sendUpdateNotification(String topic, SyndFeed feed)
|
public void sendUpdateNotification(final String topic, final SyndFeed feed) throws NotificationException {
|
||||||
throws NotificationException {
|
for (final SyndLink link : feed.getLinks()) {
|
||||||
for (SyndLink link : (List<SyndLink>) feed.getLinks()) {
|
|
||||||
if ("hub".equals(link.getRel())) {
|
if ("hub".equals(link.getRel())) {
|
||||||
sendUpdateNotification(link.getRel(), topic);
|
sendUpdateNotification(link.getRel(), topic);
|
||||||
|
|
||||||
|
@ -118,14 +110,15 @@ public class Publisher {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sends a notification for a feed. The feed MUST contain rel="hub" and rel="self" links.
|
* Sends a notification for a feed. The feed MUST contain rel="hub" and rel="self" links.
|
||||||
|
*
|
||||||
* @param feed The feed to notify
|
* @param feed The feed to notify
|
||||||
* @throws NotificationException Any failure
|
* @throws NotificationException Any failure
|
||||||
*/
|
*/
|
||||||
public void sendUpdateNotification(SyndFeed feed) throws NotificationException {
|
public void sendUpdateNotification(final SyndFeed feed) throws NotificationException {
|
||||||
SyndLink hub = null;
|
SyndLink hub = null;
|
||||||
SyndLink self = null;
|
SyndLink self = null;
|
||||||
|
|
||||||
for (SyndLink link : (List<SyndLink>) feed.getLinks()) {
|
for (final SyndLink link : feed.getLinks()) {
|
||||||
if ("hub".equals(link.getRel())) {
|
if ("hub".equals(link.getRel())) {
|
||||||
hub = link;
|
hub = link;
|
||||||
}
|
}
|
||||||
|
@ -134,7 +127,7 @@ public class Publisher {
|
||||||
self = link;
|
self = link;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((hub != null) && (self != null)) {
|
if (hub != null && self != null) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -152,27 +145,27 @@ public class Publisher {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sends the HUB url a notification of a change in topic asynchronously
|
* Sends the HUB url a notification of a change in topic asynchronously
|
||||||
|
*
|
||||||
* @param hub URL of the hub to notify.
|
* @param hub URL of the hub to notify.
|
||||||
* @param topic The Topic that has changed
|
* @param topic The Topic that has changed
|
||||||
* @param callback A callback invoked when the notification completes.
|
* @param callback A callback invoked when the notification completes.
|
||||||
* @throws NotificationException Any failure
|
* @throws NotificationException Any failure
|
||||||
*/
|
*/
|
||||||
public void sendUpdateNotificationAsyncronously(final String hub, final String topic,
|
public void sendUpdateNotificationAsyncronously(final String hub, final String topic, final AsyncNotificationCallback callback) {
|
||||||
final AsyncNotificationCallback callback) {
|
final Runnable r = new Runnable() {
|
||||||
Runnable r = new Runnable() {
|
@Override
|
||||||
@Override
|
public void run() {
|
||||||
public void run() {
|
try {
|
||||||
try {
|
sendUpdateNotification(hub, topic);
|
||||||
sendUpdateNotification(hub, topic);
|
callback.onSuccess();
|
||||||
callback.onSuccess();
|
} catch (final Throwable t) {
|
||||||
} catch (Throwable t) {
|
callback.onFailure(t);
|
||||||
callback.onFailure(t);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
};
|
||||||
|
|
||||||
if (this.executor != null) {
|
if (executor != null) {
|
||||||
this.executor.execute(r);
|
executor.execute(r);
|
||||||
} else {
|
} else {
|
||||||
new Thread(r).start();
|
new Thread(r).start();
|
||||||
}
|
}
|
||||||
|
@ -180,66 +173,70 @@ public class Publisher {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Asynchronously sends a notification for a feed located at "topic". The feed MUST contain rel="hub".
|
* Asynchronously sends a notification for a feed located at "topic". The feed MUST contain rel="hub".
|
||||||
|
*
|
||||||
* @param topic URL for the feed
|
* @param topic URL for the feed
|
||||||
* @param feed The feed itself
|
* @param feed The feed itself
|
||||||
* @param callback A callback invoked when the notification completes.
|
* @param callback A callback invoked when the notification completes.
|
||||||
* @throws NotificationException Any failure
|
* @throws NotificationException Any failure
|
||||||
*/
|
*/
|
||||||
public void sendUpdateNotificationAsyncronously(final String topic, final SyndFeed feed,
|
public void sendUpdateNotificationAsyncronously(final String topic, final SyndFeed feed, final AsyncNotificationCallback callback) {
|
||||||
final AsyncNotificationCallback callback) {
|
final Runnable r = new Runnable() {
|
||||||
Runnable r = new Runnable() {
|
@Override
|
||||||
@Override
|
public void run() {
|
||||||
public void run() {
|
try {
|
||||||
try {
|
sendUpdateNotification(topic, feed);
|
||||||
sendUpdateNotification(topic, feed);
|
callback.onSuccess();
|
||||||
callback.onSuccess();
|
} catch (final Throwable t) {
|
||||||
} catch (Throwable t) {
|
callback.onFailure(t);
|
||||||
callback.onFailure(t);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
};
|
||||||
|
|
||||||
if (this.executor != null) {
|
if (executor != null) {
|
||||||
this.executor.execute(r);
|
executor.execute(r);
|
||||||
} else {
|
} else {
|
||||||
new Thread(r).start();
|
new Thread(r).start();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Asyncronously sends a notification for a feed. The feed MUST contain rel="hub" and rel="self" links.
|
* Asyncronously sends a notification for a feed. The feed MUST contain rel="hub" and rel="self" links.
|
||||||
|
*
|
||||||
* @param feed The feed to notify
|
* @param feed The feed to notify
|
||||||
* @param callback A callback invoked when the notification completes.
|
* @param callback A callback invoked when the notification completes.
|
||||||
* @throws NotificationException Any failure
|
* @throws NotificationException Any failure
|
||||||
*/
|
*/
|
||||||
public void sendUpdateNotificationAsyncronously(final SyndFeed feed, final AsyncNotificationCallback callback) {
|
public void sendUpdateNotificationAsyncronously(final SyndFeed feed, final AsyncNotificationCallback callback) {
|
||||||
Runnable r = new Runnable() {
|
final Runnable r = new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
sendUpdateNotification(feed);
|
sendUpdateNotification(feed);
|
||||||
callback.onSuccess();
|
callback.onSuccess();
|
||||||
} catch (Throwable t) {
|
} catch (final Throwable t) {
|
||||||
callback.onFailure(t);
|
callback.onFailure(t);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
};
|
||||||
|
|
||||||
if (this.executor != null) {
|
if (executor != null) {
|
||||||
this.executor.execute(r);
|
executor.execute(r);
|
||||||
} else {
|
} else {
|
||||||
new Thread(r).start();
|
new Thread(r).start();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A callback interface for asynchronous notifications.
|
* A callback interface for asynchronous notifications.
|
||||||
*/
|
*/
|
||||||
public static interface AsyncNotificationCallback {
|
public static interface AsyncNotificationCallback {
|
||||||
/**
|
/**
|
||||||
* Called when a notification fails
|
* Called when a notification fails
|
||||||
|
*
|
||||||
* @param thrown Whatever was thrown during the failure
|
* @param thrown Whatever was thrown during the failure
|
||||||
*/
|
*/
|
||||||
public void onFailure(Throwable thrown);
|
public void onFailure(Throwable thrown);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Invoked with the asyncronous notification completes successfully.
|
* Invoked with the asyncronous notification completes successfully.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -20,17 +20,15 @@ package org.rometools.certiorem.sub;
|
||||||
|
|
||||||
import org.rometools.certiorem.sub.data.Subscription;
|
import org.rometools.certiorem.sub.data.Subscription;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author robert.cooper
|
* @author robert.cooper
|
||||||
*/
|
*/
|
||||||
public interface Requester {
|
public interface Requester {
|
||||||
public void sendSubscribeRequest(String hubUrl, Subscription subscription, String verifySync, long leaseSeconds,
|
public void sendSubscribeRequest(String hubUrl, Subscription subscription, String verifySync, long leaseSeconds, String secret, String callbackUrl,
|
||||||
String secret, String callbackUrl, RequestCallback callback);
|
RequestCallback callback);
|
||||||
|
|
||||||
public void sendUnsubscribeRequest(String hubUrl, Subscription subscription, String verifySync, String secret,
|
public void sendUnsubscribeRequest(String hubUrl, Subscription subscription, String verifySync, String secret, String callbackUrl, RequestCallback callback);
|
||||||
String callbackUrl, RequestCallback callback);
|
|
||||||
|
|
||||||
public static interface RequestCallback {
|
public static interface RequestCallback {
|
||||||
public void onFailure(Exception e);
|
public void onFailure(Exception e);
|
||||||
|
|
|
@ -18,43 +18,38 @@
|
||||||
|
|
||||||
package org.rometools.certiorem.sub;
|
package org.rometools.certiorem.sub;
|
||||||
|
|
||||||
import com.sun.syndication.feed.synd.SyndFeed;
|
|
||||||
import com.sun.syndication.feed.synd.SyndLink;
|
|
||||||
import com.sun.syndication.io.FeedException;
|
|
||||||
import com.sun.syndication.io.SyndFeedInput;
|
|
||||||
|
|
||||||
import org.rometools.certiorem.HttpStatusCodeException;
|
|
||||||
import org.rometools.certiorem.sub.Requester.RequestCallback;
|
|
||||||
import org.rometools.certiorem.sub.data.SubDAO;
|
|
||||||
import org.rometools.certiorem.sub.data.Subscription;
|
|
||||||
|
|
||||||
import org.rometools.fetcher.impl.FeedFetcherCache;
|
|
||||||
import org.rometools.fetcher.impl.SyndFeedInfo;
|
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
|
|
||||||
import java.net.MalformedURLException;
|
import java.net.MalformedURLException;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.net.URISyntaxException;
|
import java.net.URISyntaxException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
import org.rometools.certiorem.sub.data.SubscriptionCallback;
|
|
||||||
|
|
||||||
|
import org.rometools.certiorem.HttpStatusCodeException;
|
||||||
|
import org.rometools.certiorem.sub.Requester.RequestCallback;
|
||||||
|
import org.rometools.certiorem.sub.data.SubDAO;
|
||||||
|
import org.rometools.certiorem.sub.data.Subscription;
|
||||||
|
import org.rometools.certiorem.sub.data.SubscriptionCallback;
|
||||||
|
import org.rometools.fetcher.impl.FeedFetcherCache;
|
||||||
|
import org.rometools.fetcher.impl.SyndFeedInfo;
|
||||||
|
|
||||||
|
import com.sun.syndication.feed.synd.SyndFeed;
|
||||||
|
import com.sun.syndication.feed.synd.SyndLink;
|
||||||
|
import com.sun.syndication.io.FeedException;
|
||||||
|
import com.sun.syndication.io.SyndFeedInput;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author robert.cooper
|
* @author robert.cooper
|
||||||
*/
|
*/
|
||||||
public class Subscriptions {
|
public class Subscriptions {
|
||||||
//TODO unsubscribe.
|
// TODO unsubscribe.
|
||||||
private FeedFetcherCache cache;
|
private FeedFetcherCache cache;
|
||||||
private Requester requester;
|
private Requester requester;
|
||||||
private String callbackPrefix;
|
private String callbackPrefix;
|
||||||
|
@ -63,59 +58,55 @@ public class Subscriptions {
|
||||||
public Subscriptions() {
|
public Subscriptions() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Subscriptions(final FeedFetcherCache cache, final Requester requester, final String callbackPrefix,
|
public Subscriptions(final FeedFetcherCache cache, final Requester requester, final String callbackPrefix, final SubDAO dao) {
|
||||||
final SubDAO dao) {
|
|
||||||
this.cache = cache;
|
this.cache = cache;
|
||||||
this.requester = requester;
|
this.requester = requester;
|
||||||
this.callbackPrefix = callbackPrefix;
|
this.callbackPrefix = callbackPrefix;
|
||||||
this.dao = dao;
|
this.dao = dao;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void callback(String callbackPath, String feed) {
|
public void callback(final String callbackPath, final String feed) {
|
||||||
try {
|
try {
|
||||||
this.callback(callbackPath, feed.getBytes("UTF-8"));
|
this.callback(callbackPath, feed.getBytes("UTF-8"));
|
||||||
} catch (UnsupportedEncodingException ex) {
|
} catch (final UnsupportedEncodingException ex) {
|
||||||
Logger.getLogger(Subscriptions.class.getName())
|
Logger.getLogger(Subscriptions.class.getName()).log(Level.SEVERE, null, ex);
|
||||||
.log(Level.SEVERE, null, ex);
|
|
||||||
throw new HttpStatusCodeException(400, "Unable to parse feed.", ex);
|
throw new HttpStatusCodeException(400, "Unable to parse feed.", ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void callback(String callbackPath, InputStream feed) {
|
public void callback(final String callbackPath, final InputStream feed) {
|
||||||
SyndFeedInput input = new SyndFeedInput();
|
final SyndFeedInput input = new SyndFeedInput();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
this.callback(callbackPath, input.build(new InputStreamReader(feed)));
|
this.callback(callbackPath, input.build(new InputStreamReader(feed)));
|
||||||
} catch (IllegalArgumentException ex) {
|
} catch (final IllegalArgumentException ex) {
|
||||||
Logger.getLogger(Subscriptions.class.getName())
|
Logger.getLogger(Subscriptions.class.getName()).log(Level.SEVERE, null, ex);
|
||||||
.log(Level.SEVERE, null, ex);
|
|
||||||
throw new HttpStatusCodeException(500, "Unable to parse feed.", ex);
|
throw new HttpStatusCodeException(500, "Unable to parse feed.", ex);
|
||||||
} catch (FeedException ex) {
|
} catch (final FeedException ex) {
|
||||||
Logger.getLogger(Subscriptions.class.getName())
|
Logger.getLogger(Subscriptions.class.getName()).log(Level.SEVERE, null, ex);
|
||||||
.log(Level.SEVERE, null, ex);
|
|
||||||
throw new HttpStatusCodeException(400, "Unable to parse feed.", ex);
|
throw new HttpStatusCodeException(400, "Unable to parse feed.", ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void callback(String callbackPath, byte[] feed) {
|
public void callback(final String callbackPath, final byte[] feed) {
|
||||||
this.callback(callbackPath, new ByteArrayInputStream(feed));
|
this.callback(callbackPath, new ByteArrayInputStream(feed));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void callback(String callbackPath, SyndFeed feed) {
|
public void callback(final String callbackPath, final SyndFeed feed) {
|
||||||
|
|
||||||
if (!callbackPath.startsWith(callbackPrefix)) {
|
if (!callbackPath.startsWith(callbackPrefix)) {
|
||||||
throw new HttpStatusCodeException(404, "Not a valid callback prefix.", new Exception(callbackPath+" doesnt start with "+callbackPrefix));
|
throw new HttpStatusCodeException(404, "Not a valid callback prefix.", new Exception(callbackPath + " doesnt start with " + callbackPrefix));
|
||||||
}
|
}
|
||||||
|
|
||||||
String id = callbackPath.substring(callbackPrefix.length());
|
final String id = callbackPath.substring(callbackPrefix.length());
|
||||||
Logger.getLogger(Subscriptions.class.getName()).log(Level.FINE, "Got callback for {0}", id);
|
Logger.getLogger(Subscriptions.class.getName()).log(Level.FINE, "Got callback for {0}", id);
|
||||||
Subscription s = dao.findById(id);
|
final Subscription s = dao.findById(id);
|
||||||
|
|
||||||
if (s == null) {
|
if (s == null) {
|
||||||
throw new HttpStatusCodeException(404, "Not a valid callback.", null);
|
throw new HttpStatusCodeException(404, "Not a valid callback.", null);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.validateLink(feed, s.getSourceUrl());
|
validateLink(feed, s.getSourceUrl());
|
||||||
|
|
||||||
SyndFeedInfo info = null;
|
SyndFeedInfo info = null;
|
||||||
URL url = null;
|
URL url = null;
|
||||||
|
@ -123,9 +114,8 @@ public class Subscriptions {
|
||||||
try {
|
try {
|
||||||
url = new URL(s.getSourceUrl());
|
url = new URL(s.getSourceUrl());
|
||||||
info = cache.getFeedInfo(url);
|
info = cache.getFeedInfo(url);
|
||||||
} catch (MalformedURLException ex) {
|
} catch (final MalformedURLException ex) {
|
||||||
Logger.getLogger(Subscriptions.class.getName())
|
Logger.getLogger(Subscriptions.class.getName()).log(Level.SEVERE, null, ex);
|
||||||
.log(Level.SEVERE, null, ex);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (info == null) {
|
if (info == null) {
|
||||||
|
@ -141,58 +131,53 @@ public class Subscriptions {
|
||||||
s.getCallback().onNotify(s, info);
|
s.getCallback().onNotify(s, info);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void unsubscribe(final Subscription subscription, String hubUrl, boolean sync, String secret,
|
public void unsubscribe(final Subscription subscription, final String hubUrl, final boolean sync, final String secret, final SubscriptionCallback callback) {
|
||||||
final SubscriptionCallback callback) {
|
|
||||||
|
|
||||||
subscription.setUnsubscribed(true);
|
subscription.setUnsubscribed(true);
|
||||||
this.requester.sendUnsubscribeRequest(hubUrl, subscription, (sync ? "sync" : "async"), secret,
|
requester.sendUnsubscribeRequest(hubUrl, subscription, sync ? "sync" : "async", secret, callbackPrefix + subscription.getId(), new RequestCallback() {
|
||||||
this.callbackPrefix + subscription.getId(),
|
@Override
|
||||||
new RequestCallback() {
|
public void onSuccess() {
|
||||||
@Override
|
callback.onUnsubscribe(subscription);
|
||||||
public void onSuccess() {
|
}
|
||||||
callback.onUnsubscribe(subscription);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onFailure(Exception e) {
|
public void onFailure(final Exception e) {
|
||||||
callback.onFailure(e);
|
callback.onFailure(e);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public void subscribe(String hubUrl, String topic, boolean sync, long leaseSeconds, String secret,
|
public void subscribe(final String hubUrl, final String topic, final boolean sync, final long leaseSeconds, final String secret,
|
||||||
final SubscriptionCallback callback) {
|
final SubscriptionCallback callback) {
|
||||||
Subscription s = new Subscription();
|
final Subscription s = new Subscription();
|
||||||
s.setId(UUID.randomUUID().toString());
|
s.setId(UUID.randomUUID().toString());
|
||||||
s.setVerifyToken(UUID.randomUUID().toString());
|
s.setVerifyToken(UUID.randomUUID().toString());
|
||||||
s.setSourceUrl(topic);
|
s.setSourceUrl(topic);
|
||||||
s.setCallback(callback);
|
s.setCallback(callback);
|
||||||
if (leaseSeconds > 0) {
|
if (leaseSeconds > 0) {
|
||||||
s.setExpirationTime(System.currentTimeMillis() + (leaseSeconds * 1000));
|
s.setExpirationTime(System.currentTimeMillis() + leaseSeconds * 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
final Subscription stored = this.dao.addSubscription(s);
|
final Subscription stored = dao.addSubscription(s);
|
||||||
|
|
||||||
this.requester.sendSubscribeRequest(hubUrl, stored, (sync ? "sync" : "async"), leaseSeconds, secret,
|
requester.sendSubscribeRequest(hubUrl, stored, sync ? "sync" : "async", leaseSeconds, secret, callbackPrefix + stored.getId(), new RequestCallback() {
|
||||||
this.callbackPrefix + stored.getId(),
|
@Override
|
||||||
new RequestCallback() {
|
public void onSuccess() {
|
||||||
@Override
|
callback.onSubscribe(stored);
|
||||||
public void onSuccess() {
|
}
|
||||||
callback.onSubscribe(stored);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onFailure(Exception e) {
|
public void onFailure(final Exception e) {
|
||||||
callback.onFailure(e);
|
callback.onFailure(e);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public void subscribe(String topic, boolean sync, long leaseSeconds, String secret,
|
public void subscribe(final String topic, final boolean sync, final long leaseSeconds, final String secret, final SubscriptionCallback callback)
|
||||||
final SubscriptionCallback callback) throws IllegalArgumentException, IOException, FeedException {
|
throws IllegalArgumentException, IOException, FeedException {
|
||||||
SyndFeedInput input = new SyndFeedInput();
|
final SyndFeedInput input = new SyndFeedInput();
|
||||||
SyndFeed feed = input.build(new InputStreamReader(new URL(topic).openStream()));
|
final SyndFeed feed = input.build(new InputStreamReader(new URL(topic).openStream()));
|
||||||
String hubUrl = this.findHubUrl(feed);
|
final String hubUrl = findHubUrl(feed);
|
||||||
|
|
||||||
if (hubUrl == null) {
|
if (hubUrl == null) {
|
||||||
throw new FeedException("No hub link");
|
throw new FeedException("No hub link");
|
||||||
|
@ -201,20 +186,19 @@ public class Subscriptions {
|
||||||
this.subscribe(hubUrl, topic, sync, leaseSeconds, secret, callback);
|
this.subscribe(hubUrl, topic, sync, leaseSeconds, secret, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String validate(String callbackPath, String topic, String mode, String challenge, String leaseSeconds,
|
public String validate(final String callbackPath, final String topic, final String mode, final String challenge, final String leaseSeconds,
|
||||||
String verifyToken) {
|
final String verifyToken) {
|
||||||
if (!callbackPath.startsWith(callbackPrefix)) {
|
if (!callbackPath.startsWith(callbackPrefix)) {
|
||||||
throw new HttpStatusCodeException(404, "Not a valid callback prefix.", new Exception(callbackPath+" doesnt start with "+callbackPrefix));
|
throw new HttpStatusCodeException(404, "Not a valid callback prefix.", new Exception(callbackPath + " doesnt start with " + callbackPrefix));
|
||||||
}
|
}
|
||||||
|
|
||||||
String id = callbackPath.substring(callbackPrefix.length());
|
final String id = callbackPath.substring(callbackPrefix.length());
|
||||||
Logger.getLogger(Subscriptions.class.getName()).log(Level.FINE, "Handling validation request for id {0}", id);
|
Logger.getLogger(Subscriptions.class.getName()).log(Level.FINE, "Handling validation request for id {0}", id);
|
||||||
Subscription s = dao.findById(id);
|
final Subscription s = dao.findById(id);
|
||||||
if(s == null){
|
if (s == null) {
|
||||||
throw new HttpStatusCodeException(404, "Not a valid subscription id", null);
|
throw new HttpStatusCodeException(404, "Not a valid subscription id", null);
|
||||||
}
|
}
|
||||||
if (!s.getVerifyToken()
|
if (!s.getVerifyToken().equals(verifyToken)) {
|
||||||
.equals(verifyToken)) {
|
|
||||||
throw new HttpStatusCodeException(403, "Verification Token Mismatch.", null);
|
throw new HttpStatusCodeException(403, "Verification Token Mismatch.", null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -238,8 +222,8 @@ public class Subscriptions {
|
||||||
return challenge;
|
return challenge;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String findHubUrl(SyndFeed feed) {
|
private String findHubUrl(final SyndFeed feed) {
|
||||||
for (SyndLink l : (List<SyndLink>) feed.getLinks()) {
|
for (final SyndLink l : feed.getLinks()) {
|
||||||
if ("hub".equals(l.getRel())) {
|
if ("hub".equals(l.getRel())) {
|
||||||
return l.getHref();
|
return l.getHref();
|
||||||
}
|
}
|
||||||
|
@ -248,21 +232,20 @@ public class Subscriptions {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void validateLink(SyndFeed feed, String source) {
|
private void validateLink(final SyndFeed feed, final String source) {
|
||||||
for (SyndLink l : (List<SyndLink>) feed.getLinks()) {
|
for (final SyndLink l : feed.getLinks()) {
|
||||||
if ("self".equalsIgnoreCase(l.getRel())) {
|
if ("self".equalsIgnoreCase(l.getRel())) {
|
||||||
try {
|
try {
|
||||||
URI u = new URI(l.getHref());
|
final URI u = new URI(l.getHref());
|
||||||
URI t = new URI(source);
|
final URI t = new URI(source);
|
||||||
|
|
||||||
if (!u.equals(t)) {
|
if (!u.equals(t)) {
|
||||||
throw new HttpStatusCodeException(400, "Feed self link does not match the subscribed URI.", null);
|
throw new HttpStatusCodeException(400, "Feed self link does not match the subscribed URI.", null);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
} catch (URISyntaxException ex) {
|
} catch (final URISyntaxException ex) {
|
||||||
Logger.getLogger(Subscriptions.class.getName())
|
Logger.getLogger(Subscriptions.class.getName()).log(Level.SEVERE, null, ex);
|
||||||
.log(Level.SEVERE, null, ex);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -271,28 +254,28 @@ public class Subscriptions {
|
||||||
/**
|
/**
|
||||||
* @param cache the cache to set
|
* @param cache the cache to set
|
||||||
*/
|
*/
|
||||||
public void setCache(FeedFetcherCache cache) {
|
public void setCache(final FeedFetcherCache cache) {
|
||||||
this.cache = cache;
|
this.cache = cache;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param requester the requester to set
|
* @param requester the requester to set
|
||||||
*/
|
*/
|
||||||
public void setRequester(Requester requester) {
|
public void setRequester(final Requester requester) {
|
||||||
this.requester = requester;
|
this.requester = requester;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param callbackPrefix the callbackPrefix to set
|
* @param callbackPrefix the callbackPrefix to set
|
||||||
*/
|
*/
|
||||||
public void setCallbackPrefix(String callbackPrefix) {
|
public void setCallbackPrefix(final String callbackPrefix) {
|
||||||
this.callbackPrefix = callbackPrefix;
|
this.callbackPrefix = callbackPrefix;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param dao the dao to set
|
* @param dao the dao to set
|
||||||
*/
|
*/
|
||||||
public void setDao(SubDAO dao) {
|
public void setDao(final SubDAO dao) {
|
||||||
this.dao = dao;
|
this.dao = dao;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,6 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
package org.rometools.certiorem.sub.data;
|
package org.rometools.certiorem.sub.data;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -20,7 +20,6 @@ package org.rometools.certiorem.sub.data;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author robert.cooper
|
* @author robert.cooper
|
||||||
|
@ -39,8 +38,8 @@ public class Subscription implements Serializable {
|
||||||
*
|
*
|
||||||
* @param newexpirationTime new value of expirationTime
|
* @param newexpirationTime new value of expirationTime
|
||||||
*/
|
*/
|
||||||
public void setExpirationTime(long newexpirationTime) {
|
public void setExpirationTime(final long newexpirationTime) {
|
||||||
this.expirationTime = newexpirationTime;
|
expirationTime = newexpirationTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -49,7 +48,7 @@ public class Subscription implements Serializable {
|
||||||
* @return the value of expirationTime
|
* @return the value of expirationTime
|
||||||
*/
|
*/
|
||||||
public long getExpirationTime() {
|
public long getExpirationTime() {
|
||||||
return this.expirationTime;
|
return expirationTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -57,8 +56,8 @@ public class Subscription implements Serializable {
|
||||||
*
|
*
|
||||||
* @param newid new value of id
|
* @param newid new value of id
|
||||||
*/
|
*/
|
||||||
public void setId(String newid) {
|
public void setId(final String newid) {
|
||||||
this.id = newid;
|
id = newid;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -67,7 +66,7 @@ public class Subscription implements Serializable {
|
||||||
* @return the value of id
|
* @return the value of id
|
||||||
*/
|
*/
|
||||||
public String getId() {
|
public String getId() {
|
||||||
return this.id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -75,8 +74,8 @@ public class Subscription implements Serializable {
|
||||||
*
|
*
|
||||||
* @param newsourceUrl new value of sourceUrl
|
* @param newsourceUrl new value of sourceUrl
|
||||||
*/
|
*/
|
||||||
public void setSourceUrl(String newsourceUrl) {
|
public void setSourceUrl(final String newsourceUrl) {
|
||||||
this.sourceUrl = newsourceUrl;
|
sourceUrl = newsourceUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -85,7 +84,7 @@ public class Subscription implements Serializable {
|
||||||
* @return the value of sourceUrl
|
* @return the value of sourceUrl
|
||||||
*/
|
*/
|
||||||
public String getSourceUrl() {
|
public String getSourceUrl() {
|
||||||
return this.sourceUrl;
|
return sourceUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -93,8 +92,8 @@ public class Subscription implements Serializable {
|
||||||
*
|
*
|
||||||
* @param newunsubscribed new value of unsubscribed
|
* @param newunsubscribed new value of unsubscribed
|
||||||
*/
|
*/
|
||||||
public void setUnsubscribed(boolean newunsubscribed) {
|
public void setUnsubscribed(final boolean newunsubscribed) {
|
||||||
this.unsubscribed = newunsubscribed;
|
unsubscribed = newunsubscribed;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -103,7 +102,7 @@ public class Subscription implements Serializable {
|
||||||
* @return the value of unsubscribed
|
* @return the value of unsubscribed
|
||||||
*/
|
*/
|
||||||
public boolean isUnsubscribed() {
|
public boolean isUnsubscribed() {
|
||||||
return this.unsubscribed;
|
return unsubscribed;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -111,8 +110,8 @@ public class Subscription implements Serializable {
|
||||||
*
|
*
|
||||||
* @param newvalidated new value of validated
|
* @param newvalidated new value of validated
|
||||||
*/
|
*/
|
||||||
public void setValidated(boolean newvalidated) {
|
public void setValidated(final boolean newvalidated) {
|
||||||
this.validated = newvalidated;
|
validated = newvalidated;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -121,7 +120,7 @@ public class Subscription implements Serializable {
|
||||||
* @return the value of validated
|
* @return the value of validated
|
||||||
*/
|
*/
|
||||||
public boolean isValidated() {
|
public boolean isValidated() {
|
||||||
return this.validated;
|
return validated;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -129,8 +128,8 @@ public class Subscription implements Serializable {
|
||||||
*
|
*
|
||||||
* @param newverifyToken new value of verifyToken
|
* @param newverifyToken new value of verifyToken
|
||||||
*/
|
*/
|
||||||
public void setVerifyToken(String newverifyToken) {
|
public void setVerifyToken(final String newverifyToken) {
|
||||||
this.verifyToken = newverifyToken;
|
verifyToken = newverifyToken;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -139,7 +138,7 @@ public class Subscription implements Serializable {
|
||||||
* @return the value of verifyToken
|
* @return the value of verifyToken
|
||||||
*/
|
*/
|
||||||
public String getVerifyToken() {
|
public String getVerifyToken() {
|
||||||
return this.verifyToken;
|
return verifyToken;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -152,7 +151,7 @@ public class Subscription implements Serializable {
|
||||||
/**
|
/**
|
||||||
* @param callback the callback to set
|
* @param callback the callback to set
|
||||||
*/
|
*/
|
||||||
public void setCallback(SubscriptionCallback callback) {
|
public void setCallback(final SubscriptionCallback callback) {
|
||||||
this.callback = callback;
|
this.callback = callback;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,7 @@ import java.util.Date;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import org.rometools.certiorem.sub.data.SubDAO;
|
import org.rometools.certiorem.sub.data.SubDAO;
|
||||||
import org.rometools.certiorem.sub.data.Subscription;
|
import org.rometools.certiorem.sub.data.Subscription;
|
||||||
|
|
||||||
|
@ -36,16 +37,17 @@ import org.rometools.certiorem.sub.data.Subscription;
|
||||||
*/
|
*/
|
||||||
public class InMemorySubDAO implements SubDAO {
|
public class InMemorySubDAO implements SubDAO {
|
||||||
|
|
||||||
private ConcurrentHashMap<String, Subscription> subscriptions = new ConcurrentHashMap<String, Subscription>();
|
private final ConcurrentHashMap<String, Subscription> subscriptions = new ConcurrentHashMap<String, Subscription>();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Subscription findById(String id) {
|
public Subscription findById(final String id) {
|
||||||
Subscription s = subscriptions.get(id);
|
final Subscription s = subscriptions.get(id);
|
||||||
if(s == null){
|
if (s == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
if(s.getExpirationTime() > 0 && s.getExpirationTime() <= System.currentTimeMillis()){
|
if (s.getExpirationTime() > 0 && s.getExpirationTime() <= System.currentTimeMillis()) {
|
||||||
Logger.getLogger(InMemorySubDAO.class.getName()).log(Level.FINE, "Subscription {0} expired at {1}", new Object[]{s.getSourceUrl(), new Date(s.getExpirationTime())});
|
Logger.getLogger(InMemorySubDAO.class.getName()).log(Level.FINE, "Subscription {0} expired at {1}",
|
||||||
|
new Object[] { s.getSourceUrl(), new Date(s.getExpirationTime()) });
|
||||||
subscriptions.remove(id);
|
subscriptions.remove(id);
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
@ -54,20 +56,20 @@ public class InMemorySubDAO implements SubDAO {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Subscription addSubscription(Subscription s) {
|
public Subscription addSubscription(final Subscription s) {
|
||||||
subscriptions.put(s.getId(), s);
|
subscriptions.put(s.getId(), s);
|
||||||
Logger.getLogger(InMemorySubDAO.class.getName()).log(Level.FINE, "Stored subscription {0} {1}", new Object[]{s.getSourceUrl(), s.getId()});
|
Logger.getLogger(InMemorySubDAO.class.getName()).log(Level.FINE, "Stored subscription {0} {1}", new Object[] { s.getSourceUrl(), s.getId() });
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Subscription updateSubscription(Subscription s) {
|
public Subscription updateSubscription(final Subscription s) {
|
||||||
subscriptions.put(s.getId(), s);
|
subscriptions.put(s.getId(), s);
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void removeSubscription(Subscription s) {
|
public void removeSubscription(final Subscription s) {
|
||||||
subscriptions.remove(s.getId());
|
subscriptions.remove(s.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,18 +16,15 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
package org.rometools.certiorem.sub.request;
|
package org.rometools.certiorem.sub.request;
|
||||||
|
|
||||||
import org.rometools.certiorem.sub.Requester;
|
|
||||||
import org.rometools.certiorem.sub.data.Subscription;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
import java.net.HttpURLConnection;
|
import java.net.HttpURLConnection;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.net.URLEncoder;
|
import java.net.URLEncoder;
|
||||||
|
|
||||||
|
import org.rometools.certiorem.sub.Requester;
|
||||||
|
import org.rometools.certiorem.sub.data.Subscription;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -35,45 +32,35 @@ import java.net.URLEncoder;
|
||||||
*/
|
*/
|
||||||
public abstract class AbstractRequester implements Requester {
|
public abstract class AbstractRequester implements Requester {
|
||||||
|
|
||||||
protected boolean sendRequest(String hubUrl, String mode, Subscription subscription, String verifySync,
|
protected boolean sendRequest(final String hubUrl, final String mode, final Subscription subscription, final String verifySync, final long leaseSeconds,
|
||||||
long leaseSeconds, String secret, String callbackUrl, RequestCallback callback)
|
final String secret, final String callbackUrl, final RequestCallback callback) throws IOException {
|
||||||
throws IOException {
|
final StringBuilder sb = new StringBuilder("hub.callback=").append(URLEncoder.encode(callbackUrl, "UTF-8")).append("&hub.topic=")
|
||||||
StringBuilder sb = new StringBuilder("hub.callback=").append(URLEncoder.encode(callbackUrl, "UTF-8"))
|
.append(URLEncoder.encode(subscription.getSourceUrl(), "UTF-8")).append("&hub.verify=").append(URLEncoder.encode(verifySync, "UTF-8"))
|
||||||
.append("&hub.topic=")
|
.append("&hub.mode=").append(URLEncoder.encode(mode, "UTF-8"));
|
||||||
.append(URLEncoder.encode(subscription.getSourceUrl(),
|
|
||||||
"UTF-8"))
|
|
||||||
.append("&hub.verify=")
|
|
||||||
.append(URLEncoder.encode(verifySync, "UTF-8"))
|
|
||||||
.append("&hub.mode=")
|
|
||||||
.append(URLEncoder.encode(mode, "UTF-8"));
|
|
||||||
|
|
||||||
if (leaseSeconds > 0) {
|
if (leaseSeconds > 0) {
|
||||||
sb.append("&hub.lease_seconds=")
|
sb.append("&hub.lease_seconds=").append(Long.toString(leaseSeconds));
|
||||||
.append(Long.toString(leaseSeconds));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (secret != null) {
|
if (secret != null) {
|
||||||
sb.append("&hub.secret=")
|
sb.append("&hub.secret=").append(URLEncoder.encode(secret, "UTF-8"));
|
||||||
.append(URLEncoder.encode(secret, "UTF-8"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (subscription.getVerifyToken() != null) {
|
if (subscription.getVerifyToken() != null) {
|
||||||
sb.append("&hub.verify_token=")
|
sb.append("&hub.verify_token=").append(URLEncoder.encode(subscription.getVerifyToken(), "UTF-8"));
|
||||||
.append(URLEncoder.encode(subscription.getVerifyToken(), "UTF-8"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
URL url = new URL(hubUrl);
|
final URL url = new URL(hubUrl);
|
||||||
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
|
final HttpURLConnection connection = (HttpURLConnection) url.openConnection();
|
||||||
connection.setRequestMethod("POST");
|
connection.setRequestMethod("POST");
|
||||||
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
|
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
|
||||||
connection.setDoOutput(true);
|
connection.setDoOutput(true);
|
||||||
// connection.setRequestProperty("Host", url.getHost());
|
// connection.setRequestProperty("Host", url.getHost());
|
||||||
connection.setRequestProperty("User-Agent", "ROME-Certiorem");
|
connection.setRequestProperty("User-Agent", "ROME-Certiorem");
|
||||||
connection.connect();
|
connection.connect();
|
||||||
connection.getOutputStream()
|
connection.getOutputStream().write(sb.toString().getBytes("UTF-8"));
|
||||||
.write(sb.toString().getBytes("UTF-8"));
|
|
||||||
|
|
||||||
int rc = connection.getResponseCode();
|
final int rc = connection.getResponseCode();
|
||||||
connection.disconnect();
|
connection.disconnect();
|
||||||
|
|
||||||
if (rc != 204) {
|
if (rc != 204) {
|
||||||
|
|
|
@ -18,57 +18,53 @@
|
||||||
|
|
||||||
package org.rometools.certiorem.sub.request;
|
package org.rometools.certiorem.sub.request;
|
||||||
|
|
||||||
import org.rometools.certiorem.sub.data.Subscription;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
import org.rometools.certiorem.sub.data.Subscription;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A simple requester implementation that always makes requests as Async.
|
* A simple requester implementation that always makes requests as Async.
|
||||||
|
*
|
||||||
* @author robert.cooper
|
* @author robert.cooper
|
||||||
*/
|
*/
|
||||||
public class AsyncRequester extends AbstractRequester {
|
public class AsyncRequester extends AbstractRequester {
|
||||||
@Override
|
@Override
|
||||||
public void sendSubscribeRequest(final String hubUrl, final Subscription subscription, final String verifySync,
|
public void sendSubscribeRequest(final String hubUrl, final Subscription subscription, final String verifySync, final long leaseSeconds,
|
||||||
final long leaseSeconds, final String secret, final String callbackUrl, final RequestCallback callback) {
|
final String secret, final String callbackUrl, final RequestCallback callback) {
|
||||||
Logger.getLogger(AsyncRequester.class.getName()).log(Level.FINE, "Sending subscribe request to {0} for {1} to {2}", new Object[]{hubUrl, subscription.getSourceUrl(), callbackUrl});
|
Logger.getLogger(AsyncRequester.class.getName()).log(Level.FINE, "Sending subscribe request to {0} for {1} to {2}",
|
||||||
Runnable r = new Runnable() {
|
new Object[] { hubUrl, subscription.getSourceUrl(), callbackUrl });
|
||||||
@Override
|
final Runnable r = new Runnable() {
|
||||||
public void run() {
|
@Override
|
||||||
try {
|
public void run() {
|
||||||
sendRequest(hubUrl, "subscribe", subscription, verifySync, leaseSeconds, secret, callbackUrl,
|
try {
|
||||||
callback);
|
sendRequest(hubUrl, "subscribe", subscription, verifySync, leaseSeconds, secret, callbackUrl, callback);
|
||||||
} catch (Exception ex) {
|
} catch (final Exception ex) {
|
||||||
Logger.getLogger(AsyncRequester.class.getName())
|
Logger.getLogger(AsyncRequester.class.getName()).log(Level.SEVERE, null, ex);
|
||||||
.log(Level.SEVERE, null, ex);
|
callback.onFailure(ex);
|
||||||
callback.onFailure(ex);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
new Thread(r).start();
|
};
|
||||||
|
new Thread(r).start();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sendUnsubscribeRequest(final String hubUrl, final Subscription subscription, final String verifySync,
|
public void sendUnsubscribeRequest(final String hubUrl, final Subscription subscription, final String verifySync, final String secret,
|
||||||
final String secret,
|
final String callbackUrl, final RequestCallback callback) {
|
||||||
final String callbackUrl, final RequestCallback callback) {
|
Logger.getLogger(AsyncRequester.class.getName()).log(Level.FINE, "Sending unsubscribe request to {0} for {1} to {2}",
|
||||||
Logger.getLogger(AsyncRequester.class.getName()).log(Level.FINE, "Sending unsubscribe request to {0} for {1} to {2}", new Object[]{hubUrl, subscription.getSourceUrl(), callbackUrl});
|
new Object[] { hubUrl, subscription.getSourceUrl(), callbackUrl });
|
||||||
Runnable r = new Runnable() {
|
final Runnable r = new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
sendRequest(hubUrl, "unsubscribe", subscription, verifySync, -1, secret, callbackUrl,
|
sendRequest(hubUrl, "unsubscribe", subscription, verifySync, -1, secret, callbackUrl, callback);
|
||||||
callback);
|
} catch (final IOException ex) {
|
||||||
} catch (IOException ex) {
|
Logger.getLogger(AsyncRequester.class.getName()).log(Level.SEVERE, null, ex);
|
||||||
Logger.getLogger(AsyncRequester.class.getName())
|
callback.onFailure(ex);
|
||||||
.log(Level.SEVERE, null, ex);
|
|
||||||
callback.onFailure(ex);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
new Thread(r).start();
|
};
|
||||||
|
new Thread(r).start();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,46 +22,42 @@
|
||||||
*/
|
*/
|
||||||
package org.rometools.certiorem.sub.request;
|
package org.rometools.certiorem.sub.request;
|
||||||
|
|
||||||
import org.rometools.certiorem.sub.data.Subscription;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
import org.rometools.certiorem.sub.data.Subscription;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A simple requester implementation that always makes requests as Async.
|
* A simple requester implementation that always makes requests as Async.
|
||||||
|
*
|
||||||
* @author Farrukh Najmi
|
* @author Farrukh Najmi
|
||||||
*/
|
*/
|
||||||
public class SyncRequester extends AbstractRequester {
|
public class SyncRequester extends AbstractRequester {
|
||||||
@Override
|
@Override
|
||||||
public void sendSubscribeRequest(final String hubUrl, final Subscription subscription, final String verifySync,
|
public void sendSubscribeRequest(final String hubUrl, final Subscription subscription, final String verifySync, final long leaseSeconds,
|
||||||
final long leaseSeconds, final String secret, final String callbackUrl, final RequestCallback callback) {
|
final String secret, final String callbackUrl, final RequestCallback callback) {
|
||||||
Logger.getLogger(SyncRequester.class.getName()).log(Level.INFO, "Sending subscribe request to {0} for {1} to {2}", new Object[]{hubUrl, subscription.getSourceUrl(), callbackUrl});
|
Logger.getLogger(SyncRequester.class.getName()).log(Level.INFO, "Sending subscribe request to {0} for {1} to {2}",
|
||||||
|
new Object[] { hubUrl, subscription.getSourceUrl(), callbackUrl });
|
||||||
try {
|
try {
|
||||||
sendRequest(hubUrl, "subscribe", subscription, verifySync, leaseSeconds, secret, callbackUrl,
|
sendRequest(hubUrl, "subscribe", subscription, verifySync, leaseSeconds, secret, callbackUrl, callback);
|
||||||
callback);
|
|
||||||
callback.onSuccess();
|
callback.onSuccess();
|
||||||
} catch (Exception ex) {
|
} catch (final Exception ex) {
|
||||||
Logger.getLogger(SyncRequester.class.getName())
|
Logger.getLogger(SyncRequester.class.getName()).log(Level.SEVERE, null, ex);
|
||||||
.log(Level.SEVERE, null, ex);
|
|
||||||
callback.onFailure(ex);
|
callback.onFailure(ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sendUnsubscribeRequest(final String hubUrl, final Subscription subscription, final String verifySync,
|
public void sendUnsubscribeRequest(final String hubUrl, final Subscription subscription, final String verifySync, final String secret,
|
||||||
final String secret,
|
final String callbackUrl, final RequestCallback callback) {
|
||||||
final String callbackUrl, final RequestCallback callback) {
|
Logger.getLogger(SyncRequester.class.getName()).log(Level.INFO, "Sending unsubscribe request to {0} for {1} to {2}",
|
||||||
Logger.getLogger(SyncRequester.class.getName()).log(Level.INFO, "Sending unsubscribe request to {0} for {1} to {2}", new Object[]{hubUrl, subscription.getSourceUrl(), callbackUrl});
|
new Object[] { hubUrl, subscription.getSourceUrl(), callbackUrl });
|
||||||
try {
|
try {
|
||||||
sendRequest(hubUrl, "unsubscribe", subscription, verifySync, -1, secret, callbackUrl,
|
sendRequest(hubUrl, "unsubscribe", subscription, verifySync, -1, secret, callbackUrl, callback);
|
||||||
callback);
|
|
||||||
callback.onSuccess();
|
callback.onSuccess();
|
||||||
} catch (IOException ex) {
|
} catch (final IOException ex) {
|
||||||
Logger.getLogger(SyncRequester.class.getName())
|
Logger.getLogger(SyncRequester.class.getName()).log(Level.SEVERE, null, ex);
|
||||||
.log(Level.SEVERE, null, ex);
|
|
||||||
callback.onFailure(ex);
|
callback.onFailure(ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,14 +16,9 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
package org.rometools.certiorem.web;
|
package org.rometools.certiorem.web;
|
||||||
|
|
||||||
import org.rometools.certiorem.HttpStatusCodeException;
|
|
||||||
import org.rometools.certiorem.hub.Hub;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
import javax.servlet.ServletException;
|
import javax.servlet.ServletException;
|
||||||
|
@ -31,6 +26,8 @@ import javax.servlet.http.HttpServlet;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
import org.rometools.certiorem.HttpStatusCodeException;
|
||||||
|
import org.rometools.certiorem.hub.Hub;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -46,37 +43,34 @@ public abstract class AbstractHubServlet extends HttpServlet {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
|
protected void doPost(final HttpServletRequest req, final HttpServletResponse resp) throws ServletException, IOException {
|
||||||
throws ServletException, IOException {
|
|
||||||
try {
|
try {
|
||||||
if ("publish".equals(req.getParameter(HUBMODE))) {
|
if ("publish".equals(req.getParameter(HUBMODE))) {
|
||||||
hub.sendNotification(req.getServerName(), req.getParameter("hub.url"));
|
hub.sendNotification(req.getServerName(), req.getParameter("hub.url"));
|
||||||
} else {
|
} else {
|
||||||
String callback = req.getParameter("hub.callback");
|
final String callback = req.getParameter("hub.callback");
|
||||||
String topic = req.getParameter("hub.topic");
|
final String topic = req.getParameter("hub.topic");
|
||||||
String[] verifies = req.getParameterValues("hub.verify");
|
final String[] verifies = req.getParameterValues("hub.verify");
|
||||||
String leaseString = req.getParameter("hub.lease_seconds");
|
final String leaseString = req.getParameter("hub.lease_seconds");
|
||||||
String secret = req.getParameter("hub.secret");
|
final String secret = req.getParameter("hub.secret");
|
||||||
String verifyToken = req.getParameter("hub.verify_token");
|
final String verifyToken = req.getParameter("hub.verify_token");
|
||||||
String verifyMode = Arrays.asList(verifies)
|
final String verifyMode = Arrays.asList(verifies).contains("async") ? "async" : "sync";
|
||||||
.contains("async") ? "async" : "sync";
|
|
||||||
Boolean result = null;
|
Boolean result = null;
|
||||||
|
|
||||||
if ("subscribe".equals(req.getParameter(HUBMODE))) {
|
if ("subscribe".equals(req.getParameter(HUBMODE))) {
|
||||||
long leaseSeconds = (leaseString != null) ? Long.parseLong(leaseString) : (-1);
|
final long leaseSeconds = leaseString != null ? Long.parseLong(leaseString) : -1;
|
||||||
result = hub.subscribe(callback, topic, verifyMode, leaseSeconds, secret, verifyToken);
|
result = hub.subscribe(callback, topic, verifyMode, leaseSeconds, secret, verifyToken);
|
||||||
} else if ("unsubscribe".equals(req.getParameter(HUBMODE))) {
|
} else if ("unsubscribe".equals(req.getParameter(HUBMODE))) {
|
||||||
result = hub.unsubscribe(callback, topic, verifyMode, secret, verifyToken);
|
result = hub.unsubscribe(callback, topic, verifyMode, secret, verifyToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((result != null) && !result) {
|
if (result != null && !result) {
|
||||||
throw new HttpStatusCodeException(500, "Operation failed.", null);
|
throw new HttpStatusCodeException(500, "Operation failed.", null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (HttpStatusCodeException sc) {
|
} catch (final HttpStatusCodeException sc) {
|
||||||
resp.setStatus(sc.getStatus());
|
resp.setStatus(sc.getStatus());
|
||||||
resp.getWriter()
|
resp.getWriter().println(sc.getMessage());
|
||||||
.println(sc.getMessage());
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,15 +16,16 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
package org.rometools.certiorem.web;
|
package org.rometools.certiorem.web;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
import javax.servlet.ServletException;
|
import javax.servlet.ServletException;
|
||||||
import javax.servlet.http.HttpServlet;
|
import javax.servlet.http.HttpServlet;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import javax.servlet.http.HttpUtils;
|
import javax.servlet.http.HttpUtils;
|
||||||
|
|
||||||
import org.rometools.certiorem.HttpStatusCodeException;
|
import org.rometools.certiorem.HttpStatusCodeException;
|
||||||
import org.rometools.certiorem.sub.Subscriptions;
|
import org.rometools.certiorem.sub.Subscriptions;
|
||||||
|
|
||||||
|
@ -36,25 +37,25 @@ public class AbstractSubServlet extends HttpServlet {
|
||||||
|
|
||||||
private final Subscriptions subscriptions;
|
private final Subscriptions subscriptions;
|
||||||
|
|
||||||
protected AbstractSubServlet(final Subscriptions subscriptions){
|
protected AbstractSubServlet(final Subscriptions subscriptions) {
|
||||||
super();
|
super();
|
||||||
this.subscriptions = subscriptions;
|
this.subscriptions = subscriptions;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
|
protected void doGet(final HttpServletRequest req, final HttpServletResponse resp) throws ServletException, IOException {
|
||||||
String mode = req.getParameter("hub.mode");
|
final String mode = req.getParameter("hub.mode");
|
||||||
String topic = req.getParameter("hub.topic");
|
final String topic = req.getParameter("hub.topic");
|
||||||
String challenge = req.getParameter("hub.challenge");
|
final String challenge = req.getParameter("hub.challenge");
|
||||||
String leaseString = req.getParameter("hub.lease_seconds");
|
final String leaseString = req.getParameter("hub.lease_seconds");
|
||||||
String verifyToken = req.getParameter("hub.verify_token");
|
final String verifyToken = req.getParameter("hub.verify_token");
|
||||||
try{
|
try {
|
||||||
String result = subscriptions.validate(HttpUtils.getRequestURL(req).toString(), topic, mode, challenge, leaseString, verifyToken);
|
final String result = subscriptions.validate(HttpUtils.getRequestURL(req).toString(), topic, mode, challenge, leaseString, verifyToken);
|
||||||
resp.setStatus(200);
|
resp.setStatus(200);
|
||||||
resp.getWriter().print(result);
|
resp.getWriter().print(result);
|
||||||
return;
|
return;
|
||||||
} catch(HttpStatusCodeException e){
|
} catch (final HttpStatusCodeException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
resp.setStatus(e.getStatus());
|
resp.setStatus(e.getStatus());
|
||||||
resp.getWriter().print(e.getMessage());
|
resp.getWriter().print(e.getMessage());
|
||||||
|
@ -63,17 +64,15 @@ public class AbstractSubServlet extends HttpServlet {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
|
protected void doPost(final HttpServletRequest req, final HttpServletResponse resp) throws ServletException, IOException {
|
||||||
try{
|
try {
|
||||||
this.subscriptions.callback(HttpUtils.getRequestURL(req).toString(), req.getInputStream());
|
subscriptions.callback(HttpUtils.getRequestURL(req).toString(), req.getInputStream());
|
||||||
return;
|
return;
|
||||||
} catch(HttpStatusCodeException e){
|
} catch (final HttpStatusCodeException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
resp.setStatus(e.getStatus());
|
resp.setStatus(e.getStatus());
|
||||||
resp.getWriter().println(e.getMessage());
|
resp.getWriter().println(e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,6 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
package org.rometools.certiorem.hub;
|
package org.rometools.certiorem.hub;
|
||||||
|
|
||||||
import org.rometools.certiorem.hub.data.Subscriber;
|
import org.rometools.certiorem.hub.data.Subscriber;
|
||||||
|
@ -28,22 +27,22 @@ import org.rometools.certiorem.hub.data.Subscriber;
|
||||||
public class AlwaysVerifier implements Verifier {
|
public class AlwaysVerifier implements Verifier {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void verifySubscribeAsyncronously(Subscriber subscriber, VerificationCallback callback) {
|
public void verifySubscribeAsyncronously(final Subscriber subscriber, final VerificationCallback callback) {
|
||||||
callback.onVerify(true);
|
callback.onVerify(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean verifySubcribeSyncronously(Subscriber subscriber) {
|
public boolean verifySubcribeSyncronously(final Subscriber subscriber) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void verifyUnsubscribeAsyncronously(Subscriber subscriber, VerificationCallback callback) {
|
public void verifyUnsubscribeAsyncronously(final Subscriber subscriber, final VerificationCallback callback) {
|
||||||
callback.onVerify(true);
|
callback.onVerify(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean verifyUnsubcribeSyncronously(Subscriber subscriber) {
|
public boolean verifyUnsubcribeSyncronously(final Subscriber subscriber) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,22 +18,22 @@
|
||||||
|
|
||||||
package org.rometools.certiorem.hub;
|
package org.rometools.certiorem.hub;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.fail;
|
||||||
|
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
import org.rometools.certiorem.HttpStatusCodeException;
|
|
||||||
import org.rometools.fetcher.FeedFetcher;
|
|
||||||
import org.rometools.fetcher.impl.HashMapFeedInfoCache;
|
|
||||||
import org.rometools.fetcher.impl.HttpURLFeedFetcher;
|
|
||||||
|
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.AfterClass;
|
import org.junit.AfterClass;
|
||||||
import static org.junit.Assert.*;
|
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.BeforeClass;
|
import org.junit.BeforeClass;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
import org.rometools.certiorem.HttpStatusCodeException;
|
||||||
import org.rometools.certiorem.hub.data.HubDAO;
|
import org.rometools.certiorem.hub.data.HubDAO;
|
||||||
import org.rometools.certiorem.hub.data.ram.InMemoryHubDAO;
|
import org.rometools.certiorem.hub.data.ram.InMemoryHubDAO;
|
||||||
|
import org.rometools.fetcher.FeedFetcher;
|
||||||
|
import org.rometools.fetcher.impl.HashMapFeedInfoCache;
|
||||||
|
import org.rometools.fetcher.impl.HttpURLFeedFetcher;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -66,14 +66,14 @@ public class ControllerTest {
|
||||||
public void testSubscribe() {
|
public void testSubscribe() {
|
||||||
Logger.getLogger(ControllerTest.class.getName()).info("subscribe");
|
Logger.getLogger(ControllerTest.class.getName()).info("subscribe");
|
||||||
|
|
||||||
String callback = "http://localhost/doNothing";
|
final String callback = "http://localhost/doNothing";
|
||||||
String topic = "http://feeds.feedburner.com/screaming-penguin";
|
final String topic = "http://feeds.feedburner.com/screaming-penguin";
|
||||||
long lease_seconds = -1;
|
final long lease_seconds = -1;
|
||||||
String secret = null;
|
final String secret = null;
|
||||||
String verify_token = "MyVoiceIsMyPassport";
|
final String verify_token = "MyVoiceIsMyPassport";
|
||||||
HubDAO dao = new InMemoryHubDAO();
|
final HubDAO dao = new InMemoryHubDAO();
|
||||||
Notifier notifier = null;
|
final Notifier notifier = null;
|
||||||
FeedFetcher fetcher = new HttpURLFeedFetcher(HashMapFeedInfoCache.getInstance());
|
final FeedFetcher fetcher = new HttpURLFeedFetcher(HashMapFeedInfoCache.getInstance());
|
||||||
Hub instance = new Hub(dao, new AlwaysVerifier(), notifier, fetcher);
|
Hub instance = new Hub(dao, new AlwaysVerifier(), notifier, fetcher);
|
||||||
|
|
||||||
Boolean result = instance.subscribe(callback, topic, "sync", lease_seconds, secret, verify_token);
|
Boolean result = instance.subscribe(callback, topic, "sync", lease_seconds, secret, verify_token);
|
||||||
|
@ -90,7 +90,7 @@ public class ControllerTest {
|
||||||
try {
|
try {
|
||||||
instance.subscribe(null, topic, "async", lease_seconds, secret, verify_token);
|
instance.subscribe(null, topic, "async", lease_seconds, secret, verify_token);
|
||||||
fail();
|
fail();
|
||||||
} catch (HttpStatusCodeException e) {
|
} catch (final HttpStatusCodeException e) {
|
||||||
assertEquals(400, e.getStatus());
|
assertEquals(400, e.getStatus());
|
||||||
Logger.getLogger(ControllerTest.class.getName()).info(e.getMessage());
|
Logger.getLogger(ControllerTest.class.getName()).info(e.getMessage());
|
||||||
}
|
}
|
||||||
|
@ -98,7 +98,7 @@ public class ControllerTest {
|
||||||
try {
|
try {
|
||||||
instance.subscribe(callback, null, "async", lease_seconds, secret, verify_token);
|
instance.subscribe(callback, null, "async", lease_seconds, secret, verify_token);
|
||||||
fail();
|
fail();
|
||||||
} catch (HttpStatusCodeException e) {
|
} catch (final HttpStatusCodeException e) {
|
||||||
assertEquals(400, e.getStatus());
|
assertEquals(400, e.getStatus());
|
||||||
Logger.getLogger(ControllerTest.class.getName()).info(e.getMessage());
|
Logger.getLogger(ControllerTest.class.getName()).info(e.getMessage());
|
||||||
}
|
}
|
||||||
|
@ -106,7 +106,7 @@ public class ControllerTest {
|
||||||
try {
|
try {
|
||||||
instance.subscribe(callback, topic, "foo", lease_seconds, secret, verify_token);
|
instance.subscribe(callback, topic, "foo", lease_seconds, secret, verify_token);
|
||||||
fail();
|
fail();
|
||||||
} catch (HttpStatusCodeException e) {
|
} catch (final HttpStatusCodeException e) {
|
||||||
assertEquals(400, e.getStatus());
|
assertEquals(400, e.getStatus());
|
||||||
Logger.getLogger(ControllerTest.class.getName()).info(e.getMessage());
|
Logger.getLogger(ControllerTest.class.getName()).info(e.getMessage());
|
||||||
}
|
}
|
||||||
|
@ -117,7 +117,7 @@ public class ControllerTest {
|
||||||
try {
|
try {
|
||||||
result = instance.subscribe(callback, topic, "sync", lease_seconds, secret, verify_token);
|
result = instance.subscribe(callback, topic, "sync", lease_seconds, secret, verify_token);
|
||||||
fail();
|
fail();
|
||||||
} catch (HttpStatusCodeException e) {
|
} catch (final HttpStatusCodeException e) {
|
||||||
assertEquals(500, e.getStatus());
|
assertEquals(500, e.getStatus());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,18 +5,21 @@
|
||||||
package org.rometools.certiorem.hub;
|
package org.rometools.certiorem.hub;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import com.sun.syndication.feed.synd.SyndEntry;
|
|
||||||
import java.util.List;
|
|
||||||
import junit.framework.Assert;
|
|
||||||
import org.rometools.fetcher.impl.HashMapFeedInfoCache;
|
|
||||||
import org.rometools.fetcher.impl.HttpURLFeedFetcher;
|
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import com.sun.syndication.feed.synd.SyndFeed;
|
import java.util.List;
|
||||||
|
|
||||||
|
import junit.framework.Assert;
|
||||||
|
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.AfterClass;
|
import org.junit.AfterClass;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.BeforeClass;
|
import org.junit.BeforeClass;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
import org.rometools.fetcher.impl.HashMapFeedInfoCache;
|
||||||
|
import org.rometools.fetcher.impl.HttpURLFeedFetcher;
|
||||||
|
|
||||||
|
import com.sun.syndication.feed.synd.SyndEntry;
|
||||||
|
import com.sun.syndication.feed.synd.SyndFeed;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -39,7 +42,6 @@ public class DeltaSyndFeedInfoTest {
|
||||||
public static void tearDownClass() throws Exception {
|
public static void tearDownClass() throws Exception {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
feedInfoCache = new DeltaFeedInfoCache(new HashMapFeedInfoCache());
|
feedInfoCache = new DeltaFeedInfoCache(new HashMapFeedInfoCache());
|
||||||
|
@ -50,7 +52,6 @@ public class DeltaSyndFeedInfoTest {
|
||||||
public void tearDown() {
|
public void tearDown() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test of getSyndFeed method, of class DeltaSyndFeedInfo.
|
* Test of getSyndFeed method, of class DeltaSyndFeedInfo.
|
||||||
*/
|
*/
|
||||||
|
@ -62,15 +63,15 @@ public class DeltaSyndFeedInfoTest {
|
||||||
List<SyndEntry> entries = feed.getEntries();
|
List<SyndEntry> entries = feed.getEntries();
|
||||||
Assert.assertTrue(!entries.isEmpty());
|
Assert.assertTrue(!entries.isEmpty());
|
||||||
|
|
||||||
//Fetch again and this time the entries should be empty as none have changed.
|
// Fetch again and this time the entries should be empty as none have changed.
|
||||||
feed = feedFetcher.retrieveFeed(getFeedUrl());
|
feed = feedFetcher.retrieveFeed(getFeedUrl());
|
||||||
entries = feed.getEntries();
|
entries = feed.getEntries();
|
||||||
Assert.assertTrue(entries.isEmpty());
|
Assert.assertTrue(entries.isEmpty());
|
||||||
}
|
}
|
||||||
|
|
||||||
private URL getFeedUrl() throws IOException {
|
private URL getFeedUrl() throws IOException {
|
||||||
URL feedUrl = new URL("http://news.google.com/news?pz=1&cf=all&ned=us&hl=en&output=rss");
|
final URL feedUrl = new URL("http://news.google.com/news?pz=1&cf=all&ned=us&hl=en&output=rss");
|
||||||
// URL feedUrl = new URL("http://newsrss.bbc.co.uk/rss/newsonline_world_edition/front_page/rss.xml");
|
// URL feedUrl = new URL("http://newsrss.bbc.co.uk/rss/newsonline_world_edition/front_page/rss.xml");
|
||||||
|
|
||||||
return feedUrl;
|
return feedUrl;
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,6 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
package org.rometools.certiorem.hub;
|
package org.rometools.certiorem.hub;
|
||||||
|
|
||||||
import org.rometools.certiorem.hub.data.Subscriber;
|
import org.rometools.certiorem.hub.data.Subscriber;
|
||||||
|
@ -25,25 +24,25 @@ import org.rometools.certiorem.hub.data.Subscriber;
|
||||||
*
|
*
|
||||||
* @author robert.cooper
|
* @author robert.cooper
|
||||||
*/
|
*/
|
||||||
public class ExceptionVerifier implements Verifier{
|
public class ExceptionVerifier implements Verifier {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void verifySubscribeAsyncronously(Subscriber subscriber, VerificationCallback callback) {
|
public void verifySubscribeAsyncronously(final Subscriber subscriber, final VerificationCallback callback) {
|
||||||
throw new UnsupportedOperationException("Not supported yet.");
|
throw new UnsupportedOperationException("Not supported yet.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean verifySubcribeSyncronously(Subscriber subscriber) {
|
public boolean verifySubcribeSyncronously(final Subscriber subscriber) {
|
||||||
throw new UnsupportedOperationException("Not supported yet.");
|
throw new UnsupportedOperationException("Not supported yet.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void verifyUnsubscribeAsyncronously(Subscriber subscriber, VerificationCallback callback) {
|
public void verifyUnsubscribeAsyncronously(final Subscriber subscriber, final VerificationCallback callback) {
|
||||||
throw new UnsupportedOperationException("Not supported yet.");
|
throw new UnsupportedOperationException("Not supported yet.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean verifyUnsubcribeSyncronously(Subscriber subscriber) {
|
public boolean verifyUnsubcribeSyncronously(final Subscriber subscriber) {
|
||||||
throw new UnsupportedOperationException("Not supported yet.");
|
throw new UnsupportedOperationException("Not supported yet.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,6 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
package org.rometools.certiorem.hub;
|
package org.rometools.certiorem.hub;
|
||||||
|
|
||||||
import org.rometools.certiorem.hub.data.Subscriber;
|
import org.rometools.certiorem.hub.data.Subscriber;
|
||||||
|
@ -25,25 +24,25 @@ import org.rometools.certiorem.hub.data.Subscriber;
|
||||||
*
|
*
|
||||||
* @author robert.cooper
|
* @author robert.cooper
|
||||||
*/
|
*/
|
||||||
public class NeverVerifier implements Verifier{
|
public class NeverVerifier implements Verifier {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void verifySubscribeAsyncronously(Subscriber subscriber, VerificationCallback callback) {
|
public void verifySubscribeAsyncronously(final Subscriber subscriber, final VerificationCallback callback) {
|
||||||
callback.onVerify(false);
|
callback.onVerify(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean verifySubcribeSyncronously(Subscriber subscriber) {
|
public boolean verifySubcribeSyncronously(final Subscriber subscriber) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void verifyUnsubscribeAsyncronously(Subscriber subscriber, VerificationCallback callback) {
|
public void verifyUnsubscribeAsyncronously(final Subscriber subscriber, final VerificationCallback callback) {
|
||||||
callback.onVerify(false);
|
callback.onVerify(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean verifyUnsubcribeSyncronously(Subscriber subscriber) {
|
public boolean verifyUnsubcribeSyncronously(final Subscriber subscriber) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,7 @@ package org.rometools.certiorem.hub.data;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -33,40 +34,40 @@ public abstract class AbstractDAOTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSubscribe() {
|
public void testSubscribe() {
|
||||||
HubDAO instance = get();
|
final HubDAO instance = get();
|
||||||
Logger.getLogger(AbstractDAOTest.class.getName()).log(Level.INFO, "{0} testSubscribe", instance.getClass().getName());
|
Logger.getLogger(AbstractDAOTest.class.getName()).log(Level.INFO, "{0} testSubscribe", instance.getClass().getName());
|
||||||
Subscriber subscriber = new Subscriber();
|
final Subscriber subscriber = new Subscriber();
|
||||||
subscriber.setCallback("http://localhost:9797/noop");
|
subscriber.setCallback("http://localhost:9797/noop");
|
||||||
subscriber.setTopic("http://feeds.feedburner.com/screaming-penguin");
|
subscriber.setTopic("http://feeds.feedburner.com/screaming-penguin");
|
||||||
subscriber.setLeaseSeconds(-1);
|
subscriber.setLeaseSeconds(-1);
|
||||||
subscriber.setVerify("VerifyMe");
|
subscriber.setVerify("VerifyMe");
|
||||||
|
|
||||||
Subscriber result = instance.addSubscriber(subscriber);
|
final Subscriber result = instance.addSubscriber(subscriber);
|
||||||
|
|
||||||
assert result.equals(subscriber) : "Subscriber not equal.";
|
assert result.equals(subscriber) : "Subscriber not equal.";
|
||||||
|
|
||||||
List<Subscriber> subscribers = (List<Subscriber>) instance.subscribersForTopic(subscriber.getTopic());
|
final List<Subscriber> subscribers = (List<Subscriber>) instance.subscribersForTopic(subscriber.getTopic());
|
||||||
|
|
||||||
assert subscribers.contains(result) : "Subscriber not in result.";
|
assert subscribers.contains(result) : "Subscriber not in result.";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testLeaseExpire() throws InterruptedException {
|
public void testLeaseExpire() throws InterruptedException {
|
||||||
HubDAO instance = get();
|
final HubDAO instance = get();
|
||||||
Logger.getLogger(AbstractDAOTest.class.getName()).log(Level.INFO, "{0} testLeaseExpire", instance.getClass().getName());
|
Logger.getLogger(AbstractDAOTest.class.getName()).log(Level.INFO, "{0} testLeaseExpire", instance.getClass().getName());
|
||||||
Subscriber subscriber = new Subscriber();
|
final Subscriber subscriber = new Subscriber();
|
||||||
subscriber.setCallback("http://localhost:9797/noop");
|
subscriber.setCallback("http://localhost:9797/noop");
|
||||||
subscriber.setTopic("http://feeds.feedburner.com/screaming-penguin");
|
subscriber.setTopic("http://feeds.feedburner.com/screaming-penguin");
|
||||||
subscriber.setLeaseSeconds(1);
|
subscriber.setLeaseSeconds(1);
|
||||||
subscriber.setVerify("VerifyMe");
|
subscriber.setVerify("VerifyMe");
|
||||||
|
|
||||||
Subscriber result = instance.addSubscriber(subscriber);
|
final Subscriber result = instance.addSubscriber(subscriber);
|
||||||
|
|
||||||
assert subscriber.equals(result) : "Subscriber not equal.";
|
assert subscriber.equals(result) : "Subscriber not equal.";
|
||||||
//quick test for store.
|
// quick test for store.
|
||||||
List<Subscriber> subscribers = (List<Subscriber>) instance.subscribersForTopic(subscriber.getTopic());
|
List<Subscriber> subscribers = (List<Subscriber>) instance.subscribersForTopic(subscriber.getTopic());
|
||||||
assert subscribers.contains(result) : "Subscriber not in result.";
|
assert subscribers.contains(result) : "Subscriber not in result.";
|
||||||
//sleep past expiration
|
// sleep past expiration
|
||||||
Thread.sleep(1100);
|
Thread.sleep(1100);
|
||||||
subscribers = (List<Subscriber>) instance.subscribersForTopic(subscriber.getTopic());
|
subscribers = (List<Subscriber>) instance.subscribersForTopic(subscriber.getTopic());
|
||||||
assert !subscribers.contains(result) : "Subscriber should have expired";
|
assert !subscribers.contains(result) : "Subscriber should have expired";
|
||||||
|
@ -74,15 +75,15 @@ public abstract class AbstractDAOTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testUnsubscribe() throws InterruptedException {
|
public void testUnsubscribe() throws InterruptedException {
|
||||||
HubDAO instance = get();
|
final HubDAO instance = get();
|
||||||
Logger.getLogger(AbstractDAOTest.class.getName()).log(Level.INFO, "{0} testUnsubscribe", instance.getClass().getName());
|
Logger.getLogger(AbstractDAOTest.class.getName()).log(Level.INFO, "{0} testUnsubscribe", instance.getClass().getName());
|
||||||
Subscriber subscriber = new Subscriber();
|
final Subscriber subscriber = new Subscriber();
|
||||||
subscriber.setCallback("http://localhost:9797/noop");
|
subscriber.setCallback("http://localhost:9797/noop");
|
||||||
subscriber.setTopic("http://feeds.feedburner.com/screaming-penguin");
|
subscriber.setTopic("http://feeds.feedburner.com/screaming-penguin");
|
||||||
subscriber.setLeaseSeconds(1);
|
subscriber.setLeaseSeconds(1);
|
||||||
subscriber.setVerify("VerifyMe");
|
subscriber.setVerify("VerifyMe");
|
||||||
|
|
||||||
Subscriber result = instance.addSubscriber(subscriber);
|
final Subscriber result = instance.addSubscriber(subscriber);
|
||||||
// TODO
|
// TODO
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,6 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
package org.rometools.certiorem.hub.data.ram;
|
package org.rometools.certiorem.hub.data.ram;
|
||||||
|
|
||||||
import org.rometools.certiorem.hub.data.AbstractDAOTest;
|
import org.rometools.certiorem.hub.data.AbstractDAOTest;
|
||||||
|
@ -26,8 +25,8 @@ import org.rometools.certiorem.hub.data.HubDAO;
|
||||||
*
|
*
|
||||||
* @author robert.cooper
|
* @author robert.cooper
|
||||||
*/
|
*/
|
||||||
public class InMemoryDAOTest extends AbstractDAOTest{
|
public class InMemoryDAOTest extends AbstractDAOTest {
|
||||||
private InMemoryHubDAO dao = new InMemoryHubDAO();
|
private final InMemoryHubDAO dao = new InMemoryHubDAO();
|
||||||
|
|
||||||
public InMemoryDAOTest() {
|
public InMemoryDAOTest() {
|
||||||
}
|
}
|
||||||
|
@ -37,8 +36,4 @@ public class InMemoryDAOTest extends AbstractDAOTest{
|
||||||
return dao;
|
return dao;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
1
src/test/resources/.gitignore
vendored
Normal file
1
src/test/resources/.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
# needed to commit empty folder
|
Loading…
Reference in a new issue