7a8fb5f129
Phase 3 Task 4. GrpcDeploymentArtifactFetcher streams the artifact from the first configured central endpoint that answers, reassembles the chunks, and verifies SHA-256(bytes) lowercase-hex == the dispatched RevisionHash (byte-identical to ConfigComposer's Convert.ToHexStringLower(SHA256.HashData(blob))). Every per-endpoint problem — RpcException, zero-length stream, or hash mismatch — is logged and the next endpoint tried; if none yield verified bytes it returns null (apply failure, keep last-known-good — the #485 contract), never throwing into the actor loop. A Func<endpoint, client> seam keeps the gRPC boundary out of the unit tests (that is Task 8's job); the real path caches one h2c GrpcChannel per endpoint. Files live under the .DeploymentCache namespace (folder Deployment/) to avoid shadowing the Configuration.Entities.Deployment type in the test assembly — same convention as LocalDbDeploymentArtifactCache. Claude-Session: https://claude.ai/code/session_01GASWkNEi68FSCtvr6rLoEW
47 lines
3.1 KiB
XML
47 lines
3.1 KiB
XML
<Project Sdk="Microsoft.NET.Sdk">
|
|
|
|
<PropertyGroup>
|
|
<RootNamespace>ZB.MOM.WW.OtOpcUa.Runtime</RootNamespace>
|
|
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
|
</PropertyGroup>
|
|
|
|
<ItemGroup>
|
|
<PackageReference Include="Akka.Hosting"/>
|
|
<PackageReference Include="Akka.Cluster.Tools"/>
|
|
<!-- Node-side gRPC client that fetches the deployed-configuration artifact from central
|
|
(per-cluster mesh Phase 3, FetchAndCache mode). The generated stub lives in Commons. -->
|
|
<PackageReference Include="Grpc.Net.Client"/>
|
|
<!-- Core LocalDb only (ILocalDb + the connection/transaction seam) — the deployment-artifact
|
|
cache lives here, but the sync engine and its gRPC endpoint are the Host's concern. -->
|
|
<PackageReference Include="ZB.MOM.WW.LocalDb" />
|
|
</ItemGroup>
|
|
|
|
<ItemGroup>
|
|
<ProjectReference Include="..\..\Core\ZB.MOM.WW.OtOpcUa.Commons\ZB.MOM.WW.OtOpcUa.Commons.csproj"/>
|
|
<ProjectReference Include="..\..\Core\ZB.MOM.WW.OtOpcUa.Cluster\ZB.MOM.WW.OtOpcUa.Cluster.csproj"/>
|
|
<ProjectReference Include="..\..\Core\ZB.MOM.WW.OtOpcUa.Configuration\ZB.MOM.WW.OtOpcUa.Configuration.csproj"/>
|
|
<ProjectReference Include="..\ZB.MOM.WW.OtOpcUa.OpcUaServer\ZB.MOM.WW.OtOpcUa.OpcUaServer.csproj"/>
|
|
<!--
|
|
Concrete OtOpcUa.Driver.* assemblies are loaded reflectively at runtime (Phase 6,
|
|
Task 41+) and intentionally NOT project-referenced here. The driver contracts live in
|
|
ZB.MOM.WW.OtOpcUa.Core.Abstractions, which Runtime picks up transitively through
|
|
ZB.MOM.WW.OtOpcUa.Configuration. Adding a direct reference would create a build-time
|
|
coupling and force every concrete driver to compile into Runtime's output, defeating
|
|
the reflective-load design.
|
|
-->
|
|
<ProjectReference Include="..\..\Core\ZB.MOM.WW.OtOpcUa.Core.Abstractions\ZB.MOM.WW.OtOpcUa.Core.Abstractions.csproj"/>
|
|
<ProjectReference Include="..\..\Core\ZB.MOM.WW.OtOpcUa.Core.AlarmHistorian\ZB.MOM.WW.OtOpcUa.Core.AlarmHistorian.csproj"/>
|
|
<!-- ITagUpstreamSource (the scripted-alarm engine's value-feed seam) lives here;
|
|
DependencyMuxTagUpstreamSource implements it so the host actor can push
|
|
DependencyValueChanged values into the engine. -->
|
|
<ProjectReference Include="..\..\Core\ZB.MOM.WW.OtOpcUa.Core.ScriptedAlarms\ZB.MOM.WW.OtOpcUa.Core.ScriptedAlarms.csproj"/>
|
|
<!-- IScriptLogPublisher lives in Core.Scripting; DpsScriptLogPublisher implements it
|
|
here so the concrete Akka DPS routing stays out of the Core layer. -->
|
|
<ProjectReference Include="..\..\Core\ZB.MOM.WW.OtOpcUa.Core.Scripting\ZB.MOM.WW.OtOpcUa.Core.Scripting.csproj"/>
|
|
<!-- IHistoryWriter / NullHistoryWriter live in Core.VirtualTags; VirtualTagHostActor forwards
|
|
historized VirtualTag results to it (H5c). The durable sink is wired by the host's DI. -->
|
|
<ProjectReference Include="..\..\Core\ZB.MOM.WW.OtOpcUa.Core.VirtualTags\ZB.MOM.WW.OtOpcUa.Core.VirtualTags.csproj"/>
|
|
</ItemGroup>
|
|
|
|
</Project>
|