forked from open-telemetry/opamp-go
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implement plain HTTP Transport in OpAMPServer
This adds plain HTTP request support to OpAMPServer implementation. Implements spec change: open-telemetry/opamp-spec#70
- Loading branch information
1 parent
405adf8
commit 07090b0
Showing
7 changed files
with
237 additions
and
11 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
package server | ||
|
||
import ( | ||
"context" | ||
"errors" | ||
"net" | ||
"net/http" | ||
|
||
"google.golang.org/protobuf/proto" | ||
|
||
"github.com/open-telemetry/opamp-go/protobufs" | ||
"github.com/open-telemetry/opamp-go/server/types" | ||
) | ||
|
||
var errInvalidHTTPConnection = errors.New( | ||
"httpConnection is not valid (are you trying to Send() more than one message?)", | ||
) | ||
|
||
// httpConnection represents a logical OpAMP connection over a plain HTTP connection. | ||
// Note: we are distinguishing the OpAMP connection from HTTP connection | ||
// here. Only one response is possible to send when using plain HTTP connection. | ||
// The HTTP connection that was used for this OpAMP connection may remain open if the | ||
// client uses Keep-Alive option and that same HTTP connection may be reused for a future | ||
// OpAMP connection. | ||
// From OpAMP perspective the connection represented by httpConnection instance is | ||
// used to receive exactly one AgentToServer message and to send exactly one | ||
// ServerToAgent message. After sending the ServerToAgent message httpConnection | ||
// instance is no longer valid. | ||
type httpConnection struct { | ||
httpResponseWriter http.ResponseWriter | ||
callbacks types.Callbacks | ||
conn net.Conn | ||
} | ||
|
||
func (c httpConnection) RemoteAddr() net.Addr { | ||
return c.conn.RemoteAddr() | ||
} | ||
|
||
var _ types.Connection = (*httpConnection)(nil) | ||
|
||
func (c httpConnection) Send(_ context.Context, message *protobufs.ServerToAgent) error { | ||
if c.httpResponseWriter == nil { | ||
return errInvalidHTTPConnection | ||
} | ||
|
||
defer func() { | ||
if c.callbacks != nil { | ||
// Indicate via the callback that the OpAMP Connection is closed. From OpAMP | ||
// perspective the connection represented by this httpConnection instance | ||
// is closed. It is not possible to send or receive more OpAMP messages | ||
// via this httpConnection. | ||
c.callbacks.OnConnectionClose(c) | ||
} | ||
}() | ||
|
||
bytes, err := proto.Marshal(message) | ||
if err != nil { | ||
c.httpResponseWriter.WriteHeader(http.StatusInternalServerError) | ||
return err | ||
} | ||
|
||
c.httpResponseWriter.Header().Set(headerContentType, contentTypeProtobuf) | ||
|
||
_, err = c.httpResponseWriter.Write(bytes) | ||
|
||
// Mark this connection as no longer valid. | ||
c.httpResponseWriter = nil | ||
|
||
return err | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
package server | ||
|
||
import ( | ||
"context" | ||
"net" | ||
"net/http" | ||
) | ||
|
||
type connContextKeyType struct { | ||
key string | ||
} | ||
|
||
var connContextKey = connContextKeyType{key: "http-conn"} | ||
|
||
func contextWithConn(ctx context.Context, c net.Conn) context.Context { | ||
// Create a new context that stores the net.Conn. For use as ConnContext func | ||
// of http.Server to remember the connection in the context. | ||
return context.WithValue(ctx, connContextKey, c) | ||
} | ||
func connFromRequest(r *http.Request) net.Conn { | ||
// Extract the net.Conn from the context of the specified http.Request. | ||
return r.Context().Value(connContextKey).(net.Conn) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters