Skip to content
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

Fix for #24 #26

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions samples/Drupal8/DevPortal/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
<portal.api.doc.format>basic_html</portal.api.doc.format><!-- Format in the portal. Values: basic_html, restricted_html, full_html -->
<portal.directory>./specs</portal.directory> <!-- Directory where OpenAPI specs are accessible. Using ./specs for sample -->
<apigee.smartdocs.config.file>./apicatalog-config.json</apigee.smartdocs.config.file> <!-- Config for fields -->
<portal.api.id.field>title</portal.api.id.field>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nandoan - Why do I need this entry in the pom file? Why not just get the entry from apicatalog json as you are looking for "title" anyways?

</properties>
</profile>
</profiles>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,13 @@ public abstract class PortalAbstractMojo extends AbstractMojo {
*/
private String configFile;

/**
* Config File
*
* @parameter property="portal.api.id.field"
*/
private String apiIdField;

/**
* Portal User Name
*
Expand Down Expand Up @@ -181,6 +188,7 @@ public ServerProfile getProfile() {
this.buildProfile = new ServerProfile();
this.buildProfile.setOptions(this.options);
this.buildProfile.setConfigFile(this.configFile);
this.buildProfile.setApiIdField(this.apiIdField);
this.buildProfile.setPortalUserName(this.portalUserName);
this.buildProfile.setPortalPassword(this.portalPassword);
this.buildProfile.setPortalDirectory(this.portalDirectory);
Expand Down
119 changes: 72 additions & 47 deletions src/main/java/com/apigee/smartdocs/config/rest/PortalRestUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -365,50 +365,46 @@ private static ByteArrayContent constructAPIDocRequestBody(ServerProfile profile
JsonObject relationships = new JsonObject();

//config
if(profile.getConfigFile()!=null && !profile.getConfigFile().equalsIgnoreCase("")) {
FileContent tempFileContent = new FileContent("application/json", new File(profile.getConfigFile()).getAbsoluteFile());
Reader reader = new InputStreamReader(tempFileContent.getInputStream());
Map<String, Object> result = new ObjectMapper().readValue(reader, HashMap.class);
if(result!=null && result.size()>0) {
//For Custom Fields
Map<String, Object> fieldsMap = (Map<String, Object>) result.get("fields");
if(fieldsMap!=null && fieldsMap.size()>0) {
for (String key : fieldsMap.keySet()) {
if(fieldsMap.get(key) instanceof List){
attributes.add(key, gson.toJsonTree(fieldsMap.get(key)));
}
//no need to add to attributes for "field_image"
else if (key!=null && key.equals("field_image")){
hasImage = true;
imageFile = new File(profile.getPortalDirectory()+"/"+(String)fieldsMap.get(key));
}
else
attributes.addProperty(key, (String)fieldsMap.get(key));
Map<String, Object> result = loadApiConfigFile(profile);
if(result!=null && result.size()>0) {
//For Custom Fields
Map<String, Object> fieldsMap = (Map<String, Object>) result.get("fields");
if(fieldsMap!=null && fieldsMap.size()>0) {
for (String key : fieldsMap.keySet()) {
if(fieldsMap.get(key) instanceof List){
attributes.add(key, gson.toJsonTree(fieldsMap.get(key)));
}
//no need to add to attributes for "field_image"
else if (key!=null && key.equals("field_image")){
hasImage = true;
imageFile = new File(profile.getPortalDirectory()+"/"+(String)fieldsMap.get(key));
}
else
attributes.addProperty(key, (String)fieldsMap.get(key));
}
//For Custom taxonomy_terms
List<Map<String, Object>> taxonomyTerm = (List<Map<String, Object>>) result.get("taxonomy_terms");
if(taxonomyTerm!=null && taxonomyTerm.size()>0) {
for (Map<String, Object> map : taxonomyTerm) {
Map<String, List<String>> taxonomyTermsIdMap = getTaxonomyTermId(profile, map);
if(taxonomyTermsIdMap!=null && taxonomyTermsIdMap.size()>0) {
JsonArray taxonomyData = new JsonArray();
for (String key : taxonomyTermsIdMap.keySet()) {
List<String> list = taxonomyTermsIdMap.get(key);
if(list!=null && list.size()>0) {
for (String id : taxonomyTermsIdMap.get(key)) {
JsonObject taxonomyId = new JsonObject();
taxonomyId.addProperty("type", "taxonomy_term--"+(String)map.get("vocabulary"));
taxonomyId.addProperty("id", id);
taxonomyData.add(taxonomyId);
}
}
//For Custom taxonomy_terms
List<Map<String, Object>> taxonomyTerm = (List<Map<String, Object>>) result.get("taxonomy_terms");
if(taxonomyTerm!=null && taxonomyTerm.size()>0) {
for (Map<String, Object> map : taxonomyTerm) {
Map<String, List<String>> taxonomyTermsIdMap = getTaxonomyTermId(profile, map);
if(taxonomyTermsIdMap!=null && taxonomyTermsIdMap.size()>0) {
JsonArray taxonomyData = new JsonArray();
for (String key : taxonomyTermsIdMap.keySet()) {
List<String> list = taxonomyTermsIdMap.get(key);
if(list!=null && list.size()>0) {
for (String id : taxonomyTermsIdMap.get(key)) {
JsonObject taxonomyId = new JsonObject();
taxonomyId.addProperty("type", "taxonomy_term--"+(String)map.get("vocabulary"));
taxonomyId.addProperty("id", id);
taxonomyData.add(taxonomyId);
}
JsonObject taxonomyDataObj = new JsonObject();
taxonomyDataObj.add("data", taxonomyData);
relationships.add(key, taxonomyDataObj);
}
}
}
JsonObject taxonomyDataObj = new JsonObject();
taxonomyDataObj.add("data", taxonomyData);
relationships.add(key, taxonomyDataObj);
}
}
}
}
Expand Down Expand Up @@ -458,6 +454,16 @@ else if (key!=null && key.equals("field_image")){
ByteArrayContent content = new ByteArrayContent("application/vnd.api+json", payload.getBytes());
return content;
}

public static Map<String, Object> loadApiConfigFile(ServerProfile profile) throws IOException {
Map<String, Object> result = null;
if(profile.getConfigFile()!=null && !profile.getConfigFile().equalsIgnoreCase("")) {
FileContent tempFileContent = new FileContent("application/json", new File(profile.getConfigFile()).getAbsoluteFile());
Reader reader = new InputStreamReader(tempFileContent.getInputStream());
result = new ObjectMapper().readValue(reader, HashMap.class);
}
return result;
}

/**
* Posts the OpenAPI Spec to a APIDoc in Developer Portal.
Expand Down Expand Up @@ -536,14 +542,32 @@ public static Map<String, List<String>> getTaxonomyTermId(ServerProfile profile,
public static APIDocResponseObject getAPIDoc(ServerProfile profile, File file) throws IOException {
HttpResponse response = null;
try {
SpecObject spec = parseSpec(profile, file);
logger.info("Getting API doc for "+ spec.getTitle());
String apiIdField = profile.getApiIdField();
String apiIdValue = null;
if (apiIdField != null && !apiIdField.equals("title")) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nandoan - not sure I prefer the title check being hardcoded, then it doesnt make sense to have this in the pom as a property. The ideal thing would be to just look for the title field in the apicatalog json or else get the value from the pom and see if that matches any key in the apicatalog json and use that value in the code.

Map<String, Object> result = loadApiConfigFile(profile);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nandoan - Can you add the entry in the apicatalog json. Its missing in the PR

if(result!=null && result.size()>0 && result.get("fields")!=null) {
Map<String, Object> fieldsMap = (Map<String, Object>) result.get("fields");
if(fieldsMap!=null && fieldsMap.get(apiIdField) != null) {
apiIdValue = (String)fieldsMap.get(apiIdField);
}else {
throw new IllegalArgumentException("Identification field " + apiIdField + " not provided");
}
}
}else {
SpecObject spec = parseSpec(profile, file);
apiIdField = "title";
apiIdValue = spec.getTitle();
}


logger.info("Getting API doc for "+ apiIdValue);
HttpRequest restRequest = REQUEST_FACTORY
.buildGetRequest(new GenericUrl(profile.getPortalURL() + "/jsonapi/node/apidoc?filter[title]=" + spec.getTitle()));
.buildGetRequest(new GenericUrl(profile.getPortalURL() + "/jsonapi/node/apidoc?filter[" + apiIdField + "]=" + apiIdValue));
HttpHeaders headers = restRequest.getHeaders();
headers.setAccept("application/vnd.api+json");
headers.setBasicAuthentication(profile.getPortalUserName(), profile.getPortalPassword());
logger.info("Retrieving " + spec.getTitle() + " doc.");
logger.info("Retrieving " + apiIdValue + " doc.");
restRequest.setReadTimeout(0);
response = restRequest.execute();
Gson gson = new Gson();
Expand All @@ -553,7 +577,7 @@ public static APIDocResponseObject getAPIDoc(ServerProfile profile, File file) t
logger.info("API Doc uuid:" + model.data.get(0).id);
return model;
} else {
logger.info("API Doc: "+ spec.getTitle()+" does not exist");
logger.info("API Doc: "+ apiIdValue+" does not exist");
return null;
}

Expand Down Expand Up @@ -682,7 +706,8 @@ public static void updateAPIDoc(ServerProfile profile, File file, APIDocResponse
SpecObject spec = parseSpec(profile, file);

logger.info("Update API catalog");
ByteArrayContent content = constructAPIDocRequestBody(profile, spec, doc.data.get(0).id, doc.data.get(0).relationships.field_apidoc_spec.data.id, doc.data.get(0).relationships.field_image.data.id, true);
String imageId = doc.data.get(0).relationships.field_image.data != null ? doc.data.get(0).relationships.field_image.data.id : null;
ByteArrayContent content = constructAPIDocRequestBody(profile, spec, doc.data.get(0).id, doc.data.get(0).relationships.field_apidoc_spec.data.id, imageId, true);
HttpRequest restPatchRequest = APACHE_REQUEST_FACTORY.buildRequest(HttpMethods.PATCH, new GenericUrl(profile.getPortalURL() + "/jsonapi/node/apidoc/"+doc.data.get(0).id),
content);
HttpHeaders patchHeaders = restPatchRequest.getHeaders();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public class ServerProfile {

private String options;
private String configFile;

// Portal Parameters
private String portalUserName; // Developer Portal Username
private String portalPassword; // Developer Portal Password
Expand All @@ -33,6 +33,7 @@ public class ServerProfile {
private String portalModelVocabulary; // Model Vocabulary
private String portalCronKey; // Dev portal Cron Key
private String portalModelNameConfig; // OPTIONAL configuration for Model Name
private String apiIdField; // OPTIONAL configuration for the API Identification field
private String portalAPIDocFormat; // Dev Portal API Doc Format
private Map<String, PortalField> portalModelFields; // OpenAPI spec format

Expand Down Expand Up @@ -172,6 +173,17 @@ public String getConfigFile() {
public void setConfigFile(String configFile) {
this.configFile = configFile;
}

/**
* @param configuration for the API Identification field
*/
public String getApiIdField() {
return apiIdField;
}

public void setApiIdField(String apiIdField) {
this.apiIdField = apiIdField;
}

/**
* @param options the options to set
Expand Down