Esempio n. 1
0
        public async Task <IHardwareRepresentation> GenerateHardware(
            IEnumerable <string> assembliesPaths,
            IHardwareGenerationConfiguration configuration)
        {
            Argument.ThrowIfNull(assembliesPaths, nameof(assembliesPaths));
            if (!assembliesPaths.Any())
            {
                throw new ArgumentException("No assemblies were specified.");
            }

            if (assembliesPaths.Count() != assembliesPaths.Distinct().Count())
            {
                throw new ArgumentException(
                          "The same assembly was included multiple times. Only supply each assembly to generate hardware from once.");
            }

            try
            {
                HardwareRepresentation hardwareRepresentation = null;

                await _host
                .Run <ITransformer, IHardwareImplementationComposer, IDeviceManifestSelector>(
                    async (transformer, hardwareImplementationComposer, deviceManifestSelector) =>
                {
                    var hardwareDescription = await transformer.Transform(assembliesPaths, configuration);

                    var hardwareImplementation = await hardwareImplementationComposer.Compose(hardwareDescription);

                    var deviceManifest = deviceManifestSelector
                                         .GetSupporteDevices()
                                         .FirstOrDefault(manifest => manifest.Name == configuration.DeviceName);

                    if (deviceManifest == null)
                    {
                        throw new HastlayerException(
                            "There is no supported device with the name " + configuration.DeviceName + ".");
                    }

                    hardwareRepresentation = new HardwareRepresentation
                    {
                        SoftAssemblyPaths      = assembliesPaths,
                        HardwareDescription    = hardwareDescription,
                        HardwareImplementation = hardwareImplementation,
                        DeviceManifest         = deviceManifest
                    };
                }, ShellName, false);

                return(hardwareRepresentation);
            }
            catch (Exception ex) when(!ex.IsFatal())
            {
                var message =
                    "An error happened during generating the Hastlayer hardware representation for the following assemblies: " +
                    string.Join(", ", assembliesPaths);
                await _host.Run <ILoggerService>(logger => Task.Run(() => logger.Error(ex, message)));

                throw new HastlayerException(message, ex);
            }
        }
Esempio n. 2
0
 public static Task <IHardwareDescription> Transform(
     this ITransformer transformer,
     IEnumerable <Assembly> assemblies,
     IHardwareGenerationConfiguration configuration)
 {
     assemblies.ThrowArgumentExceptionIfAnyInMemory();
     return(transformer.Transform(assemblies.Select(assembly => assembly.Location), configuration));
 }
 /// <summary>
 /// Adds a public type the suitable methods of which will be accessible from the host computer as hardware
 /// implementation.
 /// </summary>
 /// <typeparam name="T">The type of the object that will be later fed to the proxy generator.</typeparam>
 public static void AddHardwareEntryPointType <T>(this IHardwareGenerationConfiguration configuration)
 {
     // If we'd just add the type's name to HardwareEntryPointMemberNamePrefixes then types with just a different
     // suffix in their names would still be included.
     foreach (var method in typeof(T).GetMethods())
     {
         configuration.HardwareEntryPointMemberFullNames.Add(method.GetFullName());
     }
 }
        /// <summary>
        /// Adds a public type the suitable methods of which will be accessible from the host computer as hardware
        /// implementation.
        /// </summary>
        /// <typeparam name="T">The type of the object that will be later fed to the proxy generator.</typeparam>
        public static void AddHardwareEntryPointType <T>(this IHardwareGenerationConfiguration configuration)
        {
            // Object base methods are not needed.
            var excludedMethodNames = new[]
            {
                "Boolean Equals(System.Object)",
                "Int32 GetHashCode()", "System.Type GetType()",
                "System.String ToString()"
            };

            // If we'd just add the type's name to HardwareEntryPointMemberNamePrefixes then types with just a different
            // suffix in their names would still be included.
            foreach (var method in typeof(T).GetMethods().Where(method => !excludedMethodNames.Contains(method.ToString())))
            {
                configuration.HardwareEntryPointMemberFullNames.Add(method.GetFullName());
            }
        }
 public static RemoteClientConfiguration RemoteClientConfiguration(this IHardwareGenerationConfiguration hardwareConfiguration)
 {
     return(hardwareConfiguration.GetOrAddCustomConfiguration <RemoteClientConfiguration>("Hast.Remote.Client.Configuration"));
 }
 /// <summary>
 /// Adds a public method that will be accessible from the host computer as hardware implementation.
 /// </summary>
 /// <typeparam name="T">The type of the object that will be later fed to the proxy generator.</typeparam>
 /// <param name="expression">An expression with a call to the method.</param>
 public static void AddHardwareEntryPointMethod <T>(
     this IHardwareGenerationConfiguration configuration,
     Expression <Action <T> > expression) =>
 configuration.HardwareEntryPointMemberFullNames.Add(expression.GetMethodFullName());
 /// <summary>
 /// Gets the custom configuration if it exists or creates and adds it if it doesn't.
 /// </summary>
 /// <typeparam name="T">Type of the configuration object.</typeparam>
 /// <param name="key">Key where the custom configuration object is stored in the
 /// <see cref="IHardwareGenerationConfiguration"/> instance.</param>
 /// <returns>The existing or newly created configuration object.</returns>
 public static T GetOrAddCustomConfiguration <T>(this IHardwareGenerationConfiguration hardwareConfiguration, string key)
     where T : new() =>
 hardwareConfiguration.CustomConfiguration.GetOrAddCustomConfiguration <T>(key);
