diff --git a/sdk/src/main/java/io/dapr/client/DaprClientImpl.java b/sdk/src/main/java/io/dapr/client/DaprClientImpl.java index 3e82862e2..895d765db 100644 --- a/sdk/src/main/java/io/dapr/client/DaprClientImpl.java +++ b/sdk/src/main/java/io/dapr/client/DaprClientImpl.java @@ -16,6 +16,8 @@ import com.google.common.base.Strings; import com.google.protobuf.ByteString; import com.google.protobuf.Empty; +import io.dapr.client.domain.AppConnectionPropertiesHealthMetadata; +import io.dapr.client.domain.AppConnectionPropertiesMetadata; import io.dapr.client.domain.BulkPublishEntry; import io.dapr.client.domain.BulkPublishRequest; import io.dapr.client.domain.BulkPublishResponse; @@ -30,6 +32,7 @@ import io.dapr.client.domain.GetConfigurationRequest; import io.dapr.client.domain.GetSecretRequest; import io.dapr.client.domain.GetStateRequest; +import io.dapr.client.domain.HttpEndpointMetadata; import io.dapr.client.domain.HttpExtension; import io.dapr.client.domain.InvokeBindingRequest; import io.dapr.client.domain.InvokeMethodRequest; @@ -62,6 +65,9 @@ import io.dapr.v1.CommonProtos; import io.dapr.v1.DaprGrpc; import io.dapr.v1.DaprProtos; +import io.dapr.v1.DaprProtos.AppConnectionHealthProperties; +import io.dapr.v1.DaprProtos.AppConnectionProperties; +import io.dapr.v1.DaprProtos.MetadataHTTPEndpoint; import io.dapr.v1.DaprProtos.PubsubSubscription; import io.dapr.v1.DaprProtos.PubsubSubscriptionRule; import io.dapr.v1.DaprProtos.RegisteredComponents; @@ -1256,8 +1262,21 @@ public Mono getMetadata() { }); } - private DaprMetadata buildDaprMetadata( - DaprProtos.GetMetadataResponse response) throws IOException { + private DaprMetadata buildDaprMetadata(DaprProtos.GetMetadataResponse response) throws IOException { + String id = response.getId(); + String runtimeVersion = response.getRuntimeVersion(); + List enabledFeatures = response.getEnabledFeaturesList(); + Map attributes = response.getExtendedMetadataMap(); + List components = getComponents(response); + List httpEndpoints = getHttpEndpoints(response); + List subscriptions = getSubscriptions(response); + AppConnectionPropertiesMetadata appConnectionProperties = getAppConnectionProperties(response); + + return new DaprMetadata(id, runtimeVersion, enabledFeatures, attributes, components, httpEndpoints, subscriptions, + appConnectionProperties); + } + + private List getComponents(DaprProtos.GetMetadataResponse response) { List registeredComponentsList = response.getRegisteredComponentsList(); List components = new ArrayList<>(); @@ -1265,7 +1284,12 @@ private DaprMetadata buildDaprMetadata( components.add(new ComponentMetadata(rc.getName(), rc.getType(), rc.getVersion())); } + return components; + } + + private List getSubscriptions(DaprProtos.GetMetadataResponse response) { List subscriptionsList = response.getSubscriptionsList(); + List subscriptions = new ArrayList<>(); for (PubsubSubscription s : subscriptionsList) { List rulesList = s.getRules().getRulesList(); @@ -1276,6 +1300,45 @@ private DaprMetadata buildDaprMetadata( subscriptions.add(new SubscriptionMetadata(s.getTopic(), s.getPubsubName(), s.getDeadLetterTopic(), rules)); } - return new DaprMetadata(response.getId(), response.getRuntimeVersion(), components, subscriptions); + return subscriptions; + } + + private List getHttpEndpoints(DaprProtos.GetMetadataResponse response) { + List httpEndpointsList = response.getHttpEndpointsList(); + + List httpEndpoints = new ArrayList<>(); + for (MetadataHTTPEndpoint m : httpEndpointsList) { + httpEndpoints.add(new HttpEndpointMetadata(m.getName())); + } + + return httpEndpoints; } -} \ No newline at end of file + + private AppConnectionPropertiesMetadata getAppConnectionProperties(DaprProtos.GetMetadataResponse response) { + AppConnectionProperties appConnectionProperties = response.getAppConnectionProperties(); + int port = appConnectionProperties.getPort(); + String protocol = appConnectionProperties.getProtocol(); + String channelAddress = appConnectionProperties.getChannelAddress(); + int maxConcurrency = appConnectionProperties.getMaxConcurrency(); + AppConnectionPropertiesHealthMetadata health = getAppConnectionPropertiesHealth(appConnectionProperties); + + return new AppConnectionPropertiesMetadata(port, protocol, channelAddress, maxConcurrency, health); + } + + private AppConnectionPropertiesHealthMetadata getAppConnectionPropertiesHealth( + AppConnectionProperties appConnectionProperties) { + if (!appConnectionProperties.hasHealth()) { + return null; + } + + AppConnectionHealthProperties health = appConnectionProperties.getHealth(); + String healthCheckPath = health.getHealthCheckPath(); + String healthProbeInterval = health.getHealthProbeInterval(); + String healthProbeTimeout = health.getHealthProbeTimeout(); + int healthThreshold = health.getHealthThreshold(); + + return new AppConnectionPropertiesHealthMetadata(healthCheckPath, healthProbeInterval, healthProbeTimeout, + healthThreshold); + } + +} diff --git a/sdk/src/main/java/io/dapr/client/domain/AppConnectionPropertiesHealthMetadata.java b/sdk/src/main/java/io/dapr/client/domain/AppConnectionPropertiesHealthMetadata.java new file mode 100644 index 000000000..c014be60f --- /dev/null +++ b/sdk/src/main/java/io/dapr/client/domain/AppConnectionPropertiesHealthMetadata.java @@ -0,0 +1,55 @@ +/* + * Copyright 2024 The Dapr Authors + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and +limitations under the License. +*/ + +package io.dapr.client.domain; + +public final class AppConnectionPropertiesHealthMetadata { + + private final String healthCheckPath; + private final String healthProbeInterval; + private final String healthProbeTimeout; + private final int healthThreshold; + + /** + * Constructor for a AppConnectionPropertiesHealthMetadata. + * + * @param healthCheckPath of the application + * @param healthProbeInterval time interval between health probes + * @param healthProbeTimeout timeout for each health probe + * @param healthThreshold max number of failed health probes + */ + public AppConnectionPropertiesHealthMetadata(String healthCheckPath, String healthProbeInterval, + String healthProbeTimeout, int healthThreshold) { + this.healthCheckPath = healthCheckPath; + this.healthProbeInterval = healthProbeInterval; + this.healthProbeTimeout = healthProbeTimeout; + this.healthThreshold = healthThreshold; + } + + public String getHealthCheckPath() { + return healthCheckPath; + } + + public String getHealthProbeInterval() { + return healthProbeInterval; + } + + public String getHealthProbeTimeout() { + return healthProbeTimeout; + } + + public int getHealthThreshold() { + return healthThreshold; + } + +} diff --git a/sdk/src/main/java/io/dapr/client/domain/AppConnectionPropertiesMetadata.java b/sdk/src/main/java/io/dapr/client/domain/AppConnectionPropertiesMetadata.java new file mode 100644 index 000000000..1e498c2dd --- /dev/null +++ b/sdk/src/main/java/io/dapr/client/domain/AppConnectionPropertiesMetadata.java @@ -0,0 +1,62 @@ +/* + * Copyright 2024 The Dapr Authors + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and +limitations under the License. +*/ + +package io.dapr.client.domain; + +public final class AppConnectionPropertiesMetadata { + + private final int port; + private final String protocol; + private final String channelAddress; + private final int maxConcurrency; + private final AppConnectionPropertiesHealthMetadata health; + + /** + * Constructor for a AppConnectionPropertiesMetadata. + * + * @param port of the application + * @param protocol of the application + * @param channelAddress host address of the application + * @param maxConcurrency number of concurrent requests the app can handle + * @param health health check details of the application + */ + public AppConnectionPropertiesMetadata(int port, String protocol, String channelAddress, int maxConcurrency, + AppConnectionPropertiesHealthMetadata health) { + this.port = port; + this.protocol = protocol; + this.channelAddress = channelAddress; + this.maxConcurrency = maxConcurrency; + this.health = health; + } + + public int getPort() { + return port; + } + + public String getProtocol() { + return protocol; + } + + public String getChannelAddress() { + return channelAddress; + } + + public int getMaxConcurrency() { + return maxConcurrency; + } + + public AppConnectionPropertiesHealthMetadata getHealth() { + return health; + } + +} diff --git a/sdk/src/main/java/io/dapr/client/domain/DaprMetadata.java b/sdk/src/main/java/io/dapr/client/domain/DaprMetadata.java index c99804d96..bba77578d 100644 --- a/sdk/src/main/java/io/dapr/client/domain/DaprMetadata.java +++ b/sdk/src/main/java/io/dapr/client/domain/DaprMetadata.java @@ -15,32 +15,46 @@ import java.util.Collections; import java.util.List; -import java.util.Objects; +import java.util.Map; /** * DaprMetadata describes the Dapr Metadata. */ public final class DaprMetadata { - private String id; - private String runtimeVersion; - private List components; - private List subscriptions; + private final String id; + private final String runtimeVersion; + private final List enabledFeatures; + private final Map attributes; + private final List components; + private final List httpEndpoints; + private final List subscriptions; + private final AppConnectionPropertiesMetadata appConnectionProperties; /** * Constructor for a DaprMetadata. * * @param id of the application * @param runtimeVersion Dapr version - * @param components list of registered componnets + * @param enabledFeatures list of enabled features + * @param attributes map of extended attributes + * @param components list of registered components + * @param httpEndpoints list of registered http endpoints * @param subscriptions list of registered subscription + * @param appConnectionProperties connection properties of the application */ - public DaprMetadata(String id, String runtimeVersion, List components, - List subscriptions) { + public DaprMetadata(String id, String runtimeVersion, List enabledFeatures, Map attributes, + List components, List httpEndpoints, + List subscriptions, AppConnectionPropertiesMetadata appConnectionProperties) { this.id = id; this.runtimeVersion = runtimeVersion; + this.enabledFeatures = enabledFeatures == null ? Collections.emptyList() : + Collections.unmodifiableList(enabledFeatures); + this.attributes = attributes == null ? Collections.emptyMap() : Collections.unmodifiableMap(attributes); this.components = components == null ? Collections.emptyList() : Collections.unmodifiableList(components); + this.httpEndpoints = httpEndpoints == null ? Collections.emptyList() : Collections.unmodifiableList(httpEndpoints); this.subscriptions = subscriptions == null ? Collections.emptyList() : Collections.unmodifiableList(subscriptions); + this.appConnectionProperties = appConnectionProperties; } public String getId() { @@ -51,12 +65,28 @@ public String getRuntimeVersion() { return runtimeVersion; } + public List getEnabledFeatures() { + return enabledFeatures; + } + + public Map getAttributes() { + return attributes; + } + public List getComponents() { return components; } + public List getHttpEndpoints() { + return httpEndpoints; + } + public List getSubscriptions() { return subscriptions; } + + public AppConnectionPropertiesMetadata getAppConnectionProperties() { + return appConnectionProperties; + } } diff --git a/sdk/src/main/java/io/dapr/client/domain/HttpEndpointMetadata.java b/sdk/src/main/java/io/dapr/client/domain/HttpEndpointMetadata.java new file mode 100644 index 000000000..43327925e --- /dev/null +++ b/sdk/src/main/java/io/dapr/client/domain/HttpEndpointMetadata.java @@ -0,0 +1,33 @@ +/* + * Copyright 2024 The Dapr Authors + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and +limitations under the License. +*/ + +package io.dapr.client.domain; + +public final class HttpEndpointMetadata { + + private final String name; + + /** + * Constructor for a HttpEndpointMetadata. + * + * @param name of the HTTP endpoint + */ + public HttpEndpointMetadata(String name) { + this.name = name; + } + + public String getName() { + return name; + } + +} diff --git a/sdk/src/test/java/io/dapr/client/DaprClientGrpcTest.java b/sdk/src/test/java/io/dapr/client/DaprClientGrpcTest.java index 93dd80203..8e1459094 100644 --- a/sdk/src/test/java/io/dapr/client/DaprClientGrpcTest.java +++ b/sdk/src/test/java/io/dapr/client/DaprClientGrpcTest.java @@ -16,28 +16,18 @@ import com.google.protobuf.Any; import com.google.protobuf.ByteString; import com.google.protobuf.Empty; -import io.dapr.client.domain.ConfigurationItem; -import io.dapr.client.domain.DaprMetadata; -import io.dapr.client.domain.DeleteStateRequest; -import io.dapr.client.domain.ExecuteStateTransactionRequest; -import io.dapr.client.domain.GetBulkStateRequest; -import io.dapr.client.domain.GetStateRequest; -import io.dapr.client.domain.PublishEventRequest; -import io.dapr.client.domain.State; -import io.dapr.client.domain.StateOptions; -import io.dapr.client.domain.SubscribeConfigurationResponse; -import io.dapr.client.domain.TransactionalStateOperation; -import io.dapr.client.domain.UnsubscribeConfigurationRequest; -import io.dapr.client.domain.UnsubscribeConfigurationResponse; -import io.dapr.exceptions.DaprError; -import io.dapr.exceptions.DaprException; +import io.dapr.client.domain.*; import io.dapr.serializer.DaprObjectSerializer; import io.dapr.serializer.DefaultObjectSerializer; import io.dapr.utils.TypeRef; import io.dapr.v1.CommonProtos; import io.dapr.v1.DaprGrpc; import io.dapr.v1.DaprProtos; +import io.dapr.v1.DaprProtos.AppConnectionHealthProperties; +import io.dapr.v1.DaprProtos.AppConnectionProperties; +import io.dapr.v1.DaprProtos.MetadataHTTPEndpoint; import io.dapr.v1.DaprProtos.PubsubSubscription; +import io.dapr.v1.DaprProtos.PubsubSubscriptionRules; import io.dapr.v1.DaprProtos.RegisteredComponents; import io.grpc.Status; import io.grpc.StatusRuntimeException; @@ -2086,25 +2076,54 @@ public static StatusRuntimeException newStatusRuntimeException(String statusCode @Test public void getMetadataTest() { - RegisteredComponents registeredComponents = DaprProtos.RegisteredComponents.newBuilder() .setName("statestore") .setType("state.redis") .setVersion("v1") .build(); + + DaprProtos.MetadataHTTPEndpoint httpEndpoint = DaprProtos.MetadataHTTPEndpoint.newBuilder() + .setName("httpEndpoint") + .build(); + + PubsubSubscriptionRules pubsubSubscriptionRules = DaprProtos.PubsubSubscriptionRules.newBuilder() + .addRules(DaprProtos.PubsubSubscriptionRule.newBuilder().setPath("/events").build()) + .build(); + PubsubSubscription pubsubSubscription = DaprProtos.PubsubSubscription.newBuilder() .setDeadLetterTopic("") .setPubsubName("pubsub") .setTopic("topic") - .setRules(DaprProtos.PubsubSubscriptionRules.newBuilder() - .addRules(DaprProtos.PubsubSubscriptionRule.newBuilder().setPath("/events").build()).build()) + .setRules(pubsubSubscriptionRules) .build(); + + AppConnectionHealthProperties healthProperties = DaprProtos.AppConnectionHealthProperties.newBuilder() + .setHealthCheckPath("/health") + .setHealthProbeInterval("10s") + .setHealthProbeTimeout("5s") + .setHealthThreshold(1) + .build(); + + AppConnectionProperties appConnectionProperties = DaprProtos.AppConnectionProperties.newBuilder() + .setPort(8080) + .setProtocol("http") + .setChannelAddress("localhost") + .setMaxConcurrency(1) + .setHealth(healthProperties) + .build(); + + DaprProtos.GetMetadataResponse responseEnvelope = DaprProtos.GetMetadataResponse.newBuilder() .setId("app") .setRuntimeVersion("1.1x.x") + .addAllEnabledFeatures(Collections.emptyList()) + .putAllExtendedMetadata(Collections.emptyMap()) .addAllRegisteredComponents(Collections.singletonList(registeredComponents)) + .addAllHttpEndpoints(Collections.singletonList(httpEndpoint)) .addAllSubscriptions(Collections.singletonList(pubsubSubscription)) + .setAppConnectionProperties(appConnectionProperties) .build(); + doAnswer((Answer) invocation -> { StreamObserver observer = (StreamObserver) invocation .getArguments()[1]; @@ -2115,19 +2134,47 @@ public void getMetadataTest() { Mono result = client.getMetadata(); DaprMetadata metadata = result.block(); + assertNotNull(metadata); assertEquals("app", metadata.getId()); assertEquals("1.1x.x", metadata.getRuntimeVersion()); + assertEquals(0, metadata.getEnabledFeatures().size()); + assertEquals(0, metadata.getAttributes().size()); + + // Components assertEquals(1, metadata.getComponents().size()); assertEquals(registeredComponents.getName(), metadata.getComponents().get(0).getName()); assertEquals(registeredComponents.getVersion(), metadata.getComponents().get(0).getVersion()); assertEquals(registeredComponents.getType(), metadata.getComponents().get(0).getType()); + + // Subscriptions assertEquals(1, metadata.getSubscriptions().size()); assertEquals(pubsubSubscription.getPubsubName(), metadata.getSubscriptions().get(0).getPubsubname()); assertEquals(pubsubSubscription.getTopic(), metadata.getSubscriptions().get(0).getTopic()); + + // Subscription Rules assertEquals(1, metadata.getSubscriptions().get(0).getRules().size()); assertEquals(pubsubSubscription.getRules().getRules(0).getPath(), metadata.getSubscriptions().get(0).getRules().get(0).getPath()); + // HTTP Endpoints + assertEquals(1, metadata.getHttpEndpoints().size()); + assertEquals(httpEndpoint.getName(), metadata.getHttpEndpoints().get(0).getName()); + + // App Connection Properties + AppConnectionPropertiesMetadata appConnectionPropertiesMetadata = metadata.getAppConnectionProperties(); + + assertEquals(appConnectionProperties.getPort(), appConnectionPropertiesMetadata.getPort()); + assertEquals(appConnectionProperties.getProtocol(), appConnectionPropertiesMetadata.getProtocol()); + assertEquals(appConnectionProperties.getChannelAddress(), appConnectionPropertiesMetadata.getChannelAddress()); + assertEquals(appConnectionProperties.getMaxConcurrency(), appConnectionPropertiesMetadata.getMaxConcurrency()); + + // App Connection Health Properties + AppConnectionPropertiesHealthMetadata healthMetadata = appConnectionPropertiesMetadata.getHealth(); + + assertEquals(healthProperties.getHealthCheckPath(), healthMetadata.getHealthCheckPath()); + assertEquals(healthProperties.getHealthProbeInterval(), healthMetadata.getHealthProbeInterval()); + assertEquals(healthProperties.getHealthProbeTimeout(), healthMetadata.getHealthProbeTimeout()); + assertEquals(healthProperties.getHealthThreshold(), healthMetadata.getHealthThreshold()); } @Test