├── .editorconfig
├── README.md
├── docs
└── media
│ └── docs-link-buttons
│ ├── azure-documentation.svg
│ ├── azure-how-to-guide.svg
│ ├── azure-quickstart.svg
│ └── azure-tutorial.svg
├── helpers
└── ColorConsoleLogger
│ ├── ColorConsoleLogger.cs
│ ├── ColorConsoleLogger.csproj
│ ├── ColorConsoleLoggerConfiguration.cs
│ ├── ColorConsoleLoggerExtensions.cs
│ ├── ColorConsoleLoggerProvider.cs
│ └── ConsoleEventListener.cs
├── horizontal-arm
├── arm-read-write.sln
├── arm-read-write
│ ├── Program.cs
│ └── arm-read-write.csproj
├── arm-template
│ └── template_iothub.json
└── testenvvars_SET.cmd
├── iot-hub
├── Quickstarts
│ ├── InvokeDeviceMethod
│ │ └── readme.md
│ ├── ReadD2cMessages
│ │ └── README.md
│ ├── SimulatedDevice
│ │ └── readme.md
│ └── SimulatedDeviceWithCommand
│ │ └── readme.md
├── Samples
│ ├── device
│ │ ├── DeviceReconnectionSample
│ │ │ └── readme.md
│ │ ├── FileUploadSample
│ │ │ └── readme.md
│ │ ├── MessageReceiveSample
│ │ │ └── readme.md
│ │ ├── MethodSample
│ │ │ └── readme.md
│ │ ├── PnpDeviceSamples
│ │ │ └── readme.md
│ │ ├── TwinSample
│ │ │ └── readme.md
│ │ ├── X509DeviceCertWithChainSample
│ │ │ └── readme.md
│ │ └── XamarinSample
│ │ │ └── readme.md
│ ├── module
│ │ └── ModuleSample
│ │ │ └── readme.md
│ └── service
│ │ ├── AutomaticDeviceManagementSample
│ │ └── readme.md
│ │ ├── AzureSasCredentialAuthenticationSample
│ │ └── readme.md
│ │ ├── CleanupDevicesSample
│ │ └── readme.md
│ │ ├── DigitalTwinClientSamples
│ │ └── readme.md
│ │ ├── EdgeDeploymentSample
│ │ └── readme.md
│ │ ├── FileUploadNotificationReceiverSample
│ │ └── readme.md
│ │ ├── ImportExportDevicesSample
│ │ └── readme.md
│ │ ├── ImportExportDevicesWithManagedIdentitySample
│ │ └── readme.md
│ │ ├── JobsSample
│ │ └── readme.md
│ │ ├── PnpServiceSamples
│ │ └── readme.md
│ │ ├── RegistryManagerSample
│ │ └── readme.md
│ │ ├── RoleBasedAuthenticationSample
│ │ └── readme.md
│ │ └── ServiceClientSample
│ │ └── readme.md
└── Tutorials
│ └── Routing
│ ├── IoT_SimulatedDevice.sln
│ └── SimulatedDevice
│ ├── Parameters.cs
│ ├── Program.cs
│ ├── SimulatedDevice.csproj
│ └── resources
│ ├── iothub_msgenrichment_cli.azcli
│ ├── iothub_routing_cli.azcli
│ ├── iothub_routing_psh.ps1
│ ├── template_iothub.json
│ ├── template_iothub_parameters.json
│ └── template_messageenrichments.json
├── nuget.config
├── provisioning
└── Samples
│ ├── device
│ ├── ComputeDerivedSymmetricKeySample
│ │ └── readme.md
│ ├── SymmetricKeySample
│ │ └── readme.md
│ ├── TpmSample
│ │ └── readme.md
│ ├── X509Sample
│ │ └── readme.md
│ └── readme.md
│ └── service
│ ├── BulkOperationSample
│ └── readme.md
│ ├── CleanupEnrollmentsSample
│ └── readme.md
│ ├── EnrollmentGroupSample
│ └── readme.md
│ ├── EnrollmentSample
│ └── readme.md
│ └── GroupCertificateVerificationSample
│ └── readme.md
└── vsts
├── CredScanSuppressions.json
└── vsts.yaml
/.editorconfig:
--------------------------------------------------------------------------------
1 | # Remove the line below if you want to inherit .editorconfig settings from higher directories
2 | root = true
3 |
4 | # C# files
5 | [*.cs]
6 |
7 | #### Core EditorConfig Options ####
8 |
9 | # Indentation and spacing
10 | indent_size = 4
11 | indent_style = space
12 | tab_width = 4
13 |
14 | # New line preferences
15 | end_of_line = crlf
16 | insert_final_newline = false
17 |
18 | #### .NET Coding Conventions ####
19 |
20 | # Organize usings
21 | dotnet_separate_import_directive_groups = false
22 | dotnet_sort_system_directives_first = true
23 |
24 | # this. and Me. preferences
25 | dotnet_style_qualification_for_event = false:suggestion
26 | dotnet_style_qualification_for_field = false:suggestion
27 | dotnet_style_qualification_for_method = false:suggestion
28 | dotnet_style_qualification_for_property = false:suggestion
29 |
30 | # Language keywords vs BCL types preferences
31 | dotnet_style_predefined_type_for_locals_parameters_members = true:suggestion
32 | dotnet_style_predefined_type_for_member_access = true:suggestion
33 |
34 | # Parentheses preferences
35 | dotnet_style_parentheses_in_arithmetic_binary_operators = never_if_unnecessary:suggestion
36 | dotnet_style_parentheses_in_other_binary_operators = never_if_unnecessary:suggestion
37 | dotnet_style_parentheses_in_other_operators = never_if_unnecessary:suggestion
38 | dotnet_style_parentheses_in_relational_binary_operators = never_if_unnecessary:suggestion
39 |
40 | # Modifier preferences
41 | dotnet_style_require_accessibility_modifiers = for_non_interface_members:suggestion
42 |
43 | # Expression-level preferences
44 | dotnet_style_coalesce_expression = true:suggestion
45 | dotnet_style_collection_initializer = true:suggestion
46 | dotnet_style_explicit_tuple_names = true:suggestion
47 | dotnet_style_null_propagation = true:suggestion
48 | dotnet_style_object_initializer = true:suggestion
49 | dotnet_style_prefer_auto_properties = true:suggestion
50 | dotnet_style_prefer_compound_assignment = true:suggestion
51 | dotnet_style_prefer_conditional_expression_over_assignment = true:suggestion
52 | dotnet_style_prefer_conditional_expression_over_return = true:suggestion
53 | dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion
54 | dotnet_style_prefer_inferred_tuple_names = true:suggestion
55 | dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion
56 |
57 | # Field preferences
58 | dotnet_style_readonly_field = true:suggestion
59 |
60 | # Parameter preferences
61 | dotnet_code_quality_unused_parameters = all:suggestion
62 |
63 | #### C# Coding Conventions ####
64 |
65 | # var preferences
66 | csharp_style_var_elsewhere = false:suggestion
67 | csharp_style_var_for_built_in_types = false:suggestion
68 | csharp_style_var_when_type_is_apparent = true:suggestion
69 |
70 | # Expression-bodied members
71 | csharp_style_expression_bodied_accessors = true:suggestion
72 | csharp_style_expression_bodied_constructors = false:silent
73 | csharp_style_expression_bodied_indexers = true:silent
74 | csharp_style_expression_bodied_lambdas = true:silent
75 | csharp_style_expression_bodied_local_functions = false:silent
76 | csharp_style_expression_bodied_methods = false:silent
77 | csharp_style_expression_bodied_operators = false:silent
78 | csharp_style_expression_bodied_properties = true:suggestion
79 |
80 | # Pattern matching preferences
81 | csharp_style_pattern_matching_over_as_with_null_check = true:suggestion
82 | csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion
83 | csharp_style_prefer_switch_expression = true:suggestion
84 |
85 | # Null-checking preferences
86 | csharp_style_conditional_delegate_call = true:suggestion
87 |
88 | # Modifier preferences
89 | csharp_prefer_static_local_function = true:suggestion
90 | csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async
91 |
92 | # Code-block preferences
93 | csharp_prefer_braces = true:suggestion
94 | csharp_prefer_simple_using_statement = true:suggestion
95 |
96 | # Expression-level preferences
97 | csharp_prefer_simple_default_expression = true:suggestion
98 | csharp_style_deconstructed_variable_declaration = true:suggestion
99 | csharp_style_inlined_variable_declaration = true:suggestion
100 | csharp_style_pattern_local_over_anonymous_function = true:suggestion
101 | csharp_style_prefer_index_operator = true:suggestion
102 | csharp_style_prefer_range_operator = true:suggestion
103 | csharp_style_throw_expression = true:suggestion
104 | csharp_style_unused_value_assignment_preference = discard_variable:suggestion
105 | csharp_style_unused_value_expression_statement_preference = discard_variable:silent
106 |
107 | # 'using' directive preferences
108 | csharp_using_directive_placement = outside_namespace:suggestion
109 |
110 | #### C# Formatting Rules ####
111 |
112 | # New line preferences
113 | csharp_new_line_before_catch = true
114 | csharp_new_line_before_else = true
115 | csharp_new_line_before_finally = true
116 | csharp_new_line_before_members_in_anonymous_types = true
117 | csharp_new_line_before_members_in_object_initializers = true
118 | csharp_new_line_before_open_brace = all
119 | csharp_new_line_between_query_expression_clauses = true
120 |
121 | # Indentation preferences
122 | csharp_indent_block_contents = true
123 | csharp_indent_braces = false
124 | csharp_indent_case_contents = true
125 | csharp_indent_case_contents_when_block = true
126 | csharp_indent_labels = flush_left
127 | csharp_indent_switch_labels = true
128 |
129 | # Space preferences
130 | csharp_space_after_cast = false
131 | csharp_space_after_colon_in_inheritance_clause = true
132 | csharp_space_after_comma = true
133 | csharp_space_after_dot = false
134 | csharp_space_after_keywords_in_control_flow_statements = true
135 | csharp_space_after_semicolon_in_for_statement = true
136 | csharp_space_around_binary_operators = before_and_after
137 | csharp_space_around_declaration_statements = false
138 | csharp_space_before_colon_in_inheritance_clause = true
139 | csharp_space_before_comma = false
140 | csharp_space_before_dot = false
141 | csharp_space_before_open_square_brackets = false
142 | csharp_space_before_semicolon_in_for_statement = false
143 | csharp_space_between_empty_square_brackets = false
144 | csharp_space_between_method_call_empty_parameter_list_parentheses = false
145 | csharp_space_between_method_call_name_and_opening_parenthesis = false
146 | csharp_space_between_method_call_parameter_list_parentheses = false
147 | csharp_space_between_method_declaration_empty_parameter_list_parentheses = false
148 | csharp_space_between_method_declaration_name_and_open_parenthesis = false
149 | csharp_space_between_method_declaration_parameter_list_parentheses = false
150 | csharp_space_between_parentheses = false
151 | csharp_space_between_square_brackets = false
152 |
153 | # Wrapping preferences
154 | csharp_preserve_single_line_blocks = true
155 | csharp_preserve_single_line_statements = true
156 |
157 | #### Naming styles ####
158 |
159 | # Naming rules
160 |
161 | dotnet_naming_rule.interface_should_be_begins_with_i.severity = suggestion
162 | dotnet_naming_rule.interface_should_be_begins_with_i.symbols = interface
163 | dotnet_naming_rule.interface_should_be_begins_with_i.style = begins_with_i
164 |
165 | dotnet_naming_rule.types_should_be_pascal_case.severity = suggestion
166 | dotnet_naming_rule.types_should_be_pascal_case.symbols = types
167 | dotnet_naming_rule.types_should_be_pascal_case.style = non_private_static_field_style
168 |
169 | dotnet_naming_rule.non_field_members_should_be_pascal_case.severity = suggestion
170 | dotnet_naming_rule.non_field_members_should_be_pascal_case.symbols = non_field_members
171 | dotnet_naming_rule.non_field_members_should_be_pascal_case.style = non_private_static_field_style
172 |
173 | dotnet_naming_rule.public_members_must_be_capitalized.symbols = public_symbols
174 | dotnet_naming_symbols.public_symbols.applicable_kinds = property,method,field,event,delegate
175 | dotnet_naming_symbols.public_symbols.applicable_accessibilities = public
176 | dotnet_naming_symbols.public_symbols.required_modifiers = readonly
177 | dotnet_naming_rule.public_members_must_be_capitalized.style = first_word_upper_case_style
178 | dotnet_naming_style.first_word_upper_case_style.capitalization = first_word_upper
179 |
180 | dotnet_naming_rule.public_members_must_be_capitalized.severity = suggestion
181 |
182 | # Non-private static fields are PascalCase
183 | dotnet_naming_rule.non_private_static_fields_should_be_pascal_case.severity = suggestion
184 | dotnet_naming_rule.non_private_static_fields_should_be_pascal_case.symbols = non_private_static_fields
185 | dotnet_naming_rule.non_private_static_fields_should_be_pascal_case.style = non_private_static_field_style
186 |
187 | dotnet_naming_symbols.non_private_static_fields.applicable_kinds = field
188 | dotnet_naming_symbols.non_private_static_fields.applicable_accessibilities = public, protected, internal, protected_internal, private_protected
189 | dotnet_naming_symbols.non_private_static_fields.required_modifiers = static
190 |
191 | dotnet_naming_style.non_private_static_field_style.capitalization = pascal_case
192 |
193 | # Non-private readonly fields are PascalCase
194 | dotnet_naming_rule.non_private_readonly_fields_should_be_pascal_case.severity = suggestion
195 | dotnet_naming_rule.non_private_readonly_fields_should_be_pascal_case.symbols = non_private_readonly_fields
196 | dotnet_naming_rule.non_private_readonly_fields_should_be_pascal_case.style = non_private_static_field_style
197 |
198 | dotnet_naming_symbols.non_private_readonly_fields.applicable_kinds = field
199 | dotnet_naming_symbols.non_private_readonly_fields.applicable_accessibilities = public, protected, internal, protected_internal, private_protected
200 | dotnet_naming_symbols.non_private_readonly_fields.required_modifiers = readonly
201 |
202 | dotnet_naming_style.non_private_readonly_field_style.capitalization = pascal_case
203 |
204 | # Constants are PascalCase
205 | dotnet_naming_rule.constants_should_be_pascal_case.severity = suggestion
206 | dotnet_naming_rule.constants_should_be_pascal_case.symbols = constants
207 | dotnet_naming_rule.constants_should_be_pascal_case.style = non_private_static_field_style
208 |
209 | dotnet_naming_symbols.constants.applicable_kinds = field
210 | dotnet_naming_symbols.constants.required_modifiers = const
211 |
212 | dotnet_naming_style.constant_style.capitalization = pascal_case
213 |
214 | # Static fields are camelCase and start with s_
215 | dotnet_naming_rule.static_fields_should_be_camel_case.severity = suggestion
216 | dotnet_naming_rule.static_fields_should_be_camel_case.symbols = static_fields
217 | dotnet_naming_rule.static_fields_should_be_camel_case.style = static_field_style
218 |
219 | dotnet_naming_symbols.static_fields.applicable_kinds = field
220 | dotnet_naming_symbols.static_fields.required_modifiers = static
221 |
222 | dotnet_naming_style.static_field_style.capitalization = camel_case
223 | dotnet_naming_style.static_field_style.required_prefix = s_
224 |
225 | # Instance fields are camelCase and start with _
226 | dotnet_naming_rule.instance_fields_should_be_camel_case.severity = suggestion
227 | dotnet_naming_rule.instance_fields_should_be_camel_case.symbols = instance_fields
228 | dotnet_naming_rule.instance_fields_should_be_camel_case.style = instance_field_style
229 |
230 | dotnet_naming_symbols.instance_fields.applicable_kinds = field
231 |
232 | dotnet_naming_style.instance_field_style.capitalization = camel_case
233 | dotnet_naming_style.instance_field_style.required_prefix = _
234 |
235 | # Locals and parameters are camelCase
236 | dotnet_naming_rule.locals_should_be_camel_case.severity = suggestion
237 | dotnet_naming_rule.locals_should_be_camel_case.symbols = locals_and_parameters
238 | dotnet_naming_rule.locals_should_be_camel_case.style = camel_case_style
239 |
240 | dotnet_naming_symbols.locals_and_parameters.applicable_kinds = parameter, local
241 |
242 | dotnet_naming_style.camel_case_style.capitalization = camel_case
243 |
244 | # Local functions are PascalCase
245 | dotnet_naming_rule.local_functions_should_be_pascal_case.severity = suggestion
246 | dotnet_naming_rule.local_functions_should_be_pascal_case.symbols = local_functions
247 | dotnet_naming_rule.local_functions_should_be_pascal_case.style = non_private_static_field_style
248 |
249 | dotnet_naming_symbols.local_functions.applicable_kinds = local_function
250 |
251 | dotnet_naming_style.local_function_style.capitalization = pascal_case
252 |
253 | # By default, name items with PascalCase
254 | dotnet_naming_rule.members_should_be_pascal_case.severity = suggestion
255 | dotnet_naming_rule.members_should_be_pascal_case.symbols = all_members
256 | dotnet_naming_rule.members_should_be_pascal_case.style = non_private_static_field_style
257 |
258 | dotnet_naming_symbols.all_members.applicable_kinds = *
259 |
260 | dotnet_naming_style.pascal_case_style.capitalization = pascal_case
261 |
262 | # Symbol specifications
263 |
264 | dotnet_naming_symbols.interface.applicable_kinds = interface
265 | dotnet_naming_symbols.interface.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
266 | dotnet_naming_symbols.interface.required_modifiers =
267 |
268 | dotnet_naming_symbols.types.applicable_kinds = class, struct, interface, enum
269 | dotnet_naming_symbols.types.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
270 | dotnet_naming_symbols.types.required_modifiers =
271 |
272 | dotnet_naming_symbols.non_field_members.applicable_kinds = property, event, method
273 | dotnet_naming_symbols.non_field_members.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
274 | dotnet_naming_symbols.non_field_members.required_modifiers =
275 |
276 | # Naming styles
277 |
278 | dotnet_naming_style.pascal_case.required_prefix =
279 | dotnet_naming_style.pascal_case.required_suffix =
280 | dotnet_naming_style.pascal_case.word_separator =
281 | dotnet_naming_style.pascal_case.capitalization = pascal_case
282 |
283 | dotnet_naming_style.begins_with_i.required_prefix = I
284 | dotnet_naming_style.begins_with_i.required_suffix =
285 | dotnet_naming_style.begins_with_i.word_separator =
286 | dotnet_naming_style.begins_with_i.capitalization = pascal_case
287 |
288 | # Async methods should have "Async" suffix
289 | dotnet_naming_rule.async_methods_end_in_async.symbols = any_async_methods
290 | dotnet_naming_rule.async_methods_end_in_async.style = end_in_async
291 | dotnet_naming_rule.async_methods_end_in_async.severity = suggestion
292 |
293 | dotnet_naming_symbols.any_async_methods.applicable_kinds = method
294 | dotnet_naming_symbols.any_async_methods.applicable_accessibilities = *
295 | dotnet_naming_symbols.any_async_methods.required_modifiers = async
296 |
297 | dotnet_naming_style.end_in_async.required_prefix =
298 | dotnet_naming_style.end_in_async.required_suffix = Async
299 | dotnet_naming_style.end_in_async.capitalization = pascal_case
300 | dotnet_naming_style.end_in_async.word_separator =
301 |
302 | # Exclude extension method 'this' parameter
303 | #
304 | # For all methods the default behaivor of the analyzer is to check to see if any argument is being
305 | # used without a null check (this is good). However, for extension methods, this means that
306 | # the "this" argument to the extension method is checked alongside of the other arguments.
307 | #
308 | # This is not great behavior as an extension method should behave like an instance method and we should
309 | # allow a NullRefException be generated if we attempt to access the "this" object.
310 | #
311 | # This flag ignores all of the "this" arguments but still reports the others.
312 | dotnet_code_quality.CA1062.exclude_extension_method_this_parameter = true
313 |
314 |
315 | # All of these severity changes below were because of an upgrade to the 3.3.1 analyzers which turned them
316 | # from warnings to errors. As we fix these warnings we should remove these lines to allow the default behaivor
317 | # and break the build.
318 | # CA2016: Forward the 'CancellationToken' parameter to methods that take one
319 | dotnet_diagnostic.CA2016.severity = warning
320 | # CA1805: Do not initialize unnecessarily
321 | dotnet_diagnostic.CA1805.severity = warning
322 | # CA1834: Consider using 'StringBuilder.Append(char)' when applicable
323 | dotnet_diagnostic.CA1834.severity = warning
324 | # CA2000: Dispose objects before losing scope
325 | dotnet_diagnostic.CA2000.severity = warning
326 |
327 | # CA2208: Instantiate argument exceptions correctly
328 | # CA2208 is suggesting that the argument that is passed to ArgumentNullException should match a name of a parameter
329 | # in the signature of the method that is throwing the exception. However, many of the CA2208 warning instances is
330 | # because the code throws an ArgumentNullException while passing in a property (or a field) on the object that is
331 | # passed into the method that is throwing the exception. A proper fix for this would be to throw an ArgumentException
332 | # instead. However, many of these instances are of a public method. So changing the exception being thrown is a breaking change.
333 | dotnet_diagnostic.CA2208.severity = suggestion
334 | csharp_style_namespace_declarations = block_scoped:silent
335 | csharp_style_prefer_method_group_conversion = true:silent
336 | [*.{cs,vb}]
337 | dotnet_style_operator_placement_when_wrapping = beginning_of_line
338 | tab_width = 4
339 | indent_size = 4
340 | end_of_line = crlf
341 | dotnet_style_coalesce_expression = true:suggestion
342 | dotnet_style_null_propagation = true:suggestion
343 | dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion
344 | dotnet_style_prefer_auto_properties = true:suggestion
345 | dotnet_style_object_initializer = true:suggestion
346 | dotnet_style_collection_initializer = true:suggestion
347 | dotnet_style_prefer_simplified_boolean_expressions = true:suggestion
348 | dotnet_style_prefer_conditional_expression_over_assignment = true:suggestion
349 | dotnet_style_prefer_conditional_expression_over_return = true:suggestion
350 | dotnet_style_explicit_tuple_names = true:suggestion
351 | dotnet_style_prefer_inferred_tuple_names = true:suggestion
352 | dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion
353 | dotnet_style_prefer_compound_assignment = true:suggestion
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | #### All samples have been [moved](https://github.com/Azure/azure-iot-sdk-csharp#samples) to the main [Azure IoT SDK for C#](https://github.com/Azure/azure-iot-sdk-csharp) Repository
--------------------------------------------------------------------------------
/docs/media/docs-link-buttons/azure-documentation.svg:
--------------------------------------------------------------------------------
1 |
27 |
--------------------------------------------------------------------------------
/docs/media/docs-link-buttons/azure-how-to-guide.svg:
--------------------------------------------------------------------------------
1 |
25 |
--------------------------------------------------------------------------------
/docs/media/docs-link-buttons/azure-quickstart.svg:
--------------------------------------------------------------------------------
1 |
24 |
--------------------------------------------------------------------------------
/docs/media/docs-link-buttons/azure-tutorial.svg:
--------------------------------------------------------------------------------
1 |
22 |
--------------------------------------------------------------------------------
/helpers/ColorConsoleLogger/ColorConsoleLogger.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft. All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using Microsoft.Extensions.Logging;
5 | using System;
6 | using System.Globalization;
7 | using System.Linq;
8 |
9 | namespace Microsoft.Azure.Devices.Logging
10 | {
11 | ///
12 | /// The ILogger implementation for writing color log entries to console.
13 | /// For additional details, see https://docs.microsoft.com/en-us/dotnet/api/microsoft.extensions.logging.ilogger?view=dotnet-plat-ext-3.1.
14 | ///
15 | public class ColorConsoleLogger : ILogger
16 | {
17 | private readonly ColorConsoleLoggerConfiguration _config;
18 |
19 | ///
20 | /// Initializes an instance of .
21 | ///
22 | /// The settings to be used for logging.
23 | public ColorConsoleLogger(ColorConsoleLoggerConfiguration config)
24 | {
25 | _config = config;
26 | }
27 |
28 | ///
29 | /// Begin a group of logical operations.
30 | ///
31 | /// The type of the state to begin scope for.
32 | /// The identifier for the scope.
33 | public IDisposable BeginScope(TState state)
34 | {
35 | throw new NotImplementedException();
36 | }
37 |
38 | ///
39 | /// Checks if the given log level is enabled.
40 | ///
41 | /// The log level to be checked.
42 | public bool IsEnabled(LogLevel logLevel)
43 | {
44 | return logLevel >= _config.MinLogLevel;
45 | }
46 |
47 | ///
48 | /// Writes the log entry to console output.
49 | ///
50 | /// The type of the object to be written.
51 | /// The log level of the log entry to be written.
52 | /// The event Id of the log entry to be written.
53 | /// The log entry to be written.
54 | /// The exception related to the log entry.
55 | /// The formatter to be used for formatting the log message.
56 | public void Log(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func formatter)
57 | {
58 | if (!IsEnabled(logLevel))
59 | {
60 | return;
61 | }
62 |
63 | var color = _config.LogLevelToColorMapping[logLevel];
64 | if (_config.EventIds.Contains(ColorConsoleLoggerConfiguration.DefaultEventId) || _config.EventIds.Contains(eventId.Id))
65 | {
66 | ConsoleColor initialColor = Console.ForegroundColor;
67 |
68 | Console.ForegroundColor = ConsoleColor.Green;
69 | Console.Write($"{DateTime.Now.ToString("yyyy-MM-ddTHH:mm:ss.fffffff", CultureInfo.InvariantCulture)}>> ");
70 |
71 | Console.ForegroundColor = color;
72 | Console.WriteLine($"{logLevel} - {formatter(state, exception)}");
73 | Console.ForegroundColor = initialColor;
74 | }
75 | }
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/helpers/ColorConsoleLogger/ColorConsoleLogger.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netstandard2.0
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/helpers/ColorConsoleLogger/ColorConsoleLoggerConfiguration.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft. All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using Microsoft.Extensions.Logging;
5 | using System;
6 | using System.Collections.Generic;
7 |
8 | namespace Microsoft.Azure.Devices.Logging
9 | {
10 | ///
11 | /// A color console logger configuration that creates different color console entries per log level, sets the default log level to Information and logs all events.
12 | ///
13 | public class ColorConsoleLoggerConfiguration
14 | {
15 | // If the EventId is set to 0, the logger will log all events.
16 | internal const int DefaultEventId = 0;
17 |
18 | ///
19 | /// A dictionary containing the log level to console color mappings to be used while writing log entries to the console.
20 | ///
21 | public IReadOnlyDictionary LogLevelToColorMapping { get; } = new Dictionary
22 | {
23 | { LogLevel.Trace, ConsoleColor.Blue },
24 | { LogLevel.Debug, ConsoleColor.DarkYellow },
25 | { LogLevel.Information, ConsoleColor.Cyan },
26 | { LogLevel.Warning, ConsoleColor.DarkMagenta },
27 | { LogLevel.Error, ConsoleColor.Red },
28 | { LogLevel.Critical, ConsoleColor.DarkRed },
29 | };
30 |
31 | ///
32 | /// The min log level that will be written to the console, defaults to .
33 | ///
34 | public LogLevel MinLogLevel { get; set; } = LogLevel.Information;
35 |
36 | ///
37 | /// The list of event Ids to be written to the console. By default, all event Ids are written.
38 | ///
39 | public IEnumerable EventIds { get; } = new int[] { DefaultEventId };
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/helpers/ColorConsoleLogger/ColorConsoleLoggerExtensions.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft. All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using Microsoft.Extensions.Logging;
5 |
6 | namespace Microsoft.Azure.Devices.Logging
7 | {
8 | ///
9 | /// Extension methods to help simplify creation of a new instance.
10 | ///
11 | public static class ColorConsoleLoggerExtensions
12 | {
13 | ///
14 | /// Add a new instance, with the supplied settings.
15 | ///
16 | /// The type for which this extension method is defined.
17 | /// The settings to be used for logging.
18 | /// The instance.
19 | public static ILoggerFactory AddColorConsoleLogger(this ILoggerFactory loggerFactory, ColorConsoleLoggerConfiguration config)
20 | {
21 | loggerFactory.AddProvider(new ColorConsoleLoggerProvider(config));
22 | return loggerFactory;
23 | }
24 |
25 | ///
26 | /// Add a new instance, with the default settings.
27 | ///
28 | /// The type for which this extension method is defined.
29 | /// The instance.
30 | public static ILoggerFactory AddColorConsoleLogger(this ILoggerFactory loggerFactory)
31 | {
32 | var config = new ColorConsoleLoggerConfiguration();
33 | return loggerFactory.AddColorConsoleLogger(config);
34 | }
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/helpers/ColorConsoleLogger/ColorConsoleLoggerProvider.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft. All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using Microsoft.Extensions.Logging;
5 | using System.Collections.Concurrent;
6 |
7 | namespace Microsoft.Azure.Devices.Logging
8 | {
9 | ///
10 | /// The implementation that creates the instance.
11 | ///
12 | public class ColorConsoleLoggerProvider : ILoggerProvider
13 | {
14 | private readonly ColorConsoleLoggerConfiguration _config;
15 | private readonly ConcurrentDictionary _loggers = new ConcurrentDictionary();
16 |
17 | ///
18 | /// Initialize an instance of with the supplied .
19 | ///
20 | /// The settings to be used for logging.
21 | public ColorConsoleLoggerProvider(ColorConsoleLoggerConfiguration config)
22 | {
23 | _config = config;
24 | }
25 |
26 | ///
27 | /// Create a new instance.
28 | ///
29 | /// The category name for the instance. This is usually the class name where the logger is initialized.
30 | /// The created instance.
31 | public ILogger CreateLogger(string categoryName)
32 | {
33 | return _loggers.GetOrAdd(categoryName, name => new ColorConsoleLogger(_config));
34 | }
35 |
36 | ///
37 | /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
38 | ///
39 | public void Dispose()
40 | {
41 | _loggers.Clear();
42 | }
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/helpers/ColorConsoleLogger/ConsoleEventListener.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft. All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using Microsoft.Extensions.Logging;
5 | using System;
6 | using System.Diagnostics.Tracing;
7 | using System.Linq;
8 |
9 | namespace Microsoft.Azure.Devices.Logging
10 | {
11 | ///
12 | /// Prints SDK events to Console output - the log level is set to TRACE
13 | ///
14 | public sealed class ConsoleEventListener : EventListener
15 | {
16 | private readonly string[] _eventFilters;
17 | private readonly ILogger _logger;
18 | private readonly object _lock = new object();
19 |
20 | public ConsoleEventListener(string filter, ILogger logger)
21 | {
22 | _eventFilters = new string[1];
23 | _eventFilters[0] = filter ?? throw new ArgumentNullException(nameof(filter));
24 | _logger = logger;
25 |
26 | InitializeEventSources();
27 | }
28 |
29 | public ConsoleEventListener(string[] filters, ILogger logger)
30 | {
31 | _eventFilters = filters ?? throw new ArgumentNullException(nameof(filters));
32 | if (_eventFilters.Length == 0) throw new ArgumentException("Filters cannot be empty", nameof(filters));
33 |
34 | foreach (string filter in _eventFilters)
35 | {
36 | if (string.IsNullOrWhiteSpace(filter))
37 | {
38 | throw new ArgumentNullException(nameof(filters));
39 | }
40 | }
41 | _logger = logger;
42 |
43 | InitializeEventSources();
44 | }
45 |
46 | private void InitializeEventSources()
47 | {
48 | foreach (EventSource source in EventSource.GetSources())
49 | {
50 | EnableEvents(source, EventLevel.LogAlways);
51 | }
52 | }
53 |
54 | protected override void OnEventSourceCreated(EventSource eventSource)
55 | {
56 | base.OnEventSourceCreated(eventSource);
57 | EnableEvents(
58 | eventSource,
59 | EventLevel.LogAlways
60 | #if !NET451
61 | , EventKeywords.All
62 | #endif
63 | );
64 | }
65 |
66 | protected override void OnEventWritten(EventWrittenEventArgs eventData)
67 | {
68 | if (_eventFilters == null) return;
69 |
70 | lock (_lock)
71 | {
72 | if (_eventFilters.Any(ef => eventData.EventSource.Name.StartsWith(ef, StringComparison.Ordinal)))
73 | {
74 | string eventIdent;
75 | #if NET451
76 | // net451 doesn't have EventName, so we'll settle for EventId
77 | eventIdent = eventData.EventId.ToString(CultureInfo.InvariantCulture);
78 | #else
79 | eventIdent = eventData.EventName;
80 | #endif
81 | string text = $"[{eventData.EventSource.Name}-{eventIdent}]{(eventData.Payload != null ? $" ({string.Join(", ", eventData.Payload)})." : "")}";
82 | _logger.LogTrace(text);
83 | }
84 | }
85 | }
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/horizontal-arm/arm-read-write.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 15
4 | VisualStudioVersion = 15.0.28307.1169
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "arm-read-write", "arm-read-write\arm-read-write.csproj", "{C460F13E-C424-477B-90BD-E2BF7BCB063F}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|Any CPU = Debug|Any CPU
11 | Release|Any CPU = Release|Any CPU
12 | EndGlobalSection
13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
14 | {C460F13E-C424-477B-90BD-E2BF7BCB063F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
15 | {C460F13E-C424-477B-90BD-E2BF7BCB063F}.Debug|Any CPU.Build.0 = Debug|Any CPU
16 | {C460F13E-C424-477B-90BD-E2BF7BCB063F}.Release|Any CPU.ActiveCfg = Release|Any CPU
17 | {C460F13E-C424-477B-90BD-E2BF7BCB063F}.Release|Any CPU.Build.0 = Release|Any CPU
18 | EndGlobalSection
19 | GlobalSection(SolutionProperties) = preSolution
20 | HideSolutionNode = FALSE
21 | EndGlobalSection
22 | GlobalSection(ExtensibilityGlobals) = postSolution
23 | SolutionGuid = {3F87CEC5-340F-47ED-89D9-A746F4EBCA05}
24 | EndGlobalSection
25 | EndGlobal
26 |
--------------------------------------------------------------------------------
/horizontal-arm/arm-read-write/Program.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft. All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | //This code that messages to an IoT Hub for testing the routing as defined
5 | // in this article: https://docs.microsoft.com/en-us/azure/iot-hub/tutorial-routing
6 | //The scripts for creating the resources are included in the resources folder in this
7 | // Visual Studio solution.
8 |
9 | using Microsoft.Azure.Devices.Client;
10 | using Newtonsoft.Json;
11 | using System;
12 | using System.Text;
13 | using System.Threading;
14 | using System.Threading.Tasks;
15 |
16 | namespace arm_read_write
17 | {
18 | class Program
19 | {
20 | //This is the arm-read-write application that simulates a virtual device.
21 | //It writes messages to the IoT Hub, which routes the messages automatically to a storage account,
22 | //where you can view them.
23 |
24 | // This was derived by the (more complicated) tutorial for routing
25 | // https://docs.microsoft.com/en-us/azure/iot-hub/tutorial-routing
26 |
27 | private static DeviceClient s_deviceClient;
28 | private static string s_myDeviceId;
29 | private static string s_iotHubUri;
30 | private static string s_deviceKey;
31 |
32 | private static async Task Main()
33 | {
34 | if (!ReadEnvironmentVariables())
35 | {
36 | Console.WriteLine();
37 | Console.WriteLine("Error! One or more environment variables not set");
38 | return;
39 | }
40 |
41 | Console.WriteLine("write messages to a hub and use routing to write them to storage");
42 |
43 | s_deviceClient = DeviceClient.Create(s_iotHubUri,
44 | new DeviceAuthenticationWithRegistrySymmetricKey(s_myDeviceId, s_deviceKey), TransportType.Mqtt);
45 |
46 | var cts = new CancellationTokenSource();
47 |
48 | var messages = SendDeviceToCloudMessagesAsync(cts.Token);
49 |
50 | Console.WriteLine("Press the Enter key to stop.");
51 | Console.ReadLine();
52 | cts.Cancel();
53 | await messages;
54 | }
55 |
56 | ///
57 | /// Read local process environment variables for required values
58 | ///
59 | ///
60 | /// True if all required environment variables are set
61 | ///
62 | private static bool ReadEnvironmentVariables()
63 | {
64 | bool result = true;
65 |
66 | s_myDeviceId = Environment.GetEnvironmentVariable("IOT_DEVICE_ID");
67 | s_iotHubUri = Environment.GetEnvironmentVariable("IOT_HUB_URI");
68 | s_deviceKey = Environment.GetEnvironmentVariable("IOT_DEVICE_KEY");
69 |
70 | if ((s_myDeviceId is null) || (s_iotHubUri is null) || (s_deviceKey is null))
71 | {
72 | result = false;
73 | }
74 |
75 | return result;
76 | }
77 |
78 | ///
79 | /// Send message to the Iot hub. This generates the object to be sent to the hub in the message.
80 | ///
81 | private static async Task SendDeviceToCloudMessagesAsync(CancellationToken token)
82 | {
83 | double minTemperature = 20;
84 | double minHumidity = 60;
85 | Random rand = new Random();
86 |
87 | while (!token.IsCancellationRequested)
88 | {
89 |
90 | double currentTemperature = minTemperature + rand.NextDouble() * 15;
91 | double currentHumidity = minHumidity + rand.NextDouble() * 20;
92 |
93 | string infoString;
94 | string levelValue;
95 |
96 | if (rand.NextDouble() > 0.7)
97 | {
98 | if (rand.NextDouble() > 0.5)
99 | {
100 | levelValue = "critical";
101 | infoString = "This is a critical message.";
102 | }
103 | else
104 | {
105 | levelValue = "storage";
106 | infoString = "This is a storage message.";
107 | }
108 | }
109 | else
110 | {
111 | levelValue = "normal";
112 | infoString = "This is a normal message.";
113 | }
114 |
115 | var telemetryDataPoint = new
116 | {
117 | deviceId = s_myDeviceId,
118 | temperature = currentTemperature,
119 | humidity = currentHumidity,
120 | pointInfo = infoString
121 | };
122 | // serialize the telemetry data and convert it to JSON.
123 | var telemetryDataString = JsonConvert.SerializeObject(telemetryDataPoint);
124 |
125 | // Encode the serialized object using UTF-8 so it can be parsed by IoT Hub when
126 | // processing messaging rules.
127 | using var message = new Message(Encoding.UTF8.GetBytes(telemetryDataString))
128 | {
129 | ContentEncoding = "utf-8",
130 | ContentType = "application/json",
131 | };
132 |
133 | //Add one property to the message.
134 | message.Properties.Add("level", levelValue);
135 |
136 | // Submit the message to the hub.
137 | await s_deviceClient.SendEventAsync(message);
138 |
139 | // Print out the message.
140 | Console.WriteLine("{0} > Sent message: {1}", DateTime.Now, telemetryDataString);
141 |
142 | await Task.Delay(1000);
143 | }
144 | }
145 | }
146 | }
147 |
--------------------------------------------------------------------------------
/horizontal-arm/arm-read-write/arm-read-write.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net6.0
6 | arm_read_write
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/horizontal-arm/arm-template/template_iothub.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json",
3 | "contentVersion": "1.0.0.0",
4 | "parameters": {
5 | "randomValue": {
6 | "defaultValue": "[substring(uniqueString(utcNow()),0,8)]",
7 | "type": "string",
8 | "metadata": {
9 | "description": "Random alphanumeric string to make the assets have a unique name."
10 | }
11 | },
12 | "subscriptionId": {
13 | "type": "string",
14 | "defaultValue": "[subscription().subscriptionid]",
15 | "metadata": {
16 | "description": "The subscription ID of the Azure subscription to deploy into."
17 | }
18 | },
19 | "IoTHubName_in": {
20 | "type": "string",
21 | "defaultValue": "ContosoTestHub",
22 | "metadata": {
23 | "description": "The name of the IoT Hub to create."
24 | }
25 | },
26 | "location": {
27 | "type": "string",
28 | "defaultValue": "westus2",
29 | "metadata": {
30 | "description": "The datacenter to use for the deployment."
31 | }
32 | },
33 | "sku_name": {
34 | "type": "string",
35 | "defaultValue": "S1",
36 | "metadata": {
37 | "description": "The SKU to use for the IoT Hub."
38 | }
39 | },
40 | "sku_units": {
41 | "type": "string",
42 | "defaultValue": "1",
43 | "metadata": {
44 | "description": "The number of IoT Hub units."
45 | }
46 | },
47 | "d2c_partitions": {
48 | "type": "string",
49 | "defaultValue": "4",
50 | "metadata": {
51 | "description": "Partitions used for the event stream."
52 | }
53 | },
54 | "storageAccountName_in": {
55 | "type": "string",
56 | "defaultValue": "contosostorage",
57 | "metadata": {
58 | "description": "Name of storage account to be created."
59 | }
60 | },
61 | "storageContainerName": {
62 | "type": "string",
63 | "defaultValue": "contosoresults",
64 | "metadata": {
65 | "description": "Name of the container in which to place the routed data."
66 | }
67 | },
68 | "storage_endpoint": {
69 | "type": "string",
70 | "defaultValue": "ContosoStorageEndpoint",
71 | "metadata": {
72 | "description": "Name of the endpoint for the storage account."
73 | }
74 | }
75 | },
76 | "variables": {
77 | "iotHubName": "[concat(parameters('IotHubName_in'),parameters('randomValue'))]",
78 | "storageAccountName": "[concat(parameters('storageAccountName_in'),parameters('randomValue'))]"
79 | },
80 | "resources": [
81 | {
82 | "type": "Microsoft.Storage/storageAccounts",
83 | "name": "[variables('storageAccountName')]",
84 | "apiVersion": "2018-07-01",
85 | "location": "[parameters('location')]",
86 | "sku": {
87 | "name": "Standard_LRS",
88 | "tier": "Standard"
89 | },
90 | "kind": "Storage",
91 | "properties": {},
92 | "resources": [
93 | {
94 | "type": "blobServices/containers",
95 | "apiVersion": "2018-07-01",
96 | "name": "[concat('default/', parameters('storageContainerName'))]",
97 | "properties": {
98 | "publicAccess": "None"
99 | } ,
100 | "dependsOn": [
101 | "[resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName'))]"
102 | ]
103 | }
104 | ]
105 | },
106 | {
107 | "apiVersion": "2018-04-01",
108 | "type": "Microsoft.Devices/IotHubs",
109 | "name": "[variables('IoTHubName')]",
110 | "location": "[parameters('location')]",
111 | "dependsOn": [
112 | "[resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName'))]"
113 | ],
114 | "properties": {
115 | "eventHubEndpoints": {
116 | "events": {
117 | "retentionTimeInDays": 1,
118 | "partitionCount": "[parameters('d2c_partitions')]"
119 | }
120 | },
121 | "routing": {
122 | "endpoints": {
123 | "serviceBusQueues": [],
124 | "serviceBusTopics": [],
125 | "eventHubs": [],
126 | "storageContainers": [
127 | {
128 | "connectionString":
129 | "[Concat('DefaultEndpointsProtocol=https;AccountName=',variables('storageAccountName'),';AccountKey=',listKeys(resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName')), providers('Microsoft.Storage', 'storageAccounts').apiVersions[0]).keys[0].value)]",
130 | "containerName": "[parameters('storageContainerName')]",
131 | "fileNameFormat": "{iothub}/{partition}/{YYYY}/{MM}/{DD}/{HH}/{mm}",
132 | "batchFrequencyInSeconds": 100,
133 | "maxChunkSizeInBytes": 104857600,
134 | "encoding": "json",
135 | "name": "[parameters('storage_endpoint')]",
136 | "subscriptionId": "[parameters('subscriptionId')]",
137 | "resourceGroup": "[resourceGroup().Name]"
138 | }
139 | ]
140 | },
141 | "routes": [
142 | {
143 | "name": "ContosoStorageRoute",
144 | "source": "DeviceMessages",
145 | "condition": "level=\"storage\"",
146 | "endpointNames": [
147 | "[parameters('storage_endpoint')]"
148 | ],
149 | "isEnabled": true
150 | }
151 | ],
152 | "fallbackRoute": {
153 | "name": "$fallback",
154 | "source": "DeviceMessages",
155 | "condition": "true",
156 | "endpointNames": [
157 | "events"
158 | ],
159 | "isEnabled": true
160 | }
161 | },
162 | "storageEndpoints": {
163 | "$default": {
164 | "sasTtlAsIso8601": "PT1H",
165 | "connectionString": "",
166 | "containerName": ""
167 | }
168 | },
169 | "messagingEndpoints": {
170 | "fileNotifications": {
171 | "lockDurationAsIso8601": "PT1M",
172 | "ttlAsIso8601": "PT1H",
173 | "maxDeliveryCount": 10
174 | }
175 | },
176 | "enableFileUploadNotifications": false,
177 | "cloudToDevice": {
178 | "maxDeliveryCount": 10,
179 | "defaultTtlAsIso8601": "PT1H",
180 | "feedback": {
181 | "lockDurationAsIso8601": "PT1M",
182 | "ttlAsIso8601": "PT1H",
183 | "maxDeliveryCount": 10
184 | }
185 | }
186 | },
187 | "sku": {
188 | "name": "[parameters('sku_name')]",
189 | "capacity": "[parameters('sku_units')]"
190 | }
191 | }
192 | ],
193 | "outputs": {
194 | }
195 | }
--------------------------------------------------------------------------------
/horizontal-arm/testenvvars_SET.cmd:
--------------------------------------------------------------------------------
1 |
2 | echo on
3 | //set environment variables. Fill in the fields below, then run each line in the command window one at a time
4 | //then run the .NET Core app from the command window. You should be in the same folder as the arm-read-write.csproj file.
5 | CMD> dotnet run
6 |
7 | //Doing this instead of hardcoding these variables ensures that you don't accidentally save them to github.
8 | //
9 | SET IOT_DEVICE_ID=Contoso-Test-Device
10 | SET IOT_HUB_URI="IOT-HUB-NAME-GOES-HERE.azure-devices-net";
11 | SET IOT_DEVICE_KEY="IoT-device-key-goes-here"
12 | //
13 | //to see local environment variables, type set and hit return, and it will show them all
--------------------------------------------------------------------------------
/iot-hub/Quickstarts/InvokeDeviceMethod/readme.md:
--------------------------------------------------------------------------------
1 | # Azure IoT Hub InvokeDeviceMethodSample
2 |
3 | The sample that previously existed here has been removed since this sample repository will be retired and archived.
4 |
5 | Please see here for the up to date [InvokeDeviceMethodSample](https://github.com/Azure/azure-iot-sdk-csharp/blob/main/readme.md#samples).
--------------------------------------------------------------------------------
/iot-hub/Quickstarts/ReadD2cMessages/README.md:
--------------------------------------------------------------------------------
1 | # Azure IoT Hub ReadD2cMessagesSample
2 |
3 | The sample that previously existed here has been removed since this sample repository will be retired and archived.
4 |
5 | Please see here for the up to date [ReadD2cMessagesSample]https://github.com/Azure/azure-iot-sdk-csharp/blob/main/readme.md#samples).
6 |
--------------------------------------------------------------------------------
/iot-hub/Quickstarts/SimulatedDevice/readme.md:
--------------------------------------------------------------------------------
1 | # Azure IoT Hub SimulatedDeviceSample
2 |
3 | The sample that previously existed here has been removed since this sample repository will be retired and archived.
4 |
5 | Please see here for the up to date [SimulatedDeviceSample](https://github.com/Azure/azure-iot-sdk-csharp/blob/main/readme.md#samples).
--------------------------------------------------------------------------------
/iot-hub/Quickstarts/SimulatedDeviceWithCommand/readme.md:
--------------------------------------------------------------------------------
1 | # Azure IoT Hub SimulatedDeviceWithCommandSample
2 |
3 | The sample that previously existed here has been removed since this sample repository will be retired and archived.
4 |
5 | Please see here for the up to date [SimulatedDeviceWithCommandSample](https://github.com/Azure/azure-iot-sdk-csharp/blob/main/readme.md#samples).
--------------------------------------------------------------------------------
/iot-hub/Samples/device/DeviceReconnectionSample/readme.md:
--------------------------------------------------------------------------------
1 | # Device Reconnection Sample
2 |
3 | The sample that previously existed here has been removed since this sample repository will be retired and archived.
4 |
5 | Please see here for the up to date [DeviceReconnectionSample](https://github.com/Azure/azure-iot-sdk-csharp/blob/main/readme.md#samples).
6 |
--------------------------------------------------------------------------------
/iot-hub/Samples/device/FileUploadSample/readme.md:
--------------------------------------------------------------------------------
1 | # FileUploadSample
2 |
3 | The sample that previously existed here has been removed since this sample repository will be retired and archived.
4 |
5 | Please see here for the up to date [FileUploadSample](https://github.com/Azure/azure-iot-sdk-csharp/blob/main/readme.md#samples).
6 |
7 |
--------------------------------------------------------------------------------
/iot-hub/Samples/device/MessageReceiveSample/readme.md:
--------------------------------------------------------------------------------
1 | # MessageReceiveSample
2 |
3 | The sample that previously existed here has been removed since this sample repository will be retired and archived.
4 |
5 | Please see here for the up to date [MessageReceiveSample](https://github.com/Azure/azure-iot-sdk-csharp/blob/main/readme.md#samples).
6 |
7 |
--------------------------------------------------------------------------------
/iot-hub/Samples/device/MethodSample/readme.md:
--------------------------------------------------------------------------------
1 | # MethodSample
2 |
3 | The sample that previously existed here has been removed since this sample repository will be retired and archived.
4 |
5 | Please see here for the up to date [MethodSample](https://github.com/Azure/azure-iot-sdk-csharp/blob/main/readme.md#samples).
6 |
--------------------------------------------------------------------------------
/iot-hub/Samples/device/PnpDeviceSamples/readme.md:
--------------------------------------------------------------------------------
1 | # IoT Plug And Play device samples
2 |
3 | The samples that previously existed here have been removed since this sample repository will be retired and archived.
4 |
5 | Please see here for the up to date [PnpDeviceSamples](https://github.com/Azure/azure-iot-sdk-csharp/blob/main/readme.md#samples).
--------------------------------------------------------------------------------
/iot-hub/Samples/device/TwinSample/readme.md:
--------------------------------------------------------------------------------
1 | # Device Twins Sample
2 |
3 | The sample that previously existed here has been removed since this sample repository will be retired and archived.
4 |
5 | Please see here for the up to date [TwinSample](https://github.com/Azure/azure-iot-sdk-csharp/blob/main/readme.md#samples).
6 |
--------------------------------------------------------------------------------
/iot-hub/Samples/device/X509DeviceCertWithChainSample/readme.md:
--------------------------------------------------------------------------------
1 | # x509 device certificate with chain sample
2 | The sample that previously existed here has been removed since this sample repository will be retired and archived.
3 |
4 | Please see here for the up to date [X509Sample](https://github.com/Azure/azure-iot-sdk-csharp/blob/main/readme.md#samples).
5 |
--------------------------------------------------------------------------------
/iot-hub/Samples/device/XamarinSample/readme.md:
--------------------------------------------------------------------------------
1 | # Microsoft Azure IoT device SDK Xamarin Samples for .NET
2 | The sample that previously existed here has been removed since this sample repository will be retired and archived.
3 |
4 | Please see here for the up to date [XamarinSample](https://github.com/Azure/azure-iot-sdk-csharp/blob/main/readme.md#samples).
5 |
--------------------------------------------------------------------------------
/iot-hub/Samples/module/ModuleSample/readme.md:
--------------------------------------------------------------------------------
1 | # Module Sample
2 |
3 | The sample that previously existed here has been removed since this sample repository will be retired and archived.
4 |
5 | Please see here for the up to date [ModuleSample](https://github.com/Azure/azure-iot-sdk-csharp/blob/main/readme.md#samples).
6 |
--------------------------------------------------------------------------------
/iot-hub/Samples/service/AutomaticDeviceManagementSample/readme.md:
--------------------------------------------------------------------------------
1 | # Azure IoT Hub AutomaticDeviceManagementSample
2 |
3 | The sample that previously existed here has been removed since this sample repository will be retired and archived.
4 |
5 | Please see here for the up to date [AutomaticDeviceManagementSample](https://github.com/Azure/azure-iot-sdk-csharp/blob/main/readme.md#samples).
--------------------------------------------------------------------------------
/iot-hub/Samples/service/AzureSasCredentialAuthenticationSample/readme.md:
--------------------------------------------------------------------------------
1 | # Azure IoT Hub AzureSasCredentialAuthenticationSample
2 |
3 | The sample that previously existed here has been removed since this sample repository will be retired and archived.
4 |
5 | Please see here for the up to date [AzureSasCredentialAuthenticationSample](https://github.com/Azure/azure-iot-sdk-csharp/blob/main/readme.md#samples).
--------------------------------------------------------------------------------
/iot-hub/Samples/service/CleanupDevicesSample/readme.md:
--------------------------------------------------------------------------------
1 | # Azure IoT Hub CleanupDevicesSample
2 |
3 | The sample that previously existed here has been removed since this sample repository will be retired and archived.
4 |
5 | Please see here for the up to date [CleanupDevicesSample](https://github.com/Azure/azure-iot-sdk-csharp/blob/main/readme.md#samples).
--------------------------------------------------------------------------------
/iot-hub/Samples/service/DigitalTwinClientSamples/readme.md:
--------------------------------------------------------------------------------
1 | # Digital Twin Client Samples for the Azure IoT Service SDK
2 | The samples that previously existed here have been removed since this sample repository will be retired and archived.
3 |
4 | Please see here for the up to date [DigialTwinsClientSample](https://github.com/Azure/azure-iot-sdk-csharp/blob/main/readme.md#samples).
5 |
--------------------------------------------------------------------------------
/iot-hub/Samples/service/EdgeDeploymentSample/readme.md:
--------------------------------------------------------------------------------
1 | # EdgeDeploymentSample
2 | The sample that previously existed here has been removed since this sample repository will be retired and archived.
3 |
4 | Please see here for the up to date [EdgeDeploymentSample](https://github.com/Azure/azure-iot-sdk-csharp/blob/main/readme.md#samples).
--------------------------------------------------------------------------------
/iot-hub/Samples/service/FileUploadNotificationReceiverSample/readme.md:
--------------------------------------------------------------------------------
1 | # FileUploadNotificationReceiverSample
2 | The sample that previously existed here has been removed since this sample repository will be retired and archived.
3 |
4 | Please see here for the up to date [FileUploadNotificationReceiverSample](https://github.com/Azure/azure-iot-sdk-csharp/blob/main/readme.md#samples).
--------------------------------------------------------------------------------
/iot-hub/Samples/service/ImportExportDevicesSample/readme.md:
--------------------------------------------------------------------------------
1 | # ImportExportDevicesSample
2 | The sample that previously existed here has been removed since this sample repository will be retired and archived.
3 |
4 | Please see here for the up to date [ImportExportDevicesSample](https://github.com/Azure/azure-iot-sdk-csharp/blob/main/readme.md#samples).
--------------------------------------------------------------------------------
/iot-hub/Samples/service/ImportExportDevicesWithManagedIdentitySample/readme.md:
--------------------------------------------------------------------------------
1 | # ImportExportDevicesWithManagedIdentitySample
2 | The sample that previously existed here has been removed since this sample repository will be retired and archived.
3 |
4 | Please see here for the up to date [ImportExportDevicesWithManagedIdentitySample](https://github.com/Azure/azure-iot-sdk-csharp/blob/main/readme.md#samples).
--------------------------------------------------------------------------------
/iot-hub/Samples/service/JobsSample/readme.md:
--------------------------------------------------------------------------------
1 | # JobsSample
2 | The sample that previously existed here has been removed since this sample repository will be retired and archived.
3 |
4 | Please see here for the up to date [JobsSample](https://github.com/Azure/azure-iot-sdk-csharp/blob/main/readme.md#samples).
--------------------------------------------------------------------------------
/iot-hub/Samples/service/PnpServiceSamples/readme.md:
--------------------------------------------------------------------------------
1 | # IoT Plug And Play service samples
2 | The samples that previously existed here have been removed since this sample repository will be retired and archived.
3 |
4 | Please see here for the up to date [PnpServiceSample](https://github.com/Azure/azure-iot-sdk-csharp/blob/main/readme.md#samples).
5 |
--------------------------------------------------------------------------------
/iot-hub/Samples/service/RegistryManagerSample/readme.md:
--------------------------------------------------------------------------------
1 | # RegistryManagerSample
2 | The sample that previously existed here has been removed since this sample repository will be retired and archived.
3 |
4 | Please see here for the up to date [RegistryManagerSample](https://github.com/Azure/azure-iot-sdk-csharp/blob/main/readme.md#samples).
--------------------------------------------------------------------------------
/iot-hub/Samples/service/RoleBasedAuthenticationSample/readme.md:
--------------------------------------------------------------------------------
1 | # RoleBasedAuthenticationSample
2 | The sample that previously existed here has been removed since this sample repository will be retired and archived.
3 |
4 | Please see here for the up to date [RoleBasedAuthenticationSample](https://github.com/Azure/azure-iot-sdk-csharp/blob/main/readme.md#samples).
--------------------------------------------------------------------------------
/iot-hub/Samples/service/ServiceClientSample/readme.md:
--------------------------------------------------------------------------------
1 | # Service Client Sample
2 | The sample that previously existed here has been removed since this sample repository will be retired and archived.
3 |
4 | Please see here for the up to date [ServiceClientSample](https://github.com/Azure/azure-iot-sdk-csharp/blob/main/readme.md#samples).
5 |
--------------------------------------------------------------------------------
/iot-hub/Tutorials/Routing/IoT_SimulatedDevice.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 15
4 | VisualStudioVersion = 15.0.27428.2005
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SimulatedDevice", "SimulatedDevice\SimulatedDevice.csproj", "{7A6973B3-9375-47E4-A593-B86A3514841A}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|Any CPU = Debug|Any CPU
11 | Release|Any CPU = Release|Any CPU
12 | EndGlobalSection
13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
14 | {7A6973B3-9375-47E4-A593-B86A3514841A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
15 | {7A6973B3-9375-47E4-A593-B86A3514841A}.Debug|Any CPU.Build.0 = Debug|Any CPU
16 | {7A6973B3-9375-47E4-A593-B86A3514841A}.Release|Any CPU.ActiveCfg = Release|Any CPU
17 | {7A6973B3-9375-47E4-A593-B86A3514841A}.Release|Any CPU.Build.0 = Release|Any CPU
18 | EndGlobalSection
19 | GlobalSection(SolutionProperties) = preSolution
20 | HideSolutionNode = FALSE
21 | EndGlobalSection
22 | GlobalSection(ExtensibilityGlobals) = postSolution
23 | SolutionGuid = {75D6C41B-4AA6-4E02-B353-34F9E0702263}
24 | EndGlobalSection
25 | EndGlobal
26 |
--------------------------------------------------------------------------------
/iot-hub/Tutorials/Routing/SimulatedDevice/Parameters.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using CommandLine;
3 |
4 | namespace SimulatedDevice
5 | {
6 | ///
7 | /// Parameters for the application.
8 | ///
9 | internal class Parameters
10 | {
11 | [Option(
12 | 'u',
13 | "IoTHubUri",
14 | Required = true,
15 | HelpText = "The URI for the IoT hub.")]
16 | public string IotHubUri { get; set; }
17 |
18 | [Option(
19 | 'd',
20 | "DeviceId",
21 | Required = true,
22 | HelpText = "The device Id that you assigned when registering the device.")]
23 | public string DeviceId { get; set; }
24 |
25 | // This is the primary key for the device. This is in the portal.
26 | // Find your IoT hub in the portal > IoT devices > select your device > copy the key.
27 | [Option(
28 | 'k',
29 | "DeviceKey",
30 | Required = true,
31 | HelpText = "Find your IoT hub in the portal > IoT devices > select your device > copy the key.")]
32 | public string DeviceKey { get; set; }
33 |
34 | [Option(
35 | "ReadTheFile",
36 | Required = false,
37 | HelpText = "If this is false, it will submit messages to the IoT hub. If this is true, it will read one of the output files and convert it to ASCII.")]
38 | public bool ReadTheFile { get; set; } = false;
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/iot-hub/Tutorials/Routing/SimulatedDevice/Program.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft. All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | //This is the code that sends messages to the IoT Hub for testing the routing as defined
5 | // in this article: https://docs.microsoft.com/azure/iot-hub/tutorial-routing
6 | //The scripts for creating the resources are included in the resources folder in this
7 | // Visual Studio solution.
8 | //
9 | // This program encodes the message body so it can be queried against by the Iot hub.
10 | //
11 | // If you want to read an encoded message body, you can do this:
12 | // * route the message to storage,
13 | // * retrieve the message from the storage account by downloading the blob,
14 | // * use the ReadOneRowFromFile method at the bottom of this module to read the first row of the file.
15 | // * It will read the file, decode the first row in the file, and write it out to a new file
16 | // in ASCII so you can view it.
17 |
18 | using CommandLine;
19 | using Microsoft.Azure.Devices.Client;
20 | using Newtonsoft.Json;
21 | using Newtonsoft.Json.Linq;
22 | using System;
23 | using System.Text;
24 | using System.Threading;
25 | using System.Threading.Tasks;
26 |
27 | namespace SimulatedDevice
28 | {
29 | internal class Program
30 | {
31 | private static DeviceClient s_deviceClient;
32 |
33 | private static async Task Main(string[] args)
34 | {
35 | // Parse application parameters
36 | Parameters parameters = null;
37 | ParserResult result = Parser.Default.ParseArguments(args)
38 | .WithParsed(parsedParams =>
39 | {
40 | parameters = parsedParams;
41 | })
42 | .WithNotParsed(errors =>
43 | {
44 | Environment.Exit(1);
45 | });
46 |
47 | // If this is false, it will submit messages to the iot hub.
48 | // If this is true, it will read one of the output files and convert it to ASCII.
49 | if (parameters.ReadTheFile)
50 | {
51 | // If you want to decode an output file, put the path in ReadOneRowFromFile(),
52 | // uncomment the call here and the return command, then run this application.
53 | ReadOneRowFromFile();
54 | }
55 | else
56 | {
57 | // Send messages to the simulated device. Each message will contain a randomly generated
58 | // Temperature and Humidity.
59 | // The "level" of each message is set randomly to "storage", "critical", or "normal".
60 | // The messages are routed to different endpoints depending on the level, temperature, and humidity.
61 | // This is set in the tutorial that goes with this sample:
62 | // http://docs.microsoft.com/azure/iot-hub/tutorial-routing
63 |
64 | Console.WriteLine("Routing Tutorial: Simulated device\n");
65 | string myDeviceId = parameters.DeviceId;
66 | string deviceKey = parameters.DeviceKey;
67 | s_deviceClient = DeviceClient.Create(
68 | parameters.IotHubUri,
69 | new DeviceAuthenticationWithRegistrySymmetricKey(myDeviceId, deviceKey),
70 | TransportType.Mqtt);
71 |
72 | using var cts = new CancellationTokenSource();
73 | Task messages = SendDeviceToCloudMessagesAsync(myDeviceId, cts.Token);
74 | Console.WriteLine("Press the Enter key to stop.");
75 | Console.ReadLine();
76 | await s_deviceClient.CloseAsync(cts.Token);
77 | cts.Cancel();
78 | await messages;
79 |
80 | }
81 | }
82 |
83 | ///
84 | /// Send message to the Iot hub. This generates the object to be sent to the hub in the message.
85 | ///
86 | private static async Task SendDeviceToCloudMessagesAsync(string myDeviceId, CancellationToken token)
87 | {
88 | double minTemperature = 20;
89 | double minHumidity = 60;
90 | var rand = new Random();
91 |
92 | while (!token.IsCancellationRequested)
93 | {
94 | double currentTemperature = minTemperature + rand.NextDouble() * 15;
95 | double currentHumidity = minHumidity + rand.NextDouble() * 20;
96 |
97 | string infoString;
98 | string levelValue;
99 |
100 | if (rand.NextDouble() > 0.7)
101 | {
102 | if (rand.NextDouble() > 0.5)
103 | {
104 | levelValue = "critical";
105 | infoString = "This is a critical message.";
106 | }
107 | else
108 | {
109 | levelValue = "storage";
110 | infoString = "This is a storage message.";
111 | }
112 | }
113 | else
114 | {
115 | levelValue = "normal";
116 | infoString = "This is a normal message.";
117 | }
118 |
119 | var telemetryDataPoint = new
120 | {
121 | deviceId = myDeviceId,
122 | temperature = currentTemperature,
123 | humidity = currentHumidity,
124 | pointInfo = infoString
125 | };
126 | // serialize the telemetry data and convert it to JSON.
127 | string telemetryDataString = JsonConvert.SerializeObject(telemetryDataPoint);
128 |
129 | // Encode the serialized object using UTF-8 so it can be parsed by IoT Hub when
130 | // processing messaging rules.
131 | using var message = new Message(Encoding.UTF8.GetBytes(telemetryDataString))
132 | {
133 | ContentEncoding = "utf-8",
134 | ContentType = "application/json",
135 | };
136 |
137 | // Add one property to the message.
138 | message.Properties.Add("level", levelValue);
139 |
140 | // Submit the message to the hub.
141 | try
142 | {
143 | await s_deviceClient.SendEventAsync(message, token);
144 | }
145 | catch (OperationCanceledException) { }
146 |
147 | // Print out the message.
148 | Console.WriteLine("{0} > Sent message: {1}", DateTime.UtcNow, telemetryDataString);
149 |
150 | try
151 | {
152 | await Task.Delay(1000, token);
153 | }
154 | catch (OperationCanceledException) { }
155 | }
156 | }
157 |
158 |
159 | ///
160 | /// This method was written to enable you to decode one of the messages sent to the hub
161 | /// and view the body of the message.
162 | /// Route the messages to storage (they get written to blob storage).
163 | /// Send messages to the hub, by running this program with readthefile set to false.
164 | /// After some messages have been written to storage, download one of the files
165 | /// to somewhere you can find it, put the path in this method, and run the program
166 | /// with readthefile set to true.
167 | /// This method will read in the output file, then convert the first line to a message body object
168 | /// and write it back out to a new file that you can open and view.
169 | ///
170 | private static void ReadOneRowFromFile()
171 | {
172 | string filePathAndName = "C:\\Users\\username\\Desktop\\testfiles\\47_utf32.txt";
173 |
174 | // Set the output file name.
175 | // Read in the file to an array of objects. These were encoded in Base64 when they were
176 | // written.
177 | string outputFilePathAndName = filePathAndName.Replace(".txt", "_new.txt");
178 | string[] fileLines = System.IO.File.ReadAllLines(filePathAndName);
179 |
180 | // Parse the first line into a message object. Retrieve the body as a string.
181 | // This string was encoded as Base64 when it was written.
182 | var messageObject = JObject.Parse(fileLines[0]);
183 | string body = messageObject.Value("Body");
184 |
185 | // Convert the body from Base64, then from UTF-32 to text, and write it out to the new file
186 | // so you can view the result.
187 | string outputResult = System.Text.Encoding.UTF32.GetString(System.Convert.FromBase64String(body));
188 |
189 | System.IO.File.WriteAllText(outputFilePathAndName, outputResult);
190 | }
191 | }
192 | }
193 |
--------------------------------------------------------------------------------
/iot-hub/Tutorials/Routing/SimulatedDevice/SimulatedDevice.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net6.0
6 | 9.0
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/iot-hub/Tutorials/Routing/SimulatedDevice/resources/iothub_msgenrichment_cli.azcli:
--------------------------------------------------------------------------------
1 | # This command retrieves the subscription id of the current Azure account.
2 | # This field is used when setting up the routing queries.
3 | subscriptionID=$(az account show --query id -o tsv)
4 |
5 | # Concatenate this number onto the resources that have to be globally unique.
6 | # You can set this to "" or to a specific value if you don't want it to be random.
7 | # This retrieves a random value.
8 | randomValue=$RANDOM
9 |
10 | # This command installs the IOT Extension for Azure CLI.
11 | # You only need to install this the first time.
12 | # You need it to create the device identity.
13 | az extension add --name azure-cli-iot-ext
14 |
15 | # Set the values for the resource names that
16 | # don't have to be globally unique.
17 | location=westus2
18 | resourceGroup=ContosoResourcesMsgEn
19 | containerName1=original
20 | containerName2=enriched
21 | iotDeviceName=Contoso-Test-Device
22 |
23 | # Create the resource group to be used
24 | # for all the resources for this tutorial.
25 | az group create --name $resourceGroup \
26 | --location $location
27 |
28 | # The IoT hub name must be globally unique,
29 | # so add a random value to the end.
30 | iotHubName=ContosoTestHubMsgEn$randomValue
31 | echo "IoT hub name = " $iotHubName
32 |
33 | # Create the IoT hub.
34 | az iot hub create --name $iotHubName \
35 | --resource-group $resourceGroup \
36 | --sku S1 --location $location
37 |
38 | # You need a storage account that will have two containers
39 | # -- one for the original messages and
40 | # one for the enriched messages.
41 | # The storage account name must be globally unique,
42 | # so add a random value to the end.
43 | storageAccountName=contosostorage$randomValue
44 | echo "Storage account name = " $storageAccountName
45 |
46 | # Create the storage account to be used as a routing destination.
47 | az storage account create --name $storageAccountName \
48 | --resource-group $resourceGroup \
49 | --location $location \
50 | --sku Standard_LRS
51 |
52 | # Get the primary storage account key.
53 | # You need this to create the containers.
54 | storageAccountKey=$(az storage account keys list \
55 | --resource-group $resourceGroup \
56 | --account-name $storageAccountName \
57 | --query "[0].value" | tr -d '"')
58 |
59 | # See the value of the storage account key.
60 | echo "storage account key = " $storageAccountKey
61 |
62 | # Create the containers in the storage account.
63 | az storage container create --name $containerName1 \
64 | --account-name $storageAccountName \
65 | --account-key $storageAccountKey \
66 | --public-access off
67 |
68 | az storage container create --name $containerName2 \
69 | --account-name $storageAccountName \
70 | --account-key $storageAccountKey \
71 | --public-access off
72 |
73 | # Create the IoT device identity to be used for testing.
74 | az iot hub device-identity create --device-id $iotDeviceName \
75 | --hub-name $iotHubName
76 |
77 | # Retrieve the information about the device identity, then copy the primary key to
78 | # Notepad. You need this to run the device simulation during the testing phase.
79 | # If you are using Cloud Shell, you can scroll the window back up to retrieve this value.
80 | az iot hub device-identity show --device-id $iotDeviceName \
81 | --hub-name $iotHubName
82 |
83 | ##### ROUTING FOR STORAGE #####
84 |
85 | # You're going to have two routes and two endpoints.
86 | # One route points to the first container ("original") in the storage account
87 | # and includes the original messages.
88 | # The other points to the second container ("enriched") in the same storage account
89 | # and includes the enriched versions of the messages.
90 |
91 | endpointType="azurestoragecontainer"
92 | endpointName1="ContosoStorageEndpointOriginal"
93 | endpointName2="ContosoStorageEndpointEnriched"
94 | routeName1="ContosoStorageRouteOriginal"
95 | routeName2="ContosoStorageRouteEnriched"
96 |
97 | # for both endpoints, retrieve the messages going to storage
98 | condition='level="storage"'
99 |
100 | # Get the connection string for the storage account.
101 | # Adding the "-o tsv" makes it be returned without the default double quotes around it.
102 | storageConnectionString=$(az storage account show-connection-string \
103 | --name $storageAccountName --query connectionString -o tsv)
104 |
105 | # Create the routing endpoints and routes.
106 | # Set the encoding format to either avro or json.
107 |
108 | # This is the endpoint for the first container, for endpoint messages that are not enriched.
109 | az iot hub routing-endpoint create \
110 | --connection-string $storageConnectionString \
111 | --endpoint-name $endpointName1 \
112 | --endpoint-resource-group $resourceGroup \
113 | --endpoint-subscription-id $subscriptionID \
114 | --endpoint-type $endpointType \
115 | --hub-name $iotHubName \
116 | --container $containerName1 \
117 | --resource-group $resourceGroup \
118 | --encoding json
119 |
120 | # This is the endpoint for the second container, for endpoint messages that are enriched.
121 | az iot hub routing-endpoint create \
122 | --connection-string $storageConnectionString \
123 | --endpoint-name $endpointName2 \
124 | --endpoint-resource-group $resourceGroup \
125 | --endpoint-subscription-id $subscriptionID \
126 | --endpoint-type $endpointType \
127 | --hub-name $iotHubName \
128 | --container $containerName2 \
129 | --resource-group $resourceGroup \
130 | --encoding json
131 |
132 | # This is the route for messages that are not enriched.
133 | # Create the route for the first storage endpoint.
134 | az iot hub route create \
135 | --name $routeName1 \
136 | --hub-name $iotHubName \
137 | --source devicemessages \
138 | --resource-group $resourceGroup \
139 | --endpoint-name $endpointName1 \
140 | --enabled \
141 | --condition $condition
142 |
143 | # This is the route for messages that are enriched.
144 | # Create the route for the second storage endpoint.
145 | az iot hub route create \
146 | --name $routeName2 \
147 | --hub-name $iotHubName \
148 | --source devicemessages \
149 | --resource-group $resourceGroup \
150 | --endpoint-name $endpointName2 \
151 | --enabled \
152 | --condition $condition
153 |
--------------------------------------------------------------------------------
/iot-hub/Tutorials/Routing/SimulatedDevice/resources/iothub_routing_cli.azcli:
--------------------------------------------------------------------------------
1 | # This command retrieves the subscription id of the current Azure account.
2 | # This field is used when setting up the routing queries.
3 | subscriptionID=$(az account show --query id -o tsv)
4 |
5 | # Concatenate this number onto the resources that have to be globally unique.
6 | # You can set this to "" or to a specific value if you don't want it to be random.
7 | # This retrieves a random value.
8 | randomValue=$RANDOM
9 |
10 | # This command installs the IOT Extension for Azure CLI.
11 | # You only need to install this the first time.
12 | # You need it to create the device identity.
13 | az extension add --name azure-cli-iot-ext
14 |
15 | # Set the values for the resource names that
16 | # don't have to be globally unique.
17 | location=westus
18 | resourceGroup=ContosoResources
19 | iotHubConsumerGroup=ContosoConsumers
20 | containerName=contosoresults
21 | iotDeviceName=Contoso-Test-Device
22 |
23 | # Create the resource group to be used
24 | # for all the resources for this tutorial.
25 | az group create --name $resourceGroup \
26 | --location $location
27 |
28 | # The IoT hub name must be globally unique,
29 | # so add a random value to the end.
30 | iotHubName=ContosoTestHub$randomValue
31 | echo "IoT hub name = " $iotHubName
32 |
33 | # Create the IoT hub.
34 | az iot hub create --name $iotHubName \
35 | --resource-group $resourceGroup \
36 | --sku S1 --location $location
37 |
38 | # Add a consumer group to the IoT hub for the 'events' endpoint.
39 | az iot hub consumer-group create --hub-name $iotHubName \
40 | --name $iotHubConsumerGroup
41 |
42 | # The storage account name must be globally unique,
43 | # so add a random value to the end.
44 | storageAccountName=contosostorage$randomValue
45 | echo "Storage account name = " $storageAccountName
46 |
47 | # Create the storage account to be used as a routing destination.
48 | az storage account create --name $storageAccountName \
49 | --resource-group $resourceGroup \
50 | --location $location \
51 | --sku Standard_LRS
52 |
53 | # Get the primary storage account key.
54 | # You need this to create the container.
55 | storageAccountKey=$(az storage account keys list \
56 | --resource-group $resourceGroup \
57 | --account-name $storageAccountName \
58 | --query "[0].value" | tr -d '"')
59 |
60 | # See the value of the storage account key.
61 | echo "storage account key = " $storageAccountKey
62 |
63 | # Create the container in the storage account.
64 | az storage container create --name $containerName \
65 | --account-name $storageAccountName \
66 | --account-key $storageAccountKey \
67 | --public-access off
68 |
69 | # The Service Bus namespace must be globally unique,
70 | # so add a random value to the end.
71 | sbNamespace=ContosoSBNamespace$randomValue
72 | echo "Service Bus namespace = " $sbNamespace
73 |
74 | # Create the Service Bus namespace.
75 | az servicebus namespace create --resource-group $resourceGroup \
76 | --name $sbNamespace \
77 | --location $location
78 |
79 | # The Service Bus queue name must be globally unique,
80 | # so add a random value to the end.
81 | sbQueueName=ContosoSBQueue$randomValue
82 | echo "Service Bus queue name = " $sbQueueName
83 |
84 | # Create the Service Bus queue to be used as a routing destination.
85 | az servicebus queue create --name $sbQueueName \
86 | --namespace-name $sbNamespace \
87 | --resource-group $resourceGroup
88 |
89 | # Create the IoT device identity to be used for testing.
90 | az iot hub device-identity create --device-id $iotDeviceName \
91 | --hub-name $iotHubName
92 |
93 | # Retrieve the information about the device identity, then copy the primary key to
94 | # Notepad. You need this to run the device simulation during the testing phase.
95 | az iot hub device-identity show --device-id $iotDeviceName \
96 | --hub-name $iotHubName
97 |
98 | ##### ROUTING FOR STORAGE #####
99 |
100 | endpointName="ContosoStorageEndpoint"
101 | endpointType="azurestoragecontainer"
102 | routeName="ContosoStorageRoute"
103 | condition='level="storage"'
104 |
105 | # Get the connection string for the storage account.
106 | # Adding the "-o tsv" makes it be returned without the default double quotes around it.
107 | storageConnectionString=$(az storage account show-connection-string \
108 | --name $storageAccountName --query connectionString -o tsv)
109 |
110 | # Create the routing endpoint for storage.
111 | # Set the encoding format to either avro or json.
112 | az iot hub routing-endpoint create \
113 | --connection-string $storageConnectionString \
114 | --endpoint-name $endpointName \
115 | --endpoint-resource-group $resourceGroup \
116 | --endpoint-subscription-id $subscriptionID \
117 | --endpoint-type $endpointType \
118 | --hub-name $iotHubName \
119 | --container $containerName \
120 | --resource-group $resourceGroup \
121 | --encoding avro
122 |
123 | # Create the route for the storage endpoint.
124 | az iot hub route create \
125 | --name $routeName \
126 | --hub-name $iotHubName \
127 | --source devicemessages \
128 | --resource-group $resourceGroup \
129 | --endpoint-name $endpointName \
130 | --enabled \
131 | --condition $condition
132 |
133 | ##### ROUTING FOR SERVICE BUS QUEUE #####
134 |
135 | # Create the authorization rule for the Service Bus queue.
136 | az servicebus queue authorization-rule create \
137 | --name "sbauthrule" \
138 | --namespace-name $sbNamespace \
139 | --queue-name $sbQueueName \
140 | --resource-group $resourceGroup \
141 | --rights Listen Manage Send \
142 | --subscription $subscriptionID
143 |
144 | # Get the Service Bus queue connection string.
145 | # The "-o tsv" ensures it is returned without the default double-quotes.
146 | sbqConnectionString=$(az servicebus queue authorization-rule keys list \
147 | --name "sbauthrule" \
148 | --namespace-name $sbNamespace \
149 | --queue-name $sbQueueName \
150 | --resource-group $resourceGroup \
151 | --subscription $subscriptionID \
152 | --query primaryConnectionString -o tsv)
153 |
154 | # Show the Service Bus queue connection string.
155 | echo "service bus queue connection string = " $sbqConnectionString
156 |
157 | endpointName="ContosoSBQueueEndpoint"
158 | endpointType="ServiceBusQueue"
159 | routeName="ContosoSBQueueRoute"
160 | condition='level="critical"'
161 |
162 | # Set up the routing endpoint for the Service Bus queue.
163 | # This uses the Service Bus queue connection string.
164 | az iot hub routing-endpoint create \
165 | --connection-string $sbqConnectionString \
166 | --endpoint-name $endpointName \
167 | --endpoint-resource-group $resourceGroup \
168 | --endpoint-subscription-id $subscriptionID \
169 | --endpoint-type $endpointType \
170 | --hub-name $iotHubName \
171 | --resource-group $resourceGroup
172 |
173 | # Set up the message route for the Service Bus queue endpoint.
174 | az iot hub route create --name $routeName \
175 | --hub-name $iotHubName \
176 | --source-type devicemessages \
177 | --resource-group $resourceGroup \
178 | --endpoint-name $endpointName \
179 | --enabled \
180 | --condition $condition
--------------------------------------------------------------------------------
/iot-hub/Tutorials/Routing/SimulatedDevice/resources/iothub_routing_psh.ps1:
--------------------------------------------------------------------------------
1 | # This retrieves the subscription id of the current Azure account.
2 | # This field is used when setting up the routing queries.
3 | $subscriptionID = (Get-AzureRmContext).Subscription.Id
4 |
5 | # Concatenate this number onto the resources that have to be globally unique.
6 | # You can set this to "" or to a specific value if you don't want it to be random.
7 | # This retrieves the first 6 digits of a random value.
8 | $randomValue = "$(Get-Random)".Substring(0,6)
9 |
10 | # Set the values for the resource names that don't have to be globally unique.
11 | $location = "West US"
12 | $resourceGroup = "ContosoResources"
13 | $iotHubConsumerGroup = "ContosoConsumers"
14 | $containerName = "contosoresults"
15 |
16 | # Create the resource group to be used
17 | # for all resources for this tutorial
18 | New-AzResourceGroup -Name $resourceGroup -Location $location
19 |
20 | # The IoT hub name must be globally unique,
21 | # so add a random value to the end.
22 | $iotHubName = "ContosoTestHub" + $randomValue
23 | Write-Host "IoT hub name is " $iotHubName
24 |
25 | # Create the IoT hub.
26 | New-AzIotHub -ResourceGroupName $resourceGroup `
27 | -Name $iotHubName `
28 | -SkuName "S1" `
29 | -Location $location `
30 | -Units 1
31 |
32 | # Add a consumer group to the IoT hub.
33 | Add-AzIotHubEventHubConsumerGroup -ResourceGroupName $resourceGroup `
34 | -Name $iotHubName `
35 | -EventHubConsumerGroupName $iotHubConsumerGroup
36 |
37 | # The storage account name must be globally unique,
38 | # so add a random value to the end.
39 | $storageAccountName = "contosostorage" + $randomValue
40 | Write-Host "storage account name is " $storageAccountName
41 |
42 | # Create the storage account to be used as a routing destination.
43 | # Save the context for the storage account
44 | # to be used when creating a container.
45 | $storageAccount = New-AzStorageAccount -ResourceGroupName $resourceGroup `
46 | -Name $storageAccountName `
47 | -Location $location `
48 | -SkuName Standard_LRS `
49 | -Kind Storage
50 | # Retrieve the connection string from the context.
51 | $storageConnectionString = $storageAccount.Context.ConnectionString
52 | Write-Host "storage connection string = " $storageConnectionString
53 |
54 | # Create the container in the storage account.
55 | New-AzStorageContainer -Name $containerName `
56 | -Context $storageAccount.Context
57 |
58 | # The Service Bus namespace must be globally unique,
59 | # so add a random value to the end.
60 | $serviceBusNamespace = "ContosoSBNamespace" + $randomValue
61 | Write-Host "Service Bus namespace is " $serviceBusNamespace
62 |
63 | # Create the Service Bus namespace.
64 | New-AzServiceBusNamespace -ResourceGroupName $resourceGroup `
65 | -Location $location `
66 | -Name $serviceBusNamespace
67 |
68 | # The Service Bus queue name must be globally unique,
69 | # so add a random value to the end.
70 | $serviceBusQueueName = "ContosoSBQueue" + $randomValue
71 | Write-Host "Service Bus queue name is " $serviceBusQueueName
72 |
73 | # Create the Service Bus queue to be used as a routing destination.
74 | New-AzServiceBusQueue -ResourceGroupName $resourceGroup `
75 | -Namespace $serviceBusNamespace `
76 | -Name $serviceBusQueueName `
77 | -EnablePartitioning $False
78 |
79 | ##### ROUTING FOR STORAGE #####
80 |
81 | $endpointName = "ContosoStorageEndpoint"
82 | $endpointType = "azurestoragecontainer"
83 | $routeName = "ContosoStorageRoute"
84 | $condition = 'level="storage"'
85 |
86 | # Create the routing endpoint for storage.
87 | # The encoding can be AVRO or JSON.
88 | Add-AzIotHubRoutingEndpoint `
89 | -ResourceGroupName $resourceGroup `
90 | -Name $iotHubName `
91 | -EndpointName $endpointName `
92 | -EndpointType $endpointType `
93 | -EndpointResourceGroup $resourceGroup `
94 | -EndpointSubscriptionId $subscriptionId `
95 | -ConnectionString $storageConnectionString `
96 | -ContainerName $containerName `
97 | -Encoding JSON
98 |
99 | # Create the route for the storage endpoint.
100 | Add-AzIotHubRoute `
101 | -ResourceGroupName $resourceGroup `
102 | -Name $iotHubName `
103 | -RouteName $routeName `
104 | -Source DeviceMessages `
105 | -EndpointName $endpointName `
106 | -Condition $condition `
107 | -Enabled
108 |
109 | ##### ROUTING FOR SERVICE BUS QUEUE #####
110 |
111 | # Create the authorization rule for the Service Bus queue.
112 | New-AzServiceBusAuthorizationRule `
113 | -ResourceGroupName $resourceGroup `
114 | -NamespaceName $serviceBusNamespace `
115 | -Queue $serviceBusQueueName `
116 | -Name "sbauthrule" `
117 | -Rights @("Manage","Listen","Send")
118 |
119 | # Get the Service Bus Queue key.
120 | $sbqkey = Get-AzServiceBusKey `
121 | -ResourceGroupName $resourceGroup `
122 | -NamespaceName $serviceBusNamespace `
123 | -Queue $servicebusQueueName `
124 | -Name "sbauthrule"
125 |
126 | $endpointName = "ContosoSBQueueEndpoint"
127 | $endpointType = "servicebusqueue"
128 | $routeName = "ContosoSBQueueRoute"
129 | $condition = 'level="critical"'
130 |
131 | # If you experience problems while running this command,
132 | # it might be because it didn't have time to finish before
133 | # running the next line. To fix this, include this pause for 90
134 | # seconds before continuing. This gives it enough time to finish.
135 |
136 | # The IoT Hub team could change this to make the prior command
137 | # loop and check to see if it's finished before it continues (like the create-iot-hub cmdlet does),
138 | # but in case they don't fix it, putting the Start-Sleep command in here makes sure it works.
139 | Start-Sleep -Seconds 90
140 |
141 | # This command is the one that sometimes doesn't work. It's as if it doesn't have time to
142 | # finish before it moves to the next line.
143 | # The error from Add-AzIotHubRoutingEndpoint is "Operation returned an invalid status code 'BadRequest'".
144 |
145 | # This command adds the routing endpoint, using the connection string property from the key.
146 | # This will definitely work if you do the Sleep command first.
147 | Add-AzIotHubRoutingEndpoint `
148 | -ResourceGroupName $resourceGroup `
149 | -Name $iotHubName `
150 | -EndpointName $endpointName `
151 | -EndpointType $endpointType `
152 | -EndpointResourceGroup $resourceGroup `
153 | -EndpointSubscriptionId $subscriptionId `
154 | -ConnectionString $sbqkey.PrimaryConnectionString
155 |
156 | # Set up the message route for the Service Bus queue endpoint.
157 | Add-AzIotHubRoute `
158 | -ResourceGroupName $resourceGroup `
159 | -Name $iotHubName `
160 | -RouteName $routeName `
161 | -Source DeviceMessages `
162 | -EndpointName $endpointName `
163 | -Condition $condition `
164 | -Enabled
165 |
--------------------------------------------------------------------------------
/iot-hub/Tutorials/Routing/SimulatedDevice/resources/template_iothub.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json",
3 | "contentVersion": "1.0.0.0",
4 | "parameters": {
5 | "randomValue": {
6 | "defaultValue": "[substring(uniqueString(utcNow()),0,8)]",
7 | "type": "string",
8 | "metadata": {
9 | "description": "Random alphanumeric string to make the assets have a unique name."
10 | }
11 | },
12 | "subscriptionId": {
13 | "type": "string",
14 | "defaultValue": "[subscription().subscriptionid]",
15 | "metadata": {
16 | "description": "The subscription ID of the Azure subscription to deploy into."
17 | }
18 | },
19 | "IoTHubName_in": {
20 | "type": "string",
21 | "defaultValue": "ContosoTestHub",
22 | "metadata": {
23 | "description": "The name of the IoT Hub to create."
24 | }
25 | },
26 | "location": {
27 | "type": "string",
28 | "defaultValue": "westus",
29 | "metadata": {
30 | "description": "The datacenter to use for the deployment."
31 | }
32 | },
33 | "consumer_group":{
34 | "type": "string",
35 | "defaultValue": "ContosoConsumers",
36 | "metadata": {
37 | "description": "The consumer group to assign to the messages for use in ASA."
38 | }
39 | },
40 | "sku_name": {
41 | "type": "string",
42 | "defaultValue": "S1",
43 | "metadata": {
44 | "description": "The SKU to use for the IoT Hub."
45 | }
46 | },
47 | "sku_units": {
48 | "type": "string",
49 | "defaultValue": "1",
50 | "metadata": {
51 | "description": "The number of IoT Hub units."
52 | }
53 | },
54 | "d2c_partitions": {
55 | "type": "string",
56 | "metadata": {
57 | "description": "Partitions used for the event stream."
58 | }
59 | },
60 | "storageAccountName_in": {
61 | "type": "string",
62 | "defaultValue": "contosostorage",
63 | "metadata": {
64 | "description": "Name of storage account to be created."
65 | }
66 | },
67 | "storageContainerName": {
68 | "type": "string",
69 | "defaultValue": "contosoresults",
70 | "metadata": {
71 | "description": "Name of the container in which to place the routed data."
72 | }
73 | },
74 | "storage_endpoint": {
75 | "type": "string",
76 | "defaultValue": "ContosoStorageEndpoint",
77 | "metadata": {
78 | "description": "Name of the endpoint for the storage account."
79 | }
80 | },
81 | "service_bus_namespace_in": {
82 | "type": "string",
83 | "defaultValue": "ContosoSBNamespace",
84 | "metadata": {
85 | "description": "Namespace of the service bus that has the queue to which messages are routed."
86 | }
87 | },
88 | "service_bus_queue_in": {
89 | "type": "string",
90 | "defaultValue": "ContosoSBQueue",
91 | "metadata": {
92 | "description": "Name of the service bus queue to which to route messages."
93 | }
94 | },
95 | "service_bus_queue_endpoint": {
96 | "type": "string",
97 | "defaultValue": "ContosoSBQueueEndpoint",
98 | "metadata": {
99 | "description": "Endpoint to use for routing messages to the service bus queue."
100 | }
101 | },
102 | "AuthRules_sb_queue": {
103 | "type": "string",
104 | "defaultValue": "AuthRules_sb_queue",
105 | "metadata": {
106 | "description": "Authorization rules for the service bus queue."
107 | }
108 | }
109 | },
110 | "variables": {
111 | "queueAuthorizationRuleResourceId": "[resourceId('Microsoft.ServiceBus/namespaces/queues/authorizationRules', variables('service_bus_namespace'), variables('service_bus_queue'), parameters('AuthRules_sb_queue'))]",
112 | "iotHubName": "[concat(parameters('IotHubName_in'),parameters('randomValue'))]",
113 | "storageAccountName": "[concat(parameters('storageAccountName_in'),parameters('randomValue'))]",
114 | "service_bus_namespace": "[concat(parameters('service_bus_namespace_in'),parameters('randomValue'))]",
115 | "service_bus_queue": "[concat(parameters('service_bus_queue_in'),parameters('randomValue'))]",
116 | "sbVersion": "2017-04-01"
117 | },
118 | "resources": [
119 | {
120 | "type": "Microsoft.Storage/storageAccounts",
121 | "name": "[variables('storageAccountName')]",
122 | "apiVersion": "2018-07-01",
123 | "location": "[parameters('location')]",
124 | "sku": {
125 | "name": "Standard_LRS",
126 | "tier": "Standard"
127 | },
128 | "kind": "Storage",
129 | "properties": {},
130 | "resources": [
131 | {
132 | "type": "blobServices/containers",
133 | "apiVersion": "2018-07-01",
134 | "name": "[concat('default/', parameters('storageContainerName'))]",
135 | "properties": {
136 | "publicAccess": "None"
137 | } ,
138 | "dependsOn": [
139 | "[resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName'))]"
140 | ]
141 | }
142 | ]
143 | },
144 | {
145 | "type": "Microsoft.ServiceBus/namespaces",
146 | "comments": "The Sku should be 'Standard' for this tutorial.",
147 | "sku": {
148 | "name": "Standard",
149 | "tier": "Standard"
150 | },
151 | "name": "[variables('service_bus_namespace')]",
152 | "apiVersion": "[variables('sbVersion')]",
153 | "location": "[parameters('location')]",
154 | "properties": {
155 | "provisioningState": "Succeeded",
156 | "metricId": "[concat('a4295411-5eff-4f81-b77e-276ab1ccda12:', variables('service_bus_namespace'))]",
157 | "serviceBusEndpoint": "[concat('https://', variables('service_bus_namespace'),'.servicebus.windows.net:443/')]",
158 | "status": "Active"
159 | },
160 | "dependsOn": []
161 | },
162 | {
163 | "type": "Microsoft.ServiceBus/namespaces/queues",
164 | "name": "[concat(variables('service_bus_namespace'), '/', variables('service_bus_queue'))]",
165 | "apiVersion": "[variables('sbVersion')]",
166 | "location": "[parameters('location')]",
167 | "scale": null,
168 | "properties": {},
169 | "dependsOn": [
170 | "[resourceId('Microsoft.ServiceBus/namespaces', variables('service_bus_namespace'))]"
171 | ]
172 | },
173 | {
174 | "apiVersion": "2018-04-01",
175 | "type": "Microsoft.Devices/IotHubs",
176 | "name": "[variables('IoTHubName')]",
177 | "location": "[parameters('location')]",
178 | "dependsOn": [
179 | "[resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName'))]",
180 | "[resourceId('Microsoft.ServiceBus/namespaces', variables('service_bus_namespace'))]",
181 | "[resourceId('Microsoft.ServiceBus/namespaces/queues', variables('service_bus_namespace'), variables('service_bus_queue'))]"
182 | ],
183 | "properties": {
184 | "eventHubEndpoints": {
185 | "events": {
186 | "retentionTimeInDays": 1,
187 | "partitionCount": "[parameters('d2c_partitions')]"
188 | }
189 | },
190 | "routing": {
191 | "endpoints": {
192 | "serviceBusQueues": [
193 | {
194 | "connectionString": "[Concat('Endpoint=sb://',variables('service_bus_namespace'),'.servicebus.windows.net/;SharedAccessKeyName=',parameters('AuthRules_sb_queue'),';SharedAccessKey=',listkeys(variables('queueAuthorizationRuleResourceId'),variables('sbVersion')).primaryKey,';EntityPath=',variables('service_bus_queue'))]",
195 | "name": "[parameters('service_bus_queue_endpoint')]",
196 | "subscriptionId": "[parameters('subscriptionId')]",
197 | "resourceGroup": "[resourceGroup().Name]"
198 | }
199 | ],
200 | "serviceBusTopics": [],
201 | "eventHubs": [],
202 | "storageContainers": [
203 | {
204 | "connectionString":
205 | "[Concat('DefaultEndpointsProtocol=https;AccountName=',variables('storageAccountName'),';AccountKey=',listKeys(resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName')), providers('Microsoft.Storage', 'storageAccounts').apiVersions[0]).keys[0].value)]",
206 | "containerName": "[parameters('storageContainerName')]",
207 | "fileNameFormat": "{iothub}/{partition}/{YYYY}/{MM}/{DD}/{HH}/{mm}",
208 | "batchFrequencyInSeconds": 100,
209 | "maxChunkSizeInBytes": 104857600,
210 | "encoding": "avro",
211 | "name": "[parameters('storage_endpoint')]",
212 | "subscriptionId": "[parameters('subscriptionId')]",
213 | "resourceGroup": "[resourceGroup().Name]"
214 | }
215 | ]
216 | },
217 | "routes": [
218 | {
219 | "name": "ContosoStorageRoute",
220 | "source": "DeviceMessages",
221 | "condition": "level=\"storage\"",
222 | "endpointNames": [
223 | "[parameters('storage_endpoint')]"
224 | ],
225 | "isEnabled": true
226 | },
227 | {
228 | "name": "ContosoSBQueueRoute",
229 | "source": "DeviceMessages",
230 | "condition": "level=\"critical\"",
231 | "endpointNames": [
232 | "[parameters('service_bus_queue_endpoint')]"
233 | ],
234 | "isEnabled": true
235 | }
236 |
237 | ],
238 | "fallbackRoute": {
239 | "name": "$fallback",
240 | "source": "DeviceMessages",
241 | "condition": "true",
242 | "endpointNames": [
243 | "events"
244 | ],
245 | "isEnabled": true
246 | }
247 | },
248 | "storageEndpoints": {
249 | "$default": {
250 | "sasTtlAsIso8601": "PT1H",
251 | "connectionString": "",
252 | "containerName": ""
253 | }
254 | },
255 | "messagingEndpoints": {
256 | "fileNotifications": {
257 | "lockDurationAsIso8601": "PT1M",
258 | "ttlAsIso8601": "PT1H",
259 | "maxDeliveryCount": 10
260 | }
261 | },
262 | "enableFileUploadNotifications": false,
263 | "cloudToDevice": {
264 | "maxDeliveryCount": 10,
265 | "defaultTtlAsIso8601": "PT1H",
266 | "feedback": {
267 | "lockDurationAsIso8601": "PT1M",
268 | "ttlAsIso8601": "PT1H",
269 | "maxDeliveryCount": 10
270 | }
271 | }
272 | },
273 | "sku": {
274 | "name": "[parameters('sku_name')]",
275 | "capacity": "[parameters('sku_units')]"
276 | }
277 | },
278 | {
279 | "type": "Microsoft.ServiceBus/namespaces/queues/authorizationRules",
280 | "name": "[concat(variables('service_bus_namespace'), '/', variables('service_bus_queue'), '/', parameters('AuthRules_sb_queue'))]",
281 | "apiVersion": "[variables('sbVersion')]",
282 | "location": "[parameters('location')]",
283 | "scale": null,
284 | "properties": {
285 | "rights": [
286 | "Send"
287 | ]
288 | },
289 | "dependsOn": [
290 | "[resourceId('Microsoft.ServiceBus/namespaces', variables('service_bus_namespace'))]",
291 | "[resourceId('Microsoft.ServiceBus/namespaces/queues', variables('service_bus_namespace'), variables('service_bus_queue'))]"
292 | ]
293 | },
294 | {
295 | "type": "Microsoft.Devices/IotHubs/eventHubEndpoints/ConsumerGroups",
296 | "name": "[concat(variables('iotHubName'), '/events/',parameters('consumer_group'))]",
297 | "apiVersion": "2018-04-01",
298 | "dependsOn": [
299 | "[concat('Microsoft.Devices/Iothubs/', variables('iotHubName'))]"
300 | ]
301 | }
302 | ],
303 | "outputs": {
304 | "sbq_connectionString": {
305 | "type": "string",
306 | "value": "[Concat('Endpoint=sb://',variables('service_bus_namespace'),'.servicebus.windows.net/;SharedAccessKeyName=',parameters('AuthRules_sb_queue'),';SharedAccessKey=',listkeys(variables('queueAuthorizationRuleResourceId'),variables('sbVersion')).primaryKey,';EntityPath=',variables('service_bus_queue'))]"
307 | }
308 | }
309 | }
--------------------------------------------------------------------------------
/iot-hub/Tutorials/Routing/SimulatedDevice/resources/template_iothub_parameters.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
3 | "contentVersion": "1.0.0.0",
4 | "parameters": {
5 | "IoTHubName_in": {
6 | "value": "ContosoTestHub"
7 | },
8 | "location": {
9 | "value": "westus"
10 | },
11 | "consumer_group":{
12 | "value": "ContosoConsumers"
13 | },
14 | "sku_name": {
15 | "value": "S1"
16 | },
17 | "sku_units": {
18 | "value": "1"
19 | },
20 | "d2c_partitions": {
21 | "value": "4"
22 | },
23 | "storageAccountName_in": {
24 | "value": "contosostorage"
25 | },
26 | "storageContainerName": {
27 | "value": "contosoresults"
28 | },
29 | "storage_endpoint": {
30 | "value": "ContosoStorageEndpoint"
31 | },
32 | "service_bus_namespace_in": {
33 | "value": "ContosoSBNamespace"
34 | },
35 | "service_bus_queue_in": {
36 | "value": "ContosoSBQueue"
37 | },
38 | "service_bus_queue_endpoint": {
39 | "value": "ContosoSBQueueEndpoint"
40 | },
41 | "AuthRules_sb_queue": {
42 | "value": "AuthRules_sb_queue"
43 | }
44 | }
45 | }
--------------------------------------------------------------------------------
/iot-hub/Tutorials/Routing/SimulatedDevice/resources/template_messageenrichments.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json",
3 | "contentVersion": "1.0.0.0",
4 | "parameters": {
5 | "randomValue": {
6 | "defaultValue": "[substring(uniqueString(utcNow()),0,8)]",
7 | "type": "string",
8 | "metadata": {
9 | "description": "Random alphanumeric string to make the assets have a unique name."
10 | }
11 | },
12 | "subscriptionId": {
13 | "type": "string",
14 | "defaultValue": "[subscription().subscriptionid]",
15 | "metadata": {
16 | "description": "The subscription ID of the Azure subscription to deploy into."
17 | }
18 | },
19 | "IoTHubName_in": {
20 | "type": "string",
21 | "defaultValue": "ContosoTestHubMsgEn",
22 | "metadata": {
23 | "description": "The name of the IoT Hub to create."
24 | }
25 | },
26 | "location": {
27 | "type": "string",
28 | "defaultValue": "westus2",
29 | "metadata": {
30 | "description": "The datacenter to use for the deployment."
31 | }
32 | },
33 | "sku_name": {
34 | "type": "string",
35 | "defaultValue": "S1",
36 | "metadata": {
37 | "description": "The SKU to use for the IoT Hub."
38 | }
39 | },
40 | "sku_units": {
41 | "type": "string",
42 | "defaultValue": "1",
43 | "metadata": {
44 | "description": "The number of IoT Hub units."
45 | }
46 | },
47 | "d2c_partitions": {
48 | "type": "string",
49 | "defaultValue": "4",
50 | "metadata": {
51 | "description": "Partitions used for the event stream."
52 | }
53 | },
54 | "storageAccountName_in": {
55 | "type": "string",
56 | "defaultValue": "contosostorage",
57 | "metadata": {
58 | "description": "Name of storage account to be created."
59 | }
60 | },
61 | "containerName1": {
62 | "type": "string",
63 | "defaultValue": "original",
64 | "metadata": {
65 | "description": "Name of the container in which to place the routed data."
66 | }
67 | },
68 | "containerName2": {
69 | "type": "string",
70 | "defaultValue": "enriched",
71 | "metadata": {
72 | "description": "Name of the container in which to place the routed data."
73 | }
74 | },
75 | "routeName1": {
76 | "type": "string",
77 | "defaultValue": "ContosoStorageRouteOriginal",
78 | "metadata": {
79 | "description": "Name of the endpoint for the storage account."
80 | }
81 | },
82 | "routeName2": {
83 | "type": "string",
84 | "defaultValue": "ContosoStorageRouteEnriched",
85 | "metadata": {
86 | "description": "Name of the endpoint for the storage account."
87 | }
88 | },
89 | "endpointName1": {
90 | "type": "string",
91 | "defaultValue": "ContosoStorageEndpointOriginal",
92 | "metadata": {
93 | "description": "Name of the endpoint for the storage account."
94 | }
95 | },
96 | "endpointName2": {
97 | "type": "string",
98 | "defaultValue": "ContosoStorageEndpointEnriched",
99 | "metadata": {
100 | "description": "Name of the endpoint for the storage account."
101 | }
102 | }
103 | },
104 | "variables": {
105 | "iotHubName": "[concat(parameters('IotHubName_in'),parameters('randomValue'))]",
106 | "storageAccountName": "[concat(parameters('storageAccountName_in'),parameters('randomValue'))]"
107 | },
108 | "resources": [
109 | {
110 | "type": "Microsoft.Storage/storageAccounts",
111 | "name": "[variables('storageAccountName')]",
112 | "apiVersion": "2018-07-01",
113 | "location": "[parameters('location')]",
114 | "sku": {
115 | "name": "Standard_LRS",
116 | "tier": "Standard"
117 | },
118 | "kind": "Storage",
119 | "properties": {},
120 | "resources": [
121 | {
122 | "type": "blobServices/containers",
123 | "apiVersion": "2018-07-01",
124 | "name": "[concat('default/', parameters('containerName1'))]",
125 | "properties": {
126 | "publicAccess": "None"
127 | } ,
128 | "dependsOn": [
129 | "[resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName'))]"
130 | ]
131 | },
132 | {
133 | "type": "blobServices/containers",
134 | "apiVersion": "2018-07-01",
135 | "name": "[concat('default/', parameters('containerName2'))]",
136 | "properties": {
137 | "publicAccess": "None"
138 | } ,
139 | "dependsOn": [
140 | "[resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName'))]"
141 | ]
142 | }
143 | ]
144 | },
145 | {
146 | "apiVersion": "2019-11-04",
147 | "type": "Microsoft.Devices/IotHubs",
148 | "name": "[variables('IoTHubName')]",
149 | "location": "[parameters('location')]",
150 | "dependsOn": [
151 | "[resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName'))]"
152 | ],
153 | "properties": {
154 | "eventHubEndpoints": {
155 | "events": {
156 | "retentionTimeInDays": 1,
157 | "partitionCount": "[parameters('d2c_partitions')]"
158 | }
159 | },
160 | "routing": {
161 | "enrichments": [
162 | {
163 | "key": "myIoTHub",
164 | "value": "$iothubname",
165 | "endpointNames": ["ContosoStorageEndpointEnriched"]
166 | },
167 | {
168 | "key": "DeviceLocation",
169 | "value": "$twin.tags.location",
170 | "endpointNames": ["ContosoStorageEndpointEnriched"]
171 | },
172 | {
173 | "key": "customerID",
174 | "value": "6ce345b8-1e4a-411e-9398-d34587459a3a",
175 | "endpointNames": ["ContosoStorageEndpointEnriched"]
176 | }
177 | ],
178 | "endpoints": {
179 | "serviceBusQueues": [],
180 | "serviceBusTopics": [],
181 | "eventHubs": [],
182 | "storageContainers": [
183 | {
184 | "connectionString":
185 | "[Concat('DefaultEndpointsProtocol=https;AccountName=',variables('storageAccountName'),';AccountKey=',listKeys(resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName')), providers('Microsoft.Storage', 'storageAccounts').apiVersions[0]).keys[0].value)]",
186 | "containerName": "[parameters('containerName1')]",
187 | "fileNameFormat": "{iothub}/{partition}/{YYYY}/{MM}/{DD}/{HH}/{mm}",
188 | "batchFrequencyInSeconds": 100,
189 | "maxChunkSizeInBytes": 104857600,
190 | "encoding": "json",
191 | "name": "[parameters('endpointName1')]",
192 | "subscriptionId": "[parameters('subscriptionId')]",
193 | "resourceGroup": "[resourceGroup().Name]"
194 | },
195 | {
196 | "connectionString":
197 | "[Concat('DefaultEndpointsProtocol=https;AccountName=',variables('storageAccountName'),';AccountKey=',listKeys(resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName')), providers('Microsoft.Storage', 'storageAccounts').apiVersions[0]).keys[0].value)]",
198 | "containerName": "[parameters('containerName2')]",
199 | "fileNameFormat": "{iothub}/{partition}/{YYYY}/{MM}/{DD}/{HH}/{mm}",
200 | "batchFrequencyInSeconds": 100,
201 | "maxChunkSizeInBytes": 104857600,
202 | "encoding": "json",
203 | "name": "[parameters('endpointName2')]",
204 | "subscriptionId": "[parameters('subscriptionId')]",
205 | "resourceGroup": "[resourceGroup().Name]"
206 | }
207 | ]
208 | },
209 | "routes": [
210 | {
211 | "name": "[parameters('routeName1')]",
212 | "source": "DeviceMessages",
213 | "condition": "level=\"storage\"",
214 | "endpointNames": [
215 | "[parameters('endpointName1')]"
216 | ],
217 | "isEnabled": true
218 | },
219 | {
220 | "name": "[parameters('routeName2')]",
221 | "source": "DeviceMessages",
222 | "condition": "level=\"storage\"",
223 | "endpointNames": [
224 | "[parameters('endpointName2')]"
225 | ],
226 | "isEnabled": true
227 | }
228 | ],
229 | "fallbackRoute": {
230 | "name": "$fallback",
231 | "source": "DeviceMessages",
232 | "condition": "true",
233 | "endpointNames": [
234 | "events"
235 | ],
236 | "isEnabled": true
237 | }
238 | },
239 | "storageEndpoints": {
240 | "$default": {
241 | "sasTtlAsIso8601": "PT1H",
242 | "connectionString": "",
243 | "containerName": ""
244 | }
245 | },
246 | "messagingEndpoints": {
247 | "fileNotifications": {
248 | "lockDurationAsIso8601": "PT1M",
249 | "ttlAsIso8601": "PT1H",
250 | "maxDeliveryCount": 10
251 | }
252 | },
253 | "enableFileUploadNotifications": false,
254 | "cloudToDevice": {
255 | "maxDeliveryCount": 10,
256 | "defaultTtlAsIso8601": "PT1H",
257 | "feedback": {
258 | "lockDurationAsIso8601": "PT1M",
259 | "ttlAsIso8601": "PT1H",
260 | "maxDeliveryCount": 10
261 | }
262 | }
263 | },
264 | "sku": {
265 | "name": "[parameters('sku_name')]",
266 | "capacity": "[parameters('sku_units')]"
267 | }
268 | }
269 | ]
270 | }
--------------------------------------------------------------------------------
/nuget.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/provisioning/Samples/device/ComputeDerivedSymmetricKeySample/readme.md:
--------------------------------------------------------------------------------
1 | # ComputeDerivedSymmetricKeySample
2 |
3 | The sample that previously existed here has been removed since this sample repository will be retired and archived.
4 |
5 | Please see here for the up to date [ComputeDerviedSymmetricKeySample](https://github.com/Azure/azure-iot-sdk-csharp/blob/main/readme.md#samples).
--------------------------------------------------------------------------------
/provisioning/Samples/device/SymmetricKeySample/readme.md:
--------------------------------------------------------------------------------
1 | # SymmetricKeySample
2 |
3 | The sample that previously existed here has been removed since this sample repository will be retired and archived.
4 |
5 | Please see here for the up to date [SymmetricKeySample](https://github.com/Azure/azure-iot-sdk-csharp/blob/main/readme.md#samples).
--------------------------------------------------------------------------------
/provisioning/Samples/device/TpmSample/readme.md:
--------------------------------------------------------------------------------
1 | # Provisioning Device Client Sample - TPM Attestation
2 | The sample that previously existed here has been removed since this sample repository will be retired and archived.
3 |
4 | Please see here for the up to date [TpmSample](https://github.com/Azure/azure-iot-sdk-csharp/blob/main/readme.md#samples).
5 |
--------------------------------------------------------------------------------
/provisioning/Samples/device/X509Sample/readme.md:
--------------------------------------------------------------------------------
1 | # Provisioning Device Client Sample - X.509 Attestation
2 | The sample that previously existed here has been removed since this sample repository will be retired and archived.
3 |
4 | Please see here for the up to date [X509Sample](https://github.com/Azure/azure-iot-sdk-csharp/blob/main/readme.md#samples).
5 |
--------------------------------------------------------------------------------
/provisioning/Samples/device/readme.md:
--------------------------------------------------------------------------------
1 | # Provisioning Device Client Sample - Microsoft Azure IoT SDK for .NET
2 |
3 | The DPS samples that previously existed here have been removed since this sample repository will be retired and archived.
4 |
5 | Please see here for the up to date [ProvisioningSamples](https://github.com/Azure/azure-iot-sdk-csharp/blob/main/readme.md#samples).
6 |
--------------------------------------------------------------------------------
/provisioning/Samples/service/BulkOperationSample/readme.md:
--------------------------------------------------------------------------------
1 | # BulkOperationSample
2 | The sample that previously existed here has been removed since this sample repository will be retired and archived.
3 |
4 | Please see here for the up to date [BulkOperationSample](https://github.com/Azure/azure-iot-sdk-csharp/blob/main/readme.md#samples).
--------------------------------------------------------------------------------
/provisioning/Samples/service/CleanupEnrollmentsSample/readme.md:
--------------------------------------------------------------------------------
1 | # CleanupEnrollmentsSample
2 | The sample that previously existed here has been removed since this sample repository will be retired and archived.
3 |
4 | Please see here for the up to date [CleanupEnrollmentsSample](https://github.com/Azure/azure-iot-sdk-csharp/blob/main/readme.md#samples).
--------------------------------------------------------------------------------
/provisioning/Samples/service/EnrollmentGroupSample/readme.md:
--------------------------------------------------------------------------------
1 | # EnrollmentGroupSample
2 | The sample that previously existed here has been removed since this sample repository will be retired and archived.
3 |
4 | Please see here for the up to date [EnrollmentGroupSample](https://github.com/Azure/azure-iot-sdk-csharp/blob/main/readme.md#samples).
--------------------------------------------------------------------------------
/provisioning/Samples/service/EnrollmentSample/readme.md:
--------------------------------------------------------------------------------
1 | # EnrollmentSample
2 | The sample that previously existed here has been removed since this sample repository will be retired and archived.
3 |
4 | Please see here for the up to date [EnrollmentSample](https://github.com/Azure/azure-iot-sdk-csharp/blob/main/readme.md#samples).
--------------------------------------------------------------------------------
/provisioning/Samples/service/GroupCertificateVerificationSample/readme.md:
--------------------------------------------------------------------------------
1 | # GroupCertificateVerificationSample
2 | The sample that previously existed here has been removed since this sample repository will be retired and archived.
3 |
4 | Please see here for the up to date [GroupCertificateVerificationSample](https://github.com/Azure/azure-iot-sdk-csharp/blob/main/readme.md#samples).
--------------------------------------------------------------------------------
/vsts/CredScanSuppressions.json:
--------------------------------------------------------------------------------
1 | {
2 | "tool": "Credential Scanner",
3 | "suppressions": [
4 | {
5 | "placeholder": "dGVzdFN0cmluZzE=",
6 | "_justification": "Dummy secret used in unit tests, it is fake"
7 | },
8 | {
9 | "placeholder": "dGVzdFN0cmluZzI=",
10 | "_justification": "Dummy secret used in unit tests, it is fake"
11 | },
12 | {
13 | "placeholder": "dGVzdFN0cmluZzM=",
14 | "_justification": "Dummy secret used in unit tests, it is fake"
15 | },
16 | {
17 | "placeholder": "dGVzdFN0cmluZzQ=",
18 | "_justification": "Dummy secret used in unit tests, it is fake"
19 | },
20 | {
21 | "placeholder": "dGVzdFN0cmluZzU=",
22 | "_justification": "Dummy secret used in unit tests, it is fake"
23 | },
24 | {
25 | "placeholder": "dGVzdFN0cmluZzY=",
26 | "_justification": "Dummy secret used in unit tests, it is fake"
27 | },
28 | {
29 | "placeholder": "notsafe",
30 | "_justification": "Dummy secret used in unit tests, it is fake"
31 | }
32 | ]
33 | }
--------------------------------------------------------------------------------
/vsts/vsts.yaml:
--------------------------------------------------------------------------------
1 | name: $(BuildID)_$(BuildDefinitionName)_$(SourceBranchName)_$(Date:yyyyMMdd)$(Rev:.r)
2 |
3 | # https://docs.microsoft.com/azure/devops/pipelines/process/runtime-parameters
4 | parameters:
5 | - name: jobTimeoutInMinutes
6 | displayName: Timeout for each job
7 | type: number
8 | default: 75
9 | - name: tests
10 | displayName: Run all tests, include clearing (if unchecked, clear service resources only).
11 | type: boolean
12 | default: true
13 |
14 | variables:
15 | ${{ if parameters.tests }}:
16 | testConfig: "-run"
17 | ${{ else }}:
18 | testConfig: "-clear"
19 |
20 | resources:
21 | - repo: self
22 | clean: true
23 |
24 | jobs:
25 | ### Linux build ###
26 | - job: LINUX
27 | displayName: Linux (timeout=${{ parameters.jobTimeoutInMinutes }}mins)
28 | condition: succeeded()
29 | pool:
30 | vmImage: 'ubuntu-latest'
31 | timeoutInMinutes: ${{ parameters.jobTimeoutInMinutes }}
32 | steps:
33 | - task: UseDotNet@2
34 | displayName: 'Use .NET 6.0 SDK'
35 | inputs:
36 | version: 6.0.x
37 | performMultiLevelLookup: true
38 | installationPath: $(Agent.ToolsDirectory)/dotnet
39 | - task: UseDotNet@2
40 | displayName: 'Use .NET 5.0 SDK'
41 | inputs:
42 | version: 5.0.x
43 | performMultiLevelLookup: true
44 | installationPath: $(Agent.ToolsDirectory)/dotnet
45 | - task: UseDotNet@2
46 | displayName: 'Use .NET Core 3.1 SDK'
47 | inputs:
48 | version: 3.1.x
49 | performMultiLevelLookup: true
50 | installationPath: $(Agent.ToolsDirectory)/dotnet
51 | - task: UseDotNet@2
52 | displayName: 'Use .NET Core 2.1 SDK'
53 | inputs:
54 | version: 2.1.x
55 | performMultiLevelLookup: true
56 | installationPath: $(Agent.ToolsDirectory)/dotnet
57 |
58 | - powershell: ./build.ps1 -clean -configuration Release -build $(testConfig)
59 | displayName: build and run
60 | env:
61 | # Environment variables for IoT hub device samples
62 | IOTHUB_DEVICE_CONN_STRING: $(IOTHUB-DEVICE-CONN-STRING)
63 | IOTHUB_MODULE_CONN_STRING: $(IOTHUB-MODULE-CONN-STRING)
64 | PNP_TC_DEVICE_CONN_STRING: $(PNP-TC-DEVICE-CONN-STRING)
65 | PNP_THERMOSTAT_DEVICE_CONN_STRING: $(PNP-THERMOSTAT-DEVICE-CONN-STRING)
66 |
67 | # Environment variables for IoT hub service samples
68 | IOTHUB_CONNECTION_STRING: $(IOTHUB-CONNECTION-STRING)
69 | IOTHUB_X509_DEVICE_PFX_THUMBPRINT: $(IOTHUB-X509-DEVICE-PFX-THUMBPRINT)
70 | STORAGE_ACCOUNT_CONNECTION_STRING: $(STORAGE-ACCOUNT-CONNECTION-STRING)
71 | FAR_AWAY_IOTHUB_CONNECTION_STRING: $(FAR-AWAY-IOTHUB-CONNECTION-STRING)
72 | MSFT_TENANT_ID: $(MSFT-TENANT-ID)
73 | E2E_TEST_AAD_APP_CLIENT_ID: $(E2E-TEST-AAD-APP-CLIENT-ID)
74 | E2E_TEST_AAD_APP_CLIENT_SECRET: $(E2E-TEST-AAD-APP-CLIENT-SECRET)
75 | IOT_HUB_SAS_KEY: $(IOTHUB-SAS-KEY)
76 | IOT_HUB_SAS_KEY_NAME: $(IOTHUB-SAS-KEY-NAME)
77 |
78 | # PATH-TO-DEVICE-PREFIX-FOR-DELETION-FILE is a variable configured on the pipeline. The possible values are: csharp_devices_list.csv, csharp_samples_devices_list.csv.
79 | # The value of this variable determines whether to delete devices created by the sample or e2e tests.
80 | # csharp_devices_list.csv contains the prefixes of devices created by e2e tests.
81 | # csharp_samples_devices_list.csv contains the prefixes of devices created by samples.
82 | PATH_TO_DEVICE_PREFIX_FOR_DELETION_FILE: $(PATH-TO-DEVICE-PREFIX-FOR-DELETION-FILE)
83 |
84 | # Environment variables for DPS device samples
85 | DPS_IDSCOPE: $(DPS-IDSCOPE)
86 | DPS_SYMMETRIC_KEY_INDIVIDUAL_ENROLLMENT_REGISTRATION_ID : $(DPS-SYMMETRIC-KEY-INDIVIDUAL-ENROLLMENT-REGISTRATION-ID)
87 | DPS_SYMMETRIC_KEY_INDIVIDUAL_ENROLLEMNT_PRIMARY_KEY : $(DPS-SYMMETRIC-KEY-INDIVIDUAL-ENROLLEMNT-PRIMARY-KEY)
88 |
89 | # Environment variables for DPS service samples
90 | PROVISIONING_CONNECTION_STRING: $(PROVISIONING-CONNECTION-STRING)
91 |
92 | - task: ComponentGovernanceComponentDetection@0
93 | displayName: Component Governance Detection
94 | inputs:
95 | scanType: 'Register'
96 | verbosity: 'Verbose'
97 | alertWarningLevel: 'Low' # The task will present a warning, but will not cause the build to fail
98 | condition: always()
99 |
100 | ### Windows build ###
101 | - job: WINDOWS
102 | displayName: Windows (timeout=${{ parameters.jobTimeoutInMinutes }}mins)
103 | # Since the samples run against the same Azure resources, CRUD operations will fight for the same resources.
104 | # So, the builds have been serialized. Comment out the line below to run them in parallel.
105 | dependsOn: LINUX
106 | condition: succeeded()
107 | pool:
108 | vmImage: 'windows-latest'
109 | timeoutInMinutes: ${{ parameters.jobTimeoutInMinutes }}
110 | steps:
111 | - task: UseDotNet@2
112 | displayName: 'Use .NET 6.0 SDK'
113 | inputs:
114 | version: 6.0.x
115 | performMultiLevelLookup: true
116 | installationPath: $(Agent.ToolsDirectory)/dotnet
117 | - task: UseDotNet@2
118 | displayName: 'Use .NET 5.0 SDK'
119 | inputs:
120 | version: 5.0.x
121 | performMultiLevelLookup: true
122 | installationPath: $(Agent.ToolsDirectory)/dotnet
123 | - task: UseDotNet@2
124 | displayName: 'Use .NET Core 3.1 SDK'
125 | inputs:
126 | version: 3.1.x
127 | performMultiLevelLookup: true
128 | installationPath: $(Agent.ToolsDirectory)/dotnet
129 | - task: UseDotNet@2
130 | displayName: 'Use .NET Core 2.1 SDK'
131 | inputs:
132 | version: 2.1.x
133 | performMultiLevelLookup: true
134 | installationPath: $(Agent.ToolsDirectory)/dotnet
135 |
136 | - powershell: ./build.ps1 -clean -configuration Release -build $(testConfig)
137 | displayName: build and run
138 | env:
139 | # Environment variables for IoT hub device samples
140 | IOTHUB_DEVICE_CONN_STRING: $(IOTHUB-DEVICE-CONN-STRING)
141 | IOTHUB_MODULE_CONN_STRING: $(IOTHUB-MODULE-CONN-STRING)
142 | PNP_TC_DEVICE_CONN_STRING: $(PNP-TC-DEVICE-CONN-STRING)
143 | PNP_THERMOSTAT_DEVICE_CONN_STRING: $(PNP-THERMOSTAT-DEVICE-CONN-STRING)
144 |
145 | # Environment variables for IoT hub service samples
146 | IOTHUB_CONNECTION_STRING: $(IOTHUB-CONNECTION-STRING)
147 | IOTHUB_X509_DEVICE_PFX_THUMBPRINT: $(IOTHUB-X509-DEVICE-PFX-THUMBPRINT)
148 | STORAGE_ACCOUNT_CONNECTION_STRING: $(STORAGE-ACCOUNT-CONNECTION-STRING)
149 | FAR_AWAY_IOTHUB_CONNECTION_STRING: $(FAR-AWAY-IOTHUB-CONNECTION-STRING)
150 | MSFT_TENANT_ID: $(MSFT-TENANT-ID)
151 | E2E_TEST_AAD_APP_CLIENT_ID: $(E2E-TEST-AAD-APP-CLIENT-ID)
152 | E2E_TEST_AAD_APP_CLIENT_SECRET: $(E2E-TEST-AAD-APP-CLIENT-SECRET)
153 | IOT_HUB_SAS_KEY: $(IOTHUB-SAS-KEY)
154 | IOT_HUB_SAS_KEY_NAME: $(IOTHUB-SAS-KEY-NAME)
155 |
156 | # PATH-TO-DEVICE-PREFIX-FOR-DELETION-FILE is a variable configured on the pipeline. The possible values are: csharp_devices_list.csv, csharp_samples_devices_list.csv.
157 | # The value of this variable determines whether to delete devices created by the sample or e2e tests.
158 | # csharp_devices_list.csv contains the prefixes of devices created by e2e tests.
159 | # csharp_samples_devices_list.csv contains the prefixes of devices created by samples.
160 | PATH_TO_DEVICE_PREFIX_FOR_DELETION_FILE: $(PATH-TO-DEVICE-PREFIX-FOR-DELETION-FILE)
161 |
162 | # Environment variables for DPS device samples
163 | DPS_IDSCOPE: $(DPS-IDSCOPE)
164 | DPS_SYMMETRIC_KEY_INDIVIDUAL_ENROLLMENT_REGISTRATION_ID : $(DPS-SYMMETRIC-KEY-INDIVIDUAL-ENROLLMENT-REGISTRATION-ID)
165 | DPS_SYMMETRIC_KEY_INDIVIDUAL_ENROLLEMNT_PRIMARY_KEY : $(DPS-SYMMETRIC-KEY-INDIVIDUAL-ENROLLEMNT-PRIMARY-KEY)
166 |
167 | # Environment variables for DPS service samples
168 | PROVISIONING_CONNECTION_STRING: $(PROVISIONING-CONNECTION-STRING)
169 |
170 | - task: ComponentGovernanceComponentDetection@0
171 | displayName: Component Governance Detection
172 | inputs:
173 | scanType: 'Register'
174 | verbosity: 'Verbose'
175 | alertWarningLevel: 'Low' # The task will present a warning, but will not cause the build to fail
176 | condition: always()
177 |
--------------------------------------------------------------------------------