Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Triple Rest Openapi Support #14924

Merged
merged 24 commits into from
Dec 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading