• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

HicServices / RDMP / 6245535001

20 Sep 2023 07:44AM UTC coverage: 57.013%. First build
6245535001

push

github

web-flow
8.1.0 Release (#1628)

* Bump Newtonsoft.Json from 13.0.1 to 13.0.2

Bumps [Newtonsoft.Json](https://github.com/JamesNK/Newtonsoft.Json) from 13.0.1 to 13.0.2.
- [Release notes](https://github.com/JamesNK/Newtonsoft.Json/releases)
- [Commits](https://github.com/JamesNK/Newtonsoft.Json/compare/13.0.1...13.0.2)

---
updated-dependencies:
- dependency-name: Newtonsoft.Json
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

* Bump NLog from 5.0.5 to 5.1.0

Bumps [NLog](https://github.com/NLog/NLog) from 5.0.5 to 5.1.0.
- [Release notes](https://github.com/NLog/NLog/releases)
- [Changelog](https://github.com/NLog/NLog/blob/dev/CHANGELOG.md)
- [Commits](https://github.com/NLog/NLog/compare/v5.0.5...v5.1.0)

---
updated-dependencies:
- dependency-name: NLog
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

* Bump NLog from 5.0.5 to 5.1.0

* Fix -r flag - should have been --results-directory all along

* Bump Newtonsoft.Json from 13.0.1 to 13.0.2

* Bump YamlDotNet from 12.0.2 to 12.1.0

Bumps [YamlDotNet](https://github.com/aaubry/YamlDotNet) from 12.0.2 to 12.1.0.
- [Release notes](https://github.com/aaubry/YamlDotNet/releases)
- [Commits](https://github.com/aaubry/YamlDotNet/compare/v12.0.2...v12.1.0)

---
updated-dependencies:
- dependency-name: YamlDotNet
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

* Bump Moq from 4.18.2 to 4.18.3

Bumps [Moq](https://github.com/moq/moq4) from 4.18.2 to 4.18.3.
- [Release notes](https://github.com/moq/moq4/releases)
- [Changelog](https://github.com/moq/moq4/blob/main/CHANGELOG.md)
- [Commits](https://github.com/moq/moq4/compare/v4.18.2...v4.18.3)

---
updated-dependencies:
- dependency-name: Moq
... (continued)

10732 of 20257 branches covered (0.0%)

Branch coverage included in aggregate %.

48141 of 48141 new or added lines in 1086 files covered. (100.0%)

30685 of 52388 relevant lines covered (58.57%)

7387.88 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

38.32
/Rdmp.Core/Curation/Data/LoadModuleAssembly.cs
1
// Copyright (c) The University of Dundee 2018-2019
2
// This file is part of the Research Data Management Platform (RDMP).
3
// RDMP is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
4
// RDMP is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
5
// You should have received a copy of the GNU General Public License along with RDMP. If not, see <https://www.gnu.org/licenses/>.
6

7
using System;
8
using System.Collections.Generic;
9
using System.Data.Common;
10
using System.IO;
11
using System.Linq;
12
using System.Threading;
13
using ICSharpCode.SharpZipLib.Zip;
14
using Rdmp.Core.CommandLine.Runners;
15
using Rdmp.Core.Curation.Data.ImportExport;
16
using Rdmp.Core.Curation.Data.Serialization;
17
using Rdmp.Core.MapsDirectlyToDatabaseTable;
18
using Rdmp.Core.MapsDirectlyToDatabaseTable.Attributes;
19
using Rdmp.Core.MapsDirectlyToDatabaseTable.Injection;
20
using Rdmp.Core.Repositories;
21
using YamlDotNet.Serialization;
22

23
namespace Rdmp.Core.Curation.Data;
24

25
/// <summary>
26
/// This entity stores the large binary blob for the <see cref="Plugin"/> class.  The <see cref="Bin"/> can be written to disk
27
/// as a nuget file which can be loaded at runtime to add plugin functionality for rdmp.
28
/// </summary>
29
public class LoadModuleAssembly : DatabaseEntity, IInjectKnown<Plugin>
30
{
31
    #region Database Properties
32

33
    private byte[] _bin;
34
    private string _committer;
35
    private DateTime _uploadDate;
36
    private int _plugin_ID;
37
    private Lazy<Plugin> _knownPlugin;
38

39

40
    /// <summary>
41
    /// The assembly (dll) file as a Byte[], use File.WriteAllBytes to write it to disk
42
    /// </summary>
43
    [YamlIgnore]
44
    public byte[] Bin
45
    {
46
        get => _bin;
16✔
47
        set => SetField(ref _bin, value);
40✔
48
    }
49

50
    /// <summary>
51
    /// The user who uploaded the dll
52
    /// </summary>
53
    public string Committer
54
    {
55
        get => _committer;
24✔
56
        set => SetField(ref _committer, value);
38✔
57
    }
58

59
    /// <summary>
60
    /// The date the dll was uploaded
61
    /// </summary>
62
    public DateTime UploadDate
63
    {
64
        get => _uploadDate;
24✔
65
        set => SetField(ref _uploadDate, value);
18✔
66
    }
67

68
    /// <summary>
69
    /// The plugin this file forms a part of (each <see cref="Plugin"/> will usually have multiple dlls as part of its dependencies)
70
    /// </summary>
71
    [Relationship(typeof(Plugin), RelationshipType.SharedObject)]
72
    public int Plugin_ID
73
    {
74
        get => _plugin_ID;
62✔
75
        set => SetField(ref _plugin_ID, value);
38✔
76
    }
77

78
    #endregion
79

80
    #region Relationships
81

82
    /// <inheritdoc cref="Plugin_ID"/>
83
    [NoMappingToDatabase]
84
    public Plugin Plugin => _knownPlugin.Value;
38✔
85

86
    #endregion
87

88
    public LoadModuleAssembly()
4✔
89
    {
90
        ClearAllInjections();
4✔
91
    }
4✔
92

93
    /// <summary>
94
    /// Uploads the given dll file to the catalogue database ready for use as a plugin within RDMP (also uploads any pdb file in the same dir)
95
    /// </summary>
96
    /// <param name="repository"></param>
97
    /// <param name="f"></param>
98
    /// <param name="plugin"></param>
99
    public LoadModuleAssembly(ICatalogueRepository repository, FileInfo f, Plugin plugin)
22✔
100
    {
101
        var dictionaryParameters = GetDictionaryParameters(f, plugin);
22✔
102

103
        //so we can reference it in fetch requests to check for duplication (normally Repository is set during hydration by the repo)
104
        Repository = repository;
22✔
105

106
        Repository.InsertAndHydrate(this, dictionaryParameters);
22✔
107
        ClearAllInjections();
22✔
108
    }
22✔
109

110
    internal LoadModuleAssembly(ICatalogueRepository repository, DbDataReader r)
111
        : base(repository, r)
4✔
112
    {
113
        Bin = r["Bin"] as byte[];
4✔
114
        Committer = r["Committer"] as string;
4✔
115
        UploadDate = Convert.ToDateTime(r["UploadDate"]);
4✔
116
        Plugin_ID = Convert.ToInt32(r["Plugin_ID"]);
4✔
117
        ClearAllInjections();
4✔
118
    }
4✔
119

120
    internal LoadModuleAssembly(ShareManager shareManager, ShareDefinition shareDefinition)
8✔
121
    {
122
        shareManager.UpsertAndHydrate(this, shareDefinition);
8✔
123
        ClearAllInjections();
8✔
124
    }
8✔
125

126
    /// <summary>
127
    /// Unpack the plugin DLL files, excluding any Windows specific dlls when not running on Windows
128
    /// </summary>
129
    internal static IEnumerable<ValueTuple<string, MemoryStream>> GetContents(Stream pluginStream)
130
    {
131
        var isWin = AppDomain.CurrentDomain.GetAssemblies()
×
132
            .Any(static a => a.FullName?.StartsWith("Rdmp.UI", StringComparison.Ordinal) == true);
×
133

134
        if (!pluginStream.CanSeek)
×
135
            throw new ArgumentException("Seek needed", nameof(pluginStream));
×
136

137
        using var zip = new ZipFile(pluginStream);
×
138
        foreach (var e in zip.Cast<ZipEntry>()
×
139
                     .Where(static e => e.IsFile && e.Name.EndsWith(".dll", StringComparison.OrdinalIgnoreCase))
×
140
                     .Where(e => isWin || !e.Name.Contains("/windows/")))
×
141
        {
142
            using var s = zip.GetInputStream(e);
×
143
            using var ms2 = new MemoryStream();
×
144
            s.CopyTo(ms2);
×
145
            ms2.Position = 0;
×
146
            yield return (e.Name, ms2);
×
147
        }
×
148
    }
×
149

150
    /// <summary>
151
    /// Unpack the plugin DLL files, excluding any Windows specific dlls when not running on Windows
152
    /// </summary>
153
    internal IEnumerable<ValueTuple<string, MemoryStream>> GetContents()
154
    {
155
        using var ms = new MemoryStream(Bin);
×
156
        return GetContents(ms);
×
157
    }
×
158

159
    /// <summary>
160
    /// Downloads the plugin nupkg to the given directory
161
    /// </summary>
162
    /// <param name="downloadDirectory"></param>
163
    public string DownloadAssembly(DirectoryInfo downloadDirectory)
164
    {
165
        var targetDirectory = downloadDirectory.FullName ??
×
166
                              throw new Exception("Could not get currently executing assembly directory");
×
167
        if (!downloadDirectory.Exists)
×
168
            downloadDirectory.Create();
×
169

170
        var targetFile = Path.Combine(targetDirectory, Plugin.Name);
×
171

172
        //file already exists
173
        if (File.Exists(targetFile))
×
174
            if (AreEqual(File.ReadAllBytes(targetFile), Bin))
×
175
                return targetFile;
×
176

177
        var timeout = 5000;
×
178

179
    TryAgain:
180
        try
181
        {
182
            //if it has changed length or does not exist, write it out to the disk
183
            File.WriteAllBytes(targetFile, Bin);
×
184
        }
×
185
        catch (Exception)
×
186
        {
187
            timeout -= 100;
×
188
            Thread.Sleep(100);
×
189

190
            if (timeout <= 0)
×
191
                throw;
×
192

193
            goto TryAgain;
×
194
        }
195

196
        return targetFile;
×
197
    }
198

199
    private static Dictionary<string, object> GetDictionaryParameters(FileInfo f, Plugin plugin)
200
    {
201
        if (f.Extension != PackPluginRunner.PluginPackageSuffix)
22!
202
            throw new Exception($"Expected LoadModuleAssembly file to be a {PackPluginRunner.PluginPackageSuffix}");
×
203

204
        var allBytes = File.ReadAllBytes(f.FullName);
22✔
205

206
        var dictionaryParameters = new Dictionary<string, object>
22✔
207
        {
22✔
208
            { "Bin", allBytes },
22✔
209
            { "Committer", Environment.UserName },
22✔
210
            { "Plugin_ID", plugin.ID }
22✔
211
        };
22✔
212

213
        return dictionaryParameters;
22✔
214
    }
215

216
    private static bool AreEqual(byte[] readAllBytes, byte[] dll)
217
    {
218
        return readAllBytes.Length == dll.Length && !dll.Where((t, i) => !readAllBytes[i].Equals(t)).Any();
×
219
    }
220

221
    public void InjectKnown(Plugin instance)
222
    {
223
        _knownPlugin = new Lazy<Plugin>(instance);
×
224
    }
×
225

226
    /// <inheritdoc/>
227
    public override string ToString() => $"LoadModuleAssembly_{ID}";
×
228

229
    public void ClearAllInjections()
230
    {
231
        _knownPlugin = new Lazy<Plugin>(() => Repository.GetObjectByID<Plugin>(Plugin_ID));
48✔
232
    }
38✔
233
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc