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

DYN-1662: As a dynamo dev, I want to serialize what packages are needed in a graph #9723

Merged
merged 61 commits into from
Jun 3, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
61 commits
Select commit Hold shift + click to select a range
8ef55c5
Add Extensions block to json
scottmitchell May 19, 2019
38dca45
Serialize package manager data to new Extensions block
scottmitchell May 19, 2019
f29ec23
Added IPackage interface
scottmitchell May 24, 2019
9344d0c
Added IPackage interface
scottmitchell May 24, 2019
25b1ecf
Added PackageDependencies property to workspace model
scottmitchell May 24, 2019
b349de0
Added comments
scottmitchell May 24, 2019
464c7e8
Unsubscribe from workspace on dispose
scottmitchell May 24, 2019
145cf1a
Simplify CollectingAssembliesUsed
scottmitchell May 24, 2019
e866d43
assemblyPackageDict uses AssemblyName objects instead of strings. Ren…
scottmitchell May 24, 2019
63349ff
NodeLibraries should be internal, not private
scottmitchell May 24, 2019
7d03524
assemblyPackageDict uses AssemblyName.FullName
scottmitchell May 24, 2019
d1001d0
Use set for packageDependencies to avoid duplicates
scottmitchell May 24, 2019
ce71f56
Add some comments to assembly collection
scottmitchell May 24, 2019
50b3186
AssemblyNames summary
scottmitchell May 24, 2019
91b55c5
Adds PackageDependency serialization support for custom nodes from pa…
scottmitchell May 28, 2019
8259502
Rename GetCustomNodesPackagesFromGuids
scottmitchell May 28, 2019
6f892ef
Rename GetCustomNodesPackagesFromGuids
scottmitchell May 28, 2019
2118181
Add new PackageInfo class to replace IPackage for serialization
scottmitchell May 28, 2019
5b08005
Remove IPackage
scottmitchell May 28, 2019
cb968f1
Move assembly name matching logic to PackageManager in order to remov…
scottmitchell May 28, 2019
c1b7e4f
Remove unnecessary
scottmitchell May 28, 2019
8417307
Fix AssemblyNames error
scottmitchell May 28, 2019
23b9749
Null check for PackageInfo converter
scottmitchell May 28, 2019
1478287
Add obsolete attribute to events that should only be used by package …
scottmitchell May 28, 2019
a1a7053
Use InternalsVisibleTo to ensure only PM extension can subscribe to p…
scottmitchell May 28, 2019
1638aeb
Serialize IDs of nodes that are dependent on each package
scottmitchell May 29, 2019
619375a
Update package manager dictionary logic for package load and remove e…
scottmitchell May 29, 2019
78097ca
Fix Guid serialization
scottmitchell May 30, 2019
df478d6
Add comment to InternalsVisibleTo
scottmitchell May 30, 2019
0355e90
Name changes to make referencedAssembly use more clear
scottmitchell May 30, 2019
bcf05c5
Add comments to Assembly collection and make more efficient
scottmitchell May 30, 2019
47d9004
Comment added
scottmitchell May 30, 2019
5112e0c
Remove unnecessary ref
scottmitchell May 30, 2019
c04b448
Removed Unecessary ref
scottmitchell May 30, 2019
c1d4f22
Comment fixes
scottmitchell May 30, 2019
c7463c7
Rename PackageInfo -> PackageDependencyInfo
scottmitchell May 30, 2019
ab7e94a
Use Version type for PackageDependencyInfo Version property
scottmitchell May 30, 2019
c866ca2
Rename Dependents -> Nodes
scottmitchell May 30, 2019
0a743aa
Move GetAssembliesReferencedByNodes
scottmitchell May 30, 2019
3d48363
Added PackageDependency deserialization
scottmitchell May 31, 2019
5813e73
Simplify if statement
scottmitchell May 31, 2019
e196912
Improve PackageDependencies update
scottmitchell May 31, 2019
c3220a9
PackageDependency deserialization null check
scottmitchell Jun 1, 2019
6ed3162
one line code improvements
scottmitchell Jun 1, 2019
4e0ad4e
IsNodeLibrary check
scottmitchell Jun 1, 2019
8278756
Remove unnecessary Any check
scottmitchell Jun 1, 2019
b8ca7d3
Add unsuccessful PackageDependencyInfo serialization log
scottmitchell Jun 1, 2019
1e284dc
Log message when node libraries or custom nodes are loaded by multipl…
scottmitchell Jun 1, 2019
7f45515
Improved RemovedNodes handling
scottmitchell Jun 1, 2019
d6d3529
Simplify descriptor lookup
scottmitchell Jun 1, 2019
e2babfd
Update comments
scottmitchell Jun 1, 2019
46b2323
Store list of packages per assembly
scottmitchell Jun 2, 2019
b03e6b3
Store list of packages per custom node id
scottmitchell Jun 2, 2019
1fa351d
Unsubscribe CurrentWorkspaceChanged
scottmitchell Jun 2, 2019
3bd9de0
lock packageDependencies
scottmitchell Jun 3, 2019
3205f95
Add NodePackageDictionary and CustomNodePackageDictionary null check
scottmitchell Jun 3, 2019
f4412f9
Move assembly collection to WorkspaceModel because LibraryServices no…
scottmitchell Jun 3, 2019
e0ff759
Remove white space
scottmitchell Jun 3, 2019
398bbfe
Add "PackageDependencies" item to test .dyn
scottmitchell Jun 3, 2019
f425b5b
Remove PackageDependencyInfo FullName property
scottmitchell Jun 3, 2019
54693ae
Throw exception for illegal subscribers to PackageDependency events
scottmitchell Jun 3, 2019
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
1 change: 1 addition & 0 deletions src/DynamoCore/DynamoCore.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ limitations under the License.
<Compile Include="Core\DynamoMigrator.cs" />
<Compile Include="Engine\ShortestQualifiedNameReplacer.cs" />
<Compile Include="Exceptions\LibraryLoadFailedException.cs" />
<Compile Include="Graph\Workspaces\PackageDependencyInfo.cs" />
<Compile Include="Graph\Nodes\NodeOutputData.cs" />
<Compile Include="Graph\Nodes\NodeInputData.cs" />
<Compile Include="Graph\Workspaces\LayoutExtensions.cs" />
Expand Down
102 changes: 102 additions & 0 deletions src/DynamoCore/Graph/Workspaces/PackageDependencyInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace Dynamo.Graph.Workspaces
{
/// <summary>
/// Class containing info about a Dynamo package.
/// Used for serialization.
/// </summary>
internal class PackageDependencyInfo
{
/// <summary>
/// Name of the package
/// </summary>
internal string Name { get; set; }

/// <summary>
/// Version of the package
/// </summary>
internal Version Version { get; set; }

/// <summary>
/// Guids of nodes in the workspace that are dependent on this package
/// </summary>
internal HashSet<Guid> Nodes
scottmitchell marked this conversation as resolved.
Show resolved Hide resolved
{
get { return nodes; }
}
private HashSet<Guid> nodes;

/// <summary>
/// Create a package info object from the package name and version
/// </summary>
/// <param name="name"></param>
/// <param name="version"></param>
internal PackageDependencyInfo(string name, Version version)
{
Name = name;
Version = version;
nodes = new HashSet<Guid>();
}

/// <summary>
/// Add the Guid of a dependent node
/// </summary>
/// <param name="guid"></param>
internal void AddDependent(Guid guid)
{
Nodes.Add(guid);
}

/// <summary>
/// Add the Guids of a dependent nodes
/// </summary>
/// <param name="guids"></param>
internal void AddDependents(IEnumerable<Guid> guids)
{
foreach(var guid in guids)
{
Nodes.Add(guid);
}
}

/// <summary>
/// Remove a dependent node
/// </summary>
/// <param name="guid"></param>
internal void RemoveDependent(Guid guid)
{
Nodes.Remove(guid);
}

/// <summary>
/// Checks whether two PackageDependencyInfos are equal
/// They are equal if their Name and Versions are equal
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
public override bool Equals(object obj)
{
if (obj == null)
{
return false;
}
if (!(obj is PackageDependencyInfo))
{
return false;
}

var other = obj as PackageDependencyInfo;
if (other.Name == this.Name && other.Version == this.Version)
{
return true;
}
return false;
}
}
}
107 changes: 107 additions & 0 deletions src/DynamoCore/Graph/Workspaces/SerializationConverters.cs
Original file line number Diff line number Diff line change
Expand Up @@ -525,6 +525,16 @@ public override object ReadJson(JsonReader reader, Type objectType, object exist
// relevant ports.
var connectors = obj["Connectors"].ToObject<IEnumerable<ConnectorModel>>(serializer);

IEnumerable<PackageDependencyInfo> packageDependencies;
if (obj["PackageDependencies"] != null)
{
packageDependencies = obj["PackageDependencies"].ToObject<IEnumerable<PackageDependencyInfo>>(serializer);
}
else
{
packageDependencies = new List<PackageDependencyInfo>();
}

var info = new WorkspaceInfo(guid.ToString(), name, description, Dynamo.Models.RunType.Automatic);

// IsVisibleInDynamoLibrary and Category should be set explicitly for custom node workspace
Expand Down Expand Up @@ -587,6 +597,8 @@ public override object ReadJson(JsonReader reader, Type objectType, object exist
info, verboseLogging, isTestMode);
}

