diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 00000000..757955ad --- /dev/null +++ b/.editorconfig @@ -0,0 +1,1397 @@ +[*] +charset = utf-8 +end_of_line = lf +indent_size = 4 +indent_style = space +insert_final_newline = false +max_line_length = 112 +tab_width = 4 +ij_continuation_indent_size = 8 +ij_formatter_off_tag = @formatter:off +ij_formatter_on_tag = @formatter:on +ij_formatter_tags_enabled = false +ij_smart_tabs = false +ij_visual_guides = none +ij_wrap_on_typing = false + +[*.css] +indent_size = 2 +tab_width = 2 +ij_continuation_indent_size = 2 +ij_css_align_closing_brace_with_properties = false +ij_css_blank_lines_around_nested_selector = 1 +ij_css_blank_lines_between_blocks = 1 +ij_css_brace_placement = end_of_line +ij_css_enforce_quotes_on_format = false +ij_css_hex_color_long_format = false +ij_css_hex_color_lower_case = false +ij_css_hex_color_short_format = false +ij_css_hex_color_upper_case = true +ij_css_keep_blank_lines_in_code = 2 +ij_css_keep_indents_on_empty_lines = false +ij_css_keep_single_line_blocks = false +ij_css_properties_order = font,font-family,font-size,font-weight,font-style,font-variant,font-size-adjust,font-stretch,line-height,position,z-index,top,right,bottom,left,display,visibility,float,clear,overflow,overflow-x,overflow-y,clip,zoom,align-content,align-items,align-self,flex,flex-flow,flex-basis,flex-direction,flex-grow,flex-shrink,flex-wrap,justify-content,order,box-sizing,width,min-width,max-width,height,min-height,max-height,margin,margin-top,margin-right,margin-bottom,margin-left,padding,padding-top,padding-right,padding-bottom,padding-left,table-layout,empty-cells,caption-side,border-spacing,border-collapse,list-style,list-style-position,list-style-type,list-style-image,content,quotes,counter-reset,counter-increment,resize,cursor,user-select,nav-index,nav-up,nav-right,nav-down,nav-left,transition,transition-delay,transition-timing-function,transition-duration,transition-property,transform,transform-origin,animation,animation-name,animation-duration,animation-play-state,animation-timing-function,animation-delay,animation-iteration-count,animation-direction,text-align,text-align-last,vertical-align,white-space,text-decoration,text-emphasis,text-emphasis-color,text-emphasis-style,text-emphasis-position,text-indent,text-justify,letter-spacing,word-spacing,text-outline,text-transform,text-wrap,text-overflow,text-overflow-ellipsis,text-overflow-mode,word-wrap,word-break,tab-size,hyphens,pointer-events,opacity,color,border,border-width,border-style,border-color,border-top,border-top-width,border-top-style,border-top-color,border-right,border-right-width,border-right-style,border-right-color,border-bottom,border-bottom-width,border-bottom-style,border-bottom-color,border-left,border-left-width,border-left-style,border-left-color,border-radius,border-top-left-radius,border-top-right-radius,border-bottom-right-radius,border-bottom-left-radius,border-image,border-image-source,border-image-slice,border-image-width,border-image-outset,border-image-repeat,outline,outline-width,outline-style,outline-color,outline-offset,background,background-color,background-image,background-repeat,background-attachment,background-position,background-position-x,background-position-y,background-clip,background-origin,background-size,box-decoration-break,box-shadow,text-shadow +ij_css_space_after_colon = true +ij_css_space_before_opening_brace = true +ij_css_use_double_quotes = true +ij_css_value_alignment = do_not_align + +[*.feature] +indent_size = 2 +ij_gherkin_keep_indents_on_empty_lines = false + +[*.gsp] +ij_gsp_keep_indents_on_empty_lines = false + +[*.haml] +indent_size = 2 +ij_haml_keep_indents_on_empty_lines = false + +[*.java] +ij_java_align_consecutive_assignments = false +ij_java_align_consecutive_variable_declarations = false +ij_java_align_group_field_declarations = false +ij_java_align_multiline_annotation_parameters = false +ij_java_align_multiline_array_initializer_expression = true +ij_java_align_multiline_assignment = true +ij_java_align_multiline_binary_operation = true +ij_java_align_multiline_chained_methods = true +ij_java_align_multiline_extends_list = true +ij_java_align_multiline_for = true +ij_java_align_multiline_method_parentheses = false +ij_java_align_multiline_parameters = true +ij_java_align_multiline_parameters_in_calls = true +ij_java_align_multiline_parenthesized_expression = false +ij_java_align_multiline_records = true +ij_java_align_multiline_resources = true +ij_java_align_multiline_ternary_operation = true +ij_java_align_multiline_text_blocks = false +ij_java_align_multiline_throws_list = true +ij_java_align_subsequent_simple_methods = false +ij_java_align_throws_keyword = false +ij_java_annotation_parameter_wrap = normal +ij_java_array_initializer_new_line_after_left_brace = true +ij_java_array_initializer_right_brace_on_new_line = true +ij_java_array_initializer_wrap = normal +ij_java_assert_statement_colon_on_next_line = false +ij_java_assert_statement_wrap = normal +ij_java_assignment_wrap = normal +ij_java_binary_operation_sign_on_next_line = true +ij_java_binary_operation_wrap = normal +ij_java_blank_lines_after_anonymous_class_header = 0 +ij_java_blank_lines_after_class_header = 0 +ij_java_blank_lines_after_imports = 1 +ij_java_blank_lines_after_package = 1 +ij_java_blank_lines_around_class = 1 +ij_java_blank_lines_around_field = 0 +ij_java_blank_lines_around_field_in_interface = 0 +ij_java_blank_lines_around_initializer = 1 +ij_java_blank_lines_around_method = 1 +ij_java_blank_lines_around_method_in_interface = 1 +ij_java_blank_lines_before_class_end = 0 +ij_java_blank_lines_before_imports = 1 +ij_java_blank_lines_before_method_body = 0 +ij_java_blank_lines_before_package = 0 +ij_java_block_brace_style = end_of_line +ij_java_block_comment_at_first_column = true +ij_java_builder_methods = none +ij_java_call_parameters_new_line_after_left_paren = false +ij_java_call_parameters_right_paren_on_new_line = false +ij_java_call_parameters_wrap = normal +ij_java_case_statement_on_separate_line = true +ij_java_catch_on_new_line = false +ij_java_class_annotation_wrap = split_into_lines +ij_java_class_brace_style = end_of_line +ij_java_class_count_to_use_import_on_demand = 1048576 +ij_java_class_names_in_javadoc = 3 +ij_java_do_not_indent_top_level_class_members = false +ij_java_do_not_wrap_after_single_annotation = false +ij_java_do_while_brace_force = always +ij_java_doc_add_blank_line_after_description = true +ij_java_doc_add_blank_line_after_param_comments = true +ij_java_doc_add_blank_line_after_return = true +ij_java_doc_add_p_tag_on_empty_lines = true +ij_java_doc_align_exception_comments = false +ij_java_doc_align_param_comments = false +ij_java_doc_do_not_wrap_if_one_line = true +ij_java_doc_enable_formatting = false +ij_java_doc_enable_leading_asterisks = true +ij_java_doc_indent_on_continuation = false +ij_java_doc_keep_empty_lines = true +ij_java_doc_keep_empty_parameter_tag = false +ij_java_doc_keep_empty_return_tag = false +ij_java_doc_keep_empty_throws_tag = true +ij_java_doc_keep_invalid_tags = true +ij_java_doc_param_description_on_new_line = false +ij_java_doc_preserve_line_breaks = true +ij_java_doc_use_throws_not_exception_tag = true +ij_java_else_on_new_line = false +ij_java_entity_dd_suffix = EJB +ij_java_entity_eb_suffix = Bean +ij_java_entity_hi_suffix = Home +ij_java_entity_lhi_prefix = Local +ij_java_entity_lhi_suffix = Home +ij_java_entity_li_prefix = Local +ij_java_entity_pk_class = java.lang.String +ij_java_entity_vo_suffix = VO +ij_java_enum_constants_wrap = normal +ij_java_extends_keyword_wrap = normal +ij_java_extends_list_wrap = normal +ij_java_field_annotation_wrap = split_into_lines +ij_java_finally_on_new_line = false +ij_java_for_brace_force = always +ij_java_for_statement_new_line_after_left_paren = false +ij_java_for_statement_right_paren_on_new_line = false +ij_java_for_statement_wrap = normal +ij_java_generate_final_locals = false +ij_java_generate_final_parameters = false +ij_java_if_brace_force = always +ij_java_imports_layout = $*,|,java.**,|,javax.**,|,org.**,|,android.**,|,net.**,|,com.**,|,com.linecorp.**,|,com.nhn.**,|,com.nhncorp.**,|,jp.naver.**,|,*,| +ij_java_indent_case_from_switch = true +ij_java_insert_inner_class_imports = true +ij_java_insert_override_annotation = true +ij_java_keep_blank_lines_before_right_brace = 1 +ij_java_keep_blank_lines_between_package_declaration_and_header = 2 +ij_java_keep_blank_lines_in_code = 1 +ij_java_keep_blank_lines_in_declarations = 1 +ij_java_keep_builder_methods_indents = false +ij_java_keep_control_statement_in_one_line = true +ij_java_keep_first_column_comment = true +ij_java_keep_indents_on_empty_lines = false +ij_java_keep_line_breaks = true +ij_java_keep_multiple_expressions_in_one_line = false +ij_java_keep_simple_blocks_in_one_line = true +ij_java_keep_simple_classes_in_one_line = true +ij_java_keep_simple_lambdas_in_one_line = false +ij_java_keep_simple_methods_in_one_line = true +ij_java_label_indent_absolute = false +ij_java_label_indent_size = 0 +ij_java_lambda_brace_style = end_of_line +ij_java_layout_static_imports_separately = true +ij_java_line_comment_add_space = false +ij_java_line_comment_at_first_column = true +ij_java_message_dd_suffix = EJB +ij_java_message_eb_suffix = Bean +ij_java_method_annotation_wrap = split_into_lines +ij_java_method_brace_style = end_of_line +ij_java_method_call_chain_wrap = normal +ij_java_method_parameters_new_line_after_left_paren = false +ij_java_method_parameters_right_paren_on_new_line = false +ij_java_method_parameters_wrap = normal +ij_java_modifier_list_wrap = false +ij_java_names_count_to_use_import_on_demand = 1048576 +ij_java_new_line_after_lparen_in_record_header = false +ij_java_parameter_annotation_wrap = normal +ij_java_parentheses_expression_new_line_after_left_paren = false +ij_java_parentheses_expression_right_paren_on_new_line = false +ij_java_place_assignment_sign_on_next_line = false +ij_java_prefer_longer_names = true +ij_java_prefer_parameters_wrap = true +ij_java_record_components_wrap = normal +ij_java_repeat_synchronized = true +ij_java_replace_instanceof_and_cast = false +ij_java_replace_null_check = true +ij_java_replace_sum_lambda_with_method_ref = true +ij_java_resource_list_new_line_after_left_paren = false +ij_java_resource_list_right_paren_on_new_line = false +ij_java_resource_list_wrap = normal +ij_java_rparen_on_new_line_in_record_header = false +ij_java_session_dd_suffix = EJB +ij_java_session_eb_suffix = Bean +ij_java_session_hi_suffix = Home +ij_java_session_lhi_prefix = Local +ij_java_session_lhi_suffix = Home +ij_java_session_li_prefix = Local +ij_java_session_si_suffix = Service +ij_java_space_after_closing_angle_bracket_in_type_argument = false +ij_java_space_after_colon = true +ij_java_space_after_comma = true +ij_java_space_after_comma_in_type_arguments = true +ij_java_space_after_for_semicolon = true +ij_java_space_after_quest = true +ij_java_space_after_type_cast = true +ij_java_space_before_annotation_array_initializer_left_brace = false +ij_java_space_before_annotation_parameter_list = false +ij_java_space_before_array_initializer_left_brace = true +ij_java_space_before_catch_keyword = true +ij_java_space_before_catch_left_brace = true +ij_java_space_before_catch_parentheses = true +ij_java_space_before_class_left_brace = true +ij_java_space_before_colon = true +ij_java_space_before_colon_in_foreach = true +ij_java_space_before_comma = false +ij_java_space_before_do_left_brace = true +ij_java_space_before_else_keyword = true +ij_java_space_before_else_left_brace = true +ij_java_space_before_finally_keyword = true +ij_java_space_before_finally_left_brace = true +ij_java_space_before_for_left_brace = true +ij_java_space_before_for_parentheses = true +ij_java_space_before_for_semicolon = false +ij_java_space_before_if_left_brace = true +ij_java_space_before_if_parentheses = true +ij_java_space_before_method_call_parentheses = false +ij_java_space_before_method_left_brace = true +ij_java_space_before_method_parentheses = false +ij_java_space_before_opening_angle_bracket_in_type_parameter = false +ij_java_space_before_quest = true +ij_java_space_before_switch_left_brace = true +ij_java_space_before_switch_parentheses = true +ij_java_space_before_synchronized_left_brace = true +ij_java_space_before_synchronized_parentheses = true +ij_java_space_before_try_left_brace = true +ij_java_space_before_try_parentheses = true +ij_java_space_before_type_parameter_list = false +ij_java_space_before_while_keyword = true +ij_java_space_before_while_left_brace = true +ij_java_space_before_while_parentheses = true +ij_java_space_inside_one_line_enum_braces = false +ij_java_space_within_empty_array_initializer_braces = false +ij_java_space_within_empty_method_call_parentheses = false +ij_java_space_within_empty_method_parentheses = false +ij_java_spaces_around_additive_operators = true +ij_java_spaces_around_assignment_operators = true +ij_java_spaces_around_bitwise_operators = true +ij_java_spaces_around_equality_operators = true +ij_java_spaces_around_lambda_arrow = true +ij_java_spaces_around_logical_operators = true +ij_java_spaces_around_method_ref_dbl_colon = false +ij_java_spaces_around_multiplicative_operators = true +ij_java_spaces_around_relational_operators = true +ij_java_spaces_around_shift_operators = true +ij_java_spaces_around_type_bounds_in_type_parameters = true +ij_java_spaces_around_unary_operator = false +ij_java_spaces_within_angle_brackets = false +ij_java_spaces_within_annotation_parentheses = false +ij_java_spaces_within_array_initializer_braces = true +ij_java_spaces_within_braces = false +ij_java_spaces_within_brackets = false +ij_java_spaces_within_cast_parentheses = false +ij_java_spaces_within_catch_parentheses = false +ij_java_spaces_within_for_parentheses = false +ij_java_spaces_within_if_parentheses = false +ij_java_spaces_within_method_call_parentheses = false +ij_java_spaces_within_method_parentheses = false +ij_java_spaces_within_parentheses = false +ij_java_spaces_within_record_header = false +ij_java_spaces_within_switch_parentheses = false +ij_java_spaces_within_synchronized_parentheses = false +ij_java_spaces_within_try_parentheses = false +ij_java_spaces_within_while_parentheses = false +ij_java_special_else_if_treatment = true +ij_java_subclass_name_suffix = Impl +ij_java_ternary_operation_signs_on_next_line = false +ij_java_ternary_operation_wrap = normal +ij_java_test_name_suffix = Test +ij_java_throws_keyword_wrap = normal +ij_java_throws_list_wrap = normal +ij_java_use_external_annotations = false +ij_java_use_fq_class_names = false +ij_java_use_relative_indents = false +ij_java_use_single_class_imports = true +ij_java_variable_annotation_wrap = split_into_lines +ij_java_visibility = public +ij_java_while_brace_force = always +ij_java_while_on_new_line = false +ij_java_wrap_comments = false +ij_java_wrap_first_method_in_call_chain = false +ij_java_wrap_long_lines = false + +[*.less] +indent_size = 2 +ij_less_align_closing_brace_with_properties = false +ij_less_blank_lines_around_nested_selector = 1 +ij_less_blank_lines_between_blocks = 1 +ij_less_brace_placement = 0 +ij_less_enforce_quotes_on_format = false +ij_less_hex_color_long_format = false +ij_less_hex_color_lower_case = false +ij_less_hex_color_short_format = false +ij_less_hex_color_upper_case = false +ij_less_keep_blank_lines_in_code = 2 +ij_less_keep_indents_on_empty_lines = false +ij_less_keep_single_line_blocks = false +ij_less_properties_order = font,font-family,font-size,font-weight,font-style,font-variant,font-size-adjust,font-stretch,line-height,position,z-index,top,right,bottom,left,display,visibility,float,clear,overflow,overflow-x,overflow-y,clip,zoom,align-content,align-items,align-self,flex,flex-flow,flex-basis,flex-direction,flex-grow,flex-shrink,flex-wrap,justify-content,order,box-sizing,width,min-width,max-width,height,min-height,max-height,margin,margin-top,margin-right,margin-bottom,margin-left,padding,padding-top,padding-right,padding-bottom,padding-left,table-layout,empty-cells,caption-side,border-spacing,border-collapse,list-style,list-style-position,list-style-type,list-style-image,content,quotes,counter-reset,counter-increment,resize,cursor,user-select,nav-index,nav-up,nav-right,nav-down,nav-left,transition,transition-delay,transition-timing-function,transition-duration,transition-property,transform,transform-origin,animation,animation-name,animation-duration,animation-play-state,animation-timing-function,animation-delay,animation-iteration-count,animation-direction,text-align,text-align-last,vertical-align,white-space,text-decoration,text-emphasis,text-emphasis-color,text-emphasis-style,text-emphasis-position,text-indent,text-justify,letter-spacing,word-spacing,text-outline,text-transform,text-wrap,text-overflow,text-overflow-ellipsis,text-overflow-mode,word-wrap,word-break,tab-size,hyphens,pointer-events,opacity,color,border,border-width,border-style,border-color,border-top,border-top-width,border-top-style,border-top-color,border-right,border-right-width,border-right-style,border-right-color,border-bottom,border-bottom-width,border-bottom-style,border-bottom-color,border-left,border-left-width,border-left-style,border-left-color,border-radius,border-top-left-radius,border-top-right-radius,border-bottom-right-radius,border-bottom-left-radius,border-image,border-image-source,border-image-slice,border-image-width,border-image-outset,border-image-repeat,outline,outline-width,outline-style,outline-color,outline-offset,background,background-color,background-image,background-repeat,background-attachment,background-position,background-position-x,background-position-y,background-clip,background-origin,background-size,box-decoration-break,box-shadow,text-shadow +ij_less_space_after_colon = true +ij_less_space_before_opening_brace = true +ij_less_use_double_quotes = true +ij_less_value_alignment = 0 + +[*.proto] +indent_size = 2 +tab_width = 2 +ij_continuation_indent_size = 4 +ij_protobuf_keep_blank_lines_in_code = 2 +ij_protobuf_keep_indents_on_empty_lines = false +ij_protobuf_keep_line_breaks = true +ij_protobuf_space_after_comma = true +ij_protobuf_space_before_comma = false +ij_protobuf_spaces_around_assignment_operators = true +ij_protobuf_spaces_within_braces = false +ij_protobuf_spaces_within_brackets = false + +[*.sass] +indent_size = 2 +ij_sass_align_closing_brace_with_properties = false +ij_sass_blank_lines_around_nested_selector = 1 +ij_sass_blank_lines_between_blocks = 1 +ij_sass_brace_placement = 0 +ij_sass_enforce_quotes_on_format = false +ij_sass_hex_color_long_format = false +ij_sass_hex_color_lower_case = false +ij_sass_hex_color_short_format = false +ij_sass_hex_color_upper_case = false +ij_sass_keep_blank_lines_in_code = 2 +ij_sass_keep_indents_on_empty_lines = false +ij_sass_keep_single_line_blocks = false +ij_sass_properties_order = font,font-family,font-size,font-weight,font-style,font-variant,font-size-adjust,font-stretch,line-height,position,z-index,top,right,bottom,left,display,visibility,float,clear,overflow,overflow-x,overflow-y,clip,zoom,align-content,align-items,align-self,flex,flex-flow,flex-basis,flex-direction,flex-grow,flex-shrink,flex-wrap,justify-content,order,box-sizing,width,min-width,max-width,height,min-height,max-height,margin,margin-top,margin-right,margin-bottom,margin-left,padding,padding-top,padding-right,padding-bottom,padding-left,table-layout,empty-cells,caption-side,border-spacing,border-collapse,list-style,list-style-position,list-style-type,list-style-image,content,quotes,counter-reset,counter-increment,resize,cursor,user-select,nav-index,nav-up,nav-right,nav-down,nav-left,transition,transition-delay,transition-timing-function,transition-duration,transition-property,transform,transform-origin,animation,animation-name,animation-duration,animation-play-state,animation-timing-function,animation-delay,animation-iteration-count,animation-direction,text-align,text-align-last,vertical-align,white-space,text-decoration,text-emphasis,text-emphasis-color,text-emphasis-style,text-emphasis-position,text-indent,text-justify,letter-spacing,word-spacing,text-outline,text-transform,text-wrap,text-overflow,text-overflow-ellipsis,text-overflow-mode,word-wrap,word-break,tab-size,hyphens,pointer-events,opacity,color,border,border-width,border-style,border-color,border-top,border-top-width,border-top-style,border-top-color,border-right,border-right-width,border-right-style,border-right-color,border-bottom,border-bottom-width,border-bottom-style,border-bottom-color,border-left,border-left-width,border-left-style,border-left-color,border-radius,border-top-left-radius,border-top-right-radius,border-bottom-right-radius,border-bottom-left-radius,border-image,border-image-source,border-image-slice,border-image-width,border-image-outset,border-image-repeat,outline,outline-width,outline-style,outline-color,outline-offset,background,background-color,background-image,background-repeat,background-attachment,background-position,background-position-x,background-position-y,background-clip,background-origin,background-size,box-decoration-break,box-shadow,text-shadow +ij_sass_space_after_colon = true +ij_sass_space_before_opening_brace = true +ij_sass_use_double_quotes = true +ij_sass_value_alignment = 0 + +[*.scala] +indent_size = 2 +tab_width = 2 +ij_continuation_indent_size = 2 +ij_scala_align_composite_pattern = true +ij_scala_align_extends_with = 0 +ij_scala_align_group_field_declarations = false +ij_scala_align_if_else = false +ij_scala_align_in_columns_case_branch = false +ij_scala_align_multiline_binary_operation = false +ij_scala_align_multiline_chained_methods = false +ij_scala_align_multiline_for = true +ij_scala_align_multiline_parameters = true +ij_scala_align_multiline_parameters_in_calls = false +ij_scala_align_multiline_parenthesized_expression = false +ij_scala_align_parameter_types_in_multiline_declarations = 0 +ij_scala_align_tuple_elements = false +ij_scala_alternate_continuation_indent_for_params = 4 +ij_scala_binary_operation_wrap = off +ij_scala_blank_lines_after_anonymous_class_header = 0 +ij_scala_blank_lines_after_class_header = 0 +ij_scala_blank_lines_after_imports = 1 +ij_scala_blank_lines_after_package = 1 +ij_scala_blank_lines_around_class = 1 +ij_scala_blank_lines_around_class_in_inner_scopes = 0 +ij_scala_blank_lines_around_field = 0 +ij_scala_blank_lines_around_field_in_inner_scopes = 0 +ij_scala_blank_lines_around_field_in_interface = 0 +ij_scala_blank_lines_around_method = 1 +ij_scala_blank_lines_around_method_in_inner_scopes = 1 +ij_scala_blank_lines_around_method_in_interface = 1 +ij_scala_blank_lines_before_class_end = 0 +ij_scala_blank_lines_before_imports = 1 +ij_scala_blank_lines_before_method_body = 0 +ij_scala_blank_lines_before_package = 0 +ij_scala_block_brace_style = end_of_line +ij_scala_block_comment_at_first_column = true +ij_scala_call_parameters_new_line_after_lparen = 0 +ij_scala_call_parameters_right_paren_on_new_line = false +ij_scala_call_parameters_wrap = off +ij_scala_case_clause_brace_force = never +ij_scala_catch_on_new_line = false +ij_scala_class_annotation_wrap = split_into_lines +ij_scala_class_brace_style = end_of_line +ij_scala_closure_brace_force = never +ij_scala_do_not_align_block_expr_params = true +ij_scala_do_not_indent_case_clause_body = false +ij_scala_do_not_indent_tuples_close_brace = true +ij_scala_do_while_brace_force = never +ij_scala_else_on_new_line = false +ij_scala_enable_scaladoc_formatting = true +ij_scala_enforce_functional_syntax_for_unit = true +ij_scala_extends_keyword_wrap = off +ij_scala_extends_list_wrap = off +ij_scala_field_annotation_wrap = split_into_lines +ij_scala_finally_brace_force = never +ij_scala_finally_on_new_line = false +ij_scala_for_brace_force = never +ij_scala_for_statement_wrap = off +ij_scala_formatter = 0 +ij_scala_if_brace_force = never +ij_scala_implicit_value_class_suffix = Ops +ij_scala_indent_braced_function_args = true +ij_scala_indent_case_from_switch = true +ij_scala_indent_first_parameter = true +ij_scala_indent_first_parameter_clause = false +ij_scala_indent_type_arguments = true +ij_scala_indent_type_parameters = true +ij_scala_indent_yield_after_one_line_enumerators = true +ij_scala_keep_blank_lines_before_right_brace = 2 +ij_scala_keep_blank_lines_in_code = 2 +ij_scala_keep_blank_lines_in_declarations = 2 +ij_scala_keep_comments_on_same_line = true +ij_scala_keep_first_column_comment = false +ij_scala_keep_indents_on_empty_lines = false +ij_scala_keep_line_breaks = true +ij_scala_keep_one_line_lambdas_in_arg_list = false +ij_scala_keep_simple_blocks_in_one_line = false +ij_scala_keep_simple_methods_in_one_line = false +ij_scala_keep_xml_formatting = false +ij_scala_line_comment_add_space = false +ij_scala_line_comment_at_first_column = true +ij_scala_method_annotation_wrap = split_into_lines +ij_scala_method_brace_force = never +ij_scala_method_brace_style = end_of_line +ij_scala_method_call_chain_wrap = off +ij_scala_method_parameters_new_line_after_left_paren = false +ij_scala_method_parameters_right_paren_on_new_line = false +ij_scala_method_parameters_wrap = off +ij_scala_modifier_list_wrap = false +ij_scala_multiline_string_align_dangling_closing_quotes = false +ij_scala_multiline_string_closing_quotes_on_new_line = false +ij_scala_multiline_string_insert_margin_on_enter = true +ij_scala_multiline_string_margin_char = | +ij_scala_multiline_string_margin_indent = 2 +ij_scala_multiline_string_opening_quotes_on_new_line = true +ij_scala_multiline_string_process_margin_on_copy_paste = true +ij_scala_newline_after_annotations = false +ij_scala_not_continuation_indent_for_params = false +ij_scala_parameter_annotation_wrap = off +ij_scala_parentheses_expression_new_line_after_left_paren = false +ij_scala_parentheses_expression_right_paren_on_new_line = false +ij_scala_place_closure_parameters_on_new_line = false +ij_scala_place_self_type_on_new_line = true +ij_scala_prefer_parameters_wrap = false +ij_scala_preserve_space_after_method_declaration_name = false +ij_scala_reformat_on_compile = false +ij_scala_replace_case_arrow_with_unicode_char = false +ij_scala_replace_for_generator_arrow_with_unicode_char = false +ij_scala_replace_lambda_with_greek_letter = false +ij_scala_replace_map_arrow_with_unicode_char = false +ij_scala_scalafmt_fallback_to_default_settings = false +ij_scala_scalafmt_reformat_on_files_save = false +ij_scala_scalafmt_show_invalid_code_warnings = true +ij_scala_scalafmt_use_intellij_formatter_for_range_format = true +ij_scala_sd_align_exception_comments = true +ij_scala_sd_align_list_item_content = true +ij_scala_sd_align_other_tags_comments = true +ij_scala_sd_align_parameters_comments = true +ij_scala_sd_align_return_comments = true +ij_scala_sd_blank_line_after_parameters_comments = false +ij_scala_sd_blank_line_after_return_comments = false +ij_scala_sd_blank_line_before_parameters = false +ij_scala_sd_blank_line_before_tags = true +ij_scala_sd_blank_line_between_parameters = false +ij_scala_sd_keep_blank_lines_between_tags = false +ij_scala_sd_preserve_spaces_in_tags = false +ij_scala_space_after_comma = true +ij_scala_space_after_for_semicolon = true +ij_scala_space_after_modifiers_constructor = false +ij_scala_space_after_type_colon = true +ij_scala_space_before_brace_method_call = true +ij_scala_space_before_class_left_brace = true +ij_scala_space_before_for_parentheses = true +ij_scala_space_before_if_parentheses = true +ij_scala_space_before_infix_like_method_parentheses = false +ij_scala_space_before_infix_method_call_parentheses = false +ij_scala_space_before_infix_operator_like_method_call_parentheses = true +ij_scala_space_before_method_call_parentheses = false +ij_scala_space_before_method_left_brace = true +ij_scala_space_before_method_parentheses = false +ij_scala_space_before_type_colon = false +ij_scala_space_before_type_parameter_in_def_list = false +ij_scala_space_before_type_parameter_leading_context_bound_colon = false +ij_scala_space_before_type_parameter_leading_context_bound_colon_hk = true +ij_scala_space_before_type_parameter_list = false +ij_scala_space_before_type_parameter_rest_context_bound_colons = true +ij_scala_space_before_while_parentheses = true +ij_scala_space_inside_closure_braces = true +ij_scala_space_inside_self_type_braces = true +ij_scala_space_within_empty_method_call_parentheses = false +ij_scala_spaces_around_at_in_patterns = false +ij_scala_spaces_in_imports = false +ij_scala_spaces_in_one_line_blocks = false +ij_scala_spaces_within_brackets = false +ij_scala_spaces_within_for_parentheses = false +ij_scala_spaces_within_if_parentheses = false +ij_scala_spaces_within_method_call_parentheses = false +ij_scala_spaces_within_method_parentheses = false +ij_scala_spaces_within_parentheses = false +ij_scala_spaces_within_while_parentheses = false +ij_scala_special_else_if_treatment = true +ij_scala_trailing_comma_arg_list_enabled = true +ij_scala_trailing_comma_import_selector_enabled = false +ij_scala_trailing_comma_mode = trailing_comma_keep +ij_scala_trailing_comma_params_enabled = true +ij_scala_trailing_comma_pattern_arg_list_enabled = false +ij_scala_trailing_comma_tuple_enabled = false +ij_scala_trailing_comma_tuple_type_enabled = false +ij_scala_trailing_comma_type_params_enabled = false +ij_scala_try_brace_force = never +ij_scala_type_annotation_exclude_constant = true +ij_scala_type_annotation_exclude_in_dialect_sources = true +ij_scala_type_annotation_exclude_in_test_sources = false +ij_scala_type_annotation_exclude_member_of_anonymous_class = false +ij_scala_type_annotation_exclude_member_of_private_class = false +ij_scala_type_annotation_exclude_when_type_is_stable = true +ij_scala_type_annotation_function_parameter = false +ij_scala_type_annotation_implicit_modifier = true +ij_scala_type_annotation_local_definition = false +ij_scala_type_annotation_private_member = false +ij_scala_type_annotation_protected_member = true +ij_scala_type_annotation_public_member = true +ij_scala_type_annotation_structural_type = true +ij_scala_type_annotation_underscore_parameter = false +ij_scala_type_annotation_unit_type = true +ij_scala_use_alternate_continuation_indent_for_params = false +ij_scala_use_scala3_indentation_based_syntax = true +ij_scala_use_scaladoc2_formatting = false +ij_scala_variable_annotation_wrap = off +ij_scala_while_brace_force = never +ij_scala_while_on_new_line = false +ij_scala_wrap_before_with_keyword = false +ij_scala_wrap_first_method_in_call_chain = false +ij_scala_wrap_long_lines = false + +[*.scss] +indent_size = 2 +ij_scss_align_closing_brace_with_properties = false +ij_scss_blank_lines_around_nested_selector = 1 +ij_scss_blank_lines_between_blocks = 1 +ij_scss_brace_placement = 0 +ij_scss_enforce_quotes_on_format = false +ij_scss_hex_color_long_format = false +ij_scss_hex_color_lower_case = false +ij_scss_hex_color_short_format = false +ij_scss_hex_color_upper_case = false +ij_scss_keep_blank_lines_in_code = 2 +ij_scss_keep_indents_on_empty_lines = false +ij_scss_keep_single_line_blocks = false +ij_scss_properties_order = font,font-family,font-size,font-weight,font-style,font-variant,font-size-adjust,font-stretch,line-height,position,z-index,top,right,bottom,left,display,visibility,float,clear,overflow,overflow-x,overflow-y,clip,zoom,align-content,align-items,align-self,flex,flex-flow,flex-basis,flex-direction,flex-grow,flex-shrink,flex-wrap,justify-content,order,box-sizing,width,min-width,max-width,height,min-height,max-height,margin,margin-top,margin-right,margin-bottom,margin-left,padding,padding-top,padding-right,padding-bottom,padding-left,table-layout,empty-cells,caption-side,border-spacing,border-collapse,list-style,list-style-position,list-style-type,list-style-image,content,quotes,counter-reset,counter-increment,resize,cursor,user-select,nav-index,nav-up,nav-right,nav-down,nav-left,transition,transition-delay,transition-timing-function,transition-duration,transition-property,transform,transform-origin,animation,animation-name,animation-duration,animation-play-state,animation-timing-function,animation-delay,animation-iteration-count,animation-direction,text-align,text-align-last,vertical-align,white-space,text-decoration,text-emphasis,text-emphasis-color,text-emphasis-style,text-emphasis-position,text-indent,text-justify,letter-spacing,word-spacing,text-outline,text-transform,text-wrap,text-overflow,text-overflow-ellipsis,text-overflow-mode,word-wrap,word-break,tab-size,hyphens,pointer-events,opacity,color,border,border-width,border-style,border-color,border-top,border-top-width,border-top-style,border-top-color,border-right,border-right-width,border-right-style,border-right-color,border-bottom,border-bottom-width,border-bottom-style,border-bottom-color,border-left,border-left-width,border-left-style,border-left-color,border-radius,border-top-left-radius,border-top-right-radius,border-bottom-right-radius,border-bottom-left-radius,border-image,border-image-source,border-image-slice,border-image-width,border-image-outset,border-image-repeat,outline,outline-width,outline-style,outline-color,outline-offset,background,background-color,background-image,background-repeat,background-attachment,background-position,background-position-x,background-position-y,background-clip,background-origin,background-size,box-decoration-break,box-shadow,text-shadow +ij_scss_space_after_colon = true +ij_scss_space_before_opening_brace = true +ij_scss_use_double_quotes = true +ij_scss_value_alignment = 0 + +[*.styl] +indent_size = 2 +ij_stylus_align_closing_brace_with_properties = false +ij_stylus_blank_lines_around_nested_selector = 1 +ij_stylus_blank_lines_between_blocks = 1 +ij_stylus_brace_placement = 0 +ij_stylus_enforce_quotes_on_format = false +ij_stylus_hex_color_long_format = false +ij_stylus_hex_color_lower_case = false +ij_stylus_hex_color_short_format = false +ij_stylus_hex_color_upper_case = false +ij_stylus_keep_blank_lines_in_code = 2 +ij_stylus_keep_indents_on_empty_lines = false +ij_stylus_keep_single_line_blocks = false +ij_stylus_properties_order = font,font-family,font-size,font-weight,font-style,font-variant,font-size-adjust,font-stretch,line-height,position,z-index,top,right,bottom,left,display,visibility,float,clear,overflow,overflow-x,overflow-y,clip,zoom,align-content,align-items,align-self,flex,flex-flow,flex-basis,flex-direction,flex-grow,flex-shrink,flex-wrap,justify-content,order,box-sizing,width,min-width,max-width,height,min-height,max-height,margin,margin-top,margin-right,margin-bottom,margin-left,padding,padding-top,padding-right,padding-bottom,padding-left,table-layout,empty-cells,caption-side,border-spacing,border-collapse,list-style,list-style-position,list-style-type,list-style-image,content,quotes,counter-reset,counter-increment,resize,cursor,user-select,nav-index,nav-up,nav-right,nav-down,nav-left,transition,transition-delay,transition-timing-function,transition-duration,transition-property,transform,transform-origin,animation,animation-name,animation-duration,animation-play-state,animation-timing-function,animation-delay,animation-iteration-count,animation-direction,text-align,text-align-last,vertical-align,white-space,text-decoration,text-emphasis,text-emphasis-color,text-emphasis-style,text-emphasis-position,text-indent,text-justify,letter-spacing,word-spacing,text-outline,text-transform,text-wrap,text-overflow,text-overflow-ellipsis,text-overflow-mode,word-wrap,word-break,tab-size,hyphens,pointer-events,opacity,color,border,border-width,border-style,border-color,border-top,border-top-width,border-top-style,border-top-color,border-right,border-right-width,border-right-style,border-right-color,border-bottom,border-bottom-width,border-bottom-style,border-bottom-color,border-left,border-left-width,border-left-style,border-left-color,border-radius,border-top-left-radius,border-top-right-radius,border-bottom-right-radius,border-bottom-left-radius,border-image,border-image-source,border-image-slice,border-image-width,border-image-outset,border-image-repeat,outline,outline-width,outline-style,outline-color,outline-offset,background,background-color,background-image,background-repeat,background-attachment,background-position,background-position-x,background-position-y,background-clip,background-origin,background-size,box-decoration-break,box-shadow,text-shadow +ij_stylus_space_after_colon = true +ij_stylus_space_before_opening_brace = true +ij_stylus_use_double_quotes = true +ij_stylus_value_alignment = 0 + +[.editorconfig] +ij_editorconfig_align_group_field_declarations = false +ij_editorconfig_space_after_colon = false +ij_editorconfig_space_after_comma = true +ij_editorconfig_space_before_colon = false +ij_editorconfig_space_before_comma = false +ij_editorconfig_spaces_around_assignment_operators = true + +[{*.ant,*.fxml,*.jhm,*.jnlp,*.jrxml,*.pom,*.qrc,*.rng,*.tld,*.wadl,*.wsdd,*.wsdl,*.xjb,*.xml,*.xsd,*.xsl,*.xslt,*.xul}] +indent_size = 2 +tab_width = 2 +ij_continuation_indent_size = 2 +ij_xml_align_attributes = true +ij_xml_align_text = false +ij_xml_attribute_wrap = normal +ij_xml_block_comment_at_first_column = true +ij_xml_keep_blank_lines = 2 +ij_xml_keep_indents_on_empty_lines = false +ij_xml_keep_line_breaks = true +ij_xml_keep_line_breaks_in_text = true +ij_xml_keep_whitespaces = false +ij_xml_keep_whitespaces_around_cdata = preserve +ij_xml_keep_whitespaces_inside_cdata = false +ij_xml_line_comment_at_first_column = true +ij_xml_space_after_tag_name = false +ij_xml_space_around_equals_in_attribute = false +ij_xml_space_inside_empty_tag = true +ij_xml_text_wrap = normal + +[{*.ats,*.ts}] +indent_size = 2 +tab_width = 2 +ij_continuation_indent_size = 4 +ij_typescript_align_imports = false +ij_typescript_align_multiline_array_initializer_expression = false +ij_typescript_align_multiline_binary_operation = false +ij_typescript_align_multiline_chained_methods = false +ij_typescript_align_multiline_extends_list = false +ij_typescript_align_multiline_for = true +ij_typescript_align_multiline_parameters = true +ij_typescript_align_multiline_parameters_in_calls = false +ij_typescript_align_multiline_ternary_operation = false +ij_typescript_align_object_properties = 0 +ij_typescript_align_union_types = false +ij_typescript_align_var_statements = 0 +ij_typescript_array_initializer_new_line_after_left_brace = false +ij_typescript_array_initializer_right_brace_on_new_line = false +ij_typescript_array_initializer_wrap = off +ij_typescript_assignment_wrap = off +ij_typescript_binary_operation_sign_on_next_line = false +ij_typescript_binary_operation_wrap = off +ij_typescript_blacklist_imports = rxjs/Rx,node_modules/**,**/node_modules/**,@angular/material,@angular/material/typings/** +ij_typescript_blank_lines_after_imports = 1 +ij_typescript_blank_lines_around_class = 1 +ij_typescript_blank_lines_around_field = 0 +ij_typescript_blank_lines_around_field_in_interface = 0 +ij_typescript_blank_lines_around_function = 1 +ij_typescript_blank_lines_around_method = 1 +ij_typescript_blank_lines_around_method_in_interface = 1 +ij_typescript_block_brace_style = end_of_line +ij_typescript_call_parameters_new_line_after_left_paren = false +ij_typescript_call_parameters_right_paren_on_new_line = false +ij_typescript_call_parameters_wrap = off +ij_typescript_catch_on_new_line = false +ij_typescript_chained_call_dot_on_new_line = true +ij_typescript_class_brace_style = end_of_line +ij_typescript_comma_on_new_line = false +ij_typescript_do_while_brace_force = never +ij_typescript_else_on_new_line = false +ij_typescript_enforce_trailing_comma = keep +ij_typescript_extends_keyword_wrap = off +ij_typescript_extends_list_wrap = off +ij_typescript_field_prefix = _ +ij_typescript_file_name_style = relaxed +ij_typescript_finally_on_new_line = false +ij_typescript_for_brace_force = never +ij_typescript_for_statement_new_line_after_left_paren = false +ij_typescript_for_statement_right_paren_on_new_line = false +ij_typescript_for_statement_wrap = off +ij_typescript_force_quote_style = false +ij_typescript_force_semicolon_style = false +ij_typescript_function_expression_brace_style = end_of_line +ij_typescript_if_brace_force = never +ij_typescript_import_merge_members = global +ij_typescript_import_prefer_absolute_path = global +ij_typescript_import_sort_members = true +ij_typescript_import_sort_module_name = false +ij_typescript_import_use_node_resolution = true +ij_typescript_imports_wrap = on_every_item +ij_typescript_indent_case_from_switch = true +ij_typescript_indent_chained_calls = true +ij_typescript_indent_package_children = 0 +ij_typescript_jsdoc_include_types = false +ij_typescript_jsx_attribute_value = braces +ij_typescript_keep_blank_lines_in_code = 2 +ij_typescript_keep_first_column_comment = true +ij_typescript_keep_indents_on_empty_lines = false +ij_typescript_keep_line_breaks = true +ij_typescript_keep_simple_blocks_in_one_line = false +ij_typescript_keep_simple_methods_in_one_line = false +ij_typescript_line_comment_add_space = true +ij_typescript_line_comment_at_first_column = false +ij_typescript_method_brace_style = end_of_line +ij_typescript_method_call_chain_wrap = off +ij_typescript_method_parameters_new_line_after_left_paren = false +ij_typescript_method_parameters_right_paren_on_new_line = false +ij_typescript_method_parameters_wrap = off +ij_typescript_object_literal_wrap = on_every_item +ij_typescript_parentheses_expression_new_line_after_left_paren = false +ij_typescript_parentheses_expression_right_paren_on_new_line = false +ij_typescript_place_assignment_sign_on_next_line = false +ij_typescript_prefer_as_type_cast = false +ij_typescript_prefer_explicit_types_function_expression_returns = false +ij_typescript_prefer_explicit_types_function_returns = false +ij_typescript_prefer_explicit_types_vars_fields = false +ij_typescript_prefer_parameters_wrap = false +ij_typescript_reformat_c_style_comments = false +ij_typescript_space_after_colon = true +ij_typescript_space_after_comma = true +ij_typescript_space_after_dots_in_rest_parameter = false +ij_typescript_space_after_generator_mult = true +ij_typescript_space_after_property_colon = true +ij_typescript_space_after_quest = true +ij_typescript_space_after_type_colon = true +ij_typescript_space_after_unary_not = false +ij_typescript_space_before_async_arrow_lparen = true +ij_typescript_space_before_catch_keyword = true +ij_typescript_space_before_catch_left_brace = true +ij_typescript_space_before_catch_parentheses = true +ij_typescript_space_before_class_lbrace = true +ij_typescript_space_before_class_left_brace = true +ij_typescript_space_before_colon = true +ij_typescript_space_before_comma = false +ij_typescript_space_before_do_left_brace = true +ij_typescript_space_before_else_keyword = true +ij_typescript_space_before_else_left_brace = true +ij_typescript_space_before_finally_keyword = true +ij_typescript_space_before_finally_left_brace = true +ij_typescript_space_before_for_left_brace = true +ij_typescript_space_before_for_parentheses = true +ij_typescript_space_before_for_semicolon = false +ij_typescript_space_before_function_left_parenth = true +ij_typescript_space_before_generator_mult = false +ij_typescript_space_before_if_left_brace = true +ij_typescript_space_before_if_parentheses = true +ij_typescript_space_before_method_call_parentheses = false +ij_typescript_space_before_method_left_brace = true +ij_typescript_space_before_method_parentheses = false +ij_typescript_space_before_property_colon = false +ij_typescript_space_before_quest = true +ij_typescript_space_before_switch_left_brace = true +ij_typescript_space_before_switch_parentheses = true +ij_typescript_space_before_try_left_brace = true +ij_typescript_space_before_type_colon = false +ij_typescript_space_before_unary_not = false +ij_typescript_space_before_while_keyword = true +ij_typescript_space_before_while_left_brace = true +ij_typescript_space_before_while_parentheses = true +ij_typescript_spaces_around_additive_operators = true +ij_typescript_spaces_around_arrow_function_operator = true +ij_typescript_spaces_around_assignment_operators = true +ij_typescript_spaces_around_bitwise_operators = true +ij_typescript_spaces_around_equality_operators = true +ij_typescript_spaces_around_logical_operators = true +ij_typescript_spaces_around_multiplicative_operators = true +ij_typescript_spaces_around_relational_operators = true +ij_typescript_spaces_around_shift_operators = true +ij_typescript_spaces_around_unary_operator = false +ij_typescript_spaces_within_array_initializer_brackets = false +ij_typescript_spaces_within_brackets = false +ij_typescript_spaces_within_catch_parentheses = false +ij_typescript_spaces_within_for_parentheses = false +ij_typescript_spaces_within_if_parentheses = false +ij_typescript_spaces_within_imports = false +ij_typescript_spaces_within_interpolation_expressions = false +ij_typescript_spaces_within_method_call_parentheses = false +ij_typescript_spaces_within_method_parentheses = false +ij_typescript_spaces_within_object_literal_braces = false +ij_typescript_spaces_within_object_type_braces = true +ij_typescript_spaces_within_parentheses = false +ij_typescript_spaces_within_switch_parentheses = false +ij_typescript_spaces_within_type_assertion = false +ij_typescript_spaces_within_union_types = true +ij_typescript_spaces_within_while_parentheses = false +ij_typescript_special_else_if_treatment = true +ij_typescript_ternary_operation_signs_on_next_line = false +ij_typescript_ternary_operation_wrap = off +ij_typescript_union_types_wrap = on_every_item +ij_typescript_use_chained_calls_group_indents = false +ij_typescript_use_double_quotes = true +ij_typescript_use_explicit_js_extension = global +ij_typescript_use_path_mapping = always +ij_typescript_use_public_modifier = false +ij_typescript_use_semicolon_after_statement = true +ij_typescript_var_declaration_wrap = normal +ij_typescript_while_brace_force = never +ij_typescript_while_on_new_line = false +ij_typescript_wrap_comments = true + +[{*.bash,*.sh,*.zsh}] +indent_size = 2 +tab_width = 2 +ij_shell_binary_ops_start_line = false +ij_shell_keep_column_alignment_padding = false +ij_shell_minify_program = false +ij_shell_redirect_followed_by_space = false +ij_shell_switch_cases_indented = false +ij_shell_use_unix_line_separator = true + +[{*.cjs,*.js}] +indent_size = 2 +tab_width = 2 +ij_continuation_indent_size = 2 +ij_javascript_align_imports = false +ij_javascript_align_multiline_array_initializer_expression = true +ij_javascript_align_multiline_binary_operation = true +ij_javascript_align_multiline_chained_methods = true +ij_javascript_align_multiline_extends_list = false +ij_javascript_align_multiline_for = true +ij_javascript_align_multiline_parameters = true +ij_javascript_align_multiline_parameters_in_calls = false +ij_javascript_align_multiline_ternary_operation = true +ij_javascript_align_object_properties = 0 +ij_javascript_align_union_types = false +ij_javascript_align_var_statements = 0 +ij_javascript_array_initializer_new_line_after_left_brace = false +ij_javascript_array_initializer_right_brace_on_new_line = false +ij_javascript_array_initializer_wrap = normal +ij_javascript_assignment_wrap = normal +ij_javascript_binary_operation_sign_on_next_line = false +ij_javascript_binary_operation_wrap = normal +ij_javascript_blacklist_imports = rxjs/Rx,node_modules/**,**/node_modules/**,@angular/material,@angular/material/typings/** +ij_javascript_blank_lines_after_imports = 1 +ij_javascript_blank_lines_around_class = 1 +ij_javascript_blank_lines_around_field = 0 +ij_javascript_blank_lines_around_function = 1 +ij_javascript_blank_lines_around_method = 1 +ij_javascript_block_brace_style = end_of_line +ij_javascript_call_parameters_new_line_after_left_paren = false +ij_javascript_call_parameters_right_paren_on_new_line = false +ij_javascript_call_parameters_wrap = normal +ij_javascript_catch_on_new_line = false +ij_javascript_chained_call_dot_on_new_line = false +ij_javascript_class_brace_style = end_of_line +ij_javascript_comma_on_new_line = false +ij_javascript_do_while_brace_force = always +ij_javascript_else_on_new_line = false +ij_javascript_enforce_trailing_comma = keep +ij_javascript_extends_keyword_wrap = off +ij_javascript_extends_list_wrap = off +ij_javascript_field_prefix = _ +ij_javascript_file_name_style = relaxed +ij_javascript_finally_on_new_line = false +ij_javascript_for_brace_force = always +ij_javascript_for_statement_new_line_after_left_paren = false +ij_javascript_for_statement_right_paren_on_new_line = false +ij_javascript_for_statement_wrap = normal +ij_javascript_force_quote_style = false +ij_javascript_force_semicolon_style = false +ij_javascript_function_expression_brace_style = end_of_line +ij_javascript_if_brace_force = always +ij_javascript_import_merge_members = global +ij_javascript_import_prefer_absolute_path = global +ij_javascript_import_sort_members = true +ij_javascript_import_sort_module_name = false +ij_javascript_import_use_node_resolution = true +ij_javascript_imports_wrap = on_every_item +ij_javascript_indent_case_from_switch = true +ij_javascript_indent_chained_calls = true +ij_javascript_indent_package_children = 0 +ij_javascript_jsx_attribute_value = braces +ij_javascript_keep_blank_lines_in_code = 1 +ij_javascript_keep_first_column_comment = true +ij_javascript_keep_indents_on_empty_lines = false +ij_javascript_keep_line_breaks = true +ij_javascript_keep_simple_blocks_in_one_line = false +ij_javascript_keep_simple_methods_in_one_line = false +ij_javascript_line_comment_add_space = true +ij_javascript_line_comment_at_first_column = false +ij_javascript_method_brace_style = end_of_line +ij_javascript_method_call_chain_wrap = off +ij_javascript_method_parameters_new_line_after_left_paren = false +ij_javascript_method_parameters_right_paren_on_new_line = false +ij_javascript_method_parameters_wrap = normal +ij_javascript_object_literal_wrap = on_every_item +ij_javascript_parentheses_expression_new_line_after_left_paren = false +ij_javascript_parentheses_expression_right_paren_on_new_line = false +ij_javascript_place_assignment_sign_on_next_line = false +ij_javascript_prefer_as_type_cast = false +ij_javascript_prefer_explicit_types_function_expression_returns = false +ij_javascript_prefer_explicit_types_function_returns = false +ij_javascript_prefer_explicit_types_vars_fields = false +ij_javascript_prefer_parameters_wrap = false +ij_javascript_reformat_c_style_comments = false +ij_javascript_space_after_colon = true +ij_javascript_space_after_comma = true +ij_javascript_space_after_dots_in_rest_parameter = false +ij_javascript_space_after_generator_mult = true +ij_javascript_space_after_property_colon = true +ij_javascript_space_after_quest = true +ij_javascript_space_after_type_colon = true +ij_javascript_space_after_unary_not = false +ij_javascript_space_before_async_arrow_lparen = true +ij_javascript_space_before_catch_keyword = true +ij_javascript_space_before_catch_left_brace = true +ij_javascript_space_before_catch_parentheses = true +ij_javascript_space_before_class_lbrace = true +ij_javascript_space_before_class_left_brace = true +ij_javascript_space_before_colon = true +ij_javascript_space_before_comma = false +ij_javascript_space_before_do_left_brace = true +ij_javascript_space_before_else_keyword = true +ij_javascript_space_before_else_left_brace = true +ij_javascript_space_before_finally_keyword = true +ij_javascript_space_before_finally_left_brace = true +ij_javascript_space_before_for_left_brace = true +ij_javascript_space_before_for_parentheses = true +ij_javascript_space_before_for_semicolon = false +ij_javascript_space_before_function_left_parenth = true +ij_javascript_space_before_generator_mult = false +ij_javascript_space_before_if_left_brace = true +ij_javascript_space_before_if_parentheses = true +ij_javascript_space_before_method_call_parentheses = false +ij_javascript_space_before_method_left_brace = true +ij_javascript_space_before_method_parentheses = false +ij_javascript_space_before_property_colon = false +ij_javascript_space_before_quest = true +ij_javascript_space_before_switch_left_brace = true +ij_javascript_space_before_switch_parentheses = true +ij_javascript_space_before_try_left_brace = true +ij_javascript_space_before_type_colon = false +ij_javascript_space_before_unary_not = false +ij_javascript_space_before_while_keyword = true +ij_javascript_space_before_while_left_brace = true +ij_javascript_space_before_while_parentheses = true +ij_javascript_spaces_around_additive_operators = true +ij_javascript_spaces_around_arrow_function_operator = true +ij_javascript_spaces_around_assignment_operators = true +ij_javascript_spaces_around_bitwise_operators = true +ij_javascript_spaces_around_equality_operators = true +ij_javascript_spaces_around_logical_operators = true +ij_javascript_spaces_around_multiplicative_operators = true +ij_javascript_spaces_around_relational_operators = true +ij_javascript_spaces_around_shift_operators = true +ij_javascript_spaces_around_unary_operator = false +ij_javascript_spaces_within_array_initializer_brackets = false +ij_javascript_spaces_within_brackets = false +ij_javascript_spaces_within_catch_parentheses = false +ij_javascript_spaces_within_for_parentheses = false +ij_javascript_spaces_within_if_parentheses = false +ij_javascript_spaces_within_imports = false +ij_javascript_spaces_within_interpolation_expressions = false +ij_javascript_spaces_within_method_call_parentheses = false +ij_javascript_spaces_within_method_parentheses = false +ij_javascript_spaces_within_object_literal_braces = false +ij_javascript_spaces_within_object_type_braces = true +ij_javascript_spaces_within_parentheses = false +ij_javascript_spaces_within_switch_parentheses = false +ij_javascript_spaces_within_type_assertion = false +ij_javascript_spaces_within_union_types = true +ij_javascript_spaces_within_while_parentheses = false +ij_javascript_special_else_if_treatment = true +ij_javascript_ternary_operation_signs_on_next_line = true +ij_javascript_ternary_operation_wrap = normal +ij_javascript_union_types_wrap = on_every_item +ij_javascript_use_chained_calls_group_indents = false +ij_javascript_use_double_quotes = false +ij_javascript_use_explicit_js_extension = global +ij_javascript_use_path_mapping = always +ij_javascript_use_public_modifier = false +ij_javascript_use_semicolon_after_statement = true +ij_javascript_var_declaration_wrap = normal +ij_javascript_while_brace_force = always +ij_javascript_while_on_new_line = false +ij_javascript_wrap_comments = true + +[{*.ft,*.vm,*.vsl}] +ij_vtl_keep_indents_on_empty_lines = false + +[{*.gant,*.gradle,*.groovy,*.gson,*.gy}] +ij_groovy_align_group_field_declarations = false +ij_groovy_align_multiline_array_initializer_expression = false +ij_groovy_align_multiline_assignment = false +ij_groovy_align_multiline_binary_operation = false +ij_groovy_align_multiline_chained_methods = false +ij_groovy_align_multiline_extends_list = false +ij_groovy_align_multiline_for = true +ij_groovy_align_multiline_list_or_map = true +ij_groovy_align_multiline_method_parentheses = false +ij_groovy_align_multiline_parameters = true +ij_groovy_align_multiline_parameters_in_calls = false +ij_groovy_align_multiline_resources = true +ij_groovy_align_multiline_ternary_operation = false +ij_groovy_align_multiline_throws_list = false +ij_groovy_align_named_args_in_map = true +ij_groovy_align_throws_keyword = false +ij_groovy_array_initializer_new_line_after_left_brace = false +ij_groovy_array_initializer_right_brace_on_new_line = false +ij_groovy_array_initializer_wrap = off +ij_groovy_assert_statement_wrap = off +ij_groovy_assignment_wrap = off +ij_groovy_binary_operation_wrap = off +ij_groovy_blank_lines_after_class_header = 0 +ij_groovy_blank_lines_after_imports = 1 +ij_groovy_blank_lines_after_package = 1 +ij_groovy_blank_lines_around_class = 1 +ij_groovy_blank_lines_around_field = 0 +ij_groovy_blank_lines_around_field_in_interface = 0 +ij_groovy_blank_lines_around_method = 1 +ij_groovy_blank_lines_around_method_in_interface = 1 +ij_groovy_blank_lines_before_imports = 1 +ij_groovy_blank_lines_before_method_body = 0 +ij_groovy_blank_lines_before_package = 0 +ij_groovy_block_brace_style = end_of_line +ij_groovy_block_comment_at_first_column = true +ij_groovy_call_parameters_new_line_after_left_paren = false +ij_groovy_call_parameters_right_paren_on_new_line = false +ij_groovy_call_parameters_wrap = off +ij_groovy_catch_on_new_line = false +ij_groovy_class_annotation_wrap = split_into_lines +ij_groovy_class_brace_style = end_of_line +ij_groovy_class_count_to_use_import_on_demand = 5 +ij_groovy_do_while_brace_force = never +ij_groovy_else_on_new_line = false +ij_groovy_enum_constants_wrap = off +ij_groovy_extends_keyword_wrap = off +ij_groovy_extends_list_wrap = off +ij_groovy_field_annotation_wrap = split_into_lines +ij_groovy_finally_on_new_line = false +ij_groovy_for_brace_force = never +ij_groovy_for_statement_new_line_after_left_paren = false +ij_groovy_for_statement_right_paren_on_new_line = false +ij_groovy_for_statement_wrap = off +ij_groovy_if_brace_force = never +ij_groovy_import_annotation_wrap = 2 +ij_groovy_imports_layout = *,|,javax.**,java.**,|,$* +ij_groovy_indent_case_from_switch = true +ij_groovy_indent_label_blocks = true +ij_groovy_insert_inner_class_imports = false +ij_groovy_keep_blank_lines_before_right_brace = 2 +ij_groovy_keep_blank_lines_in_code = 2 +ij_groovy_keep_blank_lines_in_declarations = 2 +ij_groovy_keep_control_statement_in_one_line = true +ij_groovy_keep_first_column_comment = true +ij_groovy_keep_indents_on_empty_lines = false +ij_groovy_keep_line_breaks = true +ij_groovy_keep_multiple_expressions_in_one_line = false +ij_groovy_keep_simple_blocks_in_one_line = false +ij_groovy_keep_simple_classes_in_one_line = true +ij_groovy_keep_simple_lambdas_in_one_line = true +ij_groovy_keep_simple_methods_in_one_line = true +ij_groovy_label_indent_absolute = false +ij_groovy_label_indent_size = 0 +ij_groovy_lambda_brace_style = end_of_line +ij_groovy_layout_static_imports_separately = true +ij_groovy_line_comment_add_space = false +ij_groovy_line_comment_at_first_column = true +ij_groovy_method_annotation_wrap = split_into_lines +ij_groovy_method_brace_style = end_of_line +ij_groovy_method_call_chain_wrap = off +ij_groovy_method_parameters_new_line_after_left_paren = false +ij_groovy_method_parameters_right_paren_on_new_line = false +ij_groovy_method_parameters_wrap = off +ij_groovy_modifier_list_wrap = false +ij_groovy_names_count_to_use_import_on_demand = 3 +ij_groovy_parameter_annotation_wrap = off +ij_groovy_parentheses_expression_new_line_after_left_paren = false +ij_groovy_parentheses_expression_right_paren_on_new_line = false +ij_groovy_prefer_parameters_wrap = false +ij_groovy_resource_list_new_line_after_left_paren = false +ij_groovy_resource_list_right_paren_on_new_line = false +ij_groovy_resource_list_wrap = off +ij_groovy_space_after_assert_separator = true +ij_groovy_space_after_colon = true +ij_groovy_space_after_comma = true +ij_groovy_space_after_comma_in_type_arguments = true +ij_groovy_space_after_for_semicolon = true +ij_groovy_space_after_quest = true +ij_groovy_space_after_type_cast = true +ij_groovy_space_before_annotation_parameter_list = false +ij_groovy_space_before_array_initializer_left_brace = false +ij_groovy_space_before_assert_separator = false +ij_groovy_space_before_catch_keyword = true +ij_groovy_space_before_catch_left_brace = true +ij_groovy_space_before_catch_parentheses = true +ij_groovy_space_before_class_left_brace = true +ij_groovy_space_before_closure_left_brace = true +ij_groovy_space_before_colon = true +ij_groovy_space_before_comma = false +ij_groovy_space_before_do_left_brace = true +ij_groovy_space_before_else_keyword = true +ij_groovy_space_before_else_left_brace = true +ij_groovy_space_before_finally_keyword = true +ij_groovy_space_before_finally_left_brace = true +ij_groovy_space_before_for_left_brace = true +ij_groovy_space_before_for_parentheses = true +ij_groovy_space_before_for_semicolon = false +ij_groovy_space_before_if_left_brace = true +ij_groovy_space_before_if_parentheses = true +ij_groovy_space_before_method_call_parentheses = false +ij_groovy_space_before_method_left_brace = true +ij_groovy_space_before_method_parentheses = false +ij_groovy_space_before_quest = true +ij_groovy_space_before_switch_left_brace = true +ij_groovy_space_before_switch_parentheses = true +ij_groovy_space_before_synchronized_left_brace = true +ij_groovy_space_before_synchronized_parentheses = true +ij_groovy_space_before_try_left_brace = true +ij_groovy_space_before_try_parentheses = true +ij_groovy_space_before_while_keyword = true +ij_groovy_space_before_while_left_brace = true +ij_groovy_space_before_while_parentheses = true +ij_groovy_space_in_named_argument = true +ij_groovy_space_in_named_argument_before_colon = false +ij_groovy_space_within_empty_array_initializer_braces = false +ij_groovy_space_within_empty_method_call_parentheses = false +ij_groovy_spaces_around_additive_operators = true +ij_groovy_spaces_around_assignment_operators = true +ij_groovy_spaces_around_bitwise_operators = true +ij_groovy_spaces_around_equality_operators = true +ij_groovy_spaces_around_lambda_arrow = true +ij_groovy_spaces_around_logical_operators = true +ij_groovy_spaces_around_multiplicative_operators = true +ij_groovy_spaces_around_regex_operators = true +ij_groovy_spaces_around_relational_operators = true +ij_groovy_spaces_around_shift_operators = true +ij_groovy_spaces_within_annotation_parentheses = false +ij_groovy_spaces_within_array_initializer_braces = false +ij_groovy_spaces_within_braces = true +ij_groovy_spaces_within_brackets = false +ij_groovy_spaces_within_cast_parentheses = false +ij_groovy_spaces_within_catch_parentheses = false +ij_groovy_spaces_within_for_parentheses = false +ij_groovy_spaces_within_gstring_injection_braces = false +ij_groovy_spaces_within_if_parentheses = false +ij_groovy_spaces_within_list_or_map = false +ij_groovy_spaces_within_method_call_parentheses = false +ij_groovy_spaces_within_method_parentheses = false +ij_groovy_spaces_within_parentheses = false +ij_groovy_spaces_within_switch_parentheses = false +ij_groovy_spaces_within_synchronized_parentheses = false +ij_groovy_spaces_within_try_parentheses = false +ij_groovy_spaces_within_tuple_expression = false +ij_groovy_spaces_within_while_parentheses = false +ij_groovy_special_else_if_treatment = true +ij_groovy_ternary_operation_wrap = off +ij_groovy_throws_keyword_wrap = off +ij_groovy_throws_list_wrap = off +ij_groovy_use_flying_geese_braces = false +ij_groovy_use_fq_class_names = false +ij_groovy_use_fq_class_names_in_javadoc = true +ij_groovy_use_relative_indents = false +ij_groovy_use_single_class_imports = true +ij_groovy_variable_annotation_wrap = off +ij_groovy_while_brace_force = never +ij_groovy_while_on_new_line = false +ij_groovy_wrap_chain_calls_after_dot = false +ij_groovy_wrap_long_lines = false + +[{*.gradle.kts,*.kt,*.kts,*.main.kts,*.space.kts}] +ij_kotlin_align_in_columns_case_branch = false +ij_kotlin_align_multiline_binary_operation = false +ij_kotlin_align_multiline_extends_list = false +ij_kotlin_align_multiline_method_parentheses = false +ij_kotlin_align_multiline_parameters = true +ij_kotlin_align_multiline_parameters_in_calls = false +ij_kotlin_allow_trailing_comma = false +ij_kotlin_allow_trailing_comma_on_call_site = false +ij_kotlin_assignment_wrap = off +ij_kotlin_blank_lines_after_class_header = 0 +ij_kotlin_blank_lines_around_block_when_branches = 0 +ij_kotlin_blank_lines_before_declaration_with_comment_or_annotation_on_separate_line = 1 +ij_kotlin_block_comment_at_first_column = true +ij_kotlin_call_parameters_new_line_after_left_paren = false +ij_kotlin_call_parameters_right_paren_on_new_line = false +ij_kotlin_call_parameters_wrap = off +ij_kotlin_catch_on_new_line = false +ij_kotlin_class_annotation_wrap = split_into_lines +ij_kotlin_continuation_indent_for_chained_calls = true +ij_kotlin_continuation_indent_for_expression_bodies = true +ij_kotlin_continuation_indent_in_argument_lists = true +ij_kotlin_continuation_indent_in_elvis = true +ij_kotlin_continuation_indent_in_if_conditions = true +ij_kotlin_continuation_indent_in_parameter_lists = true +ij_kotlin_continuation_indent_in_supertype_lists = true +ij_kotlin_else_on_new_line = false +ij_kotlin_enum_constants_wrap = off +ij_kotlin_extends_list_wrap = off +ij_kotlin_field_annotation_wrap = split_into_lines +ij_kotlin_finally_on_new_line = false +ij_kotlin_if_rparen_on_new_line = false +ij_kotlin_import_nested_classes = false +ij_kotlin_imports_layout = *,java.**,javax.**,kotlin.**,^ +ij_kotlin_insert_whitespaces_in_simple_one_line_method = true +ij_kotlin_keep_blank_lines_before_right_brace = 2 +ij_kotlin_keep_blank_lines_in_code = 2 +ij_kotlin_keep_blank_lines_in_declarations = 2 +ij_kotlin_keep_first_column_comment = true +ij_kotlin_keep_indents_on_empty_lines = false +ij_kotlin_keep_line_breaks = true +ij_kotlin_lbrace_on_next_line = false +ij_kotlin_line_comment_add_space = false +ij_kotlin_line_comment_at_first_column = true +ij_kotlin_method_annotation_wrap = split_into_lines +ij_kotlin_method_call_chain_wrap = off +ij_kotlin_method_parameters_new_line_after_left_paren = false +ij_kotlin_method_parameters_right_paren_on_new_line = false +ij_kotlin_method_parameters_wrap = off +ij_kotlin_name_count_to_use_star_import = 5 +ij_kotlin_name_count_to_use_star_import_for_members = 3 +ij_kotlin_packages_to_use_import_on_demand = java.util.*,kotlinx.android.synthetic.**,io.ktor.** +ij_kotlin_parameter_annotation_wrap = off +ij_kotlin_space_after_comma = true +ij_kotlin_space_after_extend_colon = true +ij_kotlin_space_after_type_colon = true +ij_kotlin_space_before_catch_parentheses = true +ij_kotlin_space_before_comma = false +ij_kotlin_space_before_extend_colon = true +ij_kotlin_space_before_for_parentheses = true +ij_kotlin_space_before_if_parentheses = true +ij_kotlin_space_before_lambda_arrow = true +ij_kotlin_space_before_type_colon = false +ij_kotlin_space_before_when_parentheses = true +ij_kotlin_space_before_while_parentheses = true +ij_kotlin_spaces_around_additive_operators = true +ij_kotlin_spaces_around_assignment_operators = true +ij_kotlin_spaces_around_equality_operators = true +ij_kotlin_spaces_around_function_type_arrow = true +ij_kotlin_spaces_around_logical_operators = true +ij_kotlin_spaces_around_multiplicative_operators = true +ij_kotlin_spaces_around_range = false +ij_kotlin_spaces_around_relational_operators = true +ij_kotlin_spaces_around_unary_operator = false +ij_kotlin_spaces_around_when_arrow = true +ij_kotlin_variable_annotation_wrap = off +ij_kotlin_while_on_new_line = false +ij_kotlin_wrap_elvis_expressions = 1 +ij_kotlin_wrap_expression_body_functions = 0 +ij_kotlin_wrap_first_method_in_call_chain = false + +[{*.har,*.jsb2,*.jsb3,*.json,.babelrc,.eslintrc,.stylelintrc,bowerrc,jest.config}] +indent_size = 2 +tab_width = 2 +ij_continuation_indent_size = 2 +ij_json_keep_blank_lines_in_code = 0 +ij_json_keep_indents_on_empty_lines = false +ij_json_keep_line_breaks = true +ij_json_space_after_colon = true +ij_json_space_after_comma = true +ij_json_space_before_colon = true +ij_json_space_before_comma = false +ij_json_spaces_within_braces = true +ij_json_spaces_within_brackets = true +ij_json_wrap_long_lines = false + +[{*.htm,*.html,*.ng,*.sht,*.shtm,*.shtml}] +indent_size = 2 +tab_width = 2 +ij_continuation_indent_size = 2 +ij_html_add_new_line_before_tags = body,div,p,form,h1,h2,h3 +ij_html_align_attributes = true +ij_html_align_text = false +ij_html_attribute_wrap = normal +ij_html_block_comment_at_first_column = true +ij_html_do_not_align_children_of_min_lines = 0 +ij_html_do_not_break_if_inline_tags = title,h1,h2,h3,h4,h5,h6,p +ij_html_do_not_indent_children_of_tags = html,body,thead,tbody,tfoot +ij_html_enforce_quotes = false +ij_html_inline_tags = a,abbr,acronym,b,basefont,bdo,big,br,cite,cite,code,dfn,em,font,i,img,input,kbd,label,q,s,samp,select,small,span,strike,strong,sub,sup,textarea,tt,u,var +ij_html_keep_blank_lines = 2 +ij_html_keep_indents_on_empty_lines = false +ij_html_keep_line_breaks = true +ij_html_keep_line_breaks_in_text = true +ij_html_keep_whitespaces = false +ij_html_keep_whitespaces_inside = span,pre,textarea +ij_html_line_comment_at_first_column = true +ij_html_new_line_after_last_attribute = never +ij_html_new_line_before_first_attribute = never +ij_html_quote_style = double +ij_html_remove_new_line_before_tags = br +ij_html_space_after_tag_name = false +ij_html_space_around_equality_in_attribute = false +ij_html_space_inside_empty_tag = true +ij_html_text_wrap = normal + +[{*.jsf,*.jsp,*.jspf,*.tag,*.tagf,*.xjsp}] +ij_jsp_jsp_prefer_comma_separated_import_list = false +ij_jsp_keep_indents_on_empty_lines = false + +[{*.jspx,*.tagx}] +ij_jspx_keep_indents_on_empty_lines = false + +[{*.markdown,*.md}] +ij_markdown_force_one_space_after_blockquote_symbol = true +ij_markdown_force_one_space_after_header_symbol = true +ij_markdown_force_one_space_after_list_bullet = true +ij_markdown_force_one_space_between_words = true +ij_markdown_keep_indents_on_empty_lines = false +ij_markdown_max_lines_around_block_elements = 1 +ij_markdown_max_lines_around_header = 1 +ij_markdown_max_lines_between_paragraphs = 1 +ij_markdown_min_lines_around_block_elements = 1 +ij_markdown_min_lines_around_header = 1 +ij_markdown_min_lines_between_paragraphs = 1 + +[{*.pb,*.textproto}] +indent_size = 2 +tab_width = 2 +ij_continuation_indent_size = 4 +ij_prototext_keep_blank_lines_in_code = 2 +ij_prototext_keep_indents_on_empty_lines = false +ij_prototext_keep_line_breaks = true +ij_prototext_space_after_colon = true +ij_prototext_space_after_comma = true +ij_prototext_space_before_colon = false +ij_prototext_space_before_comma = false +ij_prototext_spaces_within_braces = true +ij_prototext_spaces_within_brackets = false + +[{*.properties,spring.handlers,spring.schemas}] +ij_properties_align_group_field_declarations = false +ij_properties_keep_blank_lines = false +ij_properties_key_value_delimiter = equals +ij_properties_spaces_around_key_value_delimiter = false + +[{*.py,*.pyw}] +ij_python_align_collections_and_comprehensions = true +ij_python_align_multiline_imports = true +ij_python_align_multiline_parameters = true +ij_python_align_multiline_parameters_in_calls = true +ij_python_blank_line_at_file_end = true +ij_python_blank_lines_after_imports = 1 +ij_python_blank_lines_after_local_imports = 0 +ij_python_blank_lines_around_class = 1 +ij_python_blank_lines_around_method = 1 +ij_python_blank_lines_around_top_level_classes_functions = 2 +ij_python_blank_lines_before_first_method = 0 +ij_python_call_parameters_new_line_after_left_paren = false +ij_python_call_parameters_right_paren_on_new_line = false +ij_python_call_parameters_wrap = normal +ij_python_dict_alignment = 0 +ij_python_dict_new_line_after_left_brace = false +ij_python_dict_new_line_before_right_brace = false +ij_python_dict_wrapping = 1 +ij_python_from_import_new_line_after_left_parenthesis = false +ij_python_from_import_new_line_before_right_parenthesis = false +ij_python_from_import_parentheses_force_if_multiline = false +ij_python_from_import_trailing_comma_if_multiline = false +ij_python_from_import_wrapping = 1 +ij_python_hang_closing_brackets = false +ij_python_keep_blank_lines_in_code = 1 +ij_python_keep_blank_lines_in_declarations = 1 +ij_python_keep_indents_on_empty_lines = false +ij_python_keep_line_breaks = true +ij_python_method_parameters_new_line_after_left_paren = false +ij_python_method_parameters_right_paren_on_new_line = false +ij_python_method_parameters_wrap = normal +ij_python_new_line_after_colon = false +ij_python_new_line_after_colon_multi_clause = true +ij_python_optimize_imports_always_split_from_imports = false +ij_python_optimize_imports_case_insensitive_order = false +ij_python_optimize_imports_join_from_imports_with_same_source = false +ij_python_optimize_imports_sort_by_type_first = true +ij_python_optimize_imports_sort_imports = true +ij_python_optimize_imports_sort_names_in_from_imports = false +ij_python_space_after_comma = true +ij_python_space_after_number_sign = true +ij_python_space_after_py_colon = true +ij_python_space_before_backslash = true +ij_python_space_before_comma = false +ij_python_space_before_for_semicolon = false +ij_python_space_before_lbracket = false +ij_python_space_before_method_call_parentheses = false +ij_python_space_before_method_parentheses = false +ij_python_space_before_number_sign = true +ij_python_space_before_py_colon = false +ij_python_space_within_empty_method_call_parentheses = false +ij_python_space_within_empty_method_parentheses = false +ij_python_spaces_around_additive_operators = true +ij_python_spaces_around_assignment_operators = true +ij_python_spaces_around_bitwise_operators = true +ij_python_spaces_around_eq_in_keyword_argument = false +ij_python_spaces_around_eq_in_named_parameter = false +ij_python_spaces_around_equality_operators = true +ij_python_spaces_around_multiplicative_operators = true +ij_python_spaces_around_power_operator = true +ij_python_spaces_around_relational_operators = true +ij_python_spaces_around_shift_operators = true +ij_python_spaces_within_braces = false +ij_python_spaces_within_brackets = false +ij_python_spaces_within_method_call_parentheses = false +ij_python_spaces_within_method_parentheses = false +ij_python_use_continuation_indent_for_arguments = false +ij_python_use_continuation_indent_for_collection_and_comprehensions = false +ij_python_use_continuation_indent_for_parameters = true +ij_python_wrap_long_lines = false + +[{*.yaml,*.yml}] +indent_size = 2 +ij_yaml_align_values_properties = do_not_align +ij_yaml_autoinsert_sequence_marker = true +ij_yaml_block_mapping_on_new_line = false +ij_yaml_indent_sequence_value = true +ij_yaml_keep_indents_on_empty_lines = false +ij_yaml_keep_line_breaks = true +ij_yaml_sequence_on_new_line = false +ij_yaml_space_before_colon = false +ij_yaml_spaces_within_braces = true +ij_yaml_spaces_within_brackets = true diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 6bb61195..2a115602 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -16,7 +16,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v2 + uses: actions/checkout@v5 with: # We must fetch at least the immediate parents so that if this is # a pull request then we can checkout the head. @@ -27,9 +27,16 @@ jobs: - run: git checkout HEAD^2 if: ${{ github.event_name == 'pull_request' }} + # Setup JAVA + - name: Set up JDK 17 + uses: actions/setup-java@v5 + with: + distribution: 'temurin' + java-version: '17' + cache: 'gradle' # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@v1 + uses: github/codeql-action/init@v4 # Override language selection by uncommenting this and choosing your languages # with: # languages: go, javascript, csharp, python, cpp, java @@ -37,7 +44,7 @@ jobs: # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). # If this step fails, then you should remove it and run the build manually (see below) - name: Autobuild - uses: github/codeql-action/autobuild@v1 + uses: github/codeql-action/autobuild@v4 # ℹ️ Command-line programs to run using the OS shell. # 📚 https://git.io/JvXDl @@ -51,4 +58,4 @@ jobs: # make release - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v1 + uses: github/codeql-action/analyze@v4 diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 875f78e5..c91f0cf1 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -2,29 +2,20 @@ name: Test on: [push] jobs: test: - runs-on: ubuntu-18.04 + runs-on: ubuntu-latest services: dynamodb: image: amazon/dynamodb-local:1.11.477 ports: - 8000:8000 steps: - - uses: actions/checkout@v2 - - name: Set up JDK 1.8 - uses: actions/setup-java@v2 + - uses: actions/checkout@v5 + - name: Set up JDK 17 + uses: actions/setup-java@v5 with: - distribution: 'adopt' - java-version: 8.0.282+8 - - uses: actions/cache@v2.1.5 - name: Load cached Gradle Wrapper - with: - path: ~/.gradle/wrapper/dists/ - key: ${{ runner.os }}-gradle-wrapper-${{ hashFiles('gradle/wrapper/gradle-wrapper.properties') }} - - uses: actions/cache@v2.1.5 - name: Load cached dependency - with: - path: ~/.gradle/caches - key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle') }} + distribution: 'temurin' + java-version: '17' + cache: 'gradle' - name: Check Gradle Version run: | chmod +x gradlew @@ -34,7 +25,7 @@ jobs: ./gradlew --parallel --max-workers=4 test - name: If failure then upload test reports if: failure() - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v5 with: path: '*/build/reports/tests' name: SpringBootSample-reports diff --git a/README.md b/README.md index a64191bf..ead149dd 100644 --- a/README.md +++ b/README.md @@ -2,12 +2,6 @@ * Spring Boot Sample Code -# Version - -* java 1.8 -* kotlin 1.3.72 -* spring boot 2.3.0.RELEASE - # subproject - `spring-boot-aop` diff --git a/SpringBootAOP/build.gradle b/SpringBootAOP/build.gradle index fbb06549..cb9a54b4 100644 --- a/SpringBootAOP/build.gradle +++ b/SpringBootAOP/build.gradle @@ -1,6 +1,5 @@ group = 'com.example' version = '0.0.1-SNAPSHOT' -sourceCompatibility = '1.8' repositories { mavenCentral() diff --git a/SpringBootAsync/build.gradle b/SpringBootAsync/build.gradle index 8cee3bce..07a7aad2 100644 --- a/SpringBootAsync/build.gradle +++ b/SpringBootAsync/build.gradle @@ -1,7 +1,6 @@ group = 'com.example' version = '0.0.1-SNAPSHOT' -sourceCompatibility = '1.8' repositories { mavenCentral() diff --git a/SpringBootAsync/src/main/java/com/example/java/config/AsyncConfig.java b/SpringBootAsync/src/main/java/com/example/java/config/AsyncConfig.java index 52a9432e..f92cf984 100644 --- a/SpringBootAsync/src/main/java/com/example/java/config/AsyncConfig.java +++ b/SpringBootAsync/src/main/java/com/example/java/config/AsyncConfig.java @@ -1,7 +1,7 @@ package com.example.java.config; import org.springframework.context.annotation.Configuration; -import org.springframework.scheduling.annotation.AsyncConfigurerSupport; +import org.springframework.scheduling.annotation.AsyncConfigurer; import org.springframework.scheduling.annotation.EnableAsync; import java.util.concurrent.Executor; @@ -9,7 +9,7 @@ @Configuration @EnableAsync -public class AsyncConfig extends AsyncConfigurerSupport { +public class AsyncConfig implements AsyncConfigurer { @Override public Executor getAsyncExecutor() { diff --git a/SpringBootAsync/src/main/kotlin/com/example/kotlin/config/AsyncConfig.kt b/SpringBootAsync/src/main/kotlin/com/example/kotlin/config/AsyncConfig.kt index 9eb87ea8..99439ad5 100644 --- a/SpringBootAsync/src/main/kotlin/com/example/kotlin/config/AsyncConfig.kt +++ b/SpringBootAsync/src/main/kotlin/com/example/kotlin/config/AsyncConfig.kt @@ -1,15 +1,14 @@ package com.example.kotlin.config import org.springframework.context.annotation.Configuration -import org.springframework.scheduling.annotation.AsyncConfigurerSupport +import org.springframework.scheduling.annotation.AsyncConfigurer import org.springframework.scheduling.annotation.EnableAsync - import java.util.concurrent.Executor import java.util.concurrent.Executors @Configuration @EnableAsync -class AsyncConfig : AsyncConfigurerSupport() { +class AsyncConfig : AsyncConfigurer { override fun getAsyncExecutor(): Executor { // ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); diff --git a/SpringBootBatch/build.gradle b/SpringBootBatch/build.gradle index 7fe2e536..b63a2e91 100644 --- a/SpringBootBatch/build.gradle +++ b/SpringBootBatch/build.gradle @@ -1,6 +1,5 @@ group = 'com.example' version = '0.0.1-SNAPSHOT' -sourceCompatibility = '1.8' repositories { mavenCentral() @@ -8,7 +7,10 @@ repositories { dependencies { implementation 'org.springframework.boot:spring-boot-starter-web' + implementation 'org.springframework.boot:spring-boot-starter-jdbc' implementation 'org.springframework.boot:spring-boot-starter-batch' runtimeOnly 'com.h2database:h2' + + testImplementation "org.springframework.batch:spring-batch-test" } diff --git a/SpringBootBatch/src/main/java/com/heowc/BatchConfig.java b/SpringBootBatch/src/main/java/com/heowc/BatchConfig.java deleted file mode 100644 index 183f9a05..00000000 --- a/SpringBootBatch/src/main/java/com/heowc/BatchConfig.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.heowc; - -import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing; -import org.springframework.context.annotation.Configuration; - -@Configuration -@EnableBatchProcessing -public class BatchConfig { -} diff --git a/SpringBootBatch/src/main/java/com/heowc/EndOfDayJobConfig.java b/SpringBootBatch/src/main/java/com/heowc/EndOfDayJobConfig.java index 8f812869..0800edbe 100644 --- a/SpringBootBatch/src/main/java/com/heowc/EndOfDayJobConfig.java +++ b/SpringBootBatch/src/main/java/com/heowc/EndOfDayJobConfig.java @@ -4,34 +4,50 @@ import org.springframework.batch.core.Job; import org.springframework.batch.core.Step; import org.springframework.batch.core.StepExecution; -import org.springframework.batch.core.configuration.annotation.JobBuilderFactory; -import org.springframework.batch.core.configuration.annotation.StepBuilderFactory; +import org.springframework.batch.core.StepExecutionListener; +import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing; +import org.springframework.batch.core.configuration.support.DefaultBatchConfiguration; +import org.springframework.batch.core.job.builder.JobBuilder; import org.springframework.batch.core.job.flow.FlowExecutionStatus; import org.springframework.batch.core.job.flow.JobExecutionDecider; -import org.springframework.batch.core.listener.StepExecutionListenerSupport; +import org.springframework.batch.core.repository.JobRepository; +import org.springframework.batch.core.step.builder.StepBuilder; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder; +import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType; +import org.springframework.jdbc.support.JdbcTransactionManager; +import org.springframework.transaction.PlatformTransactionManager; + +import javax.sql.DataSource; @Configuration -public class EndOfDayJobConfig { +public class EndOfDayJobConfig extends DefaultBatchConfiguration { - private final StepBuilderFactory stepBuilderFactory; + @Override + protected DataSource getDataSource() { + return new EmbeddedDatabaseBuilder().setType(EmbeddedDatabaseType.H2) + .addScript("/org/springframework/batch/core/schema-h2.sql") + .generateUniqueName(true) + .build(); + } - public EndOfDayJobConfig(StepBuilderFactory stepBuilderFactory) { - this.stepBuilderFactory = stepBuilderFactory; + @Override + public PlatformTransactionManager getTransactionManager() { + return new JdbcTransactionManager(getDataSource()); } @Bean - public Job endOfDay(JobBuilderFactory jobBuilderFactory) { + public Job endOfDay(JobRepository jobRepository) { final JobExecutionDecider decider = (jobExecution, stepExecution) -> { final ExitStatus status = execute() ? ExitStatus.COMPLETED : ExitStatus.FAILED; return new FlowExecutionStatus(status.getExitCode()); }; - return jobBuilderFactory.get("endOfDay") - .start(step1()) - .next(decider).on(ExitStatus.COMPLETED.getExitCode()).to(step2()) // *, ? - .from(decider).on(ExitStatus.FAILED.getExitCode()).stopAndRestart(step3()) // to(step3()) + return new JobBuilder("endOfDay", jobRepository) + .start(step1(jobRepository)) + .next(decider).on(ExitStatus.COMPLETED.getExitCode()).to(step2(jobRepository)) // *, ? + .from(decider).on(ExitStatus.FAILED.getExitCode()).stopAndRestart(step3(jobRepository)) // to(step3()) .end() .build(); } @@ -41,29 +57,30 @@ private static boolean execute() { } @Bean - public Step step1() { - return stepBuilderFactory.get("step1") - .listener(new StepExecutionListenerSupport() { + public Step step1(JobRepository jobRepository) { + return new StepBuilder("step1", jobRepository) + .listener(new StepExecutionListener() { @Override public ExitStatus afterStep(StepExecution stepExecution) { return ExitStatus.COMPLETED; } }) - .tasklet((contribution, chunkContext) -> null) + .tasklet((contribution, chunkContext) -> null, getTransactionManager()) .build(); } @Bean - public Step step2() { - return stepBuilderFactory.get("step2") - .tasklet((contribution, chunkContext) -> null) + public Step step2(JobRepository jobRepository) { + return new StepBuilder("step2", jobRepository) + .tasklet((contribution, chunkContext) -> null, getTransactionManager()) .build(); } @Bean - public Step step3() { - return stepBuilderFactory.get("step3") - .tasklet((contribution, chunkContext) -> null) + public Step step3(JobRepository jobRepository) { + return new StepBuilder("step3", jobRepository) + .tasklet((contribution, chunkContext) -> null, getTransactionManager()) .build(); + } } diff --git a/SpringBootBatch/src/main/java/com/heowc/SimpleJobLauncherController.java b/SpringBootBatch/src/main/java/com/heowc/SimpleJobLauncherController.java index 53a97062..e423fc83 100644 --- a/SpringBootBatch/src/main/java/com/heowc/SimpleJobLauncherController.java +++ b/SpringBootBatch/src/main/java/com/heowc/SimpleJobLauncherController.java @@ -30,13 +30,8 @@ public SimpleJobLauncherController(JobLauncher jobLauncher, Job job) { @RequestMapping("/jobLauncher.html") public void handle() throws JobParametersInvalidException, JobExecutionAlreadyRunningException, JobRestartException, JobInstanceAlreadyCompleteException { - final Map map = new HashMap<>(); - map.put("create_date", new JobParameter(asDate(LocalDateTime.now()))); + final Map> map = new HashMap<>(); + map.put("create_date", new JobParameter<>(LocalDateTime.now().toString(), String.class)); jobLauncher.run(job, new JobParameters(map)); } - - - private static Date asDate(LocalDateTime localDateTime) { - return Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant()); - } } diff --git a/SpringBootBatch/src/main/resources/application.properties b/SpringBootBatch/src/main/resources/application.properties index e69de29b..29146175 100644 --- a/SpringBootBatch/src/main/resources/application.properties +++ b/SpringBootBatch/src/main/resources/application.properties @@ -0,0 +1,2 @@ +spring.batch.jdbc.initialize-schema=embedded +spring.batch.job.enabled=true \ No newline at end of file diff --git a/SpringBootBatch/src/test/java/com/heowc/BatchTest.java b/SpringBootBatch/src/test/java/com/heowc/BatchTest.java new file mode 100644 index 00000000..5bbdff77 --- /dev/null +++ b/SpringBootBatch/src/test/java/com/heowc/BatchTest.java @@ -0,0 +1,29 @@ +package com.heowc; + +import org.junit.jupiter.api.Test; +import org.springframework.batch.core.ExitStatus; +import org.springframework.batch.core.Job; +import org.springframework.batch.core.JobExecution; +import org.springframework.batch.core.JobParameters; +import org.springframework.batch.test.JobLauncherTestUtils; +import org.springframework.batch.test.context.SpringBatchTest; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit.jupiter.SpringJUnitConfig; + +import static org.assertj.core.api.Assertions.assertThat; + +@SpringBatchTest +@SpringJUnitConfig(EndOfDayJobConfig.class) +class BatchTest { + + @Autowired + private JobLauncherTestUtils jobLauncherTestUtils; + + @Test + void test(@Autowired Job job) throws Exception { + jobLauncherTestUtils.setJob(job); + JobExecution execution = jobLauncherTestUtils.launchJob(); + assertThat(execution.getExitStatus()).isEqualTo(ExitStatus.COMPLETED); + } +} diff --git a/SpringBootCache/build.gradle b/SpringBootCache/build.gradle index 0640f341..0c8580bb 100644 --- a/SpringBootCache/build.gradle +++ b/SpringBootCache/build.gradle @@ -4,7 +4,6 @@ plugins { group = 'com.example' version = '0.0.1-SNAPSHOT' -sourceCompatibility = '1.8' repositories { mavenCentral() diff --git a/SpringBootConfigurable/README.md b/SpringBootConfigurable/README.md deleted file mode 100644 index c2464772..00000000 --- a/SpringBootConfigurable/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# requirement - -```bash -java -javaagent:libs/spring-instrument-5.1.5.RELEASE.jar ... -``` \ No newline at end of file diff --git a/SpringBootConfigurable/libs/spring-instrument-5.2.1.RELEASE.jar b/SpringBootConfigurable/libs/spring-instrument-5.2.1.RELEASE.jar deleted file mode 100644 index e7406530..00000000 Binary files a/SpringBootConfigurable/libs/spring-instrument-5.2.1.RELEASE.jar and /dev/null differ diff --git a/SpringBootConfigurable/src/main/java/com/example/java/account/Account.java b/SpringBootConfigurable/src/main/java/com/example/java/account/Account.java deleted file mode 100644 index bc9357b8..00000000 --- a/SpringBootConfigurable/src/main/java/com/example/java/account/Account.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.example.java.account; - -import org.apache.commons.lang3.RandomStringUtils; -import org.springframework.beans.factory.annotation.Autowire; -import org.springframework.beans.factory.annotation.Configurable; -import org.springframework.security.crypto.password.PasswordEncoder; - -import javax.persistence.*; - -@Configurable(autowire = Autowire.BY_TYPE) -@Entity -@Access(AccessType.FIELD) -public class Account { - - @Id - private String id; - - private String password; - - @Transient - private PasswordEncoder passwordEncoder; - - protected Account() { } - - public Account(String id, String password) { - this.id = id; - this.password = password; - } - - public void setPasswordEncoder(PasswordEncoder passwordEncoder) { - this.passwordEncoder = passwordEncoder; - } - - public String getId() { - return id; - } - - public String getPassword() { - return password; - } - - public void resetPassword() { - String newPassword = RandomStringUtils.randomAlphanumeric(10); - this.password = passwordEncoder.encode(newPassword); - } -} diff --git a/SpringBootConfigurable/src/main/java/com/example/java/account/AccountRepository.java b/SpringBootConfigurable/src/main/java/com/example/java/account/AccountRepository.java deleted file mode 100644 index 9ca605d1..00000000 --- a/SpringBootConfigurable/src/main/java/com/example/java/account/AccountRepository.java +++ /dev/null @@ -1,6 +0,0 @@ -package com.example.java.account; - -import org.springframework.data.jpa.repository.JpaRepository; - -public interface AccountRepository extends JpaRepository { -} diff --git a/SpringBootConfigurable/src/main/java/com/example/java/config/ConfigurableConfig.java b/SpringBootConfigurable/src/main/java/com/example/java/config/ConfigurableConfig.java deleted file mode 100644 index 52ae56fa..00000000 --- a/SpringBootConfigurable/src/main/java/com/example/java/config/ConfigurableConfig.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.example.java.config; - -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.EnableLoadTimeWeaving; -import org.springframework.context.annotation.aspectj.EnableSpringConfigured; - -@Configuration -@EnableSpringConfigured -@EnableLoadTimeWeaving -public class ConfigurableConfig { -} diff --git a/SpringBootConfigurable/src/main/java/com/example/java/config/SecurityConfig.java b/SpringBootConfigurable/src/main/java/com/example/java/config/SecurityConfig.java deleted file mode 100644 index d1d3b08e..00000000 --- a/SpringBootConfigurable/src/main/java/com/example/java/config/SecurityConfig.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.example.java.config; - -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; -import org.springframework.security.crypto.password.PasswordEncoder; - -@Configuration -public class SecurityConfig { - - @Bean - public PasswordEncoder passwordEncoder() { - return new BCryptPasswordEncoder(); - } -} diff --git a/SpringBootConfigurable/src/main/kotlin/com/example/kotlin/SpringBootConfigurableApplication.kt b/SpringBootConfigurable/src/main/kotlin/com/example/kotlin/SpringBootConfigurableApplication.kt deleted file mode 100644 index 2a4b0478..00000000 --- a/SpringBootConfigurable/src/main/kotlin/com/example/kotlin/SpringBootConfigurableApplication.kt +++ /dev/null @@ -1,12 +0,0 @@ -package com.example.kotlin - -import org.springframework.boot.autoconfigure.SpringBootApplication -import org.springframework.boot.runApplication - -@SpringBootApplication -class SpringBootConfigurableApplication - -fun main(args: Array) { - runApplication(*args) -} - diff --git a/SpringBootConfigurable/src/main/kotlin/com/example/kotlin/account/Account.kt b/SpringBootConfigurable/src/main/kotlin/com/example/kotlin/account/Account.kt deleted file mode 100644 index ef6e6878..00000000 --- a/SpringBootConfigurable/src/main/kotlin/com/example/kotlin/account/Account.kt +++ /dev/null @@ -1,23 +0,0 @@ -package com.example.kotlin.account - -import org.apache.commons.lang3.RandomStringUtils -import org.springframework.beans.factory.annotation.Autowire -import org.springframework.beans.factory.annotation.Configurable -import org.springframework.security.crypto.password.PasswordEncoder - -import javax.persistence.* - -@Configurable(autowire = Autowire.BY_TYPE) -@Entity -@Access(AccessType.FIELD) -class Account(@Id val id: String, - var password: String) { - - @Transient - lateinit var passwordEncoder: PasswordEncoder - - fun resetPassword() { - val newPassword = RandomStringUtils.randomAlphanumeric(10) - this.password = passwordEncoder.encode(newPassword) - } -} diff --git a/SpringBootConfigurable/src/main/kotlin/com/example/kotlin/account/AccountRepository.kt b/SpringBootConfigurable/src/main/kotlin/com/example/kotlin/account/AccountRepository.kt deleted file mode 100644 index db809ae4..00000000 --- a/SpringBootConfigurable/src/main/kotlin/com/example/kotlin/account/AccountRepository.kt +++ /dev/null @@ -1,5 +0,0 @@ -package com.example.kotlin.account - -import org.springframework.data.jpa.repository.JpaRepository - -interface AccountRepository : JpaRepository diff --git a/SpringBootConfigurable/src/main/kotlin/com/example/kotlin/config/ConfigurableConfig.kt b/SpringBootConfigurable/src/main/kotlin/com/example/kotlin/config/ConfigurableConfig.kt deleted file mode 100644 index e87f081a..00000000 --- a/SpringBootConfigurable/src/main/kotlin/com/example/kotlin/config/ConfigurableConfig.kt +++ /dev/null @@ -1,10 +0,0 @@ -package com.example.kotlin.config - -import org.springframework.context.annotation.Configuration -import org.springframework.context.annotation.EnableLoadTimeWeaving -import org.springframework.context.annotation.aspectj.EnableSpringConfigured - -@Configuration -@EnableSpringConfigured -@EnableLoadTimeWeaving -class ConfigurableConfig diff --git a/SpringBootConfigurable/src/main/kotlin/com/example/kotlin/config/SecurityConfig.kt b/SpringBootConfigurable/src/main/kotlin/com/example/kotlin/config/SecurityConfig.kt deleted file mode 100644 index 8acfe256..00000000 --- a/SpringBootConfigurable/src/main/kotlin/com/example/kotlin/config/SecurityConfig.kt +++ /dev/null @@ -1,15 +0,0 @@ -package com.example.kotlin.config - -import org.springframework.context.annotation.Bean -import org.springframework.context.annotation.Configuration -import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder -import org.springframework.security.crypto.password.PasswordEncoder - -@Configuration -class SecurityConfig { - - @Bean - fun passwordEncoder(): PasswordEncoder { - return BCryptPasswordEncoder() - } -} diff --git a/SpringBootConfigurable/src/main/resources/application.properties b/SpringBootConfigurable/src/main/resources/application.properties deleted file mode 100644 index b6fb6835..00000000 --- a/SpringBootConfigurable/src/main/resources/application.properties +++ /dev/null @@ -1,4 +0,0 @@ -spring.jpa.hibernate.ddl-auto=create - -spring.jpa.show-sql=true -spring.jpa.properties.hibernate.format_sql=true \ No newline at end of file diff --git a/SpringBootConfigurable/src/test/java/com/example/java/AccountTest.java b/SpringBootConfigurable/src/test/java/com/example/java/AccountTest.java deleted file mode 100644 index bc36b876..00000000 --- a/SpringBootConfigurable/src/test/java/com/example/java/AccountTest.java +++ /dev/null @@ -1,45 +0,0 @@ -package com.example.java; - -import com.example.java.account.Account; -import com.example.java.config.ConfigurableConfig; -import com.example.java.config.SecurityConfig; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.context.annotation.Import; -import org.springframework.transaction.annotation.Transactional; - -import javax.persistence.EntityManager; -import javax.persistence.PersistenceContext; - -import static org.assertj.core.api.Assertions.assertThat; - -@SpringBootTest -@Transactional -@Import({ConfigurableConfig.class, SecurityConfig.class}) -class AccountTest { - - @PersistenceContext - private EntityManager entityManager; - - @DisplayName("Account 비밀번호 리셋 테스트") - @Test - void test() { - // given - Account account = new Account("heowc", "1234"); - entityManager.persist(account); - entityManager.flush(); - entityManager.clear(); - - // when - Account heowc = entityManager.find(Account.class, account.getId()); - heowc.resetPassword(); - entityManager.flush(); - entityManager.clear(); - - // then - Account result = entityManager.find(Account.class, account.getId()); - assertThat(result.getId()).isEqualTo(account.getId()); - assertThat(result.getPassword()).isNotEqualTo(account.getPassword()); - } -} diff --git a/SpringBootConfigurable/src/test/kotlin/com/example/kotlin/AccountTest.kt b/SpringBootConfigurable/src/test/kotlin/com/example/kotlin/AccountTest.kt deleted file mode 100644 index 733c7bda..00000000 --- a/SpringBootConfigurable/src/test/kotlin/com/example/kotlin/AccountTest.kt +++ /dev/null @@ -1,41 +0,0 @@ -package com.example.kotlin - -import com.example.kotlin.account.Account -import com.example.kotlin.config.ConfigurableConfig -import com.example.kotlin.config.SecurityConfig -import org.assertj.core.api.Assertions.assertThat -import org.junit.jupiter.api.Test; -import org.springframework.boot.test.context.SpringBootTest -import org.springframework.context.annotation.Import -import org.springframework.transaction.annotation.Transactional -import javax.persistence.EntityManager -import javax.persistence.PersistenceContext - -@SpringBootTest -@Transactional -@Import(ConfigurableConfig::class, SecurityConfig::class) -class AccountTest { - - @PersistenceContext - private lateinit var entityManager: EntityManager - - @Test - fun `Account 비밀번호 리셋 테스트`() { - // given - val account = Account("heowc", "1234") - entityManager.persist(account) - entityManager.flush() - entityManager.clear() - - // when - val heowc = entityManager.find(Account::class.java, account.id) - heowc.resetPassword() - entityManager.flush() - entityManager.clear() - - // then - val result = entityManager.find(Account::class.java, account.id) - assertThat(result.id).isEqualTo(account.id) - assertThat(result.password).isNotEqualTo(account.password) - } -} diff --git a/SpringBootCors/build.gradle b/SpringBootCors/build.gradle index 0d20adc4..7c85b818 100644 --- a/SpringBootCors/build.gradle +++ b/SpringBootCors/build.gradle @@ -1,6 +1,5 @@ group = 'com.example' version = '0.0.1-SNAPSHOT' -sourceCompatibility = '1.8' repositories { mavenCentral() diff --git a/SpringBootCors/src/main/kotlin/com/example/kotlin/config/WebConfig.kt b/SpringBootCors/src/main/kotlin/com/example/kotlin/config/WebConfig.kt index 1583e609..62bf275f 100644 --- a/SpringBootCors/src/main/kotlin/com/example/kotlin/config/WebConfig.kt +++ b/SpringBootCors/src/main/kotlin/com/example/kotlin/config/WebConfig.kt @@ -15,7 +15,7 @@ class WebConfig { override fun addCorsMappings(registry: CorsRegistry) { registry.addMapping("/message/**") .allowedOrigins("*") - .allowedMethods(HttpMethod.POST.name) + .allowedMethods(HttpMethod.POST.name()) .allowCredentials(false) .maxAge(3600) } diff --git a/SpringBootCustomJackson/build.gradle b/SpringBootCustomJackson/build.gradle index 7187b5ee..138b8f1d 100644 --- a/SpringBootCustomJackson/build.gradle +++ b/SpringBootCustomJackson/build.gradle @@ -1,6 +1,5 @@ group = 'com.example' version = '0.0.1-SNAPSHOT' -sourceCompatibility = '1.8' repositories { mavenCentral() diff --git a/SpringBootCustomJackson/src/main/java/com/example/java/component/EncodedJsonComponent.java b/SpringBootCustomJackson/src/main/java/com/example/java/component/EncodedJsonComponent.java index 3ed28a8a..b8284a8f 100644 --- a/SpringBootCustomJackson/src/main/java/com/example/java/component/EncodedJsonComponent.java +++ b/SpringBootCustomJackson/src/main/java/com/example/java/component/EncodedJsonComponent.java @@ -6,9 +6,10 @@ import com.fasterxml.jackson.core.ObjectCodec; import com.fasterxml.jackson.databind.*; import org.springframework.boot.jackson.JsonComponent; -import org.springframework.util.Base64Utils; import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.util.Base64; import java.util.Iterator; @JsonComponent @@ -33,7 +34,8 @@ public Model deserialize(JsonParser p, DeserializationContext ctxt) System.out.println(field + ":" + node.get(field)); } - String name = new String(Base64Utils.decodeFromString(node.get("name").asText())); + String name = new String(Base64.getDecoder().decode(node.get("name").asText()), + StandardCharsets.UTF_8); int type = node.get("type").asInt(); System.out.println("---------------------------------------------------"); return new Model(name, type); @@ -52,7 +54,7 @@ public void serialize(Model value, JsonGenerator json, SerializerProvider provider) throws IOException { json.writeStartObject(); json.writeFieldName("name"); - json.writeString(Base64Utils.encodeToString(value.getName().getBytes())); + json.writeString(Base64.getEncoder().encodeToString(value.getName().getBytes())); json.writeFieldName("type"); json.writeNumber(value.getType()); json.writeEndObject(); diff --git a/SpringBootCustomJackson/src/main/kotlin/com/example/kotlin/component/EncodedJsonComponent.kt b/SpringBootCustomJackson/src/main/kotlin/com/example/kotlin/component/EncodedJsonComponent.kt index 5a8ab0dd..dfb6c908 100644 --- a/SpringBootCustomJackson/src/main/kotlin/com/example/kotlin/component/EncodedJsonComponent.kt +++ b/SpringBootCustomJackson/src/main/kotlin/com/example/kotlin/component/EncodedJsonComponent.kt @@ -5,8 +5,8 @@ import com.fasterxml.jackson.core.JsonGenerator import com.fasterxml.jackson.core.JsonParser import com.fasterxml.jackson.databind.* import org.springframework.boot.jackson.JsonComponent -import org.springframework.util.Base64Utils import java.io.IOException +import java.util.Base64 @JsonComponent class EncodedJsonComponent { @@ -28,7 +28,7 @@ class EncodedJsonComponent { println(field + ":" + node.get(field)) } - val name = String(Base64Utils.decodeFromString(node.get("name").asText())) + val name = String(Base64.getDecoder().decode(node.get("name").asText())) val type = node.get("type").asInt() println("---------------------------------------------------") return Model(name, type) @@ -46,7 +46,7 @@ class EncodedJsonComponent { provider: SerializerProvider) { json.writeStartObject() json.writeFieldName("name") - json.writeString(Base64Utils.encodeToString(value.name.toByteArray())) + json.writeString(Base64.getEncoder().encodeToString(value.name.toByteArray())) json.writeFieldName("type") json.writeNumber(value.type) json.writeEndObject() diff --git a/SpringBootDocker/build.gradle b/SpringBootDocker/build.gradle index eeb5f98a..0ea35a28 100644 --- a/SpringBootDocker/build.gradle +++ b/SpringBootDocker/build.gradle @@ -1,10 +1,9 @@ plugins { - id 'com.google.cloud.tools.jib' version '3.0.0' + id 'com.google.cloud.tools.jib' version '3.4.5' } group = 'com.example' version = '0.0.1-SNAPSHOT' -sourceCompatibility = '1.8' repositories { mavenCentral() diff --git a/SpringBootDynamo/build.gradle b/SpringBootDynamo/build.gradle index 52de14a0..8dc11a07 100644 --- a/SpringBootDynamo/build.gradle +++ b/SpringBootDynamo/build.gradle @@ -1,14 +1,14 @@ group = 'com.example' version = '0.0.1-SNAPSHOT' -sourceCompatibility = '1.8' repositories { mavenCentral() } dependencies { - implementation 'com.amazonaws:aws-java-sdk-dynamodb:1.11.1019' + implementation platform('software.amazon.awssdk:bom:2.36.2') + implementation 'software.amazon.awssdk:dynamodb' implementation 'org.springframework.boot:spring-boot-starter-web' - testImplementation 'org.testcontainers:junit-jupiter:1.15.3' + testImplementation 'org.testcontainers:junit-jupiter:1.21.3' } \ No newline at end of file diff --git a/SpringBootDynamo/src/main/java/com/example/DynamoDBConfig.java b/SpringBootDynamo/src/main/java/com/example/DynamoDBConfig.java index 16e957dc..6796da90 100644 --- a/SpringBootDynamo/src/main/java/com/example/DynamoDBConfig.java +++ b/SpringBootDynamo/src/main/java/com/example/DynamoDBConfig.java @@ -1,26 +1,32 @@ package com.example; -import com.amazonaws.auth.AWSStaticCredentialsProvider; -import com.amazonaws.auth.BasicAWSCredentials; -import com.amazonaws.client.builder.AwsClientBuilder; -import com.amazonaws.services.dynamodbv2.AmazonDynamoDB; -import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClientBuilder; +import java.net.URI; +import java.net.URISyntaxException; + import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import software.amazon.awssdk.auth.credentials.AwsBasicCredentials; +import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider; +import software.amazon.awssdk.regions.Region; +import software.amazon.awssdk.services.dynamodb.DynamoDbClient; + @Configuration public class DynamoDBConfig { @Bean - public AmazonDynamoDB amazonDynamoDB( + public DynamoDbClient amazonDynamoDB( @Value("${aws.region}") String region, @Value("${aws.dynamo.endpoint}") String dynamoEndpoint, @Value("${aws.access-key}") String accessKey, - @Value("${aws.secret-key}") String secretKey) { - return AmazonDynamoDBClientBuilder.standard() - .withEndpointConfiguration(new AwsClientBuilder.EndpointConfiguration(dynamoEndpoint, region)) - .withCredentials(new AWSStaticCredentialsProvider(new BasicAWSCredentials(accessKey, secretKey))) - .build(); + @Value("${aws.secret-key}") String secretKey) throws URISyntaxException { + return DynamoDbClient.builder() + .region(Region.of(region)) + .credentialsProvider(StaticCredentialsProvider.create( + AwsBasicCredentials.create(accessKey, secretKey)) + ) + .endpointOverride(new URI(dynamoEndpoint)) + .build(); } } \ No newline at end of file diff --git a/SpringBootDynamo/src/test/java/com/example/SpringBootDynamoApplicationTests.java b/SpringBootDynamo/src/test/java/com/example/SpringBootDynamoApplicationTests.java index 6a807b95..fd57bcc6 100644 --- a/SpringBootDynamo/src/test/java/com/example/SpringBootDynamoApplicationTests.java +++ b/SpringBootDynamo/src/test/java/com/example/SpringBootDynamoApplicationTests.java @@ -1,149 +1,187 @@ package com.example; -import com.amazonaws.services.dynamodbv2.AmazonDynamoDB; -import com.amazonaws.services.dynamodbv2.model.*; +import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat; + +import java.util.HashMap; +import java.util.Map; + import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -import java.util.Arrays; -import java.util.HashMap; -import java.util.Map; - -import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat; +import software.amazon.awssdk.services.dynamodb.DynamoDbClient; +import software.amazon.awssdk.services.dynamodb.model.AttributeDefinition; +import software.amazon.awssdk.services.dynamodb.model.AttributeValue; +import software.amazon.awssdk.services.dynamodb.model.CreateTableRequest; +import software.amazon.awssdk.services.dynamodb.model.DeleteItemRequest; +import software.amazon.awssdk.services.dynamodb.model.DeleteTableRequest; +import software.amazon.awssdk.services.dynamodb.model.GetItemRequest; +import software.amazon.awssdk.services.dynamodb.model.GetItemResponse; +import software.amazon.awssdk.services.dynamodb.model.KeySchemaElement; +import software.amazon.awssdk.services.dynamodb.model.KeyType; +import software.amazon.awssdk.services.dynamodb.model.ProvisionedThroughput; +import software.amazon.awssdk.services.dynamodb.model.PutItemRequest; +import software.amazon.awssdk.services.dynamodb.model.ScalarAttributeType; +import software.amazon.awssdk.services.dynamodb.model.ScanRequest; +import software.amazon.awssdk.services.dynamodb.model.ScanResponse; +import software.amazon.awssdk.services.dynamodb.model.UpdateItemRequest; public class SpringBootDynamoApplicationTests extends AbstractIntegrationTest { private static final String TABLE_NAME = "test"; @Autowired - private AmazonDynamoDB dynamoDB; + private DynamoDbClient dynamoDB; @BeforeEach public void setup() { - dynamoDB.createTable(new CreateTableRequest() - .withTableName(TABLE_NAME) - .withAttributeDefinitions(Arrays.asList( - new AttributeDefinition("id", ScalarAttributeType.S) - )) - .withKeySchema(Arrays.asList( - new KeySchemaElement("id", KeyType.HASH) - )) - .withProvisionedThroughput(new ProvisionedThroughput(5L, 5L)) - ); + dynamoDB.createTable( + CreateTableRequest.builder() + .tableName(TABLE_NAME) + .attributeDefinitions(AttributeDefinition.builder() + .attributeName("id") + .attributeType(ScalarAttributeType.S) + .build()) + .keySchema(KeySchemaElement.builder() + .attributeName("id") + .keyType(KeyType.HASH) + .build()) + .provisionedThroughput(ProvisionedThroughput.builder() + .readCapacityUnits(5L) + .writeCapacityUnits(5L) + .build()) + .build()); } @Test public void 아이템_삽입_후_스캔_데이터_확인_성공() { // given Map item = new HashMap<>(); - item.put("id", new AttributeValue().withS("1")); - item.put("name", new AttributeValue().withS("wonchul")); - item.put("birth_year", new AttributeValue().withN("1992")); + item.put("id", AttributeValue.builder().s("1").build()); + item.put("name", AttributeValue.builder().s("wonchul").build()); + item.put("birth_year", AttributeValue.builder().n("1992").build()); // when - dynamoDB.putItem(new PutItemRequest().withTableName(TABLE_NAME).withItem(item)); + dynamoDB.putItem(PutItemRequest.builder() + .tableName(TABLE_NAME) + .item(item) + .build()); // then - ScanResult result = dynamoDB.scan(new ScanRequest(TABLE_NAME)); - assertThat(result.getCount()).isEqualTo(1); - assertThat(result.getItems().get(0).get("id").getS()).isEqualTo("1"); - assertThat(result.getItems().get(0).get("name").getS()).isEqualTo("wonchul"); - assertThat(result.getItems().get(0).get("birth_year").getN()).isEqualTo("1992"); + + ScanResponse response = dynamoDB.scan(ScanRequest.builder().tableName(TABLE_NAME).build()); + assertThat(response.count()).isEqualTo(1); + assertThat(response.items().get(0).get("id").s()).isEqualTo("1"); + assertThat(response.items().get(0).get("name").s()).isEqualTo("wonchul"); + assertThat(response.items().get(0).get("birth_year").n()).isEqualTo("1992"); } @Test public void 아이템_삽입_후_해당_데이터_검색_확인_성공() { // given Map item = new HashMap<>(); - item.put("id", new AttributeValue().withS("1")); - item.put("name", new AttributeValue().withS("wonchul")); - item.put("birth_year", new AttributeValue().withN("1992")); - dynamoDB.putItem(new PutItemRequest().withTableName(TABLE_NAME).withItem(item)); + item.put("id", AttributeValue.builder().s("1").build()); + item.put("name", AttributeValue.builder().s("wonchul").build()); + item.put("birth_year", AttributeValue.builder().n("1992").build()); + dynamoDB.putItem(PutItemRequest.builder() + .tableName(TABLE_NAME) + .item(item) + .build()); // when Map key = new HashMap<>(); - key.put("id", new AttributeValue().withS("1")); - GetItemResult result = dynamoDB.getItem(new GetItemRequest().withTableName(TABLE_NAME).withKey(key)); + key.put("id", AttributeValue.builder().s("1").build()); + GetItemResponse response = dynamoDB.getItem(GetItemRequest.builder() + .tableName(TABLE_NAME) + .key(key) + .build()); // then - assertThat(result).isNotNull(); - assertThat(result.getItem()).isNotNull(); - assertThat(result.getItem().get("id").getS()).isEqualTo("1"); - assertThat(result.getItem().get("name").getS()).isEqualTo("wonchul"); - assertThat(result.getItem().get("birth_year").getN()).isEqualTo("1992"); + assertThat(response).isNotNull(); + assertThat(response.item()).isNotNull(); + assertThat(response.item().get("id").s()).isEqualTo("1"); + assertThat(response.item().get("name").s()).isEqualTo("wonchul"); + assertThat(response.item().get("birth_year").n()).isEqualTo("1992"); } @Test public void 아이템_삽입_후_해당_데이터_수정_성공() { // given Map item = new HashMap<>(); - item.put("id", new AttributeValue().withS("1")); - item.put("name", new AttributeValue().withS("wonchul")); - item.put("birth_year", new AttributeValue().withN("1992")); - dynamoDB.putItem(new PutItemRequest().withTableName(TABLE_NAME).withItem(item)); + item.put("id", AttributeValue.builder().s("1").build()); + item.put("name", AttributeValue.builder().s("wonchul").build()); + item.put("birth_year", AttributeValue.builder().n("1992").build()); + dynamoDB.putItem(PutItemRequest.builder() + .tableName(TABLE_NAME) + .item(item) + .build()); // when Map updateKey = new HashMap<>(); - updateKey.put("id", new AttributeValue().withS("1")); + updateKey.put("id", AttributeValue.builder().s("1").build()); Map nameMap = new HashMap<>(); nameMap.put("#N", "name"); nameMap.put("#BY", "birth_year"); Map valueMap = new HashMap<>(); - valueMap.put(":name", new AttributeValue().withS("WONCHUL")); - valueMap.put(":birth_year", new AttributeValue().withN("1992")); - dynamoDB.updateItem( - new UpdateItemRequest() - .withTableName(TABLE_NAME) - .withKey(updateKey) - .withUpdateExpression("set #N = :name, #BY = :birth_year") - .withExpressionAttributeNames(nameMap) - .withExpressionAttributeValues(valueMap) - ); + valueMap.put(":name", AttributeValue.builder().s("WONCHUL").build()); + valueMap.put(":birth_year", AttributeValue.builder().n("1992").build()); + dynamoDB.updateItem(UpdateItemRequest.builder() + .tableName(TABLE_NAME) + .key(updateKey) + .updateExpression("set #N = :name, #BY = :birth_year") + .expressionAttributeNames(nameMap) + .expressionAttributeValues(valueMap) + .build()); // then Map key = new HashMap<>(); - key.put("id", new AttributeValue().withS("1")); - GetItemResult result = dynamoDB.getItem(new GetItemRequest().withTableName(TABLE_NAME).withKey(key)); - - assertThat(result).isNotNull(); - assertThat(result.getItem()).isNotNull(); - assertThat(result.getItem()).isNotNull(); - assertThat(result.getItem().get("id").getS()).isEqualTo("1"); - assertThat(result.getItem().get("name").getS()).isEqualTo("WONCHUL"); - assertThat(result.getItem().get("birth_year").getN()).isEqualTo("1992"); + key.put("id", AttributeValue.builder().s("1").build()); + GetItemResponse response = dynamoDB.getItem(GetItemRequest.builder() + .tableName(TABLE_NAME) + .key(key) + .build()); + assertThat(response).isNotNull(); + assertThat(response.item()).isNotNull(); + assertThat(response.item().get("id").s()).isEqualTo("1"); + assertThat(response.item().get("name").s()).isEqualTo("WONCHUL"); + assertThat(response.item().get("birth_year").n()).isEqualTo("1992"); } @Test public void 아이템_삽입_후_해당_데이터_삭제_성공() { // given Map item = new HashMap<>(); - item.put("id", new AttributeValue().withS("1")); - item.put("name", new AttributeValue().withS("wonchul")); - item.put("birth_year", new AttributeValue().withN("1992")); - dynamoDB.putItem(new PutItemRequest().withTableName(TABLE_NAME).withItem(item)); + item.put("id", AttributeValue.builder().s("1").build()); + item.put("name", AttributeValue.builder().s("wonchul").build()); + item.put("birth_year", AttributeValue.builder().n("1992").build()); + dynamoDB.putItem(PutItemRequest.builder() + .tableName(TABLE_NAME) + .item(item) + .build()); // when Map deleteKey = new HashMap<>(); - deleteKey.put("id", new AttributeValue().withS("1")); - dynamoDB.deleteItem(new DeleteItemRequest().withTableName(TABLE_NAME).withKey(deleteKey)); + deleteKey.put("id", AttributeValue.builder().s("1").build()); + dynamoDB.deleteItem(DeleteItemRequest.builder().tableName(TABLE_NAME).key(deleteKey).build()); // then Map key = new HashMap<>(); - key.put("id", new AttributeValue().withS("1")); - GetItemResult result = dynamoDB.getItem(new GetItemRequest().withTableName(TABLE_NAME).withKey(key)); - - assertThat(result).isNotNull(); - assertThat(result.getItem()).isNull(); + key.put("id", AttributeValue.builder().s("1").build()); + GetItemResponse response = dynamoDB.getItem(GetItemRequest.builder() + .tableName(TABLE_NAME) + .key(key) + .build()); + + assertThat(response).isNotNull(); + assertThat(response.item()).isEmpty(); } - @AfterEach public void clear() { - dynamoDB.deleteTable("test"); + dynamoDB.deleteTable(DeleteTableRequest.builder().tableName(TABLE_NAME).build()); } } \ No newline at end of file diff --git a/SpringBootEvent/build.gradle b/SpringBootEvent/build.gradle index 27e3221f..6dd0ef07 100644 --- a/SpringBootEvent/build.gradle +++ b/SpringBootEvent/build.gradle @@ -1,6 +1,5 @@ group = 'com.example' version = '0.0.1-SNAPSHOT' -sourceCompatibility = '1.8' repositories { mavenCentral() diff --git a/SpringBootEvent/src/main/java/com/heowc/domain/Member.java b/SpringBootEvent/src/main/java/com/heowc/domain/Member.java index ca6ea32a..34358f07 100644 --- a/SpringBootEvent/src/main/java/com/heowc/domain/Member.java +++ b/SpringBootEvent/src/main/java/com/heowc/domain/Member.java @@ -3,8 +3,8 @@ import com.heowc.event.PasswordChangedEvent; import org.springframework.context.ApplicationEventPublisher; -import javax.persistence.Entity; -import javax.persistence.Id; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; import java.security.SecureRandom; @Entity diff --git a/SpringBootEvent/src/test/java/com/heowc/PasswordChangingServiceTest.java b/SpringBootEvent/src/test/java/com/heowc/PasswordChangingServiceTest.java index 1df25879..d60efb32 100644 --- a/SpringBootEvent/src/test/java/com/heowc/PasswordChangingServiceTest.java +++ b/SpringBootEvent/src/test/java/com/heowc/PasswordChangingServiceTest.java @@ -6,7 +6,7 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.test.context.bean.override.mockito.MockitoBean; import static com.heowc.event.PasswordChangedEventListener.MESSAGE_FORMAT; import static org.assertj.core.api.Assertions.assertThat; @@ -22,7 +22,7 @@ class PasswordChangingServiceTest { @Autowired private MemberRepository repository; - @MockBean + @MockitoBean private SendService sendService; @Test diff --git a/SpringBootExcel/build.gradle b/SpringBootExcel/build.gradle index 5105ce8d..98202fa8 100644 --- a/SpringBootExcel/build.gradle +++ b/SpringBootExcel/build.gradle @@ -1,14 +1,15 @@ group = 'com.example' version = '0.0.1-SNAPSHOT' -sourceCompatibility = '1.8' repositories { mavenCentral() } +var poiVersion='5.4.1' + dependencies { - implementation 'org.apache.poi:poi-ooxml:5.0.0' // .xlsx - implementation 'org.apache.poi:poi:5.0.0' // .xls + implementation "org.apache.poi:poi-ooxml:${poiVersion}" // .xlsx + implementation "org.apache.poi:poi:${poiVersion}" // .xls implementation 'eu.bitwalker:UserAgentUtils:1.21' diff --git a/SpringBootExcel/src/main/java/com/example/component/ExcelWriter.java b/SpringBootExcel/src/main/java/com/example/component/ExcelWriter.java index 4a559907..1cc68294 100644 --- a/SpringBootExcel/src/main/java/com/example/component/ExcelWriter.java +++ b/SpringBootExcel/src/main/java/com/example/component/ExcelWriter.java @@ -10,8 +10,8 @@ import org.apache.poi.xssf.streaming.SXSSFWorkbook; import org.apache.poi.xssf.usermodel.XSSFWorkbook; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; diff --git a/SpringBootExcel/src/main/java/com/example/view/ExcelXlsView.java b/SpringBootExcel/src/main/java/com/example/view/ExcelXlsView.java index fe8faf5e..c3f2e97f 100644 --- a/SpringBootExcel/src/main/java/com/example/view/ExcelXlsView.java +++ b/SpringBootExcel/src/main/java/com/example/view/ExcelXlsView.java @@ -5,8 +5,8 @@ import org.springframework.stereotype.Component; import org.springframework.web.servlet.view.document.AbstractXlsView; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import java.util.Map; @Component diff --git a/SpringBootExcel/src/main/java/com/example/view/ExcelXlsxStreamingView.java b/SpringBootExcel/src/main/java/com/example/view/ExcelXlsxStreamingView.java index 13fef101..33f9b128 100644 --- a/SpringBootExcel/src/main/java/com/example/view/ExcelXlsxStreamingView.java +++ b/SpringBootExcel/src/main/java/com/example/view/ExcelXlsxStreamingView.java @@ -5,8 +5,8 @@ import org.springframework.stereotype.Component; import org.springframework.web.servlet.view.document.AbstractXlsxStreamingView; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import java.util.Map; @Component diff --git a/SpringBootExcel/src/main/java/com/example/view/ExcelXlsxView.java b/SpringBootExcel/src/main/java/com/example/view/ExcelXlsxView.java index 0d2df4b8..87634656 100644 --- a/SpringBootExcel/src/main/java/com/example/view/ExcelXlsxView.java +++ b/SpringBootExcel/src/main/java/com/example/view/ExcelXlsxView.java @@ -5,8 +5,8 @@ import org.springframework.stereotype.Component; import org.springframework.web.servlet.view.document.AbstractXlsxView; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import java.util.Map; @Component diff --git a/SpringBootException/build.gradle b/SpringBootException/build.gradle index 7187b5ee..138b8f1d 100644 --- a/SpringBootException/build.gradle +++ b/SpringBootException/build.gradle @@ -1,6 +1,5 @@ group = 'com.example' version = '0.0.1-SNAPSHOT' -sourceCompatibility = '1.8' repositories { mavenCentral() diff --git a/SpringBootException/src/main/java/com/tistory/heowc/advice/GlobalRestControllerAdvicer.java b/SpringBootException/src/main/java/com/tistory/heowc/advice/GlobalRestControllerAdvicer.java index 13fbcad0..2d6198ce 100644 --- a/SpringBootException/src/main/java/com/tistory/heowc/advice/GlobalRestControllerAdvicer.java +++ b/SpringBootException/src/main/java/com/tistory/heowc/advice/GlobalRestControllerAdvicer.java @@ -9,7 +9,7 @@ import org.springframework.web.servlet.ModelAndView; import javax.naming.NotContextException; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; @RestControllerAdvice public class GlobalRestControllerAdvicer { diff --git a/SpringBootGRpc/build.gradle b/SpringBootGRpc/build.gradle index 3c4405ee..e1478c36 100644 --- a/SpringBootGRpc/build.gradle +++ b/SpringBootGRpc/build.gradle @@ -1,19 +1,25 @@ plugins { - id "com.google.protobuf" version "0.8.16" + id "com.google.protobuf" version "0.9.5" } group = 'com.example' version = '0.0.1-SNAPSHOT' -sourceCompatibility = '1.8' repositories { mavenCentral() } +var protobufVersion='4.33.0' +var grpcVersion='1.76.0' + dependencies { + implementation 'javax.annotation:javax.annotation-api:1.3.2' // https://github.com/grpc/grpc-java/issues/9179 implementation 'org.springframework.boot:spring-boot-starter-web' - implementation 'io.github.lognet:grpc-spring-boot-starter:4.5.0' - implementation 'com.google.protobuf:protobuf-java-util:3.16.0' + implementation platform('com.linecorp.armeria:armeria-bom:1.32.5') + implementation 'com.linecorp.armeria:armeria' + implementation 'com.linecorp.armeria:armeria-spring-boot3-starter' + implementation 'com.linecorp.armeria:armeria-grpc' + implementation "com.google.protobuf:protobuf-java-util:${protobufVersion}" } sourceSets { @@ -24,13 +30,14 @@ sourceSets { } } } + protobuf { protoc { - artifact = 'com.google.protobuf:protoc:3.17.0' + artifact = "com.google.protobuf:protoc:${protobufVersion}" } plugins { grpc { - artifact = 'io.grpc:protoc-gen-grpc-java:1.37.1' + artifact = "io.grpc:protoc-gen-grpc-java:${grpcVersion}" } } generateProtoTasks { @@ -39,3 +46,11 @@ protobuf { } } } + +configurations.all { + resolutionStrategy.eachDependency { details -> + if ("io.grpc".equalsIgnoreCase(details.requested.group)) { + details.useVersion grpcVersion + } + } +} \ No newline at end of file diff --git a/SpringBootGRpc/src/main/java/com/example/SpringBootGRpcApplication.java b/SpringBootGRpc/src/main/java/com/example/SpringBootGRpcApplication.java index b1282c8a..9f201103 100644 --- a/SpringBootGRpc/src/main/java/com/example/SpringBootGRpcApplication.java +++ b/SpringBootGRpc/src/main/java/com/example/SpringBootGRpcApplication.java @@ -1,48 +1,72 @@ package com.example; +import com.linecorp.armeria.server.grpc.GrpcService; +import com.linecorp.armeria.spring.ArmeriaServerConfigurator; + import io.grpc.Status; import io.grpc.stub.StreamObserver; -import org.lognet.springboot.grpc.GRpcService; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.stereotype.Service; import org.springframework.util.StringUtils; @SpringBootApplication public class SpringBootGRpcApplication { - public static void main(String[] args) { - SpringApplication.run(SpringBootGRpcApplication.class, args); - } + public static void main(String[] args) { + SpringApplication.run(SpringBootGRpcApplication.class, args); + } +} + +@Configuration +class ArmeriaConfig { + + @Bean + ArmeriaServerConfigurator armeriaServerConfigurator(MessageSenderService service, + @Value("${grpc.port}") int port) { + return builder -> { + builder.http(port) + .service(GrpcService.builder() + .addService(service) + .build()); + }; + } } -@GRpcService -class MessageSenderImpl extends MessageSenderGrpc.MessageSenderImplBase { +@Service +class MessageSenderService extends MessageSenderGrpc.MessageSenderImplBase { - private static final Logger logger = LoggerFactory.getLogger(MessageSenderImpl.class); + private static final Logger logger = LoggerFactory.getLogger(MessageSenderService.class); - @Override - public void send(MessageSenderProto.MessageRequest request, StreamObserver responseObserver) { + @Override + public void send(MessageSenderProto.MessageRequest request, + StreamObserver responseObserver) { - logger.info("send >> request={}", request); + logger.info("send >> request={}", request); - try { - if (StringUtils.isEmpty(request.getContents())) { - throw new IllegalArgumentException("content is empty"); - } + try { + if (!StringUtils.hasText(request.getContents())) { + throw new IllegalArgumentException("content is empty"); + } - MessageSenderProto.MessageResponse response = MessageSenderProto.MessageResponse.newBuilder() - .setStatus(Status.OK.toString()) - .setReason("ok") - .build(); + final MessageSenderProto.MessageResponse response = + MessageSenderProto.MessageResponse.newBuilder() + .setStatus(Status.OK.toString()) + .setReason("ok") + .build(); - responseObserver.onNext(response); - } catch (Exception ex) { - responseObserver.onError(ex); - } finally { - responseObserver.onCompleted(); - } + responseObserver.onNext(response); + } catch (Exception ex) { + responseObserver.onError(ex); + } finally { + responseObserver.onCompleted(); + } - } + } } \ No newline at end of file diff --git a/SpringBootGRpc/src/main/resources/application.properties b/SpringBootGRpc/src/main/resources/application.properties index c45901c6..844cda32 100644 --- a/SpringBootGRpc/src/main/resources/application.properties +++ b/SpringBootGRpc/src/main/resources/application.properties @@ -1 +1,2 @@ +spring.main.web-application-type=none grpc.port=6565 \ No newline at end of file diff --git a/SpringBootGRpc/src/test/java/com/example/SpringBootGRpcApplicationTests.java b/SpringBootGRpc/src/test/java/com/example/SpringBootGRpcApplicationTests.java index e85663c4..7900599b 100644 --- a/SpringBootGRpc/src/test/java/com/example/SpringBootGRpcApplicationTests.java +++ b/SpringBootGRpc/src/test/java/com/example/SpringBootGRpcApplicationTests.java @@ -1,49 +1,50 @@ package com.example; -import io.grpc.ManagedChannel; -import io.grpc.ManagedChannelBuilder; -import io.grpc.Status; -import io.grpc.StatusRuntimeException; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + import org.assertj.core.api.InstanceOfAssertFactories; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import org.lognet.springboot.grpc.context.LocalRunningGrpcPort; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.boot.test.context.SpringBootTest; -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; +import com.example.MessageSenderGrpc.MessageSenderBlockingStub; + +import com.linecorp.armeria.client.grpc.GrpcClients; +import com.linecorp.armeria.spring.LocalArmeriaPort; + +import io.grpc.Status; +import io.grpc.StatusRuntimeException; @SpringBootTest(properties = "grpc.port=0") class SpringBootGRpcApplicationTests { private static final Logger logger = LoggerFactory.getLogger(SpringBootGRpcApplicationTests.class); - @LocalRunningGrpcPort + @LocalArmeriaPort private int port; - private ManagedChannel channel; + private MessageSenderBlockingStub blockingStub; @BeforeEach void init() { - channel = ManagedChannelBuilder.forAddress("localhost", port) - .usePlaintext() - .build(); + blockingStub = GrpcClients.newClient(String.format("http://localhost:%d", port), + MessageSenderBlockingStub.class); } @Test void test_success() { - final MessageSenderGrpc.MessageSenderBlockingStub messageSenderBlockingStub = MessageSenderGrpc.newBlockingStub(channel); - - final MessageSenderProto.MessageRequest messageRequest = MessageSenderProto.MessageRequest.newBuilder() - .setFrom("wonchul") - .setTo("naeun") - .setContents("hello!") - .build(); + final MessageSenderProto.MessageRequest messageRequest = + MessageSenderProto.MessageRequest.newBuilder() + .setFrom("wonchul") + .setTo("naeun") + .setContents("hello!") + .build(); try { - final MessageSenderProto.MessageResponse messageResponse = messageSenderBlockingStub.send(messageRequest); + final MessageSenderProto.MessageResponse messageResponse = blockingStub.send(messageRequest); assertThat(messageResponse.getStatus()).isEqualTo(Status.OK.toString()); assertThat(messageResponse.getReason()).isEqualTo("ok"); } catch (StatusRuntimeException sr) { @@ -54,16 +55,15 @@ void test_success() { @Test void test_fail() { - final MessageSenderGrpc.MessageSenderBlockingStub messageSenderBlockingStub = MessageSenderGrpc.newBlockingStub(channel); - - final MessageSenderProto.MessageRequest messageRequest = MessageSenderProto.MessageRequest.newBuilder() - .setFrom("wonchul") - .setTo("naeun") - .setContents("") - .build(); + final MessageSenderProto.MessageRequest messageRequest = + MessageSenderProto.MessageRequest.newBuilder() + .setFrom("wonchul") + .setTo("naeun") + .setContents("") + .build(); - assertThatThrownBy(()-> { - messageSenderBlockingStub.send(messageRequest); + assertThatThrownBy(() -> { + blockingStub.send(messageRequest); }).asInstanceOf(InstanceOfAssertFactories.type(StatusRuntimeException.class)).satisfies(e -> { assertThat(e.getStatus()).isEqualTo(Status.UNKNOWN); }); diff --git a/SpringBootGracefulShutdown/build.gradle b/SpringBootGracefulShutdown/build.gradle index 55d7d215..afe6a48e 100644 --- a/SpringBootGracefulShutdown/build.gradle +++ b/SpringBootGracefulShutdown/build.gradle @@ -1,6 +1,5 @@ group = 'com.example' version = '0.0.1-SNAPSHOT' -sourceCompatibility = '1.8' configurations { compileOnly { diff --git a/SpringBootHateoas/build.gradle b/SpringBootHateoas/build.gradle index f481f89a..8c91aa93 100644 --- a/SpringBootHateoas/build.gradle +++ b/SpringBootHateoas/build.gradle @@ -1,6 +1,5 @@ group = 'com.example' version = '0.0.1-SNAPSHOT' -sourceCompatibility = '1.8' repositories { mavenCentral() diff --git a/SpringBootInterceptor/build.gradle b/SpringBootInterceptor/build.gradle index c5ecdd52..e0616faf 100644 --- a/SpringBootInterceptor/build.gradle +++ b/SpringBootInterceptor/build.gradle @@ -1,6 +1,5 @@ group = 'com.example' version = '0.0.1-SNAPSHOT' -sourceCompatibility = '1.8' repositories { mavenCentral() diff --git a/SpringBootInterceptor/src/main/java/com/example/component/HttpInterceptor.java b/SpringBootInterceptor/src/main/java/com/example/component/HttpInterceptor.java index a96e1378..1e0a2a55 100644 --- a/SpringBootInterceptor/src/main/java/com/example/component/HttpInterceptor.java +++ b/SpringBootInterceptor/src/main/java/com/example/component/HttpInterceptor.java @@ -6,8 +6,8 @@ import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; @Component public class HttpInterceptor implements HandlerInterceptor { diff --git a/SpringBootJpa/build.gradle b/SpringBootJpa/build.gradle index 7d316a40..23d695e8 100644 --- a/SpringBootJpa/build.gradle +++ b/SpringBootJpa/build.gradle @@ -4,7 +4,6 @@ plugins { group = 'com.example' version = '0.0.1-SNAPSHOT' -sourceCompatibility = '1.8' repositories { mavenCentral() diff --git a/SpringBootJpa/src/main/java/com/example/java/onetomany/domain/Order.java b/SpringBootJpa/src/main/java/com/example/java/onetomany/domain/Order.java index e7ab8537..1c652929 100644 --- a/SpringBootJpa/src/main/java/com/example/java/onetomany/domain/Order.java +++ b/SpringBootJpa/src/main/java/com/example/java/onetomany/domain/Order.java @@ -1,6 +1,6 @@ package com.example.java.onetomany.domain; -import javax.persistence.*; +import jakarta.persistence.*; @Entity @Table(name = "TB_ORDER") diff --git a/SpringBootJpa/src/main/java/com/example/java/onetomany/domain/Product.java b/SpringBootJpa/src/main/java/com/example/java/onetomany/domain/Product.java index 333b47af..7af7c16c 100644 --- a/SpringBootJpa/src/main/java/com/example/java/onetomany/domain/Product.java +++ b/SpringBootJpa/src/main/java/com/example/java/onetomany/domain/Product.java @@ -1,6 +1,6 @@ package com.example.java.onetomany.domain; -import javax.persistence.*; +import jakarta.persistence.*; @Entity @Table(name = "TB_PRODUCT") diff --git a/SpringBootJpa/src/main/java/com/example/java/onetoone/domain/Market.java b/SpringBootJpa/src/main/java/com/example/java/onetoone/domain/Market.java index 61880c60..c575cd33 100644 --- a/SpringBootJpa/src/main/java/com/example/java/onetoone/domain/Market.java +++ b/SpringBootJpa/src/main/java/com/example/java/onetoone/domain/Market.java @@ -1,6 +1,6 @@ package com.example.java.onetoone.domain; -import javax.persistence.*; +import jakarta.persistence.*; @Entity @Table(name = "MARKET") diff --git a/SpringBootJpa/src/main/java/com/example/java/onetoone/domain/Owner.java b/SpringBootJpa/src/main/java/com/example/java/onetoone/domain/Owner.java index d092057b..c6f03aa1 100644 --- a/SpringBootJpa/src/main/java/com/example/java/onetoone/domain/Owner.java +++ b/SpringBootJpa/src/main/java/com/example/java/onetoone/domain/Owner.java @@ -1,6 +1,6 @@ package com.example.java.onetoone.domain; -import javax.persistence.*; +import jakarta.persistence.*; @Entity @Table(name = "OWNER") diff --git a/SpringBootJpa/src/main/java/com/example/java/simple/domain/Customer.java b/SpringBootJpa/src/main/java/com/example/java/simple/domain/Customer.java index 1512c0e2..6bc2a556 100644 --- a/SpringBootJpa/src/main/java/com/example/java/simple/domain/Customer.java +++ b/SpringBootJpa/src/main/java/com/example/java/simple/domain/Customer.java @@ -1,6 +1,6 @@ package com.example.java.simple.domain; -import javax.persistence.*; +import jakarta.persistence.*; @Entity @Access(AccessType.FIELD) diff --git a/SpringBootJpa/src/main/java/com/example/java/simple/domain/TimeData.java b/SpringBootJpa/src/main/java/com/example/java/simple/domain/TimeData.java index aa090ee7..03a3cce1 100644 --- a/SpringBootJpa/src/main/java/com/example/java/simple/domain/TimeData.java +++ b/SpringBootJpa/src/main/java/com/example/java/simple/domain/TimeData.java @@ -1,9 +1,9 @@ package com.example.java.simple.domain; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; import java.time.LocalDateTime; @Entity diff --git a/SpringBootJpa/src/main/java/com/example/java/simple/repository/SimpleCustomJpqlRepository.java b/SpringBootJpa/src/main/java/com/example/java/simple/repository/SimpleCustomJpqlRepository.java index aeb34839..4d9e5aaf 100644 --- a/SpringBootJpa/src/main/java/com/example/java/simple/repository/SimpleCustomJpqlRepository.java +++ b/SpringBootJpa/src/main/java/com/example/java/simple/repository/SimpleCustomJpqlRepository.java @@ -2,8 +2,8 @@ import com.example.java.simple.domain.Customer; -import javax.persistence.EntityManager; -import javax.persistence.PersistenceContext; +import jakarta.persistence.EntityManager; +import jakarta.persistence.PersistenceContext; import java.util.List; public class SimpleCustomJpqlRepository implements CustomJpqlRepository { diff --git a/SpringBootJpa/src/main/kotlin/com/example/kotlin/onetomany/domain/Order.kt b/SpringBootJpa/src/main/kotlin/com/example/kotlin/onetomany/domain/Order.kt index 1f060d0b..7731c419 100644 --- a/SpringBootJpa/src/main/kotlin/com/example/kotlin/onetomany/domain/Order.kt +++ b/SpringBootJpa/src/main/kotlin/com/example/kotlin/onetomany/domain/Order.kt @@ -1,6 +1,6 @@ package com.example.kotlin.onetomany.domain -import javax.persistence.* +import jakarta.persistence.* @Entity @Table(name = "TB_ORDER") diff --git a/SpringBootJpa/src/main/kotlin/com/example/kotlin/onetomany/domain/Product.kt b/SpringBootJpa/src/main/kotlin/com/example/kotlin/onetomany/domain/Product.kt index 8cbed2c8..8dd59ed7 100644 --- a/SpringBootJpa/src/main/kotlin/com/example/kotlin/onetomany/domain/Product.kt +++ b/SpringBootJpa/src/main/kotlin/com/example/kotlin/onetomany/domain/Product.kt @@ -1,6 +1,6 @@ package com.example.kotlin.onetomany.domain -import javax.persistence.* +import jakarta.persistence.* @Entity @Table(name = "TB_PRODUCT") diff --git a/SpringBootJpa/src/main/kotlin/com/example/kotlin/onetoone/domain/Market.kt b/SpringBootJpa/src/main/kotlin/com/example/kotlin/onetoone/domain/Market.kt index 73e0df33..59883d06 100644 --- a/SpringBootJpa/src/main/kotlin/com/example/kotlin/onetoone/domain/Market.kt +++ b/SpringBootJpa/src/main/kotlin/com/example/kotlin/onetoone/domain/Market.kt @@ -1,6 +1,6 @@ package com.example.kotlin.onetoone.domain -import javax.persistence.* +import jakarta.persistence.* @Entity @Table(name = "MARKET") diff --git a/SpringBootJpa/src/main/kotlin/com/example/kotlin/onetoone/domain/Owner.kt b/SpringBootJpa/src/main/kotlin/com/example/kotlin/onetoone/domain/Owner.kt index daa77b57..c7d553bb 100644 --- a/SpringBootJpa/src/main/kotlin/com/example/kotlin/onetoone/domain/Owner.kt +++ b/SpringBootJpa/src/main/kotlin/com/example/kotlin/onetoone/domain/Owner.kt @@ -1,6 +1,6 @@ package com.example.kotlin.onetoone.domain -import javax.persistence.* +import jakarta.persistence.* @Entity @Table(name = "OWNER") diff --git a/SpringBootJpa/src/main/kotlin/com/example/kotlin/simple/domain/Customer.kt b/SpringBootJpa/src/main/kotlin/com/example/kotlin/simple/domain/Customer.kt index a0a47cb5..1c22bb3d 100644 --- a/SpringBootJpa/src/main/kotlin/com/example/kotlin/simple/domain/Customer.kt +++ b/SpringBootJpa/src/main/kotlin/com/example/kotlin/simple/domain/Customer.kt @@ -1,6 +1,6 @@ package com.example.kotlin.simple.domain -import javax.persistence.* +import jakarta.persistence.* @Entity @NamedQuery(name = "Custom.findByName", query = "SELECT c FROM Customer c WHERE c.name = :name ") diff --git a/SpringBootJpa/src/main/kotlin/com/example/kotlin/simple/domain/TimeData.kt b/SpringBootJpa/src/main/kotlin/com/example/kotlin/simple/domain/TimeData.kt index a9756e7a..9e9cd57a 100644 --- a/SpringBootJpa/src/main/kotlin/com/example/kotlin/simple/domain/TimeData.kt +++ b/SpringBootJpa/src/main/kotlin/com/example/kotlin/simple/domain/TimeData.kt @@ -1,9 +1,9 @@ package com.example.kotlin.simple.domain -import javax.persistence.Entity -import javax.persistence.GeneratedValue -import javax.persistence.GenerationType -import javax.persistence.Id +import jakarta.persistence.Entity +import jakarta.persistence.GeneratedValue +import jakarta.persistence.GenerationType +import jakarta.persistence.Id import java.time.LocalDateTime @Entity diff --git a/SpringBootJpa/src/main/kotlin/com/example/kotlin/simple/repository/SimpleCustomJpqlRepository.kt b/SpringBootJpa/src/main/kotlin/com/example/kotlin/simple/repository/SimpleCustomJpqlRepository.kt index 59f308c7..7bb77c5a 100644 --- a/SpringBootJpa/src/main/kotlin/com/example/kotlin/simple/repository/SimpleCustomJpqlRepository.kt +++ b/SpringBootJpa/src/main/kotlin/com/example/kotlin/simple/repository/SimpleCustomJpqlRepository.kt @@ -1,7 +1,7 @@ package com.example.kotlin.simple.repository import com.example.kotlin.simple.domain.Customer -import javax.persistence.EntityManager +import jakarta.persistence.EntityManager class SimpleCustomJpqlRepository(val em: EntityManager) : CustomJpqlRepository { diff --git a/SpringBootJpaSecurity/build.gradle b/SpringBootJpaSecurity/build.gradle index a5b2ebb2..58d18b0a 100644 --- a/SpringBootJpaSecurity/build.gradle +++ b/SpringBootJpaSecurity/build.gradle @@ -1,6 +1,5 @@ group = 'com.example' version = '0.0.1-SNAPSHOT' -sourceCompatibility = '1.8' repositories { mavenCentral() diff --git a/SpringBootJpaSecurity/src/main/java/com/example/config/security/RestAuthenticationProcessingFilter.java b/SpringBootJpaSecurity/src/main/java/com/example/config/security/RestAuthenticationProcessingFilter.java index ff522123..f7b4e627 100644 --- a/SpringBootJpaSecurity/src/main/java/com/example/config/security/RestAuthenticationProcessingFilter.java +++ b/SpringBootJpaSecurity/src/main/java/com/example/config/security/RestAuthenticationProcessingFilter.java @@ -11,8 +11,8 @@ import org.springframework.security.web.util.matcher.RequestMatcher; import org.springframework.util.StringUtils; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; public class RestAuthenticationProcessingFilter extends AbstractAuthenticationProcessingFilter { diff --git a/SpringBootJpaSecurity/src/main/java/com/example/config/security/RestAuthenticationSuccessHandler.java b/SpringBootJpaSecurity/src/main/java/com/example/config/security/RestAuthenticationSuccessHandler.java index 577c9623..35861875 100644 --- a/SpringBootJpaSecurity/src/main/java/com/example/config/security/RestAuthenticationSuccessHandler.java +++ b/SpringBootJpaSecurity/src/main/java/com/example/config/security/RestAuthenticationSuccessHandler.java @@ -5,8 +5,8 @@ import org.springframework.security.core.Authentication; import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; public class RestAuthenticationSuccessHandler extends SimpleUrlAuthenticationSuccessHandler { diff --git a/SpringBootJpaSecurity/src/main/java/com/example/config/security/SecurityConfig.java b/SpringBootJpaSecurity/src/main/java/com/example/config/security/SecurityConfig.java index baa81164..0a740d23 100644 --- a/SpringBootJpaSecurity/src/main/java/com/example/config/security/SecurityConfig.java +++ b/SpringBootJpaSecurity/src/main/java/com/example/config/security/SecurityConfig.java @@ -1,61 +1,54 @@ package com.example.config.security; -import org.springframework.beans.factory.annotation.Autowired; +import jakarta.servlet.http.HttpServletRequest; + import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.HttpMethod; -import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; -import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; +import org.springframework.security.authentication.AuthenticationManagerResolver; +import org.springframework.security.authentication.ProviderManager; +import org.springframework.security.authentication.TestingAuthenticationToken; +import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; -import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.core.userdetails.User; +import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; -import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; -import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.security.provisioning.InMemoryUserDetailsManager; +import org.springframework.security.web.SecurityFilterChain; +import org.springframework.security.web.authentication.RequestMatcherDelegatingAuthenticationManagerResolver; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; +import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken; import org.springframework.security.web.util.matcher.AntPathRequestMatcher; import org.springframework.security.web.util.matcher.RequestMatcher; @Configuration -@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true) +@EnableMethodSecurity(securedEnabled = true) @EnableWebSecurity -public class SecurityConfig extends WebSecurityConfigurerAdapter { - - @Autowired - private UserDetailsService userDetailsService; +public class SecurityConfig { private static final String LOGIN_ENTRY_POINT = "/login"; private static final String LOGOUT_ENTRY_POINT = "/logout"; private static final String ALL_ENTRY_POINT = "/**"; - @Bean - public PasswordEncoder passwordEncoder() { - return new BCryptPasswordEncoder(); + AuthenticationManagerResolver resolver() { + return RequestMatcherDelegatingAuthenticationManagerResolver.builder() + .add(new AntPathRequestMatcher(ALL_ENTRY_POINT), new ProviderManager()) + .build(); } @Bean - public RestAuthenticationProcessingFilter restAuthenticationProcessingFilter() throws Exception { - RestAuthenticationProcessingFilter restAuthenticationProcessingFilter = new RestAuthenticationProcessingFilter(requestMatcher()); - restAuthenticationProcessingFilter.setAuthenticationManager(authenticationManager()); - restAuthenticationProcessingFilter.setAuthenticationSuccessHandler(new RestAuthenticationSuccessHandler()); - return restAuthenticationProcessingFilter; - } - - private RequestMatcher requestMatcher() { - return new AntPathRequestMatcher(LOGIN_ENTRY_POINT, HttpMethod.POST.name()); - } - - @Override - protected void configure(HttpSecurity http) throws Exception { + SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http .httpBasic().disable() - .authorizeRequests() - .antMatchers(HttpMethod.POST, LOGIN_ENTRY_POINT).permitAll() - .antMatchers(HttpMethod.GET, LOGOUT_ENTRY_POINT).permitAll() - .antMatchers(ALL_ENTRY_POINT).authenticated() + .authorizeHttpRequests() + .requestMatchers(HttpMethod.POST, LOGIN_ENTRY_POINT).permitAll() + .requestMatchers(HttpMethod.GET, LOGOUT_ENTRY_POINT).permitAll() + .requestMatchers(ALL_ENTRY_POINT).authenticated() .and() - .addFilterBefore(restAuthenticationProcessingFilter(), UsernamePasswordAuthenticationFilter.class) + .addFilterBefore(restAuthenticationProcessingFilter(), + UsernamePasswordAuthenticationFilter.class) // .formLogin() // .usernameParameter("id") // .passwordParameter("password") @@ -66,15 +59,39 @@ protected void configure(HttpSecurity http) throws Exception { .logoutUrl(LOGOUT_ENTRY_POINT) .and() .csrf().disable(); + return http.build(); + } + + @Bean + public RestAuthenticationProcessingFilter restAuthenticationProcessingFilter() throws Exception { + RestAuthenticationProcessingFilter restAuthenticationProcessingFilter = + new RestAuthenticationProcessingFilter(requestMatcher()); + restAuthenticationProcessingFilter.setAuthenticationSuccessHandler( + new RestAuthenticationSuccessHandler()); + restAuthenticationProcessingFilter.setAuthenticationManager(authentication -> { + return new PreAuthenticatedAuthenticationToken(authentication.getPrincipal(), + authentication.getCredentials()); + }); + return restAuthenticationProcessingFilter; } - @Override - protected void configure(AuthenticationManagerBuilder auth) throws Exception { - // [ in-memory 인증 ] -// auth.inMemoryAuthentication() -// .withUser("heowc").password("1234").roles("USER"); + private RequestMatcher requestMatcher() { + return new AntPathRequestMatcher(LOGIN_ENTRY_POINT, HttpMethod.POST.name()); + } -// [ 별도의 service 인증 ] - auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder()); + @Bean + public UserDetailsService users() { + UserDetails user = User.builder() + .username("user") + .password("{bcrypt}$2a$10$GRLdNijSQMUvl/au9ofL.eDwmoohzzS7.rmNSJZ.0FxO/BTk76klW") + .roles("USER") + .build(); + UserDetails admin = User.builder() + .username("admin") + .password( + "{bcrypt}$2a$10$GRLdNijSQMUvl/au9ofL.eDwmoohzzS7.rmNSJZ.0FxO/BTk76klW") + .roles("USER", "ADMIN") + .build(); + return new InMemoryUserDetailsManager(user, admin); } } \ No newline at end of file diff --git a/SpringBootJpaSecurity/src/main/java/com/example/domain/User.java b/SpringBootJpaSecurity/src/main/java/com/example/domain/User.java index a9ae938d..071a4729 100644 --- a/SpringBootJpaSecurity/src/main/java/com/example/domain/User.java +++ b/SpringBootJpaSecurity/src/main/java/com/example/domain/User.java @@ -2,7 +2,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; -import javax.persistence.*; +import jakarta.persistence.*; @Entity public class User { diff --git a/SpringBootJpaSecurity/src/test/java/com/example/web/UserControllerTest.java b/SpringBootJpaSecurity/src/test/java/com/example/web/UserControllerTest.java index a5c41387..eda8bf30 100644 --- a/SpringBootJpaSecurity/src/test/java/com/example/web/UserControllerTest.java +++ b/SpringBootJpaSecurity/src/test/java/com/example/web/UserControllerTest.java @@ -7,11 +7,10 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; -import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.context.annotation.Import; import org.springframework.http.HttpStatus; -import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.test.context.support.WithMockUser; +import org.springframework.test.context.bean.override.mockito.MockitoBean; import org.springframework.test.web.servlet.MockMvc; import static org.assertj.core.api.Assertions.assertThat; @@ -29,7 +28,7 @@ public class UserControllerTest { @Autowired private ObjectMapper objectMapper; - @MockBean + @MockitoBean private UserRepository repository; @Test diff --git a/SpringBootLogStash/build.gradle b/SpringBootLogStash/build.gradle index e159dbdd..2745fa4b 100644 --- a/SpringBootLogStash/build.gradle +++ b/SpringBootLogStash/build.gradle @@ -1,6 +1,5 @@ group = 'com.example' version = '0.0.1-SNAPSHOT' -sourceCompatibility = '1.8' configurations { compileOnly { @@ -14,7 +13,7 @@ repositories { dependencies { implementation 'org.springframework.boot:spring-boot-starter-web' - implementation 'net.logstash.logback:logstash-logback-encoder:6.6' + implementation 'net.logstash.logback:logstash-logback-encoder:8.1' compileOnly 'org.projectlombok:lombok' annotationProcessor 'org.projectlombok:lombok' diff --git a/SpringBootLogStash/src/main/resources/logback-spring.xml b/SpringBootLogStash/src/main/resources/logback-spring.xml index 68bdeb52..4c5e2bc3 100644 --- a/SpringBootLogStash/src/main/resources/logback-spring.xml +++ b/SpringBootLogStash/src/main/resources/logback-spring.xml @@ -28,7 +28,7 @@ ./log/log-%d{yyyy-MM-dd}-(%i).json 30 - + 50MB diff --git a/SpringBootMicroMeter/build.gradle b/SpringBootMicroMeter/build.gradle index 5693e4af..a0ac1d23 100644 --- a/SpringBootMicroMeter/build.gradle +++ b/SpringBootMicroMeter/build.gradle @@ -1,6 +1,5 @@ group = 'com.example' version = '0.0.1-SNAPSHOT' -sourceCompatibility = '1.8' repositories { mavenCentral() diff --git a/SpringBootMicroMeter/src/main/java/com/example/ExecutorServiceController.java b/SpringBootMicroMeter/src/main/java/com/example/ExecutorServiceController.java index fa54a2d9..d907a160 100644 --- a/SpringBootMicroMeter/src/main/java/com/example/ExecutorServiceController.java +++ b/SpringBootMicroMeter/src/main/java/com/example/ExecutorServiceController.java @@ -8,8 +8,8 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; -import javax.annotation.PostConstruct; -import javax.annotation.PreDestroy; +import jakarta.annotation.PostConstruct; +import jakarta.annotation.PreDestroy; import java.util.HashMap; import java.util.Map; import java.util.concurrent.ExecutorService; diff --git a/SpringBootMybatis/build.gradle b/SpringBootMybatis/build.gradle index afced706..569879b7 100644 --- a/SpringBootMybatis/build.gradle +++ b/SpringBootMybatis/build.gradle @@ -1,6 +1,5 @@ group = 'com.example' version = '0.0.1-SNAPSHOT' -sourceCompatibility = '1.8' configurations { compileOnly { @@ -14,7 +13,7 @@ repositories { dependencies { implementation 'org.springframework.boot:spring-boot-starter' - implementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter:2.1.4' + implementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter:3.0.5' compileOnly 'org.projectlombok:lombok' annotationProcessor 'org.projectlombok:lombok' diff --git a/SpringBootMybatis/src/main/java/com/tistory/heowc/dao/UserDao.java b/SpringBootMybatis/src/main/java/com/tistory/heowc/dao/AccountDao.java similarity index 56% rename from SpringBootMybatis/src/main/java/com/tistory/heowc/dao/UserDao.java rename to SpringBootMybatis/src/main/java/com/tistory/heowc/dao/AccountDao.java index e72d4947..28bcb1c0 100644 --- a/SpringBootMybatis/src/main/java/com/tistory/heowc/dao/UserDao.java +++ b/SpringBootMybatis/src/main/java/com/tistory/heowc/dao/AccountDao.java @@ -1,29 +1,29 @@ package com.tistory.heowc.dao; -import com.tistory.heowc.domain.User; +import com.tistory.heowc.domain.Account; import lombok.RequiredArgsConstructor; import org.apache.ibatis.session.SqlSession; import org.springframework.stereotype.Component; @Component @RequiredArgsConstructor -public class UserDao { +public class AccountDao { private final SqlSession sqlSession; - private static final String NAMESPACE = "com.tistory.heowc.dao.User."; + private static final String NAMESPACE = "com.tistory.heowc.dao.Account."; - public Long insert(User user) { - boolean isInserted = sqlSession.insert(NAMESPACE + "insert", user) == 1; + public Long insert(Account account) { + boolean inserted = sqlSession.insert(NAMESPACE + "insert", account) == 1; - if (isInserted) { - return user.getIdx(); + if (inserted) { + return account.getIdx(); } else { return null; } } - public User findByIdx(Long idx) { + public Account findByIdx(Long idx) { return sqlSession.selectOne(NAMESPACE + "findByIdx", idx); } @@ -31,7 +31,7 @@ public void deleteByIdx(Long idx) { sqlSession.delete(NAMESPACE + "deleteByIdx", idx); } - public void setFixedNameByIdx(User user) { - sqlSession.update(NAMESPACE + "setFixedNameByIdx", user); + public void setFixedNameByIdx(Account account) { + sqlSession.update(NAMESPACE + "setFixedNameByIdx", account); } } diff --git a/SpringBootMybatis/src/main/java/com/tistory/heowc/domain/User.java b/SpringBootMybatis/src/main/java/com/tistory/heowc/domain/Account.java similarity index 85% rename from SpringBootMybatis/src/main/java/com/tistory/heowc/domain/User.java rename to SpringBootMybatis/src/main/java/com/tistory/heowc/domain/Account.java index bc87e7d9..a38c7f6c 100644 --- a/SpringBootMybatis/src/main/java/com/tistory/heowc/domain/User.java +++ b/SpringBootMybatis/src/main/java/com/tistory/heowc/domain/Account.java @@ -10,7 +10,7 @@ @Data @NoArgsConstructor @AllArgsConstructor -public class User implements Serializable { +public class Account implements Serializable { private Long idx; private String name; diff --git a/SpringBootMybatis/src/main/java/com/tistory/heowc/mapper/AccountMapper.java b/SpringBootMybatis/src/main/java/com/tistory/heowc/mapper/AccountMapper.java new file mode 100644 index 00000000..f2b9a982 --- /dev/null +++ b/SpringBootMybatis/src/main/java/com/tistory/heowc/mapper/AccountMapper.java @@ -0,0 +1,26 @@ +package com.tistory.heowc.mapper; + +import com.tistory.heowc.domain.Account; +import org.apache.ibatis.annotations.*; + +@Mapper +public interface AccountMapper { + + String COLUMN = "`IDX`, `NAME`, `LOCAL`"; + + @Options( + useGeneratedKeys = true, + keyProperty = "idx" + ) + @Insert("INSERT INTO ACCOUNT VALUES (#{account.idx}, #{account.name}, #{account.local})") + int insert(@Param("account") Account account); + + @Select("SELECT " + COLUMN + " FROM ACCOUNT WHERE IDX = #{idx}") + Account findByIdx(@Param("idx") Long idx); + + @Delete("DELETE FROM ACCOUNT WHERE IDX = #{idx}") + void deleteByIdx(@Param("idx") Long idx); + + @Update("UPDATE ACCOUNT SET NAME = #{account.name} WHERE IDX = #{account.idx}") + void setFixedNameByIdx(@Param("account") Account account); +} diff --git a/SpringBootMybatis/src/main/java/com/tistory/heowc/mapper/UserMapper.java b/SpringBootMybatis/src/main/java/com/tistory/heowc/mapper/UserMapper.java deleted file mode 100644 index d7ecf8d8..00000000 --- a/SpringBootMybatis/src/main/java/com/tistory/heowc/mapper/UserMapper.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.tistory.heowc.mapper; - -import com.tistory.heowc.domain.User; -import org.apache.ibatis.annotations.*; - -@Mapper -public interface UserMapper { - - String COLUMN = "`IDX`, `NAME`, `LOCAL`"; - - @SelectKey( - statement = "SELECT #{user.idx} FROM DUAL", - keyProperty = "idx", - before = false, - resultType = Long.class - ) - @Insert("INSERT INTO USER VALUES (#{user.idx}, #{user.name}, #{user.local})") - int insert(@Param("user") User user); - - @Select("SELECT " + COLUMN + " FROM USER WHERE IDX = #{idx}") - User findByIdx(@Param("idx") Long idx); - - @Delete("DELETE FROM USER WHERE IDX = #{idx}") - void deleteByIdx(@Param("idx") Long idx); - - @Update("UPDATE USER SET NAME = #{user.name} WHERE IDX = #{user.idx}") - void setFixedNameByIdx(@Param("user") User user); -} diff --git a/SpringBootMybatis/src/main/resources/com/tistory/heowc/dao/Account.xml b/SpringBootMybatis/src/main/resources/com/tistory/heowc/dao/Account.xml new file mode 100644 index 00000000..018d7259 --- /dev/null +++ b/SpringBootMybatis/src/main/resources/com/tistory/heowc/dao/Account.xml @@ -0,0 +1,24 @@ + + + + + `IDX`, `NAME`, `LOCAL` + + + INSERT INTO ACCOUNT VALUES (#{idx}, #{name}, #{local}) + + + + + + DELETE FROM ACCOUNT WHERE IDX = #{idx} + + + + UPDATE ACCOUNT SET NAME = #{name} WHERE IDX = #{idx} + + \ No newline at end of file diff --git a/SpringBootMybatis/src/main/resources/com/tistory/heowc/dao/User.xml b/SpringBootMybatis/src/main/resources/com/tistory/heowc/dao/User.xml deleted file mode 100644 index 5a2dff72..00000000 --- a/SpringBootMybatis/src/main/resources/com/tistory/heowc/dao/User.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - - - `IDX`, `NAME`, `LOCAL` - - - - SELECT #{idx} FROM DUAL - - INSERT INTO USER VALUES (#{idx}, #{name}, #{local}) - - - - - - DELETE FROM USER WHERE IDX = #{idx} - - - - UPDATE USER SET NAME = #{name} WHERE IDX = #{idx} - - \ No newline at end of file diff --git a/SpringBootMybatis/src/main/resources/schema.sql b/SpringBootMybatis/src/main/resources/schema.sql index 535241ef..e37ac5f3 100644 --- a/SpringBootMybatis/src/main/resources/schema.sql +++ b/SpringBootMybatis/src/main/resources/schema.sql @@ -1,4 +1,4 @@ -CREATE TABLE USER ( +CREATE TABLE ACCOUNT ( IDX NUMBER PRIMARY KEY NOT NULL , NAME VARCHAR(20) NOT NULL , LOCAL VARCHAR(20) NOT NULL diff --git a/SpringBootMybatis/src/test/java/com/tistory/heowc/AccountDaoTests.java b/SpringBootMybatis/src/test/java/com/tistory/heowc/AccountDaoTests.java new file mode 100644 index 00000000..3b765cd9 --- /dev/null +++ b/SpringBootMybatis/src/test/java/com/tistory/heowc/AccountDaoTests.java @@ -0,0 +1,67 @@ +package com.tistory.heowc; + +import com.tistory.heowc.dao.AccountDao; +import com.tistory.heowc.domain.Account; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.transaction.annotation.Transactional; + +import static org.assertj.core.api.Assertions.assertThat; + +@SpringBootTest +@Transactional +class AccountDaoTests { + + @Autowired + private AccountDao userDao; + + @Test + void test_insert() { + // given + Account account = new Account(2L, "wonchul", "seoul"); + + // when + Long idx = userDao.insert(account); + + // then + Account byIdx = userDao.findByIdx(idx); + assertThat(byIdx).hasFieldOrPropertyWithValue("idx", account.getIdx()); + assertThat(byIdx).hasFieldOrPropertyWithValue("name", account.getName()); + assertThat(byIdx).hasFieldOrPropertyWithValue("local", account.getLocal()); + } + + @Test + void test_update() { + // given + Account account = new Account(1L, "wonchul", "seoul"); + Long idx = userDao.insert(account); + + // when + account.setIdx(idx); + account.setName("heowc"); + userDao.setFixedNameByIdx(account); + + // then + Account byIdx = userDao.findByIdx(idx); + assertThat(byIdx).hasFieldOrPropertyWithValue("idx", account.getIdx()); + assertThat(byIdx).hasFieldOrPropertyWithValue("name", account.getName()); + assertThat(byIdx).hasFieldOrPropertyWithValue("local", account.getLocal()); + } + + @Test + void test_delete() { + // given + Account account = new Account(1L, "wonchul", "seoul"); + Long idx = userDao.insert(account); + + // when + userDao.deleteByIdx(idx); + + // then + Account byIdx = userDao.findByIdx(idx); + assertThat(byIdx).isNull(); + } + +} \ No newline at end of file diff --git a/SpringBootMybatis/src/test/java/com/tistory/heowc/AccountMapperTests.java b/SpringBootMybatis/src/test/java/com/tistory/heowc/AccountMapperTests.java new file mode 100644 index 00000000..4c253b21 --- /dev/null +++ b/SpringBootMybatis/src/test/java/com/tistory/heowc/AccountMapperTests.java @@ -0,0 +1,65 @@ +package com.tistory.heowc; + +import com.tistory.heowc.domain.Account; +import com.tistory.heowc.mapper.AccountMapper; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.transaction.annotation.Transactional; + +import static org.assertj.core.api.Assertions.assertThat; + +@SpringBootTest +@Transactional +class AccountMapperTests { + + @Autowired + private AccountMapper accountMapper; + + @Test + void test_insert() { + // given + Account account = new Account(2L, "wonchul", "seoul"); + + // when + accountMapper.insert(account); + + // then + Account byIdx = accountMapper.findByIdx(account.getIdx()); + assertThat(byIdx).hasFieldOrPropertyWithValue("idx", account.getIdx()); + assertThat(byIdx).hasFieldOrPropertyWithValue("name", account.getName()); + assertThat(byIdx).hasFieldOrPropertyWithValue("local", account.getLocal()); + } + + @Test + void test_update() { + // given + Account account = new Account(1L, "wonchul", "seoul"); + accountMapper.insert(account); + + // when + account.setIdx(account.getIdx()); + account.setName("heowc"); + accountMapper.setFixedNameByIdx(account); + + // then + Account byIdx = accountMapper.findByIdx(account.getIdx()); + assertThat(byIdx).hasFieldOrPropertyWithValue("idx", account.getIdx()); + assertThat(byIdx).hasFieldOrPropertyWithValue("name", account.getName()); + assertThat(byIdx).hasFieldOrPropertyWithValue("local", account.getLocal()); + } + + @Test + void test_delete() { + // given + Account account = new Account(1L, "wonchul", "seoul"); + accountMapper.insert(account); + + // when + accountMapper.deleteByIdx(account.getIdx()); + + // then + Account byIdx = accountMapper.findByIdx(account.getIdx()); + assertThat(byIdx).isNull(); + } +} diff --git a/SpringBootMybatis/src/test/java/com/tistory/heowc/UserDaoTests.java b/SpringBootMybatis/src/test/java/com/tistory/heowc/UserDaoTests.java deleted file mode 100644 index 9b81ea84..00000000 --- a/SpringBootMybatis/src/test/java/com/tistory/heowc/UserDaoTests.java +++ /dev/null @@ -1,66 +0,0 @@ -package com.tistory.heowc; - -import com.tistory.heowc.dao.UserDao; -import com.tistory.heowc.domain.User; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.transaction.annotation.Transactional; - -import static org.assertj.core.api.Assertions.assertThat; - -@SpringBootTest -@Transactional -class UserDaoTests { - - @Autowired - private UserDao userDao; - - @Test - void test_insert() { - // given - User user = new User(2L, "wonchul", "seoul"); - - // when - Long idx = userDao.insert(user); - - // then - User byIdx = userDao.findByIdx(idx); - assertThat(byIdx).hasFieldOrPropertyWithValue("idx", user.getIdx()); - assertThat(byIdx).hasFieldOrPropertyWithValue("name", user.getName()); - assertThat(byIdx).hasFieldOrPropertyWithValue("local", user.getLocal()); - } - - @Test - void test_update() { - // given - User user = new User(1L, "wonchul", "seoul"); - Long idx = userDao.insert(user); - - // when - user.setIdx(idx); - user.setName("heowc"); - userDao.setFixedNameByIdx(user); - - // then - User byIdx = userDao.findByIdx(idx); - assertThat(byIdx).hasFieldOrPropertyWithValue("idx", user.getIdx()); - assertThat(byIdx).hasFieldOrPropertyWithValue("name", user.getName()); - assertThat(byIdx).hasFieldOrPropertyWithValue("local", user.getLocal()); - } - - @Test - void test_delete() { - // given - User user = new User(1L, "wonchul", "seoul"); - Long idx = userDao.insert(user); - - // when - userDao.deleteByIdx(idx); - - // then - User byIdx = userDao.findByIdx(idx); - assertThat(byIdx).isNull(); - } - -} \ No newline at end of file diff --git a/SpringBootMybatis/src/test/java/com/tistory/heowc/UserMapperTests.java b/SpringBootMybatis/src/test/java/com/tistory/heowc/UserMapperTests.java deleted file mode 100644 index bfbe909f..00000000 --- a/SpringBootMybatis/src/test/java/com/tistory/heowc/UserMapperTests.java +++ /dev/null @@ -1,65 +0,0 @@ -package com.tistory.heowc; - -import com.tistory.heowc.domain.User; -import com.tistory.heowc.mapper.UserMapper; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.transaction.annotation.Transactional; - -import static org.assertj.core.api.Assertions.assertThat; - -@SpringBootTest -@Transactional -class UserMapperTests { - - @Autowired - private UserMapper userMapper; - - @Test - void test_insert() { - // given - User user = new User(2L, "wonchul", "seoul"); - - // when - userMapper.insert(user); - - // then - User byIdx = userMapper.findByIdx(user.getIdx()); - assertThat(byIdx).hasFieldOrPropertyWithValue("idx", user.getIdx()); - assertThat(byIdx).hasFieldOrPropertyWithValue("name", user.getName()); - assertThat(byIdx).hasFieldOrPropertyWithValue("local", user.getLocal()); - } - - @Test - void test_update() { - // given - User user = new User(1L, "wonchul", "seoul"); - userMapper.insert(user); - - // when - user.setIdx(user.getIdx()); - user.setName("heowc"); - userMapper.setFixedNameByIdx(user); - - // then - User byIdx = userMapper.findByIdx(user.getIdx()); - assertThat(byIdx).hasFieldOrPropertyWithValue("idx", user.getIdx()); - assertThat(byIdx).hasFieldOrPropertyWithValue("name", user.getName()); - assertThat(byIdx).hasFieldOrPropertyWithValue("local", user.getLocal()); - } - - @Test - void test_delete() { - // given - User user = new User(1L, "wonchul", "seoul"); - userMapper.insert(user); - - // when - userMapper.deleteByIdx(user.getIdx()); - - // then - User byIdx = userMapper.findByIdx(user.getIdx()); - assertThat(byIdx).isNull(); - } -} diff --git a/SpringBootMybatis/src/test/resources/application.properties b/SpringBootMybatis/src/test/resources/application.properties new file mode 100644 index 00000000..ad73e19e --- /dev/null +++ b/SpringBootMybatis/src/test/resources/application.properties @@ -0,0 +1,5 @@ +mybatis.mapper-locations=classpath*:com/tistory/heowc/dao/*.xml +#logging.level.root=DEBUG +logging.level.org.mybatis.spring.SqlSessionUtils=DEBUG +logging.level.com.tistory.heowc.mapper=DEBUG +logging.level.com.tistory.heowc.dao=DEBUG \ No newline at end of file diff --git a/SpringBootNotice/build.gradle b/SpringBootNotice/build.gradle index f98e9b69..c2cea044 100644 --- a/SpringBootNotice/build.gradle +++ b/SpringBootNotice/build.gradle @@ -1,6 +1,5 @@ group = 'com.example' version = '0.0.1-SNAPSHOT' -sourceCompatibility = '1.8' configurations { compileOnly { @@ -26,6 +25,6 @@ dependencies { runtimeOnly 'com.h2database:h2' - implementation "org.webjars:bootstrap:5.0.1" - implementation "org.webjars:jquery:3.6.0" + implementation "org.webjars:bootstrap:5.3.8" + implementation "org.webjars:jquery:3.7.1" } diff --git a/SpringBootNotice/src/main/java/com/tistory/heowc/component/InitRunner.java b/SpringBootNotice/src/main/java/com/tistory/heowc/component/InitRunner.java index f096e97c..7b4b1f4a 100644 --- a/SpringBootNotice/src/main/java/com/tistory/heowc/component/InitRunner.java +++ b/SpringBootNotice/src/main/java/com/tistory/heowc/component/InitRunner.java @@ -11,13 +11,14 @@ @Component @Transactional public class InitRunner implements ApplicationRunner { - - @Autowired NoticeRepository repository; - + + @Autowired + private NoticeRepository repository; + @Override public void run(ApplicationArguments args) throws Exception { - for (int i = 0; i < 50; i++) { - repository.save(new Notice((long) i, "title " + i, "content " + i)); + for (long i = 0; i < 50; i++) { + repository.save(new Notice(i, "title " + i, "content " + i)); } } } diff --git a/SpringBootNotice/src/main/java/com/tistory/heowc/domain/Notice.java b/SpringBootNotice/src/main/java/com/tistory/heowc/domain/Notice.java index 0a63ed9a..e355e3cd 100644 --- a/SpringBootNotice/src/main/java/com/tistory/heowc/domain/Notice.java +++ b/SpringBootNotice/src/main/java/com/tistory/heowc/domain/Notice.java @@ -3,10 +3,9 @@ import lombok.AllArgsConstructor; import lombok.Data; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.Id; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; import java.io.Serializable; @Entity @@ -15,7 +14,6 @@ public class Notice implements Serializable { @Id - @GeneratedValue private Long idx; private String title; diff --git a/SpringBootNotice/src/main/java/com/tistory/heowc/repository/NoticeRepositoryImpl.java b/SpringBootNotice/src/main/java/com/tistory/heowc/repository/NoticeRepositoryImpl.java index 8a19ef6d..4a4d5b2c 100644 --- a/SpringBootNotice/src/main/java/com/tistory/heowc/repository/NoticeRepositoryImpl.java +++ b/SpringBootNotice/src/main/java/com/tistory/heowc/repository/NoticeRepositoryImpl.java @@ -2,8 +2,8 @@ import com.tistory.heowc.domain.Notice; -import javax.persistence.EntityManager; -import javax.persistence.PersistenceContext; +import jakarta.persistence.EntityManager; +import jakarta.persistence.PersistenceContext; import java.util.List; public class NoticeRepositoryImpl implements NoticeRepositoryCustom { diff --git a/SpringBootOAuth2/build.gradle b/SpringBootOAuth2/build.gradle index 513b84bf..513749e2 100644 --- a/SpringBootOAuth2/build.gradle +++ b/SpringBootOAuth2/build.gradle @@ -1,6 +1,5 @@ group = 'com.example' version = '0.0.1-SNAPSHOT' -sourceCompatibility = '1.8' configurations { compileOnly { @@ -19,7 +18,7 @@ dependencies { annotationProcessor 'org.projectlombok:lombok' implementation 'org.springframework.boot:spring-boot-starter-security' - implementation 'org.springframework.security.oauth.boot:spring-security-oauth2-autoconfigure:2.4.5' + implementation 'org.springframework.security.oauth.boot:spring-security-oauth2-autoconfigure:2.6.8' implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'org.springframework.boot:spring-boot-starter-data-jpa' } diff --git a/SpringBootOAuth2/src/main/resources/application.properties b/SpringBootOAuth2/src/main/resources/application.properties index 09fd769c..9ba4f08d 100644 --- a/SpringBootOAuth2/src/main/resources/application.properties +++ b/SpringBootOAuth2/src/main/resources/application.properties @@ -1,5 +1,5 @@ -security.user.name=root -security.user.password=wonchul +security.account.name=root +security.account.password=wonchul security.oauth2.client.client-id=wonchul security.oauth2.client.client-secret=wonchul diff --git a/SpringBootConfigurable/build.gradle b/SpringBootQuartz/build.gradle similarity index 56% rename from SpringBootConfigurable/build.gradle rename to SpringBootQuartz/build.gradle index 95cb845b..f2e962bc 100644 --- a/SpringBootConfigurable/build.gradle +++ b/SpringBootQuartz/build.gradle @@ -1,25 +1,21 @@ -plugins { - id 'org.jetbrains.kotlin.plugin.jpa' -} - group = 'com.example' version = '0.0.1-SNAPSHOT' -sourceCompatibility = '1.8' + +configurations { + compileOnly { + extendsFrom annotationProcessor + } +} repositories { - mavenCentral() + mavenCentral() } dependencies { + implementation 'org.springframework.boot:spring-boot-starter-quartz' implementation 'org.springframework.boot:spring-boot-starter-web' - implementation 'org.springframework.boot:spring-boot-starter-data-jpa' - implementation 'org.springframework.boot:spring-boot-starter-security' - implementation 'org.apache.commons:commons-lang3' + implementation 'org.springframework.boot:spring-boot-starter-jdbc' runtimeOnly 'com.h2database:h2' -} - - -test { - jvmArgs '-javaagent:libs/spring-instrument-5.2.1.RELEASE.jar' + testImplementation 'org.springframework.boot:spring-boot-starter-test' } \ No newline at end of file diff --git a/SpringBootQuartz/src/main/java/org/example/QuartzJobsConfig.java b/SpringBootQuartz/src/main/java/org/example/QuartzJobsConfig.java new file mode 100644 index 00000000..e2f3bd99 --- /dev/null +++ b/SpringBootQuartz/src/main/java/org/example/QuartzJobsConfig.java @@ -0,0 +1,33 @@ +package org.example; + +import org.quartz.*; +import org.springframework.boot.ApplicationRunner; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.scheduling.quartz.SchedulerFactoryBean; + +@Configuration +class QuartzJobsConfig { + + @Bean + ApplicationRunner shortenLifeCycleJob(SchedulerFactoryBean schedulerFactoryBean) { + return args -> { + // Job 생성 + final JobDetail jobDetail = JobBuilder.newJob(SimpleJob.class).build(); + + // Trigger 생성 + final Trigger trigger = TriggerBuilder.newTrigger() + .startNow() + .withSchedule(SimpleScheduleBuilder.simpleSchedule() + .withIntervalInSeconds(1) + .repeatForever()) + .build(); + + try { + schedulerFactoryBean.getScheduler().scheduleJob(jobDetail, trigger); + } catch (Exception e) { + throw new RuntimeException(e); + } + }; + } +} diff --git a/SpringBootQuartz/src/main/java/org/example/SimpleJob.java b/SpringBootQuartz/src/main/java/org/example/SimpleJob.java new file mode 100644 index 00000000..9e442c79 --- /dev/null +++ b/SpringBootQuartz/src/main/java/org/example/SimpleJob.java @@ -0,0 +1,17 @@ +package org.example; + +import org.quartz.Job; +import org.quartz.JobExecutionContext; +import org.quartz.JobExecutionException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class SimpleJob implements Job { + + private static final Logger logger = LoggerFactory.getLogger(SimpleJob.class); + + @Override + public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException { + logger.info("executing..."); + } +} diff --git a/SpringBootConfigurable/src/main/java/com/example/java/SpringBootConfigurableApplication.java b/SpringBootQuartz/src/main/java/org/example/SpringBootQuartzApplication.java similarity index 56% rename from SpringBootConfigurable/src/main/java/com/example/java/SpringBootConfigurableApplication.java rename to SpringBootQuartz/src/main/java/org/example/SpringBootQuartzApplication.java index 4882ad68..0fb822f3 100644 --- a/SpringBootConfigurable/src/main/java/com/example/java/SpringBootConfigurableApplication.java +++ b/SpringBootQuartz/src/main/java/org/example/SpringBootQuartzApplication.java @@ -1,12 +1,13 @@ -package com.example.java; +package org.example; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication -public class SpringBootConfigurableApplication { +public class SpringBootQuartzApplication { public static void main(String[] args) { - SpringApplication.run(SpringBootConfigurableApplication.class, args); + SpringApplication.run(SpringBootQuartzApplication.class, args); } + } diff --git a/SpringBootQuartz/src/main/resources/application.properties b/SpringBootQuartz/src/main/resources/application.properties new file mode 100644 index 00000000..390f323b --- /dev/null +++ b/SpringBootQuartz/src/main/resources/application.properties @@ -0,0 +1,20 @@ +spring.application.name=spring-boot-quartz + +spring.datasource.url=jdbc:h2:mem:quartz;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE + +spring.quartz.job-store-type=jdbc +spring.quartz.jdbc.platform=h2 + +spring.quartz.properties.org.quartz.scheduler.instanceId=CLUSTERED +spring.quartz.properties.org.quartz.jobStore.class = org.springframework.scheduling.quartz.LocalDataSourceJobStore +spring.quartz.properties.org.quartz.jobStore.dataSource=simpleDataSource +spring.quartz.properties.org.quartz.dataSource=simpleDataSource +spring.quartz.properties.org.quartz.dataSource.simpleDataSource.provider=hikaricp +spring.quartz.properties.org.quartz.dataSource.simpleDataSource.driver=org.h2.Driver +spring.quartz.properties.org.quartz.dataSource.simpleDataSource.URL=jdbc:h2:mem:quartz;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE +spring.quartz.properties.org.quartz.dataSource.simpleDataSource.user=sa +#spring.quartz.properties.org.quartz.dataSource.simpleDataSource.password= + +spring.quartz.properties.org.quartz.jobStore.misfireThreshold=1000 +spring.quartz.properties.org.quartz.jobStore.isClustered=true +spring.quartz.properties.org.quartz.jobStore.clusterCheckinInterval=1000 diff --git a/SpringBootQuartz/src/test/java/org/example/SpringBootQuartzApplicationTests.java b/SpringBootQuartz/src/test/java/org/example/SpringBootQuartzApplicationTests.java new file mode 100644 index 00000000..34e6fc8b --- /dev/null +++ b/SpringBootQuartz/src/test/java/org/example/SpringBootQuartzApplicationTests.java @@ -0,0 +1,13 @@ +package org.example; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest +class SpringBootQuartzApplicationTests { + + @Test + void contextLoads() { + } + +} diff --git a/SpringBootQuartz/src/test/resources/application-test.properties b/SpringBootQuartz/src/test/resources/application-test.properties new file mode 100644 index 00000000..e69de29b diff --git a/SpringBootQueryDsl/build.gradle b/SpringBootQueryDsl/build.gradle index 0c494aba..968a5a16 100644 --- a/SpringBootQueryDsl/build.gradle +++ b/SpringBootQueryDsl/build.gradle @@ -1,10 +1,5 @@ -plugins { - id 'com.ewerk.gradle.plugins.querydsl' version '1.0.10' -} - group = 'com.example' version = '0.0.1-SNAPSHOT' -sourceCompatibility = '1.8' configurations { compileOnly { @@ -23,25 +18,7 @@ dependencies { compileOnly 'org.projectlombok:lombok' annotationProcessor 'org.projectlombok:lombok' - /** - * querydsl dependency - */ - implementation "com.querydsl:querydsl-apt" - implementation "com.querydsl:querydsl-jpa" -} - -def queryDslOutput = 'src-gen/main/java' - -querydsl { - library = "com.querydsl:querydsl-apt" - jpa = true - querydslSourcesDir = queryDslOutput -} - -compileQuerydsl { - options.annotationProcessorPath = configurations.querydsl -} - -configurations { - querydsl.extendsFrom compileClasspath + annotationProcessor 'jakarta.persistence:jakarta.persistence-api' + annotationProcessor 'com.querydsl:querydsl-apt::jakarta' + implementation "com.querydsl:querydsl-jpa::jakarta" } diff --git a/SpringBootQueryDsl/src/main/java/com/tistory/heowc/config/DatabaseConfig.java b/SpringBootQueryDsl/src/main/java/com/tistory/heowc/config/DatabaseConfig.java index cb71d0c7..01c29832 100644 --- a/SpringBootQueryDsl/src/main/java/com/tistory/heowc/config/DatabaseConfig.java +++ b/SpringBootQueryDsl/src/main/java/com/tistory/heowc/config/DatabaseConfig.java @@ -1,6 +1,6 @@ package com.tistory.heowc.config; -import javax.persistence.EntityManager; +import jakarta.persistence.EntityManager; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/SpringBootQueryDsl/src/main/java/com/tistory/heowc/domain/Grade.java b/SpringBootQueryDsl/src/main/java/com/tistory/heowc/domain/Grade.java index eb82baff..0898a993 100644 --- a/SpringBootQueryDsl/src/main/java/com/tistory/heowc/domain/Grade.java +++ b/SpringBootQueryDsl/src/main/java/com/tistory/heowc/domain/Grade.java @@ -3,10 +3,10 @@ import lombok.AllArgsConstructor; import lombok.Data; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.Id; -import javax.persistence.OneToMany; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.OneToMany; import java.io.Serializable; import java.util.ArrayList; import java.util.List; diff --git a/SpringBootQueryDsl/src/main/java/com/tistory/heowc/domain/Student.java b/SpringBootQueryDsl/src/main/java/com/tistory/heowc/domain/Student.java index caff5118..998f4212 100644 --- a/SpringBootQueryDsl/src/main/java/com/tistory/heowc/domain/Student.java +++ b/SpringBootQueryDsl/src/main/java/com/tistory/heowc/domain/Student.java @@ -5,7 +5,7 @@ import lombok.Setter; import org.hibernate.annotations.GenericGenerator; -import javax.persistence.*; +import jakarta.persistence.*; import java.io.Serializable; @Entity @@ -29,7 +29,7 @@ public class Student implements Serializable { @Column(name = "STUDENT_NAME") private String name; - + @Column(name = "STUDENT_HEIGHT") private Double height; diff --git a/SpringBootRabbitMQ/build.gradle b/SpringBootRabbitMQ/build.gradle index 1ee880c0..1571b3d5 100644 --- a/SpringBootRabbitMQ/build.gradle +++ b/SpringBootRabbitMQ/build.gradle @@ -1,6 +1,5 @@ group = 'com.example' version = '0.0.1-SNAPSHOT' -sourceCompatibility = '1.8' repositories { mavenCentral() diff --git a/SpringBootRedis/build.gradle b/SpringBootRedis/build.gradle index abca2ca4..65725ef2 100644 --- a/SpringBootRedis/build.gradle +++ b/SpringBootRedis/build.gradle @@ -1,6 +1,5 @@ group = 'com.example' version = '0.0.1-SNAPSHOT' -sourceCompatibility = '1.8' configurations { compileOnly { diff --git a/SpringBootRest/build.gradle b/SpringBootRest/build.gradle index 21ad2347..178112e0 100644 --- a/SpringBootRest/build.gradle +++ b/SpringBootRest/build.gradle @@ -1,6 +1,6 @@ group = 'com.example' version = '0.0.1-SNAPSHOT' -sourceCompatibility = '1.8' + configurations { compileOnly { diff --git a/SpringBootRest/src/main/java/com/example/domain/Person.java b/SpringBootRest/src/main/java/com/example/domain/Person.java index cf497807..2de30851 100644 --- a/SpringBootRest/src/main/java/com/example/domain/Person.java +++ b/SpringBootRest/src/main/java/com/example/domain/Person.java @@ -3,9 +3,9 @@ import lombok.AllArgsConstructor; import lombok.Data; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.Id; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.Id; @Entity @Data diff --git a/SpringBootRestDocs/build.gradle b/SpringBootRestDocs/build.gradle index f58abb61..8b4836ab 100644 --- a/SpringBootRestDocs/build.gradle +++ b/SpringBootRestDocs/build.gradle @@ -1,6 +1,5 @@ group = 'com.example' version = '0.0.1-SNAPSHOT' -sourceCompatibility = '1.8' repositories { mavenCentral() diff --git a/SpringBootSecurityAddRedis/build.gradle b/SpringBootSecurityAddRedis/build.gradle index 2b60411c..a8738274 100644 --- a/SpringBootSecurityAddRedis/build.gradle +++ b/SpringBootSecurityAddRedis/build.gradle @@ -1,6 +1,5 @@ group = 'com.example' version = '0.0.1-SNAPSHOT' -sourceCompatibility = '1.8' repositories { mavenCentral() diff --git a/SpringBootSecurityAddRedis/src/main/java/com/tistory/heowc/config/SecurityConfig.java b/SpringBootSecurityAddRedis/src/main/java/com/tistory/heowc/config/SecurityConfig.java index 866fc6a9..8e43f6ce 100644 --- a/SpringBootSecurityAddRedis/src/main/java/com/tistory/heowc/config/SecurityConfig.java +++ b/SpringBootSecurityAddRedis/src/main/java/com/tistory/heowc/config/SecurityConfig.java @@ -1,45 +1,34 @@ package com.tistory.heowc.config; -import com.tistory.heowc.service.UserDetailsServiceImpl; -import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.config.annotation.web.builders.WebSecurity; -import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; -import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.security.config.annotation.web.configuration.WebSecurityCustomizer; +import org.springframework.security.web.SecurityFilterChain; @Configuration -public class SecurityConfig extends WebSecurityConfigurerAdapter { +public class SecurityConfig { - @Autowired - private UserDetailsServiceImpl userDetailsService; + @Bean + WebSecurityCustomizer customizer() { + return web -> { + web.ignoring().requestMatchers("/resources/**"); + }; + } - @Autowired - private PasswordEncoder passwordEncoder; - - @Override - public void configure(WebSecurity web) { - web.ignoring().antMatchers("/resources/**"); - } - - @Override - protected void configure(AuthenticationManagerBuilder auth) throws Exception { - auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder); - } - - @Override - protected void configure(HttpSecurity http) throws Exception { - http - .authorizeRequests() - .anyRequest().authenticated() - .and() - .formLogin() - .usernameParameter("id") - .passwordParameter("pw") - .defaultSuccessUrl("/user", true) - .permitAll() - .and() - .csrf().disable(); - } + @Bean + SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { + http + .authorizeHttpRequests() + .anyRequest().authenticated() + .and() + .formLogin() + .usernameParameter("id") + .passwordParameter("pw") + .defaultSuccessUrl("/user", true) + .permitAll() + .and() + .csrf().disable(); + return http.build(); + } } diff --git a/SpringBootSecurityAddRedis/src/main/java/com/tistory/heowc/domain/Member.java b/SpringBootSecurityAddRedis/src/main/java/com/tistory/heowc/domain/Member.java index 2452253c..d4a5ca9c 100644 --- a/SpringBootSecurityAddRedis/src/main/java/com/tistory/heowc/domain/Member.java +++ b/SpringBootSecurityAddRedis/src/main/java/com/tistory/heowc/domain/Member.java @@ -1,8 +1,8 @@ package com.tistory.heowc.domain; -import javax.persistence.Entity; -import javax.persistence.Id; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; @Entity public class Member { diff --git a/SpringBootSecurityJwt/build.gradle b/SpringBootSecurityJwt/build.gradle index f528f820..2f46e50c 100644 --- a/SpringBootSecurityJwt/build.gradle +++ b/SpringBootSecurityJwt/build.gradle @@ -1,6 +1,5 @@ group = 'com.example' version = '0.0.1-SNAPSHOT' -sourceCompatibility = '1.8' repositories { mavenCentral() diff --git a/SpringBootSecurityJwt/src/main/java/com/tistory/heowc/auth/BaseSecurityHandler.java b/SpringBootSecurityJwt/src/main/java/com/tistory/heowc/auth/BaseSecurityHandler.java index cf3ab01c..60b8cc73 100644 --- a/SpringBootSecurityJwt/src/main/java/com/tistory/heowc/auth/BaseSecurityHandler.java +++ b/SpringBootSecurityJwt/src/main/java/com/tistory/heowc/auth/BaseSecurityHandler.java @@ -12,8 +12,8 @@ import org.springframework.stereotype.Component; import org.springframework.web.server.ResponseStatusException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import java.util.ArrayList; @Component diff --git a/SpringBootSecurityJwt/src/main/java/com/tistory/heowc/auth/ajax/AjaxUserDetailsService.java b/SpringBootSecurityJwt/src/main/java/com/tistory/heowc/auth/ajax/AjaxUserDetailsService.java index 29f2b7d8..866bcdf2 100644 --- a/SpringBootSecurityJwt/src/main/java/com/tistory/heowc/auth/ajax/AjaxUserDetailsService.java +++ b/SpringBootSecurityJwt/src/main/java/com/tistory/heowc/auth/ajax/AjaxUserDetailsService.java @@ -8,9 +8,9 @@ import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UsernameNotFoundException; -import org.springframework.stereotype.Component; +import org.springframework.stereotype.Service; -@Component +@Service public class AjaxUserDetailsService implements UserDetailsService { @Autowired diff --git a/SpringBootSecurityJwt/src/main/java/com/tistory/heowc/auth/ajax/filter/AjaxAuthenticationFilter.java b/SpringBootSecurityJwt/src/main/java/com/tistory/heowc/auth/ajax/filter/AjaxAuthenticationFilter.java index 2de71040..9d35466f 100644 --- a/SpringBootSecurityJwt/src/main/java/com/tistory/heowc/auth/ajax/filter/AjaxAuthenticationFilter.java +++ b/SpringBootSecurityJwt/src/main/java/com/tistory/heowc/auth/ajax/filter/AjaxAuthenticationFilter.java @@ -2,14 +2,16 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.tistory.heowc.domain.Member; + +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; + import org.springframework.http.MediaType; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.Authentication; import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter; import org.springframework.security.web.util.matcher.RequestMatcher; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.nio.file.AccessDeniedException; diff --git a/SpringBootSecurityJwt/src/main/java/com/tistory/heowc/auth/jwt/JwtUserDetailsService.java b/SpringBootSecurityJwt/src/main/java/com/tistory/heowc/auth/jwt/JwtUserDetailsService.java index 160d913c..391f466b 100644 --- a/SpringBootSecurityJwt/src/main/java/com/tistory/heowc/auth/jwt/JwtUserDetailsService.java +++ b/SpringBootSecurityJwt/src/main/java/com/tistory/heowc/auth/jwt/JwtUserDetailsService.java @@ -7,9 +7,9 @@ import org.springframework.security.core.authority.AuthorityUtils; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; -import org.springframework.stereotype.Component; +import org.springframework.stereotype.Service; -@Component +@Service public class JwtUserDetailsService implements UserDetailsService { @Override diff --git a/SpringBootSecurityJwt/src/main/java/com/tistory/heowc/auth/jwt/filter/JwtAuthenticationFilter.java b/SpringBootSecurityJwt/src/main/java/com/tistory/heowc/auth/jwt/filter/JwtAuthenticationFilter.java index 7042ad50..4620ccfe 100644 --- a/SpringBootSecurityJwt/src/main/java/com/tistory/heowc/auth/jwt/filter/JwtAuthenticationFilter.java +++ b/SpringBootSecurityJwt/src/main/java/com/tistory/heowc/auth/jwt/filter/JwtAuthenticationFilter.java @@ -11,10 +11,10 @@ import org.springframework.security.web.util.matcher.RequestMatcher; import org.springframework.util.StringUtils; -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; public class JwtAuthenticationFilter extends AbstractAuthenticationProcessingFilter { diff --git a/SpringBootSecurityJwt/src/main/java/com/tistory/heowc/auth/jwt/matcher/SkipPathRequestMatcher.java b/SpringBootSecurityJwt/src/main/java/com/tistory/heowc/auth/jwt/matcher/SkipPathRequestMatcher.java index 7710bd2e..04f701c9 100644 --- a/SpringBootSecurityJwt/src/main/java/com/tistory/heowc/auth/jwt/matcher/SkipPathRequestMatcher.java +++ b/SpringBootSecurityJwt/src/main/java/com/tistory/heowc/auth/jwt/matcher/SkipPathRequestMatcher.java @@ -4,7 +4,7 @@ import org.springframework.security.web.util.matcher.OrRequestMatcher; import org.springframework.security.web.util.matcher.RequestMatcher; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; import java.util.List; import java.util.stream.Collectors; diff --git a/SpringBootSecurityJwt/src/main/java/com/tistory/heowc/config/SecurityConfig.java b/SpringBootSecurityJwt/src/main/java/com/tistory/heowc/config/SecurityConfig.java index 2bb4b18b..2e31af40 100644 --- a/SpringBootSecurityJwt/src/main/java/com/tistory/heowc/config/SecurityConfig.java +++ b/SpringBootSecurityJwt/src/main/java/com/tistory/heowc/config/SecurityConfig.java @@ -1,33 +1,34 @@ package com.tistory.heowc.config; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.tistory.heowc.auth.BaseSecurityHandler; -import com.tistory.heowc.auth.ajax.AjaxAuthenticationProvider; -import com.tistory.heowc.auth.ajax.filter.AjaxAuthenticationFilter; -import com.tistory.heowc.auth.jwt.JwtAuthenticationProvider; -import com.tistory.heowc.auth.jwt.filter.JwtAuthenticationFilter; -import com.tistory.heowc.auth.jwt.matcher.SkipPathRequestMatcher; +import java.util.Arrays; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.HttpMethod; -import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; -import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; +import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.config.annotation.web.builders.WebSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; -import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.config.annotation.web.configuration.WebSecurityCustomizer; import org.springframework.security.config.http.SessionCreationPolicy; -import org.springframework.security.web.access.intercept.FilterSecurityInterceptor; +import org.springframework.security.web.SecurityFilterChain; +import org.springframework.security.web.access.intercept.AuthorizationFilter; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; +import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken; import org.springframework.security.web.util.matcher.AntPathRequestMatcher; -import java.util.Arrays; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.tistory.heowc.auth.BaseSecurityHandler; +import com.tistory.heowc.auth.ajax.AjaxAuthenticationProvider; +import com.tistory.heowc.auth.ajax.filter.AjaxAuthenticationFilter; +import com.tistory.heowc.auth.jwt.JwtAuthenticationProvider; +import com.tistory.heowc.auth.jwt.filter.JwtAuthenticationFilter; +import com.tistory.heowc.auth.jwt.matcher.SkipPathRequestMatcher; @Configuration @EnableWebSecurity -@EnableGlobalMethodSecurity(prePostEnabled = true) -public class SecurityConfig extends WebSecurityConfigurerAdapter { +@EnableMethodSecurity +public class SecurityConfig { @Autowired private JwtAuthenticationProvider jwtProvider; @@ -46,30 +47,27 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter { private static final String ERROR_ENTRY_POINT = "/error"; private static final String ROOT_ENTRY_POINT = "/**"; - @Override - public void configure(WebSecurity web) { - web.ignoring().antMatchers("/resources/**"); - } - - @Override - protected void configure(AuthenticationManagerBuilder auth) { - auth.authenticationProvider(ajaxProvider) - .authenticationProvider(jwtProvider); + @Bean + WebSecurityCustomizer webSecurityCustomizer() { + return web -> web.ignoring().requestMatchers("/resources/**"); } - @Override - protected void configure(HttpSecurity http) throws Exception { + @Bean + SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http .addFilterBefore(ajaxAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class) - .addFilterBefore(jwtAuthenticationFilter(), FilterSecurityInterceptor.class) + .addFilterBefore(jwtAuthenticationFilter(), AuthorizationFilter.class) .csrf().disable() .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS) .and() - .authorizeRequests() - .antMatchers(ROOT_ENTRY_POINT).authenticated() - .antMatchers(TOKEN_ENTRY_POINT).permitAll() - .antMatchers(LOGIN_ENTRY_POINT).permitAll() - .antMatchers(ERROR_ENTRY_POINT).permitAll(); + .authenticationProvider(ajaxProvider) + .authenticationProvider(jwtProvider) + .authorizeHttpRequests() + .requestMatchers(ROOT_ENTRY_POINT).authenticated() + .requestMatchers(TOKEN_ENTRY_POINT).permitAll() + .requestMatchers(LOGIN_ENTRY_POINT).permitAll() + .requestMatchers(ERROR_ENTRY_POINT).permitAll(); + return http.build(); } @Bean @@ -80,22 +78,29 @@ public AntPathRequestMatcher antPathRequestMatcher() { @Bean public AjaxAuthenticationFilter ajaxAuthenticationFilter() throws Exception { AjaxAuthenticationFilter filter = new AjaxAuthenticationFilter(antPathRequestMatcher(), objectMapper); - filter.setAuthenticationManager(authenticationManager()); filter.setAuthenticationSuccessHandler(securityHandler); filter.setAuthenticationFailureHandler(securityHandler); + filter.setAuthenticationManager(authentication -> { + return new PreAuthenticatedAuthenticationToken(authentication.getPrincipal(), + authentication.getCredentials()); + }); return filter; } @Bean public SkipPathRequestMatcher skipPathRequestMatcher() { - return new SkipPathRequestMatcher(Arrays.asList(LOGIN_ENTRY_POINT, TOKEN_ENTRY_POINT, ERROR_ENTRY_POINT)); + return new SkipPathRequestMatcher( + Arrays.asList(LOGIN_ENTRY_POINT, TOKEN_ENTRY_POINT, ERROR_ENTRY_POINT)); } @Bean public JwtAuthenticationFilter jwtAuthenticationFilter() throws Exception { JwtAuthenticationFilter filter = new JwtAuthenticationFilter(skipPathRequestMatcher()); - filter.setAuthenticationManager(authenticationManager()); filter.setAuthenticationFailureHandler(securityHandler); + filter.setAuthenticationManager(authentication -> { + return new PreAuthenticatedAuthenticationToken(authentication.getPrincipal(), + authentication.getCredentials()); + }); return filter; } } \ No newline at end of file diff --git a/SpringBootSecurityJwt/src/main/java/com/tistory/heowc/domain/Member.java b/SpringBootSecurityJwt/src/main/java/com/tistory/heowc/domain/Member.java index 115129e1..70a570f2 100644 --- a/SpringBootSecurityJwt/src/main/java/com/tistory/heowc/domain/Member.java +++ b/SpringBootSecurityJwt/src/main/java/com/tistory/heowc/domain/Member.java @@ -1,7 +1,7 @@ package com.tistory.heowc.domain; -import javax.persistence.Entity; -import javax.persistence.Id; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; @Entity public class Member { diff --git a/SpringBootSpringDocOpenApi/build.gradle b/SpringBootSpringDocOpenApi/build.gradle index 477b97ea..5938551f 100644 --- a/SpringBootSpringDocOpenApi/build.gradle +++ b/SpringBootSpringDocOpenApi/build.gradle @@ -1,6 +1,5 @@ group = 'com.example' version = '0.0.1-SNAPSHOT' -sourceCompatibility = '1.8' repositories { mavenCentral() @@ -10,7 +9,7 @@ dependencies { implementation 'org.springframework.boot:spring-boot-starter-data-jpa' implementation 'org.springframework.boot:spring-boot-starter-web' - implementation 'org.springdoc:springdoc-openapi-ui:1.5.8' + implementation 'org.springdoc:springdoc-openapi-ui:1.8.0' runtimeOnly 'com.h2database:h2' } diff --git a/SpringBootSpringDocOpenApi/src/main/java/com/example/domain/Member.java b/SpringBootSpringDocOpenApi/src/main/java/com/example/domain/Member.java index 02b38c88..3f653820 100644 --- a/SpringBootSpringDocOpenApi/src/main/java/com/example/domain/Member.java +++ b/SpringBootSpringDocOpenApi/src/main/java/com/example/domain/Member.java @@ -1,7 +1,7 @@ package com.example.domain; -import javax.persistence.Entity; -import javax.persistence.Id; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; @Entity public class Member { diff --git a/SpringBootSse/README.md b/SpringBootSse/README.md new file mode 100644 index 00000000..257b43d1 --- /dev/null +++ b/SpringBootSse/README.md @@ -0,0 +1,21 @@ +```text +2023-10-23T00:33:17.482+09:00 INFO 17486 --- [ main] reactor.Flux.MonoFlatMapMany.1 : onSubscribe(MonoFlatMapMany.FlatMapManyMain) +2023-10-23T00:33:17.484+09:00 INFO 17486 --- [ main] reactor.Flux.MonoFlatMapMany.1 : request(unbounded) +2023-10-23T00:33:18.059+09:00 INFO 17486 --- [o-auto-1-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring DispatcherServlet 'dispatcherServlet' +2023-10-23T00:33:18.059+09:00 INFO 17486 --- [o-auto-1-exec-1] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet' +2023-10-23T00:33:18.061+09:00 INFO 17486 --- [o-auto-1-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 1 ms +2023-10-23T00:33:18.096+09:00 WARN 17486 --- [o-auto-1-exec-1] ocalVariableTableParameterNameDiscoverer : Using deprecated '-debug' fallback for parameter name resolution. Compile the affected code with '-parameters' instead or avoid its introspection: com.heowc.api.MemberApi +2023-10-23T00:33:18.102+09:00 INFO 17486 --- [o-auto-1-exec-1] com.heowc.api.MemberApi : stream all +2023-10-23T00:33:18.272+09:00 INFO 17486 --- [pool-4-thread-1] com.heowc.api.MemberApi : send sse-data. data=Member{id=1, createdAt=2023-10-23T00:33:16.541073} +2023-10-23T00:33:18.345+09:00 INFO 17486 --- [ctor-http-nio-2] reactor.Flux.MonoFlatMapMany.1 : onNext(ServerSentEvent [id = '1', event='null', retry=null, comment='null', data={"id":1,"createdAt":"2023-10-23T00:33:16.541073"}]) +2023-10-23T00:33:18.441+09:00 INFO 17486 --- [pool-4-thread-1] com.heowc.api.MemberApi : send sse-data. data=Member{id=2, createdAt=2023-10-23T00:33:16.541073} +2023-10-23T00:33:18.443+09:00 INFO 17486 --- [ctor-http-nio-2] reactor.Flux.MonoFlatMapMany.1 : onNext(ServerSentEvent [id = '2', event='null', retry=null, comment='null', data={"id":2,"createdAt":"2023-10-23T00:33:16.541073"}]) +2023-10-23T00:33:18.544+09:00 INFO 17486 --- [pool-4-thread-1] com.heowc.api.MemberApi : send sse-data. data=Member{id=3, createdAt=2023-10-23T00:33:16.541073} +2023-10-23T00:33:18.546+09:00 INFO 17486 --- [ctor-http-nio-2] reactor.Flux.MonoFlatMapMany.1 : onNext(ServerSentEvent [id = '3', event='null', retry=null, comment='null', data={"id":3,"createdAt":"2023-10-23T00:33:16.541073"}]) +2023-10-23T00:33:18.650+09:00 INFO 17486 --- [pool-4-thread-1] com.heowc.api.MemberApi : send sse-data. data=Member{id=4, createdAt=2023-10-23T00:33:16.541073} +2023-10-23T00:33:18.654+09:00 INFO 17486 --- [ctor-http-nio-2] reactor.Flux.MonoFlatMapMany.1 : onNext(ServerSentEvent [id = '4', event='null', retry=null, comment='null', data={"id":4,"createdAt":"2023-10-23T00:33:16.541073"}]) +2023-10-23T00:33:18.753+09:00 INFO 17486 --- [pool-4-thread-1] com.heowc.api.MemberApi : send sse-data. data=Member{id=5, createdAt=2023-10-23T00:33:16.541073} +2023-10-23T00:33:18.755+09:00 INFO 17486 --- [ctor-http-nio-2] reactor.Flux.MonoFlatMapMany.1 : onNext(ServerSentEvent [id = '5', event='null', retry=null, comment='null', data={"id":5,"createdAt":"2023-10-23T00:33:16.541073"}]) +2023-10-23T00:33:18.870+09:00 INFO 17486 --- [ctor-http-nio-2] reactor.Flux.MonoFlatMapMany.1 : onComplete() + +``` \ No newline at end of file diff --git a/SpringBootSse/build.gradle b/SpringBootSse/build.gradle new file mode 100644 index 00000000..4bc55304 --- /dev/null +++ b/SpringBootSse/build.gradle @@ -0,0 +1,17 @@ +group = 'com.example' +version = '0.0.1-SNAPSHOT' + +repositories { + mavenCentral() +} + +dependencies { + + implementation 'org.springframework.boot:spring-boot-starter-data-jpa' + implementation 'org.springframework.boot:spring-boot-starter-web' + + runtimeOnly 'com.h2database:h2' + + testImplementation 'org.springframework.boot:spring-boot-starter-webflux' + testImplementation 'io.projectreactor:reactor-test' +} diff --git a/SpringBootSse/src/main/java/com/heowc/SpringBootSseApplication.java b/SpringBootSse/src/main/java/com/heowc/SpringBootSseApplication.java new file mode 100644 index 00000000..b422c46e --- /dev/null +++ b/SpringBootSse/src/main/java/com/heowc/SpringBootSseApplication.java @@ -0,0 +1,37 @@ +package com.heowc; + +import com.heowc.domain.Member; +import com.heowc.domain.MemberRepository; + +import org.springframework.boot.ApplicationRunner; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.Bean; + +import java.time.LocalDateTime; +import java.util.List; + +@SpringBootApplication +public class SpringBootSseApplication { + + public static void main(String[] args) { + SpringApplication.run(SpringBootSseApplication.class, args); + } + + @Bean + ApplicationRunner runner(MemberRepository repository) { + return args -> { + final LocalDateTime now = LocalDateTime.now(); + repository.saveAll(List.of( + new Member(now), + new Member(now), + new Member(now), + new Member(now), + new Member(now), + new Member(now.minusDays(1)), + new Member(now.minusDays(1)), + new Member(now.minusDays(1)) + )); + }; + } +} diff --git a/SpringBootSse/src/main/java/com/heowc/api/MemberApi.java b/SpringBootSse/src/main/java/com/heowc/api/MemberApi.java new file mode 100644 index 00000000..a1653255 --- /dev/null +++ b/SpringBootSse/src/main/java/com/heowc/api/MemberApi.java @@ -0,0 +1,61 @@ +package com.heowc.api; + +import java.io.IOException; +import java.time.LocalDateTime; +import java.util.Objects; +import java.util.concurrent.Executors; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.http.MediaType; +import org.springframework.transaction.PlatformTransactionManager; +import org.springframework.transaction.support.TransactionTemplate; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyEmitter; +import org.springframework.web.servlet.mvc.method.annotation.SseEmitter; + +import com.heowc.domain.MemberRepository; + +@RestController +@RequestMapping("/members") +public class MemberApi { + + private static final Logger logger = LoggerFactory.getLogger(MemberApi.class); + + private final MemberRepository repository; + private final PlatformTransactionManager transactionManager; + + public MemberApi(MemberRepository repository, + PlatformTransactionManager transactionManager) { + this.repository = repository; + this.transactionManager = transactionManager; + } + + @GetMapping("/stream-all") + public ResponseBodyEmitter streamAll(LocalDateTime createdAt) { + logger.info("stream all"); + final ResponseBodyEmitter emitter = new ResponseBodyEmitter(60 * 1000L); + Executors.newSingleThreadExecutor().execute(() -> { + new TransactionTemplate(transactionManager).executeWithoutResult(status -> { + repository.streamByCreatedAtAfter(Objects.requireNonNullElse(createdAt, + LocalDateTime.now().minusDays(1))) + .forEach(it -> { + try { + logger.info("send sse-data. data={}", it); + emitter.send(SseEmitter.event() + .id(String.valueOf(it.getId())) + .data(it, MediaType.APPLICATION_JSON) + .build()); + Thread.sleep(100L); + } catch (Exception e) { + emitter.completeWithError(e); + } + }); + }); + emitter.complete(); + }); + return emitter; + } +} diff --git a/SpringBootSse/src/main/java/com/heowc/domain/Member.java b/SpringBootSse/src/main/java/com/heowc/domain/Member.java new file mode 100644 index 00000000..e8e494f0 --- /dev/null +++ b/SpringBootSse/src/main/java/com/heowc/domain/Member.java @@ -0,0 +1,40 @@ +package com.heowc.domain; + +import java.time.LocalDateTime; + +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; + +@Entity +public class Member { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private long id; + + private LocalDateTime createdAt; + + protected Member() {} + + public Member(LocalDateTime createdAt) { + this.createdAt = createdAt; + } + + public long getId() { + return id; + } + + public LocalDateTime getCreatedAt() { + return createdAt; + } + + @Override + public String toString() { + return "Member{" + + "id=" + id + + ", createdAt=" + createdAt + + '}'; + } +} diff --git a/SpringBootSse/src/main/java/com/heowc/domain/MemberRepository.java b/SpringBootSse/src/main/java/com/heowc/domain/MemberRepository.java new file mode 100644 index 00000000..045a79cf --- /dev/null +++ b/SpringBootSse/src/main/java/com/heowc/domain/MemberRepository.java @@ -0,0 +1,13 @@ +package com.heowc.domain; + +import java.time.LocalDateTime; +import java.util.stream.Stream; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.transaction.annotation.Transactional; + +@Transactional(readOnly = true) +public interface MemberRepository extends JpaRepository { + + Stream streamByCreatedAtAfter(LocalDateTime createdAt); +} diff --git a/SpringBootSse/src/main/resources/application.properties b/SpringBootSse/src/main/resources/application.properties new file mode 100644 index 00000000..1575af4e --- /dev/null +++ b/SpringBootSse/src/main/resources/application.properties @@ -0,0 +1,11 @@ +spring.datasource.driver-class-name=org.h2.Driver +spring.datasource.url=jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE + +# jpa setting +spring.jpa.hibernate.ddl-auto=create +spring.jpa.generate-ddl=false +spring.jpa.properties.hibernate.format_sql=true + +spring.mvc.format.date-time=iso + +logging.level.org.hibernate.SQL=DEBUG diff --git a/SpringBootSse/src/test/java/com/heowc/SpringBootSseTests.java b/SpringBootSse/src/test/java/com/heowc/SpringBootSseTests.java new file mode 100644 index 00000000..8497af04 --- /dev/null +++ b/SpringBootSse/src/test/java/com/heowc/SpringBootSseTests.java @@ -0,0 +1,35 @@ +package com.heowc; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; +import org.springframework.boot.test.web.server.LocalServerPort; +import org.springframework.core.ParameterizedTypeReference; +import org.springframework.http.codec.ServerSentEvent; +import org.springframework.web.reactive.function.client.WebClient; + +import reactor.core.publisher.Flux; +import reactor.test.StepVerifier; + +@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) +public class SpringBootSseTests { + + @LocalServerPort + private long port; + + @Test + void test() { + final ParameterizedTypeReference> type = new ParameterizedTypeReference<>() {}; + final WebClient client = WebClient.create(String.format("http://localhost:%d", port)); + + final Flux> exchanged = client.get() + .uri("/members/stream-all") + .exchangeToFlux(res -> res.bodyToFlux(type)) + .log(); + + StepVerifier.create(exchanged) + .expectNextCount(5) + .expectComplete() + .verify(); + } +} diff --git a/SpringBootStatemachine/build.gradle b/SpringBootStatemachine/build.gradle new file mode 100644 index 00000000..160791ce --- /dev/null +++ b/SpringBootStatemachine/build.gradle @@ -0,0 +1,18 @@ +group = 'com.example' +version = '0.0.1-SNAPSHOT' + +repositories { + mavenCentral() +} + +dependencies { + implementation 'org.springframework.statemachine:spring-statemachine-starter' + testImplementation 'org.springframework.statemachine:spring-statemachine-test' + +} + +dependencyManagement { + imports { + mavenBom 'org.springframework.statemachine:spring-statemachine-bom:4.0.1' + } +} \ No newline at end of file diff --git a/SpringBootStatemachine/src/main/java/com/example/OrderEvent.java b/SpringBootStatemachine/src/main/java/com/example/OrderEvent.java new file mode 100644 index 00000000..05491329 --- /dev/null +++ b/SpringBootStatemachine/src/main/java/com/example/OrderEvent.java @@ -0,0 +1,38 @@ +package com.example; + +public enum OrderEvent { + TAKE_OVER("TAKEOVER", "배송 업체 인계", Role.ADMIN), + OUT_OF_STOCK("OUT_OF_STOCK", "재고부족", Role.ADMIN), + // ... + + OFFER_RECEIPT("OFFER_RECEIPT", "주문 신청", Role.USER), + RECEIPT_CANCEL("RECEIPT_CANCEL", "주문 취소", Role.USER), + PURCHASE("PURCHASE", "구매", Role.USER), + PURCHASE_CANCEL("PURCHASE_CANCEL", "구매 취소", Role.USER), + REFUND("REFUND", "환불", Role.USER), + EXCHANGE("EXCHANGE", "교환", Role.USER), + RETURN("RETURN", "반품", Role.USER), + CONFIRM("CONFIRM", "확정", Role.USER); + + private final String code; + private final String description; + private final Role role; + + OrderEvent(String code, String description, Role role) { + this.code = code; + this.description = description; + this.role = role; + } + + public String getCode() { + return code; + } + + public String getDescription() { + return description; + } + + public Role getRole() { + return role; + } +} diff --git a/SpringBootStatemachine/src/main/java/com/example/OrderState.java b/SpringBootStatemachine/src/main/java/com/example/OrderState.java new file mode 100644 index 00000000..bed305c0 --- /dev/null +++ b/SpringBootStatemachine/src/main/java/com/example/OrderState.java @@ -0,0 +1,26 @@ +package com.example; + +public enum OrderState { + RECEIPTING("RECEIPTING", "접수"), + ORDER_PENDING("PENDING", "주문 대기"), + DELIVERY_PENDING("DELIVERY_PENDING", "배송 대기"), + DELIVERY_PROCEEDING("DELIVERY_PROCEEDING", "배송 중"), + CANCEL("CANCEL", "취소"), + COMPLETED("COMPLETED", "완료"); + + private final String code; + private final String description; + + OrderState(String code, String description) { + this.code = code; + this.description = description; + } + + public String getCode() { + return code; + } + + public String getDescription() { + return description; + } +} diff --git a/SpringBootStatemachine/src/main/java/com/example/Role.java b/SpringBootStatemachine/src/main/java/com/example/Role.java new file mode 100644 index 00000000..922d30ec --- /dev/null +++ b/SpringBootStatemachine/src/main/java/com/example/Role.java @@ -0,0 +1,6 @@ +package com.example; + +public enum Role { + USER, + ADMIN +} diff --git a/SpringBootStatemachine/src/main/java/com/example/SpringBootStatemachineApplication.java b/SpringBootStatemachine/src/main/java/com/example/SpringBootStatemachineApplication.java new file mode 100644 index 00000000..d53ad54a --- /dev/null +++ b/SpringBootStatemachine/src/main/java/com/example/SpringBootStatemachineApplication.java @@ -0,0 +1,42 @@ +package com.example; + +import org.springframework.boot.ApplicationRunner; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.Bean; +import org.springframework.messaging.Message; +import org.springframework.messaging.MessageHeaders; +import org.springframework.messaging.support.GenericMessage; +import org.springframework.messaging.support.MessageBuilder; +import org.springframework.statemachine.StateMachine; +import reactor.core.publisher.Mono; + +import java.util.UUID; + +@SpringBootApplication +public class SpringBootStatemachineApplication { + + public static void main(String[] args) { + SpringApplication.run(SpringBootStatemachineApplication.class, args); + } + + @Bean + ApplicationRunner runner(StateMachine stateMachine) { + return args -> { + final String orderId = UUID.randomUUID().toString(); + stateMachine.sendEvent(Mono.just(buildMessage(OrderEvent.OFFER_RECEIPT, orderId))).blockLast(); + stateMachine.sendEvent(Mono.just(buildMessage(OrderEvent.PURCHASE, orderId))).blockLast(); + stateMachine.sendEvent(Mono.just(buildMessage(OrderEvent.TAKE_OVER, orderId))).blockLast(); + stateMachine.sendEvent(Mono.just(buildMessage(OrderEvent.CONFIRM, orderId))).blockLast(); + stateMachine.sendEvent(Mono.just(buildMessage(OrderEvent.CONFIRM, orderId))).blockLast(); // not triggered + + stateMachine.sendEvent(Mono.just(buildMessage(OrderEvent.OUT_OF_STOCK, orderId))).blockLast(); // not triggered + }; + } + + private static Message buildMessage(OrderEvent event, String orderId) { + return MessageBuilder.withPayload(event) + .setHeader("orderId", orderId) + .build(); + } +} diff --git a/SpringBootStatemachine/src/main/java/com/example/StatemachineConfig.java b/SpringBootStatemachine/src/main/java/com/example/StatemachineConfig.java new file mode 100644 index 00000000..22b53824 --- /dev/null +++ b/SpringBootStatemachine/src/main/java/com/example/StatemachineConfig.java @@ -0,0 +1,98 @@ +package com.example; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.statemachine.action.Action; +import org.springframework.statemachine.config.EnableStateMachine; +import org.springframework.statemachine.config.EnumStateMachineConfigurerAdapter; +import org.springframework.statemachine.config.builders.StateMachineConfigurationConfigurer; +import org.springframework.statemachine.config.builders.StateMachineStateConfigurer; +import org.springframework.statemachine.config.builders.StateMachineTransitionConfigurer; +import org.springframework.statemachine.guard.Guard; +import org.springframework.statemachine.listener.StateMachineListener; +import org.springframework.statemachine.listener.StateMachineListenerAdapter; +import org.springframework.statemachine.state.State; + +import java.util.EnumSet; + +@Configuration +@EnableStateMachine +public class StatemachineConfig extends EnumStateMachineConfigurerAdapter { + + private final Logger logger = LoggerFactory.getLogger(StatemachineConfig.class); + + @Override + public void configure(StateMachineConfigurationConfigurer config) throws Exception { + config.withConfiguration() + .autoStartup(true) + .listener(listener()); + } + + @Override + public void configure(StateMachineStateConfigurer states) + throws Exception { + states.withStates() + .initial(OrderState.RECEIPTING) + .end(OrderState.COMPLETED) + .end(OrderState.CANCEL) + .states(EnumSet.allOf(OrderState.class)); + } + + @Override + public void configure(StateMachineTransitionConfigurer transitions) + throws Exception { + transitions + .withExternal() + // 접수 -> (주문 신청) -> 주문 대기 + .guard(offerReceiptGuard()) + .source(OrderState.RECEIPTING).target(OrderState.ORDER_PENDING) + .event(OrderEvent.OFFER_RECEIPT) + .action(offerReceiptAction()) + .and() + .withExternal() + // 주문 대기 -> (구매) -> 배송 대기 + .source(OrderState.ORDER_PENDING).target(OrderState.DELIVERY_PENDING) + .event(OrderEvent.PURCHASE) + .and() + .withExternal() + // 배송 대기 -> (인계) -> 배송 중 + .source(OrderState.DELIVERY_PENDING).target(OrderState.DELIVERY_PROCEEDING) + .event(OrderEvent.TAKE_OVER) + .and() + .withExternal() + // 배송 중 -> (확정) -> 완료 + .source(OrderState.DELIVERY_PROCEEDING).target(OrderState.COMPLETED) + .event(OrderEvent.CONFIRM); + } + + @Bean + Action offerReceiptAction() { + return context -> logger.info("offer receipt action. {}", context); + } + + @Bean + Guard offerReceiptGuard() { + return context -> true; + } + + + @Bean + StateMachineListener listener() { + + return new StateMachineListenerAdapter() { + + private final Logger logger = LoggerFactory.getLogger(StateMachineListener.class); + + @Override + public void stateChanged(State from, State to) { + if (from == null) { + logger.info("Starting state to [{}]", to.getId()); + } else { + logger.info("Changing state from [{}] to [{}]", to.getId(), from.getId()); + } + } + }; + } +} diff --git a/SpringBootStatemachine/src/main/resources/application.properties b/SpringBootStatemachine/src/main/resources/application.properties new file mode 100644 index 00000000..e69de29b diff --git a/SpringBootSwagger/src/test/java/com/example/SpringBootSwaggerApplicationTests.java b/SpringBootStatemachine/src/test/java/com/example/SpringBootStatemachineApplicationTests.java similarity index 57% rename from SpringBootSwagger/src/test/java/com/example/SpringBootSwaggerApplicationTests.java rename to SpringBootStatemachine/src/test/java/com/example/SpringBootStatemachineApplicationTests.java index 69f0dd86..e78df194 100644 --- a/SpringBootSwagger/src/test/java/com/example/SpringBootSwaggerApplicationTests.java +++ b/SpringBootStatemachine/src/test/java/com/example/SpringBootStatemachineApplicationTests.java @@ -4,10 +4,10 @@ import org.springframework.boot.test.context.SpringBootTest; @SpringBootTest -class SpringBootSwaggerApplicationTests { +public class SpringBootStatemachineApplicationTests { - @Test - void contextLoads() { - } + @Test + public void contextLoads() { + } } diff --git a/SpringBootSwagger/build.gradle b/SpringBootSwagger/build.gradle deleted file mode 100644 index 8d10dae9..00000000 --- a/SpringBootSwagger/build.gradle +++ /dev/null @@ -1,16 +0,0 @@ -group = 'com.example' -version = '0.0.1-SNAPSHOT' -sourceCompatibility = '1.8' - -repositories { - mavenCentral() -} - -dependencies { - implementation 'org.springframework.boot:spring-boot-starter-data-jpa' - implementation 'org.springframework.boot:spring-boot-starter-web' - - implementation 'io.springfox:springfox-boot-starter:3.0.0' - - runtimeOnly 'com.h2database:h2' -} diff --git a/SpringBootSwagger/src/main/java/com/example/SpringBootSwaggerApplication.java b/SpringBootSwagger/src/main/java/com/example/SpringBootSwaggerApplication.java deleted file mode 100644 index 20c58f08..00000000 --- a/SpringBootSwagger/src/main/java/com/example/SpringBootSwaggerApplication.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.example; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; - -@SpringBootApplication -public class SpringBootSwaggerApplication { - - public static void main(String[] args) { - SpringApplication.run(SpringBootSwaggerApplication.class, args); - } -} diff --git a/SpringBootSwagger/src/main/java/com/example/domain/Member.java b/SpringBootSwagger/src/main/java/com/example/domain/Member.java deleted file mode 100644 index 02b38c88..00000000 --- a/SpringBootSwagger/src/main/java/com/example/domain/Member.java +++ /dev/null @@ -1,58 +0,0 @@ -package com.example.domain; - -import javax.persistence.Entity; -import javax.persistence.Id; - -@Entity -public class Member { - - @Id - private String id; - - private String pw; - - private String name; - - private String tel; - - protected Member() { } - - public Member(String id, String pw, String name, String tel) { - this.id = id; - this.pw = pw; - this.name = name; - this.tel = tel; - } - - public String getId() { - return id; - } - - public void setId(String id) { - this.id = id; - } - - public String getPw() { - return pw; - } - - public void setPw(String pw) { - this.pw = pw; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public String getTel() { - return tel; - } - - public void setTel(String tel) { - this.tel = tel; - } -} diff --git a/SpringBootSwagger/src/main/java/com/example/domain/MemberRepository.java b/SpringBootSwagger/src/main/java/com/example/domain/MemberRepository.java deleted file mode 100644 index e62593d7..00000000 --- a/SpringBootSwagger/src/main/java/com/example/domain/MemberRepository.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.example.domain; - -import org.springframework.data.jpa.repository.JpaRepository; - -public interface MemberRepository extends JpaRepository { - -} diff --git a/SpringBootSwagger/src/main/java/com/example/web/MemberController.java b/SpringBootSwagger/src/main/java/com/example/web/MemberController.java deleted file mode 100644 index 668d8b6c..00000000 --- a/SpringBootSwagger/src/main/java/com/example/web/MemberController.java +++ /dev/null @@ -1,59 +0,0 @@ -package com.example.web; - -import com.example.domain.Member; -import com.example.domain.MemberRepository; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiResponse; -import io.swagger.annotations.ApiResponses; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.*; - -@Api(value = "Member for API") -@RestController -@RequestMapping("/member") -public class MemberController { - - @Autowired - private MemberRepository repository; - - @ApiOperation( - value = "getId", - notes = "아이디 조회", - httpMethod = "GET", -// produces = "application/json", - consumes = "application/json", - protocols = "http", - responseHeaders = { - // Headers ... - }) - @ApiResponses({ - @ApiResponse(code = 200, message = "OK"), - @ApiResponse(code = 404, message = "No param") - // Other Http Status Code ... - }) - @GetMapping("/{id}") - public Member getId(@PathVariable("id") String id) { - return repository.findById(id).orElse(null); - } - - @PostMapping - public Member createMember(@RequestBody Member member) { - return repository.save(member); - } - - @PutMapping - public Member updateMember(@RequestBody Member member) { - return repository.save(member); - } - - @DeleteMapping("/{id}") - public String deleteById(@PathVariable("id") String id) { - try { - repository.deleteById(id); - return "success"; - } catch (Exception e) { - return "fail"; - } - } -} diff --git a/SpringBootSwagger/src/main/resources/application.properties b/SpringBootSwagger/src/main/resources/application.properties deleted file mode 100644 index ea415171..00000000 --- a/SpringBootSwagger/src/main/resources/application.properties +++ /dev/null @@ -1,2 +0,0 @@ -spring.datasource.driver-class-name=org.h2.Driver -spring.datasource.url=jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE diff --git a/SpringBootTest/build.gradle b/SpringBootTest/build.gradle index 7187b5ee..138b8f1d 100644 --- a/SpringBootTest/build.gradle +++ b/SpringBootTest/build.gradle @@ -1,6 +1,5 @@ group = 'com.example' version = '0.0.1-SNAPSHOT' -sourceCompatibility = '1.8' repositories { mavenCentral() diff --git a/SpringBootTest/src/test/java/com/example/MockMvcTest.java b/SpringBootTest/src/test/java/com/example/MockMvcTest.java index b081da9c..a013fd29 100644 --- a/SpringBootTest/src/test/java/com/example/MockMvcTest.java +++ b/SpringBootTest/src/test/java/com/example/MockMvcTest.java @@ -7,8 +7,8 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; -import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.http.MediaType; +import org.springframework.test.context.bean.override.mockito.MockitoBean; import org.springframework.test.web.servlet.MockMvc; import static org.mockito.BDDMockito.given; @@ -22,7 +22,7 @@ public class MockMvcTest { @Autowired private MockMvc mvc; - @MockBean + @MockitoBean private BasicService service; @Autowired @@ -30,8 +30,8 @@ public class MockMvcTest { @Test public void test() throws Exception { - TestMessage message = new TestMessage("wonchul", 0); - String result = mapper.writeValueAsString(message); + final TestMessage message = new TestMessage("wonchul", 0); + final String result = mapper.writeValueAsString(message); given(service.jsonTest()) .willReturn(message); diff --git a/SpringBootTest/src/test/java/com/example/MockTest.java b/SpringBootTest/src/test/java/com/example/MockitoBeanTest.java similarity index 83% rename from SpringBootTest/src/test/java/com/example/MockTest.java rename to SpringBootTest/src/test/java/com/example/MockitoBeanTest.java index 9fecddf1..d1e0c9af 100644 --- a/SpringBootTest/src/test/java/com/example/MockTest.java +++ b/SpringBootTest/src/test/java/com/example/MockitoBeanTest.java @@ -5,19 +5,19 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.test.context.bean.override.mockito.MockitoBean; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.BDDMockito.given; @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) -public class MockTest { +public class MockitoBeanTest { @Autowired TestRestTemplate restTemplate; - @MockBean + @MockitoBean BasicService service; @Test @@ -25,7 +25,7 @@ public void test() { given(service.test(0)) .willReturn("Spring Boot Service Test"); - String result = restTemplate.getForObject("/test?flag=0", String.class); + final String result = restTemplate.getForObject("/test?flag=0", String.class); assertThat(result) .isEqualTo("Spring Boot Service Test"); } diff --git a/SpringBootTest/src/test/java/com/example/TestBeanTest.java b/SpringBootTest/src/test/java/com/example/TestBeanTest.java new file mode 100644 index 00000000..39641cfd --- /dev/null +++ b/SpringBootTest/src/test/java/com/example/TestBeanTest.java @@ -0,0 +1,51 @@ +package com.example; + +import static org.assertj.core.api.Assertions.assertThat; + +import com.example.domain.TestMessage; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; +import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.test.context.bean.override.convention.TestBean; + +import com.example.service.BasicService; + +@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) +public class TestBeanTest { + + @Autowired + TestRestTemplate restTemplate; + + @TestBean + BasicService basicService; + + static BasicService basicService() { + return new BasicService() { + @Override + public String test(int flag) { + return "Spring Boot Service Test"; + } + + @Override + public TestMessage jsonTest() { + throw new UnsupportedOperationException("jsonTest not implemented"); + } + }; + } + + @Test + public void mvcTest() { + final String result = restTemplate.getForObject("/test?flag=0", String.class); + assertThat(result) + .isEqualTo("Spring Boot Service Test"); + } + + @Test + public void serviceTest() { + assertThat(basicService.test(0)) + .isEqualTo("Spring Boot Service Test"); + } +} diff --git a/SpringBootValidator/build.gradle b/SpringBootValidator/build.gradle index 46258887..bebfd4a6 100644 --- a/SpringBootValidator/build.gradle +++ b/SpringBootValidator/build.gradle @@ -1,13 +1,11 @@ group = 'com.example' version = '0.0.1-SNAPSHOT' -sourceCompatibility = '1.8' repositories { mavenCentral() } dependencies { - implementation 'org.springframework.boot:spring-boot-starter-data-jpa' implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'org.springframework.boot:spring-boot-starter-validation' diff --git a/SpringBootValidator/src/main/java/com/example/config/WebMvcConfig.java b/SpringBootValidator/src/main/java/com/example/config/WebMvcConfig.java new file mode 100644 index 00000000..7a62f704 --- /dev/null +++ b/SpringBootValidator/src/main/java/com/example/config/WebMvcConfig.java @@ -0,0 +1,25 @@ +package com.example.config; + +import org.hibernate.validator.messageinterpolation.AbstractMessageInterpolator; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.support.ResourceBundleMessageSource; +import org.springframework.stereotype.Component; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +import java.nio.charset.StandardCharsets; +import java.util.Locale; + +@Configuration +public class WebMvcConfig implements WebMvcConfigurer { + + // See AbstractApplicationContext#initMessageSource + @Component("messageSource") + static class ValidationMessageSource extends ResourceBundleMessageSource { + + ValidationMessageSource() { + setBasename(AbstractMessageInterpolator.USER_VALIDATION_MESSAGES); + setDefaultEncoding(StandardCharsets.UTF_8.displayName()); + setDefaultLocale(Locale.KOREAN); + } + } +} diff --git a/SpringBootValidator/src/main/java/com/example/domain/ErrorMessage.java b/SpringBootValidator/src/main/java/com/example/domain/ErrorMessage.java deleted file mode 100644 index 25f524b2..00000000 --- a/SpringBootValidator/src/main/java/com/example/domain/ErrorMessage.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.example.domain; - -public class ErrorMessage { - - private int code; - private String message; - - public ErrorMessage(int code, String message) { - this.code = code; - this.message = message; - } - - public int getCode() { - return code; - } - - public void setCode(int code) { - this.code = code; - } - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } -} - diff --git a/SpringBootValidator/src/main/java/com/example/domain/Member.java b/SpringBootValidator/src/main/java/com/example/domain/Member.java index b2c3931d..d376fe8c 100644 --- a/SpringBootValidator/src/main/java/com/example/domain/Member.java +++ b/SpringBootValidator/src/main/java/com/example/domain/Member.java @@ -1,27 +1,19 @@ package com.example.domain; -import com.example.validator.Phone; +import com.example.validation.Phone; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.validation.constraints.Min; -import javax.validation.constraints.NotNull; +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotNull; - -@Entity public class Member { - @Id - @GeneratedValue(strategy = GenerationType.AUTO) private long idx; - @NotNull(message = "name null") + @NotNull private String name; - @NotNull(message = "age null") - @Min(value = 14, message = "min 14") + @NotNull + @Min(14) private Integer age; @Phone diff --git a/SpringBootValidator/src/main/java/com/example/domain/MemberRepository.java b/SpringBootValidator/src/main/java/com/example/domain/MemberRepository.java deleted file mode 100644 index 2c8de5e5..00000000 --- a/SpringBootValidator/src/main/java/com/example/domain/MemberRepository.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.example.domain; - -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.stereotype.Repository; - -@Repository -public interface MemberRepository extends JpaRepository { - -} diff --git a/SpringBootValidator/src/main/java/com/example/errorhandler/ErrorMessage.java b/SpringBootValidator/src/main/java/com/example/errorhandler/ErrorMessage.java new file mode 100644 index 00000000..62b47a17 --- /dev/null +++ b/SpringBootValidator/src/main/java/com/example/errorhandler/ErrorMessage.java @@ -0,0 +1,25 @@ +package com.example.errorhandler; + +public class ErrorMessage { + + private final String field; + private final String message; + + public static ErrorMessage of(String field, String message) { + return new ErrorMessage(field, message); + } + + protected ErrorMessage(String field, String message) { + this.field = field; + this.message = message; + } + + public String getField() { + return field; + } + + public String getMessage() { + return message; + } +} + diff --git a/SpringBootValidator/src/main/java/com/example/errorhandler/GlobalExceptionHandler.java b/SpringBootValidator/src/main/java/com/example/errorhandler/GlobalExceptionHandler.java new file mode 100644 index 00000000..8b46c94e --- /dev/null +++ b/SpringBootValidator/src/main/java/com/example/errorhandler/GlobalExceptionHandler.java @@ -0,0 +1,73 @@ +package com.example.errorhandler; + +import jakarta.validation.ConstraintViolationException; + +import org.hibernate.validator.internal.engine.path.PathImpl; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.context.MessageSource; +import org.springframework.http.ResponseEntity; +import org.springframework.http.converter.HttpMessageNotReadableException; +import org.springframework.web.bind.MethodArgumentNotValidException; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.RestControllerAdvice; +import org.springframework.web.context.request.WebRequest; + +import jakarta.validation.ConstraintViolation; +import jakarta.validation.ConstraintViolationException; +import jakarta.validation.Path; +import java.util.Collections; +import java.util.List; +import java.util.Locale; +import java.util.stream.Collectors; + +@RestControllerAdvice +class GlobalExceptionHandler { + + private static final Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class); + + private final MessageSource messageSource; + + GlobalExceptionHandler(MessageSource messageSource) { + this.messageSource = messageSource; + } + + @ExceptionHandler(ConstraintViolationException.class) + ResponseEntity> constraintViolationException(ConstraintViolationException exception, + WebRequest request) { + logger.warn("path: {}, locale: {}, principal: {}", request.getContextPath(), request.getLocale(), + request.getUserPrincipal()); + + final List body = exception.getConstraintViolations().stream() + .map(cv -> ErrorMessage.of(property(cv).toString(), cv.getMessage())) + .collect(Collectors.toList()); + return ResponseEntity.badRequest().body(body); + } + + @ExceptionHandler(MethodArgumentNotValidException.class) + ResponseEntity> methodArgumentNotValidException(MethodArgumentNotValidException exception, + WebRequest request) { + logger.warn("path: {}, locale: {}, principal: {}", request.getContextPath(), request.getLocale(), + request.getUserPrincipal()); + + final List body = exception.getBindingResult().getAllErrors().stream() + .map(oe -> oe.unwrap(ConstraintViolation.class)) + .map(cv -> ErrorMessage.of(property(cv).toString(), cv.getMessage())) + .collect(Collectors.toList()); + return ResponseEntity.badRequest().body(body); + } + + private static Path.Node property(ConstraintViolation constraintViolation) { + return ((PathImpl) constraintViolation.getPropertyPath()).getLeafNode(); + } + + @ExceptionHandler(HttpMessageNotReadableException.class) + ResponseEntity> emptyBodyException(HttpMessageNotReadableException exception, + WebRequest request) { + logger.warn("path: {}, locale: {}, principal: {}", request.getContextPath(), request.getLocale(), + request.getUserPrincipal()); + + final String message = messageSource.getMessage("body.incorrect.message", new Object[]{ }, Locale.getDefault()); + return ResponseEntity.badRequest().body(Collections.singletonList(ErrorMessage.of("body", message))); + } +} diff --git a/SpringBootValidator/src/main/java/com/example/validator/Phone.java b/SpringBootValidator/src/main/java/com/example/validation/Phone.java similarity index 51% rename from SpringBootValidator/src/main/java/com/example/validator/Phone.java rename to SpringBootValidator/src/main/java/com/example/validation/Phone.java index 3a5ae00a..1a8418b2 100644 --- a/SpringBootValidator/src/main/java/com/example/validator/Phone.java +++ b/SpringBootValidator/src/main/java/com/example/validation/Phone.java @@ -1,17 +1,17 @@ -package com.example.validator; +package com.example.validation; -import javax.validation.Constraint; -import javax.validation.Payload; +import jakarta.validation.Constraint; +import jakarta.validation.Payload; import java.lang.annotation.*; @Documented @Constraint(validatedBy = PhoneValidator.class) -@Target({ElementType.METHOD, ElementType.FIELD}) +@Target({ElementType.FIELD, ElementType.PARAMETER}) @Retention(RetentionPolicy.RUNTIME) public @interface Phone { - String message() default "Invalid phone number"; + String message() default "{com.example.validation.Phone.message}"; Class[] groups() default {}; Class[] payload() default {}; -} \ No newline at end of file +} diff --git a/SpringBootValidator/src/main/java/com/example/validator/PhoneValidator.java b/SpringBootValidator/src/main/java/com/example/validation/PhoneValidator.java similarity index 77% rename from SpringBootValidator/src/main/java/com/example/validator/PhoneValidator.java rename to SpringBootValidator/src/main/java/com/example/validation/PhoneValidator.java index f28990cb..c58e0a72 100644 --- a/SpringBootValidator/src/main/java/com/example/validator/PhoneValidator.java +++ b/SpringBootValidator/src/main/java/com/example/validation/PhoneValidator.java @@ -1,7 +1,7 @@ -package com.example.validator; +package com.example.validation; -import javax.validation.ConstraintValidator; -import javax.validation.ConstraintValidatorContext; +import jakarta.validation.ConstraintValidator; +import jakarta.validation.ConstraintValidatorContext; import java.util.regex.Pattern; public class PhoneValidator implements ConstraintValidator { diff --git a/SpringBootValidator/src/main/java/com/example/web/MemberController.java b/SpringBootValidator/src/main/java/com/example/web/MemberController.java index 53b5e149..c59dee97 100644 --- a/SpringBootValidator/src/main/java/com/example/web/MemberController.java +++ b/SpringBootValidator/src/main/java/com/example/web/MemberController.java @@ -1,32 +1,30 @@ package com.example.web; -import com.example.domain.ErrorMessage; import com.example.domain.Member; -import org.springframework.http.HttpStatus; +import com.example.validation.Phone; import org.springframework.http.ResponseEntity; -import org.springframework.validation.BindingResult; +import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; -import javax.validation.Valid; +import jakarta.validation.Valid; +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotNull; + +@Validated @RestController @RequestMapping("member") public class MemberController { - private static final int ZERO = 0; - - @GetMapping - public String find() { - return "Error"; - } - @PostMapping - public ResponseEntity add(@Valid @RequestBody Member member, BindingResult bindingResult) { - if (bindingResult.hasErrors()) { - String errorMessage = bindingResult.getAllErrors().get(ZERO).getDefaultMessage(); - return ResponseEntity.badRequest().body(new ErrorMessage(HttpStatus.BAD_REQUEST.value(), errorMessage)); - } - + public ResponseEntity postAdd(@Valid @RequestBody Member member) { return ResponseEntity.ok(member); } + + @GetMapping + public ResponseEntity getAdd(@NotNull String name, + @NotNull @Min(14) Integer age, + @Phone String phone) { + return ResponseEntity.ok(new Member(name, age, phone)); + } } diff --git a/SpringBootValidator/src/main/resources/ValidationMessages.properties b/SpringBootValidator/src/main/resources/ValidationMessages.properties new file mode 100644 index 00000000..7bb7151c --- /dev/null +++ b/SpringBootValidator/src/main/resources/ValidationMessages.properties @@ -0,0 +1,2 @@ +com.example.validation.Phone.message=must be a well-formed phone number +body.incorrect.message=body is incorrect diff --git a/SpringBootValidator/src/main/resources/ValidationMessages_ko.properties b/SpringBootValidator/src/main/resources/ValidationMessages_ko.properties new file mode 100644 index 00000000..dede9d5f --- /dev/null +++ b/SpringBootValidator/src/main/resources/ValidationMessages_ko.properties @@ -0,0 +1,2 @@ +com.example.validation.Phone.message=올바른 형식의 전화번호여야 합니다 +body.incorrect.message=본문이 올바르지 않습니다 diff --git a/SpringBootValidator/src/test/java/com/example/web/MemberControllerGetTest.java b/SpringBootValidator/src/test/java/com/example/web/MemberControllerGetTest.java new file mode 100644 index 00000000..554d26f8 --- /dev/null +++ b/SpringBootValidator/src/test/java/com/example/web/MemberControllerGetTest.java @@ -0,0 +1,86 @@ +package com.example.web; + +import com.example.domain.Member; +import com.example.errorhandler.ErrorMessage; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.http.MediaType; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.ResultMatcher; + +import java.util.Collections; + +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +@WebMvcTest(MemberController.class) +class MemberControllerGetTest { + + @Autowired + private MockMvc mvc; + + @Autowired + private ObjectMapper objectMapper; + + @Test + void test_success() throws Exception { + final Member member = new Member("heowc", 14, "01012345678"); + + assertResponse(member, status().isOk(), toJsonString(member)); + } + + @Test + void test_InvalidByName() throws Exception { + final Member member = new Member(null, 14, "01012345678"); + final String errorMessageToJson = toJsonString( + Collections.singletonList(ErrorMessage.of("name", "널이어서는 안됩니다")) + ); + + assertResponse(member, status().isBadRequest(), errorMessageToJson); + } + + @Test + void test_InvalidByAge() throws Exception { + final Member member = new Member("heowc", 13, "01012345678"); + final String errorMessageToJson = toJsonString( + Collections.singletonList(ErrorMessage.of("age", "14 이상이어야 합니다")) + ); + + assertResponse(member, status().isBadRequest(), errorMessageToJson); + } + + @Test + void test_InvalidByPhone() throws Exception { + final Member member = new Member("heowc", 14, "010xxxxxxxx"); + final String errorMessageToJson = toJsonString( + Collections.singletonList(ErrorMessage.of("phone", "올바른 형식의 전화번호여야 합니다")) + ); + + assertResponse(member, status().isBadRequest(), errorMessageToJson); + } + + private String toJsonString(Object obj) { + try { + return objectMapper.writeValueAsString(obj); + } catch (JsonProcessingException e) { + return null; + } + } + + private void assertResponse(Member member, ResultMatcher matcher, String result) throws Exception { + mvc.perform(get("/member") + .queryParam("name", member.getName()) + .queryParam("age", member.getAge() == null ? null : String.valueOf(member.getAge())) + .queryParam("phone", member.getPhone()) + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON)) + .andDo(print()) + .andExpect(matcher) + .andExpect(content().json(result)); + } +} diff --git a/SpringBootValidator/src/test/java/com/example/web/MemberControllerTest.java b/SpringBootValidator/src/test/java/com/example/web/MemberControllerPostTest.java similarity index 60% rename from SpringBootValidator/src/test/java/com/example/web/MemberControllerTest.java rename to SpringBootValidator/src/test/java/com/example/web/MemberControllerPostTest.java index 98b7d9ae..f8e20450 100644 --- a/SpringBootValidator/src/test/java/com/example/web/MemberControllerTest.java +++ b/SpringBootValidator/src/test/java/com/example/web/MemberControllerPostTest.java @@ -1,24 +1,25 @@ package com.example.web; -import com.example.domain.ErrorMessage; import com.example.domain.Member; +import com.example.errorhandler.ErrorMessage; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; -import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.ResultMatcher; +import java.util.Collections; + import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @WebMvcTest(MemberController.class) -class MemberControllerTest { +class MemberControllerPostTest { @Autowired private MockMvc mvc; @@ -33,10 +34,32 @@ void test_success() throws Exception { assertResponse(memberToJson, status().isOk(), memberToJson); } + @Test + void test_empty() throws Exception { + final String memberToJson = ""; + final String errorMessageToJson = toJsonString( + Collections.singletonList(ErrorMessage.of("body", "본문이 올바르지 않습니다")) + ); + + assertResponse(memberToJson, status().isBadRequest(), errorMessageToJson); + } + + @Test + void test_incorrect() throws Exception { + final String memberToJson = "incorrect"; + final String errorMessageToJson = toJsonString( + Collections.singletonList(ErrorMessage.of("body", "본문이 올바르지 않습니다")) + ); + + assertResponse(memberToJson, status().isBadRequest(), errorMessageToJson); + } + @Test void test_InvalidByName() throws Exception { final String memberToJson = toJsonString(new Member(null, 14, "01012345678")); - final String errorMessageToJson = toJsonString(new ErrorMessage(HttpStatus.BAD_REQUEST.value(), "name null")); + final String errorMessageToJson = toJsonString( + Collections.singletonList(ErrorMessage.of("name", "널이어서는 안됩니다")) + ); assertResponse(memberToJson, status().isBadRequest(), errorMessageToJson); } @@ -44,7 +67,9 @@ void test_InvalidByName() throws Exception { @Test void test_InvalidByAge() throws Exception { final String memberToJson = toJsonString(new Member("heowc", 13, "01012345678")); - final String errorMessageToJson = toJsonString(new ErrorMessage(HttpStatus.BAD_REQUEST.value(), "min 14")); + final String errorMessageToJson = toJsonString( + Collections.singletonList(ErrorMessage.of("age", "14 이상이어야 합니다")) + ); assertResponse(memberToJson, status().isBadRequest(), errorMessageToJson); } @@ -52,13 +77,19 @@ void test_InvalidByAge() throws Exception { @Test void test_InvalidByPhone() throws Exception { final String memberToJson = toJsonString(new Member("heowc", 14, "010xxxxxxxx")); - final String errorMessageToJson = toJsonString(new ErrorMessage(HttpStatus.BAD_REQUEST.value(), "Invalid phone number")); + final String errorMessageToJson = toJsonString( + Collections.singletonList(ErrorMessage.of("phone", "올바른 형식의 전화번호여야 합니다")) + ); assertResponse(memberToJson, status().isBadRequest(), errorMessageToJson); } - private String toJsonString(Object obj) throws JsonProcessingException { - return objectMapper.writeValueAsString(obj); + private String toJsonString(Object obj) { + try { + return objectMapper.writeValueAsString(obj); + } catch (JsonProcessingException e) { + return null; + } } private void assertResponse(String memberToJson, ResultMatcher matcher, String result) throws Exception { @@ -70,4 +101,4 @@ private void assertResponse(String memberToJson, ResultMatcher matcher, String r .andExpect(matcher) .andExpect(content().json(result)); } -} \ No newline at end of file +} diff --git a/SpringBootValidator/src/test/resources/application.properties b/SpringBootValidator/src/test/resources/application.properties new file mode 100644 index 00000000..70378975 --- /dev/null +++ b/SpringBootValidator/src/test/resources/application.properties @@ -0,0 +1,2 @@ +server.servlet.encoding.force-response=true +spring.web.locale=ko diff --git a/SpringBootVertx/build.gradle b/SpringBootVertx/build.gradle index f023551f..559743a8 100644 --- a/SpringBootVertx/build.gradle +++ b/SpringBootVertx/build.gradle @@ -1,6 +1,5 @@ group = 'com.example' version = '0.0.1-SNAPSHOT' -sourceCompatibility = '1.8' repositories { mavenCentral() @@ -17,7 +16,7 @@ dependencies { implementation 'org.springframework.boot:spring-boot-starter-data-jpa' implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'com.fasterxml.jackson.core:jackson-databind' - implementation 'io.vertx:vertx-web:4.0.3' + implementation 'io.vertx:vertx-web:4.5.14' runtimeOnly 'com.h2database:h2' compileOnly 'org.projectlombok:lombok' diff --git a/SpringBootVertx/src/main/java/com/tistory/heowc/SpringBootVertxApplication.java b/SpringBootVertx/src/main/java/com/tistory/heowc/SpringBootVertxApplication.java index 029bc27a..f3e3cf15 100644 --- a/SpringBootVertx/src/main/java/com/tistory/heowc/SpringBootVertxApplication.java +++ b/SpringBootVertx/src/main/java/com/tistory/heowc/SpringBootVertxApplication.java @@ -6,7 +6,7 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; -import javax.annotation.PostConstruct; +import jakarta.annotation.PostConstruct; @SpringBootApplication public class SpringBootVertxApplication { diff --git a/SpringBootVertx/src/main/java/com/tistory/heowc/domain/Article.java b/SpringBootVertx/src/main/java/com/tistory/heowc/domain/Article.java index b171c5a1..d831b645 100644 --- a/SpringBootVertx/src/main/java/com/tistory/heowc/domain/Article.java +++ b/SpringBootVertx/src/main/java/com/tistory/heowc/domain/Article.java @@ -4,8 +4,8 @@ import lombok.Data; import lombok.NoArgsConstructor; -import javax.persistence.Entity; -import javax.persistence.Id; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; @Entity @Data diff --git a/SpringBootWar/build.gradle b/SpringBootWar/build.gradle index 70978670..8f6d6348 100644 --- a/SpringBootWar/build.gradle +++ b/SpringBootWar/build.gradle @@ -4,7 +4,6 @@ plugins { group = 'com.example' version = '0.0.1-SNAPSHOT' -sourceCompatibility = '1.8' bootWar { archiveFileName = 'spring-boot.war' diff --git a/SpringBootWebFlux/build.gradle b/SpringBootWebFlux/build.gradle index 0c4ec7bc..4d1fed43 100644 --- a/SpringBootWebFlux/build.gradle +++ b/SpringBootWebFlux/build.gradle @@ -1,6 +1,5 @@ group = 'com.example' version = '0.0.1-SNAPSHOT' -sourceCompatibility = '1.8' repositories { mavenCentral() diff --git a/SpringBootWebFlux/src/main/java/com/tistory/heowc/domain/Message.java b/SpringBootWebFlux/src/main/java/com/tistory/heowc/domain/Message.java index afba8c01..9fa1704b 100644 --- a/SpringBootWebFlux/src/main/java/com/tistory/heowc/domain/Message.java +++ b/SpringBootWebFlux/src/main/java/com/tistory/heowc/domain/Message.java @@ -1,9 +1,9 @@ package com.tistory.heowc.domain; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; @Entity public class Message { diff --git a/SpringBootWebFlux/src/test/java/com/tistory/heowc/web/MessageControllerTest.java b/SpringBootWebFlux/src/test/java/com/tistory/heowc/web/MessageControllerTest.java index e854354f..7792a7ee 100644 --- a/SpringBootWebFlux/src/test/java/com/tistory/heowc/web/MessageControllerTest.java +++ b/SpringBootWebFlux/src/test/java/com/tistory/heowc/web/MessageControllerTest.java @@ -5,7 +5,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.web.server.LocalServerPort; +import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import org.springframework.test.web.reactive.server.WebTestClient; diff --git a/SpringBootWebSocket/build.gradle b/SpringBootWebSocket/build.gradle index 4745aafe..162c7ab5 100644 --- a/SpringBootWebSocket/build.gradle +++ b/SpringBootWebSocket/build.gradle @@ -1,6 +1,5 @@ group = 'com.example' version = '0.0.1-SNAPSHOT' -sourceCompatibility = '1.8' repositories { mavenCentral() diff --git a/SpringBootWebSocket/src/main/resources/static/index.html b/SpringBootWebSocket/src/main/resources/static/index.html index c22d2b0d..b8df63e2 100644 --- a/SpringBootWebSocket/src/main/resources/static/index.html +++ b/SpringBootWebSocket/src/main/resources/static/index.html @@ -3,7 +3,7 @@ - + Hello WebSocket diff --git a/build.gradle b/build.gradle index 2801065f..0e24b8c1 100644 --- a/build.gradle +++ b/build.gradle @@ -1,15 +1,15 @@ plugins { id 'java' - id 'io.spring.dependency-management' version '1.0.11.RELEASE' - id 'org.springframework.boot' version '2.4.5' - id 'org.jetbrains.kotlin.jvm' version '1.5.0' apply false - id 'org.jetbrains.kotlin.plugin.spring' version '1.5.0' apply false - id 'org.jetbrains.kotlin.plugin.jpa' version '1.5.0' apply false + id 'io.spring.dependency-management' + id 'org.springframework.boot' + id 'org.jetbrains.kotlin.jvm' apply false + id 'org.jetbrains.kotlin.plugin.spring' apply false + id 'org.jetbrains.kotlin.plugin.jpa' apply false } group = 'com.example' version = '0.0.1' -sourceCompatibility = 1.8 +sourceCompatibility = JavaVersion.VERSION_17 repositories { mavenCentral() @@ -26,10 +26,7 @@ subprojects { dependencies { implementation 'org.springframework.boot:spring-boot-starter' - - testImplementation('org.springframework.boot:spring-boot-starter-test') { - exclude group: 'org.junit.vintage', module: 'junit-vintage-engine' - } + testImplementation('org.springframework.boot:spring-boot-starter-test') } test { @@ -54,14 +51,14 @@ configure(subprojects.findAll { file("${it.projectDir}/src/main/kotlin").exists( compileKotlin { kotlinOptions { freeCompilerArgs = ['-Xjsr305=strict'] - jvmTarget = '1.8' + jvmTarget = JavaVersion.VERSION_17 } } compileTestKotlin { kotlinOptions { freeCompilerArgs = ['-Xjsr305=strict'] - jvmTarget = '1.8' + jvmTarget = JavaVersion.VERSION_17 } } } diff --git a/gradle.properties b/gradle.properties index 91d570fa..d6d78138 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1 +1 @@ -org.gradle.jvmargs=-Xmx2g -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 \ No newline at end of file +org.gradle.jvmargs=-Xmx1g -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index f3d88b1c..e6441136 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 21e622da..a80b22ce 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,7 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.4.1-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip +networkTimeout=10000 +validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew index 2fe81a7d..1aa94a42 100755 --- a/gradlew +++ b/gradlew @@ -1,7 +1,7 @@ -#!/usr/bin/env sh +#!/bin/sh # -# Copyright 2015 the original author or authors. +# Copyright © 2015-2021 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -17,78 +17,111 @@ # ############################################################################## -## -## Gradle start up script for UN*X -## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# ############################################################################## # Attempt to set APP_HOME + # Resolve links: $0 may be a link -PRG="$0" -# Need this for relative symlinks. -while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >/dev/null -APP_HOME="`pwd -P`" -cd "$SAVED" >/dev/null -APP_NAME="Gradle" -APP_BASE_NAME=`basename "$0"` - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD="maximum" +MAX_FD=maximum warn () { echo "$*" -} +} >&2 die () { echo echo "$*" echo exit 1 -} +} >&2 # OS specific support (must be 'true' or 'false'). cygwin=false msys=false darwin=false nonstop=false -case "`uname`" in - CYGWIN* ) - cygwin=true - ;; - Darwin* ) - darwin=true - ;; - MINGW* ) - msys=true - ;; - NONSTOP* ) - nonstop=true - ;; +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; esac CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + # Determine the Java command to use to start the JVM. if [ -n "$JAVA_HOME" ] ; then if [ -x "$JAVA_HOME/jre/sh/java" ] ; then # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" + JAVACMD=$JAVA_HOME/jre/sh/java else - JAVACMD="$JAVA_HOME/bin/java" + JAVACMD=$JAVA_HOME/bin/java fi if [ ! -x "$JAVACMD" ] ; then die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME @@ -97,87 +130,120 @@ Please set the JAVA_HOME variable in your environment to match the location of your Java installation." fi else - JAVACMD="java" - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + JAVACMD=java + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. Please set the JAVA_HOME variable in your environment to match the location of your Java installation." + fi fi # Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then - MAX_FD_LIMIT=`ulimit -H -n` - if [ $? -eq 0 ] ; then - if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then - MAX_FD="$MAX_FD_LIMIT" - fi - ulimit -n $MAX_FD - if [ $? -ne 0 ] ; then - warn "Could not set maximum file descriptor limit: $MAX_FD" - fi - else - warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" - fi +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac fi -# For Darwin, add options to specify how the application appears in the dock -if $darwin; then - GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" -fi +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. # For Cygwin or MSYS, switch paths to Windows format before running java -if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then - APP_HOME=`cygpath --path --mixed "$APP_HOME"` - CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` - JAVACMD=`cygpath --unix "$JAVACMD"` - - # We build the pattern for arguments to be converted via cygpath - ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` - SEP="" - for dir in $ROOTDIRSRAW ; do - ROOTDIRS="$ROOTDIRS$SEP$dir" - SEP="|" - done - OURCYGPATTERN="(^($ROOTDIRS))" - # Add a user-defined pattern to the cygpath arguments - if [ "$GRADLE_CYGPATTERN" != "" ] ; then - OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" - fi +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + # Now convert the arguments - kludge to limit ourselves to /bin/sh - i=0 - for arg in "$@" ; do - CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` - CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option - - if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition - eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` - else - eval `echo args$i`="\"$arg\"" + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) fi - i=`expr $i + 1` + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg done - case $i in - 0) set -- ;; - 1) set -- "$args0" ;; - 2) set -- "$args0" "$args1" ;; - 3) set -- "$args0" "$args1" "$args2" ;; - 4) set -- "$args0" "$args1" "$args2" "$args3" ;; - 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; - esac fi -# Escape application args -save () { - for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done - echo " " -} -APP_ARGS=`save "$@"` -# Collect all arguments for the java command, following the shell quoting and substitution rules -eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat index 62bd9b9c..25da30db 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -14,7 +14,7 @@ @rem limitations under the License. @rem -@if "%DEBUG%" == "" @echo off +@if "%DEBUG%"=="" @echo off @rem ########################################################################## @rem @rem Gradle startup script for Windows @@ -25,7 +25,8 @@ if "%OS%"=="Windows_NT" setlocal set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% @@ -40,13 +41,13 @@ if defined JAVA_HOME goto findJavaFromJavaHome set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto init +if %ERRORLEVEL% equ 0 goto execute -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 goto fail @@ -54,48 +55,36 @@ goto fail set JAVA_HOME=%JAVA_HOME:"=% set JAVA_EXE=%JAVA_HOME%/bin/java.exe -if exist "%JAVA_EXE%" goto init +if exist "%JAVA_EXE%" goto execute -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 goto fail -:init -@rem Get command-line arguments, handling Windows variants - -if not "%OS%" == "Windows_NT" goto win9xME_args - -:win9xME_args -@rem Slurp the command line arguments. -set CMD_LINE_ARGS= -set _SKIP=2 - -:win9xME_args_slurp -if "x%~1" == "x" goto execute - -set CMD_LINE_ARGS=%* - :execute @rem Setup the command line set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* :end @rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd +if %ERRORLEVEL% equ 0 goto mainEnd :fail rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% :mainEnd if "%OS%"=="Windows_NT" endlocal diff --git a/settings.gradle b/settings.gradle index 4b023a6b..bd8c8e40 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,3 +1,13 @@ +pluginManagement { + plugins { + id 'io.spring.dependency-management' version "1.1.7" + id 'org.springframework.boot' version "3.5.7" + ['jvm', 'plugin.spring', 'plugin.jpa'].forEach(postfix -> { + id "org.jetbrains.kotlin.${postfix}" version "1.8.0" + }) + } +} + rootProject.name = 'spring-boot-sample' include 'SpringBootAOP' @@ -12,9 +22,6 @@ findProject(':SpringBootBatch')?.name = 'spring-boot-batch' include 'SpringBootCache' findProject(':SpringBootCache')?.name = 'spring-boot-cache' -include 'SpringBootConfigurable' -findProject(':SpringBootConfigurable')?.name = 'spring-boot-configurable' - include 'SpringBootCors' findProject(':SpringBootCors')?.name = 'spring-boot-cors' @@ -66,8 +73,11 @@ findProject(':SpringBootMybatis')?.name = 'spring-boot-mybatis' include 'SpringBootNotice' findProject(':SpringBootNotice')?.name = 'spring-boot-notice' -include 'SpringBootOAuth2' -findProject(':SpringBootOAuth2')?.name = 'spring-boot-oauth2' +//include 'SpringBootOAuth2' +//findProject(':SpringBootOAuth2')?.name = 'spring-boot-oauth2' + +include 'SpringBootQuartz' +findProject(':SpringBootQuartz')?.name = 'spring-boot-quartz' include 'SpringBootQueryDsl' findProject(':SpringBootQueryDsl')?.name = 'spring-boot-querydsl' @@ -93,8 +103,11 @@ findProject(':SpringBootSecurityJwt')?.name = 'spring-boot-security-jwt' include 'SpringBootSpringDocOpenApi' findProject(':SpringBootSpringDocOpenApi')?.name = 'spring-boot-springdoc-openapi' -include 'SpringBootSwagger' -findProject(':SpringBootSwagger')?.name = 'spring-boot-swagger' +include 'SpringBootSse' +findProject(':SpringBootSse')?.name = 'spring-boot-sse' + +include 'SpringBootStatemachine' +findProject(':SpringBootStatemachine')?.name = 'spring-boot-statemachine' include 'SpringBootTest' findProject(':SpringBootTest')?.name = 'spring-boot-test'