Invoke C# .NET Core Lambda from AWS CodePipeline Action - .net-core

AWS CodePipeline allows you to invoke a custom Lambda from an action as described here, https://docs.aws.amazon.com/codepipeline/latest/userguide/actions-invoke-lambda-function.htmltion
I am having trouble determining how my C# Lambda function should be defined in order to access the input data from the pipeline.
I tried numerous attempts, was thinking it would be something similar to below. I have also tried to create my own C# classes that the input JSON data would be deserialized to.
public void FunctionHandler( Amazon.CodePipeline.Model.Job
CodePipeline, ILambdaContext context)

I was able to find out a solution. Initially the first step that helped was to change the input parameter for my lambda function to a Stream. I was then able to convert the stream to a string and determine exactly what was being sent to me, e.g
public void FunctionHandler(Stream input, ILambdaContext context)
{
....
}
Then, based on the input data I was able to map it to a C# class that wrapped the AWS SDK Amazon.CodePipeline.Model.Job class. It had to be mapped to the json property "CodePipeline.job". The below code worked, I was able to retrieve all input values.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Amazon.Lambda.Core;
using Amazon.CodePipeline;
using Newtonsoft.Json;
using System.IO;
// Assembly attribute to enable the Lambda function's JSON input to be converted into a .NET class.
[assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.Json.JsonSerializer))]
namespace lambdaEmptyFunction
{
public class Function
{
public class CodePipelineInput
{
[JsonProperty("CodePipeline.job")]
public Amazon.CodePipeline.Model.Job job { get; set; }
}
public void FunctionHandler(CodePipelineInput input, ILambdaContext context)
{
context.Logger.LogLine(string.Format("data {0} {1} {2}", input.job.AccountId, input.job.Data.InputArtifacts[0].Location.S3Location.BucketName, input.job.Id));
}
}
}

Related

Pass data between controllers using method void

I need to pass values from one controllaro to a method from another controller.
or is there another way to pass data to an object so that object takes care of doing all the operations receiving values from other controllers
PRIMARY CONTROLLER
DateTime TimeLog = DateTime.Now;
LogController.Insert(TimeLog);
LOG CONTROLLER
using PROGRAM.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace PROGRAM.Controllers
{
public class LogController : Controller
{
Entities db = new Entities();
internal static void Insert(DateTime TimeLog)
{
LogModel log = new LogModel();
log.User = Session["User"].ToString();
log.TimeLog = TimeLog;
db.Log_Arqueo.Add(log);
db.SaveChanges();
}
}
}
ERROR
Severity Code Description Project File Line Status deleted
Error CS0120 An object reference is required for the non-static 'Controller.Session' field, method, or property PROGRAM\Controllers\LogController.cs 17 Active

Dapper.Contrib methods unavailable for IDbConnection object

I am trying to use Dapper.Contrib to extend the functionality of the IDbConnection interface with, amongst others, the .insert() method.
To do so, I have followed the somewhat brief and scattered documentation here and here. In short, I have used NuGet to add Dapper and Dapper.Contrib to my project, I have added using Dapper; and using Dapper.Contrib; at the top of my Repository class, and I am using System.Data.SqlClient.SqlConnection() to create an IDbConnection.
Still, my connection object does not have the extended methods available. For example, when trying to use the .insert() method, I get the message:
'IDbConnection' C# does not contain a definition for 'Insert' and no
extension method 'Insert' accepting a first argument of type could be
found (are you missing a using directive or an assembly reference?)
This is in an ASP.NET Core 2.0 project using Razor Pages.
For completeness sake, you can find the Repository class below.
Maybe interesting to note, is that the using lines for Dapper and Dapper.Contrib are grayed out...
Also, of course I have a (very minimalistic) Model Class for the TEST Entity, containing one parameter, TEST_COLUMN, annotated with [Key].
using Dapper.Contrib;
using Dapper;
using Microsoft.Extensions.Configuration;
using TestProject.Model;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Threading.Tasks;
namespace TestProject.Repository
{
public class TEST_Repository
{
IConfiguration configuration;
public TEST_Repository(IConfiguration configuration)
{
this.configuration = configuration;
}
public void Insert()
{
using (var con = this.GetConnection())
{
con.Insert(new TEST { TEST_COLUMN = "test" });
}
}
public IDbConnection GetConnection()
{
return new SqlConnection(configuration.GetSection("ConnectionStrings").GetSection("DefaultConnection").Value);
}
}
}
The Insert method you are looking for lives inside of the Dapper.Contrib.Extensions namespace, as can be seen in the source, included for completeness:
namespace Dapper.Contrib.Extensions
{
...
public static long Insert<T>(this IDbConnection connection, ...)
...
}
Hence, in order to use the Extension methods, you should add the following line to your code:
using Dapper.Contrib.Extensions;

how can i reduce memory usage on my application running on azure

