Skip to content

Commit

Permalink
Triple Rest Openapi Support (#14924)
Browse files Browse the repository at this point in the history
  • Loading branch information
oxsean authored Dec 11, 2024
1 parent 779faa9 commit 92b1ac1
Show file tree
Hide file tree
Showing 240 changed files with 15,771 additions and 765 deletions.
1 change: 1 addition & 0 deletions .artifacts
Original file line number Diff line number Diff line change
Expand Up @@ -112,5 +112,6 @@ dubbo-xds
dubbo-plugin-loom
dubbo-rest-jaxrs
dubbo-rest-spring
dubbo-rest-openapi
dubbo-triple-servlet
dubbo-triple-websocket
8 changes: 8 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
Expand Up @@ -287,3 +287,11 @@ This product contains a modified portion of 'Istio', an open platform to connect
under a "Apache License 2.0" license, see https://github.com/istio/api/blob/master/LICENSE:

* security/v1alpha1/ca.proto

For the file dubbo-plugin/dubbo-rest-openapi/src/main/resources/META-INF/resources/swagger-ui/index.html:

Under a "Apache License 2.0" license, see https://github.com/swagger-api/swagger-ui/blob/master/LICENSE

For the file dubbo-plugin/dubbo-rest-openapi/src/main/resources/META-INF/resources/redoc/index.html:

Under a "MIT License" license, see https://github.com/Redocly/redoc/blob/main/LICENSE
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@
import org.apache.dubbo.rpc.cluster.support.ClusterUtils;
import org.apache.dubbo.rpc.model.ApplicationModel;
import org.apache.dubbo.rpc.model.FrameworkModel;
import org.apache.dubbo.rpc.model.ModuleModel;
import org.apache.dubbo.rpc.model.ScopeModelInitializer;

public class ClusterScopeModelInitializer implements ScopeModelInitializer {

@Override
public void initializeFrameworkModel(FrameworkModel frameworkModel) {
ScopeBeanFactory beanFactory = frameworkModel.getBeanFactory();
Expand All @@ -36,7 +36,4 @@ public void initializeApplicationModel(ApplicationModel applicationModel) {
ScopeBeanFactory beanFactory = applicationModel.getBeanFactory();
beanFactory.registerBean(ClusterUtils.class);
}

@Override
public void initializeModuleModel(ModuleModel moduleModel) {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,20 +19,13 @@
import org.apache.dubbo.common.beans.factory.ScopeBeanFactory;
import org.apache.dubbo.rpc.cluster.merger.MergerFactory;
import org.apache.dubbo.rpc.model.ApplicationModel;
import org.apache.dubbo.rpc.model.FrameworkModel;
import org.apache.dubbo.rpc.model.ModuleModel;
import org.apache.dubbo.rpc.model.ScopeModelInitializer;

public class MergeableClusterScopeModelInitializer implements ScopeModelInitializer {
@Override
public void initializeFrameworkModel(FrameworkModel frameworkModel) {}

@Override
public void initializeApplicationModel(ApplicationModel applicationModel) {
ScopeBeanFactory beanFactory = applicationModel.getBeanFactory();
beanFactory.registerBean(MergerFactory.class);
}

@Override
public void initializeModuleModel(ModuleModel moduleModel) {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,10 @@

import org.apache.dubbo.common.beans.factory.ScopeBeanFactory;
import org.apache.dubbo.rpc.cluster.router.mesh.route.MeshRuleManager;
import org.apache.dubbo.rpc.model.ApplicationModel;
import org.apache.dubbo.rpc.model.FrameworkModel;
import org.apache.dubbo.rpc.model.ModuleModel;
import org.apache.dubbo.rpc.model.ScopeModelInitializer;

public class MeshScopeModelInitializer implements ScopeModelInitializer {
@Override
public void initializeFrameworkModel(FrameworkModel frameworkModel) {}

@Override
public void initializeApplicationModel(ApplicationModel applicationModel) {}

public void initializeModuleModel(ModuleModel moduleModel) {
ScopeBeanFactory beanFactory = moduleModel.getBeanFactory();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,12 @@
import org.apache.dubbo.common.logger.ErrorTypeAwareLogger;
import org.apache.dubbo.common.logger.LoggerFactory;
import org.apache.dubbo.common.resource.Disposable;
import org.apache.dubbo.common.resource.Initializable;
import org.apache.dubbo.common.utils.CollectionUtils;
import org.apache.dubbo.common.utils.ConcurrentHashSet;
import org.apache.dubbo.common.utils.Pair;
import org.apache.dubbo.common.utils.StringUtils;
import org.apache.dubbo.common.utils.TypeUtils;
import org.apache.dubbo.rpc.model.ScopeModelAccessor;

import java.util.ArrayList;
Expand All @@ -39,6 +41,7 @@
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Collectors;

import static org.apache.dubbo.common.constants.LoggerCodeConstants.CONFIG_FAILED_DESTROY_INVOKER;
Expand All @@ -55,6 +58,7 @@ public final class ScopeBeanFactory {
private final List<ExtensionPostProcessor> extensionPostProcessors;
private final Map<Class<?>, AtomicInteger> beanNameIdCounterMap = CollectionUtils.newConcurrentHashMap();
private final List<BeanInfo> registeredBeanInfos = new CopyOnWriteArrayList<>();
private final List<BeanDefinition<?>> registeredBeanDefinitions = new CopyOnWriteArrayList<>();
private InstantiationStrategy instantiationStrategy;
private final AtomicBoolean destroyed = new AtomicBoolean();
private final Set<Class<?>> registeredClasses = new ConcurrentHashSet<>();
Expand All @@ -79,14 +83,35 @@ private void initInstantiationStrategy() {
}
}

public <T> T registerBean(Class<T> bean) throws ScopeBeanException {
return getOrRegisterBean(null, bean);
public <T> T registerBean(Class<T> clazz) throws ScopeBeanException {
return getOrRegisterBean(null, clazz);
}

public <T> T registerBean(String name, Class<T> clazz) throws ScopeBeanException {
return getOrRegisterBean(name, clazz);
}

public <T> void registerBeanDefinition(Class<T> clazz) {
registerBeanDefinition(null, clazz);
}

public <T> void registerBeanDefinition(String name, Class<T> clazz) {
registeredBeanDefinitions.add(new BeanDefinition<>(name, clazz));
}

public <T> void registerBeanFactory(Supplier<T> factory) {
registerBeanFactory(null, factory);
}

@SuppressWarnings("unchecked")
public <T> void registerBeanFactory(String name, Supplier<T> factory) {
Class<T> clazz = (Class<T>) TypeUtils.getSuperGenericType(factory.getClass(), 0);
if (clazz == null) {
throw new ScopeBeanException("unable to determine bean class from factory's superclass or interface");
}
registeredBeanDefinitions.add(new BeanDefinition<>(name, clazz, factory));
}

private <T> T createAndRegisterBean(String name, Class<T> clazz) {
checkDestroyed();
T instance = getBean(name, clazz);
Expand Down Expand Up @@ -174,6 +199,9 @@ private void initializeBean(String name, Object bean) {
for (ExtensionPostProcessor processor : extensionPostProcessors) {
processor.postProcessAfterInitialization(bean, name);
}
if (bean instanceof Initializable) {
((Initializable) bean).initialize(extensionAccessor);
}
} catch (Exception e) {
throw new ScopeBeanException(
"register bean failed! name=" + name + ", type="
Expand All @@ -182,9 +210,48 @@ private void initializeBean(String name, Object bean) {
}
}

@SuppressWarnings("SynchronizationOnLocalVariableOrMethodParameter")
private void initializeBeanDefinitions(Class<?> type) {
for (int i = 0, size = registeredBeanDefinitions.size(); i < size; i++) {
BeanDefinition<?> definition = registeredBeanDefinitions.get(i);
if (definition.initialized) {
continue;
}

Class<?> beanClass = definition.beanClass;
if (!type.isAssignableFrom(beanClass)) {
continue;
}
synchronized (type) {
if (definition.initialized) {
continue;
}

Object bean;
Supplier<?> factory = definition.beanFactory;
if (factory == null) {
try {
bean = instantiationStrategy.instantiate(beanClass);
} catch (Throwable e) {
throw new ScopeBeanException("create bean instance failed, type=" + beanClass.getName(), e);
}
} else {
initializeBean(definition.name, factory);
try {
bean = factory.get();
} catch (Exception e) {
throw new ScopeBeanException("create bean instance failed, type=" + beanClass.getName(), e);
}
}
registerBean(definition.name, bean);
definition.initialized = true;
}
}
}

private boolean containsBean(String name, Object bean) {
for (BeanInfo beanInfo : registeredBeanInfos) {
if (beanInfo.instance == bean && (name == null || StringUtils.isEquals(name, beanInfo.name))) {
if (beanInfo.instance == bean && (name == null || name.equals(beanInfo.name))) {
return true;
}
}
Expand All @@ -199,6 +266,7 @@ private int getNextId(Class<?> beanClass) {

@SuppressWarnings("unchecked")
public <T> List<T> getBeansOfType(Class<T> type) {
initializeBeanDefinitions(type);
List<T> currentBeans = (List<T>) registeredBeanInfos.stream()
.filter(beanInfo -> type.isInstance(beanInfo.instance))
.map(beanInfo -> beanInfo.instance)
Expand All @@ -223,19 +291,23 @@ public <T> T getBean(String name, Class<T> type) {

@SuppressWarnings("unchecked")
private <T> T getBeanFromCache(String name, Class<T> type) {
Object value = beanCache
.computeIfAbsent(Pair.of(type, name), k -> {
try {
return Optional.ofNullable(getBeanInternal(name, type));
} catch (ScopeBeanException e) {
return Optional.of(e);
}
})
.orElse(null);
if (value instanceof ScopeBeanException) {
throw (ScopeBeanException) value;
Pair<Class<?>, String> key = Pair.of(type, name);
Optional<Object> value = beanCache.get(key);
if (value == null) {
initializeBeanDefinitions(type);
value = beanCache.computeIfAbsent(key, k -> {
try {
return Optional.ofNullable(getBeanInternal(name, type));
} catch (ScopeBeanException e) {
return Optional.of(e);
}
});
}
Object bean = value.orElse(null);
if (bean instanceof ScopeBeanException) {
throw (ScopeBeanException) bean;
}
return (T) value;
return (T) bean;
}

@SuppressWarnings("unchecked")
Expand Down Expand Up @@ -301,6 +373,7 @@ public void destroy() {
}
}
registeredBeanInfos.clear();
registeredBeanDefinitions.clear();
beanCache.clear();
}
}
Expand All @@ -315,16 +388,36 @@ private void checkDestroyed() {
}
}

static class BeanInfo {
static final class BeanInfo {
private final String name;
private final Object instance;

public BeanInfo(String name, Object instance) {
BeanInfo(String name, Object instance) {
this.name = name;
this.instance = instance;
}
}

static final class BeanDefinition<T> {

private final String name;
private final Class<T> beanClass;
private final Supplier<T> beanFactory;
private volatile boolean initialized;

BeanDefinition(String name, Class<T> beanClass) {
this.name = name;
this.beanClass = beanClass;
beanFactory = null;
}

BeanDefinition(String name, Class<T> beanClass, Supplier<T> beanFactory) {
this.name = name;
this.beanClass = beanClass;
this.beanFactory = beanFactory;
}
}

public Set<Class<?>> getRegisteredClasses() {
return registeredClasses;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* 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 org.apache.dubbo.common.resource;

import org.apache.dubbo.common.extension.ExtensionAccessor;

/**
* An interface for Initializing resources
*/
public interface Initializable {

default void initialize(ExtensionAccessor accessor) {
initialize();
}

default void initialize() {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
*/
package org.apache.dubbo.common.utils;

import org.apache.dubbo.common.constants.CommonConstants;
import org.apache.dubbo.common.convert.ConverterUtil;
import org.apache.dubbo.rpc.model.FrameworkModel;

Expand Down Expand Up @@ -670,4 +671,8 @@ public static String[] getDeclaredMethodNames(Class<?> tClass) {
dmns.sort(Comparator.naturalOrder());
return dmns.toArray(new String[0]);
}

public static boolean hasProtobuf() {
return isPresent(CommonConstants.PROTOBUF_MESSAGE_CLASS_NAME);
}
}
Loading

0 comments on commit 92b1ac1

Please sign in to comment.