3131import io .swagger .v3 .oas .models .media .ComposedSchema ;
3232import io .swagger .v3 .oas .models .media .MapSchema ;
3333import io .swagger .v3 .oas .models .media .MediaType ;
34+ import io .swagger .v3 .oas .models .media .ObjectSchema ;
3435import io .swagger .v3 .oas .models .media .Schema ;
3536import io .swagger .v3 .oas .models .parameters .Parameter ;
3637import io .swagger .v3 .oas .models .responses .ApiResponse ;
4243import net .coru .multiapi .converter .openapi .model .ConverterPathItem ;
4344import net .coru .multiapi .converter .openapi .model .OperationType ;
4445import net .coru .multiapi .converter .utils .BasicTypeConstants ;
46+ import org .apache .commons .lang3 .ObjectUtils ;
4547import org .apache .commons .lang3 .RandomStringUtils ;
4648import org .apache .commons .lang3 .tuple .Pair ;
4749import org .springframework .cloud .contract .spec .Contract ;
@@ -208,6 +210,7 @@ private List<Response> processResponse(final String name, final ApiResponse apiR
208210 final var response = new Response ();
209211 response .body (response .anyAlphaNumeric ());
210212 response .setBodyMatchers (new ResponseBodyMatchers ());
213+ response .status (solveStatus (name ));
211214 responseList .add (response );
212215 }
213216 }
@@ -259,8 +262,7 @@ private Integer solveStatus(final String name) {
259262 return "default" .equalsIgnoreCase (name ) ? 200 : Integer .parseInt (name );
260263 }
261264
262- private List <Pair <Body , BodyMatchers >> processResponseBody (
263- final Schema schema ) {
265+ private List <Pair <Body , BodyMatchers >> processResponseBody (final Schema schema ) {
264266 final var bodyList = new ArrayList <Pair <Body , BodyMatchers >>();
265267 if (schema instanceof ComposedSchema ) {
266268 final ComposedSchema composedSchema = (ComposedSchema ) schema ;
@@ -342,7 +344,7 @@ private List<Pair<Body, BodyMatchers>> processBodyAndMatchers(final Schema schem
342344
343345 final var result = new LinkedList <Pair <Body , BodyMatchers >>();
344346 if (Objects .nonNull (schema .getType ())) {
345- result .add (processBodyAndMatchersByType (schema ));
347+ result .addAll (processBodyAndMatchersByType (schema ));
346348 }
347349 if (Objects .nonNull (schema .get$ref ())) {
348350 result .addAll (processBodyAndMatchersByRef (schema ));
@@ -360,7 +362,11 @@ private List<Pair<Body, BodyMatchers>> processBodyAndMatchersByRef(final Schema
360362 }
361363 } else {
362364 final Schema arraySchema = getSchemaFromComponent (ref );
363- bodyList = this .applyObjectToBodyList (bodyList , null , writeBodyMatcher (null , "[0]" , arraySchema , arraySchema .getType ()));
365+ if (Objects .nonNull (arraySchema )) {
366+ bodyList = this .applyObjectToBodyList (bodyList , null , writeBodyMatcher (null , "[0]" , arraySchema , arraySchema .getType ()));
367+ } else {
368+ throw new MultiApiContractConverterException ("Unsupported Schema" );
369+ }
364370 }
365371 return bodyList ;
366372 }
@@ -481,44 +487,70 @@ private Object addProperty(final Object dslValue, final String property, final O
481487 return result ;
482488 }
483489
484- private Pair <Body , BodyMatchers > processBodyAndMatchersByType (final Schema schema ) {
490+ private List <Pair <Body , BodyMatchers >> processBodyAndMatchersByType (final Schema schema ) {
491+ final List <Pair <Body , BodyMatchers >> bodyBodyMatList = new LinkedList <>();
485492 final Body body ;
486493 final BodyMatchers bodyMatchers = new BodyMatchers ();
487- if (Objects .nonNull (schema .getProperties ())) {
488- final Map <String , Object > bodyMap = new HashMap <>();
489- final Map <String , Schema > basicObjectProperties = schema .getProperties ();
490- for (Entry <String , Schema > property : basicObjectProperties .entrySet ()) {
491- if (Objects .nonNull (property .getValue ().get$ref ())) {
492- final String subRef = OpenApiContractConverterUtils .mapRefName (property .getValue ());
493- final HashMap <String , Schema > subProperties = (HashMap <String , Schema >) getSchemaFromComponent (subRef ).getProperties ();
494- final var result = processComplexBodyAndMatchers (property .getKey (), subProperties );
495- bodyMap .put (property .getKey (), result .getLeft ());
496- bodyMatchers .matchers ().addAll (result .getRight ().matchers ());
494+ if (schema instanceof ObjectSchema ) {
495+ if (Objects .nonNull (schema .getProperties ())) {
496+ final Map <String , Object > bodyMap = new HashMap <>();
497+ final Map <String , Schema > basicObjectProperties = schema .getProperties ();
498+ final List <Pair <Body , BodyMatchers >> composedElement = new LinkedList <>();
499+ for (Entry <String , Schema > property : basicObjectProperties .entrySet ()) {
500+ if (Objects .nonNull (property .getValue ().get$ref ())) {
501+ final String subRef = OpenApiContractConverterUtils .mapRefName (property .getValue ());
502+ final var componentSchema = getSchemaFromComponent (subRef );
503+ if (Objects .nonNull (componentSchema .getProperties ())) {
504+ final Map <String , Schema > subProperties = new HashMap <>(componentSchema .getProperties ());
505+ final var result = processComplexBodyAndMatchers (property .getKey (), subProperties );
506+ bodyMap .put (property .getKey (), result .getLeft ());
507+ bodyMatchers .matchers ().addAll (result .getRight ().matchers ());
508+ } else if (componentSchema instanceof ArraySchema ) {
509+ final var array = processArray (componentSchema , property .getKey ());
510+ bodyMap .put (property .getKey (), array .getLeft ());
511+ bodyMatchers .matchers ().addAll (array .getRight ().matchers ());
512+ }
513+ } else {
514+ final var result = writeBodyMatcher (null , property .getKey (), property .getValue (), property .getValue ().getType ());
515+ bodyMap .put (property .getKey (), result .getLeft ());
516+ bodyMatchers .matchers ().addAll (result .getRight ().matchers ());
517+ }
518+ }
519+ body = new Body (bodyMap );
520+ if (composedElement .isEmpty ()) {
521+ bodyBodyMatList .add (Pair .of (body , bodyMatchers ));
497522 } else {
498- final var result = writeBodyMatcher ( null , property . getKey (), property . getValue (), property . getValue (). getType ());
499- bodyMap . put ( property . getKey (), result . getLeft ( ));
500- bodyMatchers . matchers (). addAll ( result . getRight (). matchers ());
523+ for ( var halfy : composedElement ) {
524+ bodyBodyMatList . add ( bodyJoin ( halfy , body , bodyMatchers ));
525+ }
501526 }
502527 }
503- body = new Body (bodyMap );
528+ } else if (schema instanceof ArraySchema ) {
529+ final var array = processArray (schema , "[0]" );
530+ body = new Body (array .getLeft ());
531+ bodyMatchers .matchers ().addAll (array .getRight ().matchers ());
532+ bodyBodyMatList .add (Pair .of (body , bodyMatchers ));
533+ } else if (schema instanceof ComposedSchema ) {
534+ bodyBodyMatList .addAll (processComposedSchema ((ComposedSchema ) schema ));
504535 } else {
505536 final var result = writeBodyMatcher (null , "[0]" , schema , schema .getType ());
506537 body = new Body (result .getLeft ());
507538 bodyMatchers .matchers ().addAll (result .getRight ().matchers ());
539+ bodyBodyMatList .add (Pair .of (body , bodyMatchers ));
508540 }
509- return Pair . of ( body , bodyMatchers ) ;
541+ return bodyBodyMatList ;
510542 }
511543
512544 private Pair <Object , BodyMatchers > writeBodyMatcher (final Entry <String , Schema > property , final String fieldName , final Schema schema , final String type ) {
513- final var example = Objects . nonNull (property ) ? property . getValue (). getExample () : schema . getExample ( );
545+ final var example = getSafeExample (property , schema );
514546 final var bodyMatchers = new BodyMatchers ();
515547 final Pair <Object , BodyMatchers > result ;
516548 if (Objects .nonNull (example )) {
517549 result = Pair .of (schema .getExample (), bodyMatchers );
518550 } else {
519551 final String mapKey = Objects .nonNull (property ) ? property .getKey () : fieldName ;
520552
521- switch (type ) {
553+ switch (ObjectUtils . defaultIfNull ( type , BasicTypeConstants . GENERIC ) ) {
522554 case BasicTypeConstants .STRING :
523555 bodyMatchers .jsonPath (fieldName , bodyMatchers .byRegex (BasicTypeConstants .STRING_REGEX ));
524556 result = Pair .of (RandomStringUtils .random (5 , true , true ), bodyMatchers );
@@ -537,7 +569,7 @@ private Pair<Object, BodyMatchers> writeBodyMatcher(final Entry<String, Schema>
537569 result = processObjectBodyMatcher (property , fieldName , schema );
538570 break ;
539571 case BasicTypeConstants .ARRAY :
540- final var arraySchema = Objects .nonNull (property ) ? null : ( ArraySchema ) schema ;
572+ final var arraySchema = Objects .nonNull (property ) ? null : schema ;
541573 result = processArrayBodyMatcher (property , fieldName , arraySchema );
542574 break ;
543575 case BasicTypeConstants .ENUM :
@@ -546,6 +578,9 @@ private Pair<Object, BodyMatchers> writeBodyMatcher(final Entry<String, Schema>
546578 case BasicTypeConstants .MAP :
547579 result = processMapBodyMatcher (schema , fieldName );
548580 break ;
581+ case BasicTypeConstants .GENERIC :
582+ result = processEmptyObject (fieldName );
583+ break ;
549584 default :
550585 bodyMatchers .jsonPath (mapKey , bodyMatchers .byRegex (BasicTypeConstants .DEFAULT_REGEX ));
551586 result = Pair .of (RandomStringUtils .random (5 , true , true ), bodyMatchers );
@@ -555,17 +590,36 @@ private Pair<Object, BodyMatchers> writeBodyMatcher(final Entry<String, Schema>
555590 return result ;
556591 }
557592
558- private Pair <Object , BodyMatchers > processArrayBodyMatcher (final Entry <String , Schema > property , final String fieldName , final ArraySchema schema ) {
593+ private static Object getSafeExample (final Entry <String , Schema > property , final Schema schema ) {
594+ final var propertyExample = Objects .nonNull (property ) ? property .getValue ().getExample () : null ;
595+ final var schemaExample = Objects .nonNull (schema ) ? schema .getExample () : null ;
596+
597+ return ObjectUtils .defaultIfNull (propertyExample , schemaExample );
598+ }
599+
600+ private Pair <Object , BodyMatchers > processArrayBodyMatcher (final Entry <String , Schema > property , final String fieldName , final Schema schema ) {
559601 final Object result ;
560- final Schema <?> arraySchema = Objects .nonNull (property ) ? ((ArraySchema ) property .getValue ()).getItems () : schema .getItems ();
561- if (Objects .nonNull (arraySchema .getExample ())) {
562- result = Pair .of (arraySchema .getExample (), new BodyMatchers ());
602+ final Schema <?> arraySchema = getArraySchema (property , schema );
603+ if (Objects .nonNull (arraySchema )) {
604+ if (Objects .nonNull (arraySchema .getExample ())) {
605+ result = Pair .of (arraySchema .getExample (), new BodyMatchers ());
606+ } else {
607+ result = processArray (arraySchema , fieldName );
608+ }
563609 } else {
564- result = processArray ( arraySchema , fieldName );
610+ result = processEmptyObject ( property . getKey () );
565611 }
566612 return (Pair <Object , BodyMatchers >) result ;
567613 }
568614
615+ private static Schema <?> getArraySchema (final Entry <String , Schema > property , final Schema schema ) {
616+ var schemaItems = schema instanceof ArraySchema ? ((ArraySchema ) schema ).getItems () : schema ;
617+ if (Objects .nonNull (property ) && property .getValue () instanceof ArraySchema ) {
618+ schemaItems = ((ArraySchema ) property .getValue ()).getItems ();
619+ }
620+ return schemaItems ;
621+ }
622+
569623 private Pair <Object , BodyMatchers > processObjectBodyMatcher (final Entry <String , Schema > property , final String fieldName , final Schema schema ) {
570624 final Pair <Object , BodyMatchers > result ;
571625 final String ref = Objects .nonNull (property ) ? property .getValue ().get$ref () : schema .get$ref ();
@@ -578,9 +632,13 @@ private Pair<Object, BodyMatchers> processObjectBodyMatcher(final Entry<String,
578632 } else if (Objects .nonNull (internalRef .getProperties ())) {
579633 final Map <String , Schema > subProperties = internalRef .getProperties ();
580634 result = processComplexBodyAndMatchers (fieldName , subProperties );
581- } else {
635+ } else if ( Objects . nonNull ( internalRef . getAdditionalProperties ())) {
582636 final Schema subProperties = (Schema ) internalRef .getAdditionalProperties ();
583637 result = writeBodyMatcher (null , fieldName , subProperties , BasicTypeConstants .MAP );
638+ } else {
639+ var matcher = new BodyMatchers ();
640+ matcher .jsonPath ("" , new BodyMatchers ().byRegex (BasicTypeConstants .DEFAULT_REGEX ));
641+ result = Pair .of (new Object (), matcher );
584642 }
585643 return result ;
586644 }
@@ -702,7 +760,7 @@ private Pair<List<Object>, BodyMatchers> processArray(final Schema<?> arraySchem
702760 } else {
703761 final String type = arraySchema .getType ();
704762 final Pair tempValue ;
705- switch (type ) {
763+ switch (ObjectUtils . defaultIfNull ( type , BasicTypeConstants . GENERIC ) ) {
706764 case BasicTypeConstants .STRING :
707765 tempValue = processStringArray (arraySchema , objectName );
708766 break ;
@@ -716,11 +774,23 @@ private Pair<List<Object>, BodyMatchers> processArray(final Schema<?> arraySchem
716774 tempValue = processBooleanArray (arraySchema , objectName );
717775 break ;
718776 case BasicTypeConstants .ARRAY :
719- tempValue = processArrayArray ((ArraySchema ) arraySchema , objectName );
777+ if (arraySchema instanceof ArraySchema ) {
778+ final var calculatedValue = processArrayArray ((ArraySchema ) arraySchema , objectName );
779+ if (Objects .nonNull (((ArraySchema ) arraySchema ).getItems ().getType ())) {
780+ tempValue = calculatedValue ;
781+ } else {
782+ tempValue = Pair .of (calculatedValue .getLeft ().get (0 ), calculatedValue .getRight ());
783+ }
784+ } else {
785+ tempValue = processEmptyObjectArray (objectName );
786+ }
720787 break ;
721788 case BasicTypeConstants .OBJECT :
722789 tempValue = processObjectArray (arraySchema , objectName );
723790 break ;
791+ case BasicTypeConstants .GENERIC :
792+ tempValue = processEmptyObjectArray (objectName );
793+ break ;
724794 default :
725795 tempValue = null ;
726796 log .error ("Format not supported" );
@@ -732,7 +802,6 @@ private Pair<List<Object>, BodyMatchers> processArray(final Schema<?> arraySchem
732802 bodyMatchers .matchers ().addAll (((BodyMatchers ) tempValue .getRight ()).matchers ());
733803 } else {
734804 bodyMatchers .matchers ().add ((BodyMatcher ) tempValue .getRight ());
735-
736805 }
737806 }
738807 }
@@ -741,7 +810,25 @@ private Pair<List<Object>, BodyMatchers> processArray(final Schema<?> arraySchem
741810
742811 private Pair <Object , BodyMatchers > processObjectArray (final Schema <?> arraySchema , final String objectName ) {
743812 final HashMap <String , Schema > subObject = (HashMap <String , Schema >) arraySchema .getProperties ();
744- return processComplexBodyAndMatchers (objectName , subObject );
813+ final Pair <Object , BodyMatchers > result ;
814+ if (Objects .nonNull (subObject )) {
815+ result = processComplexBodyAndMatchers (objectName , subObject );
816+ } else {
817+ result = processEmptyObjectArray (objectName );
818+ }
819+ return result ;
820+ }
821+
822+ private Pair <Object , BodyMatchers > processEmptyObjectArray (final String objectName ) {
823+ var matcher = new BodyMatchers ();
824+ matcher .jsonPath (objectName + "[0]" , new BodyMatchers ().byRegex (BasicTypeConstants .DEFAULT_REGEX ));
825+ return Pair .of (Collections .emptyList (), matcher );
826+ }
827+
828+ private Pair <Object , BodyMatchers > processEmptyObject (final String objectName ) {
829+ var matcher = new BodyMatchers ();
830+ matcher .jsonPath (objectName , new BodyMatchers ().byRegex (BasicTypeConstants .DEFAULT_REGEX ));
831+ return Pair .of (Collections .emptyList (), matcher );
745832 }
746833
747834 private Pair <List <Object >, BodyMatchers > processArrayArray (final ArraySchema arraySchema , final String objectName ) {
@@ -896,19 +983,28 @@ private Pair<Body, BodyMatchers> unify(final List<Pair<Body, BodyMatchers>> temp
896983 return Pair .of (body , bodyMatchers );
897984 }
898985
986+ private Pair <Body , BodyMatchers > bodyJoin (final Pair <Body , BodyMatchers > tempBody , final Body body , final BodyMatchers matchers ) {
987+ final BodyMatchers bodyMatchers = new BodyMatchers ();
988+ final var newBody = combineProperties (body , tempBody .getLeft ());
989+ bodyMatchers .matchers ().addAll (tempBody .getRight ().matchers ());
990+ bodyMatchers .matchers ().addAll (matchers .matchers ());
991+ return Pair .of (newBody , bodyMatchers );
992+ }
899993 private List <Schema <?>> combineSchema (final List <Schema > anyOfThis ) {
900994 final List <Schema <?>> finalList = new LinkedList <>();
901- final var anySchema = solveReferenced (anyOfThis .remove (0 ));
902- if (anyOfThis .isEmpty ()) {
903- finalList .add (cloneSchema (anySchema ));
904- } else {
905- finalList .add (anySchema );
906- final List <Schema <?>> tempList = combineSchema (anyOfThis );
907- finalList .addAll (tempList );
908- for (var temp : tempList ) {
909- final var swap = cloneSchema (temp );
910- swap .getProperties ().putAll (anySchema .getProperties ());
911- finalList .add (swap );
995+ if (!anyOfThis .isEmpty ()) {
996+ final var anySchema = solveReferenced (anyOfThis .remove (0 ));
997+ if (anyOfThis .isEmpty ()) {
998+ finalList .add (cloneSchema (anySchema ));
999+ } else {
1000+ finalList .add (anySchema );
1001+ final List <Schema <?>> tempList = combineSchema (anyOfThis );
1002+ finalList .addAll (tempList );
1003+ for (var temp : tempList ) {
1004+ final var swap = cloneSchema (temp );
1005+ swap .getProperties ().putAll (anySchema .getProperties ());
1006+ finalList .add (swap );
1007+ }
9121008 }
9131009 }
9141010
@@ -994,7 +1090,11 @@ private Map<String, Schema> cloneProperties(final Map<String, Schema> properties
9941090 if (Objects .nonNull (properties )) {
9951091 properties .forEach ((key , property ) -> {
9961092 if ("array" .equalsIgnoreCase (property .getType ())) {
997- propertiesMap .put (key , cloneArraySchema ((ArraySchema ) property ));
1093+ if (property instanceof ArraySchema ) {
1094+ propertiesMap .put (key , cloneArraySchema ((ArraySchema ) property ));
1095+ } else {
1096+ propertiesMap .put (key , cloneSchema (property ));
1097+ }
9981098 } else if (Objects .nonNull (property .getAdditionalProperties ())) {
9991099 propertiesMap .put (key , cloneMapSchema ((MapSchema ) property ));
10001100 } else {
@@ -1051,7 +1151,7 @@ private Schema solveReferenced(final Schema schema) {
10511151 }
10521152
10531153 private boolean existSchemaWithPropertiesInComponent (final String ref ) {
1054- return Objects .nonNull (componentsMap .get (ref ).getProperties ());
1154+ return componentsMap . containsKey ( ref ) && Objects .nonNull (componentsMap .get (ref ).getProperties ());
10551155 }
10561156
10571157 private Schema <?> getSchemaFromComponent (final String ref ) {
0 commit comments