001package net.gdface.service.sdk.spring;
002
003import org.apache.catalina.connector.Connector;
004import org.apache.coyote.http11.Http11NioProtocol;
005import org.springframework.boot.SpringApplication;
006import org.springframework.boot.autoconfigure.SpringBootApplication;
007import org.springframework.boot.context.embedded.EmbeddedServletContainerFactory;
008import org.springframework.boot.context.embedded.tomcat.TomcatConnectorCustomizer;
009import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory;
010import org.springframework.context.annotation.Bean;
011import org.springframework.context.annotation.ComponentScan;
012import org.springframework.web.servlet.config.annotation.CorsRegistry;
013import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
014import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
015
016import net.gdface.sdk.FaceApi;
017import net.gdface.sdk.FaceApiSpringController;
018import net.gdface.sdk.fse.FeatureSe;
019import net.gdface.sdk.fse.FeatureSeSpringController;
020import springfox.documentation.builders.ApiInfoBuilder;
021import springfox.documentation.builders.PathSelectors;
022import springfox.documentation.builders.RequestHandlerSelectors;
023import springfox.documentation.service.ApiInfo;
024import springfox.documentation.service.Contact;
025import springfox.documentation.spi.DocumentationType;
026import springfox.documentation.spring.web.plugins.Docket;
027import springfox.documentation.swagger2.annotations.EnableSwagger2;
028
029import static com.google.common.base.Preconditions.*;
030
031import java.lang.reflect.Proxy;
032
033/**
034 * 将faceapi接口封装为RESTful接口spring web应用
035 * @author guyadong
036 */
037@SpringBootApplication
038@ComponentScan({"net.gdface.sdk","net.gdface.fse"})
039@EnableSwagger2
040public class RestfulService {
041        public static final int DEFAULT_HTTP_PORT = 8080;
042        /** web服务端口 */
043        private static int httpPort = DEFAULT_HTTP_PORT;
044        /** tomcat连接参数 */
045        private static TomcatConnectorCustomizer customizer = new ConnectorCustomizer();
046        /** 是否显示在线swagger文档 */
047        private static boolean swaggerEnable = true;
048        /** 是否支持跨域访问 */
049        private static boolean corsEnable = true;
050        private static FaceApi apiInstance;
051        private static FeatureSe fseInstance;
052        /** test only  */
053        public static void main(String[] args) throws Exception {
054                SpringApplication.run(RestfulService.class, args);
055        }
056        /**
057         * 启动spring boot应用
058         */
059        public static void run(){
060                SpringApplication.run(RestfulService.class, new String[]{});
061        }
062    @Bean
063    public Docket serviceApi() { 
064        return new Docket(DocumentationType.SWAGGER_2)
065                .enable(swaggerEnable)
066                .apiInfo(apiInfo())
067                .select()
068                .apis(RequestHandlerSelectors.basePackage("net.gdface.sdk"))
069                .paths(PathSelectors.any())
070                .build();    
071    }
072    private static String getImplClass(FaceApi instance){
073        checkNotNull(instance,"instance is null");
074        if(Proxy.isProxyClass(instance.getClass())){
075                return "UNKNOW";
076        }
077        return instance.getClass().getSimpleName();
078    }
079    private ApiInfo apiInfo() {         
080        FaceApi instance = checkNotNull(apiInstance,"apiInstance is uninitialized");
081        
082        String description= FaceApiSpringController.DESCRIPTION                                 
083                        + "<br>\nImplementation Class(算法实现): " + getImplClass(instance)
084                        + "<br>\nSDKVERSION(SDK版本号):" + instance.sdkCapacity().get("SDK_VERSION");
085        if(fseInstance != null){
086                description = description.concat("<br>\n" + FeatureSeSpringController.DESCRIPTION);
087        }
088        return new ApiInfoBuilder()
089                .title("FaceApi Document")
090                .description(description)
091                .contact(new Contact("10km", "https://gitee.com/l0km/faceapi", "10km0811@sohu.com"))
092                .build();
093    }
094        @Bean
095        public EmbeddedServletContainerFactory getTomcatEmbeddedServletContainerFactory(){
096                TomcatEmbeddedServletContainerFactory tomcatFactory = new TomcatEmbeddedServletContainerFactory();  
097                tomcatFactory.addConnectorCustomizers(customizer);  
098                return tomcatFactory; 
099
100        }
101        /**
102         * 默认的tomcat连接参数实例
103         * @author guyadong
104         *
105         */
106        private static class ConnectorCustomizer implements TomcatConnectorCustomizer  
107        {  
108                public void customize(Connector connector)  
109                {  
110                        Http11NioProtocol protocol = (Http11NioProtocol) connector.getProtocolHandler();  
111                        protocol.setPort(httpPort);
112                        //设置最大连接数  
113                        protocol.setMaxConnections(2000);  
114                        //设置最大线程数  
115                        protocol.setMaxThreads(2000);  
116                        protocol.setConnectionTimeout(30000);  
117                }  
118        }
119        /**
120         * 返回HTTP端口
121         * @return httpPort
122         */
123        public static int getHttpPort() {
124                return httpPort;
125        }
126        /**
127         * 设置HTTP端口,默认{@value #DEFAULT_HTTP_PORT}
128         * @param httpPort 要设置的 httpPort
129         */
130        public static void setHttpPort(int httpPort) {
131                RestfulService.httpPort = httpPort;
132        }
133        /**
134         * 返回tomcat参数定义接口实例
135         * @return customizer
136         */
137        public static TomcatConnectorCustomizer getCustomizer() {
138                return customizer;
139        }
140        /**
141         * 设置tomcat参数定义接口实例
142         * @param customizer 要设置的 customizer,不可为{@code null}
143         */
144        public static void setCustomizer(TomcatConnectorCustomizer customizer) {
145                RestfulService.customizer = checkNotNull(customizer,"customizer is null");
146        }
147
148        /**
149         * 设置{@link FaceApi}实例
150         * @param apiInstance {@link FaceApi}实例,不可为{@code null}
151         */
152        public static void setInterfaceInstance(FaceApi apiInstance){
153                RestfulService.apiInstance = checkNotNull(apiInstance,"apiInstance is null");
154                FaceApiSpringController.setInstanceSupplier(new FaceApiSpringController.InstanceSupplier(){
155                        @Override
156                        public FaceApi instanceOfFaceApi() {
157                                return RestfulService.apiInstance;
158                        }});
159        }
160        /**
161         * 设置{@link FaceApi}实例
162         * @param apiInstance {@link FaceApi}实例,不可为{@code null}
163         */
164        public static void setInterfaceInstance(FeatureSe apiInstance){
165                RestfulService.fseInstance = checkNotNull(apiInstance,"apiInstance is null");
166                FeatureSeSpringController.setInstanceSupplier(new FeatureSeSpringController.InstanceSupplier(){
167                        @Override
168                        public FeatureSe instanceOfFeatureSe() {
169                                return RestfulService.fseInstance;
170                        }});
171        }
172        /**
173         * @return swaggerEnable
174         */
175        public static boolean isSwaggerEnable() {
176                return swaggerEnable;
177        }
178        /**
179         * 设置是否显示在线swagger文档
180         * @param swaggerEnable 
181         */
182        public static void setSwaggerEnable(boolean swaggerEnable) {
183                RestfulService.swaggerEnable = swaggerEnable;
184        }
185        /**
186         * @return corsEnable
187         */
188        public static boolean isCorsEnable() {
189                return corsEnable;
190        }
191        /**
192         * 设置是否支持跨域访问(CORS)
193         * @param corsEnable
194         */
195        public static void setCorsEnable(boolean corsEnable) {
196                RestfulService.corsEnable = corsEnable;
197        }
198        /**
199         * 配置是否允许跨访问
200         * @return
201         */
202        @Bean
203    public WebMvcConfigurer corsConfigurer(){
204      return new WebMvcConfigurerAdapter(){
205        @Override
206        public void addCorsMappings(CorsRegistry registry) {
207                if(corsEnable){
208                        registry.addMapping("/**").allowedOrigins("*"); 
209                }
210          
211        }
212      };
213    }
214
215}