From a96ff20b7c4b41c92f394eaed9c022ecfb12e4eb Mon Sep 17 00:00:00 2001 From: alianides Date: Mon, 22 Jul 2024 21:45:44 +0000 Subject: [PATCH 1/8] initial starter plugin for geospatial-images-vth-plugin --- .../devcontainer.json | 124 ++++++ .../geospatial-images/plugin/.editorconfig | 140 ++++++ .../plugin/.vscode/launch.json | 84 ++++ .../plugin/.vscode/settings.json | 6 + .../plugin/.vscode/tasks.json | 163 +++++++ .../geospatial-images/plugin/README.md | 1 + .../plugin/debugPayloadApp/Program.cs | 53 +++ .../Properties/launchSettings.json | 11 + .../Services/MessageHandler.cs | 25 ++ .../debugPayloadApp/Services/MessageSender.cs | 407 ++++++++++++++++++ .../plugin/debugPayloadApp/Usings.cs | 7 + .../plugin/debugPayloadApp/appsettings.json | 12 + .../debugPayloadApp/debugPayloadApp.csproj | 13 + .../plugin/geospatial-images-vth-plugin.sln | 31 ++ .../geospatial-images/plugin/omnisharp.json | 13 + .../plugin/sampleData/astronaut.jpg | Bin 0 -> 183180 bytes .../plugin/src/Protos/ImageProvider.proto | 31 ++ .../geospatial-images/plugin/src/Usings.cs | 7 + .../src/geospatial-images-vth-plugin.csproj | 19 + ...eospatial-images-vth-plugin.spacefx_plugin | 10 + .../geospatial-images/plugin/src/plugin.cs | 159 +++++++ 21 files changed, 1316 insertions(+) create mode 100644 .devcontainer/geospatial-images-vth-plugin/devcontainer.json create mode 100644 datagenerators/geospatial-images/plugin/.editorconfig create mode 100644 datagenerators/geospatial-images/plugin/.vscode/launch.json create mode 100644 datagenerators/geospatial-images/plugin/.vscode/settings.json create mode 100644 datagenerators/geospatial-images/plugin/.vscode/tasks.json create mode 100644 datagenerators/geospatial-images/plugin/README.md create mode 100755 datagenerators/geospatial-images/plugin/debugPayloadApp/Program.cs create mode 100755 datagenerators/geospatial-images/plugin/debugPayloadApp/Properties/launchSettings.json create mode 100644 datagenerators/geospatial-images/plugin/debugPayloadApp/Services/MessageHandler.cs create mode 100644 datagenerators/geospatial-images/plugin/debugPayloadApp/Services/MessageSender.cs create mode 100755 datagenerators/geospatial-images/plugin/debugPayloadApp/Usings.cs create mode 100755 datagenerators/geospatial-images/plugin/debugPayloadApp/appsettings.json create mode 100755 datagenerators/geospatial-images/plugin/debugPayloadApp/debugPayloadApp.csproj create mode 100644 datagenerators/geospatial-images/plugin/geospatial-images-vth-plugin.sln create mode 100644 datagenerators/geospatial-images/plugin/omnisharp.json create mode 100644 datagenerators/geospatial-images/plugin/sampleData/astronaut.jpg create mode 100644 datagenerators/geospatial-images/plugin/src/Protos/ImageProvider.proto create mode 100644 datagenerators/geospatial-images/plugin/src/Usings.cs create mode 100644 datagenerators/geospatial-images/plugin/src/geospatial-images-vth-plugin.csproj create mode 100644 datagenerators/geospatial-images/plugin/src/geospatial-images-vth-plugin.spacefx_plugin create mode 100644 datagenerators/geospatial-images/plugin/src/plugin.cs diff --git a/.devcontainer/geospatial-images-vth-plugin/devcontainer.json b/.devcontainer/geospatial-images-vth-plugin/devcontainer.json new file mode 100644 index 0000000..5951dfa --- /dev/null +++ b/.devcontainer/geospatial-images-vth-plugin/devcontainer.json @@ -0,0 +1,124 @@ +// For format details, see https://aka.ms/devcontainer.json. For config options, see the +// README at: https://github.com/devcontainers/templates/tree/main/src/dotnet +{ + "name": "geospatial-images-vth-plugin", + "image": "mcr.microsoft.com/devcontainers/dotnet:0-6.0", + "runArgs": [ + "--name=geospatial-images-vth-plugin" + ], + "workspaceFolder": "/workspace/geospatial-images-vth-plugin", + "workspaceMount": "source=${localWorkspaceFolder}/datagenerators/geospatial-images/plugin,target=/workspace/geospatial-images-vth-plugin,type=bind,consistency=cached", + "features": { + "ghcr.io/microsoft/azure-orbital-space-sdk/spacefx-dev:0.11.0": { + "app_name": "geospatial-images-vth-plugin", + "app_type": "vth-plugin", + "addl_debug_shim_suffixes": "client", + "pull_containers": "datagenerator-geospatial-images:0.11.0-nightly", + "download_artifacts": "datagenerator-geospatial-images.yaml" + } + }, + "mounts": [ + "source=${localWorkspaceFolder}/datagenerators/geospatial-images/datagenerator,target=/workspace/geospatial-images-vth-datagenerator,type=bind,consistency=cached" + ], + "hostRequirements": { + "cpus": 8, + "memory": "8gb" + }, + "customizations": { + "vscode": { + "extensions": [ + "ms-dotnettools.csharp", + "ms-dotnettools.csdevkit", + "DavidAnson.vscode-markdownlint", + "zxh404.vscode-proto3", + "mutantdino.resourcemonitor", + "josefpihrt-vscode.roslynator", + "bierner.markdown-mermaid" + ] + }, + // Grant permissions to the Azure Orbital Space SDK repositories and their packages + "codespaces": { + "repositories": { + "microsoft/azure-orbital-space-sdk": { + "permissions": { + "contents": "read", + "packages": "read" + } + }, + "microsoft/azure-orbital-space-sdk-core": { + "permissions": { + "contents": "read", + "packages": "read" + } + }, + "microsoft/azure-orbital-space-sdk-setup": { + "permissions": { + "contents": "read", + "packages": "read" + } + }, + "microsoft/azure-orbital-space-sdk-coresvc-registry": { + "permissions": { + "contents": "read", + "packages": "read" + } + }, + "microsoft/azure-orbital-space-sdk-coresvc-fileserver": { + "permissions": { + "contents": "read", + "packages": "read" + } + }, + "microsoft/azure-orbital-space-sdk-coresvc-switchboard": { + "permissions": { + "contents": "read", + "packages": "read" + } + }, + "microsoft/azure-orbital-space-sdk-platform-mts": { + "permissions": { + "contents": "read", + "packages": "read" + } + }, + "microsoft/azure-orbital-space-sdk-platform-deployment": { + "permissions": { + "contents": "read", + "packages": "read" + } + }, + "microsoft/azure-orbital-space-sdk-vth": { + "permissions": { + "contents": "read", + "packages": "read" + } + }, + "microsoft/azure-orbital-space-sdk-hostsvc-link": { + "permissions": { + "contents": "read", + "packages": "read" + } + }, + "microsoft/azure-orbital-space-sdk-hostsvc-logging": { + "permissions": { + "contents": "read", + "packages": "read" + } + }, + "microsoft/azure-orbital-space-sdk-hostsvc-position": { + "permissions": { + "contents": "read", + "packages": "read" + } + }, + "microsoft/azure-orbital-space-sdk-hostsvc-sensor": { + "permissions": { + "contents": "read", + "packages": "read" + } + } + } + } + }, + "remoteUser": "root" +} \ No newline at end of file diff --git a/datagenerators/geospatial-images/plugin/.editorconfig b/datagenerators/geospatial-images/plugin/.editorconfig new file mode 100644 index 0000000..be15e47 --- /dev/null +++ b/datagenerators/geospatial-images/plugin/.editorconfig @@ -0,0 +1,140 @@ +# Imported from: https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/code-style-rule-options +# For dotnet and C# settings: https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/categories + +############################### +# Core EditorConfig Options # +############################### +root = true +# All files +[*] +indent_style = space +trim_trailing_whitespace = true +end_of_line = lf +insert_final_newline = true + +# XML project files +[*.{csproj,vbproj,vcxproj,vcxproj.filters,proj,projitems,shproj}] +indent_size = 2 + +# XML config files +[*.{props,targets,ruleset,config,nuspec,resx,vsixmanifest,vsct}] +indent_size = 2 + +# Code files +[*.{cs,csx,vb,vbx}] +indent_size = 4 +insert_final_newline = true +charset = utf-8-bom +############################### +# .NET Coding Conventions # +############################### +[*.{cs,vb}] +# file_header_template = Copyright (c) Microsoft. All Rights Reserved. +# Organize usings +dotnet_sort_system_directives_first = true +# this. preferences +dotnet_style_qualification_for_field = false:silent +dotnet_style_qualification_for_property = false:silent +dotnet_style_qualification_for_method = false:silent +dotnet_style_qualification_for_event = false:silent +# Language keywords vs BCL types preferences +dotnet_style_predefined_type_for_locals_parameters_members = true:silent +dotnet_style_predefined_type_for_member_access = true:silent +# Parentheses preferences +dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity:suggestion +dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity:suggestion +dotnet_style_parentheses_in_other_binary_operators = always_for_clarity:suggestion +dotnet_style_parentheses_in_other_operators = never_if_unnecessary:suggestion +# Modifier preferences +dotnet_style_require_accessibility_modifiers = for_non_interface_members:silent +dotnet_style_readonly_field = true:suggestion +# Expression-level preferences +dotnet_style_object_initializer = true:suggestion +dotnet_style_collection_initializer = true:suggestion +dotnet_style_explicit_tuple_names = true:suggestion +dotnet_style_null_propagation = true:suggestion +dotnet_style_coalesce_expression = true:suggestion +dotnet_style_prefer_is_null_check_over_reference_equality_method = true:silent +dotnet_style_prefer_inferred_tuple_names = true:suggestion +dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion +dotnet_style_prefer_auto_properties = true:silent +dotnet_style_prefer_conditional_expression_over_assignment = true:silent +dotnet_style_prefer_conditional_expression_over_return = true:silent +############################### +# Naming Conventions # +############################### +# Style Definitions +dotnet_naming_style.pascal_case_style.capitalization = pascal_case +dotnet_naming_style.pascal_case_style.capitalization.severity = suggestion +# Use PascalCase for constant fields +dotnet_naming_rule.constant_fields_should_be_pascal_case.severity = suggestion +dotnet_naming_rule.constant_fields_should_be_pascal_case.symbols = constant_fields +dotnet_naming_rule.constant_fields_should_be_pascal_case.style = pascal_case_style +dotnet_naming_symbols.constant_fields.applicable_kinds = field +dotnet_naming_symbols.constant_fields.applicable_accessibilities = * +dotnet_naming_symbols.constant_fields.required_modifiers = const +############################### +# C# Coding Conventions # +############################### +[*.cs] +# var preferences +csharp_style_var_for_built_in_types = true:silent +csharp_style_var_when_type_is_apparent = true:silent +csharp_style_var_elsewhere = true:silent +# Expression-bodied members +csharp_style_expression_bodied_methods = false:silent +csharp_style_expression_bodied_constructors = false:silent +csharp_style_expression_bodied_operators = false:silent +csharp_style_expression_bodied_properties = true:silent +csharp_style_expression_bodied_indexers = true:silent +csharp_style_expression_bodied_accessors = true:silent +# Pattern matching preferences +csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion +csharp_style_pattern_matching_over_as_with_null_check = true:suggestion +# Null-checking preferences +csharp_style_throw_expression = true:suggestion +csharp_style_conditional_delegate_call = true:suggestion +# Modifier preferences +csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async:suggestion +# Expression-level preferences +csharp_prefer_braces = true:silent +csharp_style_deconstructed_variable_declaration = true:suggestion +csharp_prefer_simple_default_expression = true:suggestion +csharp_style_prefer_local_over_anonymous_function = true:suggestion +csharp_style_inlined_variable_declaration = true:suggestion +############################### +# C# Formatting Rules # +############################### +# New line preferences +csharp_new_line_before_open_brace = false +csharp_new_line_before_else = false +csharp_new_line_before_catch = false +csharp_new_line_before_finally = false +csharp_new_line_before_members_in_object_initializers = false +csharp_new_line_before_members_in_anonymous_types = false +csharp_new_line_between_query_expression_clauses = false +# Indentation preferences +csharp_indent_case_contents = true +csharp_indent_switch_labels = true +csharp_indent_labels = flush_left +# Space preferences +csharp_space_after_cast = true +csharp_space_after_keywords_in_control_flow_statements = true +csharp_space_between_method_call_parameter_list_parentheses = false +csharp_space_between_method_declaration_parameter_list_parentheses = false +csharp_space_between_parentheses = true +csharp_space_before_colon_in_inheritance_clause = true +csharp_space_after_colon_in_inheritance_clause = true +csharp_space_around_binary_operators = before_and_after +csharp_space_between_method_declaration_empty_parameter_list_parentheses = false +csharp_space_between_method_call_name_and_opening_parenthesis = false +csharp_space_between_method_call_empty_parameter_list_parentheses = false +# Wrapping preferences +csharp_preserve_single_line_statements = true +csharp_preserve_single_line_blocks = true +############################### +# VB Coding Conventions # +############################### +[*.vb] +# Modifier preferences +visual_basic_preferred_modifier_order = Partial,Default,Private,Protected,Public,Friend,NotOverridable,Overridable,MustOverride,Overloads,Overrides,MustInherit,NotInheritable,Static,Shared,Shadows,ReadOnly,WriteOnly,Dim,Const,WithEvents,Widening,Narrowing,Custom,Async:suggestion \ No newline at end of file diff --git a/datagenerators/geospatial-images/plugin/.vscode/launch.json b/datagenerators/geospatial-images/plugin/.vscode/launch.json new file mode 100644 index 0000000..7b67960 --- /dev/null +++ b/datagenerators/geospatial-images/plugin/.vscode/launch.json @@ -0,0 +1,84 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "name": "vth", + "type": "coreclr", + "request": "launch", + "program": "/usr/bin/dotnet", + "preLaunchTask": "deploy-debugshim-host", + "args": [ + "${workspaceFolder}/.git/workspaces/vth/vth.dll" + ], + "env": { + "DOTNET_ENVIRONMENT": "PluginDev" + }, + "cwd": "${workspaceFolder}/src", + "stopAtEntry": false, + "console": "internalConsole", + "pipeTransport": { + "pipeCwd": "${workspaceRoot}/src", + "pipeProgram": "bash", + "pipeArgs": [ + "-c \" kubectl exec --stdin $(kubectl get pods -l app=vth -n payload-app --sort-by=.metadata.creationTimestamp -o jsonpath=\"{.items[-1:].metadata.name}\") -n payload-app -c vth -- " + ], + "quoteArgs": false, + "debuggerPath": "${workspaceFolder}/.git/spacefx-dev/vsdbg/vsdbg" + }, + "postDebugTask": "reset-debugshim-host", + "presentation": { + "hidden": false, + "group": "", + "order": 1 + }, + "requireExactSource": true + }, + { + "name": "DebugPayloadApp", + "type": "coreclr", + "request": "launch", + "program": "/usr/bin/dotnet", + "preLaunchTask": "deploy-debugshim-client", + "args": [ + "${workspaceFolder}/debugPayloadApp/bin/Debug/net6.0/debugPayloadApp.dll" + ], + "env": { + "DOTNET_ENVIRONMENT": "Development" + }, + "cwd": "${workspaceFolder}/debugPayloadApp", + "stopAtEntry": false, + "console": "internalConsole", + "pipeTransport": { + "pipeCwd": "${workspaceRoot}/debugPayloadApp", + "pipeProgram": "bash", + "pipeArgs": [ + "-c \" kubectl exec --stdin $(kubectl get pods -l app=vth-client -n payload-app --sort-by=.metadata.creationTimestamp -o jsonpath=\"{.items[-1:].metadata.name}\") -n payload-app -c vth-client -- " + ], + "quoteArgs": false, + "debuggerPath": "${workspaceFolder}/.git/spacefx-dev/vsdbg/vsdbg" + }, + "postDebugTask": "reset-debugshim-client", + "presentation": { + "hidden": false, + "group": "", + "order": 1 + }, + "requireExactSource": true + } + ], + "compounds": [ + { + "name": "vth & DebugPayloadApp", + "configurations": [ + "vth", + "DebugPayloadApp" + ], + "stopAll": true, + "presentation": { + "hidden": false, + "group": "debug", + "order": 2 + } + } + ] +} \ No newline at end of file diff --git a/datagenerators/geospatial-images/plugin/.vscode/settings.json b/datagenerators/geospatial-images/plugin/.vscode/settings.json new file mode 100644 index 0000000..c30e631 --- /dev/null +++ b/datagenerators/geospatial-images/plugin/.vscode/settings.json @@ -0,0 +1,6 @@ +{ + "omnisharp.useEditorFormattingSettings": false, // ignores any Visual Studio Code user or machine preferences for formatting and instead enforces the omnisharp.json and .editorconfig in this workspace + "omnisharp.enableRoslynAnalyzers": true, + "editor.formatOnSave": true, + "dotnet.completion.showCompletionItemsFromUnimportedNamespaces": true +} \ No newline at end of file diff --git a/datagenerators/geospatial-images/plugin/.vscode/tasks.json b/datagenerators/geospatial-images/plugin/.vscode/tasks.json new file mode 100644 index 0000000..3679ebe --- /dev/null +++ b/datagenerators/geospatial-images/plugin/.vscode/tasks.json @@ -0,0 +1,163 @@ +{ + "version": "2.0.0", + "options": { + "env": { + "DEBUG_SHIM_HOST": "vth", + "DEBUG_SHIM_CLIENT": "vth-client", + } + }, + "tasks": [ + { + "label": "deploy-debugshim-host", + "isBackground": false, + "command": "/bin/bash", + "type": "shell", + "dependsOn": [ + "build", + ], + "dependsOrder": "sequence", + "args": [ + "/spacefx-dev/debugShim-deploy.sh", + "--debug_shim", + "${DEBUG_SHIM_HOST}" + ], + "presentation": { + "echo": true, + "reveal": "never", + "focus": false, + "panel": "shared", + "showReuseMessage": false, + "clear": false + } + }, + { + "label": "reset-debugshim-host", + "isBackground": true, + "command": "/bin/bash", + "type": "shell", + "dependsOrder": "sequence", + "args": [ + "/spacefx-dev/debugShim-reset.sh", + "--debug_shim", + "${DEBUG_SHIM_HOST}", + "--skip-pod-wait" + ], + "presentation": { + "echo": false, + "reveal": "never", + "focus": false, + "panel": "shared", + "showReuseMessage": false, + "clear": false + } + }, + { + "label": "build", + "command": "dotnet", + "type": "process", + "args": [ + "build", + "${workspaceFolder}/src/geospatial-images-vth-plugin.csproj", + "/property:GenerateFullPaths=true", + "/consoleloggerparameters:NoSummary" + ], + "problemMatcher": "$msCompile" + }, + { + "label": "deploy-debugshim-client", + "isBackground": false, + "command": "/bin/bash", + "type": "shell", + "dependsOn": [ + "pause-processing", + "build-client" + ], + "dependsOrder": "sequence", + "args": [ + "/spacefx-dev/debugShim-deploy.sh", + "--debug_shim", + "${DEBUG_SHIM_CLIENT}", + "--disable_plugin_configs" + ], + "presentation": { + "echo": true, + "reveal": "never", + "focus": false, + "panel": "shared", + "showReuseMessage": false, + "clear": false + } + }, + { + "label": "reset-debugshim-client", + "isBackground": true, + "command": "/bin/bash", + "type": "shell", + "dependsOrder": "sequence", + "args": [ + "/spacefx-dev/debugShim-reset.sh", + "--debug_shim", + "${DEBUG_SHIM_CLIENT}", + "--skip-pod-wait" + ], + "presentation": { + "echo": false, + "reveal": "never", + "focus": false, + "panel": "shared", + "showReuseMessage": false, + "clear": false + } + }, + { + "label": "build-client", + "command": "dotnet", + "type": "process", + "args": [ + "build", + "${workspaceFolder}/debugPayloadApp/debugPayloadApp.csproj", + "/property:GenerateFullPaths=true", + "/consoleloggerparameters:NoSummary" + ], + "problemMatcher": "$msCompile" + }, + { + "label": "reset-debugshim-test-client", + "isBackground": true, + "command": "/bin/bash", + "type": "shell", + "dependsOrder": "sequence", + "args": [ + "/spacefx-dev/debugShim-reset.sh", + "--debug_shim", + "${DEBUG_SHIM_CLIENT}", + "--skip-pod-wait" + ], + "presentation": { + "echo": false, + "reveal": "never", + "focus": false, + "panel": "shared", + "showReuseMessage": false, + "clear": false + } + }, + { + "label": "pause-processing", + "isBackground": false, + "command": "sleep", + "type": "process", + "args": [ + "3s" + ], + "presentation": { + "echo": false, + "reveal": "never", + "focus": false, + "panel": "shared", + "showReuseMessage": false, + "clear": false + } + } + ] +} \ No newline at end of file diff --git a/datagenerators/geospatial-images/plugin/README.md b/datagenerators/geospatial-images/plugin/README.md new file mode 100644 index 0000000..dbb054c --- /dev/null +++ b/datagenerators/geospatial-images/plugin/README.md @@ -0,0 +1 @@ +README doc for writing a VTH plugin \ No newline at end of file diff --git a/datagenerators/geospatial-images/plugin/debugPayloadApp/Program.cs b/datagenerators/geospatial-images/plugin/debugPayloadApp/Program.cs new file mode 100755 index 0000000..05fe317 --- /dev/null +++ b/datagenerators/geospatial-images/plugin/debugPayloadApp/Program.cs @@ -0,0 +1,53 @@ +using Microsoft.Azure.SpaceFx.MessageFormats.Common; +using Microsoft.Azure.SpaceFx.MessageFormats.HostServices.Sensor; + +namespace DebugClient; + +public class Program { + public static void Main(string[] args) { + var builder = WebApplication.CreateBuilder(args); + + builder.Configuration.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true); + + builder.WebHost.ConfigureKestrel(options => options.ListenAnyIP(50051, o => o.Protocols = HttpProtocols.Http2)) + .ConfigureServices((services) => { + services.AddAzureOrbitalFramework(); + services.AddHostedService(); + + // Register with the messages we're expecting to receive from the service + services.AddSingleton, MessageHandler>(); + services.AddSingleton, MessageHandler>(); + services.AddSingleton, MessageHandler>(); + services.AddSingleton, MessageHandler>(); + services.AddSingleton, MessageHandler>(); + services.AddSingleton, MessageHandler>(); + services.AddSingleton, MessageHandler>(); + services.AddSingleton, MessageHandler>(); + services.AddSingleton, MessageHandler>(); + + }).ConfigureLogging((logging) => { + // Enable the Azure Orbital Space SDK Logging to route messages to the hostsvc-logging + logging.AddProvider(new Microsoft.Extensions.Logging.SpaceFX.Logger.HostSvcLoggerProvider()); + logging.AddConsole(); + }); + + var app = builder.Build(); + + // Configure a global exception handler to log the exception and stop the application on any uncaught exceptions + app.Use(async (context, next) => { + var logger = app.Services.GetRequiredService>(); + var appLifetime = app.Services.GetRequiredService(); + try { + await next(); + } catch (Exception ex) { + logger.LogError(ex, "Unhandled exception occurred. Stopping the application."); + appLifetime.StopApplication(); + throw; // Re-throwing the exception is optional and depends on how you want to handle the error response. + } + }); + + app.UseRouting(); + app.UseEndpoints(endpoints => endpoints.MapGrpcService()); + app.Run(); + } +} diff --git a/datagenerators/geospatial-images/plugin/debugPayloadApp/Properties/launchSettings.json b/datagenerators/geospatial-images/plugin/debugPayloadApp/Properties/launchSettings.json new file mode 100755 index 0000000..d588f81 --- /dev/null +++ b/datagenerators/geospatial-images/plugin/debugPayloadApp/Properties/launchSettings.json @@ -0,0 +1,11 @@ +{ + "profiles": { + "debugClient": { + "commandName": "Project", + "dotnetRunMessages": true, + "environmentVariables": { + "DOTNET_ENVIRONMENT": "Development" + } + } + } +} diff --git a/datagenerators/geospatial-images/plugin/debugPayloadApp/Services/MessageHandler.cs b/datagenerators/geospatial-images/plugin/debugPayloadApp/Services/MessageHandler.cs new file mode 100644 index 0000000..845ede8 --- /dev/null +++ b/datagenerators/geospatial-images/plugin/debugPayloadApp/Services/MessageHandler.cs @@ -0,0 +1,25 @@ +namespace DebugClient; + +public class MessageHandler : Core.IMessageHandler where T : notnull { + private readonly ILogger> _logger; + private readonly IServiceProvider _serviceProvider; + public static event EventHandler? MessageReceivedEvent; + public MessageHandler(ILogger> logger, IServiceProvider serviceProvider) { + _logger = logger; + _serviceProvider = serviceProvider; + } + + public void MessageReceived(T message, Microsoft.Azure.SpaceFx.MessageFormats.Common.DirectToApp fullMessage) { + using (var scope = _serviceProvider.CreateScope()) { + + _logger.LogInformation($"Receieved message type '{typeof(T).Name}' from '{fullMessage.SourceAppId}'"); + + if (MessageReceivedEvent != null) { + foreach (Delegate handler in MessageReceivedEvent.GetInvocationList()) { + Task.Factory.StartNew( + () => handler.DynamicInvoke(fullMessage.SourceAppId, message)); + } + } + } + } +} \ No newline at end of file diff --git a/datagenerators/geospatial-images/plugin/debugPayloadApp/Services/MessageSender.cs b/datagenerators/geospatial-images/plugin/debugPayloadApp/Services/MessageSender.cs new file mode 100644 index 0000000..82a058e --- /dev/null +++ b/datagenerators/geospatial-images/plugin/debugPayloadApp/Services/MessageSender.cs @@ -0,0 +1,407 @@ +using Microsoft.Azure.SpaceFx.MessageFormats.Common; +using Microsoft.Azure.SpaceFx.MessageFormats.HostServices.Sensor; + +namespace DebugClient; + +public class MessageSender : BackgroundService { + private readonly ILogger _logger; + private readonly IServiceProvider _serviceProvider; + private readonly Core.Client _client; + private readonly string _appId; + private readonly string _hostSvcAppId; + private readonly List _appsOnline = new(); + private readonly TimeSpan MAX_TIMESPAN_TO_WAIT_FOR_MSG = TimeSpan.FromSeconds(10); + private readonly string _testFile = "/workspace/geospatial-images-vth-plugin/sampleData/astronaut.jpg"; + + public MessageSender(ILogger logger, IServiceProvider serviceProvider) { + _logger = logger; + _serviceProvider = serviceProvider; + _client = _serviceProvider.GetService() ?? throw new NullReferenceException($"{nameof(Core.Client)} is null"); + _appId = _client.GetAppID().Result; + _hostSvcAppId = _appId.Replace("-client", ""); + } + + protected override async Task ExecuteAsync(CancellationToken stoppingToken) { + DateTime maxTimeToWait = DateTime.Now.Add(TimeSpan.FromSeconds(10)); + + using (var scope = _serviceProvider.CreateScope()) { + _logger.LogInformation("MessageSender running at: {time}", DateTimeOffset.Now); + + Boolean SVC_ONLINE = _client.ServicesOnline().Any(pulse => pulse.AppId.Equals(_hostSvcAppId, StringComparison.CurrentCultureIgnoreCase)); + + _logger.LogInformation($"Waiting for service '{_hostSvcAppId}' to come online..."); + + while (!SVC_ONLINE && DateTime.Now < maxTimeToWait) { + await Task.Delay(1000); + SVC_ONLINE = _client.ServicesOnline().Any(pulse => pulse.AppId.Equals(_hostSvcAppId, StringComparison.CurrentCultureIgnoreCase)); + ListHeardServices(); + } + + if (!SVC_ONLINE) { + throw new Exception($"Service '{_hostSvcAppId}' did not come online in time."); + } + + // Hostsvc-Position endpoints + await UpdatePosition(); + await GetCurrentPosition(); + + // Hostsvc-Link endpoints + await SendFileRootDirectory(); + + // Hostsvc-Logging endpoints + await SendTelemetryMetric(); + await SendLogMessage(); + + // Hostsvc-Sensor endpoints + RegisterForSensorData(); + await SendPluginHealthCheck(); + await SendSensorsAvailableRequest(); + await SendTaskingPreCheckRequest(); + await SendTaskingRequest(); + + _logger.LogInformation("DebugPayloadApp completed at: {time}", DateTimeOffset.Now); + } + } + + private void ListHeardServices() { + _client.ServicesOnline().ForEach((pulse) => { + if (_appsOnline.Contains(pulse.AppId)) return; + _appsOnline.Add(pulse.AppId); + _logger.LogInformation($"App:...{pulse.AppId}..."); + }); + } + + private async Task SendPluginHealthCheck() { + DateTime maxTimeToWait = DateTime.Now.Add(TimeSpan.FromSeconds(10)); + PluginHealthCheckMultiResponse? response = null; + PluginHealthCheckRequest request = new() { + RequestHeader = new() { + TrackingId = Guid.NewGuid().ToString(), + CorrelationId = Guid.NewGuid().ToString() + } + }; + + _logger.LogInformation($"Sending Plugin Healthcheck request (TrackingId: '{request.RequestHeader.TrackingId}')"); + + // Register a callback event to catch the response + void PluginResponseEventHandler(object? _, PluginHealthCheckMultiResponse _response) { + response = _response; + MessageHandler.MessageReceivedEvent -= PluginResponseEventHandler; + } + + MessageHandler.MessageReceivedEvent += PluginResponseEventHandler; + + await _client.DirectToApp(appId: _hostSvcAppId, message: request); + + _logger.LogInformation($"Waiting for response (TrackingId: '{request.RequestHeader.TrackingId}')"); + + while (response == null && DateTime.Now <= maxTimeToWait) { + Thread.Sleep(100); + } + + if (response == null) throw new TimeoutException($"Failed to hear {nameof(response)} after {MAX_TIMESPAN_TO_WAIT_FOR_MSG}. Please check that {_hostSvcAppId} is deployed"); + + if (response.ResponseHeader.Status != Microsoft.Azure.SpaceFx.MessageFormats.Common.StatusCodes.Successful) { + throw new Exception($"Plugin Health Check failed with status '{response.ResponseHeader.Status}' and message '{response.ResponseHeader.Message}'"); + } + + + _logger.LogInformation($"Plugin Healthcheck request received. Status: '{response.ResponseHeader.Status}' (TrackingId: '{request.RequestHeader.TrackingId}')"); + + } + + private async Task UpdatePosition() { + DateTime maxTimeToWait = DateTime.Now.Add(TimeSpan.FromSeconds(10)); + PositionUpdateResponse? response = null; + PositionUpdateRequest request = new() { + RequestHeader = new() { + TrackingId = Guid.NewGuid().ToString(), + CorrelationId = Guid.NewGuid().ToString() + }, + Position = new Position() { + PositionTime = Google.Protobuf.WellKnownTypes.Timestamp.FromDateTime(DateTime.UtcNow), + Point = new Position.Types.Point() { + X = 1, + Y = 2, + Z = 3, + }, + Attitude = new Position.Types.Attitude() { + X = 1, + Y = 2, + Z = 3, + K = 4 + } + } + }; + + _logger.LogInformation($"Sending '{request.GetType().Name}' request (TrackingId: '{request.RequestHeader.TrackingId}')"); + + // Register a callback event to catch the response + void ResponseEventHandler(object? _, PositionUpdateResponse _response) { + response = _response; + MessageHandler.MessageReceivedEvent -= ResponseEventHandler; + } + + MessageHandler.MessageReceivedEvent += ResponseEventHandler; + + await _client.DirectToApp(appId: _hostSvcAppId, message: request); + + _logger.LogInformation($"Waiting for response (TrackingId: '{request.RequestHeader.TrackingId}')"); + + while (response == null && DateTime.Now <= maxTimeToWait) { + Thread.Sleep(100); + } + + if (response == null) throw new TimeoutException($"Failed to hear {nameof(response)} after {MAX_TIMESPAN_TO_WAIT_FOR_MSG}. Please check that {_hostSvcAppId} is deployed"); + + _logger.LogInformation($"'{request.GetType().Name}' request received. Status: '{response.ResponseHeader.Status}' (TrackingId: '{request.RequestHeader.TrackingId}')"); + + } + + private async Task GetCurrentPosition() { + DateTime maxTimeToWait = DateTime.Now.Add(TimeSpan.FromSeconds(10)); + PositionResponse? response = null; + PositionRequest request = new() { + RequestHeader = new() { + TrackingId = Guid.NewGuid().ToString(), + CorrelationId = Guid.NewGuid().ToString() + } + }; + + _logger.LogInformation($"Sending '{request.GetType().Name}' request (TrackingId: '{request.RequestHeader.TrackingId}')"); + + // Register a callback event to catch the response + void ResponseEventHandler(object? _, PositionResponse _response) { + response = _response; + MessageHandler.MessageReceivedEvent -= ResponseEventHandler; + } + + MessageHandler.MessageReceivedEvent += ResponseEventHandler; + + await _client.DirectToApp(appId: _hostSvcAppId, message: request); + + _logger.LogInformation($"Waiting for response (TrackingId: '{request.RequestHeader.TrackingId}')"); + + while (response == null && DateTime.Now <= maxTimeToWait) { + Thread.Sleep(100); + } + + if (response == null) throw new TimeoutException($"Failed to hear {nameof(response)} after {MAX_TIMESPAN_TO_WAIT_FOR_MSG}. Please check that {_hostSvcAppId} is deployed"); + + _logger.LogInformation($"'{request.GetType().Name}' request received. Status: '{response.ResponseHeader.Status}' (TrackingId: '{request.RequestHeader.TrackingId}')"); + + } + + private async Task SendFileRootDirectory() { + var (inbox, outbox, root) = _client.GetXFerDirectories().Result; + + File.Copy(_testFile, string.Format($"{outbox}/{Path.GetFileName(_testFile)}"), overwrite: true); + + LinkRequest request = new() { + RequestHeader = new() { + TrackingId = Guid.NewGuid().ToString(), + CorrelationId = Guid.NewGuid().ToString() + }, + FileName = Path.GetFileName(_testFile), + DestinationAppId = "contoso-app-id" + }; + + await _client.DirectToApp(appId: _hostSvcAppId, message: request); + } + + private async Task SendTelemetryMetric() { + DateTime maxTimeToWait = DateTime.Now.Add(TimeSpan.FromSeconds(10)); + TelemetryMetricResponse? response = null; + + TelemetryMetric request = new() { + RequestHeader = new() { + TrackingId = Guid.NewGuid().ToString(), + CorrelationId = Guid.NewGuid().ToString() + }, + MetricName = "Testing", + MetricValue = 37 + }; + + _logger.LogInformation($"Sending '{request.GetType().Name}' request to '{_hostSvcAppId}' (TrackingId: '{request.RequestHeader.TrackingId}')"); + + // Register a callback event to catch the response + void TelemetryMetricResponseEventHandler(object? _, TelemetryMetricResponse _response) { + if (_response.ResponseHeader.CorrelationId != request.RequestHeader.CorrelationId) return; + response = _response; + MessageHandler.MessageReceivedEvent -= TelemetryMetricResponseEventHandler; + } + + MessageHandler.MessageReceivedEvent += TelemetryMetricResponseEventHandler; + + await _client.DirectToApp(appId: _hostSvcAppId, message: request); + + _logger.LogInformation($"Waiting for response message type (TrackingId: '{request.RequestHeader.TrackingId}')"); + + while (response == null && DateTime.Now <= maxTimeToWait) { + Thread.Sleep(100); + } + + if (response == null) throw new TimeoutException($"Failed to hear {nameof(response)} after {MAX_TIMESPAN_TO_WAIT_FOR_MSG}. Please check that {_hostSvcAppId} is deployed"); + + _logger.LogInformation($"'{request.GetType().Name}'received. Status: '{response.ResponseHeader.Status}' (TrackingId: '{request.RequestHeader.TrackingId}')"); + } + + private async Task SendLogMessage() { + DateTime maxTimeToWait = DateTime.Now.Add(TimeSpan.FromSeconds(10)); + LogMessageResponse? response = null; + + LogMessage request = new() { + RequestHeader = new() { + TrackingId = Guid.NewGuid().ToString(), + CorrelationId = Guid.NewGuid().ToString() + }, + LogLevel = LogMessage.Types.LOG_LEVEL.Info, + Message = "Log Message from DebugPayloadApp", + Priority = Priority.Medium, + }; + + _logger.LogInformation($"Sending '{request.GetType().Name}' request to '{_hostSvcAppId}' (TrackingId: '{request.RequestHeader.TrackingId}')"); + + // Register a callback event to catch the response + void LogMessageResponseEventHandler(object? _, LogMessageResponse _response) { + if (_response.ResponseHeader.CorrelationId != request.RequestHeader.CorrelationId) return; + response = _response; + MessageHandler.MessageReceivedEvent -= LogMessageResponseEventHandler; + } + + MessageHandler.MessageReceivedEvent += LogMessageResponseEventHandler; + + await _client.DirectToApp(appId: _hostSvcAppId, message: request); + + _logger.LogInformation($"Waiting for response message type (TrackingId: '{request.RequestHeader.TrackingId}')"); + + while (response == null && DateTime.Now <= maxTimeToWait) { + Thread.Sleep(100); + } + + if (response == null) throw new TimeoutException($"Failed to hear {nameof(response)} after {MAX_TIMESPAN_TO_WAIT_FOR_MSG}. Please check that {_hostSvcAppId} is deployed"); + + _logger.LogInformation($"'{request.GetType().Name}'received. Status: '{response.ResponseHeader.Status}' (TrackingId: '{request.RequestHeader.TrackingId}')"); + } + + private void RegisterForSensorData() { + + _logger.LogInformation($"Registering a function to process Sensor Data"); + + // Register a callback event to catch the Sensor Data + void SensorDataEventHandler(object? _, SensorData _response) { + _logger.LogInformation($"Received Sensor Data: '{_response.SensorID}'"); + // Do something with data + } + + MessageHandler.MessageReceivedEvent += SensorDataEventHandler; + + _logger.LogInformation($"Successfully registered a function to process any Sensor Data"); + + } + + private async Task SendSensorsAvailableRequest() { + DateTime maxTimeToWait = DateTime.Now.Add(TimeSpan.FromSeconds(10)); + SensorsAvailableResponse? response = null; + SensorsAvailableRequest request = new() { + RequestHeader = new() { + TrackingId = Guid.NewGuid().ToString(), + CorrelationId = Guid.NewGuid().ToString() + } + }; + + _logger.LogInformation($"Sending '{request.GetType().Name}' request (TrackingId: '{request.RequestHeader.TrackingId}')"); + + // Register a callback event to catch the response + void ResponseEventHandler(object? _, SensorsAvailableResponse _response) { + if (_response.ResponseHeader.CorrelationId != request.RequestHeader.CorrelationId) return; + response = _response; + MessageHandler.MessageReceivedEvent -= ResponseEventHandler; + } + + MessageHandler.MessageReceivedEvent += ResponseEventHandler; + + await _client.DirectToApp(appId: _hostSvcAppId, message: request); + + _logger.LogInformation($"Waiting for response (TrackingId: '{request.RequestHeader.TrackingId}')"); + + while (response == null && DateTime.Now <= maxTimeToWait) { + Thread.Sleep(100); + } + + if (response == null) throw new TimeoutException($"Failed to hear {nameof(response)} after {MAX_TIMESPAN_TO_WAIT_FOR_MSG}. Please check that {_hostSvcAppId} is deployed"); + + _logger.LogInformation($"'{request.GetType().Name}' request received. Status: '{response.ResponseHeader.Status}' (TrackingId: '{request.RequestHeader.TrackingId}')"); + + } + + private async Task SendTaskingPreCheckRequest() { + DateTime maxTimeToWait = DateTime.Now.Add(TimeSpan.FromSeconds(10)); + TaskingPreCheckResponse? response = null; + TaskingPreCheckRequest request = new() { + RequestHeader = new() { + TrackingId = Guid.NewGuid().ToString(), + CorrelationId = Guid.NewGuid().ToString() + } + }; + + _logger.LogInformation($"Sending '{request.GetType().Name}' request (TrackingId: '{request.RequestHeader.TrackingId}')"); + + // Register a callback event to catch the response + void ResponseEventHandler(object? _, TaskingPreCheckResponse _response) { + if (_response.ResponseHeader.CorrelationId != request.RequestHeader.CorrelationId) return; + response = _response; + MessageHandler.MessageReceivedEvent -= ResponseEventHandler; + } + + MessageHandler.MessageReceivedEvent += ResponseEventHandler; + + await _client.DirectToApp(appId: _hostSvcAppId, message: request); + + _logger.LogInformation($"Waiting for response (TrackingId: '{request.RequestHeader.TrackingId}')"); + + while (response == null && DateTime.Now <= maxTimeToWait) { + Thread.Sleep(100); + } + + if (response == null) throw new TimeoutException($"Failed to hear {nameof(response)} after {MAX_TIMESPAN_TO_WAIT_FOR_MSG}. Please check that {_hostSvcAppId} is deployed"); + + _logger.LogInformation($"'{request.GetType().Name}' request received. Status: '{response.ResponseHeader.Status}' (TrackingId: '{request.RequestHeader.TrackingId}')"); + + } + + private async Task SendTaskingRequest() { + DateTime maxTimeToWait = DateTime.Now.Add(TimeSpan.FromSeconds(10)); + TaskingResponse? response = null; + TaskingRequest request = new() { + RequestHeader = new() { + TrackingId = Guid.NewGuid().ToString(), + CorrelationId = Guid.NewGuid().ToString() + } + }; + + _logger.LogInformation($"Sending '{request.GetType().Name}' request (TrackingId: '{request.RequestHeader.TrackingId}')"); + + // Register a callback event to catch the response + void ResponseEventHandler(object? _, TaskingResponse _response) { + if (_response.ResponseHeader.CorrelationId != request.RequestHeader.CorrelationId) return; + response = _response; + MessageHandler.MessageReceivedEvent -= ResponseEventHandler; + } + + MessageHandler.MessageReceivedEvent += ResponseEventHandler; + + await _client.DirectToApp(appId: _hostSvcAppId, message: request); + + _logger.LogInformation($"Waiting for response (TrackingId: '{request.RequestHeader.TrackingId}')"); + + while (response == null && DateTime.Now <= maxTimeToWait) { + Thread.Sleep(100); + } + + if (response == null) throw new TimeoutException($"Failed to hear {nameof(response)} after {MAX_TIMESPAN_TO_WAIT_FOR_MSG}. Please check that {_hostSvcAppId} is deployed"); + + _logger.LogInformation($"'{request.GetType().Name}' request received. Status: '{response.ResponseHeader.Status}' (TrackingId: '{request.RequestHeader.TrackingId}')"); + + } +} \ No newline at end of file diff --git a/datagenerators/geospatial-images/plugin/debugPayloadApp/Usings.cs b/datagenerators/geospatial-images/plugin/debugPayloadApp/Usings.cs new file mode 100755 index 0000000..55a671b --- /dev/null +++ b/datagenerators/geospatial-images/plugin/debugPayloadApp/Usings.cs @@ -0,0 +1,7 @@ +global using Microsoft.Extensions.Logging; +global using Microsoft.Azure.SpaceFx; +global using Microsoft.AspNetCore.Server.Kestrel.Core; +global using Microsoft.Azure.SpaceFx.MessageFormats.Common; +global using Microsoft.Azure.SpaceFx.MessageFormats.HostServices.Link; +global using Microsoft.Azure.SpaceFx.MessageFormats.HostServices.Sensor; +global using Microsoft.Azure.SpaceFx.MessageFormats.HostServices.Position; \ No newline at end of file diff --git a/datagenerators/geospatial-images/plugin/debugPayloadApp/appsettings.json b/datagenerators/geospatial-images/plugin/debugPayloadApp/appsettings.json new file mode 100755 index 0000000..596c99e --- /dev/null +++ b/datagenerators/geospatial-images/plugin/debugPayloadApp/appsettings.json @@ -0,0 +1,12 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.Hosting.Lifetime": "Error", + "Microsoft.AspNetCore.Hosting.Diagnostics": "Error", + "Microsoft.AspNetCore.Routing.EndpointMiddleware": "Error", + "Microsoft.Azure.SpaceFx.Core.Utils.SideCar": "Error", + "Microsoft.Azure.SpaceFx.Core.Services.HeartbeatService": "Error" + } + } +} \ No newline at end of file diff --git a/datagenerators/geospatial-images/plugin/debugPayloadApp/debugPayloadApp.csproj b/datagenerators/geospatial-images/plugin/debugPayloadApp/debugPayloadApp.csproj new file mode 100755 index 0000000..6dd3b0c --- /dev/null +++ b/datagenerators/geospatial-images/plugin/debugPayloadApp/debugPayloadApp.csproj @@ -0,0 +1,13 @@ + + + + net6.0 + enable + enable + win-x64;linux-x64;linux-arm64 + + + + + + diff --git a/datagenerators/geospatial-images/plugin/geospatial-images-vth-plugin.sln b/datagenerators/geospatial-images/plugin/geospatial-images-vth-plugin.sln new file mode 100644 index 0000000..c832256 --- /dev/null +++ b/datagenerators/geospatial-images/plugin/geospatial-images-vth-plugin.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.5.002.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "geospatial-images-vth-plugin", "src\geospatial-images-vth-plugin.csproj", "{DDA13A82-3756-4A22-A6B3-4B4EE3062059}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "debugPayloadApp", "debugPayloadApp\debugPayloadApp.csproj", "{455C1F9D-E4B8-4606-8410-F603FB5CA2E2}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {DDA13A82-3756-4A22-A6B3-4B4EE3062059}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {DDA13A82-3756-4A22-A6B3-4B4EE3062059}.Debug|Any CPU.Build.0 = Debug|Any CPU + {DDA13A82-3756-4A22-A6B3-4B4EE3062059}.Release|Any CPU.ActiveCfg = Release|Any CPU + {DDA13A82-3756-4A22-A6B3-4B4EE3062059}.Release|Any CPU.Build.0 = Release|Any CPU + {455C1F9D-E4B8-4606-8410-F603FB5CA2E2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {455C1F9D-E4B8-4606-8410-F603FB5CA2E2}.Debug|Any CPU.Build.0 = Debug|Any CPU + {455C1F9D-E4B8-4606-8410-F603FB5CA2E2}.Release|Any CPU.ActiveCfg = Release|Any CPU + {455C1F9D-E4B8-4606-8410-F603FB5CA2E2}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {4E761151-B04C-4C7E-8567-19139E58D7C1} + EndGlobalSection +EndGlobal diff --git a/datagenerators/geospatial-images/plugin/omnisharp.json b/datagenerators/geospatial-images/plugin/omnisharp.json new file mode 100644 index 0000000..e1e5784 --- /dev/null +++ b/datagenerators/geospatial-images/plugin/omnisharp.json @@ -0,0 +1,13 @@ +{ + "FormattingOptions": { + "EnableEditorConfigSupport": true + }, + "RoslynExtensionsOptions": { + "documentAnalysisTimeoutMs": 30000, + "enableDecompilationSupport": true, + "enableImportCompletion": true, + "enableAnalyzersSupport": true, + "diagnosticWorkersThreadCount": 8 + }, + "files.trimTrailingWhitespace": true +} \ No newline at end of file diff --git a/datagenerators/geospatial-images/plugin/sampleData/astronaut.jpg b/datagenerators/geospatial-images/plugin/sampleData/astronaut.jpg new file mode 100644 index 0000000000000000000000000000000000000000..546605181e9ed6649591e64a758d0c4d1ce135d8 GIT binary patch literal 183180 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%0A^s=o zLCSr84pGyYOC4DezJHC4t1w9BZP<1{TFV|84k$TIt}!dJx4SFYJivBxK$={tpHzT< zd~NvM!m>5tb859%20z3GU!D16C~>QE)sOqB>Tq-PM+>wqa;LB5vGY1Z&Qv_EVyMo= z+PcF3%F&8v7@nyOgxu~y!K?ihK`K9M8(RM+IhdzmYoxxYs4zCBbXF{%feezq{%vh) zRY11!rR+_a*vM?S+jlm)1o?iH@vlZUV*Cf(PEWqp*|<^wR=!WE!|pb^q)5)g-CMR^?X>l8RIF{idt;z^!6^E$Q2_dRY7N<{LrYsuRXT)L{?%%&iA|94|-E_%;Vm%p>ou(EQt}6^nC(o zH@F)GTB*Gc##P{aB-i)@nZ;5sozr{J8QG~<5F{EKn<69O|#qxa<2be$|GG({F_^Z_0c z0gc&a5VP-QRQwrLPY$TDDBsF&Ef9{|;#vPTo*gdxujGl6 zH2>cr(_9TrrSk6J;Z5}gd(P0F#IT(#eQ-FExjsu6RQSVS$)QOs1W*sELiE_(fWoBSxMj8HHPhIsPB7nXl_3c+ON3ie!#oy z6Xr(N%Iu>0??I?_d#^Ss&*greCgB}XVj-MXp~G`iZjnyeHlU^yMs|S}ryB-l%zY~9 z6;E6YIB4B%IN)Y6LM<VYipcC1pcc zENBi1^0ikx;_SFLxo$Uyp+CAl1uLY_AsIgp;p=}Mm<=}90)CieOf5@;vugN2V2BzjkJ^=_oee6Y>3+}Nw^s$DQ5^Id6yA@@WqLhz|*BTqbT^|QqZL7 zxg_BZVAs%A07x)!^XuO%&-o;4Vb#8>u=W^07SMxe@2$EArvgoFdZs>6yn4r0y&jZ9 zllZm#`kD}}OMgL)I&|6UXtR4#pAVViRJ3ECb(KqS=c(*!UK{MCY4qLoqKeSpgDS(dkhlX1&>#%c{LjCpDCR6mdUCjn=#11t&10Nzb)&2T@ z|Hs7apJ2?nI?9O+(9CECWiX7lfdgsRu%@Kbw7*-A95-EGk%)~ zi`~@X5+{OFGcwOfwnWWbZ?bY>`OIDWKyReYRpAM4v}CO+L-I_W9~msq-nN3t9icbV zb-Z4!7;6wxp_qWC02(>Mb8{$QaKGKG;r{3sw+J7n>RpJ@Ldwa5bEh3;X1bnhT+iNn zvq8gEen!b$3Q<%H7*VttT$?)BNaMGzRZJ5wS54AC-c>Rx6PK(i+avo1EkV}B!HnR zi)x$V3so@lUleJt_Y)2v`qdic;>3-C7DX{U-b$a$P+>GpIvc3PNZchrrgg=@0Nm_8 z5uw&0;pV4dT(vBnL-W@3nWfOJ%8k=m#$CVFQe6$>uasLymkWi+PrI}p7@G*%!)iMC zEVu6`;AhZD{u}zFt)zBmG1olvnIx{bZ_(?Q)~qc1QOcLEzTnnRkMazAa)TeN_TZIF5{J%Lm< zvsO1Md323@pO^BvXo}WsN~l9m=UC$nPYyQer~o<&iGueAwD?nfRt`T0Q)DHV?3TPl zO62bwq4o}6@T769H^3V3Y>MTTeY0Mp0L~`K?&d0Kp^q0WJkO=PwiRWDQ>yN^gYRob4=F?Nw1!`TVg0(<=(iL`|v=#|qn zr;O>8?wfLC@r)BMv|MDbihn3^GraPM_FXp?vIT2~3QqfOb6?+JMcL3P%UmJSd^6SVOP4?2?A&AeX zjZ#3L6$}xc#v0xW?Yq)Vk|r@7=bMC_3k=v4JtYlLjwg20@EOYH0gjC@&hyAD9$jRi zDqGqpcgz@aBL3K6tb{Z#{6XRp1?`b#i!mLnsksUZ=E>{ZUneObUO>VDd25QZC}2>3 zzJlbZjO7fiIt7n#PM#(O*`|!*1J=iDAd%X&Pi~#sg3hQ}$+Z>8lhr1ZeM`PCfAns* zYtxm^=&;mD&#z7vQ?JtPSz5>p0xsQDEYR;LI7+t42Hs0n&Aw0_k*!mehIx-neoU#X z8vVf_{%UZ~h-mo|DnTZU({1EIuE#H?S_EIz52PuzqL?x{9E#7(Z_=Y*-v~;AYy5y|V)X@r+}-Z_nzT zh*rdEr40~%Q5r%$_*8t;(2hnb=_CeYY(A~<)v&m7an*ej!GOdZ1TlK_JYW0pe${>$ zNS%Be*`7NXbmX?*;6cP309&h5r9Ddvb4s#p02wlbxCrF$#=P8u4rRbm)Y}`UZTSTx z-tuaH`j-C)2Z5rwsD#Wh^Uv?to zf4F>aZhT-WJh~$fb@njdtED?5=QR0+&b{e9k^Y(QK>!p;Q2TT|HDTlSRsdOT?{`T&lbe6-Qr(n|q6n}8npV3* zKkAbN)642NNQC5TG?I@#0YPz_kL(aoPIg)eXT{?SBaJzGBP(!AJ`9y`K+c~ zQlCCjYk1#))nGCbT^@hmOUNi}l17|QP^_KJtxWmBzm5i3yQ9-F~?2Ch;!$yc5g-S0yeCd9?_hqF_8kaPcp8#bqHM!CS0)(+dg)_A8AxvaBRvax@n1ISM< z*tSE2>%2mR-_(dLE}j8qdWlj)M1; z#fP}Ks`Z86>w~pdjAqk}0R%XLFyFm*gFzX4DV5jED79P(m6bcp_u>C@3($Apg7Ak^ zFcPK_q4AxLIA<|q~oo(opc6;+LjQr5d)1B0=7(c&)u;9wSJ`)(gh zFn*w^Sy;lzLTLZ!QAmMj_UUrzH@6mF9sRG2TNp6na(?qhP2P-~`m`BYdTiH6)_W*o z_Z|)~WX|jKdJ>oGe|>5g#fO2j6xx3AX6MLW4;*nqQ= zf_)($a|WU;e4#3eg+McaZmW)Hi7$@J4BE=L?hJRioWb+hb>L#Lte&3HOQDZ){KuPU z#jO;e;ii7F_5n1Y*%P0aRDJ!2bYondBb9C?q!ZJoFIu1!YTDn8zbwh1+SBY#9znG* z3pc%oCcYd8*W{IKPD}aEIY@3=sp@Zif6@LnSVM`S`jDcm<4l?z9VWnFoBuIgqHPMH zs+FA!^jY{G8w&5Gz+U#a*EVpK!(T?Eo zaT(W*mf7%vE^#J!Rb?%bOAWJWig*cpaV5b$`fO%5|It5_A+PNlCUNrtj_q4$(Rzl7^dDq`q|$1>qtgC9q><`frwmj))Iq_qLGq2&^@nu zyqfru=R332x3h_aaejTuI1~)a{060`D^NBED{Tt7HX(uH`ocM>)p3L;XNpq3Ji1d? zfhswVwJ3)U_vfpto(i@dqP2Be)TdA_bl;Ze_SCyyU3w>b<%yI)Nb{5 z_sCqMH_LnS7OijhF{%XY7zfbm1Ft)2sc~D+p?RC!1vXGO675%;y65ls1A=fU3f_wA6AW^Z7W~*eq#*0 zzFwS|p_1kw9)pb2mm(71>QP35!#bWTJ4=oB@4tkA1HYXJ^rV%LmRmj67|HNBL~?L) z(FfedVlLu#LnTm4O;PI2!XgJ5i?-tn4clJ14%{RTf8BCN+<+OJ2|~18Di1!hoCs6W zoK38!U3K~J z!bSRzsbELqCaEG@)7O$%%js@Z_K|v1wm)eHCULatbgCFlhgD9p%2j;v#D>{|*i1^;E z&0}BewPbJb#P8D_o(eWg)1za-${623#MSO53Ct34KAs^J9)j5Ata2WP9fe6zya>B} zErLURCzn8p95dp*Lk_x7|M%lYpifBkOkA7FF;v<1ykNy-ZG$oT@CE=L6o#%_g3QpD zGPygh&QcKpD6o)x8P`EW5pnpM!9vZGzQbes7r|5APGmC~U31f2MXujfRf$UJC@}27 zs5J*11n)EYK}PL)-P%@qTF)`=alVMYyL3C``~&9M$ig>Xpl9rq5%;&vDOV+GpHj~N z0atoczZa`s=_o*{Ve<3U)5d=#{m0bQ&ESm5*$oMA#_1CmDvCyA!F+H3`Faha3Kfc8 za`_F=@CUS%%A8K!Aj_|H74Mrw->&%h3W&O99a1b9T-96rK7;Y8>($l@mQMh&fLLLU ziikk{2qc2brCmofpo#lG(< z=l7!CaK_%VRI$bUa$R3ft5HvO&L`i;TT*5zyEWPZ5gOVBAnGsNzI-tKkC3z~c7Ao3 z_}3DJ+WdB6EM0s)dvf4JNTa2Ow7Z1bp==P>wgHBLn69n+BcS{JZFQ?(=zy-TT-zIa zF_4pj`y+eGWc2!9^jc}o;^L)(i*pP^hu6QC73Z&Qw)#~WW;a{!SdFfGK-bnrMELy^ zm&q<(q{ppv(YL=_;{(qnoe2uWlr^|~{?w}*w6*F%X>U3k3S>SO@(OeUtu9 zD-ayyR(Bj{|K`&QMBmW5P3!@}EEi+f@|vX?V$CZ)bo-e6b`;ztZ^Ns8A|4D zIMmQM1R+oQoM!0}uM>y8A4Ni3EeD^TmrVTz_awIF20XmAs@kb9@Z)21>V|Lv1S|SC zw6p40(`&A()h$oc8F9SPUff(W?)N0fVW7=*QdLH3g3#Q89e-HEfBH*8D`y zC&)!~R&}T~ZvXqkgTa`kFedxZ6 zF~0VOc01_Y*+FA?%y@xLwmVVVUU6P6BD%UCdQ0tZ*PoD6 zicm>^t9+2XS~D+b!z*$;!k$jk$louoQ=r^AdtR}?UQoJdiH);|zPJ-?)cH{E7pHQ~ z{s+`oI^ImPrw47~CEo&^CsHq~XYm%=6C``K?kEhNlZM1Qz6Ri;&!0I_ z+kCi9)ciD6572iVE1DguwoE7N9Urb7oG54sfk4N(xQ>$UjfKO|zs@7`70mXm!K-O0 zg*I@68w$4nuc0gyw|t$&#NyWHM7fUC`bdvST!O8Kh+iNh^~784P4cQHn8P21cc#4R zzP5UO#s~%rfTRvk4{5XmTF~*6H|_%uhWYY&N(zFH5sQ@Hyb2g) zaZ%Xp#^2)HScZ!z*Zz{>>Yn4@x-}&N^~iS(-iNcePq?x!JF+A&-JDPk!G$ zJPwCd9RJ5u$~X@1OVTl4|HD%bZbo^nj-W-|1i8n7%dvj65@8NwInY9~_XS;8km zq>{{S6iRM2ds4i6TiKg8$&aj8JY;iwyKalGr9a_ddw>xPD!;LsH>T*?277VONn9}Wer)Tub}LEoo44o5i$nRsEpk#!Z9fLy-tsM+REv`H z;L*~S22oFweeH!rXuo*X!!mb3e=^(eyRA1k$z~o}Q?M^yE#{v?HRQU2OXw(FTEa!2 zlU8bR<$EXURIOW3<;d+@pP9mAC(?2j77W(Lp8@m(`6Ep$6T=l|6QH~jG0qLnqlpc^ zYxpzii2+vZ1W)S^v(|*?4mmreLE7~b5jf-Re*EIWqMu*#5=#2whJQ7~yj5_4BECv} z;|?gT@78t0t2$A5C9twwm0~^JJeOSr9cJXq${ zi^AibT}*YuMNFAu5pUIg<;j-Jm0seXVk8r#em`m7+%AHpBF0& zK5ncX0<`&E9a0YS9hwBxph<#xr_kYMwWVrG(SH6IMTL8+2wIs@*J`)frdFN4t(rYO zG2!@p@o`A=c$2zWGxvCbjB;@Z(HmNPqloBiHcb7d0knI_SDrn3Ngw#clk<$)h^M=! zplP%ZxX8%l3uFjk#yO%l;LH)Pm?RTh zmlc=xLK_|wb~jFPNj?kAA&7tV1Y-?hkh5g0f?W&0X2_DBEG<@8b2jSN3{f}ZqUQ;` zT(rcphX5`NxN~mOqD68CW_FeGtW+9emj;=N^iz)&_kc9HJq%0Ahl1pjXhR_{PLiGy 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 literal 0 HcmV?d00001 diff --git a/datagenerators/geospatial-images/plugin/src/Protos/ImageProvider.proto b/datagenerators/geospatial-images/plugin/src/Protos/ImageProvider.proto new file mode 100644 index 0000000..cafe002 --- /dev/null +++ b/datagenerators/geospatial-images/plugin/src/Protos/ImageProvider.proto @@ -0,0 +1,31 @@ +syntax = "proto3"; + +import "google/protobuf/timestamp.proto"; +option csharp_namespace = "Microsoft.Azure.SpaceFx.ImageProvider"; +package Microsoft.Azure.SpaceFx.ImageProvider; + +enum ServiceEndpoints { + health = 0; + imageRequest = 1; +} + +enum ImageType { + GEOTIFF = 0; + IMAGE = 1; +} + +message EarthLineOfSight { + float Latitude = 1; + float Longitude = 2; +} + +message EarthImageRequest { + EarthLineOfSight lineOfSight = 1; + ImageType imageType= 2; +} + +message EarthImageResponse { + EarthLineOfSight lineOfSight = 1; + google.protobuf.Timestamp timestamp = 2; + string filename = 3; +} \ No newline at end of file diff --git a/datagenerators/geospatial-images/plugin/src/Usings.cs b/datagenerators/geospatial-images/plugin/src/Usings.cs new file mode 100644 index 0000000..a4d949f --- /dev/null +++ b/datagenerators/geospatial-images/plugin/src/Usings.cs @@ -0,0 +1,7 @@ +global using Microsoft.Azure.SpaceFx; +global using Microsoft.Azure.SpaceFx.MessageFormats.Common; +global using Microsoft.Azure.SpaceFx.MessageFormats.HostServices.Link; +global using Microsoft.Azure.SpaceFx.MessageFormats.HostServices.Sensor; +global using Microsoft.Azure.SpaceFx.MessageFormats.HostServices.Position; +global using Microsoft.Extensions.Logging; +global using System.Collections.Concurrent; diff --git a/datagenerators/geospatial-images/plugin/src/geospatial-images-vth-plugin.csproj b/datagenerators/geospatial-images/plugin/src/geospatial-images-vth-plugin.csproj new file mode 100644 index 0000000..9721a20 --- /dev/null +++ b/datagenerators/geospatial-images/plugin/src/geospatial-images-vth-plugin.csproj @@ -0,0 +1,19 @@ + + + net6.0 + enable + enable + true + linux-x64;linux-arm64 + + + + + + + + + + + + diff --git a/datagenerators/geospatial-images/plugin/src/geospatial-images-vth-plugin.spacefx_plugin b/datagenerators/geospatial-images/plugin/src/geospatial-images-vth-plugin.spacefx_plugin new file mode 100644 index 0000000..5e43c1d --- /dev/null +++ b/datagenerators/geospatial-images/plugin/src/geospatial-images-vth-plugin.spacefx_plugin @@ -0,0 +1,10 @@ +{ + "pluginFile": "geospatial-images-vth-plugin.dll", + "pluginName": "geospatial-images-vth-plugin", + "targetService": "vth", + "plugin_permissions": "ALL", + "core_permissions": "ALL", + "build_artifacts": [], + "configuration": { + } +} \ No newline at end of file diff --git a/datagenerators/geospatial-images/plugin/src/plugin.cs b/datagenerators/geospatial-images/plugin/src/plugin.cs new file mode 100644 index 0000000..ea5098c --- /dev/null +++ b/datagenerators/geospatial-images/plugin/src/plugin.cs @@ -0,0 +1,159 @@ +using Microsoft.Azure.SpaceFx.MessageFormats.HostServices.Link; +using Microsoft.Azure.SpaceFx.MessageFormats.HostServices.Position; +using Microsoft.Azure.SpaceFx.MessageFormats.HostServices.Sensor; + +namespace Microsoft.Azure.SpaceFx.PlatformServices.MessageTranslationService.Plugins; +public class GeospatialImagesPlugin : Microsoft.Azure.SpaceFx.VTH.Plugins.PluginBase { + + // HelloWorld sensor is a simple request/reply sensor to validate the direct path scenario works + const string SENSOR_ID = "GeospatialImages"; + private readonly string OUTPUT_DIR = ""; + private readonly string IMAGES_DIR = ""; + private readonly HttpClient HTTP_CLIENT; + private readonly ConcurrentQueue IMAGE_QUEUE = new(); + private readonly ConcurrentDictionary LinkRequestIDs = new(); + + public GeospatialImagesPlugin() { + LoggerFactory loggerFactory = new(); + this.Logger = loggerFactory.CreateLogger(); + ServiceProvider? serviceProvider = new ServiceCollection().AddHttpClient().BuildServiceProvider() ?? throw new Exception("Unable to initialize the HTTP Client Factory"); + HTTP_CLIENT = serviceProvider.GetService().CreateClient(); + OUTPUT_DIR = Core.GetXFerDirectories().Result.outbox_directory; + } + + public override void ConfigureLogging(ILoggerFactory loggerFactory) => this.Logger = loggerFactory.CreateLogger(); + + public override ILogger Logger { get; set; } + + public override Task BackgroundTask() => Task.Run(async () => { + Logger.LogInformation("{pluginName}: {methodRequest} Background Task started.", + nameof(GeospatialImagesPlugin), nameof(BackgroundTask)); + + DateTime maxTimeToWaitForLinkResponse; + + while (true) { + if (IMAGE_QUEUE.TryDequeue(out var taskingRequest)) { + try { + Logger.LogDebug("{pluginName}: {methodRequest} Processing {messageType} (TrackingId: {trackingId}, CorrelationId: {correlationId})", + nameof(GeospatialImagesPlugin), nameof(BackgroundTask), nameof(TaskingRequest), taskingRequest.RequestHeader.TrackingId, taskingRequest.RequestHeader.CorrelationId); + + SensorData sensorData = await processImageRequest(taskingRequest); + + if (sensorData.ResponseHeader.Status == StatusCodes.Successful) { + + Logger.LogDebug("{pluginName}: {methodRequest} Waiting for successful Link Response for all files (maximum 30 seconds) (TrackingId: {trackingId}, CorrelationId: {correlationId})", + nameof(GeospatialImagesPlugin), nameof(BackgroundTask), taskingRequest.RequestHeader.TrackingId, taskingRequest.RequestHeader.CorrelationId); + + bool hasPendingLinkRequests = true; + maxTimeToWaitForLinkResponse = DateTime.Now.Add(TimeSpan.FromSeconds(30)); + + while (hasPendingLinkRequests && DateTime.Now <= maxTimeToWaitForLinkResponse) { + hasPendingLinkRequests = LinkRequestIDs.Any(i => i.Value.RequestHeader.CorrelationId == sensorData.ResponseHeader.CorrelationId); + System.Threading.Thread.Sleep(100); ; + } + + if (hasPendingLinkRequests) { + sensorData.ResponseHeader.Status = StatusCodes.Timeout; + sensorData.ResponseHeader.Message = $"Timeout while transmitting files to '{taskingRequest.RequestHeader.AppId}'. Check LinkService is deployed and operational, then retry your query."; + } + } + + Logger.LogInformation("{pluginName}: {methodRequest} Sending results to {appId} (TrackingId: {trackingId}, CorrelationId: {correlationId})", + nameof(GeospatialImagesPlugin), nameof(BackgroundTask), taskingRequest.RequestHeader.AppId, taskingRequest.RequestHeader.TrackingId, taskingRequest.RequestHeader.CorrelationId); + + Core.DirectToApp(appId: taskingRequest.RequestHeader.AppId, message: sensorData); + } catch (Exception ex) { + Logger.LogError("{pluginName}: {methodRequest} Error processing tasking request. Error message: {errorMsg} (TrackingId: {trackingId}, CorrelationId: {correlationId})", + nameof(GeospatialImagesPlugin), nameof(BackgroundTask), ex.ToString(), taskingRequest.RequestHeader.TrackingId, taskingRequest.RequestHeader.CorrelationId); + } + } else { + System.Threading.Thread.Sleep(1000); + } + } + }); + + public override Task LinkResponse(LinkResponse? input_response) => Task.Run(() => { + Logger.LogInformation("{pluginName}: received and processed a LinkResponse Event", nameof(GeospatialImagesPlugin)); + return (input_response ?? null); + }); + + public override Task<(PositionUpdateRequest?, PositionUpdateResponse?)> PositionUpdateRequest(PositionUpdateRequest? input_request, PositionUpdateResponse? input_response) => Task.Run(() => { + Logger.LogInformation("{pluginName}: Plugin received and processed a PositionUpdateRequest Event", nameof(GeospatialImagesPlugin)); + return (input_request, input_response); + }); + + public override Task PositionUpdateResponse(PositionUpdateResponse? input_response) => Task.Run(() => { + Logger.LogInformation("{pluginName}: Plugin received and processed a PositionUpdateResponse Event", nameof(GeospatialImagesPlugin)); + return (input_response ?? null); + }); + + public override Task PluginHealthCheckResponse() => Task.Run(() => { + return new MessageFormats.Common.PluginHealthCheckResponse { + ResponseHeader = new MessageFormats.Common.ResponseHeader { + CorrelationId = Guid.NewGuid().ToString(), + TrackingId = Guid.NewGuid().ToString(), + Status = MessageFormats.Common.StatusCodes.Healthy, + Message = "geospatial-images-vth-plugin is operational" + }, + }; + }); + + public override Task SensorData(SensorData? input_request) => Task.Run(() => { + Logger.LogInformation("{pluginName}: Plugin received and processed a SensorData Event", nameof(GeospatialImagesPlugin )); + return (input_request ?? null); + }); + + public override Task<(SensorsAvailableRequest?, SensorsAvailableResponse?)> SensorsAvailableRequest(SensorsAvailableRequest? input_request, SensorsAvailableResponse? input_response) => Task.Run(() => { + Logger.LogInformation("{pluginName}: Plugin received and processed a SensorsAvailableResponse Event", nameof(GeospatialImagesPlugin)); + + if (input_request == null || input_response == null) return (input_request, input_response); + + input_response.ResponseHeader.Status = StatusCodes.Successful; + input_response.Sensors.Add(new SensorsAvailableResponse.Types.SensorAvailable() { SensorID = SENSOR_ID }); + input_response.Sensors.Add(new SensorsAvailableResponse.Types.SensorAvailable() { SensorID = SENSOR_TEMPERATURE_ID }); + + + return (input_request, input_response); + }); + + public override Task SensorsAvailableResponse(SensorsAvailableResponse? input_response) => Task.Run(() => { + Logger.LogInformation("{pluginName}: Plugin received and processed a SensorsAvailableResponse Event", nameof(GeospatialImagesPlugin)); + return (input_response ?? null); + }); + + public override Task<(TaskingPreCheckRequest?, TaskingPreCheckResponse?)> TaskingPreCheckRequest(TaskingPreCheckRequest? input_request, TaskingPreCheckResponse? input_response) => Task.Run(() => { + Logger.LogInformation("{pluginName}: Plugin received and processed a TaskingPreCheckRequest Event", nameof(GeospatialImagesPlugin)); + if (input_request == null || input_response == null) return (input_request, input_response); + + // Flip it to success + input_response.ResponseHeader.Status = StatusCodes.Successful; + return (input_request, input_response); + }); + + public override Task TaskingPreCheckResponse(TaskingPreCheckResponse? input_response) => Task.Run(() => { + Logger.LogInformation("{pluginName}: Plugin received and processed a TaskingPreCheckResponse Event", nameof(GeospatialImagesPlugin)); + return (input_response ?? null); + }); + + public override Task<(TaskingRequest?, TaskingResponse?)> TaskingRequest(TaskingRequest? input_request, TaskingResponse? input_response) => Task.Run(() => { + Logger.LogInformation("{pluginName}: Plugin received and processed a TaskingRequest Event", nameof(GeospatialImagesPlugin)); + if (input_request == null || input_response == null) return (input_request, input_response); + + // Flip it to success + input_response.ResponseHeader.Status = StatusCodes.Successful; + input_response.SensorID = input_request.SensorID; + + // Add the client ID to the list so we can direct send it Sensor Data + if (!CLIENT_IDS.Contains(input_request.RequestHeader.AppId)) + CLIENT_IDS.Add(input_request.RequestHeader.AppId); + + // Flip it to success + input_response.ResponseHeader.Status = StatusCodes.Successful; + return (input_request, input_response); + }); + + public override Task TaskingResponse(TaskingResponse? input_response) => Task.Run(() => { + Logger.LogInformation("{pluginName}: Plugin received and processed a SensorsAvailableRequest Event", nameof(GeospatialImagesPlugin)); + return (input_response ?? null); + }); +} From f9c1ac39cd1fdc28922b5525c5f78776abe2520b Mon Sep 17 00:00:00 2001 From: alianides Date: Mon, 22 Jul 2024 23:48:01 +0000 Subject: [PATCH 2/8] temp workflow credentials --- .github/workflows/planetary-computer-plugin-build.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/planetary-computer-plugin-build.yaml b/.github/workflows/planetary-computer-plugin-build.yaml index 198fcff..0bdc0ad 100644 --- a/.github/workflows/planetary-computer-plugin-build.yaml +++ b/.github/workflows/planetary-computer-plugin-build.yaml @@ -30,8 +30,8 @@ jobs: PROTO_FOLDER_PATH: ./datagenerators/planetary-computer/plugin/src/Protos PROTO_FILE_NAME: PlanetaryComputer.proto secrets: - GIT_HUB_USER_NAME: ${{ secrets.GIT_HUB_USER_NAME }} - GIT_HUB_USER_TOKEN: ${{ secrets.GIT_HUB_USER_TOKEN }} + GIT_HUB_USER_NAME: ${{ secrets.TEMP_GITHUB_USERNAME }} + GIT_HUB_USER_TOKEN: ${{ secrets.TEMP_WORKFLOW_TOKEN }} SETUP_REPO_URL: ${{ secrets.SETUP_REPO_URL }} build-plugin-planetary-computer-arm64: @@ -54,6 +54,6 @@ jobs: PROTO_FOLDER_PATH: ./datagenerators/planetary-computer/plugin/src/Protos PROTO_FILE_NAME: PlanetaryComputer.proto secrets: - GIT_HUB_USER_NAME: ${{ secrets.GIT_HUB_USER_NAME }} - GIT_HUB_USER_TOKEN: ${{ secrets.GIT_HUB_USER_TOKEN }} + GIT_HUB_USER_NAME: ${{ secrets.TEMP_GITHUB_USERNAME }} + GIT_HUB_USER_TOKEN: ${{ secrets.TEMP_WORKFLOW_TOKEN }} SETUP_REPO_URL: ${{ secrets.SETUP_REPO_URL }} \ No newline at end of file From ef07f222551c9ec5fb0c1ac5a16daff95fd86e05 Mon Sep 17 00:00:00 2001 From: alianides Date: Mon, 22 Jul 2024 23:58:22 +0000 Subject: [PATCH 3/8] switch secrets --- .github/workflows/geospatial-images-generator-build.yaml | 8 ++++---- .github/workflows/planetary-computer-plugin-build.yaml | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/geospatial-images-generator-build.yaml b/.github/workflows/geospatial-images-generator-build.yaml index bea1e99..7d78d18 100644 --- a/.github/workflows/geospatial-images-generator-build.yaml +++ b/.github/workflows/geospatial-images-generator-build.yaml @@ -28,8 +28,8 @@ jobs: YAML_FOLDER_PATH: ./datagenerators/geospatial-images/datagenerator/k3s YAML_FILE_NAME: datagenerator-geospatial-images.yaml secrets: - GIT_HUB_USER_NAME: ${{ secrets.GIT_HUB_USER_NAME }} - GIT_HUB_USER_TOKEN: ${{ secrets.GIT_HUB_USER_TOKEN }} + GIT_HUB_USER_NAME: ${{ secrets.TEMP_GITHUB_USERNAME }} + GIT_HUB_USER_TOKEN: ${{ secrets.TEMP_WORKFLOW_TOKEN }} SETUP_REPO_URL: ${{ secrets.SETUP_REPO_URL }} build-datagenerator-geospatial-images-arm64: @@ -50,6 +50,6 @@ jobs: YAML_FOLDER_PATH: ./datagenerators/geospatial-images/datagenerator/k3s YAML_FILE_NAME: datagenerator-geospatial-images.yaml secrets: - GIT_HUB_USER_NAME: ${{ secrets.GIT_HUB_USER_NAME }} - GIT_HUB_USER_TOKEN: ${{ secrets.GIT_HUB_USER_TOKEN }} + GIT_HUB_USER_NAME: ${{ secrets.TEMP_GITHUB_USERNAME }} + GIT_HUB_USER_TOKEN: ${{ secrets.TEMP_WORKFLOW_TOKEN }} SETUP_REPO_URL: ${{ secrets.SETUP_REPO_URL }} \ No newline at end of file diff --git a/.github/workflows/planetary-computer-plugin-build.yaml b/.github/workflows/planetary-computer-plugin-build.yaml index 0bdc0ad..198fcff 100644 --- a/.github/workflows/planetary-computer-plugin-build.yaml +++ b/.github/workflows/planetary-computer-plugin-build.yaml @@ -30,8 +30,8 @@ jobs: PROTO_FOLDER_PATH: ./datagenerators/planetary-computer/plugin/src/Protos PROTO_FILE_NAME: PlanetaryComputer.proto secrets: - GIT_HUB_USER_NAME: ${{ secrets.TEMP_GITHUB_USERNAME }} - GIT_HUB_USER_TOKEN: ${{ secrets.TEMP_WORKFLOW_TOKEN }} + GIT_HUB_USER_NAME: ${{ secrets.GIT_HUB_USER_NAME }} + GIT_HUB_USER_TOKEN: ${{ secrets.GIT_HUB_USER_TOKEN }} SETUP_REPO_URL: ${{ secrets.SETUP_REPO_URL }} build-plugin-planetary-computer-arm64: @@ -54,6 +54,6 @@ jobs: PROTO_FOLDER_PATH: ./datagenerators/planetary-computer/plugin/src/Protos PROTO_FILE_NAME: PlanetaryComputer.proto secrets: - GIT_HUB_USER_NAME: ${{ secrets.TEMP_GITHUB_USERNAME }} - GIT_HUB_USER_TOKEN: ${{ secrets.TEMP_WORKFLOW_TOKEN }} + GIT_HUB_USER_NAME: ${{ secrets.GIT_HUB_USER_NAME }} + GIT_HUB_USER_TOKEN: ${{ secrets.GIT_HUB_USER_TOKEN }} SETUP_REPO_URL: ${{ secrets.SETUP_REPO_URL }} \ No newline at end of file From f2b5f2af502c2333ab32778585ba54a8bacaa750 Mon Sep 17 00:00:00 2001 From: alianides Date: Wed, 24 Jul 2024 22:50:51 +0000 Subject: [PATCH 4/8] GeospatialImagesPlugin --- .../devcontainer.json | 4 +- .../debugPayloadApp/Services/MessageSender.cs | 51 +++-- .../plugin/debugPayloadApp/Usings.cs | 4 +- .../debugPayloadApp/debugPayloadApp.csproj | 4 + ...eProvider.proto => GeospatialImages.proto} | 4 +- .../geospatial-images/plugin/src/Usings.cs | 7 + .../src/geospatial-images-vth-plugin.csproj | 15 ++ ...ial-images-vth-plugin.json.spacefx_plugin} | 0 .../geospatial-images/plugin/src/plugin.cs | 176 ++++++++++++++++-- 9 files changed, 235 insertions(+), 30 deletions(-) rename datagenerators/geospatial-images/plugin/src/Protos/{ImageProvider.proto => GeospatialImages.proto} (80%) rename datagenerators/geospatial-images/plugin/src/{geospatial-images-vth-plugin.spacefx_plugin => geospatial-images-vth-plugin.json.spacefx_plugin} (100%) diff --git a/.devcontainer/geospatial-images-vth-plugin/devcontainer.json b/.devcontainer/geospatial-images-vth-plugin/devcontainer.json index 5951dfa..c7566fb 100644 --- a/.devcontainer/geospatial-images-vth-plugin/devcontainer.json +++ b/.devcontainer/geospatial-images-vth-plugin/devcontainer.json @@ -13,8 +13,8 @@ "app_name": "geospatial-images-vth-plugin", "app_type": "vth-plugin", "addl_debug_shim_suffixes": "client", - "pull_containers": "datagenerator-geospatial-images:0.11.0-nightly", - "download_artifacts": "datagenerator-geospatial-images.yaml" + // "pull_containers": "datagenerator-geospatial-images:0.11.0-nightly", + // "download_artifacts": "datagenerator-geospatial-images.yaml" } }, "mounts": [ diff --git a/datagenerators/geospatial-images/plugin/debugPayloadApp/Services/MessageSender.cs b/datagenerators/geospatial-images/plugin/debugPayloadApp/Services/MessageSender.cs index 82a058e..df5d4ce 100644 --- a/datagenerators/geospatial-images/plugin/debugPayloadApp/Services/MessageSender.cs +++ b/datagenerators/geospatial-images/plugin/debugPayloadApp/Services/MessageSender.cs @@ -41,16 +41,16 @@ protected override async Task ExecuteAsync(CancellationToken stoppingToken) { throw new Exception($"Service '{_hostSvcAppId}' did not come online in time."); } - // Hostsvc-Position endpoints - await UpdatePosition(); - await GetCurrentPosition(); + // // Hostsvc-Position endpoints + // await UpdatePosition(); + // await GetCurrentPosition(); - // Hostsvc-Link endpoints - await SendFileRootDirectory(); + // // Hostsvc-Link endpoints + // await SendFileRootDirectory(); - // Hostsvc-Logging endpoints - await SendTelemetryMetric(); - await SendLogMessage(); + // // Hostsvc-Logging endpoints + // await SendTelemetryMetric(); + // await SendLogMessage(); // Hostsvc-Sensor endpoints RegisterForSensorData(); @@ -291,7 +291,12 @@ private void RegisterForSensorData() { // Register a callback event to catch the Sensor Data void SensorDataEventHandler(object? _, SensorData _response) { _logger.LogInformation($"Received Sensor Data: '{_response.SensorID}'"); - // Do something with data + _logger.LogInformation($"SensorData Status: {_response.ResponseHeader.Status}. TrackingID: {_response.ResponseHeader.TrackingId}"); + + if (!_response.SensorID.Equals("GeospatialImages", StringComparison.InvariantCultureIgnoreCase)) return; // This is not the sensor you're looking for + + Microsoft.Azure.SpaceFx.GeospatialImages.EarthImageResponse? earthImageResponse = _response.Data.Unpack(); + _logger.LogInformation($"...GeospatialImages.EarthImageResponse unpacked. datagenerator-geospatial-images output:'{earthImageResponse.Filename}'."); } MessageHandler.MessageReceivedEvent += SensorDataEventHandler; @@ -331,8 +336,11 @@ void ResponseEventHandler(object? _, SensorsAvailableResponse _response) { if (response == null) throw new TimeoutException($"Failed to hear {nameof(response)} after {MAX_TIMESPAN_TO_WAIT_FOR_MSG}. Please check that {_hostSvcAppId} is deployed"); - _logger.LogInformation($"'{request.GetType().Name}' request received. Status: '{response.ResponseHeader.Status}' (TrackingId: '{request.RequestHeader.TrackingId}')"); + _logger.LogInformation($"'{request.GetType().Name}' request received. Status: '{response.ResponseHeader.Status}' (TrackingId: '{request.RequestHeader.TrackingId}')"); + _logger.LogInformation($"SensorsAvailableResponse Heard from {response.ResponseHeader.AppId}"); + _logger.LogInformation($"{response.GetType().Name} Sensors ({response.Sensors.Count}): "); + response.Sensors.ToList().ForEach((sensor) => Console.WriteLine($"...Sensor '{sensor.SensorID}'...")); } private async Task SendTaskingPreCheckRequest() { @@ -373,11 +381,26 @@ void ResponseEventHandler(object? _, TaskingPreCheckResponse _response) { private async Task SendTaskingRequest() { DateTime maxTimeToWait = DateTime.Now.Add(TimeSpan.FromSeconds(10)); TaskingResponse? response = null; + + var trackingId = Guid.NewGuid().ToString(); + + Microsoft.Azure.SpaceFx.GeospatialImages.EarthLineOfSight lineOfSight = new Microsoft.Azure.SpaceFx.GeospatialImages.EarthLineOfSight { + Latitude = (float) 47.6062, + Longitude = (float) -122.3321 + }; + + Microsoft.Azure.SpaceFx.GeospatialImages.EarthImageRequest imageRequest = new Microsoft.Azure.SpaceFx.GeospatialImages.EarthImageRequest { + LineOfSight = lineOfSight, + ImageType = Microsoft.Azure.SpaceFx.GeospatialImages.ImageType.Geotiff + }; + TaskingRequest request = new() { - RequestHeader = new() { - TrackingId = Guid.NewGuid().ToString(), - CorrelationId = Guid.NewGuid().ToString() - } + RequestHeader = new RequestHeader() { + TrackingId = trackingId, + CorrelationId = trackingId + }, + SensorID = Microsoft.Azure.SpaceFx.VTH.Plugins.GeospatialImagesPlugin.SENSOR_ID, + RequestData = Google.Protobuf.WellKnownTypes.Any.Pack(imageRequest) }; _logger.LogInformation($"Sending '{request.GetType().Name}' request (TrackingId: '{request.RequestHeader.TrackingId}')"); diff --git a/datagenerators/geospatial-images/plugin/debugPayloadApp/Usings.cs b/datagenerators/geospatial-images/plugin/debugPayloadApp/Usings.cs index 55a671b..846996d 100755 --- a/datagenerators/geospatial-images/plugin/debugPayloadApp/Usings.cs +++ b/datagenerators/geospatial-images/plugin/debugPayloadApp/Usings.cs @@ -4,4 +4,6 @@ global using Microsoft.Azure.SpaceFx.MessageFormats.Common; global using Microsoft.Azure.SpaceFx.MessageFormats.HostServices.Link; global using Microsoft.Azure.SpaceFx.MessageFormats.HostServices.Sensor; -global using Microsoft.Azure.SpaceFx.MessageFormats.HostServices.Position; \ No newline at end of file +global using Microsoft.Azure.SpaceFx.MessageFormats.HostServices.Position; +global using Google.Protobuf; +global using Google.Protobuf.WellKnownTypes; \ No newline at end of file diff --git a/datagenerators/geospatial-images/plugin/debugPayloadApp/debugPayloadApp.csproj b/datagenerators/geospatial-images/plugin/debugPayloadApp/debugPayloadApp.csproj index 6dd3b0c..7e4e1cf 100755 --- a/datagenerators/geospatial-images/plugin/debugPayloadApp/debugPayloadApp.csproj +++ b/datagenerators/geospatial-images/plugin/debugPayloadApp/debugPayloadApp.csproj @@ -10,4 +10,8 @@ + + + + diff --git a/datagenerators/geospatial-images/plugin/src/Protos/ImageProvider.proto b/datagenerators/geospatial-images/plugin/src/Protos/GeospatialImages.proto similarity index 80% rename from datagenerators/geospatial-images/plugin/src/Protos/ImageProvider.proto rename to datagenerators/geospatial-images/plugin/src/Protos/GeospatialImages.proto index cafe002..f1c398c 100644 --- a/datagenerators/geospatial-images/plugin/src/Protos/ImageProvider.proto +++ b/datagenerators/geospatial-images/plugin/src/Protos/GeospatialImages.proto @@ -1,8 +1,8 @@ syntax = "proto3"; import "google/protobuf/timestamp.proto"; -option csharp_namespace = "Microsoft.Azure.SpaceFx.ImageProvider"; -package Microsoft.Azure.SpaceFx.ImageProvider; +option csharp_namespace = "Microsoft.Azure.SpaceFx.GeospatialImages"; +package Microsoft.Azure.SpaceFx.GeospatialImages; enum ServiceEndpoints { health = 0; diff --git a/datagenerators/geospatial-images/plugin/src/Usings.cs b/datagenerators/geospatial-images/plugin/src/Usings.cs index a4d949f..11d3bc7 100644 --- a/datagenerators/geospatial-images/plugin/src/Usings.cs +++ b/datagenerators/geospatial-images/plugin/src/Usings.cs @@ -4,4 +4,11 @@ global using Microsoft.Azure.SpaceFx.MessageFormats.HostServices.Sensor; global using Microsoft.Azure.SpaceFx.MessageFormats.HostServices.Position; global using Microsoft.Extensions.Logging; +global using Microsoft.Extensions.Options; global using System.Collections.Concurrent; +global using Google.Protobuf.WellKnownTypes; +global using System.Threading.Tasks; +global using System.Text; +global using Microsoft.Extensions.DependencyInjection; +global using System.Collections.Concurrent; +global using System.Net.Http.Json; diff --git a/datagenerators/geospatial-images/plugin/src/geospatial-images-vth-plugin.csproj b/datagenerators/geospatial-images/plugin/src/geospatial-images-vth-plugin.csproj index 9721a20..9e44787 100644 --- a/datagenerators/geospatial-images/plugin/src/geospatial-images-vth-plugin.csproj +++ b/datagenerators/geospatial-images/plugin/src/geospatial-images-vth-plugin.csproj @@ -10,6 +10,21 @@ + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + + + + + False + None + False + False + diff --git a/datagenerators/geospatial-images/plugin/src/geospatial-images-vth-plugin.spacefx_plugin b/datagenerators/geospatial-images/plugin/src/geospatial-images-vth-plugin.json.spacefx_plugin similarity index 100% rename from datagenerators/geospatial-images/plugin/src/geospatial-images-vth-plugin.spacefx_plugin rename to datagenerators/geospatial-images/plugin/src/geospatial-images-vth-plugin.json.spacefx_plugin diff --git a/datagenerators/geospatial-images/plugin/src/plugin.cs b/datagenerators/geospatial-images/plugin/src/plugin.cs index ea5098c..4351c41 100644 --- a/datagenerators/geospatial-images/plugin/src/plugin.cs +++ b/datagenerators/geospatial-images/plugin/src/plugin.cs @@ -2,11 +2,11 @@ using Microsoft.Azure.SpaceFx.MessageFormats.HostServices.Position; using Microsoft.Azure.SpaceFx.MessageFormats.HostServices.Sensor; -namespace Microsoft.Azure.SpaceFx.PlatformServices.MessageTranslationService.Plugins; +namespace Microsoft.Azure.SpaceFx.VTH.Plugins; public class GeospatialImagesPlugin : Microsoft.Azure.SpaceFx.VTH.Plugins.PluginBase { // HelloWorld sensor is a simple request/reply sensor to validate the direct path scenario works - const string SENSOR_ID = "GeospatialImages"; + public const string SENSOR_ID = "GeospatialImages"; private readonly string OUTPUT_DIR = ""; private readonly string IMAGES_DIR = ""; private readonly HttpClient HTTP_CLIENT; @@ -74,6 +74,10 @@ public override Task BackgroundTask() => Task.Run(async () => { public override Task LinkResponse(LinkResponse? input_response) => Task.Run(() => { Logger.LogInformation("{pluginName}: received and processed a LinkResponse Event", nameof(GeospatialImagesPlugin)); + if (input_response == null) return input_response; + + LinkRequestIDs.TryRemove(input_response.ResponseHeader.CorrelationId, out _); + return (input_response ?? null); }); @@ -99,7 +103,7 @@ public override Task PluginHealthCheckResponse() => T }); public override Task SensorData(SensorData? input_request) => Task.Run(() => { - Logger.LogInformation("{pluginName}: Plugin received and processed a SensorData Event", nameof(GeospatialImagesPlugin )); + Logger.LogInformation("{pluginName}: Plugin received and processed a SensorData Event", nameof(GeospatialImagesPlugin)); return (input_request ?? null); }); @@ -110,7 +114,6 @@ public override Task PluginHealthCheckResponse() => T input_response.ResponseHeader.Status = StatusCodes.Successful; input_response.Sensors.Add(new SensorsAvailableResponse.Types.SensorAvailable() { SensorID = SENSOR_ID }); - input_response.Sensors.Add(new SensorsAvailableResponse.Types.SensorAvailable() { SensorID = SENSOR_TEMPERATURE_ID }); return (input_request, input_response); @@ -136,19 +139,30 @@ public override Task PluginHealthCheckResponse() => T }); public override Task<(TaskingRequest?, TaskingResponse?)> TaskingRequest(TaskingRequest? input_request, TaskingResponse? input_response) => Task.Run(() => { - Logger.LogInformation("{pluginName}: Plugin received and processed a TaskingRequest Event", nameof(GeospatialImagesPlugin)); - if (input_request == null || input_response == null) return (input_request, input_response); + Logger.LogInformation("{pluginName}: {methodRequest} received tasking request. (TrackingId: {trackingId}, CorrelationId: {correlationId})", + nameof(GeospatialImagesPlugin), nameof(TaskingRequest), input_request.RequestHeader.TrackingId, input_request.RequestHeader.CorrelationId); + if (input_request == null) return (input_request, input_response); + if (!input_request.SensorID.Equals(SENSOR_ID, StringComparison.InvariantCultureIgnoreCase)) return (input_request, input_response); // This is not the plugin you're looking for + + + + Logger.LogTrace("{pluginName}: {methodRequest} Adding request to queue. (TrackingId: {trackingId}, CorrelationId: {correlationId})", + nameof(GeospatialImagesPlugin), nameof(TaskingRequest), input_request.RequestHeader.TrackingId, input_request.RequestHeader.CorrelationId); + + IMAGE_QUEUE.Enqueue(input_request); + // Flip it to success input_response.ResponseHeader.Status = StatusCodes.Successful; input_response.SensorID = input_request.SensorID; - // Add the client ID to the list so we can direct send it Sensor Data - if (!CLIENT_IDS.Contains(input_request.RequestHeader.AppId)) - CLIENT_IDS.Add(input_request.RequestHeader.AppId); - // Flip it to success - input_response.ResponseHeader.Status = StatusCodes.Successful; + Logger.LogDebug("{pluginName}: {methodRequest} Setting {image_response_type} status to {status}. (TrackingId: {trackingId}, CorrelationId: {correlationId})", + nameof(GeospatialImagesPlugin), nameof(TaskingRequest), input_response.GetType().Name, input_response.ResponseHeader.Status, input_request.RequestHeader.TrackingId, input_request.RequestHeader.CorrelationId); + + Logger.LogDebug("{pluginName}: {methodRequest} Returning {image_response_type} to VTH. (TrackingId: {trackingId}, CorrelationId: {correlationId})", + nameof(GeospatialImagesPlugin), nameof(TaskingRequest), input_response.GetType().Name, input_request.RequestHeader.TrackingId, input_request.RequestHeader.CorrelationId); + return (input_request, input_response); }); @@ -156,4 +170,144 @@ public override Task PluginHealthCheckResponse() => T Logger.LogInformation("{pluginName}: Plugin received and processed a SensorsAvailableRequest Event", nameof(GeospatialImagesPlugin)); return (input_response ?? null); }); + + // Helper Functions: + private async Task processImageRequest(TaskingRequest taskingRequest) { + GeospatialImages.EarthImageRequest imageRequest; + GeospatialImages.EarthImageResponse imageResponse; + string fileName; + + SensorData sensorData = new() { + ResponseHeader = new ResponseHeader() { + TrackingId = Guid.NewGuid().ToString(), + CorrelationId = taskingRequest.RequestHeader.CorrelationId + }, + DestinationAppId = taskingRequest.RequestHeader.AppId, + TaskingTrackingId = taskingRequest.RequestHeader.TrackingId, + SensorID = SENSOR_ID + }; + + // Unpack the request + try { + Logger.LogTrace("{pluginName}: {methodRequest} Extracting {embeddedMessageType} from {messageType}. (TrackingId: {trackingId}, CorrelationId: {correlationId})", + nameof(GeospatialImagesPlugin), nameof(processImageRequest), nameof(GeospatialImages.EarthImageRequest), nameof(TaskingRequest), taskingRequest.RequestHeader.TrackingId, taskingRequest.RequestHeader.CorrelationId); + + imageRequest = taskingRequest.RequestData.Unpack(); + + Logger.LogDebug("{pluginName}: {methodRequest} Successfully extracted {embeddedMessageType} from {messageType}. Request Object: {requestObject} (TrackingId: {trackingId}, CorrelationId: {correlationId})", + nameof(GeospatialImagesPlugin), nameof(processImageRequest), nameof(GeospatialImages.EarthImageRequest), nameof(TaskingRequest), Google.Protobuf.JsonFormatter.Default.Format(imageRequest), taskingRequest.RequestHeader.TrackingId, taskingRequest.RequestHeader.CorrelationId); + + } catch (Exception ex) { + Logger.LogError("{pluginName}: {methodRequest} Failed to extract {embeddedMessageType} from {messageType}. Error: {errMsg} (TrackingId: {trackingId}, CorrelationId: {correlationId})", + nameof(GeospatialImagesPlugin), nameof(processImageRequest), nameof(GeospatialImages.EarthImageRequest), nameof(TaskingRequest), ex.Message, taskingRequest.RequestHeader.TrackingId, taskingRequest.RequestHeader.CorrelationId); + + sensorData.ResponseHeader.Status = StatusCodes.GeneralFailure; + sensorData.ResponseHeader.Message = string.Format($"{nameof(GeospatialImagesPlugin)}: {nameof(TaskingRequest)} Failed to extract {nameof(GeospatialImages.EarthImageRequest)} from {nameof(TaskingRequest)}. Error: {ex.Message}"); + return sensorData; + } + + // Query the Geotiff Processor Tool + try { + Logger.LogTrace("{pluginName}: {methodRequest} Querying tool-image-provider computer. (TrackingId: {trackingId}, CorrelationId: {correlationId})", + nameof(GeospatialImagesPlugin), nameof(processImageRequest), taskingRequest.RequestHeader.TrackingId, taskingRequest.RequestHeader.CorrelationId); + + string imageType = imageRequest.ImageType.ToString().ToLower(); + + Logger.LogDebug("{pluginName}: {methodRequest} requesting {imageType}. (TrackingId: {trackingId}, CorrelationId: {correlationId})", + nameof(GeospatialImagesPlugin), nameof(processImageRequest), imageType, taskingRequest.RequestHeader.TrackingId, taskingRequest.RequestHeader.CorrelationId); + + + // var datagenerator_url = string.Format("http://datagenerator-geospatial-images.svc.cluster.local:8080/get_geotiff?lat={0}&lon={1}", imageRequest.LineOfSight.Latitude.ToString(), imageRequest.LineOfSight.Longitude.ToString()); + var datagenerator_url = string.Format("http://datagenerator-geospatial-images.platformsvc.svc.cluster.local:8080/get_{0}?lat={1}&lon={2}", imageType, imageRequest.LineOfSight.Latitude.ToString(), imageRequest.LineOfSight.Longitude.ToString()); + + + Logger.LogDebug("{pluginName}: {methodRequest} Query: {datagenerator_url} . (TrackingId: {trackingId}, CorrelationId: {correlationId})", + nameof(GeospatialImagesPlugin), nameof(processImageRequest), datagenerator_url, taskingRequest.RequestHeader.TrackingId, taskingRequest.RequestHeader.CorrelationId); + + fileName = await downloadFile(url: datagenerator_url, filePath: Path.Combine(OUTPUT_DIR, taskingRequest.RequestHeader.TrackingId)); + + + } catch (Exception ex) { + Logger.LogError("{pluginName}: {methodRequest} Failed to query datagenerator-geospatial-images. Error: {errMsg} (TrackingId: {trackingId}, CorrelationId: {correlationId})", + nameof(GeospatialImagesPlugin), nameof(processImageRequest), ex.Message, taskingRequest.RequestHeader.TrackingId, taskingRequest.RequestHeader.CorrelationId); + + sensorData.ResponseHeader.Status = MessageFormats.Common.StatusCodes.GeneralFailure; + sensorData.ResponseHeader.Message = string.Format($"{nameof(GeospatialImagesPlugin)}: {nameof(TaskingRequest)} Failed to extract {nameof(GeospatialImages.EarthImageRequest)} from {nameof(TaskingRequest)}. Error: {ex.Message}"); + return sensorData; + } + + // Build the sensor data message to return to the calling method + imageResponse = new() { + LineOfSight = imageRequest.LineOfSight, + Filename = fileName + }; + + DateTime maxTimeToWaitForFile = DateTime.Now.Add(TimeSpan.FromSeconds(30)); + + Logger.LogDebug("{pluginName}: {methodRequest} waiting for {filePath}. (TrackingId: {trackingId}, CorrelationId: {correlationId})", + nameof(GeospatialImagesPlugin), nameof(processImageRequest), Path.Combine(OUTPUT_DIR, imageResponse.Filename), taskingRequest.RequestHeader.TrackingId, taskingRequest.RequestHeader.CorrelationId); + + while (!File.Exists(Path.Combine(OUTPUT_DIR, imageResponse.Filename)) && DateTime.Now <= maxTimeToWaitForFile) { + await Task.Delay(100); + } + + + if (File.Exists(Path.Combine(OUTPUT_DIR, imageResponse.Filename))) { + Logger.LogInformation("{pluginName}: {methodRequest} Found file at '{filePath}'. Sending link request to '{destinationAppId}'. (TrackingId: {trackingId}, CorrelationId: {correlationId})", + nameof(GeospatialImagesPlugin), nameof(processImageRequest), Path.Combine(OUTPUT_DIR, imageResponse.Filename), taskingRequest.RequestHeader.AppId, taskingRequest.RequestHeader.TrackingId, taskingRequest.RequestHeader.CorrelationId); + + LinkRequest linkRequest = new() { + DestinationAppId = taskingRequest.RequestHeader.AppId, + ExpirationTime = Timestamp.FromDateTime(DateTime.UtcNow.AddHours(1)), + FileName = fileName, + LeaveSourceFile = false, + LinkType = LinkRequest.Types.LinkType.App2App, + Priority = Priority.Medium, + RequestHeader = new() { + TrackingId = Guid.NewGuid().ToString(), + CorrelationId = sensorData.ResponseHeader.CorrelationId + } + }; + + if (taskingRequest.RequestHeader.Metadata.FirstOrDefault((_item) => _item.Key == "SOURCE_PAYLOAD_APP_ID").Value != null) { + string sourcePayloadAppID = taskingRequest.RequestHeader.Metadata.FirstOrDefault((_item) => _item.Key == "SOURCE_PAYLOAD_APP_ID").Value; + linkRequest.RequestHeader.Metadata.Add("SOURCE_PAYLOAD_APP_ID", sourcePayloadAppID); + } + + LinkRequestIDs.TryAdd(sensorData.ResponseHeader.CorrelationId, linkRequest); + await Core.DirectToApp(appId: $"hostsvc-{nameof(HostServices.Link)}", message: linkRequest); + + } else { + sensorData.ResponseHeader.Status = StatusCodes.Timeout; + sensorData.ResponseHeader.Message = $"Timeout while waiting for file to land in {OUTPUT_DIR}. Check the tool-geotiff-processor pod logs for errors and troubleshoot"; + } + + Logger.LogInformation("{pluginName}: {methodRequest} Returning generated sensor data. (TrackingId: {trackingId}, CorrelationId: {correlationId})", + nameof(GeospatialImagesPlugin), nameof(processImageRequest), taskingRequest.RequestHeader.TrackingId, taskingRequest.RequestHeader.CorrelationId); + + sensorData.ResponseHeader.Status = StatusCodes.Successful; + sensorData.Data = Any.Pack(imageResponse); + + return sensorData; + } + + private async Task downloadFile(string url, string filePath) { + using (HttpResponseMessage response = await HTTP_CLIENT.GetAsync(url, HttpCompletionOption.ResponseHeadersRead)) { + response.EnsureSuccessStatusCode(); + string contentType = response.Content.Headers.ContentType.MediaType.Split('/')[1]; + string fullFilePath = filePath + "." + contentType; + + + using (Stream streamToReadFrom = await response.Content.ReadAsStreamAsync()) { + using (Stream streamToWriteTo = File.Open(fullFilePath, FileMode.Create)) { + await streamToReadFrom.CopyToAsync(streamToWriteTo); + streamToWriteTo.Close(); + } + streamToReadFrom.Close(); + } + response.Dispose(); + + return Path.GetFileName(fullFilePath); + } + } } From 3bb5ce6fe6a21284b8231ab31fabbc3a735c3172 Mon Sep 17 00:00:00 2001 From: alianides Date: Wed, 24 Jul 2024 22:52:15 +0000 Subject: [PATCH 5/8] plugin readme update --- datagenerators/geospatial-images/plugin/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/datagenerators/geospatial-images/plugin/README.md b/datagenerators/geospatial-images/plugin/README.md index dbb054c..fa02517 100644 --- a/datagenerators/geospatial-images/plugin/README.md +++ b/datagenerators/geospatial-images/plugin/README.md @@ -1 +1 @@ -README doc for writing a VTH plugin \ No newline at end of file +README doc for Geospatial Images plugin \ No newline at end of file From b5862230524848c8612db31205cb8794ca6506f9 Mon Sep 17 00:00:00 2001 From: alianides Date: Thu, 25 Jul 2024 00:09:16 +0000 Subject: [PATCH 6/8] Updated readme --- datagenerators/geospatial-images/README.md | 92 +++++++++++++++++++++- 1 file changed, 91 insertions(+), 1 deletion(-) diff --git a/datagenerators/geospatial-images/README.md b/datagenerators/geospatial-images/README.md index e1897da..490af07 100644 --- a/datagenerators/geospatial-images/README.md +++ b/datagenerators/geospatial-images/README.md @@ -1,3 +1,93 @@ # Geospatial Images -TODO \ No newline at end of file +## Using the Geospatial Images Data Generator in your app +Using the Geospatial Images Data Generator requires the Plugin, the Plugin Config, the Data Generator container, and the Data Generator Deployment yaml. The spacefx-dev container feature can be used to automatically download and deploy these with the below configuration: +```json + "features": { + "ghcr.io/microsoft/azure-orbital-space-sdk/spacefx-dev:0.11.0": { + "app_name": "MyAwesomeApp", + "download_artifacts": "GeospatialImages.proto, datagenerator-geospatial-images.yaml, geospatial-images-vth-plugin.dll, geospatial-images-vth-plugin.json.spacefx_plugin", + "pull_containers": "datagenerator-geospatial-images:0.11.0-nightly" + } + }, +``` + +## Geospatial Images Data Generator Source Code +The Geospatial Images Data Generator comprises two components: +* [Geospatial Images Data Generator](https://github.com/microsoft/azure-orbital-space-sdk-data-generators/tree/main/datagenerators/geospatial-images/datagenerator) +* [Geospatial Images VTH Plugin](https://github.com/microsoft/azure-orbital-space-sdk-data-generators/tree/main/datagenerators/geospatial-images/plugin) + +The data generator is a Flask App that contains a repository of geospatial imagery available for querying, while the VTH Plugin is used to interact with the Flask App and download any of the geospatial images stored within the datagenerator, then send them via Link Service to the requesting Payload App. + +## Building the Geospatial Images Data Generator (from source) +>:speech_balloon: The images, plugins, and artifacts are already built and pushed to the github container registry via our CI/CD process. These steps are a reference and **not** needed to run the Geospatial Images Data Generator. If you would like to just run the Geospatial Images Data Generator, please refer to [Geospatial Images Data Generator](https://github.com/microsoft/azure-orbital-space-sdk-data-generators/tree/main/datagenerators/geospatial-images) + +1. Provision /var/spacedev + ```bash + # clone the azure-orbital-space-sdk-setup repo and provision /var/spacedev + git clone https://github.com/microsoft/azure-orbital-space-sdk-setup + cd azure-orbital-space-sdk-setup + bash ./.vscode/copy_to_spacedev.sh + cd - + ``` + +2. Clone this repo + ```bash + # clone this repo + git clone https://github.com/microsoft/azure-orbital-space-sdk-data-generators + + cd azure-orbital-space-sdk-data-generators + ``` + +3. Build and push the Geospatial Images Data Generator + ```bash + # Trigger the build_containerImage.sh from azure-orbital-space-sdk-setup + /var/spacedev/build/build_containerImage.sh \ + --architecture amd64 \ + --app-name datagenerator-geospatial-images \ + --image-tag 0.11.0 \ + --dockerfile Dockerfiles/Dockerfile \ + --repo-dir ${PWD}/datagenerators/geospatial-images/datagenerator \ + --no-push \ + --annotation-config azure-orbital-space-sdk-data-generators.yaml + ``` + >:pencil2: the `--no-push` parameter will prevent build_containerImage.sh from pushing to a container registry. We added it here to prevent accidental pushes when you copy-and-paste the command. You will need to remove the `--no-push` if you want to push the final container image to a container registry + +4. Build the Geospatial Images VTH Plugin + ```bash + # Trigger the build_app.sh from azure-orbital-space-sdk-setup + /var/spacedev/build/dotnet/build_app.sh \ + --architecture amd64 \ + --app-project src/geospatial-images-vth-plugin.csproj \ + --app-version 0.11.0 \ + --output-dir /var/spacedev/tmp/geospatial-images-vth-plugin/output \ + --repo-dir ${PWD} \ + --devcontainer-json .devcontainer/geospatial-images-vth-plugin/devcontainer.json \ + --no-container-build \ + --no-push + ``` + >:pencil2: the `--no-container-build` parameter means that we're just interested in the build artifacts and there's not a container image for this. The `--no-push` is superflous since we aren't generating a container image, but kept it here for reference. + +5. Copy the artifacts to their regular folders so it can be read by the containers + ```bash + # Put the dll, spacefx_config, and yaml in the destination directories + sudo mkdir -p /var/spacedev/plugins/vth + sudo mkdir -p /var/spacedev/yamls/deploy + sudo mkdir -p /var/spacedev/protos/datagenerator/geospatial-images + + sudo cp /var/spacedev/tmp/geospatial-images-vth-plugin/output/amd64/app/geospatial-images-vth-plugin.dll /var/spacedev/plugins/vth/ + sudo cp /var/spacedev/tmp/geospatial-images-vth-plugin/output/amd64/app/geospatial-images-vth-plugin.json.spacefx_plugin /var/spacedev/plugins/vth/ + sudo cp ${PWD}/datagenerators/geospatial-images/datagenerator/k3s/datagenerator-geospatial-images.yaml /var/spacedev/yamls/deploy/ + sudo cp ${PWD}/datagenerators/geospatial-images/plugin/src/Protos/GeospatialImages.proto /var/spacedev/protos/datagenerator/geospatial-images/ + ``` + +6. (Optional) Push the build artifacts to the container registry + >:heavy_exclamation_mark: the next step will push the build artifacts to the first container registry you have write access to, including our automated channel tagging and patching aliases. Do not run this step unless you intend to deploy the artifacts to a container registry for others to consume. + ```bash + /var/spacedev/build/push_build_artifact.sh --artifact /var/spacedev/plugins/vth/geospatial-images-vth-plugin.dll --annotation-config azure-orbital-space-sdk-data-generators.yaml --architecture amd64 --artifact-version 0.11.0 + /var/spacedev/build/push_build_artifact.sh --artifact /var/spacedev/plugins/vth/geospatial-images-vth-plugin.json.spacefx_plugin --annotation-config azure-orbital-space-sdk-data-generators.yaml --architecture amd64 --artifact-version 0.11.0 + /var/spacedev/build/push_build_artifact.sh --artifact /var/spacedev/yamls/deploy/datagenerator-geospatial-images.yaml --annotation-config azure-orbital-space-sdk-data-generators.yaml --architecture amd64 --artifact-version 0.11.0 + /var/spacedev/build/push_build_artifact.sh --artifact /var/spacedev/protos/datagenerator/geospatial-images/GeospatialImages.proto --annotation-config azure-orbital-space-sdk-data-generators.yaml --architecture amd64 --artifact-version 0.11.0 + ``` + + From 813815898a766f50263c24f55b8795ab8b236981 Mon Sep 17 00:00:00 2001 From: alianides Date: Thu, 25 Jul 2024 16:22:02 +0000 Subject: [PATCH 7/8] build workflow for plugin --- .../geospatial-images-plugin-build.yaml | 59 +++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 .github/workflows/geospatial-images-plugin-build.yaml diff --git a/.github/workflows/geospatial-images-plugin-build.yaml b/.github/workflows/geospatial-images-plugin-build.yaml new file mode 100644 index 0000000..33d75f3 --- /dev/null +++ b/.github/workflows/geospatial-images-plugin-build.yaml @@ -0,0 +1,59 @@ +name: geospatial-images-plugin-build + +on: + workflow_dispatch: + push: + branches: + - main + paths: + - 'datagenerators/geospatial-images/plugin/**' + - '.github/workflows/geospatial-images-plugin-build.yaml' + +jobs: + build-plugin-geospatial-images-amd64: + permissions: + contents: read + packages: write + + uses: microsoft/azure-orbital-space-sdk-github-actions/.github/workflows/plugin-build.yaml@main + with: + APP_PROJECT: ./src/geospatial-images-vth-plugin.csproj + OUTPUT_DIR: /var/spacedev/tmp/geospatial-images-vth-plugin/output + PLUGIN_STAGING_DIRECTORY: /var/spacedev/plugins/vth + PLUGIN_FILE_NAME: geospatial-images-vth-plugin.dll + PLUGIN_CONFIG_FILE_NAME: geospatial-images-vth-plugin.json.spacefx_plugin + ANNOTATION: azure-orbital-space-sdk-data-generators.yaml + WORKFLOW_AGENT: ubuntu-latest + ARCHITECTURE: amd64 + DEV_CONTAINER_JSON: .devcontainer/geospatial-images-vth-plugin/devcontainer.json + PROTO_STAGING_DIRECTORY: /var/spacedev/protos/datagenerator/geospatial-images + PROTO_FOLDER_PATH: ./datagenerators/geospatial-images/plugin/src/Protos + PROTO_FILE_NAME: GeospatialImages.proto + secrets: + GIT_HUB_USER_NAME: ${{ secrets.TEMP_GITHUB_USERNAME }} + GIT_HUB_USER_TOKEN: ${{ secrets.TEMP_WORKFLOW_TOKEN }} + SETUP_REPO_URL: ${{ secrets.SETUP_REPO_URL }} + + build-plugin-geospatial-images-arm64: + permissions: + contents: read + packages: write + + uses: microsoft/azure-orbital-space-sdk-github-actions/.github/workflows/plugin-build.yaml@main + with: + APP_PROJECT: ./src/geospatial-images-vth-plugin.csproj + OUTPUT_DIR: /var/spacedev/tmp/geospatial-images-vth-plugin/output + PLUGIN_STAGING_DIRECTORY: /var/spacedev/plugins/vth + PLUGIN_FILE_NAME: geospatial-images-vth-plugin.dll + PLUGIN_CONFIG_FILE_NAME: geospatial-images-vth-plugin.json.spacefx_plugin + ANNOTATION: azure-orbital-space-sdk-data-generators.yaml + WORKFLOW_AGENT: spacesdk-ubuntu-2204LTS-arm64 + ARCHITECTURE: arm64 + DEV_CONTAINER_JSON: .devcontainer/geospatial-images-vth-plugin/devcontainer.json + PROTO_STAGING_DIRECTORY: /var/spacedev/protos/datagenerator/geospatial-images + PROTO_FOLDER_PATH: ./datagenerators/geospatial-images/plugin/src/Protos + PROTO_FILE_NAME: GeospatialImages.proto + secrets: + GIT_HUB_USER_NAME: ${{ secrets.TEMP_GITHUB_USERNAME }} + GIT_HUB_USER_TOKEN: ${{ secrets.TEMP_WORKFLOW_TOKEN }} + SETUP_REPO_URL: ${{ secrets.SETUP_REPO_URL }} \ No newline at end of file From cb63737f6e79fb739b8f78216d41cb01deb33e65 Mon Sep 17 00:00:00 2001 From: alianides Date: Thu, 25 Jul 2024 16:39:05 +0000 Subject: [PATCH 8/8] add artificacts --- .devcontainer/geospatial-images-vth-plugin/devcontainer.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.devcontainer/geospatial-images-vth-plugin/devcontainer.json b/.devcontainer/geospatial-images-vth-plugin/devcontainer.json index c7566fb..5951dfa 100644 --- a/.devcontainer/geospatial-images-vth-plugin/devcontainer.json +++ b/.devcontainer/geospatial-images-vth-plugin/devcontainer.json @@ -13,8 +13,8 @@ "app_name": "geospatial-images-vth-plugin", "app_type": "vth-plugin", "addl_debug_shim_suffixes": "client", - // "pull_containers": "datagenerator-geospatial-images:0.11.0-nightly", - // "download_artifacts": "datagenerator-geospatial-images.yaml" + "pull_containers": "datagenerator-geospatial-images:0.11.0-nightly", + "download_artifacts": "datagenerator-geospatial-images.yaml" } }, "mounts": [