How under the hood grails gets hold of cassandraTemplate instance? - grails

Cassandra Low-level API
A lower level API is provided by the plugin
that is based on the Spring Data Cassandra project.
Spring Data Cassandra provides a CassandraTemplate with methods to
execute statements using the regular Cassandra Java Driver
To get hold of the cassandraTemplate instance inside a controller or
service simply define a cassandraTemplate property. An example can be
seen below:
def cassandraTemplate
def myAction = {
def people = []
people << new Person(firstName: "Fred", lastName: "Flintstone")
people << new Person(firstName: "Barney", lastName: "Rubble")
cassandraTemplate.insert(people)
}

From the docs:
Dependency Injection Basics
A key aspect of Grails services is the ability to use Spring Framework's dependency injection features. Grails supports "dependency injection by convention". In other words, you can use the property name representation of the class name of a service to automatically inject them into controllers, tag libraries, and so on.
As an example, given a service called BookService, if you define a property called bookService in a controller as follows:
class BookController {
def bookService
...
}
In this case, the Spring container will automatically inject an instance of that service based on its configured scope. All dependency injection is done by name. You can also specify the type as follows:
class AuthorService {
BookService bookService
}

Related

Inject repository in service without DI framework

I have a requirement to create a simple REST API with basic CRUD operations on a resource, without using Spring but just Java.I use JAX-RS (Jersey implementation) and Jetty as an embedded servlet container.I use JPA (Hibernate implementation) and an H2 in-memory database. I don't use any DI framework so I do all the DI "manually" with new().
Below is a JAX-RS service that has a POST endpoint. I have created the repository as a static final variable inside the service. BookRepository is an interface and BookRepositoryImpl is the implementation of this repository. I wonder if this is the best approach. If I did this with Spring Autowired annotation, I would have a singleton repository so the only way I thought to emulate this is with a static final variable.
When the container runs, does a separate instance of the BookService gets created for each request (thread)?
So multiple threads will have access to a single copy of the bookRepository?
Isn't that what happens with the Autowired and singleton scope?
#Path("/books")
public class BookService {
private static final BookRepository bookRepository = new BookRepositoryImpl();
#POST
#Path("")
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.APPLICATION_JSON)
public Book registerBook(Book b) {
return bookRepository.saveBook(b);
}
}
Applying Dependency Injection without a DI Container is a practice commonly referred to as Pure DI. With that approach you apply the same principles, practices, and patterns of object-oriented design and DI. But instead of wiring everything up using a DI Container, at the startup path of the application, you build your object graphs manually, using the new keyword.
Pure DI is a common—and valid—approach of practicing DI—DI Containers are useful, but optional tools.
This, however, is not the approach you are currently practicing. You are not injecting your dependencies into their consumers. By creating BookRepositoryImpl inside the BookService class, you are applying the Control Freak anti-pattern, with is a special form of a Dependency Inversion Principle violation. This tightly couples the BookRepositoryImpl class to the BookService class, which will likely cause maintainability issues, because BookRepositoryImpl is a Volatile Dependency. Volatile Dependencies are the reason we introduce abstractions and use Dependency Injection.
Besides, the use of static fields only magnifies the pain, because this might cause thread-safety issues in case BookRepositoryImpl (or one of its dependencies) isn't thread-safe.
So, instead of tightly coupling BookRepositoryImpl to BookService, you should inject the BookRepository abstraction into the BookService's constructor. This keeps the two components loosely coupled, and gives you all the benefits that loose coupling brings:
#Path("/books")
public class BookService {
private final BookRepository bookRepository;
public BookService(BookRepository bookRepository) {
this.bookRepository = bookRepository;
}
#POST
#Path("")
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.APPLICATION_JSON)
public Book registerBook(Book b) {
return bookRepository.saveBook(b);
}
}
This does mean, however, that you should override the way your REST API web framework creates that service. Such framework is typically only able to create instances on your behalf if they have a default constructor. I must admit that I have no experience with JAX-RS, but most frameworks allow overriding the creation of their root classes. With the Microsoft ASP.NET MVC framework, for instance, you can implement a custom IControllerFactory, and replace the framework's default implementation. Inside your custom factory, you will create the complete tree by hand, with plain old Java.
public object create(Type controllerType)
{
if (controllerType == typeof(HomeService))
return
new HomeService(
new PersonsRepositoryImpl(this.connectionString));
if (controllerType == typeof(BookService))
return
new BookService(
new BookRepositoryImpl(this.connectionString));
if (...)
throw new InvalidOperationException("Unknown type.");
}
My expectation is that JAX-RS contains a similar extension model, which allows you to practice Pure DI.
Thanks Steven for the answer. To conclude, this is the JAX-RS config where I am doing the DI:
public class AppConfig extends ResourceConfig {
public AppConfig() {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("my-unit");
BookRepository bookRepository = new BookRepositoryImpl(emf);
BookService bookService = new BookService(bookRepository);
register(bookService);
}
}

