Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(file imports): adds an experimental IFC parser #3525

Merged
merged 51 commits into from
Nov 29, 2024
Merged
Show file tree
Hide file tree
Changes from 24 commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
02b9b11
first pass of CLI ifc converter
adamhathcock Oct 22, 2024
d8527ad
Merge remote-tracking branch 'origin/main' into adam/ifc-dotnet
adamhathcock Oct 22, 2024
bcec852
Merge remote-tracking branch 'origin/main' into adam/ifc-dotnet
adamhathcock Nov 20, 2024
c3fd0e0
some updates
adamhathcock Nov 20, 2024
7603319
Merge remote-tracking branch 'origin/main' into adam/ifc-dotnet
adamhathcock Nov 20, 2024
68d6c49
closer
adamhathcock Nov 20, 2024
0fbf747
yarn works
adamhathcock Nov 20, 2024
3315e9a
Merge remote-tracking branch 'origin/main' into adam/ifc-dotnet
adamhathcock Nov 20, 2024
d12fdf5
can execute ifc?
adamhathcock Nov 20, 2024
d5341b5
change exe
adamhathcock Nov 20, 2024
f8f1c77
Merge remote-tracking branch 'origin/adam/ifc-dotnet' into adam/ifc-d…
adamhathcock Nov 20, 2024
43b1e58
remove extra venv needs
adamhathcock Nov 21, 2024
00f4d4d
Merge remote-tracking branch 'origin/adam/ifc-dotnet' into adam/ifc-d…
adamhathcock Nov 21, 2024
899fe0a
invocation works
adamhathcock Nov 21, 2024
eee6641
fixed dockerfile and url
adamhathcock Nov 21, 2024
1129951
refactor(fileimport): temp results path should not be hardcoded in pa…
iainsproat Nov 21, 2024
e60d7b9
update importer to output stuff
adamhathcock Nov 21, 2024
badc7a0
Merge remote-tracking branch 'origin/iain/file-import-do-not-hard-cod…
adamhathcock Nov 21, 2024
719c34b
fix up argments
adamhathcock Nov 21, 2024
283e3d6
Merge remote-tracking branch 'origin/main' into adam/ifc-dotnet
adamhathcock Nov 21, 2024
aacd2f3
remove dead code
adamhathcock Nov 21, 2024
f39ea08
adjust dockerfile to have tini and workdir better
adamhathcock Nov 21, 2024
baaef6e
fix node to a specific version
adamhathcock Nov 21, 2024
fe2851e
Add shell statement and pin yarn version
iainsproat Nov 21, 2024
c3c4aa7
add ifc converter c# to ignore
adamhathcock Nov 21, 2024
415c474
Merge remote-tracking branch 'origin/main' into adam/ifc-dotnet
adamhathcock Nov 22, 2024
ae36427
merge fix
adamhathcock Nov 22, 2024
cd951f3
move ifc c#
adamhathcock Nov 22, 2024
ef1106e
fix the api usage
adamhathcock Nov 22, 2024
aba5aaf
update the importer to new SDK
adamhathcock Nov 26, 2024
71aa98e
Merge remote-tracking branch 'origin/main' into adam/ifc-dotnet
adamhathcock Nov 26, 2024
0ab88c5
Merge branch 'main' into adam/ifc-dotnet
iainsproat Nov 26, 2024
f1a2f84
Adds a feature flag `FF_FILEIMPORT_IFC_DOTNET_ENABLED` for enabling .…
iainsproat Nov 26, 2024
ec14b39
move directories
adamhathcock Nov 26, 2024
889629e
put back ifc js
adamhathcock Nov 26, 2024
76d0479
use FF and reversions
adamhathcock Nov 26, 2024
3e488ee
needs token too
adamhathcock Nov 26, 2024
7488f16
fix docker?
adamhathcock Nov 26, 2024
08896a8
one last copy fix
adamhathcock Nov 26, 2024
c6028c7
adjust prettier ignore
adamhathcock Nov 26, 2024
bdfb574
change to enable
adamhathcock Nov 26, 2024
d783427
fix helm chart nesting
iainsproat Nov 26, 2024
06d0a99
Merge branch 'main' into adam/ifc-dotnet
iainsproat Nov 26, 2024
eb75ffa
Amend healthcheck node binary path
iainsproat Nov 26, 2024
7bc0a3e
Add FF_FILEIMPORT_IFC_DOTNET_ENABLED to feature flag parser
iainsproat Nov 26, 2024
8a9d9b0
Merge branch 'main' into adam/ifc-dotnet
iainsproat Nov 26, 2024
cf567f8
Allow app to write to /.config directory
iainsproat Nov 26, 2024
a3349c5
fix: volume name has to be lower case
iainsproat Nov 26, 2024
35baf57
Merge remote-tracking branch 'origin/main' into adam/ifc-dotnet
adamhathcock Nov 28, 2024
e2ddcf4
update ifc importing
Nov 28, 2024
2c29cf5
Merge remote-tracking branch 'origin/adam/ifc-dotnet' into adam/ifc-d…
adamhathcock Nov 28, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,9 @@ postgres-data/
redis-data/

