Spring Sleuth X-Span-Export/spanExportable not displaying in log4j - log4j2

I am using Spring Sleuth with Log4j2 logger,
While to trying to print TraceId, SpanId & Span Exportable in logs, below pattern didn't print the Span Exportable flag,
%X{traceId},%X{spanId},%X{spanExportable}
%X{traceId},%X{spanId},%X{X-Span-Export}
While tried to analyse with %X - {spanId=d1457051eee5778d, traceId=d1457051eee5778d}

As explained in Sleuth 2.0 to 3.0 migration guide here
For performance reasons, we no longer set the following fields by
default:
parentId
spanExportable
To enable that fields you should add following bean to your application:
#Bean
CorrelationScopeCustomizer addSampled() {
return b -> b.add(SingleCorrelationField.create(BaggageFields.SAMPLED));
}
And also you should use "sampled" field in your patterns nor "X-Span-Export" or "spanExportable".

Related

Unable to find a model that matches key

Upgraded Swagger from 2.9.2 to 3.0.0 based on steps below:
https://springfox.github.io/springfox/docs/snapshot/#migrating-from-existing-2-x-version
In new version, though functionality is working fine, following ERROR is printed in logs when hitting the "/swagger-ui/index.html".
Using springfox-boot-starter 3.0.0. Would appreciate your inputs.
[ReferenceModelSpecificationToPropertyConverter] Unable to find a
model that matches key
ModelKey{qualifiedModelName=ModelName{namespace='java.time',
name='LocalDate'}, viewDiscriminator=null,
validationGroupDiscriminators=[], isResponse=true}
As per the Springfox documentation
http://springfox.github.io/springfox/docs/current/#answers-to-common-questions-and-problems
The way to correctly map the "Date" and "DateTime" types to their
corresponding swagger types:
Substitute "Date" types (java.util.LocalDate, org.joda.time.LocalDate)
by java.sql.Date.
Substitute "DateTime" types (java.util.ZonedDateTime,
org.joda.time.LocalDateTime, …​) by java.util.Date.
docket
.directModelSubstitute(LocalDate.class, java.sql.Date.class)
.directModelSubstitute(LocalDateTime.class, java.util.Date.class)
Example of Docket bean
#Bean
public Docket api()
{
Docket docket = new Docket(DocumentationType.SWAGGER_2) //
.select() //
.apis(RequestHandlerSelectors.basePackage("com.test")) //
.paths(PathSelectors.regex("/api/.*")).build() //
.apiInfo(apiInfo()) //
.pathMapping("/") //
.forCodeGeneration(true) //
.genericModelSubstitutes(ResponseEntity.class) //
.directModelSubstitute(LocalDate.class, java.sql.Date.class)
.directModelSubstitute(LocalDateTime.class, java.util.Date.class)
.useDefaultResponseMessages(false);
return docket;
}
Not sure if this is your case, but to me this problem arised because I had a JsonSubTyped generic inheritance where one of the children had List<LocalDate> and List<LocalDateTime> as their parameter. The fix was - for me - to include extra rules for the types as follows:
myDocket.alternateTypeRules(
AlternateTypeRules.newRule(typeResolver.resolve(List.class, LocalDate.class), typeResolver.resolve(List.class, java.sql.Date.class)),
AlternateTypeRules.newRule(typeResolver.resolve(List.class, LocalDateTime.class), typeResolver.resolve(List.class, java.util.Date.class)))
The replacement classes are from the official site.

How to customize an existing Grails plugin functionality, modifying behavior of doWithSpring method

