Skip to content

Commit

Permalink
feat: Customizing Cloudevents validation
Browse files Browse the repository at this point in the history
Signed-off-by: vbhat6 <[email protected]>
  • Loading branch information
vbhat6 committed Feb 7, 2024
1 parent f1e1f96 commit 982d4ae
Show file tree
Hide file tree
Showing 6 changed files with 90 additions and 91 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/*
* Copyright 2018-Present The CloudEvents Authors
* <p>
* 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
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* 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 io.cloudevents.core.provider;

import io.cloudevents.CloudEvent;
import io.cloudevents.core.validator.CloudEventValidator;

import java.util.Iterator;
import java.util.ServiceConfigurationError;
import java.util.ServiceLoader;

/**
* CloudEventValidatorProvider is a singleton class which loads and access CE Validator service providers on behalf of service clients.
*/
public class CloudEventValidatorProvider {

private static CloudEventValidatorProvider cloudEventValidatorProvider;

private ServiceLoader<CloudEventValidator> loader;

private CloudEventValidatorProvider(){
loader = ServiceLoader.load(CloudEventValidator.class);
}

public static synchronized CloudEventValidatorProvider getInstance(){
if(cloudEventValidatorProvider == null){
cloudEventValidatorProvider = new CloudEventValidatorProvider();
}
return cloudEventValidatorProvider;
}

/**
* iterates through available Cloudevent validators.
* @param cloudEvent
*/
public void validate(CloudEvent cloudEvent){
try{
//
Iterator<CloudEventValidator> validatorIterator = loader.iterator();
while (validatorIterator.hasNext()){
CloudEventValidator validator = validatorIterator.next();
validator.validate(cloudEvent);

}
} catch (ServiceConfigurationError serviceError) {

serviceError.printStackTrace();
}

}





}
24 changes: 3 additions & 21 deletions core/src/main/java/io/cloudevents/core/v1/CloudEventBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import io.cloudevents.SpecVersion;
import io.cloudevents.core.CloudEventUtils;
import io.cloudevents.core.impl.BaseCloudEventBuilder;
import io.cloudevents.core.provider.CloudEventValidatorProvider;
import io.cloudevents.core.validator.CloudEventValidator;
import io.cloudevents.rw.CloudEventContextReader;
import io.cloudevents.rw.CloudEventContextWriter;
Expand Down Expand Up @@ -122,27 +123,8 @@ public CloudEvent build() {

CloudEvent cloudEvent = new CloudEventV1(id, source, type, datacontenttype, dataschema, subject, time, this.data, this.extensions);

String name = null;
try{
// check if the header.validator.class is set as a system property,
if ((name = System.getProperty("header.validator.class")) != null){
Class<?> dynamicClass = Class.forName(name);
Object dynamicObject = dynamicClass.newInstance();

if (dynamicObject instanceof CloudEventValidator) {
// pluggable implementation of validation implementation
CloudEventValidator cloudEventValidator = (CloudEventValidator) dynamicObject;

cloudEventValidator.validate(cloudEvent);
}
else {
throw new IllegalArgumentException("Passed class is not an instance of CloudEventValidator");
}
}
}
catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) {
throw new IllegalArgumentException("Unable to load the header.validator.class passed as vm argument = " + name + ". Please check the classpath", e);
}
CloudEventValidatorProvider validator = CloudEventValidatorProvider.getInstance();
validator.validate(cloudEvent);

return cloudEvent;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,25 @@
/*
* Copyright 2018-Present The CloudEvents Authors
* <p>
* 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
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* 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 io.cloudevents.core.validator;

import io.cloudevents.CloudEvent;

/**
* @author Vinay Bhat
* Interface which defines validation for CloudEvents attributes and extensions.
*/
public interface CloudEventValidator {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -142,48 +142,4 @@ void testMissingType() {
).hasMessageContaining("Attribute 'type' cannot be null");
}

@Test
void testClassNotFoundExceptionForValidator(){

System.setProperty("header.validator.class", "io.cloudevents.core.v1.CustomCloudEventValidatorTest");
assertThatCode(() -> CloudEventBuilder
.v1()
.withId("000")
.withSource(URI.create("http://localhost"))
.withType("aaa")
.withExtension("astring", 10)
.build()
).hasMessageContaining("Unable to load the header.validator.class passed as vm argument");
}

@Test
void testClassCastExceptionForValidator(){

System.setProperty("header.validator.class", "io.cloudevents.core.v1.CustomCloudEventValidator");
assertThatCode(() -> CloudEventBuilder
.v1()
.withId("000")
.withSource(URI.create("http://localhost"))
.withType("aaa")
.withExtension("astring", 10)
.build()
).hasMessageContaining("Passed class is not an instance of CloudEventValidator");
}

/**
* This test is to check for the mandatory extension 'namespace' as per Organization need
*/
@Test
void testMissingNamespaceExtension(){

System.setProperty("header.validator.class", "io.cloudevents.core.v1.CustomCloudEventValidatorImpl");
assertThatCode(() -> CloudEventBuilder
.v1()
.withId("000")
.withSource(URI.create("http://localhost"))
.withType("aaa")
.build()
).hasMessageContaining("Extension 'namespace' cannot be null");
}

}

This file was deleted.

This file was deleted.

0 comments on commit 982d4ae

Please sign in to comment.