本文针对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注解。

  1. @ApiModelProperty(name = RackResourceProvider.ID_PROPERTY)

@ApiModelProperty是Swagger的一个注解,而Swagger是一款目前世界最流行的API管理工具。详情介绍:点击

2. xxxResourceProvider.java的构造方法的改变

路径:org/apache/ambari/server/controller/internal/

举例:

ambari 2.6

  1. RackResourceProvider(Set<String> propertyIds,

  2.                             Map<Resource.Type, String> keyPropertyIds,

  3.                             AmbariManagementController managementController) {

  4.        super(propertyIds, keyPropertyIds, managementController);

  5. setRequiredCreateAuthorizations(EnumSet.of(RoleAuthorization.AMBARI_MANAGE_USERS));

  6. setRequiredDeleteAuthorizations(EnumSet.of(RoleAuthorization.AMBARI_MANAGE_USERS));

  7.    }

ambari 2.7

  1. RackResourceProvider(@Assisted AmbariManagementController managementController) {

  2.    super(Resource.Type.Rack, propertyIds, keyPropertyIds, managementController);

  3.  setRequiredCreateAuthorizations(EnumSet.of(RoleAuthorization.AMBARI_MANAGE_USERS));

  4.  setRequiredDeleteAuthorizations(EnumSet.of(RoleAuthorization.AMBARI_MANAGE_USERS));

  5. }

3. AbstractControllerResourceProvider.java

路径:org/apache/ambari/server/controller/internal/

举例:

ambari 2.6

  1. case Rack:

  2.        return new RackResourceProvider(propertyIds, keyPropertyIds, managementController);

ambari 2.7

  1. case Rack:

  2.    return new RackResourceProvider(managementController);

4. 代码规范

路径:ambari-server/checkstyle.xml

ambari 2.6

  1. <module name="Checker">

  2.  <module name="TreeWalker">

  3.    <module name="AvoidTransactionalOnPrivateMethodsCheck"/>

  4.  </module>

  5. </module>

ambari 2.7

  1. <module name="Checker">

  2.  <!-- Checkstyle binds to phase "validate" by default.

  3.  Run independently as, cd ambari-server ; mvn checkstyle:checkstyle

  4.  Or can skip as, mvn ... -Dcheckstyle.skip

  5.  -->

  6.  <!-- 每个java文件一个语法树 -->

  7.  <module name="TreeWalker">

  8.    <module name="AvoidTransactionalOnPrivateMethodsCheck"/>

  9.    <module name="UndocumentedRestApiOperationCheck"/> <!-- Swagger -->

  10.    <module name="FallThrough"/>

  11.    <!-- 检查没有使用*表示法的import语句 -->

  12.    <module name="AvoidStarImport"/>

  13.    <!-- 检查是否从非法的包中导入了类 -->

  14.    <module name="IllegalImport">

  15.      <property name="illegalPkgs" value="sun, org.apache.ambari.metrics.sink.relocated, org.apache.hadoop.metrics2.sink.relocated"/>

  16.    </module>

  17.    <!-- 检查类的导入顺序 -->

  18.    <module name="ImportOrder">

  19.      <!-- 类型导入组的列表 -->

  20.      <property name="groups" value="java,javax,org,com,*"/>

  21.      <!-- 是否应对每个组中的类型导入进行排序(它不会影响静态导入的排序。) -->

  22.      <property name="ordered" value="true"/>

  23.      <!-- 类型导入组是否应至少由一个空行或注释分隔, -->

  24.      <property name="separated" value="true"/>

  25.      <!-- 关于类型导入和静态导入之间的相对顺序的策略 -->

  26.      <property name="option" value="top"/>

  27.      <!-- 允许按字母顺序对按顶部分组的静态导入进行排序 -->

  28.      <property name="sortStaticImportsAlphabetically" value="true"/>

  29.    </module>

  30.    <!-- 检查是否导入了多余的包 -->

  31.    <module name="RedundantImport"/>

  32.    <!-- 检查是否导入了没有被用到的包 -->

  33.    <module name="UnusedImports"/>

  34.    <!-- blocks -->

  35.    <!-- 检查是否有嵌套代码块 -->

  36.    <module name="AvoidNestedBlocks">

  37.      <property name="allowInSwitchCase" value="true"/>

  38.    </module>

  39.    <!-- 检查是否有空代码块 -->

  40.    <module name="EmptyBlock">

  41.      <property name="option" value="text"/>

  42.    </module>

  43.  </module>

  44. </module>

