예제 #1
0
        public async Task Component_Lifecycle()
        {
            // arrange

            DigitalTwinsClient client = GetClient();

            string wifiModelId = await GetUniqueModelIdAsync(client, TestAssetSettings.WifiModelIdPrefix).ConfigureAwait(false);

            string roomWithWifiModelId = await GetUniqueModelIdAsync(client, TestAssetSettings.RoomWithWifiModelIdPrefix).ConfigureAwait(false);

            string roomWithWifiTwinId = await GetUniqueTwinIdAsync(client, TestAssetSettings.RoomWithWifiTwinIdPrefix).ConfigureAwait(false);

            string wifiComponentName = "wifiAccessPoint";

            try
            {
                // CREATE

                // create roomWithWifi model
                string wifiModel = TestAssetsHelper.GetWifiModelPayload(wifiModelId);

                // create wifi model
                string roomWithWifiModel = TestAssetsHelper.GetRoomWithWifiModelPayload(roomWithWifiModelId, wifiModelId, wifiComponentName);

                await client.CreateModelsAsync(new List <string> {
                    roomWithWifiModel, wifiModel
                }).ConfigureAwait(false);

                // create room digital twin
                string roomWithWifiTwin = TestAssetsHelper.GetRoomWithWifiTwinPayload(roomWithWifiModelId, wifiModelId, wifiComponentName);

                await client.CreateDigitalTwinAsync(roomWithWifiTwinId, roomWithWifiTwin);

                // Get the component
                Response <string> getComponentResponse = await client
                                                         .GetComponentAsync(
                    roomWithWifiTwinId,
                    wifiComponentName)
                                                         .ConfigureAwait(false);

                // The response to the GET request should be 200 (OK)
                getComponentResponse.GetRawResponse().Status.Should().Be((int)HttpStatusCode.OK);

                // Patch component
                Response <string> updateComponentResponse = await client
                                                            .UpdateComponentAsync(
                    roomWithWifiTwinId,
                    wifiComponentName,
                    TestAssetsHelper.GetWifiComponentUpdatePayload())
                                                            .ConfigureAwait(false);

                // The response to the Patch request should be 204 (No content)
                updateComponentResponse.GetRawResponse().Status.Should().Be((int)HttpStatusCode.NoContent);
            }
            finally
            {
                // clean up
                try
                {
                    if (!string.IsNullOrWhiteSpace(roomWithWifiTwinId))
                    {
                        await client.DeleteDigitalTwinAsync(roomWithWifiTwinId).ConfigureAwait(false);
                    }
                    if (!string.IsNullOrWhiteSpace(roomWithWifiModelId))
                    {
                        await client.DeleteModelAsync(roomWithWifiModelId).ConfigureAwait(false);
                    }
                    if (!string.IsNullOrWhiteSpace(wifiModelId))
                    {
                        await client.DeleteModelAsync(wifiModelId).ConfigureAwait(false);
                    }
                }
                catch (Exception ex)
                {
                    Assert.Fail($"Test clean up failed: {ex.Message}");
                }
            }
        }