Esempio n. 8
0
        public Task <IHardwareDescription> Transform(IEnumerable <string> assemblyPaths, IHardwareGenerationConfiguration configuration)
        {
            Logger.Warning("No Transformer is available. This most possibly means an issue.");

            var mockHardwareEntryPointMappings = new Dictionary <string, int>();

            for (int i = 0; i < configuration.HardwareEntryPointMemberFullNames.Count; i++)
            {
                mockHardwareEntryPointMappings[configuration.HardwareEntryPointMemberFullNames[i]] = i;
            }

            return(Task.FromResult <IHardwareDescription>(new HardwareDescription(mockHardwareEntryPointMappings)));
        }
 /// <summary>
 /// Adds a public type the suitable methods of which will be accessible from the host computer as hardware
 /// implementation.
 /// </summary>
 /// <typeparam name="T">The type of the object that will be later fed to the proxy generator.</typeparam>
 public static void AddHardwareEntryPointType <T>(this IHardwareGenerationConfiguration configuration) =>
 configuration.HardwareEntryPointMemberNamePrefixes.Add(typeof(T).FullName);
        public async Task <IHardwareDescription> Transform(IEnumerable <string> assemblyPaths, IHardwareGenerationConfiguration configuration)
        {
            var apiClient = ApiClientFactory.CreateApiClient(configuration.RemoteClientConfiguration());

            var assemblyContainers = assemblyPaths
                                     .Select(path => new AssemblyContainer
            {
                Name        = Path.GetFileNameWithoutExtension(path),
                FileContent = File.ReadAllBytes(path)
            });

            var apiConfiguration = new Bridge.Models.HardwareGenerationConfiguration
            {
                CustomConfiguration = configuration.CustomConfiguration,
                DeviceName          = configuration.DeviceName,
                HardwareEntryPointMemberFullNames    = configuration.HardwareEntryPointMemberFullNames,
                HardwareEntryPointMemberNamePrefixes = configuration.HardwareEntryPointMemberNamePrefixes
            };

            var transformationTicket = await apiClient
                                       .RequestTransformation(new TransformationRequest
            {
                Assemblies    = assemblyContainers,
                Configuration = apiConfiguration
            });


            TransformationResult transformationResult  = null;
            const int            maxResultAttemptCount = 100;
            var waitAttemptIndex = 0;
            var waitMilliseconds = 333;

            while (transformationResult == null && waitAttemptIndex < maxResultAttemptCount)
            {
                await Task.Delay(waitMilliseconds);

                var transformationResultResponse = await apiClient.GetTransformationResult(transformationTicket.Token);

                if (transformationResultResponse.ResponseMessage.IsSuccessStatusCode)
                {
                    transformationResult = transformationResultResponse.GetContent();
                }
                else if (transformationResultResponse.ResponseMessage.StatusCode != System.Net.HttpStatusCode.NotFound)
                {
                    transformationResultResponse.ResponseMessage.EnsureSuccessStatusCode();
                }

                if (++waitAttemptIndex % 10 == 0)
                {
                    waitMilliseconds *= 2;
                }
            }

            var exceptionMessageBase =
                "Transforming the following assemblies failed: " + string.Join(", ", assemblyPaths) + ". ";

            if (transformationResult == null)
            {
                throw new Exception(
                          exceptionMessageBase + "The remote Hastlayer service didn't produce a result in a timely manner. " +
                          "This could indicate a problem with the service or that the assemblies contained exceptionally complex code.");
            }

            if (transformationResult.Errors?.Any() == true)
            {
                throw new Exception(
                          exceptionMessageBase + "The following error(s) happened: " + Environment.NewLine +
                          string.Join(Environment.NewLine, transformationResult.Errors));
            }

            var hardwareDescription = transformationResult.HardwareDescription;

            return(new RemoteHardwareDescription
            {
                HardwareEntryPointNamesToMemberIdMappings = hardwareDescription.HardwareEntryPointNamesToMemberIdMappings,
                Language = hardwareDescription.Language,
                Source = hardwareDescription.Source,
                Warnings = hardwareDescription.Warnings.Select(warning =>
                                                               new Common.Models.TransformationWarning {
                    Code = warning.Code, Message = warning.Message
                })
            });
        }
