package com.capitalone.dashboard.collector; import com.capitalone.dashboard.model.Environment; import com.capitalone.dashboard.model.EnvironmentComponent; import com.capitalone.dashboard.model.EnvironmentStatus; import com.capitalone.dashboard.model.UDeployApplication; import com.capitalone.dashboard.model.UDeployEnvResCompData; import com.capitalone.dashboard.repository.EnvironmentComponentRepository; import com.capitalone.dashboard.util.Supplier; import org.apache.commons.codec.binary.Base64; import org.apache.commons.lang3.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.json.simple.JSONArray; import org.json.simple.JSONObject; import org.json.simple.parser.JSONParser; import org.json.simple.parser.ParseException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Component; import org.springframework.web.client.RestClientException; import org.springframework.web.client.RestOperations; import java.nio.charset.Charset; import java.util.ArrayList; import java.util.List; @Component public class DefaultUDeployClient implements UDeployClient { private static final Log LOG = LogFactory .getLog(DefaultUDeployClient.class); private final UDeploySettings uDeploySettings; private final RestOperations restOperations; @Autowired public DefaultUDeployClient(UDeploySettings uDeploySettings, Supplier<RestOperations> restOperationsSupplier) { this.uDeploySettings = uDeploySettings; this.restOperations = restOperationsSupplier.get(); } @Override public List<UDeployApplication> getApplications(String instanceUrl) { List<UDeployApplication> applications = new ArrayList<>(); for (Object item : paresAsArray(makeRestCall(instanceUrl, "deploy/application"))) { JSONObject jsonObject = (JSONObject) item; UDeployApplication application = new UDeployApplication(); application.setInstanceUrl(instanceUrl); application.setApplicationName(str(jsonObject, "name")); application.setApplicationId(str(jsonObject, "id")); applications.add(application); } return applications; } @Override public List<Environment> getEnvironments(UDeployApplication application) { List<Environment> environments = new ArrayList<>(); String url = "deploy/application/" + application.getApplicationId() + "/environments/false"; for (Object item : paresAsArray(makeRestCall( application.getInstanceUrl(), url))) { JSONObject jsonObject = (JSONObject) item; environments.add(new Environment(str(jsonObject, "id"), str( jsonObject, "name"))); } return environments; } @Override public List<EnvironmentComponent> getEnvironmentComponents( UDeployApplication application, Environment environment) { List<EnvironmentComponent> components = new ArrayList<>(); String url = "deploy/environment/" + environment.getId() + "/latestDesiredInventory"; try { for (Object item : paresAsArray(makeRestCall( application.getInstanceUrl(), url))) { JSONObject jsonObject = (JSONObject) item; JSONObject versionObject = (JSONObject) jsonObject .get("version"); JSONObject componentObject = (JSONObject) jsonObject .get("component"); JSONObject complianceObject = (JSONObject) jsonObject .get("compliancy"); EnvironmentComponent component = new EnvironmentComponent(); component.setEnvironmentName(environment.getName()); component.setEnvironmentUrl(normalizeUrl( application.getInstanceUrl(), "/#environment/" + environment.getId())); component.setComponentID(str(componentObject, "id")); component.setComponentName(str(componentObject, "name")); component.setComponentVersion(str(versionObject, "name")); component.setDeployed(complianceObject.get("correctCount") .equals(complianceObject.get("desiredCount"))); component.setAsOfDate(date(jsonObject, "date")); components.add(component); } } catch (NullPointerException npe) { LOG.info("No Environment data found, No components deployed"); } return components; } // Called by DefaultEnvironmentStatusUpdater @Override public List<UDeployEnvResCompData> getEnvironmentResourceStatusData( UDeployApplication application, Environment environment) { List<UDeployEnvResCompData> environmentStatuses = new ArrayList<>(); String urlNonCompliantResources = "deploy/environment/" + environment.getId() + "/noncompliantResources"; String urlAllResources = "deploy/environment/" + environment.getId() + "/resources"; ResponseEntity<String> nonCompliantResourceResponse = makeRestCall( application.getInstanceUrl(), urlNonCompliantResources); JSONArray nonCompliantResourceJSON = paresAsArray(nonCompliantResourceResponse); ResponseEntity<String> allResourceResponse = makeRestCall( application.getInstanceUrl(), urlAllResources); JSONArray allResourceJSON = paresAsArray(allResourceResponse); for (Object item : allResourceJSON) { JSONObject jsonObject = (JSONObject) item; if (jsonObject != null) { JSONObject parentObject = (JSONObject) jsonObject.get("parent"); if (parentObject != null) { String resourceName = str(jsonObject, "name"); boolean status = "ONLINE".equalsIgnoreCase(str( parentObject, "status")); JSONArray jsonChildren = (JSONArray) jsonObject .get("children"); if ((jsonChildren != null) && (jsonChildren.size() > 0)) { for (Object children : jsonChildren) { JSONObject childrenObject = (JSONObject) children; String componentName = (String) childrenObject .get("name"); UDeployEnvResCompData data = new UDeployEnvResCompData(); data.setEnvironmentName(environment.getName()); data.setCollectorItemId(application.getId()); data.setResourceName(resourceName); data.setOnline(status); data.setComponentName(componentName); JSONArray jsonVersions = (JSONArray) childrenObject .get("versions"); String version = "UNKNOWN"; data.setDeployed(false); if ((jsonVersions != null) && (jsonVersions.size() > 0)) { JSONObject versionObject = (JSONObject) jsonVersions .get(0); version = (String) versionObject.get("name"); data.setAsOfDate(date(versionObject, "created")); data.setDeployed(true); } else { // get it from non-compliant resource list nonCompliantSearchLoop: for (Object nonCompItem : nonCompliantResourceJSON) { JSONArray nonCompChildrenArray = (JSONArray) ((JSONObject) nonCompItem) .get("children"); for (Object nonCompChildItem : nonCompChildrenArray) { JSONObject nonCompChildObject = (JSONObject) nonCompChildItem; JSONObject nonCompVersonObject = (JSONObject) nonCompChildObject .get("version"); if (nonCompVersonObject != null) { JSONObject nonCompComponentObject = (JSONObject) nonCompVersonObject .get("component"); if ((nonCompComponentObject != null) && (componentName .equalsIgnoreCase((String) nonCompComponentObject .get("name")))) { version = (String) nonCompVersonObject .get("name"); data.setAsOfDate(date( nonCompVersonObject, "created")); data.setDeployed(false); break nonCompliantSearchLoop; } } } } } data.setComponentVersion(version); environmentStatuses.add(data); } } } } } return environmentStatuses; } // ////// Helpers private ResponseEntity<String> makeRestCall(String instanceUrl, String endpoint) { String url = normalizeUrl(instanceUrl, "/rest/" + endpoint); ResponseEntity<String> response = null; try { response = restOperations.exchange(url, HttpMethod.GET, new HttpEntity<>(createHeaders()), String.class); } catch (RestClientException re) { LOG.error("Error with REST url: " + url); LOG.error(re.getMessage()); } return response; } private String normalizeUrl(String instanceUrl, String remainder) { return StringUtils.removeEnd(instanceUrl, "/") + remainder; } private HttpHeaders createHeaders() { return new HttpHeaders() { { String auth = uDeploySettings.getUsername() + ":" + uDeploySettings.getPassword(); byte[] encodedAuth = Base64.encodeBase64(auth.getBytes(Charset .forName("US-ASCII"))); String authHeader = "Basic " + new String(encodedAuth); set("Authorization", authHeader); } }; } private JSONArray paresAsArray(ResponseEntity<String> response) { if (response == null) return new JSONArray(); try { return (JSONArray) new JSONParser().parse(response.getBody()); } catch (ParseException pe) { LOG.debug(response.getBody()); LOG.error(pe.getMessage()); } return new JSONArray(); } private String str(JSONObject json, String key) { Object value = json.get(key); return value == null ? null : value.toString(); } private long date(JSONObject jsonObject, String key) { Object value = jsonObject.get(key); return value == null ? 0 : (long) value; } }