From 088bb55a4e6201f80ee571c1e7f2dc325d65bc89 Mon Sep 17 00:00:00 2001
From: VihasMakwana <121151420+VihasMakwana@users.noreply.github.com>
Date: Wed, 16 Oct 2024 20:07:31 +0530
Subject: [PATCH] [receiver/cloudflare]: follow receiver contract for
 cloudflare (#35642)

#### Description
Follow [the
contract](https://github.com/open-telemetry/opentelemetry-collector/blob/df3c9e38a80ccc3b14705462be2e2e51c628a3b3/receiver/doc.go#L10)
for cloudflare receiver
<!-- Issue number (e.g. #1234) or full URL to issue, if applicable. -->
#### Link to tracking issue
Related
https://github.com/open-telemetry/opentelemetry-collector-contrib/issues/5909

<!--Describe what testing was performed and which tests were added.-->
#### Testing

Added
---
 .chloggen/cloudflare-receiver-contract.yaml | 27 +++++++++++++++++++++
 receiver/cloudflarereceiver/go.mod          |  5 +++-
 receiver/cloudflarereceiver/go.sum          |  4 +--
 receiver/cloudflarereceiver/logs.go         |  3 ++-
 receiver/cloudflarereceiver/logs_test.go    | 23 +++++++++++++++++-
 5 files changed, 57 insertions(+), 5 deletions(-)
 create mode 100644 .chloggen/cloudflare-receiver-contract.yaml

diff --git a/.chloggen/cloudflare-receiver-contract.yaml b/.chloggen/cloudflare-receiver-contract.yaml
new file mode 100644
index 000000000000..5a025eb4c920
--- /dev/null
+++ b/.chloggen/cloudflare-receiver-contract.yaml
@@ -0,0 +1,27 @@
+# Use this changelog template to create an entry for release notes.
+
+# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix'
+change_type: enhancement
+
+# The name of the component, or a single word describing the area of concern, (e.g. filelogreceiver)
+component: cloudflarereceiver
+
+# A brief description of the change.  Surround your text with quotes ("") if it needs to start with a backtick (`).
+note: Respond 503 on non-permanent and 400 on permanent errors 
+
+# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists.
+issues: [35642]
+
+# (Optional) One or more lines of additional information to render under the primary note.
+# These lines will be padded with 2 spaces and then inserted directly into the document.
+# Use pipe (|) for multiline entries.
+subtext:
+
+# If your change doesn't affect end users or the exported elements of any package,
+# you should instead start your pull request title with [chore] or use the "Skip Changelog" label.
+# Optional: The change log or logs in which this entry should be included.
+# e.g. '[user]' or '[user, api]'
+# Include 'user' if the change is relevant to end users.
+# Include 'api' if there is a change to a library API.
+# Default: '[user]'
+change_logs: []
diff --git a/receiver/cloudflarereceiver/go.mod b/receiver/cloudflarereceiver/go.mod
index 642721b9241f..d6cfbc66dec3 100644
--- a/receiver/cloudflarereceiver/go.mod
+++ b/receiver/cloudflarereceiver/go.mod
@@ -4,6 +4,7 @@ go 1.22.0
 
 require (
 	github.com/open-telemetry/opentelemetry-collector-contrib/internal/common v0.111.0
+	github.com/open-telemetry/opentelemetry-collector-contrib/internal/coreinternal v0.111.0
 	github.com/open-telemetry/opentelemetry-collector-contrib/pkg/golden v0.111.0
 	github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatatest v0.111.0
 	github.com/stretchr/testify v1.9.0
@@ -55,7 +56,7 @@ require (
 	go.opentelemetry.io/otel/trace v1.30.0 // indirect
 	golang.org/x/net v0.28.0 // indirect
 	golang.org/x/sys v0.25.0 // indirect
-	golang.org/x/text v0.17.0 // indirect
+	golang.org/x/text v0.19.0 // indirect
 	google.golang.org/genproto/googleapis/rpc v0.0.0-20240822170219-fc7c04adadcd // indirect
 	google.golang.org/grpc v1.67.1 // indirect
 	google.golang.org/protobuf v1.35.1 // indirect
@@ -74,3 +75,5 @@ retract (
 )
 
 replace github.com/open-telemetry/opentelemetry-collector-contrib/pkg/golden => ../../pkg/golden
+
+replace github.com/open-telemetry/opentelemetry-collector-contrib/internal/coreinternal => ../../internal/coreinternal
diff --git a/receiver/cloudflarereceiver/go.sum b/receiver/cloudflarereceiver/go.sum
index b7a4eb3cf239..687febfd37e9 100644
--- a/receiver/cloudflarereceiver/go.sum
+++ b/receiver/cloudflarereceiver/go.sum
@@ -125,8 +125,8 @@ golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34=
 golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
-golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc=
-golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
+golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM=
+golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
 golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
 golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
diff --git a/receiver/cloudflarereceiver/logs.go b/receiver/cloudflarereceiver/logs.go
index f98407333cf7..3570d8146665 100644
--- a/receiver/cloudflarereceiver/logs.go
+++ b/receiver/cloudflarereceiver/logs.go
@@ -25,6 +25,7 @@ import (
 	rcvr "go.opentelemetry.io/collector/receiver"
 	"go.uber.org/zap"
 
+	"github.com/open-telemetry/opentelemetry-collector-contrib/internal/coreinternal/errorutil"
 	"github.com/open-telemetry/opentelemetry-collector-contrib/receiver/cloudflarereceiver/internal/metadata"
 )
 
@@ -185,7 +186,7 @@ func (l *logsReceiver) handleRequest(rw http.ResponseWriter, req *http.Request)
 	}
 
 	if err := l.consumer.ConsumeLogs(req.Context(), l.processLogs(pcommon.NewTimestampFromTime(time.Now()), logs)); err != nil {
-		rw.WriteHeader(http.StatusInternalServerError)
+		errorutil.HTTPError(rw, err)
 		l.logger.Error("Failed to consumer alert as log", zap.Error(err))
 		return
 	}
diff --git a/receiver/cloudflarereceiver/logs_test.go b/receiver/cloudflarereceiver/logs_test.go
index 7a60461d3247..9cf4def0e9a0 100644
--- a/receiver/cloudflarereceiver/logs_test.go
+++ b/receiver/cloudflarereceiver/logs_test.go
@@ -22,6 +22,7 @@ import (
 	"github.com/stretchr/testify/require"
 	"go.opentelemetry.io/collector/config/configtls"
 	"go.opentelemetry.io/collector/consumer"
+	"go.opentelemetry.io/collector/consumer/consumererror"
 	"go.opentelemetry.io/collector/consumer/consumertest"
 	"go.opentelemetry.io/collector/pdata/pcommon"
 	"go.opentelemetry.io/collector/pdata/plog"
@@ -191,6 +192,7 @@ func TestHandleRequest(t *testing.T) {
 		expectedStatusCode int
 		logExpected        bool
 		consumerFailure    bool
+		permanentFailure   bool // indicates a permanent error
 	}{
 		{
 			name: "No secret provided",
@@ -229,7 +231,22 @@ func TestHandleRequest(t *testing.T) {
 			},
 			logExpected:        false,
 			consumerFailure:    true,
-			expectedStatusCode: http.StatusInternalServerError,
+			expectedStatusCode: http.StatusServiceUnavailable,
+		},
+		{
+			name: "Consumer fails - permanent error",
+			request: &http.Request{
+				Method: "POST",
+				URL:    &url.URL{},
+				Body:   io.NopCloser(bytes.NewBufferString(`{"ClientIP": "127.0.0.1"}`)),
+				Header: map[string][]string{
+					textproto.CanonicalMIMEHeaderKey(secretHeaderName): {"abc123"},
+				},
+			},
+			logExpected:        false,
+			consumerFailure:    true,
+			permanentFailure:   true,
+			expectedStatusCode: http.StatusBadRequest,
 		},
 		{
 			name: "Request succeeds",
@@ -298,6 +315,10 @@ func TestHandleRequest(t *testing.T) {
 			var consumer consumer.Logs
 			if tc.consumerFailure {
 				consumer = consumertest.NewErr(errors.New("consumer failed"))
+				if tc.permanentFailure {
+					consumer = consumertest.NewErr(consumererror.NewPermanent(errors.New("consumer failed")))
+
+				}
 			} else {
 				consumer = &consumertest.LogsSink{}
 			}