2016-12-12 1 views
0

私はプロジェクトで依存関係注入を行うためにSpringを使用していますが、私はプロダクション環境とユーザーログインに従ってテストを変更する必要があります。 (生産/テストにchecboxがあります)プロダクションとテストの間のSpring Envirormentの変更方法は、ユーザーの選択に従ってログインしますか?

各ユーザーは、本番データベースまたはテストデータベースのどちらかを選択することができます。

@Profileについて読んでいますが、各プロファイルはサーバーまたはアプリケーションの実行時に定義されていますが、ログイン後に変更する必要があります。

どうすればいいですか?それは春で可能ですか?

これは、問題を説明するために、いくつかのクラスである:

applicationContext.xmlを

<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://www.springframework.org/schema/beans" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:context="http://www.springframework.org/schema/context" 
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans.xsd 
    http://www.springframework.org/schema/context 
    http://www.springframework.org/schema/context/spring-context-4.0.xsd"> 

    <bean class="br.com.cpb.gsa.config.AppConfig" /> 
    <context:component-scan base-package="br.com.cpb.gsa" /> 

</beans> 

のAppConfigクラス

@Configuration 
@EnableVaadin 
public class AppConfig { 

    private DataSource dataSource; 

    @Profile("production") 
    @Bean(name = "dataSource") 
    public DataSource datasourceProdction() { 
     DriverManagerDataSource ds = new DriverManagerDataSource(); 
     ds.setDriverClassName("net.sourceforge.jtds.jdbc.Driver"); 
     ds.setUrl("jdbc:jtds:sqlserver://ip:1433;databaseName=myDataBase"); 
     ds.setUsername("user"); 
     ds.setPassword("pass"); 

     return this.dataSource = ds; 
    } 

    @Profile("test") 
    @Bean(name = "dataSource") 
    public DataSource datasourceProdction() { 
     DriverManagerDataSource ds = new DriverManagerDataSource(); 
     ds.setDriverClassName("net.sourceforge.jtds.jdbc.Driver"); 
     ds.setUrl("jdbc:jtds:sqlserver://ip:1433;databaseName=myDataBaseTest"); 
     ds.setUsername("user"); 
     ds.setPassword("pass"); 

     return this.dataSource = ds; 
    } 

    public DataSource getDataSource() { 
     return dataSource; 
    } 

    public void setDataSource(DataSource dataSource) { 
     this.dataSource = dataSource; 
    } 

} 

GSAUI - マイVaadinクラス

@Theme("gsaTheme") 
@SpringUI 
@SpringViewDisplay 
public class GSAUI extends UI { 

    private static final long serialVersionUID = -4276841722171307964L; 

    public static final String VIEW_NAME = "mainView"; 

    @Autowired 
    ApplicationContext applicationContext; 

    @WebListener 
    public static class MyContextLoaderListener extends ContextLoaderListener { 
    } 

    ..... 

} 

D AO - UserDAO

@Repository("userDAO") 
public class UserDAOImpl implements UserDAO { 

    @Autowired 
    private DataSource dataSource; 

    @Override 
    public Usuario getAuthenticatedUser(String login) { 

     try (Connection conn = dataSource.getConnection()){ 

      //... sample code, just for explanation ... 
      Usuario user = new Usuario(); 
      user.setLogin("test"); 

      return user; 

     } catch (SQLException e) { 
      throw new RuntimeException(e); 
     } 
    } 
} 

サービス - LoginService

@Service("loginService") 
public class LoginServiceImpl implements LoginService, Serializable { 

    private static final long serialVersionUID = 4014652022146807624L; 

    @Autowired 
    private UserDAO userDAO; 

    public Usuario doLogin(Usuario user){ 

     if ((user == null) ||     (JavaUtil.isNull(user.getLogin(),"").trim().length() == 0)){ 
     throw new RuntimeException(Constant.LOGIN_OR_PASSWORD_NOT_PROVIDED); 
     } 

     //UsuarioDAO dao = (UsuarioDAO)  applicationContext.getBean("usuarioDAO"); 
     Usuario savedUser = userDAO.getAuthenticatedUser(user.getLogin()); 

     if ((savedUser == null) || (!savedUser.getSenha().equals(user.getSenha()))){ 
      throw new RuntimeException(Constant.INVALID_USER_OR_PASSWORD); 
     } 

     return user; 
    } 

} 

LoginView - ユーザーのログインおよび

