Should "persistent" field appear in serialized PanacheEntity? - orm

I am building a simple Jaxrs api in quarkus. When I call my index method it looks like jackson serializes the objects with the persistent field, that it gets from the PanacheEntityBase.
Example:
[
{
"persistent": true,
"id": 1,
"createdAt": "2019-03-18",
"updatedAt": "2019-03-18"
},
{
"persistent": true,
"id": 2,
"createdAt": "2019-03-18",
"updatedAt": "2019-03-18"
}
]
The persistent field isn't saved to the database, but it shows up in the response. I have looked into using #jsonIgnore and jackson mixins, but I would rather not have to do this, especially if this is just a configuration issue. I am curious if Panache should be doing this, or if anyone else is having this problem.

This happens when we use 3-rd party libraries as returned data type and provide it to Jackson serialisation process. PanacheEntity extends PanacheEntityBase which contains isPersistent method which is treated by Jackson like a POJO getter method.
public boolean isPersistent() {
return JpaOperations.isPersistent(this);
}
Jackson automatically takes all get* and is* methods and try to serialise it and include to result JSON. There is no way to configure it on quarkus level. Your solution with JsonIgnore and MixIn feature is good approach.

With Json-B add in your entity :
#JsonbTransient
public boolean isPersistent() {
return super.isPersistent();
}

Related

Is it possible to define extra details in the callerContext of a Cognito pre-token lambda call?

In Cognito, I have a pretoken generation hook setup and my lambda receives this
{
"callerContext": {
"clientId": "abcde12345" // some hash,
...
},
"request": {
"userAttributes": {
"email": "foo#bar.com",
"sub": "someUserID",
...
},
...
},
...
}
I would like to be able to determine what claims to assign this user, not by the user attributes, but by the app the user is using to login.
Naturally, I could just use callContext.clientId but that can change when an app client is recreated. Is there a way to use a custom string from the callerContext? e.g
"callerContext": {
"clientId": "abcde12345" // some hash,
"appName": "FoobarGame"
}
Is it possible to define this custom string in the Cognito App client instead of relying on the cognito Id?(which can change upon recreation).
I don't think this is doable. At least in the document, they haven't mentioned a way to use a custom string within the callerContext.
As your requirement is: to avoid the code changes, based on the changes in client id, I would suggest to use lambda environment variables.
So we can specify the client Id as an environment variable. Then in the code, retrieve it from there. With that approach, way we don't have to change the code and only the environment variable value.
Would that work for you?

How to define relations using primary keys instead of entities in TypeORM WIth NestJS

