我偶然发现了功能标记的概念,以及一个名为Togglz的流行的开源Java库,它引用了Martin Fowler博客文章:
基本思想是拥有一个配置文件,为您拥有的各种功能定义一系列切换.然后,正在运行的应用程序使用这些切换来决定是否显示新功能.
但对我来说,这听起来像授权:用户是否有权查看此内容?
例如,用户是否应该能够看到FizzBuzz菜单?
在Togglz中,我可能会像这样执行此检查:
if(MyFeatures.ShowFizzBuzz.isActive()) {
// Show the FizzBuzz menu.
}
Run Code Online (Sandbox Code Playgroud)
比方说,Apache Shiro,我可以做同样的事情:
ShowFizzBuzzPermission showFizzBuzz = new ShowFizzBuzzPermission();
if(currentUser.isPermitted(showFizzBuzz) {
// Show the FizzBuzz menu.
}
Run Code Online (Sandbox Code Playgroud)
再次,功能标记只是感觉像为基于角色或允许检查其完全相同的问题.
我确定我错了,但我不知道怎么回事.所以我问:功能标记与授权和角色/权限检查有何不同,具体用例是什么类型的例子?换句话说:我何时应该使用授权/角色/权限检查,何时应该使用功能标志?
将 Togglz 与我的 Spring MVC 应用程序集成时出现异常。
例外
java.lang.IllegalStateException: Could not find the FeatureManager. For web applications please verify that the TogglzFilter starts up correctly. In other deployment scenarios you will typically have to implement a FeatureManagerProvider as described in the 'Advanced Configuration' chapter of the documentation.
org.togglz.core.context.FeatureContext.getFeatureManager(FeatureContext.java:53)
org.togglz.core.manager.LazyResolvingFeatureManager.getDelegate(LazyResolvingFeatureManager.java:24)
org.togglz.core.manager.LazyResolvingFeatureManager.getCurrentFeatureUser(LazyResolvingFeatureManager.java:49)
org.togglz.console.TogglzConsoleServlet.isFeatureAdmin(TogglzConsoleServlet.java:75)
org.togglz.console.TogglzConsoleServlet.service(TogglzConsoleServlet.java:62)
javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
org.togglz.servlet.TogglzFilter.doFilter(TogglzFilter.java:100)
Run Code Online (Sandbox Code Playgroud)
以下依赖项在 maven 中定义 -
<dependency>
<groupId>org.togglz</groupId>
<artifactId>togglz-core</artifactId>
<version>2.3.0.Final</version>
</dependency>
<!-- Spring integration (optional) -->
<dependency>
<groupId>org.togglz</groupId>
<artifactId>togglz-spring-web</artifactId>
<version>2.3.0.Final</version>
</dependency>
<!-- Togglz Admin Console -->
<dependency>
<groupId>org.togglz</groupId> …Run Code Online (Sandbox Code Playgroud) 我有带有几个(REST)端点的spring控制器.我想提出这个控制器的多个实例,其中每个实例都有几个端点有选择地启用/禁用.
根据我到目前为止的阅读,togglz提供了功能翻转,但它不启用/禁用REST端点(togglz提供API,以便调用者代码可以检查是否启用了功能); ff4j似乎是另一种选择,但是如果它可以启用/禁用REST端点,则从文档中不是很明显
我阅读了线程功能切换Java注释,但它是一个更长的实现.是否有任何软件包可用于指定需要在配置文件中启用/禁用的端点,并在REST端点上使用注释来禁用/启用它们(这样我的方法中的逻辑保持不变并最小化测试)
我的 spring-boot+jersey 应用程序已集成 togglz。我添加了以下依赖项,如下所示。
// togglz
compile('org.togglz:togglz-servlet:'+togglzVersion)
compile('org.togglz:togglz-cdi:'+togglzVersion)
compile('javax.enterprise:cdi-api:2.0-EDR1')
compile('org.togglz:togglz-spring-web:'+togglzVersion)
compile("org.togglz:togglz-spring-boot-starter:"+togglzVersion)
compile("org.togglz:togglz-console:"+togglzVersion)
compile("org.togglz:togglz-spring-security:"+togglzVersion)
compile("com.github.heneke.thymeleaf:thymeleaf-extras-togglz:1.0.1.RELEASE")
Run Code Online (Sandbox Code Playgroud)
在我的引导类中,我添加了以下代码:
@Bean
public FeatureProvider featureProvider() {
return new EnumBasedFeatureProvider(AppFeatures.class);
}
Run Code Online (Sandbox Code Playgroud)
启动应用程序后,我可以从此链接看到 json 数据:http://localhost:8080/togglz。但我无法访问http://localhost:8080/togglz-console。我收到“无法加载资源:服务器响应状态为 403(禁止)”错误。
我可以在我的日志文件中看到以下日志,但无法访问 togglz-console/*。
o.s.b.c.e.ServletRegistrationBean : Mapping servlet: 'togglzConsoleServlet' to [/togglz-console/*]
Run Code Online (Sandbox Code Playgroud)
下面是我的 togglz 属性文件:
# togglz
togglz:
feature-enums: com.cooltoo.backend.features.AppFeatures # Comma-separated list of fully-qualified feature enum class names.
features:
SMS_CODE: false
console:
enabled: true # Enable admin console.
path: /togglz-console # The path of the admin console when enabled.
Run Code Online (Sandbox Code Playgroud)
我在这里错过了什么?
我正在尝试在 Spring Boot 上运行 Togglz 控制台,但我在屏幕上看到以下内容:
(type=Forbidden, status=403). You are not allowed to access the Togglz Console.
Run Code Online (Sandbox Code Playgroud)
我刚刚注意到很多人都有同样的问题,并且一些解决方案对他们有效。但我不明白我做错了什么。
这是我的代码:
我的功能
public enum MyFeatures implements Feature {
@EnabledByDefault
@Label("The list of employees can be displayed")
SHOW_LIST,
@Label("Second Feature")
FEATURE_TWO;
public boolean isActive() {
return FeatureContext.getFeatureManager().isActive(this);
}
@Bean
public FeatureProvider featureProvider() {
return new EnumBasedFeatureProvider(MyFeatures.class);
}}
Run Code Online (Sandbox Code Playgroud)
我的Togglz配置
public class MyTogglzConfiguration implements TogglzConfig {
@Override
public Class<? extends Feature> getFeatureClass() {
return null;
}
@Override
public StateRepository getStateRepository() {
return null;
}
@Override …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用@Configuration bean而不是XML来实现Togglz和Spring.我不确定如何配置Configuration bean的返回类型.例如:
@Configuration
public class SystemClockConfig {
@Bean
public SystemClock plainSystemClock() {
return new PlainSystemClock();
}
@Bean
public SystemClock awesomeSystemClock() {
return new AwesomeSystemClock();
}
@Bean
public FeatureProxyFactoryBean systemClock() {
FeatureProxyFactoryBean proxyFactoryBean = new FeatureProxyFactoryBean();
proxyFactoryBean.setActive(awesomeSystemClock());
proxyFactoryBean.setInactive(plainSystemClock());
proxyFactoryBean.setFeature(Features.AWESOME_SYSTEM_CLOCK.name());
proxyFactoryBean.setProxyType(SystemClock.class);
return proxyFactoryBean;
}
}
Run Code Online (Sandbox Code Playgroud)
该systemClock方法返回一个FeatureProxyFactoryBean但该bean的客户端需要一个SystemClock.当然,编译器对此感到不满.
我想它在使用XML配置时才有效.使用配置bean时应该如何处理它?
从版本2.0.0开始,Togglz提供激活策略以使用功能.例如,您可以连接应启用该功能的服务器IP地址列表.但是,这些策略如何实际附加到功能上?我只看到我可以在Togglz控制台中更改策略,甚至可以在数据库中手动编辑数据.
我正在寻找的是一些非常类似的默认机制@EnabledByDefault.我可以实现一个自定义状态存储库,它甚至可以查找注释,但我怀疑这个解决方案是开箱即用的.
我们正在使用Togglz在项目中打开和关闭功能。以下TogglzFeature枚举正在实现org.togglz.core.Feature接口
public enum TogglzFeature implements Feature {
@EnabledByDefault
@Label("Current XSLT code")
FEATURE_XSLT,
@Label("NEW JAXB code")
FEATURE_JAXB;
public boolean isActive() {
FeatureManager manager = FeatureContext.getFeatureManager();
return manager.isActive(this);
}
}
Run Code Online (Sandbox Code Playgroud)
然后要测试的一种方法(例如mut_1(params))是检查枚举,例如
if(TogglzFeature.FEATURE_JAXB.isActive()) { dothings();}
Run Code Online (Sandbox Code Playgroud)
注意,togglz功能不在mut_1的参数中。mut_1只是在运行时从上下文中拾取它。
那么让mut_1()知道我要TogglzFeature.FEATURE_JAXB.isActive()返回true 的最佳方法是什么?
我尝试了Mockito / PowerMock
@RunWith(PowerMockRunner.class)
@PrepareForTest({TogglzFeature.class})
public class myTestClass {
//private members and set up
@Test
public void testTogglz(){
PowerMockito.mockStatic(TogglzFeature.class);
BDDMockito.given(TogglzFeature.FEATURE_JAXB.isActive()).willReturn(true);
//execution and verification
}
}
Run Code Online (Sandbox Code Playgroud)
系统会将所有这些吐给我
java.lang.VerifyError: Inconsistent stackmap frames at branch target 128
Exception Details:
Location:
com/lmig/ci/rate/togglz/TogglzFeature.values()[Lcom/lmig/ci/rate/togglz/TogglzFeature; @128: ldc
Reason: …Run Code Online (Sandbox Code Playgroud) 如果我在单元测试中声明TogglzRule它必须是公共的,否则会抛出异常: java.lang.Exception: The @Rule 'togglzRule' must be public.
我以前宣称成员私有,为什么这不可能?
togglz ×9
java ×4
spring ×3
spring-boot ×2
enums ×1
ff4j ×1
jersey ×1
security ×1
spring-mvc ×1
unit-testing ×1