How to expose additional models : Migrating from Springfox to Springdoc - openapi

I need to expose some models which don't used directly in REST API methods.
With springfox I used Docket's additionalModels method to programmatically add models to specification:
docket.additionalModels(
typeResolver.resolve(XModel1.class),
typeResolver.resolve(XModel2.class)
)
How to do it with springdoc?
I've created a dummy operation with dummy-parameter which includes all required models. But I feel the approach has space for improvement.

With OpenApiCustomiser , you have access to the OpenAPI Object.
You can add any object/operation you want without having to add annotations on your code.
You can have a look at the documentation for more details:
https://springdoc.org/#how-can-i-customise-the-openapi-object

In Kotlin
fun components(): Components {
val components = Components()
val converter = ModelConverters.getInstance()
val schema1 = converter.readAllAsResolvedSchema(XModel1::class.java)
val schema2 = converter.readAllAsResolvedSchema(XModel2::class.java)
schema1.referencedSchemas.forEach { s -> components.addSchemas(s.key, s.value) }
schema2.referencedSchemas.forEach { s -> components.addSchemas(s.key, s.value) }
return components
}
Additionally you may need to specify the property in application.yml:
springdoc:
remove-broken-reference-definitions: false

Related

How does lagom manage event versioning?

Lets say we modified an event to have a new field added. I understand that we can handle the serialization for event mapping changes in this documentation https://www.lagomframework.com/documentation/1.5.x/scala/Serialization.html but how does lagom know which version the event is? When declaring and defining case classes events, we do not specify the event version. So how does lagom serialization know which event version mapping to use?
In the image below, there is a field called fromVersion. How does lagom know the current version of events pulled from event store datastore?
So, to implement migration you add following code:
private val itemAddedMigration = new JsonMigration(2) {
override def transform(fromVersion: Int, json: JsObject): JsObject = {
if (fromVersion < 2) {
json + ("discount" -> JsNumber(0.0d))
} else {
json
}
}
}
override def migrations = Map[String, JsonMigration](
classOf[ItemAdded].getName -> itemAddedMigration
)
}
That means that all new events of type ItemAdded now will have version 2. All previous events will be treated as version 1.
It is defined in the class PlayJsonSerializer
Please see the following code:
private def parseManifest(manifest: String) = {
val i = manifest.lastIndexOf('#')
val fromVersion = if (i == -1) 1 else manifest.substring(i + 1).toInt
val manifestClassName = if (i == -1) manifest else manifest.substring(0, i)
(fromVersion, manifestClassName)
}
Also, you can check it in the database. I use Cassandra, I if I will open my database, in eventsbytag1 collection I can find the field ser_manifest where described version. Where is simple class - it is version 1, where you have specified additional '#2', it means version 2 and so on.
If you need more information about how it works, you can check method fromBinary in class PlayJsonSerializer.

How to create custom schema with Corda Vault Extension

From Corda documents, it says we can have custom schema in Vault Extension.
However there is not much clarity for Vault Extension which should have ability to create/manage custom database schema pertaining to node vault database.
Are we going to publish API in feature release of Corda
Inside flows, the node exposes a JDBC connection that allows you to write native custom SQL queries (as a vault extension). You can access this JDBC connection using serviceHub.jdbcSession().
If your question is about how to write a custom schema then please see the existing Corda Persistence API docs.
You can then query that custom schema using the new Vault Query API - please see the existing [Corda Vault Query API][3] docs.
Just to add an example to the above, here's a custom schema for the Yo! CorDapp. See YoSchemaV1 below:
// State.
data class State(val origin: Party,
val target: Party,
val yo: String = "Yo!") : ContractState, QueryableState {
override val participants get() = listOf(target)
override val contract get() = Yo()
override fun toString() = "${origin.name}: $yo"
override fun supportedSchemas() = listOf(YoSchemaV1)
override fun generateMappedObject(schema: MappedSchema) = YoSchemaV1.YoEntity(this)
object YoSchemaV1 : MappedSchema(Yo.State::class.java, 1, listOf(YoEntity::class.java)) {
#Entity #Table(name = "yos")
class YoEntity(yo: State) : PersistentState() {
#Column var origin: String = yo.origin.name.toString()
#Column var target: String = yo.target.name.toString()
#Column var yo: String = yo.yo
}
}
}
In short, your state object needs to implement QueryableState, as above.
The full CorDapp is available here: https://github.com/roger3cev/yo-cordapp
Cheers

Handling Connections in Slick 3.0