I'm using NestJS + TypeORM, and have two entities that looks like follows:
export class User {
#PrimaryColumn()
UserID: number;
#Column()
UserName: string;
#OneToOne(() => Blog)
#JoinColumn()
Blog: Blog;
}
export class Blog {
#PrimaryColumn()
BlogID: number;
#Column()
BlogName: string;
}
When a consumer sends a request to create a User like the following, with the BlogID in the request:
userRequest = {
"UserID": 1,
"UserName": "me",
"BlogID": 12
}
On the backend, I can't do userRepository.create(userRequest), I'll have to convert the BlogID sent in the request to an actual Blog entity object so that typeorm can process this. Now, the only way I can think of doing this is my injecting the Blog repository and doing:
userEntity = {
"UserID": userRequest.UserID
"UserName": userRequest.UserName
"Blog": await this.blogRepository.findOneBy({
BlogID: userRequest.BlogID
})
and finally doing:
userRepository.create(userEntity)
My main question: is there a way to do this without injecting the Blog repository into the User service? The problem that arises is that I also implement a functionality that requires me to inject the User repository into the Blog service, which creates a circular dependency. NestJS mandates that circular dependencies should be avoided at all costs, but I don't believe I'm trying to do anything that's programmatically bad practice by implementing this. If I could implement this without introducing a circular dependency, I would. And I believe the main thing that's stopping me from doing so is the fact that I need to import the repository of the entity into the service of the adjacent service. Any tips?
userEntity = {
"UserID": userRequest.UserID
"UserName": userRequest.UserName
"Blog": {id: userRequest.BlogId}
}
pass userRequest.BlogId as userEntity.Blog.id
Update your relation like this :
#OneToOne(() => Blog)
#JoinColumn({ name: "blogId" })
Blog: Blog;

Traverse of linked entities with API client exposed by spring-data-rest

With a generated client by openapi-generator (typescript-axios in my case), it is easy to request an entity that is exposed by spring-data-rest, let's say a Person entity with
const endpoint = PersonEntityControllerApiFactory(configuration);
endpoint.getItemResourcePersonGet('5000')
which gives me an object like
{
"id" : "5000",
"name" : "Mr. Anderson",
"_links" : {
"self": {
"href": "http://localhost:8888/api/persons/5000"
},
"addresses": {
"href": "http://localhost:8888/api/persons/5000/addresses"
}
}
}
Now, is there an easy way to request the addresses collection of that entity with the generated API client (typescript-axios in my case)?
One compicated way comes to my mind to solve this. It's possible to provide a spring data rest projection for Person which inlines ids or complete Address entities into Person. But that would take some extra effort and would be against the HAL / HATEOAS idea.
Another way could be to perform a request on the provided addresses link manually (e.g. by calling axios). But that would question the use of a generated API client in general.

OData: Change URL value for entity type in EDM Model

I'm working with a ASP.NET Core Web Api project that uses OData for the exposed endpoints and are consumed with a Simple.OData.Client.
Some of my endpoints are:
http://{baseUrl}/odata/Vehicle --> this works perfectly
But I'm having issues with these two:
http://{baseUrl}/odata/Vehicle/Brand
http://{baseUrl}/odata/Vehicle/Type
Basicly, I can't modify my EDM Models for modifying the URL property that is exposed in the metadata of OData. My EDM looks like this:
private IEdmModel GetEdmModel()
{
var odataBuilder = new ODataConventionModelBuilder();
odataBuilder.EntitySet<Vehicle>("Vehicle");
odataBuilder.EntitySet<VehicleType>("VehicleType");
odataBuilder.EntitySet<VehicleBrand>("VehicleBrand");
return odataBuilder.GetEdmModel();
}
And the metadata that I get when I navigate through http://{baseUrl}/odata/ is the following:
{
"#odata.context": "https://localhost:44332/odata/$metadata",
"value": [
{
"name": "Vehicle",
"kind": "EntitySet",
"url": "Vehicle"
},
{
"name": "VehicleType",
"kind": "EntitySet",
"url": "VehicleType"
},
{
"name": "VehicleBrand",
"kind": "EntitySet",
"url": "VehicleBrand"
}
]
}
I couldn't find a way to maintain the name as it is, but modify the "url" property shown on the JSON to point to my proper endpoint. I want this result:
{
"name": "VehicleBrand",
"kind": "EntitySet",
"url": "Vehicle/Brand"
}
Any of the methods exposed on EntitySetConfiguration or ODataConventionModelBuilder seems to have a way to specify a different URI for a registered entity type.
Someone has faced this issue? I'm sure that might be some way of solving this.
Odata Route or Navigation Property?
Please have a look at that documentation here
Long story short - an OData URI consists of:
The service root
The OData path
Query options
For example. This is a Path that goes to the EntitySet "Products", takes the first, and then Navigates (see Navigation Properties) to its Supplier.
https://example.com/odata/Products(1)/Supplier?$top=2
------------base---------|-----Path-----------?---options---
So, everything you make accessible at root level should have its own path, and the / telling Odata to navigate onward from there.
So, now for OData, it would freak the hell out of most clients and surely be bad style if you would define an entitysets path as something that can be confused with another entititysets navigation property.
But if you REALLY need to do it, maybe you can achieve it by defining a custom routing convention.
But dont! It will only make trouble
Do you want a navigation property?
If you want the set that "Type" returns to be dependent on the Vehicle, you should define a navigation property on Vehicle instead.
Greetings, Mike

How to use RSA in .net Core

I try to encrypt a file with RSA, but it don't have the toXmlString() and fromXmlString method. how to use RSA class in .net core ?
And I want to encrypt with private key and decrypt with public key ,so others can only read this file but can't generate this file , Is that possible ?
While the ToXmlString and FromXmlString methods are not available, ImportParameters(RSAParameters) and ExportParameters(bool) are.
If you have existing XML formatted values that you need to continue to read, the XML format of the keys isn't very interesting:
Public only:
<RSAKeyValue>
<Modulus>[base64-encoded value]</Modulus>
<Exponent>[base64-encoded value]</Exponent>
</RSAKeyValue>
Public+Private:
<RSAKeyValue>
<Modulus>[base64-encoded value]</Modulus>
<Exponent>[base64-encoded value]</Exponent>
<P>[base64-encoded value]</P>
<Q>[base64-encoded value]</Q>
<DP>[base64-encoded value]</DP>
<DQ>[base64-encoded value]</DQ>
<InverseQ>[base64-encoded value]</InverseQ>
</RSAKeyValue>
(where each named XML element maps to the field of the same name on the RSAParameters struct)
Otherwise you can/should use whatever serialization mechanism is the best suited for you and your application.
Currently you get less when using pure .net core:
In the end this means you can build on .NET Core today, and expect
more features to light up later, so things will get easier as time
goes on. Whether you want to be an early adopter with the less
featured framework now, or jump in later when more features have been
added and the third party eco-system has caught up is going to be a
(tough) decision that we all have to make on your own.
You will have them available if you target the full .net framework in .net core.
{
"version": "1.0.0-*",
"dependencies": {
"NETStandard.Library": "1.6.0"
},
"frameworks": {
"net461": {}
}
}
They won't be available with for example:
"frameworks": {
"netcoreapp1.0": {
"imports": [
"dotnet5.6",
"portable-net45+win8"
]
}
},