5. spring security

5.1 下面是对含license字段的api进行免登陆访问:

ambari 2.6

路径:ambari-server/src/main/resources/webapp/WEB-INF/spring-security.xml

新增代码:

  1. <http pattern="/**/license/**" security="none"/>

ambari 2.7

路径:ambari-server/src/main/java/org/apache/ambari/server/configuration/spring/ApiSecurityConfig.java

web的方法

  1. import org.springframework.security.config.annotation.web.builders.WebSecurity;

  2. @Override

  3. public void configure(WebSecurity web) throws Exception {

  4.    // license-related api free login verification

  5.    web.ignoring().antMatchers("/**/license/**");

  6. }

http的方法

  1. import org.springframework.security.config.annotation.web.builders.HttpSecurity;

  2. @Override

  3. protected void configure(HttpSecurity http) throws Exception {

  4.    http.csrf().disable()

  5.        .authorizeRequests()

  6.        .antMatchers("/**/license/**").permitAll()

  7.        .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请求

ambari-server版本比较_ambari

解决办法:

  1. import org.springframework.context.annotation.Configuration;

  2. import org.springframework.security.config.annotation.web.builders.WebSecurity;

  3. import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;

  4. import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

  5. @Configuration

  6. @EnableWebSecurity

  7. @Import(GuiceBeansConfig.class)

  8. @ComponentScan("org.apache.ambari.server.security")

  9. public class ApiSecurityConfig extends WebSecurityConfigurerAdapter{

  10.    @Bean

  11.    public DefaultHttpFirewall allowUrlEncodedSlashHttpFirewall() {

  12.      DefaultHttpFirewall firewall = new DefaultHttpFirewall();

  13.      firewall.setAllowUrlEncodedSlash(true);

  14.      return firewall;

  15.    }

  16.    @Override

  17.    public void configure(WebSecurity web) throws Exception {

  18.      // license-related api free login verification

  19.      web.ignoring().antMatchers("/**/license/**");

  20.      // Resolved a request to reject a URL containing %2F

  21.      web.httpFirewall(allowUrlEncodedSlashHttpFirewall());

  22.    }

  23. }

6. keyPropertyIds的获取

ambari 2.6

路径:ambari-server/src/main/resources/key_properties.json和properties.json

以Resource的Type是 Rack为例:

properties.json

  1. "Rack":[

  2.    "rack/rack_id",

  3.    "rack/rack_name",

  4.    "rack/rack_height",

  5.    "rack/rack_type",

  6.    "rack/rack_location",

  7.    "rack/rack_description",

  8.    "_"

  9. ],

key_properties.json

  1. "Rack": {

  2.    "RepositoryVersion": "rack/rack_id",

  3.    "Rack": "rack/rack_name",

  4.    "User": "rack/rack_height",

  5.    "Member": "rack/rack_type",

  6.    "Task": "rack/rack_location",

  7.    "Auditlog": "rack/rack_description"

  8. },

ambari 2.7

  1. private static Set<String> propertyIds = Sets.newHashSet(

  2.            RACK_ID_PROPERTY_ID,

  3.            RACK_NAME_PROPERTY_ID,

  4.            RACK_HEIGHT_PROPERTY_ID,

  5.            RACK_TYPE_PROPERTY_ID,

  6.            RACK_LOCATION_PROPERTY_ID,

  7.            RACK_DESCRIPTION_PROPERTY_ID

  8.    );

  9. private static Map<Resource.Type, String> keyPropertyIds = ImmutableMap.<Resource.Type, String>builder()

  10.    .put(Resource.Type.Rack, RACK_NAME_PROPERTY_ID)

  11.    .put(Resource.Type.RepositoryVersion, RACK_ID_PROPERTY_ID)

  12.    .put(Resource.Type.User, RACK_HEIGHT_PROPERTY_ID)

  13.    .put(Resource.Type.Member, RACK_TYPE_PROPERTY_ID)

  14.    .put(Resource.Type.Task, RACK_LOCATION_PROPERTY_ID)

  15.    .put(Resource.Type.Auditlog, RACK_DESCRIPTION_PROPERTY_ID)

  16.    .build();

总结:去除了properties.json和key_properties.json文件,使用java代码来代替json文件的读取。

 

ambari-server版本比较_ambari_02