Disable spring boot auditing in a jhipster generated application - jhipster

I would like to disable/limit auditing (CustomAuditEventRepository) in an application generated using jhipster.
How can I do this?

Modify CustomAuditEventRepository so that it does nothing in add(), this is generated code, it's yours so you can do whatever you want with it.

Options 1: Disable audit event of spring actuator. Adding config properties to application.yml file:
management:
auditevents:
enabled: false
Refer: AuditAutoConfiguration
#Configuration(proxyBeanMethods = false)
#ConditionalOnBean(AuditEventRepository.class)
#ConditionalOnProperty(prefix = "management.auditevents", name = "enabled", matchIfMissing = true)
public class AuditAutoConfiguration {
...
}
Options 2: Add custom AuditListener bean
#Bean
public MyAuditListener auditListener() {
return new MyAuditListener();
}
public class MyAuditListener extends AbstractAuditListener {
private static final Log logger = LogFactory.getLog(MyAuditListener.class);
public MyAuditListener() {
...
}
#Override
protected void onAuditEvent(AuditEvent event) {
...
}
}

Related

Accessing test context data in custom cucumber formatter/listener

I am creating some kind of custom reporting with cucumber with custom listener/formatter. but I am unable to add some data from test context to my report.
I know we share data/state between steps using cucumber-picocontainer, but my question is how can I access test context data from the custom listener/formatter that i am writing?
Cucumber-Java : 5.2.0
Update: Adding more details. is there a way i can use use context object in the custom listener/plugin. i would like to context.setFailMessage(""); from the custom listener.
Thanks,
Vikas
In order to create custom reporting in cucumber, you have to follow the below steps.
Step 1: Implement ConcurrentEventListener interface
public class DesktopStepDisplayer implements ConcurrentEventListener
Step 2: Add the implementation in EventHandler as show below
private EventHandler<TestStepStarted> eventHandler = new EventHandler<TestStepStarted>()
{
public void receive(TestStepStarted event)
{
if(event.getTestStep() instanceof PickleStepTestStep)
{
String message = ((PickleStepTestStep)event.getTestStep()).getStep().getText();
}
};
public void setEventPublisher(EventPublisher publisher) {
publisher.registerHandlerFor(TestStepStarted.class, eventHandler);
}
Step 3: Set the event publisher
public void setEventPublisher(EventPublisher publisher) {
publisher.registerHandlerFor(TestStepStarted.class, eventHandler);
}
Entire Script:
public class DesktopStepDisplayer implements ConcurrentEventListener {
private EventHandler<TestStepStarted> eventHandler = new EventHandler<TestStepStarted>()
{
public void receive(TestStepStarted event)
{
if(event.getTestStep() instanceof PickleStepTestStep)
{
String message = ((PickleStepTestStep)event.getTestStep()).getStep().getText();
}
};
public void setEventPublisher(EventPublisher publisher) {
publisher.registerHandlerFor(TestStepStarted.class, eventHandler);
}
}

log4net - how to call ActivateOptions on AdoNetAppenderParameter.Layout

I am trying to configure log4net dynamically for writing log to sql database. For that I am using AdoNetAppender class from log4net library.
I see activateOptions for the appender but not for the Layout defined in Command Parameters
public override void ActivateOptions();
Calling AdoNetAppender.ActivateOptions() is writing logs to database but its writing same data to all columns, instead of writing to corresponding data to respective columns.
I figured this has to do with ActiveOptions on Layout, but I don't see ActivateOptions for Layout.
Any help is greatly appreciated.
For anyone facing this issue. Below fix did the trick:
public class CustomAdoNetAppender : AdoNetAppender
{
//code omitted for simplicity
//parameter using inherited layout
AddParameter(new AdoNetAppenderParameter()
{
ParameterName = "#thread",
DbType = System.Data.DbType.String,
Size = 255,
Layout = new CustomLayout2RawLayoutAdapter(new PatternLayout() { ConversionPattern = "%thread" })
});
}
private class CustomLayout2RawLayoutAdapter : Layout2RawLayoutAdapter
{
private readonly PatternLayout _layout;
public CustomLayout2RawLayoutAdapter(PatternLayout layout)
: base(layout)
{
_layout = layout;
}
public void ActivateOptions()
{
_layout.ActivateOptions();
}
}
public override void ActivateOptions()
{
base.ActivateOptions();
if (m_usePreparedCommand)
{
foreach (AdoNetAppenderParameter item in m_parameters)
{
if (item.Layout is CustomLayout2RawLayoutAdapter)
(item.Layout as CustomLayout2RawLayoutAdapter).ActivateOptions();
}
}
}

Where and How To Define An Application Property? - JHIpster

In Spring Boot, an application property can be defined in application.properties file. For example, a prefix of Rest can be defined as
spring.data.rest.basePath=api
For JHipster which is based on Spring Boot, I guess that an application property could defined in the application.yml file. But none of the follow approach work for me: a 404 error.
spring.data.rest.basePath: api
spring:
data:
rest:
basePath: api
The other possibility is the configuration itself doesn't work.
I have same problem and finally figured it out!
Quote from Jhipster website:
Your generated application can also have its own Spring Boot properties. This is highly recommended, as it allows type-safe configuration of the application, as well as auto-completion and documentation within an IDE.
JHipster has generated a ApplicationProperties class in the config package, which is already preconfigured, and it is already documented at the bottom the application.yml, application-dev.yml and application-prod.yml files. All you need to do is code your own specific properties.
In my case, I have set the properties in applicaiton-prod.yml
application:
redis:
host: vnode1
pool:
max-active: 8
max-idle: 8
max-wait: -1
min-idle: 0
port: 6379
In ApplicationProperties class:
#ConfigurationProperties(prefix = "application", ignoreUnknownFields = false)
public class ApplicationProperties {
public final Redis redis = new Redis();
public Redis getRedis() {
return redis;
}
public static class Redis {
private String host = "127.0.0.1";
private int port = 0;
public String getHost() {
return host;
}
public void setHost(String host) {
this.host = host;
}
public int getPort() {
return port;
}
public void setPort(int port) {
this.port = port;
}
private Pool pool = new Pool();
public void setPool(Pool pool) {
this.pool = pool;
}
public Pool getPool() {
return this.pool;
}
public static class Pool {
private int maxActive = 8;
private int maxWait = -1;
public int getMaxIdle() {
return maxIdle;
}
public void setMaxIdle(int maxIdle) {
this.maxIdle = maxIdle;
}
private int maxIdle = 8;
private int minIdle = 0;
public void setMaxActive(int maxActive) {
this.maxActive = maxActive;
}
public int getMaxActive() {
return maxActive;
}
public int getMinIdle() {
return minIdle;
}
public void setMinIdle(int minIdle) {
this.minIdle = minIdle;
}
public int getMaxWait() {
return maxWait;
}
public void setMaxWait(int maxWait) {
this.maxWait = maxWait;
}
}
}
}
Then I use it as:
private final ApplicationProperties.Redis redis;
public RedisConfiguration(ApplicationProperties applicationProperties){
redis = applicationProperties.getRedis();
}
For instance use max-wait and host:
this.redis.getPool().getMaxWait();
this.redis.getHost();
Hope it helps.
The application.yml should be whit spaces not tabs.
Try like this:
spring:
data:
rest:
basePath: api
In my application the file is in the path:
src\main\resources\config\application.yml
After trying dozens of time how to handle the problem I finally figured out how to make it work. Maybe it will be useful for somebody.
To use prefix for controllers (let's say for example jh) we need to use server.servlet.context-path and not spring.data.rest.basePath.
Link to documentation https://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html
So application.yml should looks like this:
server:
servlet:
context-path: /jh
session:
cookie:
http-only: true
The information in this link is also useful to help solve.
https://docs.spring.io/spring-boot/docs/1.0.1.RELEASE/reference/html/boot-features-external-config.html
After you have built you application config class as per Haifeng Zhang answer above you can then access these properties anywhere by:
#Autowired
private ApplicationProperties redis;
then to access the properties
int myEnvironmentPort = redis.getPort();

Convert log level (log4net)

I want to convert an INFO log level to a WARN if the INFO log message contains an exception. Is there anyway I can accomplish this? (I am integrating log4net in a .NET application)
Unless you already wrap your logging calls, in which case you could intercept the messages before passing them to log4net, your best bet would be to create your own appenders which promote log events as appropriate. As each appender subclass would need the exact same code I've created an extension method which does the actual promotion:
public static class AppenderExtensions
{
public static LoggingEvent Promote(this LoggingEvent loggingEvent)
{
if (loggingEvent.Level != Level.Info
|| loggingEvent.ExceptionObject == null)
{
return loggingEvent;
}
var data = loggingEvent.GetLoggingEventData(FixFlags.All);
data.Level = Level.Warn;
return new LoggingEvent(data);
}
}
public class PromotingAdoNetAppender : AdoNetAppender
{
protected override void Append(LoggingEvent loggingEvent)
{
base.Append(loggingEvent.Promote());
}
}
public class PromotingRollingFileAppender : RollingFileAppender
{
protected override void Append(LoggingEvent loggingEvent)
{
base.Append(loggingEvent.Promote());
}
}
Then all you need to do is to declare these appender types in your config:
<appender name="DatabaseAppender"
type="Your.Namespace.Here.PromotingAdoNetAppender">
…

How to set log4net's log file location in autofac?

I am now adding controller log by following this post: Using Autofac to inject log4net into controller
After doing that, I can get my application run correctly. Below are the details:
LogInjectionModule here:
public class LogInjectionModule:Module
{
protected override void AttachToComponentRegistration(Autofac.Core.IComponentRegistry componentRegistry, Autofac.Core.IComponentRegistration registration)
{
registration.Preparing += OnComponentPreparing;
}
static void OnComponentPreparing(object sender, PreparingEventArgs e)
{
var t = e.Component.Activator.LimitType;
e.Parameters = e.Parameters.Union(new[]
{
new ResolvedParameter((p, i) => p.ParameterType == typeof(ILog), (p, i) => LogManager.GetLogger(t))
});
}
}
DependencyRegister here:
private void RegisterDependency()
{
var builder = new ContainerBuilder();
builder.RegisterControllers(Assembly.GetExecutingAssembly());
builder.RegisterGeneric(typeof(Repository<>)).As(typeof(IRepository<>)).InstancePerHttpRequest();
builder.RegisterType<UnitOfWork>().As<IUnitOfWork>().InstancePerHttpRequest();
builder.RegisterType<BookContext>().As<IDbContext>().SingleInstance().PreserveExistingDefaults();
builder.RegisterType<ManagerRepository>().As<IManager>().InstancePerHttpRequest();
builder.RegisterType<BookLendRepository>().As<IBookLend>().InstancePerHttpRequest();
builder.RegisterType<BookPlaceRepository>().As<IBookPlace>().InstancePerHttpRequest();
builder.RegisterType<BookRepository>().As<IBook>().InstancePerHttpRequest();
builder.RegisterType<BookTypeRepository>().As<IBookType>().InstancePerHttpRequest();
builder.RegisterType<StudentRepository>().As<IStudent>().InstancePerHttpRequest();
builder.RegisterType<ManagerService>().As<IManagerService>().InstancePerHttpRequest();
builder.RegisterModule(new LogInjectionModule());
var container = builder.Build();
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
}
MyController here:
public HomeController(
IManagerService managerService
,ILog logger
)
{
this.managerService = managerService;
this.logger = logger;
}
private readonly IManagerService managerService;
private readonly ILog logger;
public ActionResult Index(Manager manager)
{
logger.Info("test");
return View();
}
And when I debug to logger.Info("test") , I can get the log instance. But the problem is , where is the log file's location? is there any config for the integrated log4net that I can decide where to put the log file?
The question isn't related to Autofac. Log4net is a standalone library. You can read more about log4net on its homepage and how to configure it here.

Resources