Is there a way to use Specifications in ElasticsearchRepository?

I've implemented the Specification pattern for filtering some of my JpaRepositories. After I have implemented a Specification, I can use it with a JpaRepository like this:
Page<Entity> page = entityJpaRepository.findAll(entitySpecification, pageable)
Is there a feature, or planned feature, for supporting Specifications in ElasticsearchRepository?
I understand your pain however the thing is that Specification interface belongs to the JPA API that currently none of the Elastic Search Spring Data repositories implement and I don't think they will.
If you really want to use them you should rather migrate from ElasticsearchRepository coming from spring-data-elasticsearch into JPA-based repositories.
Did not try to use JPA together with ElasticSearch myself but noticed that some people does it, check out this link:
https://programmertoday.com/spring-boot-elastic-search-with-spring-data-jpa/
I don't know about Specifications, but Spring provides a bean ElasticsearchOperations which has a "search" method which accepts org.springframework.data.elasticsearch.core.query.CriteriaQuery which is similar to standard hibernate Criteria. Try mapping Specification to CriteriaQuery.
#Service
#RequiredArgsConstructor
public class FooService {
private final ElasticsearchOperations elasticsearchTemplate; // autowired bean
public void search() {
Criteria criteria = new Criteria();
criteria.and(new Criteria("foo").is(foo));
criteria.and(new Criteria("bar").in(bars));
CriteriaQuery criteriaQuery = new CriteriaQuery(criteria);
elasticsearchOperations.search(criteriaQuery,
FooElasticEntity.class).stream()
.map(SearchHit::getContent)
.collect(Collectors.toList())
}
}
Also it's worth to note that there is a SearchHitSupport utility class which adds support for Pageable.

Grails: How do I use a request scoped service in a tag library?

I'm relatively new to the Grails community, but I love already what the engine has to offer. Currently, I'm implementing a custom tag library in order to easily facilitate a standard design on our pages. However, I need a way of calling helper functions for utility purposes (e.g. filtering data) and to stash request level meta data about my tags (e.g. counters, parent/child relationships).
I have attempted two solutions:
First: I've created a service, set its scope to "request"
package myapp
class CustomTagService {
static scope = 'request'
def data = []
def add(localData) {
data.add(localData)
}
}
However, when I try to inject it in my tag library
package myapp
class MyTagLib {
def customTagService
def myTag = { attrs, body ->
customTagService.add(attrs)
}
}
The engine yells at me for referencing a request scope (after a long painful stacktrace): "Scope 'request' is not active for the current thread; consider defining a scoped proxy for this bean if you intend to refer to it from a singleton"
Second: I understand the pageScope is available to me inside of a tag closure, and I've exploited it before. However, for the structure I am wanting, encapsulation would be much preferred.
Please let me know if I am going down the wrong path on this. Any suggestions would be much appreciated!
You can't use scoped beans in singleton beans since the singleton beans (including taglibs) are created at startup when there's no request active. Instead use a scoped proxy (a bit complicated) or just get the bean from the ApplicationContext for each use at runtime when there is an active request:
package myapp
class MyTagLib {
def grailsApplication
def myTag = { attrs, body ->
customTagService.add(attrs)
}
private getCustomTagService() {
grailsApplication.mainContext.customTagService
}
}

Retrieving a list of GORM persistent properties for a domain

