ni / measurement-plugin-python

Python framework to develop measurement plug-ins for NI application software. Contains sample measurement plug-ins for InstrumentStudio and TestStand.
MIT License
19 stars 15 forks source link

Measurement client generator does not work with C# services #851

Closed bkeryan closed 1 month ago

bkeryan commented 2 months ago

Bug Report

The generated measurement client gets a gRPC UNKNOWN error from C# services.

The generated measurement client generator does not specify MeasureRequest.configuration_parameters.type_url. C# measurement services use Any.Unpack<T>, which validates the type URL.

Repro or Code Sample

Run the C# GameOfLife example.

PS D:\dev\measurement-plugin-python\packages\generator> poetry run ni-measurement-plugin-client-generator ni.examples.GameOfLife
PS D:\dev\measurement-plugin-python\packages\generator> poetry run python
Python 3.9.13 (tags/v3.9.13:6de2ca5, May 17 2022, 16:36:42) [MSC v.1929 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import game_of_life_client
>>> client = game_of_life_client.GameOfLifeClient()
>>> client.measure()

Expected Behavior

It returns a measurement.

Current Behavior

>>> client.measure()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "D:\dev\measurement-plugin-python\packages\generator\game_of_life_client.py", line 192, in measure
    for response in self._get_stub().Measure(request):
  File "D:\dev\measurement-plugin-python\packages\generator\.venv\lib\site-packages\grpc\_channel.py", line 543, in __next__
    return self._next()
  File "D:\dev\measurement-plugin-python\packages\generator\.venv\lib\site-packages\grpc\_channel.py", line 969, in _next
    raise self
grpc._channel._MultiThreadedRendezvous: <_MultiThreadedRendezvous of RPC that terminated with:
        status = StatusCode.UNKNOWN
        details = "Exception was thrown by handler."
        debug_error_string = "UNKNOWN:Error received from peer  {grpc_message:"Exception was thrown by handler.", grpc_status:2, created_time:"2024-08-28T18:45:14.0185954+00:00"}"
>

C:\ProgramData\National Instruments\Plug-Ins\Logs\DiscoveryService.txt:

===== 08/28/2024 13:45:09 ===== Information: ResolveService "ni.measurementlink.measurement.v2.MeasurementService": Local IP: "127.0.0.1" Remote IP: "127.0.0.1" DeploymentTarget: ""
===== 08/28/2024 13:45:09 ===== Information: Resolved "127.0.0.1" to HostName: "replicas"
===== 08/28/2024 13:45:09 ===== Information: HTTP "POST" "/ni.measurementlink.discovery.v1.DiscoveryService/ResolveService" responded 200 in 0.7390 ms
===== 08/28/2024 13:45:09 ===== Information: "Game Of Life (.NET)": "[13:45:09 INF] HTTP POST /ni.measurementlink.measurement.v2.MeasurementService/GetMetadata responded 200 in 0.8750 ms"
===== 08/28/2024 13:45:14 ===== Information: "Game Of Life (.NET)": "[13:45:14 ERR] Error when executing service method 'Measure'."
===== 08/28/2024 13:45:14 ===== Information: "Game Of Life (.NET)": "Google.Protobuf.InvalidProtocolBufferException: Full type name for GameOfLifeParameters is ni.measurementlink.examples.v1.GameOfLifeParameters; Any message's type url is "
===== 08/28/2024 13:45:14 ===== Information: "Game Of Life (.NET)": "   at Google.Protobuf.WellKnownTypes.Any.Unpack[T]()"
===== 08/28/2024 13:45:14 ===== Information: "Game Of Life (.NET)": "   at NationalInstruments.MeasurementLink.Examples.GameOfLifeMeasurement.MeasureAsync(MeasureRequest request, IServerStreamWriter`1 responseWriter, ServerCallContext context) in C:\dev\asw\Source\MeasurementServices\Examples\GameOfLife\Services\GameOfLifeMeasurement.cs:line 36"
===== 08/28/2024 13:45:14 ===== Information: "Game Of Life (.NET)": "   at NationalInstruments.MeasurementLink.Measurement.MeasurementServiceV2`2.Measure(MeasureRequest request, IServerStreamWriter`1 responseStream, ServerCallContext context) in C:\dev\asw\Source\MeasurementServices\MeasurementService\MeasurementServiceV2.cs:line 42"
===== 08/28/2024 13:45:14 ===== Information: "Game Of Life (.NET)": "   at Grpc.Shared.Server.ServerStreamingServerMethodInvoker`3.Invoke(HttpContext httpContext, ServerCallContext serverCallContext, TRequest request, IServerStreamWriter`1 streamWriter)"
===== 08/28/2024 13:45:14 ===== Information: "Game Of Life (.NET)": "   at Grpc.Shared.Server.ServerStreamingServerMethodInvoker`3.Invoke(HttpContext httpContext, ServerCallContext serverCallContext, TRequest request, IServerStreamWriter`1 streamWriter)"
===== 08/28/2024 13:45:14 ===== Information: "Game Of Life (.NET)": "   at Grpc.AspNetCore.Server.Internal.CallHandlers.ServerStreamingServerCallHandler`3.HandleCallAsyncCore(HttpContext httpContext, HttpContextServerCallContext serverCallContext)"
===== 08/28/2024 13:45:14 ===== Information: "Game Of Life (.NET)": "   at Grpc.AspNetCore.Server.Internal.CallHandlers.ServerCallHandlerBase`3.<HandleCallAsync>g__AwaitHandleCall|8_0(HttpContextServerCallContext serverCallContext, Method`2 method, Task handleCall)"
===== 08/28/2024 13:45:14 ===== Information: "Game Of Life (.NET)": "[13:45:14 INF] HTTP POST /ni.measurementlink.measurement.v2.MeasurementService/Measure responded 200 in 0.9208 ms"

Possible Solution

Change the generator to build a type URL using the message name from the MeasurementSignature.

Context

841

Your Environment

AB#2841900