예제 #2
0
        /// <summary>
        /// Creates a digital twin with Component and upates Component
        /// </summary>
        public async Task RunSamplesAsync(DigitalTwinsClient client)
        {
            PrintHeader("COMPONENT SAMPLE");

            // For the purpose of this example we will create temporary models using a random model Ids.
            // We have to make sure these model Ids are unique within the DT instance.

            string componentModelId = await GetUniqueModelIdAsync(SamplesConstants.TemporaryComponentModelPrefix, client);

            string modelId = await GetUniqueModelIdAsync(SamplesConstants.TemporaryModelPrefix, client);

            string basicDtId = await GetUniqueTwinIdAsync(SamplesConstants.TemporaryTwinPrefix, client);

            string newComponentModelPayload = SamplesConstants.TemporaryComponentModelPayload
                                              .Replace(SamplesConstants.ComponentId, componentModelId);

            string newModelPayload = SamplesConstants.TemporaryModelWithComponentPayload
                                     .Replace(SamplesConstants.ModelId, modelId)
                                     .Replace(SamplesConstants.ComponentId, componentModelId);

            // Then we create models
            await client.CreateModelsAsync(
                new[]
            {
                newComponentModelPayload,
                newModelPayload
            });

            Console.WriteLine($"Created models {componentModelId} and {modelId}.");

            #region Snippet:DigitalTwinsSampleCreateBasicTwin

            // Create digital twin with component payload using the BasicDigitalTwin serialization helper

            var basicTwin = new BasicDigitalTwin
            {
                Id = basicDtId,
                // model Id of digital twin
                Metadata = { ModelId = modelId },
                Contents =
                {
                    // digital twin properties
                    { "Prop1",          "Value1"            },
                    { "Prop2",                          987 },
                    // component
                    {
                        "Component1",
                        new BasicDigitalTwinComponent
                        {
                            // component properties
                            Contents =
                            {
                                { "ComponentProp1", "Component value 1" },
                                { "ComponentProp2",                 123 },
                            },
                        }
                    },
                },
            };

            Response <BasicDigitalTwin> createDigitalTwinResponse = await client.CreateOrReplaceDigitalTwinAsync(basicDtId, basicTwin);

            Console.WriteLine($"Created digital twin '{createDigitalTwinResponse.Value.Id}'.");

            #endregion Snippet:DigitalTwinsSampleCreateBasicTwin

            // You can also get a digital twin as a BasicDigitalTwin type.
            // It works well for basic stuff, but as you can see it gets more difficult when delving into
            // more complex properties, like components.

            #region Snippet:DigitalTwinsSampleGetBasicDigitalTwin

            Response <BasicDigitalTwin> getBasicDtResponse = await client.GetDigitalTwinAsync <BasicDigitalTwin>(basicDtId);

            if (getBasicDtResponse.GetRawResponse().Status == (int)HttpStatusCode.OK)
            {
                BasicDigitalTwin basicDt = getBasicDtResponse.Value;

                // Must cast Component1 as a JsonElement and get its raw text in order to deserialize it as a dictionary
                string component1RawText = ((JsonElement)basicDt.Contents["Component1"]).GetRawText();
                IDictionary <string, object> component1 = JsonSerializer.Deserialize <IDictionary <string, object> >(component1RawText);

                Console.WriteLine($"Retrieved and deserialized digital twin {basicDt.Id}:\n\t" +
                                  $"ETag: {basicDt.ETag}\n\t" +
                                  $"Prop1: {basicDt.Contents["Prop1"]}\n\t" +
                                  $"Prop2: {basicDt.Contents["Prop2"]}\n\t" +
                                  $"ComponentProp1: {component1["ComponentProp1"]}\n\t" +
                                  $"ComponentProp2: {component1["ComponentProp2"]}");
            }

            #endregion Snippet:DigitalTwinsSampleGetBasicDigitalTwin

            string customDtId = await GetUniqueTwinIdAsync(SamplesConstants.TemporaryTwinPrefix, client);

            // Alternatively, you can create your own custom data types to serialize and deserialize your digital twins.
            // By specifying your properties and types directly, it requires less code or knowledge of the type for
            // interaction.

            #region Snippet:DigitalTwinsSampleCreateCustomTwin

            var customTwin = new CustomDigitalTwin
            {
                Id         = customDtId,
                Metadata   = { ModelId = modelId },
                Prop1      = "Prop1 val",
                Prop2      = 987,
                Component1 = new MyCustomComponent
                {
                    ComponentProp1 = "Component prop1 val",
                    ComponentProp2 = 123,
                },
            };
            Response <CustomDigitalTwin> createCustomDigitalTwinResponse = await client.CreateOrReplaceDigitalTwinAsync(customDtId, customTwin);

            Console.WriteLine($"Created digital twin '{createCustomDigitalTwinResponse.Value.Id}'.");

            #endregion Snippet:DigitalTwinsSampleCreateCustomTwin

            // Getting a digital twin as a custom data type is extremely easy.
            // Custom types provide the best possible experience.

            #region Snippet:DigitalTwinsSampleGetCustomDigitalTwin

            Response <CustomDigitalTwin> getCustomDtResponse = await client.GetDigitalTwinAsync <CustomDigitalTwin>(customDtId);

            CustomDigitalTwin customDt = getCustomDtResponse.Value;
            Console.WriteLine($"Retrieved and deserialized digital twin {customDt.Id}:\n\t" +
                              $"ETag: {customDt.ETag}\n\t" +
                              $"Prop1: {customDt.Prop1}\n\t" +
                              $"Prop2: {customDt.Prop2}\n\t" +
                              $"ComponentProp1: {customDt.Component1.ComponentProp1}\n\t" +
                              $"ComponentProp2: {customDt.Component1.ComponentProp2}");

            #endregion Snippet:DigitalTwinsSampleGetCustomDigitalTwin

            #region Snippet:DigitalTwinsSampleUpdateComponent

            // Update Component1 by replacing the property ComponentProp1 value,
            // using an optional utility to build the payload.
            var componentJsonPatchDocument = new JsonPatchDocument();
            componentJsonPatchDocument.AppendReplace("/ComponentProp1", "Some new value");
            await client.UpdateComponentAsync(basicDtId, "Component1", componentJsonPatchDocument);

            Console.WriteLine($"Updated component for digital twin '{basicDtId}'.");

            #endregion Snippet:DigitalTwinsSampleUpdateComponent

            // Get Component

            #region Snippet:DigitalTwinsSampleGetComponent

            await client.GetComponentAsync <MyCustomComponent>(basicDtId, SamplesConstants.ComponentName);

            Console.WriteLine($"Retrieved component for digital twin '{basicDtId}'.");

            #endregion Snippet:DigitalTwinsSampleGetComponent

            // Clean up

            try
            {
                await client.DeleteDigitalTwinAsync(basicDtId);

                await client.DeleteDigitalTwinAsync(customDtId);
            }
            catch (RequestFailedException ex)
            {
                Console.WriteLine($"Failed to delete digital twin due to {ex}");
            }

            try
            {
                await client.DeleteModelAsync(modelId);

                await client.DeleteModelAsync(componentModelId);
            }
            catch (RequestFailedException ex)
            {
                Console.WriteLine($"Failed to delete models due to {ex}");
            }
        }
