How do I get a handle to the VPC instance created by AWS-CDK ApplicationLoadBalancedFargateService - aws-cdk

According to the documentation, the Service;
uses the VPC defined in the cluster or creates a new VPC.
But, there doesn't appear to be a property available to get at the newly created VPC. Since CDK mangles the name, getting it by lookup is also difficult.

The VPC can be accessed via the cluster property of the services;
#property
def vpc(self) -> Vpc:
return self._fargate.cluster.vpc

Related

How to add public subnets to a security group?

I wrote this code to add public subnets of VPC to a rdsSecurityGroup.
for publicSubnet in self.vpc.public_subnets:
self.rdsSecurityGroup.add_ingress_rule(peer=publicSubnet,
connection=ec2.Port.tcp(3306))
But I got this error:
jsii.errors.JSIIError: peer.toIngressRuleConfig is not a function
How can I resolve this?
According to https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-security-groups.html#security-group-rules, the source/destination of the security group rule can be one of
IP address (range)
Security group
AWS service prefix
Based on above, you would need to lookup CIDR blocks of your public subnets and add those as your sources for ingress rules. However, it looks like lookup of CIDR blocks of vpc/subnets is not so easy at the moment - https://github.com/aws/aws-cdk/issues/2232. You would need to either remember your CIDR blocks in the code if you are creating the subnets, or have CIDR blocks as a constans in your code in case you are using existing VPC and subnets.
Alternative, perhaps more suitable and convenient is to use security groups as a source for your rules. Add all resources in your public subnets to security groups and manage security group rules based on those.

How to remove children from cloudformation constructs

I am using aws-cdk for creating the stack of a new app. We have existing resources deployed with Cloudformation, such as route tables with our VPC peerings and other.
When i create a Subnet with aws-cdk, it automatically creates a route table.
However, i don't need this route table. I use another, already created route table. How can i remove the default routetable ?
I can i could use CfnSubnet instead of Subnet, but I was wondering if there is another solution.
Subnet Subnet = new Subnet(this, "Subnet", SubnetProps.builder()
.withVpcId(vpc.getVpcId())
.withAvailabilityZone("eu-west-1b")
.withCidrBlock(String.format("10.%d.43.128/25", environmentId))
.build());
CfnSubnetRouteTableAssociation routeTableAssociation = (CfnSubnetRouteTableAssociation) subnet.getNode().tryFindChild("RouteTableAssociation");
routeTableAssociation.setRouteTableId(Fn.importValue(String.format("%s-nat-nat000", environment)));
CfnRouteTable cfnRouteTable = (CfnRouteTable) subnet.getNode().tryFindChild("RouteTable");
I think the solution you proposed is the best way to achieve that.

Is it possible to have default properties of nodes in neo4j?

In my application there are already many nodes with different labels. We are passing property value at the time of creation. I wanted to have 2 properties for all the nodes by default (like creationDate and createdBy). Is there any possibility from configuration side that we can pass these property by default to all the nodes at the time of creation.
If by configuration, you only mean neo4j.conf, then no. You need some code to actually compute the value of the properties anyway: how do you represent the date, how do you determine who created the node?
To do that, you could deploy an extension in Neo4j to intercept the creation of nodes through transaction events by implementing a TransactionEventHandler: you'll get the TransactionData which directly exposes the nodes that were created, on which you can then set the audit properties you want.
The handler is registered through GraphDatabaseService, which can be obtained at startup by implementing PluginLifecycle and exposing the implementation via the Service Locator mechanism (put the class name in META-INF/services/org.neo4j.server.plugins.PluginLifecycle).

netcore dependency injection per user

I am wondering how to set up the netcore dependency container for mvc with one instance per user.
According to https://learn.microsoft.com/en-us/aspnet/core/fundamentals/dependency-injection#service-lifetimes-and-registration-options there are currently only three methods of specifying a lifetime: singleton(one instance per application), scoped (one instance shared within a HttpRequest), transient (one instance per DI instance request)
Has someone attempted to do create on instance per user yet? I would be curious how it's done - if not i will probably dig through the docs at some point to see how it can be done and share the solution.
Create instance on first user request and keep it alive (for next requests) until with some expiration timeout... This looks like a Sessions.
You may register your service with factory method and analyze current Session inside.
If this is an asp.net core application, middleware that is automatically added to the middleware pipeline handles creating a new DI scope at the start of a request, and disposing of that scope at the end of a request. This scope is stored in HttpContext. This scope will be used when injecting MVC controllers etc. Therefore if you want to have per-user services injected into your MVC controllers / action methods, you'll need to replace this scope in HttpContext with your own one built for the current user. You'd have to do this with middleware which would have to run after the authentication middleware (so after the current user was established). Your custom middleware would look at the current authenticated user, and the GetOrCreate the IServiceProvider (container) held in some cache with probably a sliding expiry. With the per user IServiceProvider in hand, it would then create a scope for the current request and replace the scope currently in HttpContext with this user specific one, also ensuring its disposed of at the end of the request. The thing is, when building the per user container, if you create a new ServiceCollection for each user and register a few services and build and cache that IServiceProvider for that user, you won't be able to resolve any services that you've only registered at the application level I.e on startup. This is where the concept of child containers are handy, which microsoft doesnt implement out of the box, but you can use if you switch to using another DI provider like Autofac. Autofac provides an implementation of IServiceProvider and the ability to spawn child containers. If you used this mechanism you could create a child container for each user, which means it would still be able to resolve all your higher level services, but now you can also resolve the user specific services. If you do all this, you'll be able to have per user services injected.
It's a fair amount of work. If there is enough interest I'd consider adding this feature to my multitenancy library as it already does something similar to create per tenant containers: https://github.com/dazinator/Dotnettency
something like that?
var shoppingLists = new Dictionary < string,
ShoppingListStateContainer > ();
services.AddTransient < ShoppingListStateContainer > (s = >{
var userName = s.GetRequiredService < AuthenticationStateProvider > ().GetAuthenticationStateAsync().GetAwaiter().GetResult().User.Identity.Name ? ?"null";
lock(s) {
if (!shoppingLists.ContainsKey(userName)) shoppingLists.Add(userName, new ShoppingListStateContainer());
}
return shoppingLists[userName];
});

In grails app, the field in service is shared by user or not?

I have a question about the field in service is shared by user or not? My grails version is 2.3.4.
Now I have a controller with two actions and trying to set and get value from service field.
//This is a controller
class TestController{
def testService
def setValue(){
testService.setValue("123")
}
def getValue(){}
println testService.getValue()
}
}
//This is a service
class TestService{
def var
def setValue(def value){
var = value
}
def getValue(){}
return var
}
}
In other words, if several users are using the action getValue in the controller, do they share the var in the service or not?
Thank you!
Yes, by default all services are singletons, so there is only one instance of service per webapp, but functions inside are not synchronised:
By default, access to service methods is not synchronised, so nothing prevents concurrent
execution of those methods. In fact, because the service is a
singleton and may be used concurrently, you should be very careful
about storing state in a service. Or take the easy (and better) road
and never store state in a service.
You can change this behaviour by placing a service in a particular
scope. The supported scopes are:
prototype - A new service is created every time it is injected into another class
request - A new service will be created per request
flash - A new service will be created for the current and next request only
flow - In web flows the service will exist for the scope of the flow
conversation - In web flows the service will exist for the scope of the conversation. ie a root flow and its sub flows
session - A service is created for the scope of a user session
singleton (default) - Only one instance of the service ever exists

Resources