+
+ /**
+ * Get Policy Type definitions. This could be previously loaded, or could be
+ * stored in application path, or may need to be pulled from the API.
+ *
+ *
+ * @param policyTypeId Policy Type Id
+ * @return A list of PolicyTypes
+ */
+ private List<ToscaPolicyType> getPolicyTypes(ToscaPolicyTypeIdentifier policyTypeId) {
+ //
+ // Create identifier from the policy
+ //
+ ToscaPolicyTypeIdentifier typeId = new ToscaPolicyTypeIdentifier(policyTypeId);
+ //
+ // Find the Policy Type
+ //
+ ToscaPolicyType policyType = findPolicyType(typeId);
+ if (policyType == null) {
+ return Collections.emptyList();
+ }
+ //
+ // Create our return object
+ //
+ List<ToscaPolicyType> listTypes = new ArrayList<>();
+ listTypes.add(policyType);
+ //
+ // Look for parent policy types that could also contain matchable properties
+ //
+ ToscaPolicyType childPolicyType = policyType;
+ while (! childPolicyType.getDerivedFrom().startsWith("tosca.policies.Root")) {
+ //
+ // Create parent policy type id.
+ //
+ // We will have to assume the same version between child and the
+ // parent policy type it derives from.
+ //
+ // Or do we assume 1.0.0?
+ //
+ String strDerivedFrom = childPolicyType.getDerivedFrom();
+ //
+ // Hack that fixes policy/models appending 0.0.0 to the derivedFrom name
+ //
+ if (strDerivedFrom.endsWith("0.0.0")) {
+ strDerivedFrom = strDerivedFrom.substring(0, strDerivedFrom.length() - "0.0.0".length() - 1);
+ }
+ ToscaPolicyTypeIdentifier parentId = new ToscaPolicyTypeIdentifier(strDerivedFrom, "1.0.0");
+ //
+ // Find the policy type
+ //
+ ToscaPolicyType parentPolicyType = findPolicyType(parentId);
+ if (parentPolicyType == null) {
+ //
+ // Probably would be best to throw an exception and
+ // return nothing back.
+ //
+ // But instead we will log a warning
+ //
+ LOGGER.warn("Missing parent policy type - proceeding anyway {}", parentId);
+ //
+ // Break the loop
+ //
+ break;
+ }
+ //
+ // Great save it
+ //
+ listTypes.add(parentPolicyType);
+ //
+ // Move to the next parent
+ //
+ childPolicyType = parentPolicyType;
+ }
+
+
+ return listTypes;
+ }
+
+ private ToscaPolicyType findPolicyType(ToscaPolicyTypeIdentifier policyTypeId) {
+ //
+ // Is it loaded in memory?
+ //
+ ToscaPolicyType policyType = this.matchablePolicyTypes.get(policyTypeId);
+ if (policyType == null) {
+ //
+ // Load the policy
+ //
+ policyType = this.loadPolicyType(policyTypeId);
+ }
+ //
+ // Yep return it
+ //
+ return policyType;
+ }
+
+ private ToscaPolicyType loadPolicyType(ToscaPolicyTypeIdentifier policyTypeId) {
+ //
+ // Construct what the file name should be
+ //
+ Path policyTypePath = this.constructLocalFilePath(policyTypeId);
+ //
+ // See if it exists
+ //
+ byte[] bytes;
+ try {
+ //
+ // If it exists locally, read the bytes in
+ //
+ bytes = Files.readAllBytes(policyTypePath);
+ } catch (IOException e) {
+ //
+ // Does not exist locally, so let's GET it from the policy api
+ //
+ LOGGER.error("PolicyType not found in data area yet {}", policyTypePath, e);
+ //
+ // So let's pull it from API REST call and save it locally
+ //
+ return this.pullPolicyType(policyTypeId, policyTypePath);
+ }
+ LOGGER.info("Read in local policy type {}", policyTypePath.toAbsolutePath());
+ try {
+ ToscaServiceTemplate serviceTemplate = standardCoder.decode(new String(bytes, StandardCharsets.UTF_8),
+ ToscaServiceTemplate.class);
+ JpaToscaServiceTemplate jtst = new JpaToscaServiceTemplate();
+ jtst.fromAuthorative(serviceTemplate);
+ ToscaServiceTemplate completedJtst = jtst.toAuthorative();
+ //
+ // Search for our Policy Type, there really only should be one but
+ // this is returned as a map.
+ //
+ for ( Entry<String, ToscaPolicyType> entrySet : completedJtst.getPolicyTypes().entrySet()) {
+ ToscaPolicyType entryPolicyType = entrySet.getValue();
+ if (policyTypeId.getName().equals(entryPolicyType.getName())
+ && policyTypeId.getVersion().equals(entryPolicyType.getVersion())) {
+ LOGGER.info("Found existing local policy type {} {}", entryPolicyType.getName(),
+ entryPolicyType.getVersion());
+ //
+ // Just simply return the policy type right here
+ //
+ return entryPolicyType;
+ } else {
+ LOGGER.warn("local policy type contains different name version {} {}", entryPolicyType.getName(),
+ entryPolicyType.getVersion());
+ }
+ }
+ //
+ // This would be an error, if the file stored does not match what its supposed to be
+ //
+ LOGGER.error("Existing policy type file does not contain right name and version");
+ } catch (CoderException e) {
+ LOGGER.error("Failed to decode tosca template for {}", policyTypePath, e);
+ }
+ //
+ // Hopefully we never get here
+ //
+ LOGGER.error("Failed to find/load policy type {}", policyTypeId);
+ return null;
+ }
+
+ private synchronized ToscaPolicyType pullPolicyType(ToscaPolicyTypeIdentifier policyTypeId, Path policyTypePath) {
+ //
+ // This is what we return
+ //
+ ToscaPolicyType policyType = null;
+ try {
+ PolicyApiCaller api = new PolicyApiCaller(this.apiRestParameters);
+
+ policyType = api.getPolicyType(policyTypeId);
+ } catch (PolicyApiException e) {
+ LOGGER.error("Failed to make API call", e);
+ LOGGER.error("parameters: {} ", this.apiRestParameters);
+ return null;
+ }
+ //
+ // Store it locally
+ //
+ try {
+ standardCoder.encode(policyTypePath.toFile(), policyType);
+ } catch (CoderException e) {
+ LOGGER.error("Failed to store {} locally to {}", policyTypeId, policyTypePath, e);
+ }
+ //
+ // Done return the policy type
+ //
+ return policyType;
+ }
+
+ private Path constructLocalFilePath(ToscaPolicyTypeIdentifier policyTypeId) {
+ return Paths.get(this.pathForData.toAbsolutePath().toString(), policyTypeId.getName() + "-"
+ + policyTypeId.getVersion() + ".json");
+ }