-
Notifications
You must be signed in to change notification settings - Fork 160
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: Customizing Cloudevents validation #594
Conversation
d2706e0
to
8389a27
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would be curious on the design of it and why this approach over some other alternatives that you could have considered
To clarify my comment why not having a public interface CloudEventValidator {
void Validate(CloudEvent) throws CloudEventValidationException;
}
// ... builder classes
public class CloudEventBuilder {
// ... omitted methods ...
public CloudEventBuilder withValidator(CloudEventValidator validator) {
this.validator = validator;
return this;
}
// use validator (if set) in `build()` |
My approach explaination Suggested approach explaination |
I'm not fully convinced on the approach, did you consider using something like SPI https://docs.oracle.com/javase/tutorial/ext/basics/spi.html ? |
Addressed review comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks!
Can we add new tests which would test end to end the provider ?
/* | ||
* 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(); | ||
} | ||
|
||
} | ||
|
||
|
||
|
||
|
||
|
||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we can:
- remove the need of synchronize every time in
build()
- instead of catching and printing errors which could hide important mis-configurations, let the caller decide how to handle them
- remove many empty lines
- use more
final
s fields/variables to be explicit
/* | |
* 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(); | |
} | |
} | |
} | |
/* | |
* 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.ServiceLoader; | |
/** | |
* CloudEventValidatorProvider is a singleton class which loads and access CE Validator service providers on behalf of service clients. | |
*/ | |
public class CloudEventValidatorProvider { | |
private static final CloudEventValidatorProvider cloudEventValidatorProvider = new CloudEventValidatorProvider(); | |
private final ServiceLoader<CloudEventValidator> loader; | |
private CloudEventValidatorProvider() { | |
loader = ServiceLoader.load(CloudEventValidator.class); | |
} | |
public static CloudEventValidatorProvider getInstance() { | |
return cloudEventValidatorProvider; | |
} | |
/** | |
* iterates through available Cloudevent validators. | |
* | |
* @param cloudEvent event to validate. | |
*/ | |
public void validate(final CloudEvent cloudEvent) { | |
for (final CloudEventValidator validator : loader) { | |
validator.validate(cloudEvent); | |
} | |
} | |
} |
@@ -119,7 +121,12 @@ public CloudEvent build() { | |||
throw createMissingAttributeException(TYPE); | |||
} | |||
|
|||
return new CloudEventV1(id, source, type, datacontenttype, dataschema, subject, time, this.data, this.extensions); | |||
CloudEvent cloudEvent = new CloudEventV1(id, source, type, datacontenttype, dataschema, subject, time, this.data, this.extensions); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
CloudEvent cloudEvent = new CloudEventV1(id, source, type, datacontenttype, dataschema, subject, time, this.data, this.extensions); | |
final CloudEvent cloudEvent = new CloudEventV1(id, source, type, datacontenttype, dataschema, subject, time, this.data, this.extensions); |
return new CloudEventV1(id, source, type, datacontenttype, dataschema, subject, time, this.data, this.extensions); | ||
CloudEvent cloudEvent = new CloudEventV1(id, source, type, datacontenttype, dataschema, subject, time, this.data, this.extensions); | ||
|
||
CloudEventValidatorProvider validator = CloudEventValidatorProvider.getInstance(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
CloudEventValidatorProvider validator = CloudEventValidatorProvider.getInstance(); | |
final CloudEventValidatorProvider validator = CloudEventValidatorProvider.getInstance(); |
CloudEvent cloudEvent = new CloudEventV1(id, source, type, datacontenttype, dataschema, subject, time, this.data, this.extensions); | ||
|
||
CloudEventValidatorProvider validator = CloudEventValidatorProvider.getInstance(); | ||
validator.validate(cloudEvent); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need to add the same logic for the 0.3 builder https://github.com/cloudevents/sdk-java/blob/main/core/src/main/java/io/cloudevents/core/v03/CloudEventBuilder.java
See also DCO error here https://github.com/cloudevents/sdk-java/pull/594/checks?check_run_id=21047384482 |
43ea478
to
1beaf00
Compare
Review comment addressed |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The new test is failing
README.md
Outdated
If there is a security concern with one of the CloudEvents specifications, or | ||
with one of the project's SDKs, please send an email to | ||
[[email protected]](mailto:[email protected]). | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems an unrelated change ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did a rebase while doing DCO change. I think after that it came
Just to clarify/help fixing the test. we would need to implement the SPI for testing, see this https://www.baeldung.com/java-spi, in particular the section on "Building the Service Provider" that part should be done in the test directory, an example is also in the SDK here https://github.com/cloudevents/sdk-java/blob/main/core/src/test/resources/META-INF/services/io.cloudevents.core.format.EventFormat for testing the |
I had this commit in an unversioned commit. Now committed those files. Apologies for missing |
Signed-off-by: vbhat6 <[email protected]>
Signed-off-by: Doug Davis <[email protected]> Signed-off-by: vbhat6 <[email protected]>
Signed-off-by: vbhat6 <[email protected]>
Signed-off-by: vbhat6 <[email protected]>
Signed-off-by: Calum Murray <[email protected]> Signed-off-by: vbhat6 <[email protected]>
Signed-off-by: vbhat6 <[email protected]>
ea6b839
to
8c66b1b
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Add SPI for custom CloudEvent validation. Signed-off-by: vbhat6 <[email protected]>
No description provided.