예제 #3
0
        public async Task Component_Lifecycle()
        {
            // arrange

            DigitalTwinsClient client = GetClient();

            string wifiModelId = await GetUniqueModelIdAsync(client, TestAssetDefaults.WifiModelIdPrefix).ConfigureAwait(false);

            string roomWithWifiModelId = await GetUniqueModelIdAsync(client, TestAssetDefaults.RoomWithWifiModelIdPrefix).ConfigureAwait(false);

            string roomWithWifiTwinId = await GetUniqueTwinIdAsync(client, TestAssetDefaults.RoomWithWifiTwinIdPrefix).ConfigureAwait(false);

            string wifiComponentName = "wifiAccessPoint";

            try
            {
                // CREATE

                // create roomWithWifi model
                string wifiModel = TestAssetsHelper.GetWifiModelPayload(wifiModelId);

                // create wifi model
                string roomWithWifiModel = TestAssetsHelper.GetRoomWithWifiModelPayload(roomWithWifiModelId, wifiModelId, wifiComponentName);

                await CreateAndListModelsAsync(client, new List <string> {
                    roomWithWifiModel, wifiModel
                }).ConfigureAwait(false);

                // create room digital twin
                BasicDigitalTwin roomWithWifiTwin = TestAssetsHelper.GetRoomWithWifiTwinPayload(roomWithWifiModelId, wifiComponentName);
                await client.CreateOrReplaceDigitalTwinAsync <BasicDigitalTwin>(roomWithWifiTwinId, roomWithWifiTwin);

                // Get the component
                Response <object> getComponentResponse = await client
                                                         .GetComponentAsync <object>(
                    roomWithWifiTwinId,
                    wifiComponentName)
                                                         .ConfigureAwait(false);

                // The response to the GET request should be 200 (OK)
                getComponentResponse.GetRawResponse().Status.Should().Be((int)HttpStatusCode.OK);

                // Patch component
                JsonPatchDocument componentUpdatePatchDocument = new JsonPatchDocument();
                componentUpdatePatchDocument.AppendReplace("/Network", "New Network");

                Response updateComponentResponse = await client
                                                   .UpdateComponentAsync(
                    roomWithWifiTwinId,
                    wifiComponentName,
                    componentUpdatePatchDocument)
                                                   .ConfigureAwait(false);

                // The response to the Patch request should be 204 (No content)
                updateComponentResponse.Status.Should().Be((int)HttpStatusCode.NoContent);
            }
            catch (Exception ex)
            {
                Assert.Fail($"Failure in executing a step in the test case: {ex.Message}.");
            }
            finally
            {
                // clean up
                try
                {
                    if (!string.IsNullOrWhiteSpace(roomWithWifiTwinId))
                    {
                        await client.DeleteDigitalTwinAsync(roomWithWifiTwinId).ConfigureAwait(false);
                    }
                    if (!string.IsNullOrWhiteSpace(roomWithWifiModelId))
                    {
                        await client.DeleteModelAsync(roomWithWifiModelId).ConfigureAwait(false);
                    }
                    if (!string.IsNullOrWhiteSpace(wifiModelId))
                    {
                        await client.DeleteModelAsync(wifiModelId).ConfigureAwait(false);
                    }
                }
                catch (Exception ex)
                {
                    Assert.Fail($"Test clean up failed: {ex.Message}");
                }
            }
        }
