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

feat(QTDI-723): fixed schema #944

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/**
* Copyright (C) 2006-2024 Talend Inc. - www.talend.com
*
* 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
*
* 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.talend.sdk.component.api.service.schema;

import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

import java.lang.annotation.Retention;
import java.lang.annotation.Target;

import org.talend.sdk.component.api.meta.Documentation;

@Target(TYPE)
@Retention(RUNTIME)
@Documentation("Mark a connector as having a fixed schema. " +
"Annotation's value must match the name of a DiscoverSchema or a DiscoverSchemaExtended annotation. " +
"The related action will return the fixed schema.")
public @interface FixedSchema {

String value() default "";
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/**
* Copyright (C) 2006-2024 Talend Inc. - www.talend.com
*
* 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
*
* 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.talend.sdk.component.runtime.manager.reflect.parameterenricher;

import static java.util.Collections.emptyMap;

import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import java.util.HashMap;
import java.util.Map;

import org.talend.sdk.component.api.service.schema.FixedSchema;

public class SchemaParameterEnricher extends BaseParameterEnricher {

public static final String META_PREFIX = "tcomp::ui::schema::fixed";

@Override
public Map<String, String> onParameterAnnotation(final String parameterName, final Type parameterType,
final Annotation annotation) {
if (FixedSchema.class.equals(annotation.annotationType())) {
FixedSchema fixed = FixedSchema.class.cast(annotation);
return new HashMap<String, String>() {

{

Check warning on line 38 in component-runtime-manager/src/main/java/org/talend/sdk/component/runtime/manager/reflect/parameterenricher/SchemaParameterEnricher.java

View check run for this annotation

sonar-eks / Component Runtime Sonarqube Results

component-runtime-manager/src/main/java/org/talend/sdk/component/runtime/manager/reflect/parameterenricher/SchemaParameterEnricher.java#L38

Move the contents of this initializer to a standard constructor or to field initializers.
put(META_PREFIX, fixed.value());
}
};
}
return emptyMap();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/**
* Copyright (C) 2006-2024 Talend Inc. - www.talend.com
*
* 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
*
* 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.talend.sdk.component.runtime.manager.reflect.parameterenricher;

import static org.junit.jupiter.api.Assertions.assertEquals;

import java.lang.annotation.Annotation;
import java.util.HashMap;

import org.junit.jupiter.api.Test;
import org.talend.sdk.component.api.service.schema.FixedSchema;

public class SchemaParameterEnricherTest {

Check notice on line 26 in component-runtime-manager/src/test/java/org/talend/sdk/component/runtime/manager/reflect/parameterenricher/SchemaParameterEnricherTest.java

View check run for this annotation

sonar-eks / Component Runtime Sonarqube Results

component-runtime-manager/src/test/java/org/talend/sdk/component/runtime/manager/reflect/parameterenricher/SchemaParameterEnricherTest.java#L26

Remove this 'public' modifier.

private final SchemaParameterEnricher enricher = new SchemaParameterEnricher();

@Test
void validateConnectorReference() throws ReflectiveOperationException {
assertEquals(new HashMap<String, String>() {

{
put("tcomp::ui::schema::fixed", "discover");
}
}, enricher.onParameterAnnotation("testParam", null, new FixedSchema() {

@Override
public Class<? extends Annotation> annotationType() {
return FixedSchema.class;
}

@Override
public String value() {
return "discover";
}
}));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -310,5 +310,7 @@ public static class Configuration {

private boolean validateSchema;

private boolean validateFixedSchema;

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/**
* Copyright (C) 2006-2024 Talend Inc. - www.talend.com
*
* 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
*
* 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.talend.sdk.component.tools.validator;

import static java.util.function.Function.identity;
import static java.util.stream.Collectors.toMap;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import org.apache.xbean.finder.AnnotationFinder;
import org.talend.sdk.component.api.service.schema.DiscoverSchema;
import org.talend.sdk.component.api.service.schema.DiscoverSchemaExtended;
import org.talend.sdk.component.api.service.schema.FixedSchema;

public class FixedSchemaValidator implements Validator {

@Override
public Stream<String> validate(final AnnotationFinder finder, final List<Class<?>> components) {
final List<String> errors = new ArrayList<>();
final Map<Class<?>, String> classes = finder.findAnnotatedClasses(FixedSchema.class)
.stream()
.collect(toMap(identity(), d -> d.getAnnotation(FixedSchema.class).value()));
// search for empty annotations
errors.addAll(classes.entrySet()
.stream()
.filter(e -> e.getValue().isEmpty())
.map(e -> String.format("Empty @FixedSchema annotation's value in class %s.",
e.getKey().getSimpleName()))
.collect(Collectors.toList()));
// search for missing methods
final List<String> methods = Stream
.concat(finder.findAnnotatedMethods(DiscoverSchema.class)
.stream()
.map(m -> m.getDeclaredAnnotation(DiscoverSchema.class).value()),
finder.findAnnotatedMethods(DiscoverSchemaExtended.class)
.stream()
.map(m -> m.getDeclaredAnnotation(DiscoverSchemaExtended.class).value()))
.collect(Collectors.toList());
errors.addAll(classes.entrySet()
.stream()
.filter(e -> !e.getValue().isEmpty())
.filter(e -> !methods.contains(e.getValue()))
.map(e -> String.format("@FixedSchema '%s' in class %s is not declared anywhere as DiscoverSchema*.",
e.getValue(), e.getKey().getSimpleName()))
.collect(Collectors.toList()));

return errors.stream();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@
return errors;
}

public static Validators build(final Configuration configuration, final ValidatorHelper helper,

Check failure on line 80 in component-tools/src/main/java/org/talend/sdk/component/tools/validator/Validators.java

View check run for this annotation

sonar-eks / Component Runtime Sonarqube Results

component-tools/src/main/java/org/talend/sdk/component/tools/validator/Validators.java#L80

Refactor this method to reduce its Cognitive Complexity from 23 to the 15 allowed.
final Iterable<ValidationExtension> extensions, final File sourceRoot) {

final List<Validator> activeValidators = new ArrayList<>();
Expand Down Expand Up @@ -173,6 +173,9 @@
if (configuration.isValidateSchema()) {
activeValidators.add(new SchemaValidator());
}
if (configuration.isValidateFixedSchema()) {
activeValidators.add(new FixedSchemaValidator());
}

return new Validators(activeValidators);

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
/**
* Copyright (C) 2006-2024 Talend Inc. - www.talend.com
*
* 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
*
* 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.talend.sdk.component.tools.validator;

import static org.junit.jupiter.api.Assertions.assertEquals;

import java.io.Serializable;
import java.util.Arrays;
import java.util.stream.Stream;

import org.apache.xbean.finder.AnnotationFinder;
import org.apache.xbean.finder.archive.ClassesArchive;
import org.junit.jupiter.api.Test;
import org.talend.sdk.component.api.configuration.Option;
import org.talend.sdk.component.api.configuration.type.DataSet;
import org.talend.sdk.component.api.input.Emitter;
import org.talend.sdk.component.api.input.Producer;
import org.talend.sdk.component.api.record.Record;
import org.talend.sdk.component.api.record.Schema;
import org.talend.sdk.component.api.service.Service;
import org.talend.sdk.component.api.service.schema.DiscoverSchema;
import org.talend.sdk.component.api.service.schema.DiscoverSchemaExtended;
import org.talend.sdk.component.api.service.schema.FixedSchema;

public class FixedSchemaValidatorTest {

Check notice on line 38 in component-tools/src/test/java/org/talend/sdk/component/tools/validator/FixedSchemaValidatorTest.java

View check run for this annotation

sonar-eks / Component Runtime Sonarqube Results

component-tools/src/test/java/org/talend/sdk/component/tools/validator/FixedSchemaValidatorTest.java#L38

Remove this 'public' modifier.

@Test
void validateFixedSchema() {
final FixedSchemaValidator validator = new FixedSchemaValidator();
AnnotationFinder finder =
new AnnotationFinder(new ClassesArchive(MySourceOk.class, MySourceOkExt.class, FixedService.class));
final Stream<String> noerrors =
validator.validate(finder, Arrays.asList(MySourceOk.class, MySourceOkExt.class, FixedService.class));
assertEquals(0, noerrors.count());

finder = new AnnotationFinder(
new ClassesArchive(MySourceKoEmpty.class, MySourceKoMissing.class, FixedService.class));
final Stream<String> errors = validator.validate(finder,
Arrays.asList(MySourceKoEmpty.class, MySourceKoMissing.class, FixedService.class));
assertEquals(2, errors.count());
}

@Emitter(family = "test", name = "mysource0")
@FixedSchema("discover")
static class MySourceOk implements Serializable {

@Producer
public Record next() {
return null;
}
}

@Emitter(family = "test", name = "mysource1")
@FixedSchema("discoverext")
static class MySourceOkExt implements Serializable {

@Producer
public Record next() {
return null;
}
}

@Emitter(family = "test", name = "mysource2")
@FixedSchema
static class MySourceKoEmpty implements Serializable {

@Producer
public Record next() {
return null;
}
}

@Emitter(family = "test", name = "mysource3")
@FixedSchema("missing")
static class MySourceKoMissing implements Serializable {

@Producer
public Record next() {
return null;
}
}

@DataSet("ds")
public static class DS {

@Option
private String dto;
}

@Service
static class FixedService {

@DiscoverSchema("discover")
public Schema discover(DS ds) {
return null;
}

@DiscoverSchemaExtended("discoverext")
public Schema discover(DS ds, String branch) {
return null;
}
}
}
Loading
Loading