SpringBootとTogglzの側面

1。概要

このチュートリアルでは、TogglzライブラリをSpringBootアプリケーションで使用する方法を見ていきます。

2. Togglz

Togglzのライブラリは、実装の提供を切り替え機能デザインパターンを。このパターンは、アプリケーションの実行時に、トグルに基づいて特定の機能が有効になっているかどうかを判断できるメカニズムを持つことを意味します。

実行時に機能を無効にすることは、まだ完了していない新機能での作業、一部のユーザーのみに機能へのアクセスを許可したい、A / Bテストの実行など、さまざまな状況で役立つ場合があります。

次のセクションでは、機能名を提供するアノテーションでメソッドをインターセプトするアスペクトを作成し、機能が有効かどうかに応じてメソッドの実行を続行するかどうかを決定します。

3.Mavenの依存関係

Spring Bootの依存関係に加えて、TogglzライブラリはSpring Boot Starterjarを提供します。

 org.springframework.boot spring-boot-starter-parent 2.0.1.RELEASE   org.togglz togglz-spring-boot-starter 2.4.1  org.togglz togglz-spring-security 2.4.1    org.springframework.boot spring-boot-starter-web   org.springframework.boot spring-boot-starter-data-jpa   org.springframework.boot spring-boot-starter-test   com.h2database h2 1.4.194 

togglz-spring-boot-starter、togglz-spring-security、spring-boot-starter-web、spring-boot-starter-data-jpa、spring-boot-starter-test、h2の最新バージョンはMavenからダウンロードできます。中央。

4.Togglz構成

togglzスプリング・ブート・スターターライブラリは、必要に応じて豆作成するための自動設定が含まれているのFeatureManagerを。提供する必要がある唯一のBeanは、featureProviderBeanです。

まず、機能インターフェイスを実装し、機能名のリストを含む列挙型を作成しましょう。

public enum MyFeatures implements Feature { @Label("Employee Management Feature") EMPLOYEE_MANAGEMENT_FEATURE; public boolean isActive() { return FeatureContext.getFeatureManager().isActive(this); } }

列挙型は、特定の機能が有効になっているかどうかを確認するisActive()というメソッドも定義します。

次に、SpringBoot構成クラスでタイプEnumBasedFeatureProviderのBeanを定義できます。

@Configuration public class ToggleConfiguration { @Bean public FeatureProvider featureProvider() { return new EnumBasedFeatureProvider(MyFeatures.class); } }

5.アスペクトの作成

次に、カスタムのAssociatedFeatureアノテーションをインターセプトし、アノテーションパラメータで提供される機能をチェックして、アクティブかどうかを判断するアスペクトを作成します。

@Aspect @Component public class FeaturesAspect { private static final Logger LOG = Logger.getLogger(FeaturesAspect.class); @Around( "@within(featureAssociation) || @annotation(featureAssociation)" ) public Object checkAspect(ProceedingJoinPoint joinPoint, FeatureAssociation featureAssociation) throws Throwable { if (featureAssociation.value().isActive()) { return joinPoint.proceed(); } else { LOG.info( "Feature " + featureAssociation.value().name() + " is not enabled!"); return null; } } }

MyFeatures列挙型のvalue()パラメーターを持つFeatureAssociationと呼ばれるカスタムアノテーションも定義しましょう。

@Retention(RetentionPolicy.RUNTIME) @Target({ ElementType.METHOD, ElementType.TYPE }) public @interface FeatureAssociation { MyFeatures value(); }

機能がアクティブな場合、アスペクトはメソッドの実行を続行します。そうでない場合は、メソッドコードを実行せずにメッセージをログに記録します。

6.機能のアクティブ化

Togglzの機能は、アクティブまたは非アクティブのいずれかになります。この動作は、有効フラグとオプションでアクティブ化戦略によって制御されます。

有効フラグをtrueに設定するには、列挙値定義で@EnabledByDefaultアノテーションを使用できます。

Togglzライブラリは、特定の条件に基づいて機能が有効になっているかどうかを判断するために使用できるさまざまなアクティベーション戦略も提供します。

この例では、Systemプロパティの値に基づいて機能の状態を評価するEMPLOYEE_MANAGEMENT_FEATUREにSystemPropertyActivationStrategyを使用してみましょう。必要なプロパティ名と値は、@ ActivationParameterアノテーションを使用して指定できます。