예제 #4
0
        public async Task Component_UpdateComponentSucceedsWhenIfMatchHeaderIsCorrect()
        {
            // arrange

            DigitalTwinsClient client = GetClient();

            string wifiModelId = await GetUniqueModelIdAsync(client, TestAssetDefaults.WifiModelIdPrefix).ConfigureAwait(false);

            string roomWithWifiModelId = await GetUniqueModelIdAsync(client, TestAssetDefaults.RoomWithWifiModelIdPrefix).ConfigureAwait(false);

            string roomWithWifiTwinId = await GetUniqueTwinIdAsync(client, TestAssetDefaults.RoomWithWifiTwinIdPrefix).ConfigureAwait(false);

            string wifiComponentName = "wifiAccessPoint";

            try
            {
                // CREATE

                // create roomWithWifi model
                string wifiModel = TestAssetsHelper.GetWifiModelPayload(wifiModelId);

                // create wifi model
                string roomWithWifiModel = TestAssetsHelper.GetRoomWithWifiModelPayload(roomWithWifiModelId, wifiModelId, wifiComponentName);

                await client.CreateModelsAsync(new List <string> {
                    roomWithWifiModel, wifiModel
                }).ConfigureAwait(false);

                // create room digital twin
                BasicDigitalTwin roomWithWifiTwin = TestAssetsHelper.GetRoomWithWifiTwinPayload(roomWithWifiModelId, wifiComponentName);
                await client.CreateOrReplaceDigitalTwinAsync <BasicDigitalTwin>(roomWithWifiTwinId, roomWithWifiTwin);

                // Get the component
                Response <object> getComponentResponse = await client
                                                         .GetComponentAsync <object>(
                    roomWithWifiTwinId,
                    wifiComponentName)
                                                         .ConfigureAwait(false);

                // Patch component
                JsonPatchDocument componentUpdatePatchDocument = new JsonPatchDocument();
                componentUpdatePatchDocument.AppendReplace("/Network", "New Network");

                Response updateComponentResponse = await client
                                                   .UpdateComponentAsync(
                    roomWithWifiTwinId,
                    wifiComponentName,
                    componentUpdatePatchDocument)
                                                   .ConfigureAwait(false);

                // Get the latest ETag
                ETag?etagBeforeUpdate = (await client.GetDigitalTwinAsync <BasicDigitalTwin>(roomWithWifiTwinId)).Value.ETag;
                Assert.IsNotNull(etagBeforeUpdate);

                // Patch component again, but with the now out of date ETag
                JsonPatchDocument secondComponentUpdatePatchDocument = new JsonPatchDocument();
                componentUpdatePatchDocument.AppendReplace("/Network", "Even newer Network");

                try
                {
                    await client
                    .UpdateComponentAsync(
                        roomWithWifiTwinId,
                        wifiComponentName,
                        secondComponentUpdatePatchDocument,
                        etagBeforeUpdate)
                    .ConfigureAwait(false);
                }
                catch (RequestFailedException ex) when(ex.Status == (int)HttpStatusCode.PreconditionFailed)
                {
                    throw new AssertionException("UpdateComponent should not have thrown PreconditionFailed because the ETag was up to date", ex);
                }
            }
            finally
            {
                // clean up
                try
                {
                    if (!string.IsNullOrWhiteSpace(roomWithWifiTwinId))
                    {
                        await client.DeleteDigitalTwinAsync(roomWithWifiTwinId).ConfigureAwait(false);
                    }
                    if (!string.IsNullOrWhiteSpace(roomWithWifiModelId))
                    {
                        await client.DeleteModelAsync(roomWithWifiModelId).ConfigureAwait(false);
                    }
                    if (!string.IsNullOrWhiteSpace(wifiModelId))
                    {
                        await client.DeleteModelAsync(wifiModelId).ConfigureAwait(false);
                    }
                }
                catch (Exception ex)
                {
                    Assert.Fail($"Test clean up failed: {ex.Message}");
                }
            }
        }