.tshy-build
obj/
bin/


# Server
multiregion.json
Expand Down
105 changes: 41 additions & 64 deletions packages/fileimport-service/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,97 +1,74 @@
ARG NODE_ENV=production

FROM node:18-bookworm-slim@sha256:408f8cbbb7b33a5bb94bdb8862795a94d2b64c2d516856824fd86c4a5594a443 as build-stage
FROM mcr.microsoft.com/dotnet/sdk:8.0-noble AS dotnet-build-stage
WORKDIR /app
COPY packages/ifc-converter .
RUN dotnet publish ifc-converter.csproj -c Release -o output/

ARG NODE_ENV
ENV NODE_ENV=${NODE_ENV}

FROM mcr.microsoft.com/dotnet/runtime:8.0-noble AS runtime
SHELL ["/bin/bash", "-o", "pipefail", "-c"]

WORKDIR /speckle-server

# install tini
ARG TINI_VERSION=v0.19.0
ENV TINI_VERSION=${TINI_VERSION}
ADD https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini ./tini
RUN chmod +x ./tini

# install wait
ARG WAIT_VERSION=2.8.0
ENV WAIT_VERSION=${WAIT_VERSION}
ADD https://github.com/ufoscout/docker-compose-wait/releases/download/${WAIT_VERSION}/wait ./wait
RUN chmod +x ./wait
ADD https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini /usr/bin/tini
RUN chmod +x /usr/bin/tini

RUN apt-get update -y \
&& DEBIAN_FRONTEND=noninteractive apt-get install -y \
--no-install-recommends \
curl=8.5.0-2ubuntu10.5 \
&& curl -fsSL https://deb.nodesource.com/setup_18.x | bash - \
&& DEBIAN_FRONTEND=noninteractive apt-get install -y \
--no-install-recommends \
nodejs=18.20.5-1nodesource1 \
&& npm install -g [email protected] \
iainsproat marked this conversation as resolved.
Show resolved Hide resolved
&& DEBIAN_FRONTEND=noninteractive apt-get remove curl -y \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*

# download yarn dependencies for building shared libraries
COPY .yarnrc.yml .
COPY .yarn ./.yarn
COPY package.json yarn.lock ./

COPY packages/frontend-2/type-augmentations/stubs ./packages/frontend-2/type-augmentations/stubs/
COPY packages/shared/package.json ./packages/shared/
COPY packages/fileimport-service/package.json ./packages/fileimport-service/
COPY packages/frontend-2/type-augmentations/stubs packages/frontend-2/type-augmentations/stubs/
COPY packages/shared/package.json packages/shared/
COPY packages/fileimport-service/package.json packages/fileimport-service/

RUN yarn workspaces focus --all

# build shared libraries
COPY packages/shared ./packages/shared/
COPY packages/fileimport-service ./packages/fileimport-service/
COPY packages/shared packages/shared/
COPY packages/fileimport-service packages/fileimport-service/
RUN yarn workspaces foreach -W run build

