-
Notifications
You must be signed in to change notification settings - Fork 129
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Opamp client api #1481
base: main
Are you sure you want to change the base?
Opamp client api #1481
Changes from all commits
946988a
eb665b7
d291767
42484e3
91e174d
d278b81
0a8cd32
1fbd155
c983ede
d58e171
14b6d41
d0a61c4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
[submodule "opamp-client/opamp-spec"] | ||
path = opamp-client/opamp-spec | ||
url = [email protected]:open-telemetry/opamp-spec.git |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
/* | ||
* Copyright The OpenTelemetry Authors | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
package io.opentelemetry.opamp.client.internal; | ||
|
||
import io.opentelemetry.opamp.client.internal.response.MessageData; | ||
import opamp.proto.Opamp; | ||
|
||
public interface OpampClient { | ||
|
||
/** | ||
* Starts the client and begin attempts to connect to the Server. Once connection is established | ||
* the client will attempt to maintain it by reconnecting if the connection is lost. All failed | ||
* connection attempts will be reported via {@link Callbacks#onConnectFailed(OpampClient, | ||
* Throwable)} callback. | ||
* | ||
* <p>This method does not wait until the connection to the Server is established and will likely | ||
* return before the connection attempts are even made. | ||
* | ||
* <p>This method may be called only once. | ||
* | ||
* @param callbacks The Callback to which the Client will notify about any Server requests and | ||
* responses. | ||
*/ | ||
void start(Callbacks callbacks); | ||
|
||
/** | ||
* Stops the client. May be called only after {@link #start(Callbacks)}. May be called only once. | ||
* After this call returns successfully it is guaranteed that no callbacks will be called. Once | ||
* stopped, the client cannot be started again. | ||
*/ | ||
void stop(); | ||
|
||
/** | ||
* Sets attributes of the Agent. The attributes will be included in the next status report sent to | ||
* the Server. When called after {@link #start(Callbacks)}, the attributes will be included in the | ||
* next outgoing status report. This is typically used by Agents which allow their | ||
* AgentDescription to change dynamically while the OpAMPClient is started. May be also called | ||
* from {@link Callbacks#onMessage(OpampClient, MessageData)}. | ||
* | ||
* @param agentDescription The new agent description. | ||
*/ | ||
void setAgentDescription(Opamp.AgentDescription agentDescription); | ||
|
||
/** | ||
* Sets the current remote config status which will be sent in the next agent to server request. | ||
* | ||
* @param remoteConfigStatus The new remote config status. | ||
*/ | ||
void setRemoteConfigStatus(Opamp.RemoteConfigStatus remoteConfigStatus); | ||
|
||
interface Callbacks { | ||
/** | ||
* Called when the connection is successfully established to the Server. May be called after | ||
* {@link #start(Callbacks)} is called and every time a connection is established to the Server. | ||
* For WebSocket clients this is called after the handshake is completed without any error. For | ||
* HTTP clients this is called for any request if the response status is OK. | ||
* | ||
* @param client The relevant {@link OpampClient} instance. | ||
*/ | ||
void onConnect(OpampClient client); | ||
|
||
/** | ||
* Called when the connection to the Server cannot be established. May be called after {@link | ||
* #start(Callbacks)} is called and tries to connect to the Server. May also be called if the | ||
* connection is lost and reconnection attempt fails. | ||
* | ||
* @param client The relevant {@link OpampClient} instance. | ||
* @param throwable The exception. | ||
*/ | ||
void onConnectFailed(OpampClient client, Throwable throwable); | ||
|
||
/** | ||
* Called when the Server reports an error in response to some previously sent request. Useful | ||
* for logging purposes. The Agent should not attempt to process the error by reconnecting or | ||
* retrying previous operations. The client handles the ErrorResponse_UNAVAILABLE case | ||
* internally by performing retries as necessary. | ||
* | ||
* @param client The relevant {@link OpampClient} instance. | ||
* @param errorResponse The error returned by the Server. | ||
*/ | ||
void onErrorResponse(OpampClient client, Opamp.ServerErrorResponse errorResponse); | ||
|
||
/** | ||
* Called when the Agent receives a message that needs processing. See {@link MessageData} | ||
* definition for the data that may be available for processing. During onMessage execution the | ||
* {@link OpampClient} functions that change the status of the client may be called, e.g. if | ||
* RemoteConfig is processed then {@link | ||
* #setRemoteConfigStatus(opamp.proto.Opamp.RemoteConfigStatus)} should be called to reflect the | ||
* processing result. These functions may also be called after onMessage returns. This is | ||
* advisable if processing can take a long time. In that case returning quickly is preferable to | ||
* avoid blocking the {@link OpampClient}. | ||
* | ||
* @param client The relevant {@link OpampClient} instance. | ||
* @param messageData The server response data that needs processing. | ||
*/ | ||
void onMessage(OpampClient client, MessageData messageData); | ||
} | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I assume more callbacks will be added later, e.g. OnOpampConnectionSettings, OnCommand, etc. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Correct, I think those should be added as soon as we add support for those functionalities (unless we see a reason to add them beforehand with noop functionality). |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
/* | ||
* Copyright The OpenTelemetry Authors | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
package io.opentelemetry.opamp.client.internal.response; | ||
|
||
import com.google.auto.value.AutoValue; | ||
import io.opentelemetry.opamp.client.internal.OpampClient; | ||
import javax.annotation.Nullable; | ||
import opamp.proto.Opamp; | ||
|
||
/** | ||
* Data class provided in {@link OpampClient.Callbacks#onMessage(OpampClient, MessageData)} with | ||
* Server's provided status changes. | ||
*/ | ||
@AutoValue | ||
public abstract class MessageData { | ||
@Nullable | ||
public abstract Opamp.AgentRemoteConfig getRemoteConfig(); | ||
|
||
public static Builder builder() { | ||
return new AutoValue_MessageData.Builder(); | ||
} | ||
|
||
@AutoValue.Builder | ||
public abstract static class Builder { | ||
public abstract Builder setRemoteConfig(Opamp.AgentRemoteConfig remoteConfig); | ||
|
||
public abstract MessageData build(); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see some of opamp-go Client's methods here, e.g.
SetAgentDescription
. Just wanted to confirm this is deliberate and not accidentally missing.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, for context, I'm currently moving the PoC implementation created here which had only the bare minimum apis/functionality for our use-case to work. So we should keep on adding more methods in the future. The
SetAgentDescription
one seems to be pretty straightforward so I think we could add it right away to account for the use-case of changing the description after the client has started.An interesting note on the client initialization method used in the PoC is that it relies on the builder pattern. So, setting the agent description before starting the client is done in the client builder, as you can see here. There are 2 main reasons for this, the first one being that it's less error-prone as users wouldn't need to remember setting the agent description before starting the client, which is something I noticed is mentioned here in the Go impl, and the second reason is that using the builder pattern to solve these issues is a common practice in Java and makes it easier to adjust/extend initialization-related processes in the future. It's also the pattern used when initializing the OTel Java SDK so I think that's a bonus in terms of consistency across Java-related projects in OTel.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've just added
SetAgentDescription
.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Makes sense. I think you are free to deviate from opamp-go and use whatever is the most idiomatic approach for Java. Builder pattern is less common in Go world. Struct of options is typically what Go uses, e.g. the standard library http server: https://pkg.go.dev/net/http#hdr-Servers