Case 별 상세 설정

다음은 java based 설정의 기본 입니다.

@Configuration
public class FiroConfiguration {
    @Bean
    InitializingBean initializingBean(DirectoryPathPolicy policy) {
        return () -> {
            FiroRegistry.from(firoProperties, policy);
        };
    }
}

이 상태의 설정은 자동으로 구성되므로, 작성할 필요가 없습니다.

이제 이 설정을 바탕으로, 사용자 정의 설정을 해보기 시작하겠습니다.

case #1 - 기본 저장소를 FTP 로 변경

먼저 FTP 저장소를 사용하기 위해 다음과 같이 yml 파일에 ftp 설정을 추가합니다.

unvus:
  firo:
    directory: 생략
    database: 생략
    ftp:
      host: unvus.com
      port: 21
      username: ftp user name
      password: ftp password

위에서 ftp 설정을 추가한것 만으로, firo 내부에서 자동으로 FtpAdapter 를 구성하게 됩니다.

이제는 LocalAdapterFtpAdapter 모두 사용 할 수 있습니다.

하지만 특별히 FtpAdapter 를 사용하겠다고 선언을 해주어야만 FtpAdapter 가 사용되고, 그렇지 않으면 여전히 LocalAdapter 가 기본 세팅 됩니다.

FiroRegistry.from 메소드를 통해 기본 Adapter 를 FTP 로 변경합니다.

@Configuration
public class FiroConfiguration {
    @Bean
    InitializingBean initializingBean(DirectoryPathPolicy policy) {
        return () -> {
            // 기본 Adapter 를 FtpAdapter 로 변경
            FiroRegistry.from(firoProperties, policy, AdapterType.FTP);
        };
    }
}

이제부터 모든 첨부파일은 FTP 를 통해 전송됩니다.

TIP

대부분의 사이트는 여기까지의 설정만으로 사용 가능합니다.

이제부터 조금더 복잡한 경우를 살펴보도록 하겠습니다.

case #2 - product 모델만 FTP Adapter 사용

기본 설정은 LocalAdapter 으로 하고, product 모델만 FtpAdapter 를 사용 하도록 설정해 봅니다.

product domain 을 수동으로 만들어 줍니다.

@Configuration
public class FiroConfiguration {
    @Bean
    InitializingBean initializingBean(DirectoryPathPolicy policy) {
        return () -> {
            // 기본 설정은 LocalAdapter
            FiroRegistry.from(firoProperties, policy);

            // product domain 추가
            FiroRegistry.add(
                FiroDomain
                    .builder("product")
                    // adapter 를 FtpAdapter 으로 변경
                    .adapter(FiroRegistry.getAdapter(AdapterType.FTP))
                    // ftp 서버의 디렉토리 지정
                    .directoryPathPolicy(new DateDirectoryPathPolicy(
                        DateDirectoryPathPolicy.DATE_SUBDIR_TYPE.YYYY_MM,
                        "/my/ftp/root/dir/attach/dev",
                        "/my/ftp/root/dir/attach/dev/tmp"
                    ))
                    .build()
            );
        };
    }
}

이제부터 모든 domain 및 그 하위 category 은 모두 LocalAdapter 가 적용되고,
product 모델 및 그 하위 category 은 FtpAdapter 를 사용하게 됩니다.

설정 상속

firo 의 domain 과 category 은 상속 개념이 적용 됩니다.
지정하지 않은 모든 domain 은 FiroRegistry 에 등록된 기본 AdapterDirectoryPathPolicy 를 따르게 되고,
지정하지 않은 모든 category 는 자신의 domain 에 등록된 AdapterDirectoryPathPolicy 를 따르게 됩니다.

실시간 자동 구성

configuration 에서 등록하지 않은 domain, category 에 대한 요청이 오면, firo 는 실시간으로 해당 domain 과 category 을 기본 값으로 구성합니다.

case #3 - product 의 primary category 만 FTP 사용