I am new to grails and while working with Spring Security LDAP plugin it was identified that it accepts the ldap server password in plain text only. The task in hand is to pass an encrypted password which is decrypted before it is consumed by the plugin during its initialization phase.
I have already searched for all possible blogs and stackoverflow questions but could not find a way to extend the main plugin class to simply override the doWithSpring() method so that i can simply add the required decryption logic for the Ldap server password. Any help here will be appreciated.
I have already seen and tried jasypt plugin but it also does not work well if the password is stored in some external file and not application yml. So I am looking for a solution to extend the Spring security plugin main class, add the required behavior and register the custom class.
EDIT
Adding the snippet from Grails LDAP Security plugin, which I am trying to override. So If i am successfully able to update the value of securityConfig object before the plugin loads, the purpose is solved.
Some snippet from the plugin:
def conf = SpringSecurityUtils.securityConfig
...
...
contextSource(DefaultSpringSecurityContextSource, conf.ldap.context.server) { // 'ldap://localhost:389'
authenticationSource = ref('ldapAuthenticationSource')
authenticationStrategy = ref('authenticationStrategy')
userDn = conf.ldap.context.managerDn // 'cn=admin,dc=example,dc=com'
**password = conf.ldap.context.managerPassword // 'secret'**
contextFactory = contextFactoryClass
dirObjectFactory = dirObjectFactoryClass
baseEnvironmentProperties = conf.ldap.context.baseEnvironmentProperties // none
cacheEnvironmentProperties = conf.ldap.context.cacheEnvironmentProperties // true
anonymousReadOnly = conf.ldap.context.anonymousReadOnly // false
referral = conf.ldap.context.referral // null
}
ldapAuthenticationSource(SimpleAuthenticationSource) {
principal = conf.ldap.context.managerDn // 'cn=admin,dc=example,dc=com'
**credentials = conf.ldap.context.managerPassword // 'secret'**
}
You don't need to override the doWithSpring() method in the existing plugin. You can provide your own plugin which loads after the one you want to affect and have your doWithSpring() add whatever you want to the context. If you add beans with the same name as the ones added by the other plugin, yours will replace the ones provided by the other plugin as long as you configure your plugin to load after the other one. Similarly, you could do the same think in resources.groovy of the app if you don't want to write a plugin for this.
You have other options too. You could write a bean post processor or bean definition post processor that affects the beans created by the other plugin. Depending on the particulars, that might be a better idea.
EDIT:
After seeing your comment below I created a simple example that shows how you might use a definition post processor. See the project at https://github.com/jeffbrown/postprocessordemo.
The interesting bits:
https://github.com/jeffbrown/postprocessordemo/blob/master/src/main/groovy/demo/SomeBean.groovy
package demo
class SomeBean {
String someValue
}
https://github.com/jeffbrown/postprocessordemo/blob/master/src/main/groovy/demo/SomePostProcessor.groovy
package demo
import org.springframework.beans.BeansException
import org.springframework.beans.MutablePropertyValues
import org.springframework.beans.PropertyValue
import org.springframework.beans.factory.config.BeanDefinition
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory
import org.springframework.beans.factory.support.BeanDefinitionRegistry
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor
class SomePostProcessor implements BeanDefinitionRegistryPostProcessor{
#Override
void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
BeanDefinition definition = registry.getBeanDefinition('someBean')
MutablePropertyValues values = definition.getPropertyValues()
PropertyValue value = values.getPropertyValue('someValue')
def originalValue = value.getValue()
// this is where you could do your decrypting...
values.addPropertyValue('someValue', "MODIFIED: ${originalValue}".toString())
}
#Override
void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
}
}
https://github.com/jeffbrown/postprocessordemo/blob/master/grails-app/conf/spring/resources.groovy
beans = {
someBean(demo.SomeBean) {
someValue = 'Some Value'
}
somePostProcessor demo.SomePostProcessor
}
https://github.com/jeffbrown/postprocessordemo/blob/master/grails-app/init/postprocessordemo/BootStrap.groovy
package postprocessordemo
import demo.SomeBean
class BootStrap {
SomeBean someBean
def init = { servletContext ->
log.info "The Value: ${someBean.someValue}"
}
def destroy = {
}
}
At application startup you will see log output that looks something like this...
2017-10-23 19:04:54.356 INFO --- [ main] postprocessordemo.BootStrap : The Value: MODIFIED: Some Value
The "MODIFIED" there is evidence that the bean definition post processor modified the property value in the bean. In my example I am simply prepending some text to the string. In your implementation you could decrypt a password or do whatever you want to do there.
I hope that helps.
After trying Jasypt plugin and BeanPostProcessor solutions unsuccessfully for my use case, I found below solution to work perfectly.
To describe again the problem statement here,
a) we had to keep the passwords in an encrypted format inside properties files
b) and given we were packaging as a war file so the properties must not be kept inside the war to allow automated deployment scripts update the encrypted passwords depending on the environment
Jasypt plugin was a perfect solution for the use case a), but it was not able to cover the b) scenario
Moreover, the Grails LDAP Security plugin was getting loaded quite early hence Bean Post processors were also not helping out here.
Solution:
Created a new class by implementing the interface SpringApplicationRunListener. Extended its methods and parsed the properties file using YamlPropertySourceLoader
Sample code:
YamlPropertySourceLoader loader = new YamlPropertySourceLoader();
PropertySource<?> applicationYamlPropertySource = loader.load(
"application.yml", new ClassPathResource("application.yml"),"default");
return applicationYamlPropertySource;
Once the properties were loaded inside the MapPropertySource object, parsed them for the encrypted values and applied the decryption logic.
This whole implementation was executed before any plugins were initialized during Grails bootup process solving the purpose.
Hope it will help others.

Spring Boot 1.3 WebSocket JSON converter Produces Invalid JSON