What's the best/easiest way to get a list of the persistent properties associated with a given GORM domain object? I can get the list of all properties, but this list contains non-persistent fields such as class and constraints.
Currently I'm using this and filtering out the list of nonPersistent properties using a list I created:
def nonPersistent = ["log", "class", "constraints", "properties", "errors", "mapping", "metaClass"]
def newMap = [:]
domainObject.getProperties().each { property ->
if (!nonPersistent.contains(property.key)) {
newMap.put property.key, property.value
}
}
There seems like there must be a better way of getting just the persistent properties.
Try this:
import org.codehaus.groovy.grails.commons.DefaultGrailsDomainClass
...
def d = new DefaultGrailsDomainClass(YourDomain.class)
d.persistentProperties
Here's a link to the Grails API for GrailsDomainClass (it's a link to an older version; I couldn't find a newer one after some quick searches). It's got a getPersistentProperties() (used in the code snippet above). You can traverse the API documentation to see what other methods might be useful to you.
If you want an example, do a grails install-templates and then look at src/templates/scaffolding/create.gsp. There's a block in there where it iterates over the persistent domain properties.
Now (strarting Grails 2.x) you don't even have to instantiate new DefaultGrailsDomainClass(...) and avoid unnecessary code executions. All domain class objects have injected property domainClass:
def domainObject = new YourDomain()
domainObject.domainClass.persistentProperties
Or, if you haven't domain class object, you can get DefaultGrailsDomainClass from application context by domain class name - each domain class has a DefaultGrailsDomainClass registered as a Spring bean. So you can use, for example, Holders (assuming your domain class name is 'Foo'):
def defaultGrailsDomainClass = Holders.applicationContext.getBean("FooDomainClass")
defaultGrailsDomainClass.persistentProperties
As of grails 3.3.0
All code that uses the GrailsDomainClass or GrailsDomainClassProperty classes should be re-written to use the mapping context api.
To get started, inject the grailsDomainClassMappingContext bean. See the api documentation for more information on the MappingContext, PersistentEntity (GrailsDomainClass), and PersistentProperty(GrailsDomainClassProperty)
For example:
class MyService {
def grailsDomainClassMappingContext //inject
def accessDomainProperties(Class clazz) {
PersistentEntity entityClass = grailsDomainClassMappingContext.getPersistentEntity(clazz.name)
List<PersistentProperty> persistentPropertyList = entityClass.persistentProperties
persistentPropertyList.each { property ->
println property.name
}
}
}
Hope this helps someone.

Ninject with Windows Application

I want to use Ninject in my Windows application and I want to know if there is best practices that I can do; strategies to find a balance between performance and maintenance.
The problem with Windows application and Web application is that in Web application, there is a scope easy to define that is the context but with Windows application, you have no scope that is easy to use form after form.
As example, I have a service that query the database. This service have a constructor and received a UnitOfWork. With Ninject, I can create a property marked as to be injected but if I do that, each time I will create this service, a new connection will be created to the database.
Just for this reason, I must manually create my services to control the number of connection created and no dependency injector can be used.
I have found that you can call the Inject method after created the service for inject dependencies but I'm sure I can use a better strategy.
With Ninject, you can have Ninject scope lifetimes of your injected dependencies to any object you want to provide (not just Singleton, Request, Thread, and Transient scopes).
From the Ninject Documentation Wiki:
You can also easily define you own
scopes using the .InScope(object o)
method.
You'll find some actual detail about how object scoping works in this Ninject Google Groups question & answer.
I finally found what I searching for.
Create a class that inherits from 'Ninject.Activation.Provider(of T)'
Overrrides the function 'CreateInstance'
Bind your interface with that 'Bind(Of [Your interface]).ToProvider([Your provider class])'
And now, you will be able to control each instance created that are associated with the specified interface.
Note that you can pass a type or an instance to the provider parameter of the Bind method. You can with an instance create a provider before binding your interfaces and use this provider in your code when you want to create a new instance.
The provider in conjunction with InScope allows great flexibility for each place where you want to have and instance of an object that can be injected automatically and have a determined scope.
Here is an example:
Public Interface IConnection
End Interface
Public Class Connection
Implements IConnection
End Class
Imports Ninject
Public Class StandardModule
Inherits Ninject.Modules.NinjectModule
Public Property ConnectionProvider As ConnectionProvider
Public Overrides Sub Load()
Bind(Of IConnection).ToProvider(Me.ConnectionProvider)
End Sub
End Class
Public Class ConnectionProvider
Inherits Ninject.Activation.Provider(Of IConnection)
Public Property Connection As IConnection
Protected Overrides Function CreateInstance(ByVal context As Ninject.Activation.IContext) As IConnection
Return Me.Connection
End Function
End Class
Imports Ninject
Module EntryPoint
Sub Main()
Dim provider As New ConnectionProvider
Dim standardModule As New StandardModule
Dim connection As IConnection
Dim kernel As New Ninject.StandardKernel()
standardModule.ConnectionProvider = provider
kernel = New Ninject.StandardKernel(standardModule)
' Here you should use a factory instead of create an instance directly but
' for demonstration, it show how an instance can be propagated to object created
' by NInject.
provider.Connection = New Connection
connection = kernel.Get(Of IConnection)()
End Sub
End Module
This article by Ayende in MSDN Magazine is ostensibly about NHibernate, and mentions the word inject only once (and that only wrt AOP), but the phrasing of your question suggests to me it'll be great food for thought as you consider how to architect your app.
You can also make your frameworks depend on a factory instance, and rely on the factory to perform your connection pooling.
Alternatively, you can use Ninject itself to always use the same object instance for the particular type.

Resources