I am learning how to use the .NET framework. I am working with ASP .NET core. I have never had or hit my azure webhosting quota until recently I keep hitting quota by making very few request and this started ever since I installed dotnetbrowser library. its the best library for my project because it makes getting data easier. however, I will appreciate if someone can tell me how to get same data without using a browser control like web browser or dotnetbrowser. the data I needed go through multiple server and client communications before the needed value is provided. So my question is how can achieve the same thing without using browser control?
finally, my code might be buggy given that I am not too familiar with threads and task. I might be using too much memory. so below is my code
using DotNetBrowser;
using Newtonsoft.Json.Linq;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Web;
using System.Web.Http;
namespace AjaxRequest.Controllers
{
public class ValuesController : ApiController
{
private static ManualResetEvent waitEvent;
private static List<string> ajaxUrls = new List<string>();
static string str = "";
public static Browser browser;
public ValuesController()
{
waitEvent = new ManualResetEvent(false);
browser = BrowserFactory.Create();
browser.Context.NetworkService.ResourceHandler = new AjaxResourceHandler();
browser.Context.NetworkService.NetworkDelegate = new AjaxNetworkDelegate();
}
// GET api/values
public string Get(int id, string title)
{
string Title = title.Replace(" ", "-");
browser.LoadURL(string.Format("https://ba.com/foo/{0}-{1}/something.html", Title, id));
waitEvent.WaitOne();
browser.Dispose();
string Json = Regex.Replace(str, #"\\","");
return Json.Replace("\\\"", "\"");
}
public class AjaxResourceHandler : ResourceHandler
{
//HomeController hc;
public bool CanLoadResource(ResourceParams parameters)
{
if (parameters.ResourceType == ResourceType.XHR && parameters.URL.Contains("https://something.com/ajax/blahblah"))
{
ajaxUrls.Add(parameters.URL);
}
return true;
}
}
public class AjaxNetworkDelegate : DefaultNetworkDelegate
{
//HomeController hc;
public override void OnDataReceived(DataReceivedParams parameters)
{
if (ajaxUrls.Contains(parameters.Url))
{
PrintResponseData(parameters.Data);
}
}
public void PrintResponseData(byte[] data)
{
str = Encoding.UTF8.GetString(data);
ajaxUrls.Clear();
browser.Stop();
browser.dispose();
waitEvent.Set();
}
public void error(string info)
{
str = info;
waitEvent.Set();
}
}
}
}
is it possible that I am doing it wrong? if that's the case how can it be improved to conserve memory or data?
UPDATE: am using azure free hosting services
DotNetBrowser is a Chromium wrapper - I am not entirely sure why you would need it in a web app, but that said, it is likely it is the culprit. Once you remove it, you can use HttpClient to perform the right requests with no memory overhead.
Profiling-wise, your best bet is to start with Application Insights - it's enabled by default in ASP.NET Core projects. It will allow resource tracking across app components.
It seems like you have more than one running Browser instance.
I can suggest to check that Browser instance is disposed correctly. If not, you can try to dispose it in the Dispose method of the controller.

While activity in WF 4 rehosted designer

I have written a custom activity which contains a simple ExpressionTextBox:
<sapv:ExpressionTextBox HintText="List of Strings"
Grid.Row ="0" Grid.Column="1" MaxWidth="150" MinWidth="150" Margin="5"
OwnerActivity="{Binding Path=ModelItem}"
Expression="{Binding Path=ModelItem.Test, Mode=TwoWay,
Converter={StaticResource ArgumentToExpressionConverter},
ConverterParameter=In }" />
In the library, i've added Test property as follows:
public InArgument<string> Test { get; set; }
So, this is the whole thing:
A while and a variable i of type i defined in its scope. I would expect to get back "Test1", "Test2" ... and so on, but instead i get :
So, that variable i is seen as a string and not interpreted as the integer defined in the variables section.
I've tried this with a simple property of type string also. Then i thought that InArgument might handle the thing.. i don't know what to do more. Any clues about this?
I might need more of your code posting to bb able to help more, and understand fully what you want to achieve. But from the screen shot I can see that your not accessing the Runtime Arguments in the cache meta data method. Subsequently the console writeline method you are calling is interpreting the raw text value rather than correctly evaluating the expression.
Try the following in your code activity
using System;
using System.ComponentModel;
using System.IO;
using System.Runtime;
using System.Activities.Validation;
using System.Collections.Generic;
using System.Windows.Markup;
using System.Collections.ObjectModel;
using System.Activities;
namespace WorkflowConsoleApplication2
{
public sealed class CodeActivity1 : CodeActivity
{
// Define an activity input argument of type string
[DefaultValue(null)]
public InArgument<string> Test
{
get;
set;
}
protected override void CacheMetadata(CodeActivityMetadata metadata)
{
RuntimeArgument textArgument = new RuntimeArgument("Test", typeof(string), ArgumentDirection.In);
metadata.Bind(this.Test, textArgument);
metadata.SetArgumentsCollection(
new Collection<RuntimeArgument>
{
textArgument,
});
}
// If your activity returns a value, derive from CodeActivity<TResult>
// and return the value from the Execute method.
protected override void Execute(CodeActivityContext context)
{
Console.WriteLine(this.Test.Get(context));
}
}
}

Connecting Web API to SQL Server

I am new to ASP.NET and I am creating a Web API using sort of code first. I have model class call gender and defined as follow
public class Gender
{
public int Id { get; set; }
public string Description { get; set; }
}
I decided to create a new folder call DBContext and inside will defined all my DBContext, so for the gender class I have created GenderDb and look like follow:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data.Entity;
namespace BackAPI.Models
{
public class GenderDB : DbContext
{
// not define yet
}
}
However I am having an issue however with DbContext not being defined, apparently I am supposed to use Entity Framework, however I want to create my database not through Visual Studio, but using SQL Server 2014 Express.
I did add my data connection and can see that I created a table in SQL Server, however how do I fix DbContext, if I use EF wouldn't that just create it locally and that not what I want
Entity Framework, along with Migrations, will help you here.
I suggest you check out this tutorial: Code First to a New Database

Resources