Beispiel #1
0
        private static Maybe <EntityConvertorArgs> SetPropertyValue(
            [NotNull] PropertyInfo argPropertyInfo,
            [NotNull] string arg,
            [NotNull] EntityConvertorArgs typedArgs)
        {
            var argType = argPropertyInfo.GetGetMethod().ReturnType;

            try
            {
                if (!argType.IsArray)
                {
                    ArgsPropertySettersMap.GetValue(argType)
                    .Do(argsSetter => argsSetter(argPropertyInfo, arg, typedArgs),
                        () => argPropertyInfo.SetValue(typedArgs, Convert.ChangeType(arg, argType)));
                }
                else
                {
                    var mayBeArray = ParseArray(arg, argType);
                    if (!mayBeArray.HasValue)
                    {
                        return(Maybe <EntityConvertorArgs> .Nothing);
                    }

                    argPropertyInfo.SetValue(typedArgs, mayBeArray.Value);
                }
            }
            catch (Exception ex)
            {
                Console.Error.WriteLine($"{arg} is not a valid {argType.Name} argument. {ex.Message}");
                return(Maybe <EntityConvertorArgs> .Nothing);
            }

            return(typedArgs);
        }
Beispiel #2
0
        public static Maybe <EntityConvertorArgs> ParseCommandLine([NotNull][ItemNotNull] string[] args)
        {
            // (Key + value) * args.count
            if (args.Length != SupportedArgs.Value.Length * 2)
            {
                return(Maybe <EntityConvertorArgs> .Nothing);
            }

            var typedArgs     = new EntityConvertorArgs();
            var supportedArgs = SupportedArgs.Value;

            PropertyInfo expectedArgPropertyInfo = null;
            var          passedArgPropertyInfos  = new HashSet <PropertyInfo>();

            foreach (var arg in args)
            {
                var argMeta = supportedArgs.FirstOrDefault(supportedArg => supportedArg.Attribute.Keys.Contains(arg));

                if (expectedArgPropertyInfo != null)
                {
                    if (argMeta != null)
                    {
                        // Key in place of value.
                        return(Maybe <EntityConvertorArgs> .Nothing);
                    }

                    var mayBeTypedArgs = SetPropertyValue(expectedArgPropertyInfo, arg.Trim(), typedArgs);
                    if (!mayBeTypedArgs.HasValue)
                    {
                        // Can't set key by value, incorrect value.
                        return(Maybe <EntityConvertorArgs> .Nothing);
                    }

                    typedArgs = mayBeTypedArgs.Value;
                    expectedArgPropertyInfo = null;
                }
                else
                {
                    // Unknown key.
                    if (argMeta == null)
                    {
                        return(Maybe <EntityConvertorArgs> .Nothing);
                    }

                    expectedArgPropertyInfo = argMeta.PropertyInfo;
                    passedArgPropertyInfos.Add(expectedArgPropertyInfo);
                }
            }

            // Not all args are passed.
            if (passedArgPropertyInfos.Count != SupportedArgs.Value.Length)
            {
                return(Maybe <EntityConvertorArgs> .Nothing);
            }

            return(typedArgs);
        }
Beispiel #3
0
        private static Uri CreateConversionEndpointUri([NotNull] EntityConvertorArgs args)
        {
            const string convertGeneralToTypeEndpointPath = "PageServices/ActionsService.asmx/ConvertGeneralToType";
            const string authenticationTokenParamTemplate = "?access_token={0}";

            string authenticatedConvertGeneralToTypeEndpointPath =
                $"{convertGeneralToTypeEndpointPath}{string.Format(authenticationTokenParamTemplate, args.AccessToken)}";

            return(new Uri(args.InstanceUri, authenticatedConvertGeneralToTypeEndpointPath));
        }
Beispiel #4
0
        private static int PerformConversionGeneralToType([NotNull] EntityConvertorArgs args)
        {
            // Targetprocess enforces TLS 1.2 On-Demand, so add this to supported security protocols.
            // https://www.targetprocess.com/blog/2016/03/targetprocess-will-start-enforcing-tls-1-2-encryption/
            ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11;

            // When you want to use C# 7.0 value tuple, for .NET 4.6.2 or lower, .NET Core 1.x, and .NET Standard 1.x
            // you need to install the NuGet package System.ValueTuple.
            var conversions        = new List <(int GeneralId, Task <HttpResponseMessage> ConversionTask)>(args.GeneralIdsToConvert.Count());
            var serializerSettings = new JsonSerializerSettings
            {
                ContractResolver = new CamelCasePropertyNamesContractResolver()
            };

            using (var httpClient = new HttpClient())
            {
                Uri conversionEndpointUri = CreateConversionEndpointUri(args);

                // Try run conversions in parallel to reduce overall time.
                foreach (var generalIdToConvert in args.GeneralIdsToConvert)
                {
                    var convertDto = new ConvertGeneralToTypeDto
                    {
                        EntityTypeId = args.EntityKindId,
                        GeneralId    = generalIdToConvert
                    };

                    var conversionRequest = CreateConversionRequest(convertDto, serializerSettings);
                    var conversionTask    = httpClient.PostAsync(conversionEndpointUri, conversionRequest);

                    conversions.Add((generalIdToConvert, conversionTask));
                }

                var waitTimeout = args.WaitTimeout;

                try
                {
                    bool areAllConversionsDone = Task.WaitAll(conversions.Select(conversion => conversion.ConversionTask).ToArray <Task>(), waitTimeout);
                    if (!areAllConversionsDone)
                    {
                        throw new TimeoutException($"Conversion is not completed in {waitTimeout}, ending coversion.");
                    }
                }
                catch (AggregateException ex)
                {
                    Console.Error.WriteLine(ex.Flatten());
                    return(ErrorCodes.ConvertError);
                }
                catch (TimeoutException ex)
                {
                    Console.Error.WriteLine(ex);
                    return(ErrorCodes.ConvertError);
                }
            }

            var conversionErrors = conversions
                                   .Where(conversion => !conversion.ConversionTask.Result.IsSuccessStatusCode)
                                   .Select(conversion =>
            {
                var conversionTaskResponse = conversion.ConversionTask.Result;
                var body = conversionTaskResponse.Content.ToString();
                return($"Error during conversion of general with id {conversion.GeneralId}.{Environment.NewLine}" +
                       $"Status code: {conversionTaskResponse.StatusCode}, Body: {body}" +
                       $"{Environment.NewLine}");
            })
                                   .ToList();

            if (conversionErrors.Count == 0)
            {
                Console.WriteLine($"All generals with ids {string.Join(", ", args.GeneralIdsToConvert)} " +
                                  "are converted successfully.");
                return(ErrorCodes.Ok);
            }

            conversionErrors.ForEach(conversionError => Console.Error.WriteLine(conversionError));
            return(ErrorCodes.ConvertError);
        }