예제 #5
0
        public async Task Component_UpdateComponentFailsWhenIfMatchHeaderOutOfDate()
        {
            // arrange

            DigitalTwinsClient client = GetClient();

            string wifiModelId = await GetUniqueModelIdAsync(client, TestAssetDefaults.WifiModelIdPrefix).ConfigureAwait(false);

            string roomWithWifiModelId = await GetUniqueModelIdAsync(client, TestAssetDefaults.RoomWithWifiModelIdPrefix).ConfigureAwait(false);

            string roomWithWifiTwinId = await GetUniqueTwinIdAsync(client, TestAssetDefaults.RoomWithWifiTwinIdPrefix).ConfigureAwait(false);

            string wifiComponentName = "wifiAccessPoint";

            try
            {
                // CREATE

                // create roomWithWifi model
                string wifiModel = TestAssetsHelper.GetWifiModelPayload(wifiModelId);

                // create wifi model
                string roomWithWifiModel = TestAssetsHelper.GetRoomWithWifiModelPayload(roomWithWifiModelId, wifiModelId, wifiComponentName);

                await CreateAndListModelsAsync(client, new List <string> {
                    roomWithWifiModel, wifiModel
                }).ConfigureAwait(false);

                // create room digital twin
                BasicDigitalTwin roomWithWifiTwin = TestAssetsHelper.GetRoomWithWifiTwinPayload(roomWithWifiModelId, wifiComponentName);
                await client.CreateOrReplaceDigitalTwinAsync <BasicDigitalTwin>(roomWithWifiTwinId, roomWithWifiTwin);

                // Get the component
                Response <object> getComponentResponse = await client
                                                         .GetComponentAsync <object>(
                    roomWithWifiTwinId,
                    wifiComponentName)
                                                         .ConfigureAwait(false);

                ETag?etagBeforeUpdate = (await client.GetDigitalTwinAsync <BasicDigitalTwin>(roomWithWifiTwinId)).Value.ETag;

                // Patch component
                JsonPatchDocument componentUpdatePatchDocument = new JsonPatchDocument();
                componentUpdatePatchDocument.AppendReplace("/Network", "New Network");

                Response updateComponentResponse = await client
                                                   .UpdateComponentAsync(
                    roomWithWifiTwinId,
                    wifiComponentName,
                    componentUpdatePatchDocument)
                                                   .ConfigureAwait(false);

                // Patch component again, but with the now out of date ETag
                JsonPatchDocument secondComponentUpdatePatchDocument = new JsonPatchDocument();
                secondComponentUpdatePatchDocument.AppendReplace("/Network", "Even newer Network");

                Func <Task> act = async() =>
                {
                    await client
                    .UpdateComponentAsync(
                        roomWithWifiTwinId,
                        wifiComponentName,
                        secondComponentUpdatePatchDocument,
                        etagBeforeUpdate)
                    .ConfigureAwait(false);
                };

                act.Should().Throw <RequestFailedException>()
                .And.Status.Should().Be((int)HttpStatusCode.PreconditionFailed);
            }
            catch (Exception ex)
            {
                Assert.Fail($"Failure in executing a step in the test case: {ex.Message}.");
            }
            finally
            {
                // clean up
                try
                {
                    if (!string.IsNullOrWhiteSpace(roomWithWifiTwinId))
                    {
                        await client.DeleteDigitalTwinAsync(roomWithWifiTwinId).ConfigureAwait(false);
                    }
                    if (!string.IsNullOrWhiteSpace(roomWithWifiModelId))
                    {
                        await client.DeleteModelAsync(roomWithWifiModelId).ConfigureAwait(false);
                    }
                    if (!string.IsNullOrWhiteSpace(wifiModelId))
                    {
                        await client.DeleteModelAsync(wifiModelId).ConfigureAwait(false);
                    }
                }
                catch (Exception ex)
                {
                    Assert.Fail($"Test clean up failed: {ex.Message}");
                }
            }
        }