ws.PackageDependencies = packageDependencies.ToList();

return ws;
}

Expand Down Expand Up @@ -689,6 +701,10 @@ public override void WriteJson(JsonWriter writer, object value, JsonSerializer s
}
writer.WriteEndArray();

// PackageDependencies
writer.WritePropertyName("PackageDependencies");
serializer.Serialize(writer, ws.PackageDependencies);

if (engine != null)
{
// Bindings
Expand Down Expand Up @@ -739,6 +755,97 @@ public override object ReadJson(JsonReader reader, Type objectType, object exist
}
}

/// <summary>
/// PackageDependencyInfoConverter is used to serialize and deserialize graph package dependencies
/// </summary>
public class PackageDependencyInfoConverter : JsonConverter
{
private Logging.ILogger logger;

/// <summary>
/// Constructs a PackageDependencyInfoConverter.
/// </summary>
/// <param name="logger"></param>
public PackageDependencyInfoConverter(Logging.ILogger logger)
{
this.logger = logger;
}

public override bool CanConvert(Type objectType)
{
return typeof(PackageDependencyInfo).IsAssignableFrom(objectType);
}

public override bool CanRead
{
get { return true; }
}

public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
PackageDependencyInfo p = value as PackageDependencyInfo;
if (p != null)
{
writer.WriteStartObject();
writer.WritePropertyName("Name");
writer.WriteValue(p.Name);
writer.WritePropertyName("Version");
writer.WriteValue(p.Version.ToString());
writer.WritePropertyName("Nodes");
writer.WriteStartArray();
foreach(var node in p.Nodes)
{
writer.WriteValue(node.ToString("N"));
}
writer.WriteEndArray();
writer.WriteEndObject();
}
scottmitchell marked this conversation as resolved.
Show resolved Hide resolved
else
{
logger.LogWarning("Unnsuccessful attempt to serialize a PackageDependencyInfo object.", Logging.WarningLevel.Moderate);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this need to be localizable?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point, we should escape the localization of it

}
}

