99import com .networknt .schema .SpecVersion ;
1010import com .networknt .schema .ValidationMessage ;
1111import dev .cdevents .config .CustomObjectMapper ;
12+ import dev .cdevents .constants .CDEventConstants ;
1213import dev .cdevents .exception .CDEventsException ;
1314import dev .cdevents .models .CDEvent ;
1415import io .cloudevents .CloudEvent ;
2021import java .net .URISyntaxException ;
2122import java .nio .charset .StandardCharsets ;
2223import java .time .OffsetDateTime ;
24+ import java .util .Arrays ;
2325import java .util .Set ;
2426import java .util .UUID ;
2527
@@ -77,11 +79,7 @@ public static CloudEvent cdEventAsCloudEvent(CDEvent cdEvent) {
7779 * @return valid cdEvent
7880 */
7981 public static boolean validateCDEvent (CDEvent cdEvent ) {
80- JsonSchemaFactory factory = JsonSchemaFactory .getInstance (SpecVersion .VersionFlag .V202012 );
81- JsonSchema jsonSchema = factory .getSchema (cdEvent .eventSchema ());
82-
83- JsonNode jsonNode = objectMapper .convertValue (cdEvent , ObjectNode .class );
84- Set <ValidationMessage > errors = jsonSchema .validate (jsonNode );
82+ Set <ValidationMessage > errors = getJsonSchemaValidationMessages (cdEvent );
8583
8684 if (!errors .isEmpty ()) {
8785 log .error ("CDEvent validation failed with errors {}" , errors );
@@ -90,4 +88,91 @@ public static boolean validateCDEvent(CDEvent cdEvent) {
9088 return true ;
9189 }
9290
91+ /**
92+ * Creates cdEvent from cdEventJson string and validates against schema.
93+ * @param cdEventJson
94+ * @return CDEvent, needs type casting to specific CDEvent class
95+ */
96+ public static CDEvent cdEventFromJson (String cdEventJson ) {
97+ if (!validateCDEventJson (cdEventJson )) {
98+ throw new CDEventsException ("CDEvent Json validation failed against schema" );
99+ }
100+ String eventType = getUnVersionedEventTypeFromJson (cdEventJson );
101+ CDEventConstants .CDEventTypes cdEventType = getCDEventTypeEnum (eventType );
102+ try {
103+ CDEvent cdEvent = (CDEvent ) new ObjectMapper ().readValue (cdEventJson , cdEventType .getEventClass ());
104+ return cdEvent ;
105+ } catch (JsonProcessingException e ) {
106+ log .error ("Exception occurred while creating CDEvent from json {}" , cdEventJson );
107+ throw new CDEventsException ("Exception occurred while creating CDEvent from json " , e );
108+ }
109+ }
110+
111+ /**
112+ * Validates the cdEventJson against the Schema URL.
113+ * @param cdEventJson
114+ * @return true, If cdEventJson is valid
115+ */
116+ public static boolean validateCDEventJson (String cdEventJson ) {
117+ String eventType = getUnVersionedEventTypeFromJson (cdEventJson );
118+ CDEventConstants .CDEventTypes cdEventType = getCDEventTypeEnum (eventType );
119+ try {
120+ CDEvent cdEvent = (CDEvent ) new ObjectMapper ().readValue (cdEventJson , cdEventType .getEventClass ());
121+ Set <ValidationMessage > errors = getJsonSchemaValidationMessages (cdEvent );
122+
123+ if (!errors .isEmpty ()) {
124+ log .error ("CDEvent Json validation failed against schema URL {}" , cdEvent .schemaURL ());
125+ log .error ("CDEvent Json validation failed with errors {}" , errors );
126+ return false ;
127+ }
128+ } catch (JsonProcessingException e ) {
129+ throw new CDEventsException ("Exception occurred while validating CDEvent json with schema file " , e );
130+ }
131+ return true ;
132+ }
133+
134+ private static Set <ValidationMessage > getJsonSchemaValidationMessages (CDEvent cdEvent ) {
135+ JsonSchemaFactory factory = JsonSchemaFactory .getInstance (SpecVersion .VersionFlag .V202012 );
136+ JsonSchema jsonSchema = factory .getSchema (cdEvent .eventSchema ());
137+
138+ JsonNode jsonNode = objectMapper .convertValue (cdEvent , ObjectNode .class );
139+ Set <ValidationMessage > errors = jsonSchema .validate (jsonNode );
140+ return errors ;
141+ }
142+
143+ private static CDEventConstants .CDEventTypes getCDEventTypeEnum (String eventType ) {
144+ return Arrays .stream (CDEventConstants .CDEventTypes .values ())
145+ .filter (type -> eventType .equals (type .getEventType ()))
146+ .findFirst ()
147+ .orElseThrow (
148+ () -> {
149+ log .error ("Invalid CDEvent type found {} from cdEventJson" , eventType );
150+ return new CDEventsException ("Invalid CDEvent type found from cdEventJson" );
151+ }
152+ );
153+ }
154+
155+ private static String getUnVersionedEventTypeFromJson (String cdEventJson ) {
156+ String unVersionedEventType = "" ;
157+ try {
158+ JsonNode rootNode = objectMapper .readTree (cdEventJson );
159+ if (rootNode .get ("context" ) != null && rootNode .get ("context" ).get ("type" ) != null ) {
160+ String versionedEventType = rootNode .get ("context" ).get ("type" ).asText ();
161+ if (versionedEventType .startsWith (CDEventConstants .EVENT_PREFIX )) {
162+ String [] type = versionedEventType .split ("\\ ." );
163+ String subject = type [CDEventConstants .EVENT_SUBJECT_INDEX ];
164+ String predicate = type [CDEventConstants .EVENT_PREDICATE_INDEX ];
165+ unVersionedEventType = CDEventConstants .EVENT_PREFIX + subject + "." + predicate + "." ;
166+ } else {
167+ throw new CDEventsException ("Invalid CDEvent type found in CDEvent Json " + versionedEventType );
168+ }
169+ } else {
170+ throw new CDEventsException ("Unable to find context and type in CDEvent Json" );
171+ }
172+ return unVersionedEventType ;
173+ } catch (JsonProcessingException e ) {
174+ throw new CDEventsException ("Exception occurred while reading CDEvent Json for eventType " , e );
175+ }
176+
177+ }
93178}
0 commit comments