# SDK开发说明

# 公共方法说明

1、com.primeton.gocom.afcenter.common.sdk.SdkClientFactory:sdk客户端工厂

    /**
	 * 注册本地sdk api实现
	 * 
	 * @param sdkApiClass sdk接口类
	 * @param sdkApiLocalImpl sdk本地实现对象
	 */
	public static void registLocalSdkApiImpl(Class sdkApiClass, Object sdkApiLocalImpl);

    /**
	 * 获取客户端
	 * 
	 * @param clientClass 客户端类
	 * @param starterClassName starter配置的类名,用于判断是本地,还是远程
	 * @param sdkApiRemoteMethodInvocationHandler 远程实现的方法拦截对象
	 * @return 客户端类
	 */
	public static <T> T getClientProxy(Class<T> clientClass, String starterClassName, IMethodInvocationHandler sdkApiRemoteMethodInvocationHandler);

2、com.primeton.gocom.afcenter.common.sdk.AbstractSdkApiRemoteMethodInvocationHandler:sdk api 远程方法调用抽象实现
   
    // 路径前缀
	protected String pathPrefix = null;
	
	// 服务名或者应用名(nacos对应)
	protected String serviceName = null;
	
	// header
	protected Map<String, String> mapHeader = new HashMap<>();

# Afc sdk实现示例说明

1、afc sdk api,使用用户的IUserAPI示例

1) 接口定义(在sdk模块中):
    要求:I+资源名+API

    public interface IUserAPI {

        User findUserByCode(String userCode);

        。。。

    }

2)本地实现(在sdk模块中)

    public class UserLocalImpl implements IUserAPI {


        private IUserService userService;

        public UserLocalImpl() {
            this.userService = EOS8ApplicationContext.INSTANCE.getBean(IUserService.class);
            // 可以在这里注册本地实现,也可以在后续的factory中
            // SdkClientFactory.registLocalSdkApiImpl(IUserAPI.class, this);
        }

        /**
        * 根据用户code 查询用户信息
        *
        * @param userCode 用户code
        * @return 用户实体
        */
        @Override
        public User findUserByCode(String userCode) {
            return userService.findUserByCode(userCode, StatusEum.ENABLE.getCode());
        }

        。。。

    }

3)远程实现(在restproxy模块中):
     要求,httpPath是资源名(小写)/方法名(-连接), http方法是post,参数是MultiRequestBody类型。

    @ApiIgnore
    @RestController
    @RequestMapping(value = SDK_URL_PREFIX + "/user", consumes = {APPLICATION_JSON_UTF8_VALUE}, produces = {APPLICATION_JSON_UTF8_VALUE})
    public class UserProxyController implements IUserAPI {

        @Autowired
        private IUserService userService;

        /**
        * 根据用户code查询可用用户信息
        */
        @PostMapping("/find-user-by-code")
        @Override
        public User findUserByCode(@ApiParam("用户code") @MultiRequestBody String userCode) {
            return userService.findUserByCode(userCode, StatusEum.ENABLE.getCode());
        }
        。。。
    }

2、afc sdk client

1)afc sdk client(在sdk模块中)
    public interface IAFCClient {

        IUserAPI getUserAPI();

        。。。

    }

2)远程调用AfcSdkApiRemoteMethodInvocationHandler(在sdk模块中)

    public class AfcSdkApiRemoteMethodInvocationHandler extends AbstractSdkApiRemoteMethodInvocationHandler {
        
        private static final long serialVersionUID = 1L;
        
        public static final String APPCODE = "afc-appCode";
        public static final String APPSECRET = "afc-appSecret";
        public static final String TENANTID = "afc-tenantId";
        
        public AfcSdkApiRemoteMethodInvocationHandler() {
            // 路径前缀
            this.pathPrefix = "api/afc/afc-proxy";

            //服务名或者应用名
            this.serviceName = EOS8ApplicationContext.INSTANCE.getProperty("afc.application.name");

            // head相关参数
            String tenant = EOS8ApplicationContext.INSTANCE.getProperty("afc.application.tenant");
            String appCode = EOS8ApplicationContext.INSTANCE.getProperty("afc.application.appCode");
            String appSecret = EOS8ApplicationContext.INSTANCE.getProperty("afc.application.appSecret");
            Map<String, String> mapHeader = new HashMap<>();
            if(StringUtils.isBlank(tenant)) {
                HttpServletRequest httpRequest = DataContextService.current().getHttpRequest();
                if (httpRequest != null) {
                    String tenantId = httpRequest.getHeader(CommonConstants.TENANT);
                    if(StringUtils.isBlank(tenantId)) {
                        tenantId = httpRequest.getParameter(CommonConstants.TENANT);
                    }
                    if (StringUtils.isNotBlank(tenantId)) {
                        mapHeader.put(TENANTID, tenantId);
                    }
                }
            } else {
                mapHeader.put(APPCODE, appCode);
                mapHeader.put(APPSECRET, appSecret);
                mapHeader.put(TENANTID, tenant);
            }
        }
    }

3)afc sdk client 工厂(在sdk模块中)

    public class AFCClientFactory {
        
        private static AFCClientFactory instance = null;
        
        private AFCClientFactory() {
            // 注册本地sdk api实现,如果在构造方法中注册,此处可以不用
            SdkClientFactory.registLocalSdkApiImpl(IUserAPI.class, new UserLocalImpl());
            ...
        }
        
        public static AFCClientFactory getInstance() {
            if(instance == null) {
                instance = new AFCClientFactory();
            }
            return instance;
        }
        
        // 获取afc sdk 客户端
        public IAFCClient createAFCClient() {
            return SdkClientFactory.getClientProxy(IAFCClient.class, 
                    "com.primeton.gocom.afcenter.starter.config.AFCServerAutoConfiguration", 
                    new AfcSdkApiRemoteMethodInvocationHandler());
        }

    }

4)AFCSDKConfiguration:sdk中的配置类(在sdk模块中)
    @Configuration
    @ComponentScan(basePackages = "com.primeton.gocom.afcenter")
    public class AFCSDKConfiguration {
        
        @Bean
        public IAFCClient afcClient() {// spring方式使用
            return AFCClientFactory.getInstance().createAFCClient();
        }

        。。。

    }

3、使用

1)直接使用
    IUserAPI userApi = AFCClientFactory.getInstance().createAFCClient().getUserAPI();

2)spring方式使用
  
  @Autowired
  private IAFCClient afcClient;


上次更新: 2023/7/20下午12:25:28