분류없음2019.04.14 00:27

스프링에서 가장 쉽게 프로퍼티를 읽어오는 방법은 @Value를 이용하는 것이다.

- @Value(value="${app.base.name}") 를 이용해서 application의 프로퍼티 하나를 읽어오거나
- @Value("#{systemProperties['os.name']}") 처럼 이용해서 시스템 값을 가져오거나
- @Value("${spring.profiles.active:default}") 를 이용해서 프로파일값을 가져 올 수 있지만,

expression 을 이용하거나, 몇몇 한정된 경우에만 쓰이고 실제로는 @ConfigurationProperties를 더 많이 이용한다.
(링크 : https://docs.spring.io/spring-boot/docs/current/api/org/springframework/boot/context/properties/ConfigurationProperties.html )

ConfigurationProperties를 를 이용해서 외부 설정값을 application 내부에 사용하기 위해서는 spring bean으로 등록해야 한다.

첫번째로 명시적으로 @Bean 으로 명시적으로 생성 하기

@Configuration
public class AppConfigurare {
    @Bean
    public BistrosAppProperties bistrosAppProperties() {
        return new BistrosAppProperties();
    }
}

두번째로는 간단하기 해당 클래스에 바로 @Configuration을 붙여도 된다.

@Configuration
@ConfigurationProperties(prefix = "app.base")
public class BistrosAppProperties {
...
}

둘다 동작은 하지만, Intellij IDE 에서는  아래와 같은 화면을 보여준다. 

이 꼴보기 싫은 빨간줄을 없애려면 가이드대로 @EnableConfigratuinProperties를 사용해야 한다.
그래서 order-eda-gateway 는 4개의 @ConfigurationProperties 클래스가 존재하지만  @EnableConfigurationProperties 도 3개나 선언했다.  (패키지별로의 커플링을 위해서 모듈화 되어 있다)

왜 이럴까 갑자기 궁금해져서 찾아보니.... https://youtrack.jetbrains.com/issue/IDEA-204153

 

Spring: Incorrect error when combining @Configuration and @ConfigurationProperties annotations : IDEA-204153

What steps will reproduce the issue? 1. Start a Spring Boot project 2. Create a class with both the "@Configuration" and "@ConfigurationProperties" annotations (see screenshot) 3. See the red squiggle…

youtrack.jetbrains.com

@Component 는 사용하면 빨간줄이 안나오도록 수정되었고, @Service는 여전히 에러라고 표시된다.   
@Configuration 이나 @Service 어노테이션을 사용 할 경우에 에러라고 나오는 것은 문제이고 '경고'로 나와야 할것 같지만, 그건 좀 어려운것 같다. 정도로 이해했다. 그러니까... 그냥 이렇게 쓰자 '_';;

ps. 내 스프링 기억은 2.5에서 끝인데 끝도 없이 뭐가 생기네 https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html 를 보면 properties 의 적용 순서의 첫번째가 devtools global properties이다. 쓸일도 없고 써본적도 없는 devtools ....

Posted by dev.bistro
분류없음2019.04.11 15:59

Spring Security OAuth2  인증 순서.

1. https://localhost:8443/login  으로 로그인을 하려고 하면 security의 `anyRequest().authenticated()` 코드에 의해 인증이 필요한것으로 파악하여 302응답이 돌아온다.
    Status Code : 302
    Location: https://www.facebook.com/dialog/oauth?client_id=394182450695217&redirect_uri=https://localhost:8443/login&response_type=code&state=X6kWlA

해당 Server Log

...더보기

2019-04-11 15:17:37.327 DEBUG 52044 --- [nio-8443-exec-6] o.s.security.web.FilterChainProxy        : /login at position 2 of 12 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
2019-04-11 15:17:37.327 DEBUG 52044 --- [nio-8443-exec-6] w.c.HttpSessionSecurityContextRepository : HttpSession returned null object for SPRING_SECURITY_CONTEXT
2019-04-11 15:17:37.327 DEBUG 52044 --- [nio-8443-exec-6] w.c.HttpSessionSecurityContextRepository : No SecurityContext was available from the HttpSession: org.apache.catalina.session.StandardSessionFacade@16504e11. A new one will be created.

2019-04-11 15:17:37.327 DEBUG 52044 --- [nio-8443-exec-6] o.s.security.web.FilterChainProxy        : /login at position 6 of 12 in additional filter chain; firing Filter: 'OAuth2ClientAuthenticationProcessingFilter'
2019-04-11 15:17:37.327 DEBUG 52044 --- [nio-8443-exec-6] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/login'; against '/login'

2019-04-11 15:17:37.327 DEBUG 52044 --- [nio-8443-exec-6] uth2ClientAuthenticationProcessingFilter : Request is to process authentication

2019-04-11 15:17:37.329 DEBUG 52044 --- [nio-8443-exec-6] w.c.HttpSessionSecurityContextRepository : SecurityContext is empty or contents are anonymous - context will not be stored in HttpSession.
2019-04-11 15:17:37.329 DEBUG 52044 --- [nio-8443-exec-6] s.s.w.c.SecurityContextPersistenceFilter : SecurityContextHolder now cleared, as request processing completed
2019-04-11 15:17:37.329 DEBUG 52044 --- [nio-8443-exec-6] o.s.s.web.DefaultRedirectStrategy        : Redirecting to 'https://www.facebook.com/dialog/oauth?client_id=394182450695217&redirect_uri=https://localhost:8443/login&response_type=code&state=X6kWlA'

 

2.  해당 링크에서 다시 한번 페이스북 로그인을 요청하기 위해 302:redirect를 한다.

https://www.facebook.com/login.php?skip_api_login .. 이때 cancel_url 과 redirect_url 파라미터를 추가로 붙인다. 거기서 성공하면 다시 한번 https://www.facebook.com/dialog/oauth 를 호출하게 되고 302응답과 함께 code 값을 받아온다.

 

해당 값으로 access token을 얻기 위해 호출한다. ->  https://git.io/fjqur 에서 OAuth2RestTeamplte 를 이용해서 access token을 얻어온다는 https://git.io/fjquP 에서 context에 저장한다. 

Posted by dev.bistro
분류없음2019.03.14 21:54


Netty를 학습하기 위해서 Debug 레벨로 로그를 보고 싶음.

모든 튜토리얼에서 처음에 나오는 클래스인 ServerBootstrap ( https://git.io/fjeuN ) 를 살펴보면  InternalLoggerFactory 클래스를 이용해서 인스턴스를 획득하는 것을 볼 수 있다. 해당 클래스는 abstract class 이고 다양한 로그 라이브러를 지원하고 있음을 알 수 있다.


그 중에서 slf4j - logback 콤보를 이용하기 위해 아래 디펜던시를 추가한다.


<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
</dependency>


그리고 classpath에 아래와 같은 기본적인 logback.xml 을 설정한다

<?xml version="1.0" encoding="UTF-8" ?>
<configuration>
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
            <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36}                      - %msg%n</pattern>
</encoder>
</appender>

<root level="DEBUG">
<appender-ref ref="console"/>
</root>
</configuration>


아래와 같은 콘솔 로그를 확인 할 수 있다.

 io.netty.util.internal.logging.InternalLoggerFactory - Using SLF4J as the default logging framework
 io.netty.channel.MultithreadEventLoopGroup - -Dio.netty.eventLoopThreads: 24
 io.netty.util.internal.PlatformDependent0 - -Dio.netty.noUnsafe: false
 io.netty.util.internal.PlatformDependent0 - Java version: 8
 io.netty.util.internal.PlatformDependent0 - sun.misc.Unsafe.theUnsafe: available
 io.netty.util.internal.PlatformDependent0 - sun.misc.Unsafe.copyMemory: available
 io.netty.util.internal.PlatformDependent0 - java.nio.Buffer.address: available
 io.netty.util.internal.PlatformDependent0 - direct buffer constructor: available
 io.netty.util.internal.PlatformDependent0 - java.nio.Bits.unaligned: available, true
 io.netty.util.internal.PlatformDependent0 - jdk.internal.misc.Unsafe.allocateUninitializedArray(int): unavailable prior to Java9
 io.netty.util.internal.PlatformDependent0 - java.nio.DirectByteBuffer.(long, int): available
 io.netty.util.internal.PlatformDependent - sun.misc.Unsafe: available
 io.netty.util.internal.PlatformDependent - -Dio.netty.tmpdir: /var/folders/sr/grtv_wmn3wj092488tqh7slr0000gn/T (java.io.tmpdir)
 io.netty.util.internal.PlatformDependent - -Dio.netty.bitMode: 64 (sun.arch.data.model)
 io.netty.util.internal.PlatformDependent - -Dio.netty.noPreferDirect: false
 io.netty.util.internal.PlatformDependent - -Dio.netty.maxDirectMemory: 3817865216 bytes
 io.netty.util.internal.PlatformDependent - -Dio.netty.uninitializedArrayAllocationThreshold: -1
 io.netty.util.internal.CleanerJava6 - java.nio.ByteBuffer.cleaner(): available
 io.netty.channel.nio.NioEventLoop - -Dio.netty.noKeySetOptimization: false
 io.netty.channel.nio.NioEventLoop - -Dio.netty.selectorAutoRebuildThreshold: 512
 io.netty.util.internal.PlatformDependent - org.jctools-core.MpscChunkedArrayQueue: available
 io.netty.channel.DefaultChannelId - -Dio.netty.processId: 78164 (auto-detected)
 io.netty.util.NetUtil - -Djava.net.preferIPv4Stack: false
 io.netty.util.NetUtil - -Djava.net.preferIPv6Addresses: false
 io.netty.util.NetUtil - Loopback interface: lo0 (lo0, 0:0:0:0:0:0:0:1%lo0)
 io.netty.util.NetUtil - Failed to get SOMAXCONN from sysctl and file /proc/sys/net/core/somaxconn. Default: 128
 io.netty.channel.DefaultChannelId - -Dio.netty.machineId: xx:1c:xx:ff:fe:00:00:09 (auto-detected)
 io.netty.util.ResourceLeakDetector - -Dio.netty.leakDetection.level: simple
 io.netty.util.ResourceLeakDetector - -Dio.netty.leakDetection.maxRecords: 4
 io.netty.buffer.PooledByteBufAllocator - -Dio.netty.allocator.numHeapArenas: 24
 io.netty.buffer.PooledByteBufAllocator - -Dio.netty.allocator.numDirectArenas: 24
 io.netty.buffer.PooledByteBufAllocator - -Dio.netty.allocator.pageSize: 8192
 io.netty.buffer.PooledByteBufAllocator - -Dio.netty.allocator.maxOrder: 11
 io.netty.buffer.PooledByteBufAllocator - -Dio.netty.allocator.chunkSize: 16777216
 io.netty.buffer.PooledByteBufAllocator - -Dio.netty.allocator.tinyCacheSize: 512
 io.netty.buffer.PooledByteBufAllocator - -Dio.netty.allocator.smallCacheSize: 256
 io.netty.buffer.PooledByteBufAllocator - -Dio.netty.allocator.normalCacheSize: 64
 io.netty.buffer.PooledByteBufAllocator - -Dio.netty.allocator.maxCachedBufferCapacity: 32768
 io.netty.buffer.PooledByteBufAllocator - -Dio.netty.allocator.cacheTrimInterval: 8192
 io.netty.buffer.PooledByteBufAllocator - -Dio.netty.allocator.useCacheForAllThreads: true
 io.netty.buffer.ByteBufUtil - -Dio.netty.allocator.type: pooled
 io.netty.buffer.ByteBufUtil - -Dio.netty.threadLocalDirectBufferSize: 65536
 io.netty.buffer.ByteBufUtil - -Dio.netty.maxThreadLocalCharBufferSize: 16384


1라인 : slf4j 를 로깅 프레임웍으로 쓰고 있는 것을 확인 
2라인 : 내 맥북의 사용가능 CPU가 12개 여서 24 ( https://git.io/fjez0 )


주의) 혹시나 java.lang.ClassNotFoundException: jdk.internal.misc.Unsafe 오류가 보인다면 Netty 4.11 을 사용하고 있는지 확인하고 4.12+ 로 버전 변경 한다 ( https://github.com/netty/netty/issues/6901 ) 


Posted by dev.bistro
TAG logback, Netty