public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
var obj = JObject.Load(reader);

// Get package name
var name = obj["Name"].Value<string>();

// Try get package version
var versionString = obj["Version"].Value<string>();
Version version;
if (!Version.TryParse(versionString, out version))
{
logger.LogWarning(
string.Format("The version of Package Dependency {0} could not be deserialized.", name),
Logging.WarningLevel.Moderate);
}

// Create new PackageDependencyInfo
var packageInfo = new PackageDependencyInfo(name, version);

// Try get dependent node IDs
var nodes = obj["Nodes"].Values<string>();
foreach(var nodeID in nodes)
{
Guid guid;
if (!Guid.TryParse(nodeID, out guid))
{
logger.LogWarning(
string.Format("The id ({0}) of a node dependent on {1} could not be parsed as a GUID.", nodeID, name),
Logging.WarningLevel.Moderate);
}
else
{
packageInfo.AddDependent(guid);
}
}
return packageInfo;
}
}

/// <summary>
/// DummyNodeWriteConverter is used for serializing DummyNodes to JSON.
/// Note that the DummyNode objects serialize as their original content and not as a DummyNode.
Expand Down
3 changes: 2 additions & 1 deletion src/DynamoCore/Graph/Workspaces/SerializationExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ internal static string ToJson(this WorkspaceModel workspace, EngineController en
new ConnectorConverter(logger),
new WorkspaceWriteConverter(engine),
new DummyNodeWriteConverter(),
new TypedParameterConverter()
new TypedParameterConverter(),
new PackageDependencyInfoConverter(logger),
},
ReferenceResolverProvider = () => { return new IdReferenceResolver(); }
};
Expand Down
Loading