本文针对ambari-server v2.6和v2.7之间的源码进行比较,有些功能的实现还是有变化的。
该文仅是在工作中将ambari2.6 二次开发的代码迁移到ambari 2.7上产生变化的一个记录。
1. @ApiModelProperty
2.7版本在 org/apache/ambari/server/controller/目录下的xxxRequest.java和xxxResponse.java文件内新增了@ApiModelProperty注解。
-
@ApiModelProperty(name = RackResourceProvider.ID_PROPERTY)
@ApiModelProperty是Swagger的一个注解,而Swagger是一款目前世界最流行的API管理工具。详情介绍:点击
2. xxxResourceProvider.java的构造方法的改变
路径:org/apache/ambari/server/controller/internal/
举例:
ambari 2.6
-
RackResourceProvider(Set<String> propertyIds,
-
Map<Resource.Type, String> keyPropertyIds,
-
AmbariManagementController managementController) {
-
super(propertyIds, keyPropertyIds, managementController);
-
setRequiredCreateAuthorizations(EnumSet.of(RoleAuthorization.AMBARI_MANAGE_USERS));
-
setRequiredDeleteAuthorizations(EnumSet.of(RoleAuthorization.AMBARI_MANAGE_USERS));
-
}
ambari 2.7
-
RackResourceProvider(@Assisted AmbariManagementController managementController) {
-
super(Resource.Type.Rack, propertyIds, keyPropertyIds, managementController);
-
setRequiredCreateAuthorizations(EnumSet.of(RoleAuthorization.AMBARI_MANAGE_USERS));
-
setRequiredDeleteAuthorizations(EnumSet.of(RoleAuthorization.AMBARI_MANAGE_USERS));
-
}
3. AbstractControllerResourceProvider.java
路径:org/apache/ambari/server/controller/internal/
举例:
ambari 2.6
-
case Rack:
-
return new RackResourceProvider(propertyIds, keyPropertyIds, managementController);
ambari 2.7
-
case Rack:
-
return new RackResourceProvider(managementController);
4. 代码规范
路径:ambari-server/checkstyle.xml
ambari 2.6
-
<module name="Checker">
-
<module name="TreeWalker">
-
<module name="AvoidTransactionalOnPrivateMethodsCheck"/>
-
</module>
-
</module>
ambari 2.7
-
<module name="Checker">
-
<!-- Checkstyle binds to phase "validate" by default.
-
Run independently as, cd ambari-server ; mvn checkstyle:checkstyle
-
Or can skip as, mvn ... -Dcheckstyle.skip
-
-->
-
<!-- 每个java文件一个语法树 -->
-
<module name="TreeWalker">
-
<module name="AvoidTransactionalOnPrivateMethodsCheck"/>
-
<module name="UndocumentedRestApiOperationCheck"/> <!-- Swagger -->
-
<module name="FallThrough"/>
-
<!-- 检查没有使用*表示法的import语句 -->
-
<module name="AvoidStarImport"/>
-
<!-- 检查是否从非法的包中导入了类 -->
-
<module name="IllegalImport">
-
<property name="illegalPkgs" value="sun, org.apache.ambari.metrics.sink.relocated, org.apache.hadoop.metrics2.sink.relocated"/>
-
</module>
-
<!-- 检查类的导入顺序 -->
-
<module name="ImportOrder">
-
<!-- 类型导入组的列表 -->
-
<property name="groups" value="java,javax,org,com,*"/>
-
<!-- 是否应对每个组中的类型导入进行排序(它不会影响静态导入的排序。) -->
-
<property name="ordered" value="true"/>
-
<!-- 类型导入组是否应至少由一个空行或注释分隔, -->
-
<property name="separated" value="true"/>
-
<!-- 关于类型导入和静态导入之间的相对顺序的策略 -->
-
<property name="option" value="top"/>
-
<!-- 允许按字母顺序对按顶部分组的静态导入进行排序 -->
-
<property name="sortStaticImportsAlphabetically" value="true"/>
-
</module>
-
<!-- 检查是否导入了多余的包 -->
-
<module name="RedundantImport"/>
-
<!-- 检查是否导入了没有被用到的包 -->
-
<module name="UnusedImports"/>
-
<!-- blocks -->
-
<!-- 检查是否有嵌套代码块 -->
-
<module name="AvoidNestedBlocks">
-
<property name="allowInSwitchCase" value="true"/>
-
</module>
-
<!-- 检查是否有空代码块 -->
-
<module name="EmptyBlock">
-
<property name="option" value="text"/>
-
</module>
-
</module>
-
</module>
5. spring security
5.1 下面是对含license字段的api进行免登陆访问:
ambari 2.6
路径:ambari-server/src/main/resources/webapp/WEB-INF/spring-security.xml
新增代码:
-
<http pattern="/**/license/**" security="none"/>
ambari 2.7
路径:ambari-server/src/main/java/org/apache/ambari/server/configuration/spring/ApiSecurityConfig.java
web的方法
-
import org.springframework.security.config.annotation.web.builders.WebSecurity;
-
@Override
-
public void configure(WebSecurity web) throws Exception {
-
// license-related api free login verification
-
web.ignoring().antMatchers("/**/license/**");
-
}
http的方法
-
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
-
@Override
-
protected void configure(HttpSecurity http) throws Exception {
-
http.csrf().disable()
-
.authorizeRequests()
-
.antMatchers("/**/license/**").permitAll()
-
.anyRequest().authenticated()
5.2 api中%2F的处理
我在ambari-server后台开发了一个自定义api,例如:http://ip:8080/api/v1/racks//rack1,ambari-server会将 /rack1转换为 %2Frack1。
ambari 2.6
ambari-server api中允许 %2F等字段
ambari 2.7
ambari-server拒绝包含%2F的URL请求
解决办法:
-
import org.springframework.context.annotation.Configuration;
-
import org.springframework.security.config.annotation.web.builders.WebSecurity;
-
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
-
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
-
@Configuration
-
@EnableWebSecurity
-
@Import(GuiceBeansConfig.class)
-
@ComponentScan("org.apache.ambari.server.security")
-
public class ApiSecurityConfig extends WebSecurityConfigurerAdapter{
-
@Bean
-
public DefaultHttpFirewall allowUrlEncodedSlashHttpFirewall() {
-
DefaultHttpFirewall firewall = new DefaultHttpFirewall();
-
firewall.setAllowUrlEncodedSlash(true);
-
return firewall;
-
}
-
@Override
-
public void configure(WebSecurity web) throws Exception {
-
// license-related api free login verification
-
web.ignoring().antMatchers("/**/license/**");
-
// Resolved a request to reject a URL containing %2F
-
web.httpFirewall(allowUrlEncodedSlashHttpFirewall());
-
}
-
}
6. keyPropertyIds的获取
ambari 2.6
路径:ambari-server/src/main/resources/key_properties.json和properties.json
以Resource的Type是 Rack为例:
properties.json
-
"Rack":[
-
"rack/rack_id",
-
"rack/rack_name",
-
"rack/rack_height",
-
"rack/rack_type",
-
"rack/rack_location",
-
"rack/rack_description",
-
"_"
-
],
key_properties.json
-
"Rack": {
-
"RepositoryVersion": "rack/rack_id",
-
"Rack": "rack/rack_name",
-
"User": "rack/rack_height",
-
"Member": "rack/rack_type",
-
"Task": "rack/rack_location",
-
"Auditlog": "rack/rack_description"
-
},
ambari 2.7
-
private static Set<String> propertyIds = Sets.newHashSet(
-
RACK_ID_PROPERTY_ID,
-
RACK_NAME_PROPERTY_ID,
-
RACK_HEIGHT_PROPERTY_ID,
-
RACK_TYPE_PROPERTY_ID,
-
RACK_LOCATION_PROPERTY_ID,
-
RACK_DESCRIPTION_PROPERTY_ID
-
);
-
private static Map<Resource.Type, String> keyPropertyIds = ImmutableMap.<Resource.Type, String>builder()
-
.put(Resource.Type.Rack, RACK_NAME_PROPERTY_ID)
-
.put(Resource.Type.RepositoryVersion, RACK_ID_PROPERTY_ID)
-
.put(Resource.Type.User, RACK_HEIGHT_PROPERTY_ID)
-
.put(Resource.Type.Member, RACK_TYPE_PROPERTY_ID)
-
.put(Resource.Type.Task, RACK_LOCATION_PROPERTY_ID)
-
.put(Resource.Type.Auditlog, RACK_DESCRIPTION_PROPERTY_ID)
-
.build();
总结:去除了properties.json和key_properties.json文件,使用java代码来代替json文件的读取。