Skip to content
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

Implement Models API Part #1 #14533

Merged
merged 15 commits into from
Aug 31, 2020
47 changes: 18 additions & 29 deletions sdk/digitaltwins/azure-digitaltwins-core/API design.md
Original file line number Diff line number Diff line change
Expand Up @@ -1178,44 +1178,41 @@ Async APIs
/**
* 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
* @return A {@link PagedFlux} of created models and the http response.
*/
@ServiceMethod(returns = ReturnType.COLLECTION)
public Mono<List<ModelData>> createModels(List<String> 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<Response<List<ModelData>>> createModelsWithResponse(List<String> models) { }
public PagedFlux<ModelData> createModels(List<String> models) { }
azabbasi marked this conversation as resolved.
Show resolved Hide resolved

/**
* Gets a model, including the model metadata and the model definition.
* @param modelId The Id of the model.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unique Identifier?

* @return The application/json model
* @return The ModelData
*/
@ServiceMethod(returns = ReturnType.SINGLE)
public Mono<ModelData> getModel(String modelId) { }

/**
* Gets a model, including the model metadata and the model definition asynchronously.
* @param modelId The Id of the model.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here as above and other places

* @return A REST response containing the model.
* @return The ModelData and the http response
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have seen the format of "The Http response containing modelData"
We can decide one and use the same everywhere.

*/
@ServiceMethod(returns = ReturnType.SINGLE)
public Mono<Response<ModelData>> 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.
* @return A {@link PagedFlux} of ModelData and the http response.
*/
@ServiceMethod(returns = ReturnType.COLLECTION)
public PagedFlux<ModelData> listModels(List<String> dependenciesFor, boolean includeModelDefinition, DigitalTwinModelsListOptions options) { }
public PagedFlux<ModelData> listModels() { }

/**
* 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<ModelData> listModels(ListModelOptions listModelOptions) { }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here, with response?


/**
* Deletes a model.
Expand Down Expand Up @@ -1254,18 +1251,10 @@ Sync APIs
/**
* 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<ModelData> createModels(List<String> 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.
* @return A {@link PagedIterable} of created ModelData.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add a comment about context too?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will only update the actual implementation from now on

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is part 2 suppose to contain?
Decommision and rest of it?

Decommission APIs and the Samples and tests.

*/
@ServiceMethod(returns = ReturnType.COLLECTION)
public Response<List<ModelData>> createModelsWithResponse(List<String> models, Context context) { }
public PagedIterable<ModelData> createModels(Iterable<String> models, Context context) { }

/**
* Gets a model, including the model metadata and the model definition.
Expand All @@ -1291,7 +1280,7 @@ Sync APIs
* @return A {@link PagedIterable} of ModelData.
*/
@ServiceMethod(returns = ReturnType.COLLECTION)
public PagedIterable<ModelData> listModels(List<String> dependenciesFor, boolean includeModelDefinition, DigitalTwinModelsListOptions options, Context context) { }
public PagedIterable<ModelData> listModels(Iterable<String> dependenciesFor, boolean includeModelDefinition, DigitalTwinModelsListOptions options, Context context) { }

/**
* Deletes a model.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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");
Expand Down Expand Up @@ -228,4 +234,149 @@ Mono<PagedResponse<String>> listRelationshipsNextSinglePageAsync(String nextLink
});
}


//==================================================================================================================================================
azabbasi marked this conversation as resolved.
Show resolved Hide resolved
// 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<ModelData> createModels(List<String> models) {
azabbasi marked this conversation as resolved.
Show resolved Hide resolved
return new PagedFlux<>(
() -> withContext(context -> createModelsSinglePageAsync(models, context)),
nextLink -> withContext(context -> Mono.empty()));
}

PagedFlux<ModelData> createModels(List<String> models, Context context){
return new PagedFlux<>(
() -> createModelsSinglePageAsync(models, context),
nextLink -> Mono.empty());
}

Mono<PagedResponse<ModelData>> createModelsSinglePageAsync(List<String> models, Context context)
{
List<Object> 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<ModelData> 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<Response<ModelData>> getModelWithResponse(String modelId) {
return withContext(context -> getModelWithResponse(modelId, context));
}

Mono<Response<ModelData>> 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<ModelData> 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<ModelData> listModels() {
return listModels(new ListModelOptions());
}

PagedFlux<ModelData> listModels(Context context){
return new PagedFlux<>(
() -> listModelsSinglePageAsync(new ListModelOptions(), context),
nextLink -> listModelsNextSinglePageAsync(nextLink, context));
}

PagedFlux<ModelData> listModels(ListModelOptions listModelOptions, Context context){
return new PagedFlux<>(
() -> listModelsSinglePageAsync(listModelOptions, context),
nextLink -> listModelsNextSinglePageAsync(nextLink, context));
}

Mono<PagedResponse<ModelData>> listModelsSinglePageAsync(ListModelOptions listModelOptions, Context context){
return protocolLayer.getDigitalTwinModels().listSinglePageAsync(
listModelOptions.getDependenciesFor(),
listModelOptions.getIncludeModelDefinition(),
new DigitalTwinModelsListOptions().setMaxItemCount(listModelOptions.getMaxItemCount()),
context);
}

Mono<PagedResponse<ModelData>> 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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we even need to mention this return?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, we will get doc verification errors.

*/
@ServiceMethod(returns = ReturnType.SINGLE)
public Mono<Void> 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<Response<Void>> deleteModelWithResponse(String modelId) {
return withContext(context -> deleteModelWithResponse(modelId, context));
}

Mono<Response<Void>> deleteModelWithResponse(String modelId, Context context){
return protocolLayer.getDigitalTwinModels().deleteWithResponseAsync(modelId, context);
}

//TODO: Decommission Model APIs (waiting for Abhipsa's change to come in)
}
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -80,4 +88,84 @@ public Response<String> createRelationshipWithResponse(String digitalTwinId, Str
public PagedIterable<String> 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<ModelData> createModels(List<String> 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<ModelData> 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<ModelData> 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<ModelData> 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<Void> deleteModelWithResponse(String modelId, Context context) {
return digitalTwinsAsyncClient.deleteModelWithResponse(modelId, context).block();
}

//TODO: Decommission Model APIs (waiting for Abhipsa's change to come in)
}
Loading