Skip to content

Commit

Permalink
Optimize to support spring webflux in ark (#798)
Browse files Browse the repository at this point in the history
* extend ArkNettyReactiveWebServerFactory

* fix biz override master ReactorHttpHandlerAdapter

* fix Port in use

* fix base service faile when biz uninstalled

* fix the biz service is still accessible after biz was uninstalled

* change version to 2.2.5

* remove unuse code

* disposableServer dispose when master stopping

* fix ut,sofa-ark-springboot-starter dependent reactor-netty, change netty-handler version

* fix ci check

---------

Co-authored-by: yuanyuan <fengjun.zfj@antgroup.com>
Co-authored-by: leo james <leojames.googol@gmail.com>
  • Loading branch information
3 people committed Nov 30, 2023
1 parent ef684f6 commit 361d445
Show file tree
Hide file tree
Showing 13 changed files with 161 additions and 133 deletions.
53 changes: 0 additions & 53 deletions .github/workflows/codecov.yml

This file was deleted.

4 changes: 2 additions & 2 deletions .github/workflows/linux_unit_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ on:
branches: [ master ]

jobs:
unit_test_for_jdk8:
build:

runs-on: ubuntu-latest

Expand All @@ -27,4 +27,4 @@ jobs:
&& sh ./check_format.sh
&& mvn test
- name: Codecov
uses: codecov/codecov-action@v4.0.0-beta.3
uses: codecov/codecov-action@v3.1.4
4 changes: 2 additions & 2 deletions .github/workflows/windows_unit_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ on:
branches: [ "master" ]

jobs:
unit_test_for_jdk8:
build:
runs-on: windows-latest
strategy:
fail-fast: true
Expand All @@ -32,4 +32,4 @@ jobs:
&& sh ./check_format.sh
&& mvn test
- name: Codecov
uses: codecov/codecov-action@v4.0.0-beta.3
uses: codecov/codecov-action@v3.1.4
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,6 @@
<artifactId>sofa-ark-springboot-starter</artifactId>

<dependencies>
<dependency>
<groupId>io.projectreactor.netty</groupId>
<artifactId>reactor-netty</artifactId>
<version>1.0.22</version>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot</artifactId>
Expand Down Expand Up @@ -132,6 +126,12 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-loader</artifactId>
</dependency>

<dependency>
<groupId>io.projectreactor.netty</groupId>
<artifactId>reactor-netty</artifactId>
<version>1.0.22</version>
</dependency>
</dependencies>

<build>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@
package com.alipay.sofa.ark.springboot;

import com.alipay.sofa.ark.springboot.condition.ConditionalOnArkEnabled;
import com.alipay.sofa.ark.springboot.processor.ArkEventHandlerProcessor;
import com.alipay.sofa.ark.springboot.processor.ArkServiceInjectProcessor;
import com.alipay.sofa.ark.springboot.web.ArkNettyReactiveWebServerFactory;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
Expand All @@ -40,16 +38,7 @@
@Configuration
@ConditionalOnArkEnabled
@AutoConfigureBefore(ReactiveWebServerFactoryAutoConfiguration.class)
public class ArkReactiveAutoConfigure {
@Bean
public static ArkServiceInjectProcessor serviceInjectProcessor() {
return new ArkServiceInjectProcessor();
}

@Bean
public static ArkEventHandlerProcessor arkEventHandlerProcessor() {
return new ArkEventHandlerProcessor();
}
public class ArkReactiveAutoConfiguration {

@Configuration
@ConditionalOnMissingBean({ ReactiveWebServerFactory.class })
Expand All @@ -61,7 +50,9 @@ static class EmbeddedNetty {
@Bean
@ConditionalOnMissingBean
ReactorResourceFactory reactorServerResourceFactory() {
return new ReactorResourceFactory();
ReactorResourceFactory reactorResourceFactory = new ReactorResourceFactory();
reactorResourceFactory.setUseGlobalResources(false);
return reactorResourceFactory;
}

@Bean
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@
package com.alipay.sofa.ark.springboot;

import com.alipay.sofa.ark.springboot.condition.ConditionalOnArkEnabled;
import com.alipay.sofa.ark.springboot.processor.ArkEventHandlerProcessor;
import com.alipay.sofa.ark.springboot.processor.ArkServiceInjectProcessor;
import com.alipay.sofa.ark.springboot.web.ArkTomcatServletWebServerFactory;
import org.apache.catalina.startup.Tomcat;
import org.apache.coyote.UpgradeProtocol;
Expand All @@ -42,7 +40,7 @@
@ConditionalOnArkEnabled
@ConditionalOnClass(ServletWebServerFactoryAutoConfiguration.class)
@AutoConfigureBefore(ServletWebServerFactoryAutoConfiguration.class)
public class ArkAutoConfiguration {
public class ArkServletAutoConfiguration {

@Configuration
@ConditionalOnClass(value = { Servlet.class, Tomcat.class, UpgradeProtocol.class,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alipay.sofa.ark.springboot.web;

import com.alipay.sofa.ark.exception.ArkRuntimeException;
import org.springframework.http.server.reactive.HttpHandler;
import org.springframework.http.server.reactive.ReactorHttpHandlerAdapter;
import reactor.core.publisher.Mono;
import reactor.netty.http.server.HttpServerRequest;
import reactor.netty.http.server.HttpServerResponse;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
* @author: yuanyuan
*/
public class ArkCompositeReactorHttpHandlerAdapter extends ReactorHttpHandlerAdapter {

private Map<String, ReactorHttpHandlerAdapter> bizReactorHttpHandlerAdapters = new ConcurrentHashMap<>();

public ArkCompositeReactorHttpHandlerAdapter(HttpHandler httpHandler) {
super(httpHandler);
}

@Override
public Mono<Void> apply(HttpServerRequest reactorRequest, HttpServerResponse reactorResponse) {
String uri = reactorRequest.uri();
for (Map.Entry<String, ReactorHttpHandlerAdapter> entry : bizReactorHttpHandlerAdapters
.entrySet()) {
if (uri.startsWith(entry.getKey())) {
ReactorHttpHandlerAdapter adapter = entry.getValue();
return adapter.apply(reactorRequest, reactorResponse);
}
}
return super.apply(reactorRequest, reactorResponse);
}

public void registerBizReactorHttpHandlerAdapter(String contextPath,
ReactorHttpHandlerAdapter reactorHttpHandlerAdapter) {
ReactorHttpHandlerAdapter old = bizReactorHttpHandlerAdapters.putIfAbsent(contextPath,
reactorHttpHandlerAdapter);
if (old != null) {
throw new ArkRuntimeException("Duplicated context path");
}
}

public void unregisterBizReactorHttpHandlerAdapter(String contextPath) {
bizReactorHttpHandlerAdapters.remove(contextPath);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,51 +39,62 @@
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import static com.alipay.sofa.ark.spi.constant.Constants.ROOT_WEB_CONTEXT_PATH;

public class ArkNettyReactiveWebServerFactory extends NettyReactiveWebServerFactory {
private static final Charset DEFAULT_CHARSET = StandardCharsets.UTF_8;
private Duration lifecycleTimeout;
private static final Charset DEFAULT_CHARSET = StandardCharsets.UTF_8;
private Duration lifecycleTimeout;

private List<NettyRouteProvider> routeProviders = new ArrayList();
private List<NettyRouteProvider> routeProviders = new ArrayList();
@ArkInject
private EmbeddedServerService embeddedNettyService;
private EmbeddedServerService embeddedNettyService;

@ArkInject
private BizManagerService bizManagerService;
private BizManagerService bizManagerService;

private boolean useForwardHeaders;
private boolean useForwardHeaders;

private ReactorResourceFactory resourceFactory;
private ReactorResourceFactory resourceFactory;

private int backgroundProcessorDelay;
private Set<NettyServerCustomizer> serverCustomizers = new LinkedHashSet();
private int backgroundProcessorDelay;
private Set<NettyServerCustomizer> serverCustomizers = new LinkedHashSet();

public ArkNettyReactiveWebServerFactory() {
}
private static ArkCompositeReactorHttpHandlerAdapter adapter;

public ArkNettyReactiveWebServerFactory(int port) {
super(port);
public ArkNettyReactiveWebServerFactory() {
}

@Override
public WebServer getWebServer(HttpHandler httpHandler) {
if (embeddedNettyService == null) {
return super.getWebServer(httpHandler);
} else if (embeddedNettyService.getEmbedServer() == null) {
embeddedNettyService.setEmbedServer(initEmbedNetty());
}

String contextPath = getContextPath();
Map<String, HttpHandler> handlerMap = new HashMap<>();
handlerMap.put(contextPath, httpHandler);
ContextPathCompositeHandler contextHandler = new ContextPathCompositeHandler(handlerMap);

if (embeddedNettyService == null) {
return super.getWebServer(contextHandler);
} else if (embeddedNettyService.getEmbedServer() == null) {
embeddedNettyService.setEmbedServer(initEmbedNetty());
if (adapter == null) {
adapter = new ArkCompositeReactorHttpHandlerAdapter(contextHandler);
} else {
adapter.registerBizReactorHttpHandlerAdapter(contextPath,
new ReactorHttpHandlerAdapter(contextHandler));
}

HttpServer httpServer = (HttpServer) embeddedNettyService.getEmbedServer();
ReactorHttpHandlerAdapter handlerAdapter = new ReactorHttpHandlerAdapter(contextHandler);
ArkNettyWebServer webServer = (ArkNettyWebServer) createNettyWebServer(httpServer,
handlerAdapter, lifecycleTimeout);
ArkNettyWebServer webServer = (ArkNettyWebServer) createNettyWebServer(contextPath,
httpServer, adapter, lifecycleTimeout);
webServer.setRouteProviders(this.routeProviders);

return webServer;
Expand All @@ -103,15 +114,20 @@ public String getContextPath() {
if (StringUtils.isEmpty(biz.getWebContextPath())) {
return ROOT_WEB_CONTEXT_PATH;
}
return biz.getWebContextPath();
contextPath = biz.getWebContextPath();
if (!contextPath.startsWith("/")) {
contextPath = "/" + contextPath;
}
return contextPath;
} else {
return ROOT_WEB_CONTEXT_PATH;
}
}

WebServer createNettyWebServer(HttpServer httpServer, ReactorHttpHandlerAdapter handlerAdapter,
WebServer createNettyWebServer(String contextPath, HttpServer httpServer,
ReactorHttpHandlerAdapter handlerAdapter,
Duration lifecycleTimeout) {
return new ArkNettyWebServer(httpServer, handlerAdapter, lifecycleTimeout);
return new ArkNettyWebServer(contextPath, httpServer, handlerAdapter, lifecycleTimeout);
}

private HttpServer initEmbedNetty(){
Expand Down

0 comments on commit 361d445

Please sign in to comment.