lib/google/cloud/compute/v1/images/rest/service_stub.rb in google-cloud-compute-v1-1.4.0 vs lib/google/cloud/compute/v1/images/rest/service_stub.rb in google-cloud-compute-v1-1.5.0

- old
+ new

@@ -53,39 +53,31 @@ # @return [::Google::Cloud::Compute::V1::Operation] # A result object deserialized from the server's reply def delete request_pb, options = nil raise ::ArgumentError, "request must be provided" if request_pb.nil? - uri, _body, query_string_params = transcode_delete_request request_pb - response = @client_stub.make_delete_request( + verb, uri, query_string_params, body = transcode_delete_request request_pb + query_string_params = if query_string_params.any? + query_string_params.to_h { |p| p.split("=", 2) } + else + {} + end + + response = @client_stub.make_http_request( + verb, uri: uri, + body: body || "", params: query_string_params, options: options ) result = ::Google::Cloud::Compute::V1::Operation.decode_json response.body, ignore_unknown_fields: true yield result, response if block_given? result end ## - # GRPC transcoding helper method for the delete REST call - # - # @param request_pb [::Google::Cloud::Compute::V1::DeleteImageRequest] - # A request object representing the call parameters. Required. - # @return [Array(String, [String, nil], Hash{String => String})] - # Uri, Body, Query string parameters - def transcode_delete_request request_pb - uri = "/compute/v1/projects/#{request_pb.project}/global/images/#{request_pb.image}" - body = nil - query_string_params = {} - query_string_params["requestId"] = request_pb.request_id.to_s if request_pb.has_request_id? - - [uri, body, query_string_params] - end - - ## # Baseline implementation for the deprecate REST call # # @param request_pb [::Google::Cloud::Compute::V1::DeprecateImageRequest] # A request object representing the call parameters. Required. # @param options [::Gapic::CallOptions] @@ -98,40 +90,31 @@ # @return [::Google::Cloud::Compute::V1::Operation] # A result object deserialized from the server's reply def deprecate request_pb, options = nil raise ::ArgumentError, "request must be provided" if request_pb.nil? - uri, body, query_string_params = transcode_deprecate_request request_pb - response = @client_stub.make_post_request( + verb, uri, query_string_params, body = transcode_deprecate_request request_pb + query_string_params = if query_string_params.any? + query_string_params.to_h { |p| p.split("=", 2) } + else + {} + end + + response = @client_stub.make_http_request( + verb, uri: uri, - body: body, + body: body || "", params: query_string_params, options: options ) result = ::Google::Cloud::Compute::V1::Operation.decode_json response.body, ignore_unknown_fields: true yield result, response if block_given? result end ## - # GRPC transcoding helper method for the deprecate REST call - # - # @param request_pb [::Google::Cloud::Compute::V1::DeprecateImageRequest] - # A request object representing the call parameters. Required. - # @return [Array(String, [String, nil], Hash{String => String})] - # Uri, Body, Query string parameters - def transcode_deprecate_request request_pb - uri = "/compute/v1/projects/#{request_pb.project}/global/images/#{request_pb.image}/deprecate" - body = request_pb.deprecation_status_resource.to_json - query_string_params = {} - query_string_params["requestId"] = request_pb.request_id.to_s if request_pb.has_request_id? - - [uri, body, query_string_params] - end - - ## # Baseline implementation for the get REST call # # @param request_pb [::Google::Cloud::Compute::V1::GetImageRequest] # A request object representing the call parameters. Required. # @param options [::Gapic::CallOptions] @@ -144,37 +127,31 @@ # @return [::Google::Cloud::Compute::V1::Image] # A result object deserialized from the server's reply def get request_pb, options = nil raise ::ArgumentError, "request must be provided" if request_pb.nil? - uri, _body, _query_string_params = transcode_get_request request_pb - response = @client_stub.make_get_request( + verb, uri, query_string_params, body = transcode_get_request request_pb + query_string_params = if query_string_params.any? + query_string_params.to_h { |p| p.split("=", 2) } + else + {} + end + + response = @client_stub.make_http_request( + verb, uri: uri, + body: body || "", + params: query_string_params, options: options ) result = ::Google::Cloud::Compute::V1::Image.decode_json response.body, ignore_unknown_fields: true yield result, response if block_given? result end ## - # GRPC transcoding helper method for the get REST call - # - # @param request_pb [::Google::Cloud::Compute::V1::GetImageRequest] - # A request object representing the call parameters. Required. - # @return [Array(String, [String, nil], Hash{String => String})] - # Uri, Body, Query string parameters - def transcode_get_request request_pb - uri = "/compute/v1/projects/#{request_pb.project}/global/images/#{request_pb.image}" - body = nil - query_string_params = {} - - [uri, body, query_string_params] - end - - ## # Baseline implementation for the get_from_family REST call # # @param request_pb [::Google::Cloud::Compute::V1::GetFromFamilyImageRequest] # A request object representing the call parameters. Required. # @param options [::Gapic::CallOptions] @@ -187,37 +164,31 @@ # @return [::Google::Cloud::Compute::V1::Image] # A result object deserialized from the server's reply def get_from_family request_pb, options = nil raise ::ArgumentError, "request must be provided" if request_pb.nil? - uri, _body, _query_string_params = transcode_get_from_family_request request_pb - response = @client_stub.make_get_request( + verb, uri, query_string_params, body = transcode_get_from_family_request request_pb + query_string_params = if query_string_params.any? + query_string_params.to_h { |p| p.split("=", 2) } + else + {} + end + + response = @client_stub.make_http_request( + verb, uri: uri, + body: body || "", + params: query_string_params, options: options ) result = ::Google::Cloud::Compute::V1::Image.decode_json response.body, ignore_unknown_fields: true yield result, response if block_given? result end ## - # GRPC transcoding helper method for the get_from_family REST call - # - # @param request_pb [::Google::Cloud::Compute::V1::GetFromFamilyImageRequest] - # A request object representing the call parameters. Required. - # @return [Array(String, [String, nil], Hash{String => String})] - # Uri, Body, Query string parameters - def transcode_get_from_family_request request_pb - uri = "/compute/v1/projects/#{request_pb.project}/global/images/family/#{request_pb.family}" - body = nil - query_string_params = {} - - [uri, body, query_string_params] - end - - ## # Baseline implementation for the get_iam_policy REST call # # @param request_pb [::Google::Cloud::Compute::V1::GetIamPolicyImageRequest] # A request object representing the call parameters. Required. # @param options [::Gapic::CallOptions] @@ -230,39 +201,31 @@ # @return [::Google::Cloud::Compute::V1::Policy] # A result object deserialized from the server's reply def get_iam_policy request_pb, options = nil raise ::ArgumentError, "request must be provided" if request_pb.nil? - uri, _body, query_string_params = transcode_get_iam_policy_request request_pb - response = @client_stub.make_get_request( + verb, uri, query_string_params, body = transcode_get_iam_policy_request request_pb + query_string_params = if query_string_params.any? + query_string_params.to_h { |p| p.split("=", 2) } + else + {} + end + + response = @client_stub.make_http_request( + verb, uri: uri, + body: body || "", params: query_string_params, options: options ) result = ::Google::Cloud::Compute::V1::Policy.decode_json response.body, ignore_unknown_fields: true yield result, response if block_given? result end ## - # GRPC transcoding helper method for the get_iam_policy REST call - # - # @param request_pb [::Google::Cloud::Compute::V1::GetIamPolicyImageRequest] - # A request object representing the call parameters. Required. - # @return [Array(String, [String, nil], Hash{String => String})] - # Uri, Body, Query string parameters - def transcode_get_iam_policy_request request_pb - uri = "/compute/v1/projects/#{request_pb.project}/global/images/#{request_pb.resource}/getIamPolicy" - body = nil - query_string_params = {} - query_string_params["optionsRequestedPolicyVersion"] = request_pb.options_requested_policy_version.to_s if request_pb.has_options_requested_policy_version? - - [uri, body, query_string_params] - end - - ## # Baseline implementation for the insert REST call # # @param request_pb [::Google::Cloud::Compute::V1::InsertImageRequest] # A request object representing the call parameters. Required. # @param options [::Gapic::CallOptions] @@ -275,41 +238,31 @@ # @return [::Google::Cloud::Compute::V1::Operation] # A result object deserialized from the server's reply def insert request_pb, options = nil raise ::ArgumentError, "request must be provided" if request_pb.nil? - uri, body, query_string_params = transcode_insert_request request_pb - response = @client_stub.make_post_request( + verb, uri, query_string_params, body = transcode_insert_request request_pb + query_string_params = if query_string_params.any? + query_string_params.to_h { |p| p.split("=", 2) } + else + {} + end + + response = @client_stub.make_http_request( + verb, uri: uri, - body: body, + body: body || "", params: query_string_params, options: options ) result = ::Google::Cloud::Compute::V1::Operation.decode_json response.body, ignore_unknown_fields: true yield result, response if block_given? result end ## - # GRPC transcoding helper method for the insert REST call - # - # @param request_pb [::Google::Cloud::Compute::V1::InsertImageRequest] - # A request object representing the call parameters. Required. - # @return [Array(String, [String, nil], Hash{String => String})] - # Uri, Body, Query string parameters - def transcode_insert_request request_pb - uri = "/compute/v1/projects/#{request_pb.project}/global/images" - body = request_pb.image_resource.to_json - query_string_params = {} - query_string_params["forceCreate"] = request_pb.force_create.to_s if request_pb.has_force_create? - query_string_params["requestId"] = request_pb.request_id.to_s if request_pb.has_request_id? - - [uri, body, query_string_params] - end - - ## # Baseline implementation for the list REST call # # @param request_pb [::Google::Cloud::Compute::V1::ListImagesRequest] # A request object representing the call parameters. Required. # @param options [::Gapic::CallOptions] @@ -322,43 +275,31 @@ # @return [::Google::Cloud::Compute::V1::ImageList] # A result object deserialized from the server's reply def list request_pb, options = nil raise ::ArgumentError, "request must be provided" if request_pb.nil? - uri, _body, query_string_params = transcode_list_request request_pb - response = @client_stub.make_get_request( + verb, uri, query_string_params, body = transcode_list_request request_pb + query_string_params = if query_string_params.any? + query_string_params.to_h { |p| p.split("=", 2) } + else + {} + end + + response = @client_stub.make_http_request( + verb, uri: uri, + body: body || "", params: query_string_params, options: options ) result = ::Google::Cloud::Compute::V1::ImageList.decode_json response.body, ignore_unknown_fields: true yield result, response if block_given? result end ## - # GRPC transcoding helper method for the list REST call - # - # @param request_pb [::Google::Cloud::Compute::V1::ListImagesRequest] - # A request object representing the call parameters. Required. - # @return [Array(String, [String, nil], Hash{String => String})] - # Uri, Body, Query string parameters - def transcode_list_request request_pb - uri = "/compute/v1/projects/#{request_pb.project}/global/images" - body = nil - query_string_params = {} - query_string_params["filter"] = request_pb.filter.to_s if request_pb.has_filter? - query_string_params["maxResults"] = request_pb.max_results.to_s if request_pb.has_max_results? - query_string_params["orderBy"] = request_pb.order_by.to_s if request_pb.has_order_by? - query_string_params["pageToken"] = request_pb.page_token.to_s if request_pb.has_page_token? - query_string_params["returnPartialSuccess"] = request_pb.return_partial_success.to_s if request_pb.has_return_partial_success? - - [uri, body, query_string_params] - end - - ## # Baseline implementation for the patch REST call # # @param request_pb [::Google::Cloud::Compute::V1::PatchImageRequest] # A request object representing the call parameters. Required. # @param options [::Gapic::CallOptions] @@ -371,40 +312,31 @@ # @return [::Google::Cloud::Compute::V1::Operation] # A result object deserialized from the server's reply def patch request_pb, options = nil raise ::ArgumentError, "request must be provided" if request_pb.nil? - uri, body, query_string_params = transcode_patch_request request_pb - response = @client_stub.make_patch_request( + verb, uri, query_string_params, body = transcode_patch_request request_pb + query_string_params = if query_string_params.any? + query_string_params.to_h { |p| p.split("=", 2) } + else + {} + end + + response = @client_stub.make_http_request( + verb, uri: uri, - body: body, + body: body || "", params: query_string_params, options: options ) result = ::Google::Cloud::Compute::V1::Operation.decode_json response.body, ignore_unknown_fields: true yield result, response if block_given? result end ## - # GRPC transcoding helper method for the patch REST call - # - # @param request_pb [::Google::Cloud::Compute::V1::PatchImageRequest] - # A request object representing the call parameters. Required. - # @return [Array(String, [String, nil], Hash{String => String})] - # Uri, Body, Query string parameters - def transcode_patch_request request_pb - uri = "/compute/v1/projects/#{request_pb.project}/global/images/#{request_pb.image}" - body = request_pb.image_resource.to_json - query_string_params = {} - query_string_params["requestId"] = request_pb.request_id.to_s if request_pb.has_request_id? - - [uri, body, query_string_params] - end - - ## # Baseline implementation for the set_iam_policy REST call # # @param request_pb [::Google::Cloud::Compute::V1::SetIamPolicyImageRequest] # A request object representing the call parameters. Required. # @param options [::Gapic::CallOptions] @@ -417,38 +349,31 @@ # @return [::Google::Cloud::Compute::V1::Policy] # A result object deserialized from the server's reply def set_iam_policy request_pb, options = nil raise ::ArgumentError, "request must be provided" if request_pb.nil? - uri, body, _query_string_params = transcode_set_iam_policy_request request_pb - response = @client_stub.make_post_request( + verb, uri, query_string_params, body = transcode_set_iam_policy_request request_pb + query_string_params = if query_string_params.any? + query_string_params.to_h { |p| p.split("=", 2) } + else + {} + end + + response = @client_stub.make_http_request( + verb, uri: uri, - body: body, + body: body || "", + params: query_string_params, options: options ) result = ::Google::Cloud::Compute::V1::Policy.decode_json response.body, ignore_unknown_fields: true yield result, response if block_given? result end ## - # GRPC transcoding helper method for the set_iam_policy REST call - # - # @param request_pb [::Google::Cloud::Compute::V1::SetIamPolicyImageRequest] - # A request object representing the call parameters. Required. - # @return [Array(String, [String, nil], Hash{String => String})] - # Uri, Body, Query string parameters - def transcode_set_iam_policy_request request_pb - uri = "/compute/v1/projects/#{request_pb.project}/global/images/#{request_pb.resource}/setIamPolicy" - body = request_pb.global_set_policy_request_resource.to_json - query_string_params = {} - - [uri, body, query_string_params] - end - - ## # Baseline implementation for the set_labels REST call # # @param request_pb [::Google::Cloud::Compute::V1::SetLabelsImageRequest] # A request object representing the call parameters. Required. # @param options [::Gapic::CallOptions] @@ -461,38 +386,31 @@ # @return [::Google::Cloud::Compute::V1::Operation] # A result object deserialized from the server's reply def set_labels request_pb, options = nil raise ::ArgumentError, "request must be provided" if request_pb.nil? - uri, body, _query_string_params = transcode_set_labels_request request_pb - response = @client_stub.make_post_request( + verb, uri, query_string_params, body = transcode_set_labels_request request_pb + query_string_params = if query_string_params.any? + query_string_params.to_h { |p| p.split("=", 2) } + else + {} + end + + response = @client_stub.make_http_request( + verb, uri: uri, - body: body, + body: body || "", + params: query_string_params, options: options ) result = ::Google::Cloud::Compute::V1::Operation.decode_json response.body, ignore_unknown_fields: true yield result, response if block_given? result end ## - # GRPC transcoding helper method for the set_labels REST call - # - # @param request_pb [::Google::Cloud::Compute::V1::SetLabelsImageRequest] - # A request object representing the call parameters. Required. - # @return [Array(String, [String, nil], Hash{String => String})] - # Uri, Body, Query string parameters - def transcode_set_labels_request request_pb - uri = "/compute/v1/projects/#{request_pb.project}/global/images/#{request_pb.resource}/setLabels" - body = request_pb.global_set_labels_request_resource.to_json - query_string_params = {} - - [uri, body, query_string_params] - end - - ## # Baseline implementation for the test_iam_permissions REST call # # @param request_pb [::Google::Cloud::Compute::V1::TestIamPermissionsImageRequest] # A request object representing the call parameters. Required. # @param options [::Gapic::CallOptions] @@ -505,34 +423,276 @@ # @return [::Google::Cloud::Compute::V1::TestPermissionsResponse] # A result object deserialized from the server's reply def test_iam_permissions request_pb, options = nil raise ::ArgumentError, "request must be provided" if request_pb.nil? - uri, body, _query_string_params = transcode_test_iam_permissions_request request_pb - response = @client_stub.make_post_request( + verb, uri, query_string_params, body = transcode_test_iam_permissions_request request_pb + query_string_params = if query_string_params.any? + query_string_params.to_h { |p| p.split("=", 2) } + else + {} + end + + response = @client_stub.make_http_request( + verb, uri: uri, - body: body, + body: body || "", + params: query_string_params, options: options ) result = ::Google::Cloud::Compute::V1::TestPermissionsResponse.decode_json response.body, ignore_unknown_fields: true yield result, response if block_given? result end + + private + ## + # @private + # + # GRPC transcoding helper method for the delete REST call + # + # @param request_pb [::Google::Cloud::Compute::V1::DeleteImageRequest] + # A request object representing the call parameters. Required. + # @return [Array(String, [String, nil], Hash{String => String})] + # Uri, Body, Query string parameters + def transcode_delete_request request_pb + transcoder = Gapic::Rest::GrpcTranscoder.new + .with_bindings( + uri_method: :delete, + uri_template: "/compute/v1/projects/{project}/global/images/{image}", + matches: [ + ["project", %r{[^/]+}, false], + ["image", %r{[^/]+}, false] + ] + ) + transcoder.transcode request_pb + end + + ## + # @private + # + # GRPC transcoding helper method for the deprecate REST call + # + # @param request_pb [::Google::Cloud::Compute::V1::DeprecateImageRequest] + # A request object representing the call parameters. Required. + # @return [Array(String, [String, nil], Hash{String => String})] + # Uri, Body, Query string parameters + def transcode_deprecate_request request_pb + transcoder = Gapic::Rest::GrpcTranscoder.new + .with_bindings( + uri_method: :post, + uri_template: "/compute/v1/projects/{project}/global/images/{image}/deprecate", + body: "deprecation_status_resource", + matches: [ + ["project", %r{[^/]+}, false], + ["image", %r{[^/]+}, false] + ] + ) + transcoder.transcode request_pb + end + + ## + # @private + # + # GRPC transcoding helper method for the get REST call + # + # @param request_pb [::Google::Cloud::Compute::V1::GetImageRequest] + # A request object representing the call parameters. Required. + # @return [Array(String, [String, nil], Hash{String => String})] + # Uri, Body, Query string parameters + def transcode_get_request request_pb + transcoder = Gapic::Rest::GrpcTranscoder.new + .with_bindings( + uri_method: :get, + uri_template: "/compute/v1/projects/{project}/global/images/{image}", + matches: [ + ["project", %r{[^/]+}, false], + ["image", %r{[^/]+}, false] + ] + ) + transcoder.transcode request_pb + end + + ## + # @private + # + # GRPC transcoding helper method for the get_from_family REST call + # + # @param request_pb [::Google::Cloud::Compute::V1::GetFromFamilyImageRequest] + # A request object representing the call parameters. Required. + # @return [Array(String, [String, nil], Hash{String => String})] + # Uri, Body, Query string parameters + def transcode_get_from_family_request request_pb + transcoder = Gapic::Rest::GrpcTranscoder.new + .with_bindings( + uri_method: :get, + uri_template: "/compute/v1/projects/{project}/global/images/family/{family}", + matches: [ + ["project", %r{[^/]+}, false], + ["family", %r{[^/]+}, false] + ] + ) + transcoder.transcode request_pb + end + + ## + # @private + # + # GRPC transcoding helper method for the get_iam_policy REST call + # + # @param request_pb [::Google::Cloud::Compute::V1::GetIamPolicyImageRequest] + # A request object representing the call parameters. Required. + # @return [Array(String, [String, nil], Hash{String => String})] + # Uri, Body, Query string parameters + def transcode_get_iam_policy_request request_pb + transcoder = Gapic::Rest::GrpcTranscoder.new + .with_bindings( + uri_method: :get, + uri_template: "/compute/v1/projects/{project}/global/images/{resource}/getIamPolicy", + matches: [ + ["project", %r{[^/]+}, false], + ["resource", %r{[^/]+}, false] + ] + ) + transcoder.transcode request_pb + end + + ## + # @private + # + # GRPC transcoding helper method for the insert REST call + # + # @param request_pb [::Google::Cloud::Compute::V1::InsertImageRequest] + # A request object representing the call parameters. Required. + # @return [Array(String, [String, nil], Hash{String => String})] + # Uri, Body, Query string parameters + def transcode_insert_request request_pb + transcoder = Gapic::Rest::GrpcTranscoder.new + .with_bindings( + uri_method: :post, + uri_template: "/compute/v1/projects/{project}/global/images", + body: "image_resource", + matches: [ + ["project", %r{[^/]+}, false] + ] + ) + transcoder.transcode request_pb + end + + ## + # @private + # + # GRPC transcoding helper method for the list REST call + # + # @param request_pb [::Google::Cloud::Compute::V1::ListImagesRequest] + # A request object representing the call parameters. Required. + # @return [Array(String, [String, nil], Hash{String => String})] + # Uri, Body, Query string parameters + def transcode_list_request request_pb + transcoder = Gapic::Rest::GrpcTranscoder.new + .with_bindings( + uri_method: :get, + uri_template: "/compute/v1/projects/{project}/global/images", + matches: [ + ["project", %r{[^/]+}, false] + ] + ) + transcoder.transcode request_pb + end + + ## + # @private + # + # GRPC transcoding helper method for the patch REST call + # + # @param request_pb [::Google::Cloud::Compute::V1::PatchImageRequest] + # A request object representing the call parameters. Required. + # @return [Array(String, [String, nil], Hash{String => String})] + # Uri, Body, Query string parameters + def transcode_patch_request request_pb + transcoder = Gapic::Rest::GrpcTranscoder.new + .with_bindings( + uri_method: :patch, + uri_template: "/compute/v1/projects/{project}/global/images/{image}", + body: "image_resource", + matches: [ + ["project", %r{[^/]+}, false], + ["image", %r{[^/]+}, false] + ] + ) + transcoder.transcode request_pb + end + + ## + # @private + # + # GRPC transcoding helper method for the set_iam_policy REST call + # + # @param request_pb [::Google::Cloud::Compute::V1::SetIamPolicyImageRequest] + # A request object representing the call parameters. Required. + # @return [Array(String, [String, nil], Hash{String => String})] + # Uri, Body, Query string parameters + def transcode_set_iam_policy_request request_pb + transcoder = Gapic::Rest::GrpcTranscoder.new + .with_bindings( + uri_method: :post, + uri_template: "/compute/v1/projects/{project}/global/images/{resource}/setIamPolicy", + body: "global_set_policy_request_resource", + matches: [ + ["project", %r{[^/]+}, false], + ["resource", %r{[^/]+}, false] + ] + ) + transcoder.transcode request_pb + end + + ## + # @private + # + # GRPC transcoding helper method for the set_labels REST call + # + # @param request_pb [::Google::Cloud::Compute::V1::SetLabelsImageRequest] + # A request object representing the call parameters. Required. + # @return [Array(String, [String, nil], Hash{String => String})] + # Uri, Body, Query string parameters + def transcode_set_labels_request request_pb + transcoder = Gapic::Rest::GrpcTranscoder.new + .with_bindings( + uri_method: :post, + uri_template: "/compute/v1/projects/{project}/global/images/{resource}/setLabels", + body: "global_set_labels_request_resource", + matches: [ + ["project", %r{[^/]+}, false], + ["resource", %r{[^/]+}, false] + ] + ) + transcoder.transcode request_pb + end + + ## + # @private + # # GRPC transcoding helper method for the test_iam_permissions REST call # # @param request_pb [::Google::Cloud::Compute::V1::TestIamPermissionsImageRequest] # A request object representing the call parameters. Required. # @return [Array(String, [String, nil], Hash{String => String})] # Uri, Body, Query string parameters def transcode_test_iam_permissions_request request_pb - uri = "/compute/v1/projects/#{request_pb.project}/global/images/#{request_pb.resource}/testIamPermissions" - body = request_pb.test_permissions_request_resource.to_json - query_string_params = {} - - [uri, body, query_string_params] + transcoder = Gapic::Rest::GrpcTranscoder.new + .with_bindings( + uri_method: :post, + uri_template: "/compute/v1/projects/{project}/global/images/{resource}/testIamPermissions", + body: "test_permissions_request_resource", + matches: [ + ["project", %r{[^/]+}, false], + ["resource", %r{[^/]+}, false] + ] + ) + transcoder.transcode request_pb end end end end end