My code uses Slick 3.0. It has as a common db object.
object Common {
private [database] val db = Database.forURL(
url = // read from config,
user = // read from config,
password = // read from config
)
}
Then, in my database services object's, my methods look like:
private lazy val myTableQuery = TableQuery[MyTable]
def getTableObjects: Future[Seq[MyTableObject]] = {
val action = myTableQuery.result
Common.db.run(action)
}
where I'm re-using the Common.db throughout multiple services.
In Slick 3.0, what's the idiomatic way to run a DB call?
I saw in the Slick 2.0 docs that an implicit session can be used.
However, I'm not sure if what I'm doing is correct in Slick 3.0.
You no longer need an implicit session.
Currently mobile, check out the sample chapters of essential slick -http://underscore.io/training/courses/essential-slick/
It shows how to do it now.
I am one of the authors.
Jono

How do I correctly map versioned resources in Grails?

I have grails running a REST API and using version numbers in the URL like so: https://api.mycompany.com/v2/metadata. I need to change the parameters of one of the endpoints, so I'm bumping the version up to v3. Only one controller is affected, so I would like to delegate the remaining calls back to the controllers for v2 without having to copy/paste everything again. Here's the relevant section of my UrlMappings.groovy:
class UrlMappings {
static mappings = {
"/v3/widget"(controller: "v3widget")
"/v3/$otherResource" {
// does not work, but illustrates what I want to happen
uri = { "/v2/" + params.otherResource }
}
// rest of my file...
"/v2/metadata"(controller: 'metadata')
...
What's the correct way to do this? I'm using grails 2.2.5
I would use a variable in the uri path, and instead of your example you would have the following mappings:
class UrlMappings {
static mappings = {
"/$apiVersion/widget"(controller: "v3widget")
"/$apiVersion/otherResource"(controller: "otherResource")
// rest of my file...
"/$apiVersion/metadata"(controller: 'metadata')
...
And then you could check for the value in controller:
class OtherResourceController {
def index(){
if(params.apiVersion == 'v2') {
...
} else {
...
}
}
}
The example here is checking for the string value, but you could go a bit deeper and actually convert the string value into internal api version enum representation which might be easier to manage. You could also do that in filter.
This way you can increment the logic changes and api will have a nice fallback, will delegate to default version.
But it gets really curly when you have couple of api versions layered one on the other.
The solution I found that works relies on the fact that wildcard mappings can also accept other regular expressions:
class UrlMappings {
static mappings = {
// v3 specific
"/v3/widget"(controller: "v3widget")
// v3/v2 common
"/v[23]/$otherResource" {
// normal mappings go here
}
// v2 specific
"/v2/metadata"(controller: 'v2metadata')
...
This solution works well since I don't have to repeat any mappings, and it's clear what's different between v2 and v3 resources.

Reuse autofac's find ctor logic

Autofac finds "best" ctor when registering a component like this
builder.RegisterType<MyType>()...;
or
builder.RegisterType(typeof(MyType))...;
I'm looking for a way to reuse Autofac's reflection code to find ctor parameters. Is this logic available in some public API?
The reason I want above...
I have some components with unknown types at compile time (=dynamic proxies). Currently I register them like this
builder.Register(c =>
{
var dep1 = c.Resolve<IFoo>();
var dep2 = c.Resolve<IBar>();
var dep3 = c.Resolve<IFooBar>();
return someProxyFactory.CreateProxyFrom<MyType>(dep1, dep2, dep3);
}...;
--- Edit ---
The same question is valid if no proxy is involved but when RegisterType cannot be used. Eg...
builder.Register(c =>
{
[...]
if(something)
return new SomeType(dep1, dep2, dep3);
else
return new SomeOtherType(dep1, dep4, dep2, dep5);
}
Here I also would like to reuse Autofac's "find ctor logic" if possible.
--- End edit ---
It works fine but, if possible, I would like to use autofac's logic to find the ctor dependencies for me. I want to write something like
builder.Register(c =>
{
object[] ctorDependencies = letAutofacDoTheSimilarWorkAsInRegisterType(typeof(MyType));
return someProxyFactory.Create<MyType>(ctorDependencies);
}
Is this possible or do I have to write my own logic for this? Or is some completely different approach available for this scenario?
Not quite the answer you're after I guess, but could you use the existing DynamicProxy2? This enables you to attach interceptors to registered interfaces, much like what you are doing with your proxy factory.
Update: you could possibly use the IConstructorFinder and IConstructorSelector interfaces in the Autofac.Core.Activators.Reflection namespace, implemented by the PublicConstructorFinder and MostParametersConstructorSelector respectively.