After upgrading to Spring Boot 1.3 (via Grails 3.1), the JSON output is rendered incorrectly. I believe it is because of the new auto-configured WebSocket JSON converter.
For example, with previous versions of Spring Boot (via Grails 3.0), using the following code:
#MessageMapping("/chat")
#SendTo("/sub/chat")
protected String chatMessage() {
def builder = new groovy.json.JsonBuilder()
builder {
type("message")
text("foobar")
}
builder.toString()
}
This would produce:
{"type": "message", "text": "foobar"}
With Spring Boot 1.3 (via Grails 3.1), that web socket produces the following:
"{\"type\":\"message\",\"text\":\"foobar\"}"
This is not valid JSON. How can I get rid of this new behavior and have it render the JSON as it was before? Please let me know if you have any suggestions.
I tried overriding the new configureMessageConverters method, but it did not have any effect.
looks like you are right. referenced commit shows questionable autoconfiguration imho.
especially b/c in the past, the converter ordering was intentionally changed to that StringMessageConverter takes precedence before MappingJackson2MessageConverter: https://github.com/spring-projects/spring-framework/commit/670c216d3838807fef46cd28cc82165f9abaeb45
for now, you can either disable that autoconfiguration:
#EnableAutoConfiguration(exclude = [WebSocketMessagingAutoConfiguration])
class Application extends GrailsAutoConfiguration { ... }
or, you add yet another StringMessageConverter to the top of the configured converters (maybe because you do want the boot autoconfiguration behavior because it is using the jackson ObjectMapper bean instead of creating a new one):
#Configuration
#EnableWebSocketMessageBroker
class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {
#Override
boolean configureMessageConverters(List<MessageConverter> messageConverters) {
messageConverters.add 0, new StringMessageConverter()
return true
}
...
}
hope that helps.
I don't know how to do it in Grails but in Java you have to now pass the object instead of an object in the String class. I believe the old behavior was actually incorrect as it was returning a string as an object so there was no way to return a String that had JSON inside it as a String. So create an object with the structure you want and return it and you should be fine. I went through the same issue when upgrading from 1.2.X to 1.3.X. I am not exactly sure what change caused this but I think in the long run it is the correct thing to do.

Ensure web.xml filter-mapping from plugin is appended after springSecurityFilterChain

I'm attempting to add a very simple DelegatingFilterProxy to my Grails application via a custom plugin.
I would like the filter to execute after the springSecurityFilterChain filter so that I can make use of certain security-specific information in the custom filter.
I've tried using loadAfter and loadBefore with different techniques in doWithWebDescriptor, but all end with the same result: my custom filter-mapping is always listed before springSecurityFilterChain. Below is my current iteration of doWithWebDescriptor
def contextParams = xml.'context-param'
contextParams[contextParams.size() - 1] + {
filter {
'filter-name'('auditFilter')
'filter-class'(DelegatingFilterProxy.name)
}
}
def filterMappings = xml.'filter-mapping'
filterMappings[filterMappings.size() - 1] + {
'filter-mapping' {
'filter-name'('auditFilter')
'url-pattern'('/*')
}
}
Is there a correct way to go about this?
The grails WebXmlConfig plugin provides additional features to work with the web.xml file. It hooks into an event, eventWebXmlEnd that listens for when the web.xml file is done generating. Once it's done, the plugin will attempt to re-order the servlet filters if necessary. It iterates over all other plugins and looks for a webXmlFilterOrder property in the plugin descriptor. If it finds that property, it registers the desired position and after looping over all plugins, rewrites the web.xml file.
The plugin is actually already included as a dependency of the Spring Security Core plugin, but you should also add it to your own plugin's BuildConfig.groovy file:
compile ':webxml:1.4.1'
So to hook in this functionality, you need to add a webXmlFilterOrder property to your plugin descriptor (really just a getter actually). You can throw this right above the doWithWebDescriptor closure (youll also need to import grails.plugin.webxml.FilterManager):
def getWebXmlFilterOrder() {
[auditFilter: FilterManager.GRAILS_WEB_REQUEST_POSITION + 101]
}
The getter returns a Map where the key is the name of your filter and the value is an int describing the desired position in web.xml. WebXmlConfig provides a FilterManager class with a few position constants that you can use. In this case, GRAILS_WEB_REQUEST_POSITION has a value of 1000.
A quick look at the Spring Security Core plugin descriptor shows that it's putting the springSecurityFilterChain filter at FilterManager.GRAILS_WEB_REQUEST_POSITION + 100, so by setting your auditFilter to anything higher, it will appear below spring security in web.xml.

Setting default maxLength for Grails GORM Strings?

I know you can set default constraints via the grails.gorm.default.constraints config property by name by:
grails.gorm.default.constraints = {
'*'(nullable:true)
}
but is there a way to set it by type? I want to default all my strings to default to maxSize:2000 (primarily to force the default db mapping to not be to varchar(255))
I don't think there's any way to do this easily in Config.groovy. You can create a custom dialect for hibernate without too much trouble though. For example (using the Postgres dialect):
package mypackage;
import org.hibernate.dialect.PostgreSQLDialect;
import java.sql.Types;
public MyPostgresDialect extends PostgresSQLDialect {
public MyPostgresDialect() {
super();
registerColumnType(Types.VARCHAR, "text");
}
}
Then update DataSource.groovy to use the new dialect:
datasource {
...
dialect = mypackage.MyPostgresDialect
}
Just to provide an additional answer I received from a co-worker - which wasn't applicable in this case, but might help others...
if you can follow a naming convention in your properties, then you could do a:
'*_s': (maxSize:2000)
I personally don't like cross-tying prop names and datatypes - but wanted to include this as an approach (even though I like the dialect answer by ataylor more...)

Resources