/*
* Copyright (c) MuleSoft, Inc. All rights reserved. http://www.mulesoft.com
* The software in this package is published under the terms of the CPAL v1.0
* license, a copy of which has been included with this distribution in the
* LICENSE.txt file.
*/
package org.mule.runtime.config.spring.dsl.model.internal;
import static java.lang.String.format;
import static org.apache.commons.lang.StringUtils.isBlank;
import static org.mule.runtime.api.component.ComponentIdentifier.builder;
import static org.mule.runtime.api.util.Preconditions.checkArgument;
import static org.mule.runtime.extension.api.ExtensionConstants.INFRASTRUCTURE_PARAMETER_NAMES;
import static org.mule.runtime.extension.api.ExtensionConstants.POOLING_PROFILE_PARAMETER_NAME;
import static org.mule.runtime.extension.api.ExtensionConstants.RECONNECTION_STRATEGY_PARAMETER_NAME;
import static org.mule.runtime.extension.api.ExtensionConstants.REDELIVERY_POLICY_PARAMETER_NAME;
import static org.mule.runtime.extension.api.ExtensionConstants.STREAMING_STRATEGY_PARAMETER_NAME;
import static org.mule.runtime.extension.api.ExtensionConstants.TLS_PARAMETER_NAME;
import static org.mule.runtime.extension.api.declaration.type.ReconnectionStrategyTypeBuilder.RECONNECT_ALIAS;
import static org.mule.runtime.extension.api.declaration.type.StreamingStrategyTypeBuilder.REPEATABLE_FILE_STORE_BYTES_STREAM_ALIAS;
import static org.mule.runtime.extension.api.declaration.type.StreamingStrategyTypeBuilder.REPEATABLE_FILE_STORE_OBJECTS_STREAM_ALIAS;
import static org.mule.runtime.internal.dsl.DslConstants.CORE_PREFIX;
import static org.mule.runtime.internal.dsl.DslConstants.EE_PREFIX;
import static org.mule.runtime.internal.dsl.DslConstants.POOLING_PROFILE_ELEMENT_IDENTIFIER;
import static org.mule.runtime.internal.dsl.DslConstants.RECONNECT_ELEMENT_IDENTIFIER;
import static org.mule.runtime.internal.dsl.DslConstants.RECONNECT_FOREVER_ELEMENT_IDENTIFIER;
import static org.mule.runtime.internal.dsl.DslConstants.REDELIVERY_POLICY_ELEMENT_IDENTIFIER;
import static org.mule.runtime.internal.dsl.DslConstants.TLS_CONTEXT_ELEMENT_IDENTIFIER;
import static org.mule.runtime.internal.dsl.DslConstants.TLS_PREFIX;
import org.mule.runtime.api.app.declaration.ParameterValue;
import org.mule.runtime.api.app.declaration.ParameterValueVisitor;
import org.mule.runtime.api.app.declaration.fluent.ParameterObjectValue;
import org.mule.runtime.api.app.declaration.fluent.ParameterSimpleValue;
import org.mule.runtime.api.meta.model.parameter.ParameterModel;
import org.mule.runtime.config.spring.dsl.model.DslElementModel;
import org.mule.runtime.dsl.api.component.config.ComponentConfiguration;
import org.mule.runtime.extension.api.dsl.syntax.DslElementSyntax;
import com.google.common.collect.ImmutableSet;
import java.util.Set;
/**
* Delegate to be used by a {@link DeclarationBasedElementModelFactory} in order to
* resolve the {@link DslElementModel} of an infrastructure parameter.
*
* @since 4.0
*/
class InfrastructureElementModelDelegate {
private final Set<String> eeStreamingStrategies =
ImmutableSet.of(REPEATABLE_FILE_STORE_BYTES_STREAM_ALIAS, REPEATABLE_FILE_STORE_OBJECTS_STREAM_ALIAS);
public void addParameter(String parameterName, ParameterValue value,
ParameterModel parameterModel,
DslElementSyntax paramDsl,
ComponentConfiguration.Builder parentConfig,
DslElementModel.Builder parentElement) {
checkArgument(INFRASTRUCTURE_PARAMETER_NAMES.contains(parameterName),
format("The parameter '%s' is not of infrastructure kind", parameterName));
switch (parameterName) {
case RECONNECTION_STRATEGY_PARAMETER_NAME:
createReconnectionStrategy(value, parameterModel, paramDsl, parentConfig, parentElement);
return;
case STREAMING_STRATEGY_PARAMETER_NAME:
createStreamingStrategy(value, parameterModel, paramDsl, parentConfig, parentElement);
return;
case REDELIVERY_POLICY_PARAMETER_NAME:
cloneDeclarationToElement(parameterModel, paramDsl, parentConfig, parentElement,
(ParameterObjectValue) value,
REDELIVERY_POLICY_ELEMENT_IDENTIFIER, paramDsl.getNamespace());
return;
case POOLING_PROFILE_PARAMETER_NAME:
cloneDeclarationToElement(parameterModel, paramDsl, parentConfig, parentElement,
(ParameterObjectValue) value,
POOLING_PROFILE_ELEMENT_IDENTIFIER, paramDsl.getNamespace());
return;
case TLS_PARAMETER_NAME:
createTlsContext(value, parameterModel, paramDsl, parentConfig, parentElement);
return;
default:
value.accept(new ParameterValueVisitor() {
@Override
public void visitSimpleValue(ParameterSimpleValue text) {
parentConfig.withParameter(parameterName, text.getValue());
parentElement.containing(DslElementModel.builder()
.withModel(parameterModel)
.withDsl(paramDsl)
.withValue(text.getValue())
.build());
}
});
}
}
private void createTlsContext(ParameterValue value,
ParameterModel parameterModel,
DslElementSyntax paramDsl,
ComponentConfiguration.Builder parentConfig,
DslElementModel.Builder parentElement) {
value.accept(new ParameterValueVisitor() {
@Override
public void visitSimpleValue(ParameterSimpleValue text) {
parentConfig.withParameter(TLS_PARAMETER_NAME, text.getValue());
parentElement.containing(DslElementModel.builder()
.withModel(parameterModel)
.withDsl(paramDsl)
.build());
}
@Override
public void visitObjectValue(ParameterObjectValue objectValue) {
ComponentConfiguration.Builder tlsConfig = ComponentConfiguration.builder()
.withIdentifier(builder()
.withNamespace(TLS_PREFIX)
.withName(TLS_CONTEXT_ELEMENT_IDENTIFIER)
.build());
objectValue.getParameters()
.forEach((name, value) -> value.accept(new ParameterValueVisitor() {
@Override
public void visitSimpleValue(ParameterSimpleValue text) {
tlsConfig.withParameter(name, text.getValue());
}
@Override
public void visitObjectValue(ParameterObjectValue objectValue) {
ComponentConfiguration.Builder nested = ComponentConfiguration.builder()
.withIdentifier(builder()
.withNamespace(TLS_PREFIX)
.withName(name)
.build());
cloneParameters(objectValue, nested);
tlsConfig.withNestedComponent(nested.build());
}
}));
addParameterElement(parameterModel, paramDsl, parentConfig, parentElement, tlsConfig.build());
}
});
}
private void createReconnectionStrategy(ParameterValue value,
ParameterModel parameterModel,
DslElementSyntax paramDsl,
ComponentConfiguration.Builder parentConfig,
DslElementModel.Builder parentElement) {
ParameterObjectValue objectValue = (ParameterObjectValue) value;
checkArgument(!isBlank(objectValue.getTypeId()), "Missing declaration of which reconnection to use");
String elementName = objectValue.getTypeId().equals(RECONNECT_ALIAS)
? RECONNECT_ELEMENT_IDENTIFIER : RECONNECT_FOREVER_ELEMENT_IDENTIFIER;
cloneDeclarationToElement(parameterModel, paramDsl, parentConfig, parentElement, objectValue, elementName,
paramDsl.getNamespace());
}
private void createStreamingStrategy(ParameterValue value,
ParameterModel parameterModel,
DslElementSyntax paramDsl,
ComponentConfiguration.Builder parentConfig,
DslElementModel.Builder parentElement) {
ParameterObjectValue objectValue = (ParameterObjectValue) value;
checkArgument(!isBlank(objectValue.getTypeId()), "Missing declaration of which streaming strategy to use");
String namespace = eeStreamingStrategies.contains(objectValue.getTypeId()) ? EE_PREFIX : CORE_PREFIX;
cloneDeclarationToElement(parameterModel, paramDsl, parentConfig, parentElement, objectValue, objectValue.getTypeId(),
namespace);
}
private void cloneDeclarationToElement(ParameterModel parameterModel, DslElementSyntax paramDsl,
ComponentConfiguration.Builder parentConfig, DslElementModel.Builder parentElement,
ParameterObjectValue objectValue, String elementName, String customNamespace) {
ComponentConfiguration.Builder config = ComponentConfiguration.builder()
.withIdentifier(builder()
.withNamespace(isBlank(customNamespace) ? CORE_PREFIX : customNamespace)
.withName(elementName)
.build());
cloneParameters(objectValue, config);
addParameterElement(parameterModel, paramDsl, parentConfig, parentElement, config.build());
}
private void addParameterElement(ParameterModel parameterModel, DslElementSyntax paramDsl,
ComponentConfiguration.Builder parentConfig, DslElementModel.Builder parentElement,
ComponentConfiguration result) {
parentConfig.withNestedComponent(result);
parentElement.containing(DslElementModel.builder()
.withModel(parameterModel)
.withDsl(paramDsl)
.withConfig(result).build());
}
private void cloneParameters(ParameterObjectValue objectValue, final ComponentConfiguration.Builder redeliveryConfig) {
objectValue.getParameters()
.forEach((name, value) -> value.accept(new ParameterValueVisitor() {
@Override
public void visitSimpleValue(ParameterSimpleValue text) {
redeliveryConfig.withParameter(name, text.getValue());
}
}));
}
}