示例#1
0
        public async Task <IActionResult> Init([FromForm] ShareInitDto parameters)
        {
            try
            {
                _logger.LogDebug("Share controller Init('{Tag}')", parameters.Tag);

                var initRes = await _shareManager.Initialize(parameters);

                return(Ok(initRes));
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Exception in Share controller Init('{Tag}')", parameters.Tag);

                return(ExceptionResult(ex));
            }
        }
示例#2
0
        public async Task <ShareInitResultDto> Initialize(ShareInitDto parameters)
        {
            if (parameters == null)
            {
                throw new BadRequestException("Invalid parameters");
            }

            var currentUser = await _authManager.GetCurrentUser();

            if (currentUser == null)
            {
                throw new UnauthorizedException("Invalid user");
            }

            // Check if user has enough space to upload any file
            await _utils.CheckCurrentUserStorage();

            Dataset dataset;
            TagDto  tag = parameters.Tag.ToTag();

            // No organization requested
            if (tag.OrganizationSlug == null)
            {
                if (tag.DatasetSlug != null)
                {
                    throw new BadRequestException("Cannot specify a dataset without an organization");
                }

                string orgSlug;

                _logger.LogInformation("No organization and dataset specified");

                var nameSlug = currentUser.UserName.ToSlug();

                // We start from the principle that a default user organization begins with the username in slug form
                // If we notice that this strategy is weak we have to add a new field to the db entry
                var userOrganization = _context.Organizations.FirstOrDefault(item =>
                                                                             item.OwnerId == currentUser.Id && item.Name.StartsWith(nameSlug));

                // Some idiot removed its own organization, maybe we should prevent this, btw nevermind: let's take care of it
                if (userOrganization == null)
                {
                    // This section of code can be extracted and put in a separated utils method
                    orgSlug = _utils.GetFreeOrganizationSlug(currentUser.UserName);

                    _logger.LogInformation("No default user organization found, adding a new one: '{OrgSlug}'",
                                           orgSlug);

                    var org = await _organizationsManager.AddNew(new OrganizationDto
                    {
                        Name         = currentUser.UserName,
                        IsPublic     = false,
                        CreationDate = DateTime.Now,
                        Owner        = currentUser.Id,
                        Slug         = orgSlug
                    });

                    userOrganization = _context.Organizations.First(item => item.Slug == orgSlug);
                }

                orgSlug = userOrganization.Slug;

                _logger.LogInformation("Using default user organization '{OrgSlug}'", orgSlug);

                var dsSlug = GetUniqueDatasetSlug();

                _logger.LogInformation("Generated unique dataset slug '{DsSlug}'", dsSlug);

                await _datasetsManager.AddNew(orgSlug, new DatasetNewDto
                {
                    Slug     = dsSlug,
                    Name     = parameters.DatasetName,
                    IsPublic = true
                });

                dataset = await _utils.GetDataset(orgSlug, dsSlug);

                _logger.LogInformation("Created new dataset '{DsSlug}', creating batch", dsSlug);
            }
            else
            {
                // Check if the requested organization exists
                var organization = await _utils.GetOrganization(tag.OrganizationSlug, true);

                if (organization == null)
                {
                    throw new BadRequestException($"Cannot find organization '{tag.OrganizationSlug}'");
                }

                _logger.LogInformation("Organization found");

                // If no dataset is specified, we create a new one with a random slug
                if (tag.DatasetSlug == null)
                {
                    var dsSlug = GetUniqueDatasetSlug();

                    _logger.LogInformation("Generated unique dataset slug '{DsSlug}'", dsSlug);

                    await _datasetsManager.AddNew(tag.OrganizationSlug, new DatasetNewDto
                    {
                        Slug     = dsSlug,
                        Name     = parameters.DatasetName,
                        IsPublic = true
                    });

                    dataset = _context.Datasets.First(ds => ds.Slug == dsSlug);

                    _logger.LogInformation("Dataset created");
                }
                else
                {
                    dataset = await _utils.GetDataset(tag.OrganizationSlug, tag.DatasetSlug, true);

                    // Create dataset if not exists
                    if (dataset == null)
                    {
                        _logger.LogInformation("Dataset '{DatasetSlug}' not found, creating it", tag.DatasetSlug);

                        await _datasetsManager.AddNew(tag.OrganizationSlug, new DatasetNewDto
                        {
                            Slug     = tag.DatasetSlug,
                            Name     = parameters.DatasetName,
                            IsPublic = true
                        });

                        _logger.LogInformation("Dataset created");

                        dataset = _context.Datasets.First(ds => ds.Slug == tag.DatasetSlug);
                    }
                    else
                    {
                        _logger.LogInformation("Checking for running batches");
                        await _context.Entry(dataset).Collection(item => item.Batches).LoadAsync();

                        var runningBatches = dataset.Batches.Where(item => item.End == null).ToArray();

                        if (runningBatches.Any())
                        {
                            _logger.LogInformation(
                                "Found '{RunningBatchesCount}' running batch(es), stopping and rolling back before starting a new one",
                                runningBatches.Length);

                            foreach (var b in runningBatches)
                            {
                                await RollbackBatch(b);
                            }
                        }
                    }
                }
            }

            var batch = new Batch
            {
                Dataset  = dataset,
                Start    = DateTime.Now,
                Token    = _batchTokenGenerator.GenerateToken(),
                UserName = await _authManager.SafeGetCurrentUserName(),
                Status   = BatchStatus.Running
            };

            _logger.LogInformation("Adding new batch for user '{BatchUserName}' with token '{BatchToken}'",
                                   batch.UserName, batch.Token);

            await _context.Batches.AddAsync(batch);

            await _context.SaveChangesAsync();

            _logger.LogInformation("Batch created, it is now possible to upload files");

            return(new ShareInitResultDto
            {
                Token = batch.Token

                        // NOTE: Maybe useful in the future
                        // Tag = tag
            });
        }