eclipes4j's 개발은 언제나 즐겁다.

죽음이란 무엇인가, 얼터드 카본

후비고!

'죽음이란 무엇인가' 라는 책을 보면서 육체,정신,영혼등등에 대한 정말 죽음은??을 고민하고 있을때 무심코 넷플릭스에서 보게된 미드 '얼터드 카본' ..책과 과 드라마 모두 죽음에 대한 의문를 던지고 시작한다.


물론 책보다는 '얼터드 카본'이 훨씬 재밌고, 즐겁게 볼 수 있다.~


책은 이제 반을 넘어서 보고 있는 중이니 내용은 나중에 정리해보고, 

얼터드 카본을 보면 육체는 그저 인간에 의해 만들어지는 물질이고 기억저장소에 저장되어 있는 기억이 그 인간임을 나타낸다. 그렇기에 기억저장소가 파괴되면 정말 죽음을 맞이하는 상태. 근데 얼터드 카본의 시작은 기억저장소가 파괴된 부유층 인간 하나가 자신이 왜 죽었는지 밝혀내려고 하는 것에서 시작된다.


아니!!!? 기억저장소가 파괴되면 죽은거라며???


아.. 그 부유층 인간은 너무나 부유한 나머지 자신의 기억을 위성어딘가에 주기적으로 백업을 해 놓는단다.( 이런 개발자 스러운.! ㅡㅡㅋ)


흥미롭게 생각해볼 것이..( 죽음이란 무엇인가와 살짝 비교해 생각해서. )

정말 그 기억은 그사람을 나타내는 것인가? 기억 저장소는 우리가 얘기하는 정신,영혼이 될 수 있는가?? 백업된 기억은 또다른 자아인가?

백업된 기억을 다른 육체에 심으면 그게 내가 알던 사람인가? 기억을 누군가 해킹해서 조작하면 그 기억은 또 누구가 되는가? 허허...

이부분은 조금 깊게 들어가기 위해, 책을 끝가지 읽어보고 결정을 내려야 겠다. 휘릭~


또 하나 이 얼터드 카본에서 더욱 흥미로운것은, 

수백년을 살아온(?) 부유층들의 일과들이다. 난 이 부유층들을 보면서 한가지 의문이 생기게 되더라.. 과연 내가 저렇게 수백년의 기억을 가지고 육체만 바꿔가면서 살면 내가 가지고 있던 사회성과 인간성이 유지될 수 있을까?하는.. 그 질문이 계속 머리속에 멤돌더니 결론은 그냥 내게 주어진 인생을 최대한 즐겁게 누리며 살다 가자!로 떨어졌다. 

그래 억지로 오래살아 봐야 별거 없..ㅎㅎ



간만에 재밌게 보고있는 책과 미드였으.




  


'얼터드 카본 원작 : http://www.yes24.com/24/goods/3064975

Java 8 Collection 돌려보기

Programming!

우선 City라는 Dto를 하나 만들어 둔다.

public class City {

    

    private Long id;

    

    private String name;

    

    private String country;

    

    public City(Long id, String name, String country) {

        this.id = id;

        this.name = name;

        this.country = country;

    }


...getter/setter...

}



해당 City를 List로 만든 후, 여러가지를 해볼 수 있다. 

가령 cities의 특정 property를 키로 두고 List<City>를 가지는 맵을 만든다던지 하는.. 예제를 직접 만들어 보자.


public class CollectionExample {


    private static List<City> getCities(){

        List<City> cities = new ArrayList<>();

        cities.add(new City(1L, "서울", "대한민국"));

        cities.add(new City(2L, "대구", "대한민국"));

        cities.add(new City(3L, "Newyork", "미국"));

        cities.add(new City(4L, "경기도", "대한민국"));

        cities.add(new City(5L, "대전", "대한민국"));

        cities.add(new City(6L, "LA", "미국"));

        return cities;

    }


    public static void main(String[] args){

        // Key 는 CityName이 되며, City Object를 Value로 가지는 Map을 만든다.

        Map<String, City> example1 = getCities().stream().collect(Collectors.toMap(City::getName, Function.identity()));

        

        // Key 는 Country가 되며, List<City>를 Value로 가지는 Map을 만든다.

        Map<String, List<City>> example2 = getCities().stream().collect(Collectors.groupingBy(City::getCountry, Collectors.toList()));

        

        // Key 는 Country가 되며, List<String:CityName>를 Value로 가지는 Map을 만든다.

        Map<String, List<String>> example3 = getCities().stream().collect(Collectors.groupingBy(City::getCountry, Collectors.mapping(City::getName, Collectors.toList())));

    }

}


위와 같은 예제를 좀 더 확장할 수 있을것이다. 가령 미국을 뺀 '대한민국'만으로 구성한다던지..

Map<String, List<City>> example2_2 = getCities().stream().filter(o -> !"미국".equals(o.getCountry())).collect(Collectors.groupingBy(City::getCountry, Collectors.toList()));

주) .filter 내의 "o -> !"미국".equals(o.getCountry())" 이런 부분은 별도의 Function으로 빼도 좋다.


음.. 전체적으로 Collection을 람다 형식으로 사용하고는 있지만, 계속 써보고 분석해봐야지만 늘어나는거 같다. 간혹 나도모르게 for 를 돌리는 경우가 많아서.