@Configuration
public class FiroConfiguration {
    @Bean
    InitializingBean initializingBean(DirectoryPathPolicy policy) {
        return () -> {
            FiroRegistry.from(firoProperties, policy);
            
            FiroDomain prodDomain = FiroDomain.builder("product").build();
            prodDomain.addCategory(
                FiroCategory
                    .builder(prodDomain, "primary")
                    // adapter 를 FtpAdapter 으로 변경
                    .adapter(FiroRegistry.getAdapter(AdapterType.FTP))
                    // ftp 서버의 디렉토리 지정
                    .directoryPathPolicy(new DateDirectoryPathPolicy(
                        DateDirectoryPathPolicy.DATE_SUBDIR_TYPE.YYYY_MM,
                        "/my/ftp/root/dir/attach/dev",
                        "/my/ftp/root/dir/attach/dev/tmp"
                    ))
            );
            
            FiroRegistry.add(prodDomain);
        };
    }
}

case #4 - 추가 FtpAdapter 사용

yaml 설정에 따르는 기본 FtpAdapter 외에 추가 일부 domain 은 다른 Ftp 서버를 바라봐야 하는 경우입니다.

@Configuration
public class FiroConfiguration {
    @Bean
    InitializingBean initializingBean(FtpRemoteFileTemplate template, DirectoryPathPolicy policy) {
        return () -> {
            // 기본 FtpAdapter 를 전역
            FiroRegistry.from(firoProperties, policy, AdapterType.FTP);

            // product domain 추가
            FiroRegistry.add(
                FiroDomain
                    .builder("product")
                    // 기본 FptAdapter 가 아닌 다른 FtpAdapter 으로 변경
                    .adapter(new FtpAdapter(template))
                    // ftp 서버의 디렉토리 지정
                    .directoryPathPolicy(new DateDirectoryPathPolicy(
                        DateDirectoryPathPolicy.DATE_SUBDIR_TYPE.YYYY_MM,
                        "/my/ftp/root/dir/attach/dev",
                        "/my/ftp/root/dir/attach/dev/tmp"
                    ))
                    .build()
            );
        };
    }

    @Bean
    public DefaultFtpSessionFactory myFtpSessionFactory() {
        DefaultFtpSessionFactory ftpSessionFactory = new DefaultFtpSessionFactory();
        ftpSessionFactory.setHost("my.ftp.com");
        ftpSessionFactory.setPort(21);
        ftpSessionFactory.setUsername("ftpusername");
        ftpSessionFactory.setPassword("ftppassword");
        ftpSessionFactory.setClientMode(PASSIVE_LOCAL_DATA_CONNECTION_MODE);
        return ftpSessionFactory;
    }
  
    @Bean
    public FtpRemoteFileTemplate myFtpTemplate(DefaultFtpSessionFactory myFtpSessionFactory) {
        FtpRemoteFileTemplate template = new FtpRemoteFileTemplate(myFtpSessionFactory);
        return template;
    }
}

case #5 - 보안 설정

첨부파일을 보거나 다운 받을 수 있는 URL 은 예측 가능 하기 때문에,
허용되지 않은 사용자가 접근 하는 것을 막아야 하는 경우에는 다음과 같이 접근 권한을 설정 할 수 있습니다.

@Configuration
public class FiroConfig {
    @Bean
    InitializingBean initializingBean(DirectoryPathPolicy policy) {

        return () -> {
            FiroRegistry.from(firoProperties, policy);

            FiroRegistry.add(
                FiroDomain
                    // 관리자 domain 설정
                    .builder("admin")
                    .secureAccessFunc((request, firoFile) -> {
                        // admin, root 권한이 있으면 접근 허용
                        if(SecurityUtils.hasAnyAuthority("ROLE_ADMIN", "ROLE_ROOT")) {
                            return true;
                        }

                        // 첨부파일의 소유자가 현재 로그인한 사람이면 접근 허용
                        Admin admin = (Admin)SecurityUtils.getCurrentUser();
                        if(firoFile.getCreatedBy().equals(admin.getId())) {
                            return true;
                        }
                        return false;
                    })
                    .build()
            );
        };
    }
}
Ready for more?