GH-9683: Remove deprecated Groovy components for Control Bus
Related to: https://github.com/spring-projects/spring-integration/issues/9683 The functionality is now fully covered by the `ControlBusCommandRegistry` API
This commit is contained in:
@@ -1,160 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-2024 the original author or authors.
|
||||
*
|
||||
* Licensed 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
|
||||
*
|
||||
* https://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.springframework.integration.groovy;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
import groovy.lang.Binding;
|
||||
import groovy.lang.GString;
|
||||
|
||||
import org.springframework.integration.IntegrationPattern;
|
||||
import org.springframework.integration.IntegrationPatternType;
|
||||
import org.springframework.integration.scripting.AbstractScriptExecutingMessageProcessor;
|
||||
import org.springframework.integration.scripting.ScriptVariableGenerator;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.scripting.ScriptSource;
|
||||
import org.springframework.scripting.groovy.GroovyObjectCustomizer;
|
||||
import org.springframework.scripting.groovy.GroovyScriptFactory;
|
||||
import org.springframework.scripting.support.StaticScriptSource;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
* @author Mark Fisher
|
||||
* @author Oleg Zhurakousky
|
||||
* @author Artem Bilan
|
||||
* @author Stefan Reuter
|
||||
* @author Gary Russell
|
||||
*
|
||||
* @since 2.0
|
||||
*
|
||||
* @deprecated in favor of {@link org.springframework.integration.handler.ControlBusMessageProcessor}
|
||||
*/
|
||||
@Deprecated(since = "6.4", forRemoval = true)
|
||||
public class GroovyCommandMessageProcessor extends AbstractScriptExecutingMessageProcessor<Object>
|
||||
implements IntegrationPattern {
|
||||
|
||||
private GroovyObjectCustomizer customizer;
|
||||
|
||||
@Nullable
|
||||
private Binding binding;
|
||||
|
||||
/**
|
||||
* Creates a {@link GroovyCommandMessageProcessor} that will use the
|
||||
* {@link org.springframework.integration.scripting.DefaultScriptVariableGenerator}.
|
||||
*/
|
||||
public GroovyCommandMessageProcessor() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link GroovyCommandMessageProcessor} that will use the provided {@link ScriptVariableGenerator}.
|
||||
* @param scriptVariableGenerator The variable generator.
|
||||
*/
|
||||
public GroovyCommandMessageProcessor(ScriptVariableGenerator scriptVariableGenerator) {
|
||||
super(scriptVariableGenerator);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link GroovyCommandMessageProcessor} that will use the
|
||||
* {@link org.springframework.integration.scripting.DefaultScriptVariableGenerator}
|
||||
* and provided {@link Binding}.
|
||||
* Provided 'binding' will be used in the {@link BindingOverwriteGroovyObjectCustomizerDecorator} to overwrite
|
||||
* original Groovy Script 'binding'.
|
||||
* @param binding The binding.
|
||||
*/
|
||||
public GroovyCommandMessageProcessor(Binding binding) {
|
||||
Assert.notNull(binding, "binding must not be null");
|
||||
this.binding = binding;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link GroovyCommandMessageProcessor} that will use the provided {@link ScriptVariableGenerator} and
|
||||
* Binding.
|
||||
* Provided 'binding' will be used in the {@link BindingOverwriteGroovyObjectCustomizerDecorator} to overwrite
|
||||
* original Groovy Script 'binding'.
|
||||
* @param binding The binding.
|
||||
* @param scriptVariableGenerator The variable generator.
|
||||
*/
|
||||
public GroovyCommandMessageProcessor(Binding binding, ScriptVariableGenerator scriptVariableGenerator) {
|
||||
this(scriptVariableGenerator);
|
||||
Assert.notNull(binding, "binding must not be null");
|
||||
this.binding = binding;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a {@link GroovyObjectCustomizer} for this processor.
|
||||
* @param customizer The customizer.
|
||||
*/
|
||||
public void setCustomizer(GroovyObjectCustomizer customizer) {
|
||||
this.customizer = customizer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IntegrationPatternType getIntegrationPatternType() {
|
||||
return IntegrationPatternType.control_bus;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ScriptSource getScriptSource(Message<?> message) {
|
||||
Object payload = message.getPayload();
|
||||
Assert.isInstanceOf(String.class, payload, "Payload must be a String containing a Groovy script.");
|
||||
String className = generateScriptName(message);
|
||||
return new StaticScriptSource((String) payload, className);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object executeScript(ScriptSource scriptSource, Map<String, Object> variables) {
|
||||
Assert.notNull(scriptSource, "scriptSource must not be null");
|
||||
VariableBindingGroovyObjectCustomizerDecorator customizerDecorator =
|
||||
this.binding != null
|
||||
? new BindingOverwriteGroovyObjectCustomizerDecorator(this.binding)
|
||||
: new VariableBindingGroovyObjectCustomizerDecorator();
|
||||
if (this.customizer != null) {
|
||||
customizerDecorator.setCustomizer(this.customizer);
|
||||
}
|
||||
if (!CollectionUtils.isEmpty(variables)) {
|
||||
customizerDecorator.setVariables(variables);
|
||||
}
|
||||
GroovyScriptFactory factory = new GroovyScriptFactory(getClass().getSimpleName(), customizerDecorator);
|
||||
ClassLoader beanClassLoader = getBeanClassLoader();
|
||||
if (beanClassLoader != null) {
|
||||
factory.setBeanClassLoader(beanClassLoader);
|
||||
}
|
||||
factory.setBeanFactory(getBeanFactory());
|
||||
try {
|
||||
Object result = factory.getScriptedObject(scriptSource);
|
||||
return (result instanceof GString) ? result.toString() : result;
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new UncheckedIOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
protected String generateScriptName(Message<?> message) {
|
||||
// Don't use the same script (class) name for all invocations by default
|
||||
UUID id = message.getHeaders().getId();
|
||||
return getClass().getSimpleName()
|
||||
+ (id != null ? id.toString().replaceAll("-", "") : ObjectUtils.getIdentityHexString(message));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,158 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-2024 the original author or authors.
|
||||
*
|
||||
* Licensed 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
|
||||
*
|
||||
* https://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.springframework.integration.groovy.config;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import groovy.lang.Binding;
|
||||
import groovy.lang.MissingPropertyException;
|
||||
|
||||
import org.springframework.beans.factory.BeanClassLoaderAware;
|
||||
import org.springframework.beans.factory.BeanCreationNotAllowedException;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.context.Lifecycle;
|
||||
import org.springframework.core.annotation.AnnotationUtils;
|
||||
import org.springframework.integration.config.AbstractSimpleMessageHandlerFactoryBean;
|
||||
import org.springframework.integration.handler.ServiceActivatingHandler;
|
||||
import org.springframework.integration.support.management.IntegrationManagedResource;
|
||||
import org.springframework.jmx.export.annotation.ManagedResource;
|
||||
import org.springframework.messaging.MessageHandler;
|
||||
import org.springframework.scripting.groovy.GroovyObjectCustomizer;
|
||||
import org.springframework.util.CustomizableThreadCreator;
|
||||
|
||||
/**
|
||||
* FactoryBean for creating {@link MessageHandler} instances to handle a message as a Groovy Script.
|
||||
*
|
||||
* @author Dave Syer
|
||||
* @author Oleg Zhurakousky
|
||||
* @author Mark Fisher
|
||||
* @author Artem Bilan
|
||||
* @author Stefan Reuter
|
||||
* @author Gary Russell
|
||||
*
|
||||
* @since 2.0
|
||||
*
|
||||
* @deprecated in favor of {@link org.springframework.integration.config.ControlBusFactoryBean}
|
||||
*/
|
||||
@Deprecated(since = "6.4", forRemoval = true)
|
||||
public class GroovyControlBusFactoryBean extends AbstractSimpleMessageHandlerFactoryBean<MessageHandler>
|
||||
implements BeanClassLoaderAware {
|
||||
|
||||
private volatile Long sendTimeout;
|
||||
|
||||
private volatile GroovyObjectCustomizer customizer;
|
||||
|
||||
private volatile ClassLoader beanClassLoader;
|
||||
|
||||
public void setSendTimeout(Long sendTimeout) {
|
||||
this.sendTimeout = sendTimeout;
|
||||
}
|
||||
|
||||
public void setCustomizer(GroovyObjectCustomizer customizer) {
|
||||
this.customizer = customizer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBeanClassLoader(ClassLoader classLoader) {
|
||||
this.beanClassLoader = classLoader;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("removal")
|
||||
protected MessageHandler createHandler() {
|
||||
Binding binding = new ManagedBeansBinding(this.getBeanFactory());
|
||||
org.springframework.integration.groovy.GroovyCommandMessageProcessor processor =
|
||||
new org.springframework.integration.groovy.GroovyCommandMessageProcessor(binding,
|
||||
message -> {
|
||||
Map<String, Object> variables = new HashMap<>();
|
||||
variables.put("headers", message.getHeaders());
|
||||
return variables;
|
||||
});
|
||||
if (this.customizer != null) {
|
||||
processor.setCustomizer(this.customizer);
|
||||
}
|
||||
if (this.beanClassLoader != null) {
|
||||
processor.setBeanClassLoader(this.beanClassLoader);
|
||||
}
|
||||
if (getBeanFactory() != null) {
|
||||
processor.setBeanFactory(getBeanFactory());
|
||||
}
|
||||
return this.configureHandler(new ServiceActivatingHandler(processor));
|
||||
}
|
||||
|
||||
private ServiceActivatingHandler configureHandler(ServiceActivatingHandler handler) {
|
||||
if (this.sendTimeout != null) {
|
||||
handler.setSendTimeout(this.sendTimeout);
|
||||
}
|
||||
return handler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Bridge {@link Binding} implementation which uses <code>beanFactory</code>
|
||||
* to resolve Groovy variable as delegate if the last one isn't contained
|
||||
* in the original Groovy script {@link Binding}.
|
||||
* In additionally beans should be 'managed' with specific properties which
|
||||
* are allowed in the Control Bus operations.
|
||||
*/
|
||||
private static final class ManagedBeansBinding extends Binding {
|
||||
|
||||
private final ConfigurableListableBeanFactory beanFactory;
|
||||
|
||||
private ManagedBeansBinding(BeanFactory beanFactory) {
|
||||
this.beanFactory = (beanFactory instanceof ConfigurableListableBeanFactory)
|
||||
? (ConfigurableListableBeanFactory) beanFactory : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getVariable(String name) {
|
||||
try {
|
||||
return super.getVariable(name);
|
||||
}
|
||||
catch (MissingPropertyException e) {
|
||||
// Original {@link Binding} doesn't have 'variable' for the given 'name'.
|
||||
// Try to resolve it as 'managed bean' from the given <code>beanFactory</code>.
|
||||
}
|
||||
if (this.beanFactory == null) {
|
||||
throw new MissingPropertyException(name, this.getClass());
|
||||
}
|
||||
|
||||
Object bean = null;
|
||||
try {
|
||||
bean = this.beanFactory.getBean(name);
|
||||
}
|
||||
catch (NoSuchBeanDefinitionException e) {
|
||||
throw new MissingPropertyException(name, this.getClass(), e);
|
||||
}
|
||||
|
||||
if (bean instanceof Lifecycle ||
|
||||
bean instanceof CustomizableThreadCreator ||
|
||||
(AnnotationUtils.findAnnotation(bean.getClass(), ManagedResource.class) != null) ||
|
||||
(AnnotationUtils.findAnnotation(bean.getClass(), IntegrationManagedResource.class) != null)) {
|
||||
return bean;
|
||||
}
|
||||
throw new BeanCreationNotAllowedException(name,
|
||||
"Only beans with @ManagedResource or beans which implement " +
|
||||
"org.springframework.context.Lifecycle or org.springframework.util.CustomizableThreadCreator " +
|
||||
"are allowed to use as ControlBus components.");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-2024 the original author or authors.
|
||||
*
|
||||
* Licensed 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
|
||||
*
|
||||
* https://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.springframework.integration.groovy.config;
|
||||
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.beans.factory.xml.ParserContext;
|
||||
import org.springframework.integration.config.xml.AbstractConsumerEndpointParser;
|
||||
import org.springframework.integration.config.xml.IntegrationNamespaceUtils;
|
||||
|
||||
/**
|
||||
* Parser for the <groovy:control-bus/> element.
|
||||
*
|
||||
* @author Dave Syer
|
||||
* @author Artem Bilan
|
||||
*
|
||||
* @since 2.0
|
||||
*
|
||||
* @deprecated in favor of {@link org.springframework.integration.config.xml.ControlBusParser}
|
||||
*/
|
||||
@Deprecated(since = "6.4", forRemoval = true)
|
||||
public class GroovyControlBusParser extends AbstractConsumerEndpointParser {
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("removal")
|
||||
protected BeanDefinitionBuilder parseHandler(Element element, ParserContext parserContext) {
|
||||
BeanDefinitionBuilder builder =
|
||||
BeanDefinitionBuilder.genericBeanDefinition(
|
||||
org.springframework.integration.groovy.config.GroovyControlBusFactoryBean.class);
|
||||
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "customizer");
|
||||
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "send-timeout");
|
||||
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "order");
|
||||
return builder;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2024 the original author or authors.
|
||||
* Copyright 2002-2025 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -26,10 +26,8 @@ import org.springframework.integration.config.xml.AbstractIntegrationNamespaceHa
|
||||
*/
|
||||
public class GroovyNamespaceHandler extends AbstractIntegrationNamespaceHandler {
|
||||
|
||||
@SuppressWarnings("removal")
|
||||
public void init() {
|
||||
registerBeanDefinitionParser("script", new GroovyScriptParser());
|
||||
registerBeanDefinitionParser("control-bus", new GroovyControlBusParser());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -65,39 +65,4 @@
|
||||
</xsd:complexContent>
|
||||
</xsd:complexType>
|
||||
|
||||
|
||||
<xsd:element name="control-bus">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
[DEPRECATED in favor 'control-bus' component from core module]
|
||||
Control bus ('org.springframework.integration.groovy.config.GroovyControlBusFactoryBean') that accepts
|
||||
messages in the form of Groovy scripts. The scripts should be provided as
|
||||
String payload in incoming messages. The variable bindings will include any @ManagedResource, Lifecycle,
|
||||
or CustomizableThreadCreator instances from within the ApplicationContext.
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:complexType>
|
||||
<xsd:choice minOccurs="0" maxOccurs="2">
|
||||
<xsd:element ref="integration:poller" minOccurs="0"
|
||||
maxOccurs="1"/>
|
||||
<xsd:element name="transactional" type="integration:transactionalType" minOccurs="0" maxOccurs="1"/>
|
||||
<xsd:element name="request-handler-advice-chain" type="integration:handlerAdviceChainType"
|
||||
minOccurs="0" maxOccurs="1"/>
|
||||
</xsd:choice>
|
||||
<xsd:attributeGroup ref="integration:inputOutputChannelGroup"/>
|
||||
<xsd:attribute name="customizer" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
Reference to a GroovyObjectCustomizer bean to be
|
||||
applied to each script payload.
|
||||
</xsd:documentation>
|
||||
<xsd:appinfo>
|
||||
<tool:expected-type
|
||||
type="org.springframework.scripting.groovy.GroovyObjectCustomizer"/>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
|
||||
</xsd:schema>
|
||||
|
||||
Reference in New Issue
Block a user