# Install python virtual env and python dependencies
RUN apt-get update && \
DEBIAN_FRONTEND=noninteractive apt-get install -y \
--no-install-recommends \
python3-venv=3.11.2-1+b1 \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/* \
&& python3 -m venv /venv
RUN apt-get update -y \
&& DEBIAN_FRONTEND=noninteractive apt-get install -y \
--no-install-recommends \
python3.12=3.12.3-1ubuntu0.3 \
python3-pip=24.0+dfsg-1ubuntu1.1 \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*

COPY packages/fileimport-service/requirements.txt /speckle-server/
RUN /venv/bin/pip install --disable-pip-version-check --no-cache-dir --requirement /speckle-server/requirements.txt

FROM node:18-bookworm-slim@sha256:408f8cbbb7b33a5bb94bdb8862795a94d2b64c2d516856824fd86c4a5594a443 as dependency-stage
# installing just the production dependencies
# separate stage to avoid including development dependencies
ARG NODE_ENV
ENV NODE_ENV=${NODE_ENV}

WORKDIR /speckle-server
COPY .yarnrc.yml .
COPY .yarn ./.yarn
COPY package.json yarn.lock ./

COPY packages/frontend-2/type-augmentations/stubs ./packages/frontend-2/type-augmentations/stubs/
COPY packages/shared/package.json ./packages/shared/
COPY packages/fileimport-service/package.json ./packages/fileimport-service/

WORKDIR /speckle-server/packages/fileimport-service
RUN yarn workspaces focus --production
iainsproat marked this conversation as resolved.
Show resolved Hide resolved

FROM gcr.io/distroless/python3-debian12:nonroot@sha256:14c62b8925d3bb30319de2f346bde203fe18103a68898284a62db9d4aa54c794 as python-image

FROM gcr.io/distroless/nodejs18-debian12:nonroot@sha256:afdea027580f7afcaf1f316b2b3806690c297cb3ce6ddc5cf6a15804dc1c790f as distributable-stage
RUN pip install --break-system-packages --disable-pip-version-check --no-cache-dir --requirement /speckle-server/requirements.txt

ARG NODE_ENV
ENV NODE_ENV=${NODE_ENV}
ARG NODE_BINARY_PATH=/nodejs/bin/node
ARG NODE_BINARY_PATH=/usr/bin/node
ENV NODE_BINARY_PATH=${NODE_BINARY_PATH}
ARG PYTHON_BINARY_PATH=/venv/bin/python3
ARG PYTHON_BINARY_PATH=/usr/bin/python3
ENV PYTHON_BINARY_PATH=${PYTHON_BINARY_PATH}
ARG DOTNET_BINARY_PATH=/usr/bin/dotnet
ENV DOTNET_BINARY_PATH=${DOTNET_BINARY_PATH}

WORKDIR /speckle-server

COPY --from=python-image / /
COPY --from=build-stage /speckle-server/tini /usr/bin/tini
COPY --from=build-stage /speckle-server/wait /usr/bin/wait
COPY --from=build-stage /speckle-server/packages/shared ./packages/shared
COPY --from=build-stage /speckle-server/packages/fileimport-service ./packages/fileimport-service
COPY --from=build-stage /venv /venv
COPY --from=dependency-stage /speckle-server/node_modules ./node_modules
COPY --from=dotnet-build-stage /app/output packages/ifc-converter

WORKDIR /speckle-server/packages/fileimport-service

# Prefixing PATH with our virtual environment should seek required binaries
# from virtual environment first.
# Unsetting python home
ENV PATH=/venv/bin:${PATH} \
PYTHONHOME=

ENTRYPOINT [ "tini", "--", "/nodejs/bin/node", "--no-experimental-fetch", "src/daemon.js"]
ENTRYPOINT [ "tini", "--", "node", "--no-experimental-fetch", "src/daemon.js"]
8 changes: 2 additions & 6 deletions packages/fileimport-service/src/daemon.js
Original file line number Diff line number Diff line change
Expand Up @@ -129,17 +129,13 @@ async function doTask(mainDb, regionName, taskDb, task) {
if (info.fileType.toLowerCase() === 'ifc') {
await runProcessWithTimeout(
iainsproat marked this conversation as resolved.
Show resolved Hide resolved
taskLogger,
process.env['NODE_BINARY_PATH'] || 'node',
process.env['DOTNET_BINARY_PATH'] || 'dotnet',
[
'--no-experimental-fetch',
'./ifc/import_file.js',
'/speckle-server/packages/ifc-converter/ifc-converter.dll',
TMP_FILE_PATH,
TMP_RESULTS_PATH,
info.userId,
info.streamId,
info.branchName,
`File upload: ${info.fileName}`,
info.id,
existingBranch?.id,
regionName
],
Expand Down
12 changes: 12 additions & 0 deletions packages/ifc-converter/.config/dotnet-tools.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"version": 1,
"isRoot": true,
"tools": {
"csharpier": {
"version": "0.30.1",
"commands": [
"dotnet-csharpier"
]
}
}
}
33 changes: 33 additions & 0 deletions packages/ifc-converter/ConsoleProgress.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
using Speckle.Sdk.Transports;

namespace Speckle.Converter;

public class ConsoleProgress : IProgress<ProgressArgs>
{
private readonly TimeSpan DEBOUNCE = TimeSpan.FromSeconds(1);
private DateTime _lastTime = DateTime.UtcNow;

private long _totalBytes;

public void Report(ProgressArgs value)
{
if (value.ProgressEvent == ProgressEvent.DownloadBytes)
{
Interlocked.Add(ref _totalBytes, value.Count);
}
var now = DateTime.UtcNow;
if (now - _lastTime >= DEBOUNCE)
{
if (value.ProgressEvent == ProgressEvent.DownloadBytes)
{
Console.WriteLine(value.ProgressEvent + " t " + _totalBytes);
}
else
{
Console.WriteLine(value.ProgressEvent + " c " + value.Count + " t " + value.Total);
}

_lastTime = now;
}
}
}
47 changes: 47 additions & 0 deletions packages/ifc-converter/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
using System.CommandLine;
using System.Text.Json;
using Speckle.Sdk.Common;
using Speckle.WebIfc.Importer;

var filePathArgument = new Argument<string>(name: "filePath");
var outputPathArgument = new Argument<string>("outputPath");
var streamIdArgument = new Argument<string>("streamId");
var commitMessageArgument = new Argument<string>("commitMessage");
var modelIdArgument = new Argument<string>("modelId");
var regionNameArgument = new Argument<string>("regionName");

var rootCommand = new RootCommand
{
filePathArgument,
outputPathArgument,
streamIdArgument,
commitMessageArgument,
modelIdArgument,
regionNameArgument,
};
rootCommand.SetHandler(
async (filePath, outputPath, streamId, commitMessage, modelId, _) =>
{
try
{
var token = Environment.GetEnvironmentVariable("USER_TOKEN").NotNull("USER_TOKEN is missing");
var url = Environment.GetEnvironmentVariable("SPECKLE_SERVER_URL") ?? "http://127.0.0.1:3000";
var commitId = await Import.Ifc(url, filePath, streamId, modelId, commitMessage, token);
File.WriteAllText(outputPath, JsonSerializer.Serialize(new { success = true, commitId }));
}
catch (Exception e)
{
File.WriteAllText(
outputPath,
JsonSerializer.Serialize(new { success = false, error = e.ToString() })
);
}
},
filePathArgument,
outputPathArgument,
streamIdArgument,
commitMessageArgument,
modelIdArgument,
regionNameArgument
);
await rootCommand.InvokeAsync(args);
17 changes: 17 additions & 0 deletions packages/ifc-converter/ifc-converter.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<RootNamespace>Speckle.Converter</RootNamespace>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.1" />
<PackageReference Include="Speckle.WebIfc.Importer" Version="0.0.3" />
<PackageReference Include="System.CommandLine" Version="2.0.0-beta4.22272.1" />
</ItemGroup>

</Project>
16 changes: 16 additions & 0 deletions packages/ifc-converter/ifc-converter.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@

Microsoft Visual Studio Solution File, Format Version 12.00
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ifc-converter", "ifc-converter.csproj", "{4D63FBD3-8ABF-4F51-A08F-740B17BDCA28}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{4D63FBD3-8ABF-4F51-A08F-740B17BDCA28}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4D63FBD3-8ABF-4F51-A08F-740B17BDCA28}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4D63FBD3-8ABF-4F51-A08F-740B17BDCA28}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4D63FBD3-8ABF-4F51-A08F-740B17BDCA28}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal