diff --git a/crossplane-function-springboot-starter/src/main/java/io/crossplane/compositefunctions/starter/config/CrossplaneServiceConfiguration.java b/crossplane-function-springboot-starter/src/main/java/io/crossplane/compositefunctions/starter/config/CrossplaneServiceConfiguration.java index dcba8b8..bc1cba7 100644 --- a/crossplane-function-springboot-starter/src/main/java/io/crossplane/compositefunctions/starter/config/CrossplaneServiceConfiguration.java +++ b/crossplane-function-springboot-starter/src/main/java/io/crossplane/compositefunctions/starter/config/CrossplaneServiceConfiguration.java @@ -1,9 +1,48 @@ package io.crossplane.compositefunctions.starter.config; +import io.crossplane.compositefunctions.starter.conversion.CrossplaneExtraResourcesService; +import io.crossplane.compositefunctions.starter.conversion.CrossplaneObservableService; +import io.crossplane.compositefunctions.starter.conversion.CrossplaneResourceService; +import org.checkerframework.checker.units.qual.C; import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; +/** + * Autoconfiguration for the crossplane services. + */ @AutoConfiguration -@ComponentScan(basePackages = {"io.crossplane.compositefunctions.starter.conversion"}) public class CrossplaneServiceConfiguration { + + + /** + * Set up services for working with extra resources + * @return the crossplaneExtraResourcesService + * @since 1.15 + */ + @Bean + public CrossplaneExtraResourcesService crossplaneExtraResourcesService() { + return new CrossplaneExtraResourcesService(); + } + + /** + * Set up services for working with observed resources + * @return the crossplaneObservableService + * @since 1.14 + */ + @Bean + public CrossplaneObservableService crossplaneObservableService() { + return new CrossplaneObservableService(); + } + + /** + * Set up services for working with default resources + * @return the crossplaneResourceService + * @since 1.15 + */ + @Bean + public CrossplaneResourceService crossplaneResourceService() { + return new CrossplaneResourceService(); + } + } diff --git a/crossplane-function-springboot-starter/src/main/java/io/crossplane/compositefunctions/starter/conversion/CrossplaneExtraResourcesService.java b/crossplane-function-springboot-starter/src/main/java/io/crossplane/compositefunctions/starter/conversion/CrossplaneExtraResourcesService.java index 233d3f7..13941d8 100644 --- a/crossplane-function-springboot-starter/src/main/java/io/crossplane/compositefunctions/starter/conversion/CrossplaneExtraResourcesService.java +++ b/crossplane-function-springboot-starter/src/main/java/io/crossplane/compositefunctions/starter/conversion/CrossplaneExtraResourcesService.java @@ -10,15 +10,20 @@ import io.fabric8.kubernetes.client.utils.Serialization; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.stereotype.Component; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Optional; - -@Component +/** + * Class that helps with the extra resources map and also to create ResourceSelector in order to get extra resources + * to the function + * + * Commented out in 1.14 + * + * @since 1.15 + */ public class CrossplaneExtraResourcesService { private static final Logger logger = LoggerFactory.getLogger(CrossplaneExtraResourcesService.class); diff --git a/crossplane-function-springboot-starter/src/main/java/io/crossplane/compositefunctions/starter/conversion/CrossplaneObservableService.java b/crossplane-function-springboot-starter/src/main/java/io/crossplane/compositefunctions/starter/conversion/CrossplaneObservableService.java index c1850d5..266357b 100644 --- a/crossplane-function-springboot-starter/src/main/java/io/crossplane/compositefunctions/starter/conversion/CrossplaneObservableService.java +++ b/crossplane-function-springboot-starter/src/main/java/io/crossplane/compositefunctions/starter/conversion/CrossplaneObservableService.java @@ -8,16 +8,25 @@ import io.fabric8.kubernetes.client.utils.Serialization; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.stereotype.Component; import java.util.Optional; -@Component +/** + * Class with helper methods for observable resources. + */ public class CrossplaneObservableService { private static final Logger logger = LoggerFactory.getLogger(CrossplaneObservableService.class); private final JsonFormat.Printer printer = JsonFormat.printer(); + /** + * Retrieve a resource from the observedstate and convert in into class T + * @param resourceName The resource name to find in the observed state + * @param observedState The observed state from the crossplane input + * @param clazz The class/type to create + * @return An instance of class T from the observed state + * @param The class/type to create + */ public Optional getObservableResource(String resourceName, State observedState, Class clazz) { Resource observedResource = observedState.getResourcesOrDefault(resourceName, null); Optional result = Optional.empty(); diff --git a/crossplane-function-springboot-starter/src/main/java/io/crossplane/compositefunctions/starter/conversion/CrossplaneResourceService.java b/crossplane-function-springboot-starter/src/main/java/io/crossplane/compositefunctions/starter/conversion/CrossplaneResourceService.java index 12a1a57..7e2ac50 100644 --- a/crossplane-function-springboot-starter/src/main/java/io/crossplane/compositefunctions/starter/conversion/CrossplaneResourceService.java +++ b/crossplane-function-springboot-starter/src/main/java/io/crossplane/compositefunctions/starter/conversion/CrossplaneResourceService.java @@ -4,15 +4,23 @@ import io.crossplane.compositefunctions.protobuf.State; import io.crossplane.compositefunctions.starter.exception.CrossplaneUnmarshallException; import io.fabric8.kubernetes.client.utils.Serialization; -import org.springframework.stereotype.Component; import java.util.Optional; -@Component +/** + * Class with helper methods for default resources. + */ public class CrossplaneResourceService { final JsonFormat.Printer printer = JsonFormat.printer(); + /** + * Converts the incoming Composite to instance of class T + * @param observedState The observed state from the crossplane input + * @param clazz The class/type to create + * @return An instance of class T from the observed state + * @param The class/type to create + */ public Optional getResource(State observedState, Class clazz) { try { String resource = printer.print(observedState.getComposite().getResource()); diff --git a/crossplane-function-springboot-starter/src/main/java/io/crossplane/compositefunctions/starter/exception/CrossplaneUnexpectedItemsException.java b/crossplane-function-springboot-starter/src/main/java/io/crossplane/compositefunctions/starter/exception/CrossplaneUnexpectedItemsException.java index 1e87c1d..e0bbbdf 100644 --- a/crossplane-function-springboot-starter/src/main/java/io/crossplane/compositefunctions/starter/exception/CrossplaneUnexpectedItemsException.java +++ b/crossplane-function-springboot-starter/src/main/java/io/crossplane/compositefunctions/starter/exception/CrossplaneUnexpectedItemsException.java @@ -1,11 +1,23 @@ package io.crossplane.compositefunctions.starter.exception; +/** + * Exception for unexpected items encountered when converting + */ public class CrossplaneUnexpectedItemsException extends RuntimeException { + /** + * Constructor with message + * @param message The exception message + */ public CrossplaneUnexpectedItemsException(String message) { super(message); } + /** + * Constructor with message and cause + * @param message The exception message + * @param cause The throwable that caused the exception + */ public CrossplaneUnexpectedItemsException(String message, Throwable cause) { super(message, cause); } diff --git a/crossplane-function-springboot-starter/src/main/java/io/crossplane/compositefunctions/starter/exception/CrossplaneUnmarshallException.java b/crossplane-function-springboot-starter/src/main/java/io/crossplane/compositefunctions/starter/exception/CrossplaneUnmarshallException.java index c6b1b93..f6a8645 100644 --- a/crossplane-function-springboot-starter/src/main/java/io/crossplane/compositefunctions/starter/exception/CrossplaneUnmarshallException.java +++ b/crossplane-function-springboot-starter/src/main/java/io/crossplane/compositefunctions/starter/exception/CrossplaneUnmarshallException.java @@ -1,11 +1,23 @@ package io.crossplane.compositefunctions.starter.exception; +/** + * Exception for errors when unmarhsalling + */ public class CrossplaneUnmarshallException extends RuntimeException { + /** + * Constructor with message + * @param message The exception message + */ public CrossplaneUnmarshallException(String message) { super(message); } + /** + * Constructor with message and cause + * @param message The exception message + * @param cause The throwable that caused the exception + */ public CrossplaneUnmarshallException(String message, Throwable cause) { super(message, cause); } diff --git a/crossplane-function-springboot-starter/src/main/java/io/crossplane/compositefunctions/starter/registration/CrossplaneCompositeResourceMixin.java b/crossplane-function-springboot-starter/src/main/java/io/crossplane/compositefunctions/starter/registration/CrossplaneCompositeResourceMixin.java index fce63ab..6aaeaf8 100644 --- a/crossplane-function-springboot-starter/src/main/java/io/crossplane/compositefunctions/starter/registration/CrossplaneCompositeResourceMixin.java +++ b/crossplane-function-springboot-starter/src/main/java/io/crossplane/compositefunctions/starter/registration/CrossplaneCompositeResourceMixin.java @@ -3,6 +3,10 @@ import com.fasterxml.jackson.annotation.JsonIgnore; import io.fabric8.kubernetes.api.model.ObjectMeta; +/** + * Class to aid in setting up autoregistration. Used to ignore the default + * fields when creating the openapiv3schema + */ public abstract class CrossplaneCompositeResourceMixin { @JsonIgnore diff --git a/crossplane-function-springboot-starter/src/main/java/io/crossplane/compositefunctions/starter/registration/CrossplaneCompositeResourceService.java b/crossplane-function-springboot-starter/src/main/java/io/crossplane/compositefunctions/starter/registration/CrossplaneCompositeResourceService.java index c57c71b..f5d1528 100644 --- a/crossplane-function-springboot-starter/src/main/java/io/crossplane/compositefunctions/starter/registration/CrossplaneCompositeResourceService.java +++ b/crossplane-function-springboot-starter/src/main/java/io/crossplane/compositefunctions/starter/registration/CrossplaneCompositeResourceService.java @@ -19,22 +19,33 @@ import java.util.ArrayList; import java.util.List; -import static io.crossplane.compositefunctions.starter.registration.CrossplanJsonSchemaGenerator.getOpenAPIV3Schema; +import static io.crossplane.compositefunctions.starter.registration.CrossplaneJsonSchemaGenerator.getOpenAPIV3Schema; +/** + * Service that can register the composite resource together with a function, + * which can also add other function to the pipeline definition + */ public class CrossplaneCompositeResourceService { - - public static > void registerOrUpdateCompositeResource(String functionName, - List additionalFunctions, - T functionDefinition, + /** + * Register or update the composite resource definition using the provided client. + * The client needs access to register the types + * + * @param pipelineFunctions A list of functionnames to add to the composition pipeline + * @param compositionDefinition The object that has the composition definiton + * @param kubernetesClient The client to use to register the definition + * @param Must extend CustomResource + */ + public static > void registerOrUpdateCompositeResource(List pipelineFunctions, + T compositionDefinition, KubernetesClient kubernetesClient) { - CompositeResourceDefinition compositeResourceDefinition = createCompositeResourceDefinition(functionDefinition); + CompositeResourceDefinition compositeResourceDefinition = createCompositeResourceDefinition(compositionDefinition); registerOrUpdateCompositeResourceDefinition(compositeResourceDefinition, kubernetesClient); - Composition composition = createCompositionDefinition(functionName, additionalFunctions, functionDefinition); + Composition composition = createCompositionDefinition(pipelineFunctions, compositionDefinition); registerOrUpdateCompositeResourceDefinition(composition, kubernetesClient); @@ -52,41 +63,49 @@ private static void registerOrUpdateCompositeResourceDefinition(CompositeResourc } } - public static > CompositeResourceDefinition createCompositeResourceDefinition(T functionDefinition) { //}, Class functionMixin) { + /** + * Create a CompositeResourceDefinition based on the provided CustomResource + * If Namespaced, ClaimNames will be added in addition to Names. + * + * @param compositionDefinition The composition definition + * @return A CompositeResourceDefintion based on the provided CustomResource + * @param Must extend CustomResource + */ + public static > CompositeResourceDefinition createCompositeResourceDefinition(T compositionDefinition) { //}, Class functionMixin) { CompositeResourceDefinition compositeResourceDefinition = new CompositeResourceDefinition(); - compositeResourceDefinition.setMetadata(CrossplaneMetadataBuilder.createMetadata(functionDefinition.getCRDName())); + compositeResourceDefinition.setMetadata(CrossplaneMetadataBuilder.createMetadata(compositionDefinition.getCRDName())); CompositeResourceDefinitionSpec spec = new CompositeResourceDefinitionSpec(); - spec.setGroup(functionDefinition.getGroup()); + spec.setGroup(compositionDefinition.getGroup()); String namePrefix = ""; - if (functionDefinition instanceof Namespaced) { + if (compositionDefinition instanceof Namespaced) { ClaimNames claimNames = new ClaimNames(); - claimNames.setKind(functionDefinition.getKind()); - claimNames.setPlural(functionDefinition.getPlural()); - claimNames.setSingular(functionDefinition.getSingular()); + claimNames.setKind(compositionDefinition.getKind()); + claimNames.setPlural(compositionDefinition.getPlural()); + claimNames.setSingular(compositionDefinition.getSingular()); spec.setClaimNames(claimNames); namePrefix = "x"; } Names names = new Names(); - names.setKind(namePrefix + functionDefinition.getKind()); - names.setPlural(namePrefix + functionDefinition.getPlural()); - names.setSingular(namePrefix + functionDefinition.getSingular()); + names.setKind(namePrefix + compositionDefinition.getKind()); + names.setPlural(namePrefix + compositionDefinition.getPlural()); + names.setSingular(namePrefix + compositionDefinition.getSingular()); spec.setNames(names); Versions versions = new Versions(); - versions.setName(functionDefinition.getVersion()); + versions.setName(compositionDefinition.getVersion()); // This is not 100%. isStorage vs referencable. Need to check the crossplan docs - versions.setReferenceable(functionDefinition.isStorage()); - versions.setServed(functionDefinition.isServed()); + versions.setReferenceable(compositionDefinition.isStorage()); + versions.setServed(compositionDefinition.isServed()); Schema schema = new Schema(); - schema.setOpenAPIV3Schema(getOpenAPIV3Schema(functionDefinition.getClass(), CrossplaneCompositeResourceMixin.class)); + schema.setOpenAPIV3Schema(getOpenAPIV3Schema(compositionDefinition.getClass(), CrossplaneCompositeResourceMixin.class)); versions.setSchema(schema); spec.setVersions(List.of(versions)); @@ -108,26 +127,23 @@ private static void registerOrUpdateCompositeResourceDefinition(Composition comp } private static > Composition createCompositionDefinition( - String functionName, List additionalFunctions, - T functionDefinition) { + List pipelineFunctions, T compositionDefinition) { Composition composition = new Composition(); - composition.setMetadata(CrossplaneMetadataBuilder.createMetadata(functionDefinition.getKind().toLowerCase() + "-composition")); + composition.setMetadata(CrossplaneMetadataBuilder.createMetadata(compositionDefinition.getKind().toLowerCase() + "-composition")); CompositionSpec compositionSpec = new CompositionSpec(); CompositeTypeRef compositeTypeRef = new CompositeTypeRef(); - compositeTypeRef.setKind(functionDefinition.getKind()); - compositeTypeRef.setApiVersion(functionDefinition.getApiVersion()); + compositeTypeRef.setKind(compositionDefinition.getKind()); + compositeTypeRef.setApiVersion(compositionDefinition.getApiVersion()); compositionSpec.setCompositeTypeRef(compositeTypeRef); compositionSpec.setMode(CompositionSpec.Mode.PIPELINE); List pipelineList = new ArrayList<>(); - pipelineList.add(createPipeline(functionName)); - - additionalFunctions.forEach(s -> pipelineList.add(createPipeline(s))); + pipelineFunctions.forEach(s -> pipelineList.add(createPipeline(s))); compositionSpec.setPipeline(pipelineList); composition.setSpec(compositionSpec); diff --git a/crossplane-function-springboot-starter/src/main/java/io/crossplane/compositefunctions/starter/registration/CrossplanJsonSchemaGenerator.java b/crossplane-function-springboot-starter/src/main/java/io/crossplane/compositefunctions/starter/registration/CrossplaneJsonSchemaGenerator.java similarity index 86% rename from crossplane-function-springboot-starter/src/main/java/io/crossplane/compositefunctions/starter/registration/CrossplanJsonSchemaGenerator.java rename to crossplane-function-springboot-starter/src/main/java/io/crossplane/compositefunctions/starter/registration/CrossplaneJsonSchemaGenerator.java index 1b61aa2..4d95937 100644 --- a/crossplane-function-springboot-starter/src/main/java/io/crossplane/compositefunctions/starter/registration/CrossplanJsonSchemaGenerator.java +++ b/crossplane-function-springboot-starter/src/main/java/io/crossplane/compositefunctions/starter/registration/CrossplaneJsonSchemaGenerator.java @@ -12,8 +12,17 @@ import java.io.IOException; import java.util.stream.Stream; -public class CrossplanJsonSchemaGenerator { +/** + * Generator of OpenApiV3Schema used when creating CompositeResourceDefinition + */ +public class CrossplaneJsonSchemaGenerator { + /** + * Create the OpenApiV3Schema + * @param clazz The class to create the schema from + * @param mixin A mixin to use when Jackson maps the class + * @return A OpenAPIV3Schema based on the given class + */ public static OpenAPIV3Schema getOpenAPIV3Schema(Class clazz, Class mixin) { try { ObjectMapper mapper = new ObjectMapper(); @@ -52,6 +61,11 @@ private static void removeIdField(JsonSchema jsonSchema) { } + /** + * Get the JSONSchemaProps from the class + * @param clazz The class to get the schema from + * @return The schemaprops based on the provided class + */ public static JSONSchemaProps getJsonSchema(Class clazz) { try { ObjectMapper mapper = new ObjectMapper(); @@ -73,7 +87,9 @@ public static JSONSchemaProps getJsonSchema(Class clazz) { } - + /** + * Class just use to ignore the ID property that automatically gets added. + */ private abstract class IdIgnorer { @JsonIgnore diff --git a/crossplane-function-springboot-starter/src/main/java/io/crossplane/compositefunctions/starter/registration/CrossplaneMetadataBuilder.java b/crossplane-function-springboot-starter/src/main/java/io/crossplane/compositefunctions/starter/registration/CrossplaneMetadataBuilder.java index 565fdc3..20d9a68 100644 --- a/crossplane-function-springboot-starter/src/main/java/io/crossplane/compositefunctions/starter/registration/CrossplaneMetadataBuilder.java +++ b/crossplane-function-springboot-starter/src/main/java/io/crossplane/compositefunctions/starter/registration/CrossplaneMetadataBuilder.java @@ -6,24 +6,51 @@ import java.util.LinkedHashMap; import java.util.Map; +/** + * Convinience methods to create the Metadata object in any kubernetes resource + */ public class CrossplaneMetadataBuilder { private CrossplaneMetadataBuilder() { } + /** + * Create metadata with name + * @param name The name of the resource + * @return The metdata object based on the input + */ + public static ObjectMeta createMetadata(String name) { + return createMetadata(name, null); + } + + /** + * Create metadata with name and namespace + * @param name The name of the resource + * @param namespace The namespace of the resource + * @return The metdata object based on the input + */ public static ObjectMeta createMetadata(String name, String namespace) { return createMetadata(name, namespace, null); } + /** + * Create metadata with name, namespace and annotations + * @param name The name of the resource + * @param namespace The namespace of the resource + * @param annotations Annotations to add to the metadata + * @return The metdata object based on the input + */ public static ObjectMeta createMetadata(String name, String namespace, Map annotations) { return new ObjectMetaBuilder().withName(name).withNamespace(namespace).withAnnotations(annotations).build(); } - public static ObjectMeta createMetadata(String name) { - return createMetadata(name, null); - } - + /** + * Add extra metadata to a Metadata object + * @param annotations The extra metadata to add + * @param objectMeta The metadata object to add it to + * @return The metadata with the added annotations + */ public static ObjectMeta addAnnotations(Map annotations, ObjectMeta objectMeta) { Map existingAnnotations = objectMeta.getAnnotations(); diff --git a/pom.xml b/pom.xml index c400f25..047dc1a 100644 --- a/pom.xml +++ b/pom.xml @@ -29,7 +29,7 @@ 6.13.0 1.7.1 3.25.1 - 1.64.0 + 1.63.0 1.3.5 2.0.13 2.17.1 @@ -100,43 +100,10 @@ io.grpc - grpc-protobuf - ${grpc.version} - - - io.grpc - grpc-stub - ${grpc.version} - - - io.grpc - grpc-core - ${grpc.version} - - - io.grpc - grpc-api - ${grpc.version} - - - io.grpc - grpc-util - ${grpc.version} - - - io.grpc - grpc-services - ${grpc.version} - - - io.grpc - grpc-inprocess - ${grpc.version} - - - io.grpc - grpc-netty-shaded + grpc-bom ${grpc.version} + import + pom jakarta.annotation