-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #8 from equinor/story/boundary-application
Boundary dotnet app
- Loading branch information
Showing
17 changed files
with
421 additions
and
42 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
name: "Run tests (required)" | ||
on: | ||
workflow_dispatch: | ||
pull_request: | ||
push: | ||
branches: | ||
- main | ||
|
||
jobs: | ||
dotnet-tests: | ||
runs-on: ubuntu-latest | ||
name: ".NET Tests & Reports" | ||
timeout-minutes: 5 | ||
steps: | ||
- name: Checkout | ||
uses: actions/checkout@v4 | ||
|
||
- name: Setup .NET | ||
uses: actions/setup-dotnet@v4 | ||
with: | ||
dotnet-version: 8.0.x | ||
|
||
- name: Restore dependencies | ||
run: dotnet restore ./client/Boundaries/Boundaries.sln | ||
|
||
- name: Build | ||
run: dotnet build ./client/Boundaries/Boundaries.sln --no-restore | ||
|
||
- name: Test | ||
run: | | ||
dotnet test ./client/Boundaries/Boundaries.sln --no-build --verbosity normal |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,3 +4,5 @@ dexpi.properties | |
pandid.xml | ||
pandid.trig | ||
imf-ontology.owl.ttl | ||
rml/segments.trig | ||
client/.idea |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
|
||
Microsoft Visual Studio Solution File, Format Version 12.00 | ||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Boundaries", "Boundaries\Boundaries.csproj", "{B7723633-9BCD-44C6-BC90-1E3F5C6C8101}" | ||
EndProject | ||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestBoundaries", "TestBoundaries\TestBoundaries.csproj", "{6389698E-C0E2-4262-AE30-FD2A01654FA5}" | ||
EndProject | ||
Global | ||
GlobalSection(SolutionConfigurationPlatforms) = preSolution | ||
Debug|Any CPU = Debug|Any CPU | ||
Release|Any CPU = Release|Any CPU | ||
EndGlobalSection | ||
GlobalSection(ProjectConfigurationPlatforms) = postSolution | ||
{B7723633-9BCD-44C6-BC90-1E3F5C6C8101}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | ||
{B7723633-9BCD-44C6-BC90-1E3F5C6C8101}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||
{B7723633-9BCD-44C6-BC90-1E3F5C6C8101}.Release|Any CPU.ActiveCfg = Release|Any CPU | ||
{B7723633-9BCD-44C6-BC90-1E3F5C6C8101}.Release|Any CPU.Build.0 = Release|Any CPU | ||
{6389698E-C0E2-4262-AE30-FD2A01654FA5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | ||
{6389698E-C0E2-4262-AE30-FD2A01654FA5}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||
{6389698E-C0E2-4262-AE30-FD2A01654FA5}.Release|Any CPU.ActiveCfg = Release|Any CPU | ||
{6389698E-C0E2-4262-AE30-FD2A01654FA5}.Release|Any CPU.Build.0 = Release|Any CPU | ||
EndGlobalSection | ||
EndGlobal |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<OutputType>Exe</OutputType> | ||
<TargetFramework>net8.0</TargetFramework> | ||
<ImplicitUsings>enable</ImplicitUsings> | ||
<Nullable>enable</Nullable> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="IriTools" Version="2.2.0" /> | ||
</ItemGroup> | ||
|
||
</Project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
using IriTools; | ||
|
||
namespace Boundaries; | ||
|
||
public class DatalogCreator | ||
{ | ||
public IriReference BoundaryGraph = new IriReference($"https://data.equinor.com/boundaries/{Guid.NewGuid()}"); | ||
|
||
public string CreateCommissioningSparqlQuery() | ||
{ | ||
return $"select ?s(GROUP_CONCAT(?label; SEPARATOR=',') AS ?labels) where {{?s a <{BoundaryGraph}>; rdfs:label ?label. OPTIONAL{{?s <http://sandbox.dexpi.org/rdl/TagNameAssignmentClass> ?tag.}} }} GROUP BY (?s)"; | ||
} | ||
|
||
public string CreateBoundaryDatalogRule(string internalComponentLabel, IriReference[] borderComponentIris) | ||
{ | ||
var filters = borderComponentIris | ||
.Select(iri => $"NOT FILTER(?node1 = <{iri}>)") | ||
.Aggregate("", (acc, filter) => acc + ",\n " + filter); | ||
return $$""" | ||
<{{BoundaryGraph}}> [?node] :- | ||
rdfs:label [?internal, "{{internalComponentLabel}}"], | ||
imf:connectedTo [?internal, ?node], | ||
dexpi:PipingOrEquipment [?node]. | ||
<{{BoundaryGraph}}> [?node] :- | ||
<{{BoundaryGraph}}> [?node1], | ||
imf:connectedTo [?node1, ?node]{{filters}}, | ||
dexpi:PipingOrEquipment [?node]. | ||
"""; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
using IriTools; | ||
|
||
namespace Boundaries; | ||
|
||
internal class Program | ||
{ | ||
private static async Task Main(string[] args) | ||
{ | ||
if (args.Length < 3) | ||
{ | ||
Console.WriteLine( | ||
"Usage \"dotnet run filename-for-dexpi-in-rdf \"label-of-internal-componenet\" iri-of-border-component ... iri-of-border-component "); | ||
Console.WriteLine( | ||
"For example \"dotnet run ../../../rml/pandid.trig \"T4750\" https://assetid.equinor.com/plantx#Nozzle-12 https://assetid.equinor.com/plantx#Nozzle-8 https://assetid.equinor.com/plantx#PlateHeatExchanger-1 https://assetid.equinor.com/plantx#ReciprocatingPump-1"); | ||
return; | ||
} | ||
|
||
var dexpiFilePath = args[0]; | ||
var internalComponentLabel = args[1]; | ||
if (!File.Exists(dexpiFilePath)) | ||
{ | ||
Console.WriteLine( | ||
$"Could not find one of the input file {dexpiFilePath}"); | ||
return; | ||
} | ||
|
||
var borderComponentIris = args.Skip(2).Select(iri => new IriReference(iri)).ToArray(); | ||
var datalogCreator = new DatalogCreator(); | ||
var datalog = datalogCreator.CreateBoundaryDatalogRule(internalComponentLabel, borderComponentIris); | ||
var conn = RdfoxApi.GetDefaultConnectionSettings(); | ||
await RdfoxApi.LoadDatalog(conn, datalog); | ||
|
||
var data = File.ReadAllText(dexpiFilePath); | ||
await RdfoxApi.LoadData(conn, data); | ||
|
||
var queryString = datalogCreator.CreateCommissioningSparqlQuery(); | ||
var result = await RdfoxApi.QuerySparql(conn, queryString); | ||
Console.WriteLine("Commissioning package:"); | ||
Console.WriteLine(result); | ||
|
||
await RdfoxApi.DeleteData(conn, data); | ||
await RdfoxApi.DeleteDatalog(conn, datalog); | ||
|
||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,148 @@ | ||
using System.Text; | ||
using IriTools; | ||
|
||
namespace Boundaries; | ||
|
||
|
||
public class RdfoxApi | ||
{ | ||
public struct ConnectionSettings | ||
{ | ||
public string Host { get; set; } | ||
public int Port { get; set; } | ||
public string Username { get; set; } | ||
public string Password { get; set; } | ||
public string Datastore { get; set; } | ||
|
||
} | ||
|
||
public static ConnectionSettings GetDefaultConnectionSettings() | ||
{ | ||
return new ConnectionSettings | ||
{ | ||
Host = "localhost", | ||
Port = 12110, | ||
Username = "admin", | ||
Password = "admin", | ||
Datastore = "boundaries" | ||
}; | ||
} | ||
|
||
|
||
/// <summary> | ||
/// curl -i -X POST localhost:12110/datastores/boundaries/content?operation=delete-content -H "Content-Type: application/x.datalog" -T boundaries.dlog | ||
/// </summary> | ||
/// <param name="conn"></param> | ||
/// <param name="datalog"></param> | ||
public static async Task DeleteDatalog(ConnectionSettings conn, string datalog) | ||
{ | ||
using (var client = new HttpClient()) | ||
{ | ||
var uri = new Uri($"http://{conn.Host}:{conn.Port}/datastores/{conn.Datastore}/content?operation=delete-content"); | ||
var content = new StringContent(datalog, Encoding.UTF8, "application/x.datalog"); | ||
|
||
var request = new HttpRequestMessage(HttpMethod.Patch, uri) | ||
{ | ||
Content = content | ||
}; | ||
|
||
var response = await client.SendAsync(request); | ||
response.EnsureSuccessStatusCode(); | ||
} | ||
} | ||
|
||
/// <summary> | ||
/// curl -i -X POST localhost:12110/datastores/boundaries/content -H "Content-Type: application/x.datalog" -T boundaries.dlog | ||
/// </summary> | ||
/// <param name="conn"></param> | ||
/// <param name="datalog"></param> | ||
public static async Task LoadDatalog(ConnectionSettings conn, string datalog) | ||
{ | ||
using (var client = new HttpClient()) | ||
{ | ||
var uri = new Uri($"http://{conn.Host}:{conn.Port}/datastores/{conn.Datastore}/content"); | ||
var content = new StringContent(datalog, Encoding.UTF8, "application/x.datalog"); | ||
|
||
var request = new HttpRequestMessage(HttpMethod.Post, uri) | ||
{ | ||
Content = content | ||
}; | ||
|
||
|
||
var response = await client.SendAsync(request); | ||
response.EnsureSuccessStatusCode(); | ||
} | ||
} | ||
|
||
/// <summary> | ||
/// curl -i -X PATCH localhost:12110/datastores/boundaries/content?operation=delete-content -H "Content-Type: application/trig" -T boundaries.dlog | ||
/// </summary> | ||
/// <param name="conn"></param> | ||
/// <param name="datalog"></param> | ||
public static async Task DeleteData(ConnectionSettings conn, string data) | ||
{ | ||
using (var client = new HttpClient()) | ||
{ | ||
var uri = new Uri($"http://{conn.Host}:{conn.Port}/datastores/{conn.Datastore}/content?operation=delete-content"); | ||
var content = new StringContent(data, Encoding.UTF8, "application/trig"); | ||
|
||
var request = new HttpRequestMessage(HttpMethod.Patch, uri) | ||
{ | ||
Content = content | ||
}; | ||
|
||
|
||
var response = await client.SendAsync(request); | ||
response.EnsureSuccessStatusCode(); | ||
} | ||
} | ||
|
||
/// <summary> | ||
/// curl -i -X POST localhost:12110/datastores/boundaries/content -H "Content-Type: application/trig" -T boundaries.dlog | ||
/// </summary> | ||
/// <param name="conn"></param> | ||
/// <param name="datalog"></param> | ||
public static async Task LoadData(ConnectionSettings conn, string data) | ||
{ | ||
using (var client = new HttpClient()) | ||
{ | ||
var uri = new Uri($"http://{conn.Host}:{conn.Port}/datastores/{conn.Datastore}/content"); | ||
var content = new StringContent(data, Encoding.UTF8, "application/trig"); | ||
|
||
var request = new HttpRequestMessage(HttpMethod.Post, uri) | ||
{ | ||
Content = content | ||
}; | ||
|
||
|
||
var response = await client.SendAsync(request); | ||
response.EnsureSuccessStatusCode(); | ||
} | ||
} | ||
|
||
/// <summary> | ||
/// curl -i -X POST localhost:12110/datastores/boundaries/sparql -H "Accept: application/x.sparql-results+turtle-abbrev" -d "query=SELECT ?S ?P ?O WHERE { ?S ?P ?O }" | ||
/// </summary> | ||
/// <param name="conn"></param> | ||
/// <param name="query"></param> | ||
/// <returns></returns> | ||
public static async Task<string> QuerySparql(ConnectionSettings conn, string query) | ||
{ | ||
using (var client = new HttpClient()) | ||
{ | ||
var uri = new Uri($"http://{conn.Host}:{conn.Port}/datastores/{conn.Datastore}/sparql"); | ||
var content = new StringContent(query, Encoding.UTF8, "application/sparql-query"); | ||
|
||
var request = new HttpRequestMessage(HttpMethod.Post, uri) | ||
{ | ||
Content = content | ||
}; | ||
|
||
var response = await client.SendAsync(request); | ||
if(!response.IsSuccessStatusCode) | ||
throw new Exception(await response.Content.ReadAsStringAsync()); | ||
return await response.Content.ReadAsStringAsync(); | ||
} | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
# Boundaries to Commissioning app | ||
|
||
## Usage | ||
|
||
Start a rdfox server from the folder [../../rdfox/](../../rdfox) with the following command: | ||
|
||
``` | ||
RDFox sandbox ../../rdfox boundaries | ||
``` | ||
|
||
Then run `dotnet run` and follow instructions |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
namespace TestBoundaries; | ||
|
||
public class DatalogCreatorTests | ||
{ | ||
[Fact] | ||
public void TestCreateDatalog() | ||
{ | ||
var datalogCreator = new Boundaries.DatalogCreator(); | ||
var graphIri = datalogCreator.BoundaryGraph; | ||
var datalog = datalogCreator.CreateBoundaryDatalogRule("T4750", new IriTools.IriReference[] | ||
{ | ||
new IriTools.IriReference("https://assetid.equinor.com/plantx#Nozzle-12"), | ||
new IriTools.IriReference("https://assetid.equinor.com/plantx#Nozzle-8"), | ||
new IriTools.IriReference("https://assetid.equinor.com/plantx#PlateHeatExchanger-1"), | ||
new IriTools.IriReference("https://assetid.equinor.com/plantx#ReciprocatingPump-1") | ||
}); | ||
Assert.Equal( $$""" | ||
<{{graphIri}}> [?node] :- | ||
rdfs:label [?internal, "T4750"], | ||
imf:connectedTo [?internal, ?node], | ||
dexpi:PipingOrEquipment [?node]. | ||
<{{graphIri}}> [?node] :- | ||
<{{graphIri}}> [?node1], | ||
imf:connectedTo [?node1, ?node], | ||
NOT FILTER(?node1 = <https://assetid.equinor.com/plantx#Nozzle-12>), | ||
NOT FILTER(?node1 = <https://assetid.equinor.com/plantx#Nozzle-8>), | ||
NOT FILTER(?node1 = <https://assetid.equinor.com/plantx#PlateHeatExchanger-1>), | ||
NOT FILTER(?node1 = <https://assetid.equinor.com/plantx#ReciprocatingPump-1>), | ||
dexpi:PipingOrEquipment [?node]. | ||
""" , datalog); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
global using Xunit; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<TargetFramework>net8.0</TargetFramework> | ||
<ImplicitUsings>enable</ImplicitUsings> | ||
<Nullable>enable</Nullable> | ||
|
||
<IsPackable>false</IsPackable> | ||
<IsTestProject>true</IsTestProject> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.6.0"/> | ||
<PackageReference Include="xunit" Version="2.4.2"/> | ||
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.5"> | ||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> | ||
<PrivateAssets>all</PrivateAssets> | ||
</PackageReference> | ||
<PackageReference Include="coverlet.collector" Version="6.0.0"> | ||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> | ||
<PrivateAssets>all</PrivateAssets> | ||
</PackageReference> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<ProjectReference Include="..\Boundaries\Boundaries.csproj" /> | ||
</ItemGroup> | ||
|
||
</Project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.