I'm migrating a 2.5.6 app to 3.3.10. When generating controllers, detected that a service was created and used from the controllers auto-generated code. Looking at the service, is just an interface.
Looking at the grails generate-controller documentation, I can't find information about that "interface service"
http://docs.grails.org/3.3.10/ref/Command%20Line/create-controller.html
What that service is doing internally is also a mistery, and it's not clear what/where should I touch the code when I need to customize any of those methods in the service. I guess this is a new thing in Grails 3.3.x but not sure where to find more info.
So the concrete questions are:
What is the purpose of that interface service?
Where is that documented?
How to customize? Like being implemented by a custom service?
Sample service:
import grails.gorm.services.Service
#Service(SyncLog)
interface SyncLogService {
SyncLog get(Serializable id)
List<SyncLog> list(Map args)
Long count()
void delete(Serializable id)
SyncLog save(SyncLog syncLog)
}
What is the purpose of that interface service?
It is a starting point for your data access layer.
Where is that documented?
At http://gorm.grails.org/latest/hibernate/manual/index.html#dataServices
How to customize?
It is an interface that you can edit and add/delete whatever query methods you like. The documentation linked above describes a lot of details.
Related
I am working on a greenfield project and I want to integrate serilog with ninject.
The use case is as follows:
There are a number of common libraries
These libraries are used in a number of modules i.e plugins. These plugins each receive a GUID at run time which is unique. This
is a base property on an abstract plugin class which every
implementation of a plugin inherits
We want to append this unique name to every log message that a plugin makes
as well as any calls to the common libraries from that plugin so that a log
message can be traced to the unique instance of a plugin that made it
We would prefer not to modify each class in the common libraries to take in a logger to use to log
My thoughts were to :
Create a singleton logger provider. This will be called by anything needing to log.
Use postsharp and CallContext.LogicalSetData to set the GUID prior to any call to the logging provider
Use CallContext.LogicalGetData to get the GUID in the singleton logger provider. This will either retrieve an existing logger for that GUID using Logger.ContextFor or create a new one to add to a dictionary.
Use Ninject to resolve the ILoggerProvider to the singleton provider always when requested
Before I down this circuitious route, is there a better way to do this, maybe with ninject?
Thanks for reading.
I went with the solution as described but due to it being a singleton there was no need for ninject in the end.
The solution is working and doesnt seem to have any performance issues logging at high volumes
Using Sring Data JPA, Spring Data REST 2.4.2, Spring Security and Spring Boot 1.3.1. I have an Account entity that I want to expose over REST for admin purposes:
#PreAuthorize("hasRole('ROLE_ADMIN')") //exclusive admin access
public interface AccountRepository extends JpaRepository<Account, Long> {}
This works as expected and I can access the REST interface with a proper admin role.
Another requirement I have is to allow non-admin users to register and authenticate over HTTP. For that I've created a custom Controller that exposes register() and login() functionality over /register and /login resources. The issue is that when the registration/login internal logic interacts with the repo above, there is no user security context that can be attached, apart from an anonymous one.
To keep things simple I have created a second repo that is not exported and has no security requirements:
#RepositoryRestResource(exported = false)
public interface AccountRepositoryInternal extends JpaRepository<Account, Long> {}
This repo is then then injected in the said controller.
The issue is that I see inconsistent behaviour with the exported interface. In some runtime environments the interface is exported over REST and in others it is not. Is there a better strategy I could use?
You can add #PreAuthorize at both class and method level, so if you need only some methods do be secured just:
Use only one repo instead of two
Extend Repository instead that JPARepository
Copy and paste (literally, they are just placeholders) all the methods that you need from PagingAndSortingRepository.
Add #PreAuthorize accordingly to your needs to specific methods, not to the class.
Copying and pasting methods among repositories interfaces is what the docs suggests (http://docs.spring.io/spring-data/jpa/docs/1.9.2.RELEASE/reference/html/#repositories.definition-tuning) if you want to have a fine grained control, such as in you case.
What actually happens when we do def someService? Does the service code get linked to the controller code?
Grails uses spring IOC, your controllers and services are managed as spring beans, when you define a service inside a controller, spring will inject the service inside the controller, code does not get linked in anyway, just reference to service will be set. Though its not a much expensive operation, you would not want to define service dependencies that are not used to keep the code clean
I think under the hood it's the same process as Spring's #Autowired annotation, so you pay a bit of a performance penalty on start up but I don't think it's significant.
There's another stackoverflow question on the subject here.
Does the service code get linked to the controller code?
That does not make sense.
Actually services in grails are singleton by default.So if you inject a Service by def serviceName it wont create a new service object but a reference to same old service object.
So its not expensive of course.
But if in a service there is a property static session="prototype" or some non-singleton like this.Then it is expensive .
What is the best way to configure a Grails service with environment specific values? I believe there are two options:
access grailsApplication values from within the service class or
configure the service bean in a beans closure in Config.groovy or resources.groovy.
I've seen a couple of posts on stackoverflow and other places that show how to do #1 (accessing grailsApplication in the service). One such post is: Inject grails application configuration into service.
However, I think this creates an unnecessary coupling of the service to Grails. Isn't this similar to accessing Spring's applicationContext in a pojo rather than configuring/injecting the values? Also, I've not had any luck getting this to work in a unit test of the service class as of yet.
Two books have examples of injecting the properties (approach #2). The book The Definitive Guide to Grails 2, chapter 10, section entitled "Services in Action" shows how to do this, but without an environment specific value. The book Groovy and Grails Recipes, section 16-2 also shows an example using resources.groovy, but I've not been able to get it to work either yet.
The following blog post also has a nice example, but not environment specific: http://ldaley.com/post/1253952347/getting-more-out-of-property-override-configuration. Chapter 15 of the Grails Reference is consistent with these examples as well and shows how to set the properties on a bean on a per environment basis.
However, none of the examples of either approach give any opinion or rational for doing it one way or another. Is there really no pros and cons to either approach? Wouldn't the injection approach be easier to unit test and more consistent with the spring way of doing things?
Nathan
I'd say use whichever you're more comfortable with. I tend to go with accessing grailsApplication.config directly from the service, because that lets you make the configuration more "semantic" (for want of a better word) in the sense that you can name the configuration options after what they do, rather than which bean they control. And if two (or more) different beans need to know the site administrator's email address (for example) then they can both read grailsApplication.config.myapp.admin.email rather than my having to configure beans.monitorService.destinationEmail and beans.userService.fromEmail separately.
In unit tests you'd have to mock the grailsApplication config anyway, so it's no big deal filling in test values for the config options your services need to read.
There's a difference in the concept of services (classes that exists in the service folder) and Spring Beans defined in resources.groovy.
To services, Grails already setup transactions:
Services are typically involved with coordinating logic between domain
classes, and hence often involved with persistence that spans large
operations. Given the nature of services, they frequently require
transactional behaviour. You can use programmatic transactions with
the withTransaction method, however this is repetitive and doesn't
fully leverage the power of Spring's underlying transaction
abstraction.
The Spring Beans that you declared aren't transactional by default.
"However, I think this creates an unnecessary coupling of the service
to Grails"
Since Grails services differ from Spring Beans I don't see a problem using approach #1.
For Unit Tests you need to manually wire up you service instance. Example:
class MyService {
def grailsApplication
}
class MyServiceTests {
MyService getServiceInstance() {
MyService myService = new MyService()
myService.grailsApplication = grailsApplication //static attribute in unit tests
return myService
}
}
I'm looking for an example to expose the methods already exposed via MBean server with SNMP.
I read that since Java6 this is already supported in the JDK, but I also found snmp4j as a library. But I couldn't find any example that fits my scenario, or would be helpful.
I already have MBeans registered to the MBeanServer, and I'm looking for a way to enhance the classes I already have in order to make them suitable for SNMP. I can't use mibgen, as it would be the other way around.
Maybe someone can give me an example on what I need to do in order to be able to monitor my application via some SNMP manager.
An example MBean would be
public interface ExporterMXBean {
public static String BEANNAME = "exporter:type=Exporter,name=Exporter";
String getOutputDirectory();
void setOutputDirectory(String outputDirectory);
void startExport();
int getNumberOfThreadsWorking();
}
What would I need to add to the implementation of the interface, how would I register this to a MIB, and how would it be exposed/viewable to a Manager?
Thanks in advance.
I would recommend using SNMP4J-AgentJMX on top of SNMP4J-Agent and SNMP4J like the in the example of SNMP4J-AgentJMX called JvmManagementMibInst.java.
With this approach you do not modify your existing classes (MBeans). Instead your programm or generate a mapping which makes use of the above APIs.
A basic How-To on the necessary steps to create a SNMP agent based on some MBeans of a MBean server is described in the SNMP4J-AgentJMX HowTo