diff --git a/sdk/digitaltwins/azure-digitaltwins-core/API design.md b/sdk/digitaltwins/azure-digitaltwins-core/API design.md index 1ae87eee05c0..1e9b645702ea 100644 --- a/sdk/digitaltwins/azure-digitaltwins-core/API design.md +++ b/sdk/digitaltwins/azure-digitaltwins-core/API design.md @@ -1175,63 +1175,7 @@ When updating a model, the payload for a multi-operation json patch follows the Async APIs ```java - /** - * Creates one or many models. - * @param models The list of models to create. Each string corresponds to exactly one model. - * @return The list of created models - */ - @ServiceMethod(returns = ReturnType.COLLECTION) - public Mono> createModels(List models) { } - - /** - * Creates one or many models. - * @param models The list of models to create. Each string corresponds to exactly one model. - * @return A REST response containing the list of created models. - */ - @ServiceMethod(returns = ReturnType.COLLECTION) - public Mono>> createModelsWithResponse(List models) { } - - /** - * Gets a model, including the model metadata and the model definition. - * @param modelId The Id of the model. - * @return The application/json model - */ - @ServiceMethod(returns = ReturnType.SINGLE) - public Mono getModel(String modelId) { } - - /** - * Gets a model, including the model metadata and the model definition asynchronously. - * @param modelId The Id of the model. - * @return A REST response containing the model. - */ - @ServiceMethod(returns = ReturnType.SINGLE) - public Mono> getModelWithResponse(String modelId) { } - - /** - * Gets the list of models by iterating through a collection. - * @param dependenciesFor The model Ids to have dependencies retrieved. - * @param includeModelDefinition Whether to include the model definition in the result. If false, only the model metadata will be returned. - * @param options The options to follow when listing the models. For example, the page size hint can be specified. - * @return A {@link PagedFlux} of ModelData. - */ - @ServiceMethod(returns = ReturnType.COLLECTION) - public PagedFlux listModels(List dependenciesFor, boolean includeModelDefinition, DigitalTwinModelsListOptions options) { } - - /** - * Deletes a model. - * @param modelId The id for the model. The id is globally unique and case sensitive. - */ - @ServiceMethod(returns = ReturnType.SINGLE) - public Mono deleteModel(String modelId) { } - - /** - * Deletes a model. - * @param modelId The id for the model. The id is globally unique and case sensitive. - * @return The http response. - */ - @ServiceMethod(returns = ReturnType.SINGLE) - public Mono deleteModelWithResponse(String modelId) { } - + /** * Decommissions a model. * @param modelId The Id of the model to decommission. @@ -1252,61 +1196,6 @@ Async APIs Sync APIs ```java /** - * Creates one or many models. - * @param models The list of models to create. Each string corresponds to exactly one model. - * @return The list of created models - */ - @ServiceMethod(returns = ReturnType.COLLECTION) - public List createModels(List models) { } - - /** - * Creates one or many models. - * @param models The list of models to create. Each string corresponds to exactly one model. - * @return A REST response containing the list of created models. - */ - @ServiceMethod(returns = ReturnType.COLLECTION) - public Response> createModelsWithResponse(List models, Context context) { } - - /** - * Gets a model, including the model metadata and the model definition. - * @param modelId The Id of the model. - * @return The application/json model - */ - @ServiceMethod(returns = ReturnType.SINGLE) - public ModelData getModel(String modelId) { } - - /** - * Gets a model, including the model metadata and the model definition. - * @param modelId The Id of the model. - * @return A REST response containing the model. - */ - @ServiceMethod(returns = ReturnType.SINGLE) - public Response getModelWithResponse(String modelId, Context context) { } - - /** - * Gets the list of models by iterating through a collection. - * @param dependenciesFor The model Ids to have dependencies retrieved. - * @param includeModelDefinition Whether to include the model definition in the result. If false, only the model metadata will be returned. - * @param options The options to follow when listing the models. For example, the page size hint can be specified. - * @return A {@link PagedIterable} of ModelData. - */ - @ServiceMethod(returns = ReturnType.COLLECTION) - public PagedIterable listModels(List dependenciesFor, boolean includeModelDefinition, DigitalTwinModelsListOptions options, Context context) { } - - /** - * Deletes a model. - * @param modelId The id for the model. The id is globally unique and case sensitive. - */ - @ServiceMethod(returns = ReturnType.SINGLE) - public Mono deleteModel(String modelId) { } - - /** - * Deletes a model. - * @param modelId The id for the model. The id is globally unique and case sensitive. - * @return The http response. - */ - @ServiceMethod(returns = ReturnType.SINGLE) - public Response deleteModelWithResponse(String modelId, Context context) { } /** * Decommissions a model. @@ -1318,6 +1207,7 @@ Sync APIs /** * Decommissions a model. * @param modelId The Id of the model to decommission. + * @param context Additional context that is passed through the Http pipeline during the service call. * @return The http response. */ @ServiceMethod(returns = ReturnType.SINGLE) diff --git a/sdk/digitaltwins/azure-digitaltwins-core/src/main/java/com/azure/digitaltwins/core/DigitalTwinsAsyncClient.java b/sdk/digitaltwins/azure-digitaltwins-core/src/main/java/com/azure/digitaltwins/core/DigitalTwinsAsyncClient.java index 6b24eeda5dfc..13b9120310c5 100644 --- a/sdk/digitaltwins/azure-digitaltwins-core/src/main/java/com/azure/digitaltwins/core/DigitalTwinsAsyncClient.java +++ b/sdk/digitaltwins/azure-digitaltwins-core/src/main/java/com/azure/digitaltwins/core/DigitalTwinsAsyncClient.java @@ -13,14 +13,19 @@ import com.azure.core.util.serializer.JacksonAdapter; import com.azure.digitaltwins.core.implementation.AzureDigitalTwinsAPIImpl; import com.azure.digitaltwins.core.implementation.AzureDigitalTwinsAPIImplBuilder; +import com.azure.digitaltwins.core.implementation.models.DigitalTwinModelsListOptions; +import com.azure.digitaltwins.core.models.ModelData; import com.azure.digitaltwins.core.util.DigitalTwinsResponse; import com.azure.digitaltwins.core.util.DigitalTwinsResponseHeaders; import com.azure.digitaltwins.core.implementation.serializer.DigitalTwinsStringSerializer; +import com.azure.digitaltwins.core.util.ListModelOptions; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.module.SimpleModule; +import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; +import java.util.ArrayList; import java.util.List; import java.util.Objects; import java.util.function.Function; @@ -48,6 +53,7 @@ public final class DigitalTwinsAsyncClient { private static final ObjectMapper mapper = new ObjectMapper(); private final DigitalTwinsServiceVersion serviceVersion; private final AzureDigitalTwinsAPIImpl protocolLayer; + private static final Boolean includeModelDefinition = true; DigitalTwinsAsyncClient(HttpPipeline pipeline, DigitalTwinsServiceVersion serviceVersion, String host) { final SimpleModule stringModule = new SimpleModule("String Serializer"); @@ -228,4 +234,149 @@ Mono> listRelationshipsNextSinglePageAsync(String nextLink }); } + + //================================================================================================================================================== + // Models APIs + //================================================================================================================================================== + + /** + * Creates one or many models. + * @param models The list of models to create. Each string corresponds to exactly one model. + * @return A {@link PagedFlux} of created models and the http response. + */ + @ServiceMethod(returns = ReturnType.COLLECTION) + public PagedFlux createModels(List models) { + return new PagedFlux<>( + () -> withContext(context -> createModelsSinglePageAsync(models, context)), + nextLink -> withContext(context -> Mono.empty())); + } + + PagedFlux createModels(List models, Context context){ + return new PagedFlux<>( + () -> createModelsSinglePageAsync(models, context), + nextLink -> Mono.empty()); + } + + Mono> createModelsSinglePageAsync(List models, Context context) + { + List modelsPayload = new ArrayList<>(); + for (String model: models) { + try { + modelsPayload.add(mapper.readValue(model, Object.class)); + } + catch (JsonProcessingException e) { + logger.error("Could not parse the model payload [%s]: %s", model, e); + return Mono.error(e); + } + } + + return protocolLayer.getDigitalTwinModels().addWithResponseAsync(modelsPayload, context) + .map( + listResponse -> new PagedResponseBase<>( + listResponse.getRequest(), + listResponse.getStatusCode(), + listResponse.getHeaders(), + listResponse.getValue(), + null, + ((ResponseBase)listResponse).getDeserializedHeaders())); + } + + /** + * Gets a model, including the model metadata and the model definition. + * @param modelId The Id of the model. + * @return The ModelData + */ + @ServiceMethod(returns = ReturnType.SINGLE) + public Mono getModel(String modelId) { + return withContext(context -> getModelWithResponse(modelId, context)) + .flatMap(response -> Mono.just(response.getValue())); + } + + /** + * Gets a model, including the model metadata and the model definition. + * @param modelId The Id of the model. + * @return The ModelData and the http response + */ + @ServiceMethod(returns = ReturnType.SINGLE) + public Mono> getModelWithResponse(String modelId) { + return withContext(context -> getModelWithResponse(modelId, context)); + } + + Mono> getModelWithResponse(String modelId, Context context){ + return protocolLayer + .getDigitalTwinModels() + .getByIdWithResponseAsync(modelId, includeModelDefinition, context); + } + + /** + * Gets the list of models by iterating through a collection. + * @param listModelOptions The options to follow when listing the models. For example, the page size hint can be specified. + * @return A {@link PagedFlux} of ModelData and the http response. + */ + @ServiceMethod(returns = ReturnType.COLLECTION) + public PagedFlux listModels(ListModelOptions listModelOptions) { + return new PagedFlux<>( + () -> withContext(context -> listModelsSinglePageAsync(listModelOptions, context)), + nextLink -> withContext(context -> listModelsNextSinglePageAsync(nextLink, context))); + } + + /** + * Gets the list of models by iterating through a collection. + * @return A {@link PagedFlux} of ModelData and the http response. + */ + @ServiceMethod(returns = ReturnType.COLLECTION) + public PagedFlux listModels() { + return listModels(new ListModelOptions()); + } + + PagedFlux listModels(Context context){ + return new PagedFlux<>( + () -> listModelsSinglePageAsync(new ListModelOptions(), context), + nextLink -> listModelsNextSinglePageAsync(nextLink, context)); + } + + PagedFlux listModels(ListModelOptions listModelOptions, Context context){ + return new PagedFlux<>( + () -> listModelsSinglePageAsync(listModelOptions, context), + nextLink -> listModelsNextSinglePageAsync(nextLink, context)); + } + + Mono> listModelsSinglePageAsync(ListModelOptions listModelOptions, Context context){ + return protocolLayer.getDigitalTwinModels().listSinglePageAsync( + listModelOptions.getDependenciesFor(), + listModelOptions.getIncludeModelDefinition(), + new DigitalTwinModelsListOptions().setMaxItemCount(listModelOptions.getMaxItemCount()), + context); + } + + Mono> listModelsNextSinglePageAsync(String nextLink, Context context){ + return protocolLayer.getDigitalTwinModels().listNextSinglePageAsync(nextLink, context); + } + + /** + * Deletes a model. + * @param modelId The Id for the model. The Id is globally unique and case sensitive. + * @return An empty Mono + */ + @ServiceMethod(returns = ReturnType.SINGLE) + public Mono deleteModel(String modelId) { + return withContext(context -> deleteModelWithResponse(modelId, context)) + .flatMap(response -> Mono.just(response.getValue())); + } + + /** + * Deletes a model. + * @param modelId The Id for the model. The Id is globally unique and case sensitive. + * @return The http response. + */ + @ServiceMethod(returns = ReturnType.SINGLE) + public Mono> deleteModelWithResponse(String modelId) { + return withContext(context -> deleteModelWithResponse(modelId, context)); + } + + Mono> deleteModelWithResponse(String modelId, Context context){ + return protocolLayer.getDigitalTwinModels().deleteWithResponseAsync(modelId, context); + } + + //TODO: Decommission Model APIs (waiting for Abhipsa's change to come in) } diff --git a/sdk/digitaltwins/azure-digitaltwins-core/src/main/java/com/azure/digitaltwins/core/DigitalTwinsClient.java b/sdk/digitaltwins/azure-digitaltwins-core/src/main/java/com/azure/digitaltwins/core/DigitalTwinsClient.java index 496cd1844e76..9aff8f0b8407 100644 --- a/sdk/digitaltwins/azure-digitaltwins-core/src/main/java/com/azure/digitaltwins/core/DigitalTwinsClient.java +++ b/sdk/digitaltwins/azure-digitaltwins-core/src/main/java/com/azure/digitaltwins/core/DigitalTwinsClient.java @@ -7,10 +7,18 @@ import com.azure.core.annotation.ServiceClient; import com.azure.core.annotation.ServiceMethod; import com.azure.core.http.HttpPipeline; -import com.azure.core.http.rest.PagedIterable; -import com.azure.core.http.rest.Response; +import com.azure.core.http.rest.*; import com.azure.core.util.Context; +import com.azure.digitaltwins.core.implementation.models.DigitalTwinModelsListOptions; +import com.azure.digitaltwins.core.models.ModelData; +import com.azure.digitaltwins.core.util.ListModelOptions; import com.fasterxml.jackson.core.JsonProcessingException; +import reactor.core.publisher.Mono; + +import java.util.ArrayList; +import java.util.List; + +import static com.azure.core.util.FluxUtil.withContext; /** * This class provides a client for interacting synchronously with an Azure Digital Twins instance. @@ -80,4 +88,84 @@ public Response createRelationshipWithResponse(String digitalTwinId, Str public PagedIterable listRelationships(String digitalTwinId, String relationshipName, Context context) { return new PagedIterable<>(digitalTwinsAsyncClient.listRelationships(digitalTwinId, relationshipName, context)); } + + //================================================================================================================================================== + // Models APIs + //================================================================================================================================================== + + /** + * Creates one or many models. + * @param models The list of models to create. Each string corresponds to exactly one model. + * @param context Additional context that is passed through the Http pipeline during the service call. + * @return A {@link PagedIterable} of created models and the http response. + */ + @ServiceMethod(returns = ReturnType.COLLECTION) + public PagedIterable createModels(List models, Context context) { + return new PagedIterable<>(digitalTwinsAsyncClient.createModels(models, context)); + } + + /** + * Gets a model, including the model metadata and the model definition. + * @param modelId The Id of the model. + * @return The ModelData + */ + @ServiceMethod(returns = ReturnType.SINGLE) + public ModelData getModel(String modelId) { + return digitalTwinsAsyncClient.getModel(modelId).block(); + } + + /** + * Gets a model, including the model metadata and the model definition. + * @param modelId The Id of the model. + * @param context Additional context that is passed through the Http pipeline during the service call. + * @return The ModelData and the http response + */ + @ServiceMethod(returns = ReturnType.SINGLE) + public Response getModelWithResponse(String modelId, Context context) { + return digitalTwinsAsyncClient.getModelWithResponse(modelId, context).block(); + } + + /** + * Gets the list of models by iterating through a collection. + * @param listModelOptions The options to follow when listing the models. For example, the page size hint can be specified. + * @param context Additional context that is passed through the Http pipeline during the service call. + * @return A {@link PagedIterable} of ModelData and the http response. + */ + @ServiceMethod(returns = ReturnType.COLLECTION) + public PagedIterable listModels(ListModelOptions listModelOptions, Context context) { + return new PagedIterable<>( + digitalTwinsAsyncClient.listModels(listModelOptions, context)); + } + + /** + * Gets the list of models by iterating through a collection. + * @return A {@link PagedFlux} of ModelData and the http response. + */ + @ServiceMethod(returns = ReturnType.COLLECTION) + public PagedIterable listModels() { + return new PagedIterable<>(digitalTwinsAsyncClient.listModels()); + } + + /** + * Deletes a model. + * @param modelId The Id for the model. The Id is globally unique and case sensitive. + * @return Void + */ + @ServiceMethod(returns = ReturnType.SINGLE) + public Void deleteModel(String modelId) { + return digitalTwinsAsyncClient.deleteModel(modelId).block(); + } + + /** + * Deletes a model. + * @param modelId The Id for the model. The Id is globally unique and case sensitive. + * @param context Additional context that is passed through the Http pipeline during the service call. + * @return The http response. + */ + @ServiceMethod(returns = ReturnType.SINGLE) + public Response deleteModelWithResponse(String modelId, Context context) { + return digitalTwinsAsyncClient.deleteModelWithResponse(modelId, context).block(); + } + + //TODO: Decommission Model APIs (waiting for Abhipsa's change to come in) } diff --git a/sdk/digitaltwins/azure-digitaltwins-core/src/main/java/com/azure/digitaltwins/core/util/ListModelOptions.java b/sdk/digitaltwins/azure-digitaltwins-core/src/main/java/com/azure/digitaltwins/core/util/ListModelOptions.java new file mode 100644 index 000000000000..e63131a3e433 --- /dev/null +++ b/sdk/digitaltwins/azure-digitaltwins-core/src/main/java/com/azure/digitaltwins/core/util/ListModelOptions.java @@ -0,0 +1,81 @@ +package com.azure.digitaltwins.core.util; + +import com.azure.core.annotation.Fluent; + +import java.util.List; + +@Fluent +public final class ListModelOptions { + + /* + * The maximum number of items to retrieve per request. The server may + * choose to return less than the requested max. + */ + private Integer maxItemCount; + + /** + * Get the maxItemCount property. + * + * @return the maxItemCount value. + */ + public Integer getMaxItemCount() { + return this.maxItemCount; + } + + /** + * Set the maxItemCount property. + * + * @param maxItemCount the maxItemCount value to set. + * @return the ListModelOptions object itself. + */ + public ListModelOptions setMaxItemCount(Integer maxItemCount) { + this.maxItemCount = maxItemCount; + return this; + } + + /* + * Whether to include the model definition in the result. If false, only the model metadata will be returned. + */ + private Boolean includeModelDefinition; + + /** + * Get the includeModelDefinition property. + * + * @return the includeModelDefinition value. + */ + public Boolean getIncludeModelDefinition() { return this.includeModelDefinition; } + + /** + * Set the includeModelDefinition property. + * + * @param includeModelDefinition the includeModelDefinition value to set. + * @return the ListModelOptions object itself. + */ + public ListModelOptions setIncludeModelDefinition(Boolean includeModelDefinition) { + this.includeModelDefinition = includeModelDefinition; + return this; + } + + /* + * The model Ids to have dependencies retrieved. + */ + private List dependenciesFor; + + /** + * Get the dependenciesFor property. + * + * @return the dependenciesFor value. + */ + public List getDependenciesFor() { return this.dependenciesFor; } + + /** + * Set the dependenciesFor property. + * + * @param dependenciesFor the dependenciesFor value to set. + * @return the ListModelOptions object itself. + */ + public ListModelOptions setDependenciesFor(List dependenciesFor) { + this.dependenciesFor = dependenciesFor; + return this; + } +}