public virtual async Task <ActionResult <EntitiesResponse <TEntity> > > GetByIds([FromQuery] GetByIdsArguments <TKey> args, CancellationToken cancellation) { return(await ControllerUtilities.InvokeActionImpl(async() => { // Calculate server time at the very beginning for consistency var serverTime = DateTimeOffset.UtcNow; // Load the data var service = GetFactWithIdService(); var(entities, extras) = await service.GetByIds(args.I, args, Constants.Read, cancellation); // Flatten and Trim var relatedEntities = FlattenAndTrim(entities, cancellation); // Prepare the result in a response object var result = new EntitiesResponse <TEntity> { Result = entities, RelatedEntities = relatedEntities, CollectionName = ControllerUtilities.GetCollectionName(typeof(TEntity)), Extras = extras, ServerTime = serverTime, }; return Ok(result); }, _logger)); }
public static IActionResult Run( [HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = null)] HttpRequest req, ILogger log, ExecutionContext context) { IConfigurationRoot settings = null; string connectionString = null; CloudStorageAccount storageAccount = null; CloudTableClient tableClient = null; try { settings = new ConfigurationBuilder() .SetBasePath(context.FunctionAppDirectory) .AddJsonFile("local.settings.json", optional: true, reloadOnChange: true) .AddEnvironmentVariables() .Build(); connectionString = settings["AzureWebJobsStorage"]; storageAccount = CloudStorageAccount.Parse(connectionString); tableClient = storageAccount.CreateCloudTableClient(); } catch (Exception ex) { log.LogError(ex, "Failed to initialize Table Client."); return(new BadRequestResult()); } DateTime season = DateTime.UtcNow; var seasonStr = req.Query["season"].ToString(); if (seasonStr != "") { try { season = DateTime.ParseExact(req.Query["season"], "yyyyMM", CultureInfo.InvariantCulture); } catch (Exception) { return(new BadRequestObjectResult("Invalid season parameter. It should be a string formatted like 'yyyyMM'")); } } var responseObject = new EntitiesResponse <LedgerEntity>(); var table = tableClient.GetTableReference(settings["TableName"]); var query = table.CreateQuery <LedgerEntity>() .Where(x => x.PartitionKey == $"{Util.GetPartitionKey(season)}") .Where(x => x.RowKey.CompareTo($"faction-") > 0) .Where(x => x.RowKey.CompareTo($"faction-{season.AddMonths(1):yyyyMM}01-00") < 0); foreach (var thing in query) { responseObject.Entries[thing.RowKey] = thing; } var resp = new OkObjectResult(responseObject); resp.ContentTypes.Add(new Microsoft.Net.Http.Headers.MediaTypeHeaderValue("application/json")); return(resp); }
/// <summary> /// Saves the entities (Insert or Update) into the database after authorization and validation /// </summary> /// <returns>Optionally returns the same entities in their persisted READ form</returns> protected virtual async Task <EntitiesResponse <TDto> > SaveImplAsync(List <TDtoForSave> entities, SaveArguments args) { await CheckUpdatePermissions(entities, args); // Trim all strings as a preprocessing step entities.ForEach(e => TrimStringProperties(e)); using (var trx = await BeginSaveTransaction()) { try { // Validate await ValidateAsync(entities); if (!ModelState.IsValid) { throw new UnprocessableEntityException(ModelState); } // Save var(memoryList, query) = await PersistAsync(entities, args); // Add the metadata ApplySelectAndAddMetadata(memoryList, args.Expand, null); // Apply the permission masks (setting restricted fields to null) and adjust the metadata accordingly if (memoryList != null && memoryList.Any()) { var permissions = await UserPermissions(PermissionLevel.Read); var defaultMask = GetDefaultMask(); await ApplyReadPermissionsMask(memoryList, query, permissions, defaultMask); } // Flatten related entities and map each to its respective DTO var relatedEntities = FlattenRelatedEntitiesAndTrim(memoryList, args.Expand); // Map the primary result to DTOs as well var resultData = Mapper.Map <List <TDto> >(memoryList); // Prepare the result in a response object var result = new EntitiesResponse <TDto> { Data = resultData, RelatedEntities = relatedEntities, CollectionName = GetCollectionName(typeof(TDto)) }; // Commit and return trx.Commit(); return(result); } catch (Exception ex) { // Roll back the transaction trx.Rollback(); throw ex; } } }
public async Task <ActionResult <EntitiesResponse <LineForSave> > > Generate([FromRoute] int lineDefId, [FromQuery] Dictionary <string, string> args, CancellationToken cancellation) { var serverTime = DateTimeOffset.UtcNow; var(lines, accounts, resources, agents, entryTypes, centers, currencies, units) = await GetService().Generate(lineDefId, args, cancellation); // Related entitiess var relatedEntities = new RelatedEntities { Account = accounts, Resource = resources, Agent = agents, EntryType = entryTypes, Center = centers, Currency = currencies, Unit = units }; // Prepare the result in a response object var response = new EntitiesResponse <LineForSave> { Result = lines, RelatedEntities = relatedEntities, CollectionName = "", // Not important ServerTime = serverTime, }; // Return return(Ok(response)); }
/// <summary> /// Example code to call Rosette API to get entities from a piece of text. /// Requires Nuget Package: /// rosette_api /// </summary> static void Main(string[] args) { //To use the C# API, you must provide an API key string apikey = "Your API key"; string alturl = string.Empty; //You may set the API key via command line argument: //entities yourapikeyhere if (args.Length != 0) { apikey = args[0]; alturl = args.Length > 1 ? args[1] : string.Empty; } try { CAPI EntitiesCAPI = string.IsNullOrEmpty(alturl) ? new CAPI(apikey) : new CAPI(apikey, alturl); string entities_text_data = @"Bill Murray will appear in new Ghostbusters film: Dr. Peter Venkman was spotted filming a cameo in Boston this… http://dlvr.it/BnsFfS"; //The results of the API call will come back in the form of a Dictionary EntitiesResponse response = EntitiesCAPI.Entity(entities_text_data, null, null, null, false, "social-media"); foreach (KeyValuePair <string, string> h in response.Headers) { Console.WriteLine(string.Format("{0}:{1}", h.Key, h.Value)); } Console.WriteLine(response.ToString()); } catch (Exception e) { Console.WriteLine("Exception: " + e.Message); } }
/// <summary> /// Saves the entities (Insert or Update) into the database after authorization and validation. /// </summary> /// <returns>Optionally returns the same entities in their persisted READ form.</returns> protected virtual async Task <EntitiesResponse <TEntity> > SaveImplAsync(List <TEntityForSave> entities, SaveArguments args) { try { // Parse arguments var expand = ExpandExpression.Parse(args?.Expand); var returnEntities = args?.ReturnEntities ?? false; // Trim all strings as a preprocessing step entities.ForEach(e => TrimStringProperties(e)); // This implements field level security entities = await ApplyUpdatePermissionsMask(entities); // Start a transaction scope for save since it causes data modifications using var trx = ControllerUtilities.CreateTransaction(null, GetSaveTransactionOptions()); // Optional preprocessing await SavePreprocessAsync(entities); // Validate // Basic validation that applies to all entities ControllerUtilities.ValidateUniqueIds(entities, ModelState, _localizer); // Actual Validation await SaveValidateAsync(entities); if (!ModelState.IsValid) { throw new UnprocessableEntityException(ModelState); } // Save and retrieve Ids var ids = await SaveExecuteAsync(entities, expand, returnEntities); // Use the Ids to retrieve the items EntitiesResponse <TEntity> result = null; if (returnEntities && ids != null) { result = await GetByIdListAsync(ids.ToArray(), expand); } await PostProcess(result); // Commit and return await OnSaveCompleted(); trx.Complete(); return(result); } catch (Exception ex) { await OnSaveError(ex); throw ex; } }
/// <summary> /// Saves the entities (Insert or Update) into the database after authorization and validation /// </summary> /// <returns>Optionally returns the same entities in their persisted READ form</returns> protected virtual async Task <EntitiesResponse <TDto> > SaveImplAsync(List <TDtoForSave> entities, SaveArguments args) { // TODO Authorize POST await CheckUpdatePermissions(entities, args); // Trim all strings as a preprocessing step entities.ForEach(e => TrimStringProperties(e)); using (var trx = await BeginSaveTransaction()) { try { // Validate await ValidateAsync(entities); if (!ModelState.IsValid) { throw new UnprocessableEntityException(ModelState); } // Save var memoryList = await PersistAsync(entities, args); // Flatten related entities and map each to its respective DTO var relatedEntities = FlattenRelatedEntities(memoryList, args.Expand); // Map the primary result to DTOs as well var resultData = Map(memoryList); // Prepare the result in a response object var result = new EntitiesResponse <TDto> { Data = resultData, RelatedEntities = relatedEntities, CollectionName = GetCollectionName(typeof(TDto)) }; // Commit and return trx.Commit(); return(result); } catch (Exception ex) { // Roll back the transaction trx.Rollback(); throw ex; } } }
/// <summary> /// Example code to call Rosette API to get entities from a piece of text. /// Requires Nuget Package: /// rosette_api /// </summary> static void Main(string[] args) { //To use the C# API, you must provide an API key string apikey = "Your API key"; string alturl = string.Empty; //You may set the API key via command line argument: //entities yourapikeyhere if (args.Length != 0) { apikey = args[0]; alturl = args.Length > 1 ? args[1] : string.Empty; } try { CAPI EntitiesCAPI = string.IsNullOrEmpty(alturl) ? new CAPI(apikey) : new CAPI(apikey, alturl); string entities_text_data = @"The Securities and Exchange Commission today announced the leadership of the agency’s trial unit. Bridget Fitzpatrick has been named Chief Litigation Counsel of the SEC and David Gottesman will continue to serve as the agency’s Deputy Chief Litigation Counsel. Since December 2016, Ms. Fitzpatrick and Mr. Gottesman have served as Co-Acting Chief Litigation Counsel. In that role, they were jointly responsible for supervising the trial unit at the agency’s Washington D.C. headquarters as well as coordinating with litigators in the SEC’s 11 regional offices around the country."; //The results of the API call will come back in the form of a Dictionary EntitiesResponse response = EntitiesCAPI.Entity(entities_text_data, null, null, null, "social-media"); foreach (KeyValuePair <string, string> h in response.Headers) { Console.WriteLine(string.Format("{0}:{1}", h.Key, h.Value)); } Console.WriteLine(response.ToString()); // Entities with full ADM EntitiesCAPI.SetUrlParameter("output", "rosette"); response = EntitiesCAPI.Entity(entities_text_data, null, null, null, "social-media"); // response.Content contains the IDictionary results of the full ADM. // PrintContent() is a provided method to print the Dictionary to the console response.PrintContent(); } catch (Exception e) { Console.WriteLine("Exception: " + e.Message); } }
private async Task <ActionResult <EntitiesResponse <LocalUser> > > ActivateDeactivate([FromBody] List <int> ids, bool returnEntities, string expand, bool isActive) { await CheckActionPermissions(ids.Cast <int?>()); var isActiveParam = new SqlParameter("@IsActive", isActive); DataTable idsTable = DataTable(ids.Select(id => new { Id = id }), addIndex: false); var idsTvp = new SqlParameter("@Ids", idsTable) { TypeName = $"dbo.IdList", SqlDbType = SqlDbType.Structured }; string sql = @" SET NOCOUNT ON; DECLARE @Now DATETIMEOFFSET(7) = SYSDATETIMEOFFSET(); DECLARE @UserId INT = CONVERT(INT, SESSION_CONTEXT(N'UserId')); DECLARE @Emails [dbo].[CodeList]; INSERT INTO @Emails([Code]) SELECT x.[Email] FROM ( MERGE INTO [dbo].[LocalUsers] AS t USING ( SELECT [Id] FROM @Ids ) AS s ON (t.Id = s.Id) WHEN MATCHED AND (t.IsActive <> @IsActive) THEN UPDATE SET t.[IsActive] = @IsActive, t.[ModifiedAt] = @Now, t.[ModifiedById]= @UserId OUTPUT inserted.[Email] ) As x; SELECT [Code] AS [Value] FROM @Emails; "; // Tenant Id var tenantId = new SqlParameter("TenantId", _tenantIdProvider.GetTenantId()); using (var trxApp = await _db.Database.BeginTransactionAsync()) { try { // Update the entities and retrieve the emails of the entities that were updated List <string> emails = await _db.Strings.FromSql(sql, idsTvp, isActiveParam).Select(e => e.Value).ToListAsync(); // Prepare the TVP of emails to update from the manager DataTable emailsTable = DataTable(emails.Select(e => new { Code = e }), addIndex: false); var emailsTvp = new SqlParameter("Emails", emailsTable) { TypeName = $"dbo.CodeList", SqlDbType = SqlDbType.Structured }; using (var trxAdmin = await _adminDb.Database.BeginTransactionAsync()) { try { if (isActive) { // Insert efficiently with a SQL query await _adminDb.Database.ExecuteSqlCommandAsync($@" INSERT INTO dbo.[TenantMemberships] SELECT Id, @TenantId FROM [dbo].[GlobalUsers] WHERE Email IN (SELECT Code from @Emails); ", emailsTvp, tenantId); } else { // Delete efficiently with a SQL query await _adminDb.Database.ExecuteSqlCommandAsync($@" DELETE FROM dbo.[TenantMemberships] WHERE TenantId = @TenantId AND UserId IN ( SELECT Id FROM [dbo].[GlobalUsers] WHERE Email IN (SELECT Code from @Emails) ); ", emailsTvp, tenantId); } // Commit both trxAdmin.Commit(); trxApp.Commit(); } catch (Exception ex) { trxApp.Rollback(); trxAdmin.Rollback(); throw ex; } } } catch (Exception ex) { trxApp.Rollback(); throw ex; } } // Determine whether entities should be returned if (!returnEntities) { // IF no returned items are expected, simply return 200 OK return(Ok()); } else { // Load the entities using their Ids var affectedDbEntitiesQ = _db.LocalUsers.Where(e => ids.Contains(e.Id)); // _db.LocalUsers.FromSql("SELECT * FROM [dbo].[LocalUsers] WHERE Id IN (SELECT Id FROM @Ids)", idsTvp); var affectedDbEntitiesExpandedQ = Expand(affectedDbEntitiesQ, expand); var affectedDbEntities = await affectedDbEntitiesExpandedQ.ToListAsync(); var affectedEntities = _mapper.Map <List <LocalUser> >(affectedDbEntities); // sort the entities the way their Ids came, as a good practice LocalUser[] sortedAffectedEntities = new LocalUser[ids.Count]; Dictionary <int, LocalUser> affectedEntitiesDic = affectedEntities.ToDictionary(e => e.Id.Value); for (int i = 0; i < ids.Count; i++) { var id = ids[i]; LocalUser entity = null; if (affectedEntitiesDic.ContainsKey(id)) { entity = affectedEntitiesDic[id]; } sortedAffectedEntities[i] = entity; } // Prepare a proper response var response = new EntitiesResponse <LocalUser> { Data = sortedAffectedEntities, CollectionName = GetCollectionName(typeof(LocalUser)) }; // Commit and return return(Ok(response)); } }
/// <summary> /// Gives an opportunity for inheriting controllers to post process the result before it is served /// </summary> protected virtual Task PostProcess(EntitiesResponse <TEntity> result) { return(Task.CompletedTask); }
private async Task <ActionResult <EntitiesResponse <Role> > > ActivateDeactivate([FromBody] List <int> ids, bool returnEntities, string expand, bool isActive) { await CheckActionPermissions(ids.Cast <int?>()); using (var trx = await _db.Database.BeginTransactionAsync()) { try { // TODO Authorize Activate // TODO Validate (No used units, no duplicate Ids, no missing Ids?) var isActiveParam = new SqlParameter("@IsActive", isActive); DataTable idsTable = ControllerUtilities.DataTable(ids.Select(id => new { Id = id }), addIndex: false); var idsTvp = new SqlParameter("@Ids", idsTable) { TypeName = $"dbo.IdList", SqlDbType = SqlDbType.Structured }; string sql = @" -- TODO: PermissionsVersion DECLARE @NewId UNIQUEIDENTIFIER = NEWID(); UPDATE [dbo].[LocalUsers] SET PermissionsVersion = @NewId; DECLARE @Now DATETIMEOFFSET(7) = SYSDATETIMEOFFSET(); DECLARE @UserId INT = CONVERT(INT, SESSION_CONTEXT(N'UserId')); MERGE INTO [dbo].[Roles] AS t USING ( SELECT [Id] FROM @Ids ) AS s ON (t.Id = s.Id) WHEN MATCHED AND (t.IsActive <> @IsActive) THEN UPDATE SET t.[IsActive] = @IsActive, t.[ModifiedAt] = @Now, t.[ModifiedById] = @UserId; "; // Update the entities await _db.Database.ExecuteSqlCommandAsync(sql, idsTvp, isActiveParam); trx.Commit(); } catch (Exception ex) { trx.Rollback(); throw ex; } } // Determine whether entities should be returned if (!returnEntities) { // IF no returned items are expected, simply return 200 OK return(Ok()); } else { // Load the entities using their Ids var affectedDbEntitiesQ = _db.VW_Roles.Where(e => ids.Contains(e.Id.Value)); // _db.VW_Roles.FromSql("SELECT * FROM [dbo].[Roles] WHERE Id IN (SELECT Id FROM @Ids)", idsTvp); var affectedDbEntitiesExpandedQ = Expand(affectedDbEntitiesQ, expand); var affectedDbEntities = await affectedDbEntitiesExpandedQ.ToListAsync(); // Add the metadata ApplySelectAndAddMetadata(affectedDbEntities, expand, null); // sort the entities the way their Ids came, as a good practice var affectedEntities = Mapper.Map <List <Role> >(affectedDbEntities); Role[] sortedAffectedEntities = new Role[ids.Count]; Dictionary <int, Role> affectedEntitiesDic = affectedEntities.ToDictionary(e => e.Id.Value); for (int i = 0; i < ids.Count; i++) { var id = ids[i]; Role entity = null; if (affectedEntitiesDic.ContainsKey(id)) { entity = affectedEntitiesDic[id]; } sortedAffectedEntities[i] = entity; } // Apply the permission masks (setting restricted fields to null) and adjust the metadata accordingly await ApplyReadPermissionsMask(affectedDbEntities, affectedDbEntitiesExpandedQ, await UserPermissions(PermissionLevel.Read), GetDefaultMask()); // Flatten related entities and map each to its respective DTO var relatedEntities = FlattenRelatedEntitiesAndTrim(affectedDbEntities, expand); // Prepare a proper response var response = new EntitiesResponse <Role> { Data = sortedAffectedEntities, CollectionName = GetCollectionName(typeof(Role)), RelatedEntities = relatedEntities }; // Commit and return return(Ok(response)); } }
private async Task <ActionResult <EntitiesResponse <Agent> > > ActivateDeactivate([FromBody] List <int> ids, bool returnEntities, string expand, bool isActive) { await CheckActionPermissions(ids.Cast <int?>()); var isActiveParam = new SqlParameter("@IsActive", isActive); DataTable idsTable = DataTable(ids.Select(id => new { Id = id }), addIndex: false); var idsTvp = new SqlParameter("@Ids", idsTable) { TypeName = $"dbo.IdList", SqlDbType = SqlDbType.Structured }; string sql = @" DECLARE @Now DATETIMEOFFSET(7) = SYSDATETIMEOFFSET(); DECLARE @UserId INT = CONVERT(INT, SESSION_CONTEXT(N'UserId')); MERGE INTO [dbo].[Custodies] AS t USING ( SELECT [Id] FROM @Ids ) AS s ON (t.Id = s.Id) WHEN MATCHED AND (t.IsActive <> @IsActive) THEN UPDATE SET t.[IsActive] = @IsActive, t.[ModifiedAt] = @Now, t.[ModifiedById] = @UserId; "; using (var trx = await _db.Database.BeginTransactionAsync()) { try { // Update the entities await _db.Database.ExecuteSqlCommandAsync(sql, idsTvp, isActiveParam); trx.Commit(); } catch (Exception ex) { trx.Rollback(); throw ex; } } // Determine whether entities should be returned if (!returnEntities) { // IF no returned items are expected, simply return 200 OK return(Ok()); } else { // Load the entities using their Ids var affectedDbEntitiesQ = _db.Agents.Where(e => ids.Contains(e.Id)); //.FromSql("SELECT * FROM [dbo].[Custodies] WHERE Id IN (SELECT Id FROM @Ids)", idsTvp); var affectedDbEntitiesExpandedQ = Expand(affectedDbEntitiesQ, expand); var affectedDbEntities = await affectedDbEntitiesExpandedQ.ToListAsync(); var affectedEntities = _mapper.Map <List <Agent> >(affectedDbEntities); // sort the entities the way their Ids came, as a good practice Agent[] sortedAffectedEntities = new Agent[ids.Count]; Dictionary <int, Agent> affectedEntitiesDic = affectedEntities.ToDictionary(e => e.Id.Value); for (int i = 0; i < ids.Count; i++) { var id = ids[i]; Agent entity = null; if (affectedEntitiesDic.ContainsKey(id)) { entity = affectedEntitiesDic[id]; } sortedAffectedEntities[i] = entity; } // Prepare a proper response var response = new EntitiesResponse <Agent> { Data = sortedAffectedEntities, CollectionName = GetCollectionName(typeof(Agent)) }; // Commit and return return(Ok(response)); } }