JPA Converter 를 Generics로 처리하기...

Programming!

를 하려고 했으나.. 가령.


@Entity

@Table(catalog = XXX.CCC, name = "hotel")

public class Hotel {

...

    @Column(name = "spec")

    @Convert(converter = HotelSpecJsonConverter.class)

    private HotelSpec spec;


위 spec 컬럼은 json 으로 저장되어 있다. 해서 HotelSpecJsonConverter 를 지정해서 사용했으나.. 

다른 테이블에도 json으로 저장되어 있는 컬럼들이 여기저기 많아서 그때마다 AttributeConverter 를 구현하는 건 좀 무리라는 생각.



제너릭하게 이런 형태를 원했으나 @Convert를 지정할때 타입을 보낼 수 없으니.

Fail Source~

public class HotelSpecJsonConverter<T> implements AttributeConverter<T, String>{



Success Source~

해서 AttributeConverter 를 확장한 인터페이스 하나 더 만들고.

public interface ColumnJsonConverter<T> extends AttributeConverter<T, String> {


    @Override

    default String convertToDatabaseColumn(T t) {

        ...

    }


    @Override

    default T convertToEntityAttribute(String v) {

        ...

    }

}



default로 구현 소스 만들어 놓고 이놈을 다시 Converter로...콜록.

@Converter(autoApply=true)

public class HotelSpecJsonConverter implements ColumnJsonConverter<HotelSpec>{

....

}


다시 적용.

    @Column(name = "spec")

    @Convert(converter = HotelSpecJsonConverter.class)

    private HotelSpec spec;


이렇게 하니 뭐.. 클래스는 늘어나도 구현 소스는 그나마.. 뭐 더 명시적이니 좋다라고 자기위안을 삼아본다.


그나저나... 뭔 테이블에 json 저장이 이렇게 많은지 거기에!!! key가 동적이야...그럼 Map으로 해야 되는데...

거기에!!! 특정 column에 json문구를 like 검색을 하는 곳도 있다.. like '%Text%' ...

엌...

작업 끝난 후에 마이그레이션도 해야되것네.. 허허.



Ubuntu root full space 와 docker

Programming!

갑자기 나의 민트리눅스께서 "/"의 용량이 부족하다고 경고를 때리신다. ( 100% / )


이미지가 쌓였나..?하고 기존대로 "linux-image*"를 모두 지웠는데...

$ sudo dpkg -l "linux-image*"

$ sudo apt remove "linux-image-x.y.z" ( -headers 포함 )



참고로 Image 설정에서 이전 이미지는 가지고 있지 않도록 하자.




여튼 지웠으나.......................고작 6G가 확보. 어어...이게 뭐야?!



해서, 디렉토리 용량 리스트 뽑아보니 "/var/lib/docker : 73G" 우어어어어어어어.. 


얼릉 볼륨을 지워버림. 아~ 뭐든 자주 관리해줘야하는 구나..허허.

$ docker volume prune -f


https://forums.docker.com/t/some-way-to-clean-up-identify-contents-of-var-lib-docker-overlay/30604


https://docs.docker.com/engine/reference/commandline/image_prune/



Spring Boot 1.5 Security 적용

Programming!

신규 플젝에서 Spring Security 를 적용하면서 몇가지 트러블.


@EnableWebSecurity

@Configuration

public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Override

    protected void configure(HttpSecurity httpSecurity) throws Exception {

        httpSecurity.authorizeRequests()

            .antMatchers("/", "/index", "/health").permitAll()

            .antMatchers("/{serviceRoleType}/**").access("@guard.validServiceRoleType(authentication,#serviceRoleType)")

            .antMatchers("/stay/**").authenticated()

            .antMatchers("/gormet/**").authenticated()

            .anyRequest().authenticated()

            .and()

            .formLogin()

            .usernameParameter("username")

            .passwordParameter("password")

            .loginPage("/login")

            .successHandler(successHandler)

            .failureHandler(failureHandler)

            .permitAll()

            .and()

            .logout()

            .permitAll();

        httpSecurity.csrf().disable().exceptionHandling().accessDeniedPage("/403");

...


1.

레퍼런스를 보고 위와 같이 configure 를 Override 해서 돌려보니 Login이 해제되는 현상이 있었다. 아오 뭐가 문제지...하면서 소스를 파고 들어가보니 httpSecurity 의 체인 형태가 좀... 즉 httpSecurity. 를 두번 지정하니 위의 것이 초기화된 문제였다. 아.. 해서 .and() 로 묶어서 해결.

(시파! 어느 사이트의 레퍼런스...)




    @Override

    public void configure(WebSecurity webSecurity) throws Exception {

        webSecurity.ignoring().antMatchers("/static/**", "/resources/**");

    }


2.

이 주소와 thymeleaf 와 <img src=" ... 주소처리. 아씨... 이것도 햇갈려서 죽는줄 알았네..




    @Override

    protected void configure(AuthenticationManagerBuilder auth) throws Exception {

        auth.userDetailsService(userDetailsService).passwordEncoder(pelicanPasswordEncoder);

    }


3.

별도의 password 정책이 있다면 passwordEncoder 추가.