Skip to content

Commit

Permalink
Add reverse mapping for postman collection
Browse files Browse the repository at this point in the history
  • Loading branch information
cschoell committed Oct 20, 2023
1 parent 94a686d commit 17cf150
Show file tree
Hide file tree
Showing 7 changed files with 248 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,15 @@ public class GScript extends GenericModelBase {
*/
String exec;

String srcUrl;
String srcUrl;

String contentType;

String name;

String id;

boolean disabled;

/**
* The client this script has been copied from originally
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
package org.cschoell.postman.mapper;

import org.apache.commons.lang3.StringUtils;
import org.cschoell.generic.model.*;
import org.cschoell.generic.model.body.GBody;
import org.cschoell.generic.model.body.GBodyContentType;
import org.cschoell.generic.model.body.GKeyValueBody;
import org.cschoell.postman.model.*;
import org.mapstruct.*;
import org.mapstruct.factory.Mappers;

import java.net.MalformedURLException;
import java.net.URL;
import java.util.*;
import java.util.stream.Collectors;

@Mapper(imports = PostmanToGenericCollectionMapper.class)
public interface GenericCollectionToPostmanMapper {

GenericCollectionToPostmanMapper INSTANCE = Mappers.getMapper(GenericCollectionToPostmanMapper.class);


@Mapping(target = "variable", ignore = true)
@Mapping(target = "event", ignore = true)
@Mapping(target = "item", source = ".", qualifiedByName = "collectItems")
PostmanCollection toPostmanCollection(GCollection in);

@Named("collectItems")
default List<PostmanPolymorphicBase> collectItems(GCollection in) {
final List<PostmanPolymorphicBase> items = mapFoldersToPostmanList(in.getFolders());
items.addAll(mapToPostmanList(in.getRequests()));
return items;
}

@Mapping(target = "event", ignore = true)
@Mapping(target = "item", source = ".", qualifiedByName = "collectItemsFromFolder")
VirtualFolder toFolder(GFolder gFolder);

@Named("collectItemsFromFolder")
default List<Item> collectItemsFromFolder(GFolder in) {
return mapToPostmanList(in.getRequests());
}

default List<PostmanPolymorphicBase> mapFoldersToPostmanList(List<GFolder> folders) {
return folders.stream().map(this::toFolder).collect(Collectors.toList());
}

@Mapping(target = "oauth2", source = "authAttributes", conditionExpression = "java(gAuth.getAuthType() == GAuth.Type.OAUTH_2)")
@Mapping(target = "oauth1", source = "authAttributes", conditionExpression = "java(gAuth.getAuthType() == GAuth.Type.OAUTH_1)")
@Mapping(target = "ntlm", source = "authAttributes", conditionExpression = "java(gAuth.getAuthType() == GAuth.Type.NTLM)")
@Mapping(target = "hawk", source = "authAttributes", conditionExpression = "java(gAuth.getAuthType() == GAuth.Type.HAWK)")
@Mapping(target = "edgegrid", source = "authAttributes", conditionExpression = "java(gAuth.getAuthType() == GAuth.Type.EDGEGRID)")
@Mapping(target = "digest", source = "authAttributes", conditionExpression = "java(gAuth.getAuthType() == GAuth.Type.DIGEST)")
@Mapping(target = "bearer", source = "authAttributes", conditionExpression = "java(gAuth.getAuthType() == GAuth.Type.BEARER)")
@Mapping(target = "basic", source = "authAttributes", conditionExpression = "java(gAuth.getAuthType() == GAuth.Type.BASIC)")
@Mapping(target = "awsv4", source = "authAttributes", conditionExpression = "java(gAuth.getAuthType() == GAuth.Type.AWSV_4)")
@Mapping(target = "apikey", ignore = true)
Auth toAuth(GAuth gAuth);

@Named("item")
default List<Item> mapToPostmanList(List<GRequest> value) {
return value.stream().map(this::toItem).collect(Collectors.toList());
}

@Mapping(target = "event", source = ".")
@Mapping(target = "request", source = ".")
@Named("item")
Item toItem(GRequest gRequest);

@InheritInverseConfiguration
@Mapping(target = "url", source = "url.raw")
Request toRequest(GRequest from);


default List<Event> toEventList(GRequest request) {
List<Event> events = new ArrayList<>();
events.add(toEvent(request.getTests(), "test"));
events.add(toEvent(request.getPostResponseScript(), "postresponse"));
events.add(toEvent(request.getPreRequestScript(), "prerequest"));
return events;
}

@Mapping(target = "listen", source = "listen")
@Mapping(target = "script.src", source = "from.srcUrl")
@Mapping(target = "script.type", source = "from.contentType")
@Mapping(target = "script.exec", source = "from.exec")
Event toEvent(GScript from, String listen);


default List<String> toLines(String from) {
return from == null ? Collections.emptyList() : from.lines().toList();
}

default Url toUrl(String from) {
try {
URL url = new URL(from);
return new Url(from,
url.getProtocol(),
Arrays.stream(StringUtils.split(url.getHost(), ".")).collect(Collectors.toList()),
Arrays.stream(StringUtils.split(url.getPath(), "/")).collect(Collectors.toList()),
url.getPort() >= 0 ? String.valueOf(url.getPort()) : "",
toQueries(url.getQuery()),
null,
Collections.emptyList(),
new HashMap<>()

);
} catch (MalformedURLException e) {
final Url url = new Url();
url.setRaw(from);
return url;
}
}

default List<Query> toQueries(String query) {
return Arrays.stream(StringUtils.split(query, "&")).map(this::toQuery).toList();
}

default Query toQuery(String s) {
final String[] keyvalue = StringUtils.split(s, "=", 2);
Query q = new Query();
q.setKey(keyvalue[0]);
if (keyvalue.length > 1) {
q.setValue(keyvalue[1]);
}
return q;
}


@Mapping(target = "disabled", ignore = true)
@Mapping(target = "options", ignore = true)
@Mapping(target = "raw", source = "text.value")
@Mapping(target = "mode", source = "contentType")
Body toBody(GBody gBody);

@AfterMapping
default void afterToBody(@MappingTarget Body to, GBody from) {
}

default Body.Mode toBodyMode(GBodyContentType contentType) {
Body.Mode mode = switch (contentType) {
case none -> null;
case json -> Body.Mode.RAW;
case text -> Body.Mode.RAW;
case xml -> Body.Mode.RAW;
case formUrlencoded -> Body.Mode.URLENCODED;
case multipartForm -> Body.Mode.FORMDATA;
case graphql -> Body.Mode.GRAPHQL;
};
return mode;
}


default List<Urlencoded> mapListToUrlEncoded(GKeyValueBody value) {
return value.getKeyValueBody().entrySet().stream().map(this::toUrlencoded).collect(Collectors.toList());
}

default List<Formdatum> mapListToFormdata(GKeyValueBody value) {
return value.getKeyValueBody().entrySet().stream().map(this::toFormData).collect(Collectors.toList());
}

@Mapping(target = "description", source = "value.description")
@Mapping(target = "disabled", source = "value.disabled")
@Mapping(target = "additionalProperties", source = "value.additionalProperties")
@Mapping(target = "value", source = "value.value")
Urlencoded toUrlencoded(Map.Entry<String, GValue> entry);


@Mapping(target = "contentType", ignore = true)
@Mapping(target = "description", source = "value.description")
@Mapping(target = "disabled", source = "value.disabled")
@Mapping(target = "additionalProperties", source = "value.additionalProperties")
@Mapping(target = "value", source = "value.value")
Formdatum toFormData(Map.Entry<String, GValue> entry);
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@
import org.cschoell.generic.model.body.GBody;
import org.cschoell.generic.model.body.GBodyContentType;
import org.cschoell.generic.model.body.GKeyValueBody;
import org.cschoell.postman.model.Auth;
import org.cschoell.postman.model.Body;
import org.cschoell.postman.model.*;
import org.mapstruct.*;
import org.mapstruct.factory.Mappers;
Expand All @@ -15,8 +13,9 @@
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

import static org.cschoell.postman.model.Body.Mode.*;
import static org.cschoell.postman.model.Body.Mode.RAW;

@Mapper()
public interface PostmanToGenericCollectionMapper {
Expand Down Expand Up @@ -126,24 +125,34 @@ default void afterToRequestFile(@MappingTarget GRequest request, Item item) {
default void handleEvents(GRequest request, Item item) {
final List<Event> events = item.getEvent();
for (Event event : events) {
final GScript script = toGScript(event.getScript());
script.setDisabled(event.getDisabled());
switch (event.getListen()) {
case "test" -> {
request.setTests(toGScript(event.getScript()));
request.setTests(script);
}
case "prerequest" -> {
request.setPreRequestScript(toGScript(event.getScript()));
request.setPreRequestScript(script);
}
case "postresponse" -> {
request.setPostResponseScript(toGScript(event.getScript()));
request.setPostResponseScript(script);
}
}
}
}


@Mapping(target = "disabled", ignore = true)
@Mapping(target = "description", ignore = true)
@Mapping(target = "srcUrl", source = "src")
@Mapping(target = "scriptOriginClient", constant = "postman")
@Mapping(target = "contentType", source = "type")
GScript toGScript(Script script);

@Mapping(target = "type", ignore = true)
@Mapping(target = "disabled", ignore = true)
@Mapping(target = "description", ignore = true)
@Mapping(target = "additionalProperties", ignore = true)
@Mapping(target = "value", source = "val")
GValue toValue(String val);

Expand Down Expand Up @@ -224,7 +233,8 @@ default String buildUrlString(Url url) {
if (url == null) return null;
if (url.getHost() == null || url.getHost().isEmpty()) return url.getRaw();
String portString = StringUtils.isNotBlank(url.getPort()) ? ":" + url.getPort() : "";
return url.getProtocol() + "://" + StringUtils.join(url.getHost(), ".") + portString + "/" + StringUtils.join(url.getPath(), "/");
String queryString = url.getQuery().isEmpty() ? "" : "?" + url.getQuery().stream().map(query -> query.getKey() + "=" + query.getValue()).collect(Collectors.joining("&"));
return url.getProtocol() + "://" + StringUtils.join(url.getHost(), ".") + portString + "/" + StringUtils.join(url.getPath(), "/") + queryString;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,11 @@ public class Formdatum {
@JsonIgnore
private Map<String, AdditionalProperty> additionalProperties = new LinkedHashMap<>();

public Formdatum(String key, String value) {
this.key = key;
this.value = value;
}

public enum Type {

TEXT("text"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,11 @@ public class Urlencoded {
@JsonIgnore
private Map<String, AdditionalProperty> additionalProperties = new LinkedHashMap<>();

public Urlencoded(String key, String value) {
this.key = key;
this.value = value;
}

/**
*
* (Required)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.cschoell.postman.mapper;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.assertj.core.api.recursive.assertion.RecursiveAssertionConfiguration;
import org.cschoell.generic.model.GCollection;
import org.cschoell.postman.model.PostmanCollection;
import org.cschoell.postman.module.schematoobject.PostmanObjectMapperBuilder;
Expand All @@ -18,18 +19,46 @@ class PostmanToGenericCollectionMapperTest {

TestCollectionProvider provider = TestCollectionProvider.instance();
PostmanToGenericCollectionMapper mapper = PostmanToGenericCollectionMapper.INSTANCE;
GenericCollectionToPostmanMapper reverseMapper = GenericCollectionToPostmanMapper.INSTANCE;



@Test
void allmappedCorrectly() throws IOException {
final PostmanCollection postmanCollection = new SourcePostmanCollection().generateCollection();

final GCollection genericCollection = mapper.toGenericCollection(postmanCollection);

final StringWriter w = new StringWriter();
objectMapper.writeValue(w,genericCollection);
final PostmanCollection afterMapping = reverseMapper.toPostmanCollection(genericCollection);

// assertThat(postmanCollection).isEqualTo(afterMapping);

System.out.println();
System.out.println();
System.out.println();
System.out.println();
System.out.println();

final StringWriter w = new StringWriter();
objectMapper.writeValue(w,postmanCollection);
System.out.println(w);
System.out.println();
System.out.println();
System.out.println();
System.out.println();
System.out.println();

final StringWriter w2 = new StringWriter();
objectMapper.writeValue(w2,afterMapping);
System.out.println(w2);
System.out.println();
System.out.println();
System.out.println();
System.out.println();
System.out.println();

// assertThat(w).isEqualTo(w2);


}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,8 @@ public PostmanCollection generateCollection() {
final List<PostmanPolymorphicBase> items = createItems();
final List<Event> events = createEvents();
final List<Variable> variables = createVariables();
final Auth auth = createAuth();
final ProtocolProfileBehavior protocolProfileBehavior = new ProtocolProfileBehavior(null);
return new PostmanCollection(info, items, events, variables, auth, protocolProfileBehavior, null);
return new PostmanCollection(info, items, events, variables, null, protocolProfileBehavior, null);
}

private List<Variable> createVariables() {
Expand All @@ -25,15 +24,17 @@ private List<Variable> createVariables() {

private ArrayList<PostmanPolymorphicBase> createItems() {
final ArrayList<PostmanPolymorphicBase> items = new ArrayList<>();
items.add(createRequest());
final Item request = createRequest();
request.getRequest().setAuth(createAuth());
items.add(request);
items.add(createFolder());
return items;
}

private PostmanPolymorphicBase createFolder() {
final ArrayList<Item> requests = new ArrayList<>();
requests.add(createRequest());
return new VirtualFolder("folder.name", createDescription(), createVariables(), null, new ProtocolProfileBehavior(), requests, createAuth());
return new VirtualFolder("folder.name", createDescription(), createVariables(), null, new ProtocolProfileBehavior(), requests, null);
}

private Item createRequest() {
Expand All @@ -42,7 +43,7 @@ private Item createRequest() {
final Certificate certificate = new Certificate("cert.name", Arrays.asList("match1", "match2"), new Key("key.src", null),
new Cert("cert.src", null), "passphrase", null);
final Body body = new Body(Body.Mode.URLENCODED, "raw", createUrlEncoded(), createFormData(), new File("file.src", "file.content", null), new Graphql("graphql.query", "graphql.variables", null), new Options(null), false, null);
final Request request = new Request(url, createAuth(), proxy, certificate, Request.Method.GET, createDescription(), createHeaders(), body, null);
final Request request = new Request(url, null, proxy, certificate, Request.Method.GET, createDescription(), createHeaders(), body, null);
return new Item("request.name", createDescription(), createVariables(), createEvents(), new ProtocolProfileBehavior(),
"rid", request, Collections.emptyList(), null);
}
Expand Down

0 comments on commit 17cf150

Please sign in to comment.