@SpringView(name = LoginView.VIEW_NAME) 
public class LoginView extends LoginDesign implements View { 

    private static final long serialVersionUID = 1L; 
    public static final String VIEW_NAME = "loginView"; 

    public LoginView() { 
     setSizeFull(); 

     btnEnter.setClickShortcut(KeyCode.ENTER); 
     btnEnter.addClickListener(e -> this.login()); 
    } 

    public void login() { 
     Usuario user = new Usuario(); 

     user.setLogin(login.getValue()); 
     user.setSenha(senha.getValue()); 

     /******** Here i would like to define the profile, but the context  already have been loaded ********/ 
     ConfigurableEnvironment env = (ConfigurableEnvironment) ((GSAUI)getUI()).getApplicationContext().getEnvironment(); 

     if (user.getSenha() == "spedtjob"){ 
      env.setActiveProfiles("producao"); 
     }else{ 
      env.setActiveProfiles("test"); 
     user.setSenha("spedtjob"); 
     } 

     LoginService loginService = (LoginService) ((GSAUI)getUI()).getApplicationContext().getBean(LoginService.class); 
     Usuario loggedUser = loginService.doLogin(user); 

     System.out.println(loggedUser.getLogin()); 
     getUI().removeStyleName("loginview"); 

     ((GSAUI)getUI()).setUser(loggedUser); 

     getUI().getNavigator().navigateTo(((GSAUI)getUI()).getRedirectPage());  
     ((Window)getParent()).close(); 
    } 


} 

私はこのアプローチをテストしていたが動作しませんを使用するプロファイルを決定します。 私は助けていただければ幸いです。

+2

*なぜ*別々に起動しますか?ステージングコードに厄介なバグがあり、プログラム的に切り替えている場合は、ステージング環境を完全に排除した場合と同じように、運用システムが危険にさらされます。 – chrylis

+0

こんにちは@chrylis!私はリスクを理解していますが、同じシステムを使用する15社の会社があり、15台のシステムを導入すると複雑になります。 – Weles

答えて

1

私が答えを与える前に、テストシステムとプロダクションシステムを完全に別々に実行するようアドバイスしたいと思います。私は、共通のログインページだけを作成し、ユーザーにログインさせてから、ユーザーのシステム選択。

しかし、あなたは、単一のJVMでのテスト/本番を持つようにしたい場合は、私は、「春の豆のスコープが」あなたが探しているものだと思います:http://docs.spring.io/spring/docs/current/spring-framework-reference/html/beans.html#beans-factory-scopes

デフォルトのスコープがあること、を意味し、「シングルトン」でありますアプリケーションの開始時にBeanが作成され、配線されているため、変更するのは非常に困難です。

ユーザAとユーザBで異なるDataSource Beanを使用する場合は、DataSource Beanの「セッション」スコープ(多分「リクエスト」スコープ)を使用する必要があります。 @AutowiredをDataSourceに使用すると、各セッションごとに実際のBeanが作成されます - つまり、ログインしている各ユーザーがどのBeanを使用するかを制御できます。

+0

私はvaadinで春を使用していますが、何らかの理由でセッションや要求がありません。ありがとう! – Weles

1

あなたは何らかの形で(データベース内、Bean内など)ユーザーの選択肢を保存し、両方のデータベースへの接続を持つことができます。データベースにアクセスするときは、実際にアクセスするデータベースを決定するためのチェックを行います。

各ユーザーに使用するデータベースを決定するための専用のBeanを作成することをお勧めします。

しかし、@chrylisが言ったことを実行し、予算に応じて別々の導入を行うことをお勧めします。コードの複雑さを軽減するだけでなく、すでに指摘されているような問題が発生するのを避けることができます。

+0

こんにちは@Adam Rosiniデータソースが "@Autowire"アノテーションによって注入され、パラメータを渡すことができないため、これを行う方法がわかりません。サンプルはありますか? – Weles

+0

@Weles 2つのデータソース(testDatasource、prodDatasource)を挿入します。 http://stackoverflow.com/questions/30362546/how-to-use-2-or-more-databases-with-springしかし、常に正しいデータソースを使用するように注意する必要があります。それは危険ですが、あなたが本当に望むものなら、私は以下のメソッドを使ってBeanを作成します: 'getDataSourceForUser(...)' – Adam

+0

こんにちは@Adam Rosini!はい、わかった。私はプロファイルのようなオプションを見つけたいと思います。実行時に変更することが可能でした。しかし説明のおかげで。 – Weles

関連する問題