public enum MyFeatures implements Feature { @Label("Employee Management Feature") @EnabledByDefault @DefaultActivationStrategy(id = SystemPropertyActivationStrategy.ID, parameters = { @ActivationParameter( name = SystemPropertyActivationStrategy.PARAM_PROPERTY_NAME, value = "employee.feature"), @ActivationParameter( name = SystemPropertyActivationStrategy.PARAM_PROPERTY_VALUE, value = "true") }) EMPLOYEE_MANAGEMENT_FEATURE; //... }

employee.featureプロパティの値がtrueの場合にのみ、機能を有効にするように設定しました。

Togglzライブラリによって提供される他のタイプのアクティベーション戦略は次のとおりです。

  • UsernameActivationStrategy – allows the feature to be active for a specified list of users
  • UserRoleActivationStrategy – the current user's role is used to determine the state of a feature
  • ReleaseDateActivationStrategy – automatically activates a feature at a certain date and time
  • GradualActivationStrategy – enables a feature for a specified percentage of users
  • ScriptEngineActivationStrategy – allows the use of a custom script written in a language supported by the ScriptEngine of the JVM to determine whether a feature is active or not
  • ServerIpActivationStrategy – a feature is enabled based on IP addresses of the server

7. Testing the Aspect

7.1. Example Application

To see our aspect in action, let's create a simple example that contains a feature for managing the employees of an organization.

As this feature will be developed, we can add methods and classes annotated with our @AssociatedFeature annotation with a value of EMPLOYEE_MANAGEMENT_FEATURE. This ensures that they will only be accessible if the feature is active.

First, let's define an Employee entity class and repository based on Spring Data:

@Entity public class Employee { @Id private long id; private double salary; // standard constructor, getters, setters }
public interface EmployeeRepository extends CrudRepository{ }

Next, let's add an EmployeeService with a method to increase an employee's salary. We will add the @AssociatedFeature annotation to the method with a parameter of EMPLOYEE_MANAGEMENT_FEATURE:

@Service public class SalaryService { @Autowired EmployeeRepository employeeRepository; @FeatureAssociation(value = MyFeatures.EMPLOYEE_MANAGEMENT_FEATURE) public void increaseSalary(long id) { Employee employee = employeeRepository.findById(id).orElse(null); employee.setSalary(employee.getSalary() + employee.getSalary() * 0.1); employeeRepository.save(employee); } } 

このメソッドは、テストのために呼び出す/ increaseSalaryエンドポイントから呼び出されます。

@Controller public class SalaryController { @Autowired SalaryService salaryService; @PostMapping("/increaseSalary") @ResponseBody public void increaseSalary(@RequestParam long id) { salaryService.increaseSalary(id); } }

7.2。JUnitテスト

まず、employee.featureプロパティをfalseに設定した後、POSTマッピングを呼び出すテストを追加しましょう。この場合、機能はアクティブであってはならず、従業員の給与の値は変更されるべきではありません。

@Test public void givenFeaturePropertyFalse_whenIncreaseSalary_thenNoIncrease() throws Exception { Employee emp = new Employee(1, 2000); employeeRepository.save(emp); System.setProperty("employee.feature", "false"); mockMvc.perform(post("/increaseSalary") .param("id", emp.getId() + "")) .andExpect(status().is(200)); emp = employeeRepository.findOne(1L); assertEquals("salary incorrect", 2000, emp.getSalary(), 0.5); }

次に、プロパティをtrueに設定した後に呼び出しを実行するテストを追加しましょう。この場合、給与の値を増やす必要があります。

@Test public void givenFeaturePropertyTrue_whenIncreaseSalary_thenIncrease() throws Exception { Employee emp = new Employee(1, 2000); employeeRepository.save(emp); System.setProperty("employee.feature", "true"); mockMvc.perform(post("/increaseSalary") .param("id", emp.getId() + "")) .andExpect(status().is(200)); emp = employeeRepository.findById(1L).orElse(null); assertEquals("salary incorrect", 2200, emp.getSalary(), 0.5); }

8.結論

このチュートリアルでは、アスペクトを使用してTogglzライブラリをSpringBootと統合する方法を示しました。

例の完全なソースコードはGitHubにあります。