Esempio n. 11
0
        public async Task <IHardwareDescription> Transform(IEnumerable <string> assemblyPaths, IHardwareGenerationConfiguration configuration)
        {
            var apiClient = ApiClientFactory.CreateApiClient(configuration.RemoteClientConfiguration());

            var assemblyContainers = assemblyPaths
                                     .Select(path => new AssemblyContainer
            {
                Name        = Path.GetFileNameWithoutExtension(path),
                FileContent = File.ReadAllBytes(path)
            });

            var apiConfiguration = new Bridge.Models.HardwareGenerationConfiguration
            {
                CustomConfiguration = configuration.CustomConfiguration,
                DeviceName          = configuration.DeviceName,
                HardwareEntryPointMemberFullNames    = configuration.HardwareEntryPointMemberFullNames,
                HardwareEntryPointMemberNamePrefixes = configuration.HardwareEntryPointMemberNamePrefixes
            };

            try
            {
                var transformationTicket = await apiClient
                                           .RequestTransformation(new TransformationRequest
                {
                    Assemblies    = assemblyContainers,
                    Configuration = apiConfiguration
                });


                TransformationResult transformationResult  = null;
                const int            maxResultAttemptCount = 100;
                var waitAttemptIndex = 0;
                var waitMilliseconds = 333;
                while (transformationResult == null && waitAttemptIndex < maxResultAttemptCount)
                {
                    await Task.Delay(waitMilliseconds);

                    var transformationResultResponse = await apiClient.GetTransformationResult(transformationTicket.Token);

                    if (transformationResultResponse.ResponseMessage.IsSuccessStatusCode)
                    {
                        transformationResult = transformationResultResponse.GetContent();
                    }
                    else if (transformationResultResponse.ResponseMessage.StatusCode != System.Net.HttpStatusCode.NotFound)
                    {
                        transformationResultResponse.ResponseMessage.EnsureSuccessStatusCode();
                    }

                    if (++waitAttemptIndex % 10 == 0)
                    {
                        waitMilliseconds *= 2;
                    }
                }

                var exceptionMessageBase =
                    "Transforming the following assemblies failed: " + string.Join(", ", assemblyPaths) + ". ";
                if (transformationResult == null)
                {
                    throw new Exception(
                              exceptionMessageBase + "The remote Hastlayer service didn't produce a result in a timely manner. " +
                              "This could indicate a problem with the service or that the assemblies contained exceptionally complex code.");
                }

                if (transformationResult.Errors?.Any() == true)
                {
                    throw new Exception(
                              exceptionMessageBase + "The following error(s) happened: " + Environment.NewLine +
                              string.Join(Environment.NewLine, transformationResult.Errors));
                }

                var hardwareDescription = transformationResult.HardwareDescription;
                return(new RemoteHardwareDescription
                {
                    HardwareEntryPointNamesToMemberIdMappings = hardwareDescription.HardwareEntryPointNamesToMemberIdMappings,
                    Language = hardwareDescription.Language,
                    Source = hardwareDescription.Source,
                    Warnings = hardwareDescription.Warnings.Select(warning =>
                                                                   new Common.Models.TransformationWarning {
                        Code = warning.Code, Message = warning.Message
                    })
                });
            }
            catch (ApiException ex)
            {
                var message = "Remote transformation failed: ";

                if (ex.StatusCode == System.Net.HttpStatusCode.Unauthorized)
                {
                    message += "Authorizing with Hastlayer Remote Services failed. Maybe you mistyped your credentials?";
                }
                else
                {
                    message += $"The response code was {ex.StatusCode}. Most possibly there is some issue with Hastlayer Remote Services. If this error persists please get in touch with us under https://hastlayer.com/contact.";
                }

                throw new RemoteTransformationException(message, ex);
            }
            catch (JsonReaderException ex)
            {
                // This will happen also when authorization fails and Azure AD authentication takes over from the API,
                // and redirects the client to the Microsoft login screen (there doesn't seem to be a way to prevent
                // this).
                throw new RemoteTransformationException("Remote transformation failed because Hastlayer Remote Services returned an unexpected response. This might be because authorization failed (check if you mistyped your credentials) or because there is some issue with the service. If this error persists please get in touch with us under https://hastlayer.com/contact.", ex);
            }
        }
Esempio n. 12
0
 /// <summary>
 /// Generates and implements a hardware representation of the given assemblies.
 /// </summary>
 /// <param name="assemblies">The assemblies that should be implemented as hardware.</param>
 /// <param name="configuration">Configuration for how the hardware generation should happen.</param>
 /// <returns>The representation of the assemblies implemented as hardware.</returns>
 /// <exception cref="HastlayerException">
 /// Thrown if any lower-level exception or other error happens during hardware generation.
 /// </exception>
 public static Task <IHardwareRepresentation> GenerateHardware(
     this IHastlayer hastlayer,
     IEnumerable <Assembly> assemblies,
     IHardwareGenerationConfiguration configuration) =>
 hastlayer.GenerateHardware(assemblies.Select(assembly => assembly.Location), configuration);
 public static VhdlTransformerConfiguration VhdlTransformerConfiguration(this IHardwareGenerationConfiguration hardwareConfiguration)
 {
     return(hardwareConfiguration.GetOrAddCustomConfiguration <VhdlTransformerConfiguration>("Hast.Transformer.Vhdl.Configuration"));
 }