public async Task <IActionResult> RunPreprocessHistory([FromRoute] long id, [FromBody] RunPreprocessHistoryInputModel model,
                                                               [FromServices] IDataRepository dataRepository,
                                                               [FromServices] IClusterManagementLogic clusterManagementLogic)
        {
            var validateResult = await ValidateCreatePreprocessHistoryInputModelAsync(id, model.DataId, dataRepository);

            if (validateResult.IsSuccess == false)
            {
                return(validateResult.Error);
            }
            PreprocessHistory preprocessHistory = validateResult.Value;

            preprocessHistory.Cpu       = model.Cpu;
            preprocessHistory.Memory    = model.Memory;
            preprocessHistory.Gpu       = model.Gpu;
            preprocessHistory.Partition = model.Partition;
            preprocessHistory.OptionDic = model.Options ?? new Dictionary <string, string>(); //オプションはnullの可能性があるので、その時は初期化
            if (preprocessHistory.OptionDic.ContainsKey(""))                                  //空文字は除外する
            {
                preprocessHistory.OptionDic.Remove("");
            }

            preprocessHistoryRepository.Add(preprocessHistory);
            unitOfWork.Commit();

            //入力データの詳細情報がないので、取得
            preprocessHistory.InputData = await dataRepository.GetDataIncludeAllAsync(preprocessHistory.InputDataId);

            var result = await clusterManagementLogic.RunPreprocessingContainerAsync(preprocessHistory);

            if (result.IsSuccess == false)
            {
                //コンテナの起動に失敗した状態。エラーを出力して、保存した学習履歴も削除する。
                preprocessHistoryRepository.Delete(preprocessHistory);

                return(JsonError(HttpStatusCode.ServiceUnavailable, "Failed to run preprocessing. The message bellow may be help to resolve: " + result.Error));
            }

            //結果に従い、学習結果を更新する。
            //実行には時間がかかりうるので、DBから最新の情報を取ってくる
            preprocessHistory = await preprocessHistoryRepository.GetByIdAsync(preprocessHistory.Id);

            preprocessHistory.Status = result.Value.Status.Key;
            unitOfWork.Commit();

            if (result.Value.Status.Succeed())
            {
                return(JsonCreated(new HistoriesOutputModel(preprocessHistory)));
            }
            else
            {
                return(JsonError(HttpStatusCode.ServiceUnavailable, $"Failed to run preprocessing. Status={result.Value.Status.Name}. Please contact your server administrator."));
            }
        }
        public async Task <IActionResult> RunPreprocessHistory([FromRoute] long id, [FromBody] RunPreprocessHistoryInputModel model)
        {
            // 環境変数名のチェック
            if (model.Options != null && model.Options.Count > 0)
            {
                foreach (var env in model.Options)
                {
                    if (!string.IsNullOrEmpty(env.Key))
                    {
                        // フォーマットチェック
                        if (!Regex.IsMatch(env.Key, "^[-._a-zA-Z][-._a-zA-Z0-9]*$"))
                        {
                            return(JsonNotFound($"Invalid envName. Please match the format of '^[-._a-zA-Z][-._a-zA-Z0-9]*$'."));
                        }
                    }
                }
            }

            // 各リソースの超過チェック
            Tenant tenant       = tenantRepository.Get(CurrentUserInfo.SelectedTenant.Id);
            string errorMessage = clusterManagementLogic.CheckQuota(tenant, model.Cpu.Value, model.Memory.Value, model.Gpu.Value);

            if (errorMessage != null)
            {
                return(JsonBadRequest(errorMessage));
            }

            var validateResult = await ValidateCreatePreprocessHistoryInputModelAsync(id, model.DataId);

            if (validateResult.IsSuccess == false)
            {
                return(validateResult.Error);
            }
            PreprocessHistory preprocessHistory = validateResult.Value;

            preprocessHistory.Cpu       = model.Cpu;
            preprocessHistory.Memory    = model.Memory;
            preprocessHistory.Gpu       = model.Gpu;
            preprocessHistory.Partition = model.Partition;
            preprocessHistory.OptionDic = model.Options ?? new Dictionary <string, string>(); // オプションはnullの可能性があるので、その時は初期化
            if (preprocessHistory.OptionDic.ContainsKey(""))                                  // 空文字は除外する
            {
                preprocessHistory.OptionDic.Remove("");
            }

            preprocessHistoryRepository.Add(preprocessHistory);
            unitOfWork.Commit();

            // 入力データの詳細情報がないので、取得
            preprocessHistory.InputData = await dataRepository.GetDataIncludeAllAsync(preprocessHistory.InputDataId);

            var result = await clusterManagementLogic.RunPreprocessingContainerAsync(preprocessHistory);

            if (result.IsSuccess == false)
            {
                // コンテナの起動に失敗した状態。エラーを出力して、保存した学習履歴も削除する。
                preprocessHistoryRepository.Delete(preprocessHistory);

                return(JsonError(HttpStatusCode.ServiceUnavailable, "Failed to run preprocessing. The message bellow may be help to resolve: " + result.Error));
            }

            // 結果に従い、学習結果を更新する。
            // 実行には時間がかかりうるので、DBから最新の情報を取ってくる
            preprocessHistory = await preprocessHistoryRepository.GetByIdAsync(preprocessHistory.Id);

            preprocessHistory.Status = result.Value.Status.Key;
            unitOfWork.Commit();

            if (result.Value.Status.Succeed())
            {
                return(JsonCreated(new HistoriesOutputModel(preprocessHistory)));
            }
            else
            {
                return(JsonError(HttpStatusCode.ServiceUnavailable, $"Failed to run preprocessing. Status={result.Value.Status.Name}. Please contact your server administrator."));
            }
        }