/* * Copyright (c) 2005-2009, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. * * WSO2 Inc. licenses this file to you under the Apache License, * Version 2.0 (the "License"); you may not use this file except * in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * */ package org.wso2.carbon.governance.api.common; import org.apache.axiom.om.OMAbstractFactory; import org.apache.axiom.om.OMElement; import org.apache.axiom.om.OMNamespace; import org.apache.axiom.om.OMText; import org.apache.commons.lang.ArrayUtils; import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.wso2.carbon.governance.api.common.dataobjects.GovernanceArtifact; import org.wso2.carbon.governance.api.common.dataobjects.GovernanceArtifactImpl; import org.wso2.carbon.governance.api.exception.GovernanceException; import org.wso2.carbon.governance.api.generic.dataobjects.GenericArtifact; import org.wso2.carbon.governance.api.util.GovernanceArtifactConfiguration; import org.wso2.carbon.governance.api.util.GovernanceUtils; import org.wso2.carbon.registry.common.TermData; import org.wso2.carbon.registry.core.Association; import org.wso2.carbon.registry.core.Registry; import org.wso2.carbon.registry.core.Resource; import org.wso2.carbon.registry.core.exceptions.RegistryException; import org.wso2.carbon.registry.core.pagination.Paginate; import org.wso2.carbon.registry.core.utils.RegistryUtils; import org.wso2.carbon.registry.extensions.utils.CommonConstants; import javax.xml.namespace.QName; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Properties; import java.util.Set; import java.util.UUID; /** * Base Manager Functionality which can be used by any Artifact Manager instance. */ @SuppressWarnings("unused") public class GovernanceArtifactManager { private static final Log log = LogFactory.getLog(GovernanceArtifactManager.class); private Registry registry; private String mediaType; private String artifactNameAttribute; private String artifactNamespaceAttribute; private String artifactElementRoot; private String artifactElementNamespace; private String pathExpression; private String lifecycle; private List<Association> relationshipDefinitions; private List<Map> validationAttributes; /** * Constructor accepting an instance of the registry, and also details on the type of manager. * * @param registry the instance of the registry. * @param mediaType the media type of resources being saved or fetched. * @param artifactNameAttribute the attribute that specifies the name of the artifact. * @param artifactNamespaceAttribute the attribute that specifies the namespace of the artifact. * @param artifactElementRoot the attribute that specifies the root artifact element. * @param artifactElementNamespace the attribute that specifies the artifact element's * namespace. * @param pathExpression the expression that can be used to compute where to store * the artifact. * @param relationshipDefinitions the relationship definitions for the types of associations * that will be created when the artifact gets updated. */ public GovernanceArtifactManager(Registry registry, String mediaType, String artifactNameAttribute, String artifactNamespaceAttribute, String artifactElementRoot, String artifactElementNamespace, String pathExpression, Association[] relationshipDefinitions) { this.registry = registry; this.mediaType = mediaType; this.artifactNameAttribute = artifactNameAttribute; this.artifactNamespaceAttribute = artifactNamespaceAttribute; this.artifactElementRoot = artifactElementRoot; this.artifactElementNamespace = artifactElementNamespace; this.pathExpression = pathExpression; this.relationshipDefinitions = Arrays.asList(relationshipDefinitions); } /** * Constructor accepting an instance of the registry, and also details on the type of manager. * * @param registry the instance of the registry. * @param mediaType the media type of resources being saved or fetched. * @param artifactNameAttribute the attribute that specifies the name of the artifact. * @param artifactNamespaceAttribute the attribute that specifies the namespace of the artifact. * @param artifactElementRoot the attribute that specifies the root artifact element. * @param artifactElementNamespace the attribute that specifies the artifact element's * namespace. * @param pathExpression the expression that can be used to compute where to store * the artifact. * @param lifecycle the lifecycle name which associated with the artifacts * @param validationAttributes the validations for artifact attributes * @param relationshipDefinitions the relationship definitions for the types of associations * that will be created when the artifact gets updated. * */ public GovernanceArtifactManager(Registry registry, String mediaType, String artifactNameAttribute, String artifactNamespaceAttribute, String artifactElementRoot, String artifactElementNamespace, String pathExpression, String lifecycle, List<Map> validationAttributes, Association[] relationshipDefinitions) { this.registry = registry; this.mediaType = mediaType; this.artifactNameAttribute = artifactNameAttribute; this.artifactNamespaceAttribute = artifactNamespaceAttribute; this.artifactElementRoot = artifactElementRoot; this.artifactElementNamespace = artifactElementNamespace; this.pathExpression = pathExpression; this.lifecycle = lifecycle; this.validationAttributes = validationAttributes; this.relationshipDefinitions = Arrays.asList(relationshipDefinitions); } /** * Creates a new artifact from the given qualified name. * * @return the artifact added. * @throws GovernanceException if the operation failed. */ public GovernanceArtifact newGovernanceArtifact() throws GovernanceException { List<String> uniqueAttributes = GovernanceUtils.getUniqueAttributesNames(registry, mediaType); return GovernanceArtifactImpl.create(registry, UUID.randomUUID().toString(), uniqueAttributes); } /** * Creates a new artifact from the given content. * * @param content the artifact content. * * @return the artifact added. * @throws GovernanceException if the operation failed. */ public GovernanceArtifact newGovernanceArtifact(OMElement content) throws GovernanceException { List<String> uniqueAttributes = GovernanceUtils.getUniqueAttributesNames(registry, mediaType); return GovernanceArtifactImpl.create(registry, UUID.randomUUID().toString(), content, uniqueAttributes); } /** * Adds the given artifact to the registry. Please do not use this method to update an existing * artifact use the update method instead. If this method is used to update an existing * artifact, all existing properties (such as lifecycle details) will be removed from the * existing artifact. * * @param artifact the artifact. * * @throws GovernanceException if the operation failed. */ public void addGovernanceArtifact(GovernanceArtifact artifact) throws GovernanceException { // adding the attributes for name, namespace + artifact if (artifact.getQName() == null || artifact.getQName().getLocalPart() == null) { String msg = "A valid qualified name was not set for this artifact"; log.error(msg); throw new GovernanceException(msg); } String artifactName = artifact.getQName().getLocalPart(); if (artifactNameAttribute != null) { if (StringUtils.isNotEmpty(artifactName)) { artifact.setAttributes(artifactNameAttribute, new String[]{artifactName}); } } String namespace = artifact.getQName().getNamespaceURI(); if (artifactNamespaceAttribute != null && StringUtils.isNotEmpty(namespace)) { artifact.setAttributes(artifactNamespaceAttribute, new String[]{namespace}); } else if (artifactNamespaceAttribute != null) { namespace = artifact.getAttribute(artifactNamespaceAttribute); } setQName(artifact, artifactName, namespace); validateArtifact(artifact); ((GovernanceArtifactImpl)artifact).associateRegistry(registry); boolean succeeded = false; Resource resource = null; String path = null; try { registry.beginTransaction(); resource = registry.newResource(); resource.setMediaType(mediaType); setContent(artifact, resource); // the artifact will not actually stored in the tmp path. path = GovernanceUtils.getPathFromPathExpression( pathExpression, artifact); if(registry.resourceExists(path)){ throw new GovernanceException("Governance artifact " + artifactName + " already exists at " + path); } String artifactId = artifact.getId(); resource.setUUID(artifactId); registry.put(path, resource); String updatedPath = GovernanceUtils.getArtifactPath(registry, artifactId); if(updatedPath != null && !path.equals(updatedPath)){ path = updatedPath; } if (lifecycle != null){ String[] lifeCycles = lifecycle.split(","); ArrayUtils.reverse(lifeCycles); for (String attachingLifeCycle : lifeCycles) { if (StringUtils.isNotEmpty(attachingLifeCycle)) { registry.associateAspect(path, attachingLifeCycle); } } } ((GovernanceArtifactImpl)artifact).updatePath(); // artifact.setId(resource.getUUID()); //This is done to get the UUID of a existing resource. addRelationships(path, artifact); succeeded = true; } catch (RegistryException e) { String msg; if (artifact.getPath() != null) { msg = "Failed to add artifact: artifact id: " + artifact.getId() + ", path: " + artifact.getPath() + ". " + e.getMessage(); } else { msg = "Failed to add artifact: artifact id: " + artifact.getId() + ". " + e.getMessage(); } log.error(msg, e); throw new GovernanceException(msg, e); } finally { if (succeeded) { try { registry.commitTransaction(); } catch (RegistryException e) { String msg ; if (artifact.getPath() != null) { msg = "Error in committing transactions. Failed to add artifact: artifact " + "id: " + artifact.getId() + ", path: " + artifact.getPath() + "."; } else { msg = "Error in committing transactions. Failed to add artifact: artifact " + "id: " + artifact.getId() + "."; } log.error(msg, e); } } else { try { registry.rollbackTransaction(); } catch (RegistryException e) { String msg = "Error in rolling back transactions. Failed to add artifact: " + "artifact id: " + artifact.getId() + ", path: " + artifact.getPath() + "."; log.error(msg, e); } } } } private void setQName(GovernanceArtifact artifact, String artifactName, String namespace) throws GovernanceException { if (StringUtils.isNotEmpty(artifactNamespaceAttribute) && StringUtils.isNotEmpty(artifactNameAttribute)) { QName qname = new QName(namespace, artifactName); artifact.setQName(qname); } else if (StringUtils.isNotEmpty(artifactNameAttribute)) { QName qname = new QName(artifactName); artifact.setQName(qname); } } private void addRelationships(String path, GovernanceArtifact artifact) throws RegistryException { Map<String, AssociationInteger> typeMap = new LinkedHashMap<String, AssociationInteger>(); for (Association relationship : relationshipDefinitions) { String type = relationship.getAssociationType(); String source = relationship.getSourcePath(); String target = relationship.getDestinationPath(); if (typeMap.containsKey(type)) { AssociationInteger associationInteger = typeMap.get(type); if (source == null) { if (associationInteger.getInteger() < 0) { associationInteger.setInteger(0); } for (String targetPath : GovernanceUtils.getPathsFromPathExpression(target, artifact)) { if (registry.resourceExists(targetPath)) { associationInteger.getAssociations().add(new Association(path, targetPath, type)); } else { if (log.isDebugEnabled()) { log.debug("Can not add association. Resource does not exist at" + targetPath); } } } } else if (target == null) { if (associationInteger.getInteger() > 0) { associationInteger.setInteger(0); } for (String sourcePath : GovernanceUtils.getPathsFromPathExpression(source, artifact)) { if (registry.resourceExists(sourcePath)) { associationInteger.getAssociations().add(new Association(sourcePath, path, type)); } else { if (log.isDebugEnabled()) { log.debug("Can not add association. Resource does not exist at" + sourcePath); } } } } } else { AssociationInteger associationInteger = new AssociationInteger(); if (source == null) { associationInteger.setInteger(1); for (String targetPath : GovernanceUtils.getPathsFromPathExpression(target, artifact)) { if (registry.resourceExists(targetPath)) { associationInteger.getAssociations().add(new Association(path, targetPath, type)); } else { if (log.isDebugEnabled()) { log.debug("Can not add association. Resource does not exist at" + targetPath); } } } } else if (target == null) { associationInteger.setInteger(-1); for (String sourcePath : GovernanceUtils.getPathsFromPathExpression(source, artifact)) { if (registry.resourceExists(sourcePath)) { associationInteger.getAssociations().add(new Association(sourcePath, path, type)); } else { if (log.isDebugEnabled()) { log.debug("Can not add association. Resource does not exist at" + sourcePath); } } } } typeMap.put(type, associationInteger); } } for (Map.Entry<String, AssociationInteger> e : typeMap.entrySet()) { AssociationInteger value = e.getValue(); List<Association> associations = value.getAssociations(); fixAssociations(path, e.getKey(), value.getInteger() >= 0, value.getInteger() <= 0, associations.toArray(new Association[associations.size()])); } } private void fixAssociations(String path, String type, boolean isSource, boolean isTarget, Association[] toAdd) throws RegistryException { final String SEPARATOR = ":"; // Get the existing association list which is related to the current operation Set<String> existingSet = new HashSet<String>(); for (Association association : registry.getAllAssociations(path)) { if (type.equals(association.getAssociationType()) && ((isSource && association.getSourcePath().equals(path)) || (isTarget && association.getDestinationPath().equals(path)))) { existingSet.add(association.getSourcePath() + SEPARATOR + association.getDestinationPath() + SEPARATOR + association.getAssociationType()); } } // Get the updated association list from the projectGroup object Set<String> updatedSet = new HashSet<String>(); for (Association association : toAdd) { updatedSet.add(association.getSourcePath() + SEPARATOR + association.getDestinationPath() + SEPARATOR + association.getAssociationType()); } Set<String> removedAssociations = new HashSet<String>(existingSet); removedAssociations.removeAll(updatedSet); Set<String> newAssociations = new HashSet<String>(updatedSet); newAssociations.removeAll(existingSet); for (String removedAssociation : removedAssociations) { String[] params = removedAssociation.split(SEPARATOR); registry.removeAssociation(params[0], params[1], params[2]); } for (String newAssociation : newAssociations) { String[] params = newAssociation.split(SEPARATOR); registry.addAssociation(params[0], params[1], params[2]); } } /** * Updates the given artifact on the registry. * @param artifact the artifact. * * @throws GovernanceException if the operation failed. */ public void updateGovernanceArtifact(GovernanceArtifact artifact) throws GovernanceException { boolean succeeded = false; try { registry.beginTransaction(); String artifactName = artifact.getQName().getLocalPart(); if (artifactNameAttribute != null) { if (StringUtils.isNotEmpty(artifactName)) { artifact.setAttributes(artifactNameAttribute, new String[]{artifactName}); } else { artifactName = artifact.getAttribute(artifactNameAttribute); } } String namespace = artifact.getQName().getNamespaceURI(); if (artifactNamespaceAttribute != null && StringUtils.isNotEmpty(namespace)) { artifact.setAttributes(artifactNamespaceAttribute, new String[]{namespace}); } else if (artifactNamespaceAttribute != null) { namespace = artifact.getAttribute(artifactNamespaceAttribute); } setQName(artifact, artifactName, namespace); validateArtifact(artifact); GovernanceArtifact oldArtifact = getGovernanceArtifact(artifact.getId()); // first check for the old artifact and remove it. String oldPath = null; boolean needsToMove = false; if (oldArtifact != null) { QName oldName = oldArtifact.getQName(); if (!oldName.equals(artifact.getQName())) { String temp = oldArtifact.getPath(); // then it is analogue to moving the resource for the new location // so just delete the old path needsToMove = true; //registry.delete(temp); } else { oldPath = oldArtifact.getPath(); } } else { throw new GovernanceException("No artifact found for the artifact id :" + artifact.getId() + "."); } String artifactId = artifact.getId(); Resource resource = registry.newResource(); resource.setMediaType(mediaType); setContent(artifact, resource); String path; if (oldPath != null) { path = oldPath; } else { path = GovernanceUtils.getPathFromPathExpression(pathExpression, artifact); } if (needsToMove){ if (isInbuiltMediatype()) { registry.delete(oldArtifact.getPath()); } else if (!oldArtifact.getPath().equals(path)) { registry.move(oldArtifact.getPath(), path); } } if (registry.resourceExists(path)) { Resource oldResource = registry.get(path); Properties properties = (Properties) oldResource.getProperties().clone(); // first clone existing properties resource.setProperties(properties); // then set updated properties // Stop the attributes been added as properties /*String[] attributeKeys = artifact.getAttributeKeys(); if (attributeKeys != null) { for (String aggregatedKey : attributeKeys) { if (!aggregatedKey.equals(artifactNameAttribute) && !aggregatedKey.equals(artifactNamespaceAttribute)) { resource.setProperty(aggregatedKey, Arrays.asList(artifact.getAttributes(aggregatedKey))); } } }*/ //persisting resource description at artifact update String description = oldResource.getDescription(); if(description != null) { resource.setDescription(description); } String oldContent; Object content = oldResource.getContent(); if (content instanceof String) { oldContent = (String) content; } else { oldContent = new String((byte[]) content); } String newContent; content = resource.getContent(); if (content instanceof String) { newContent = (String) content; } else { newContent = new String((byte[]) content); } if (newContent.equals(oldContent)) { artifact.setId(oldResource.getUUID()); addRelationships(path, artifact); succeeded = true; return; } } resource.setUUID(artifactId); registry.put(path, resource); // artifact.setId(resource.getUUID()); //This is done to get the UUID of a existing resource. addRelationships(path, artifact); ((GovernanceArtifactImpl)artifact).updatePath(artifactId); succeeded = true; } catch (RegistryException e) { if (e instanceof GovernanceException) { throw (GovernanceException) e; } String msg; if (artifact.getPath() != null) { msg = "Error in updating the artifact, artifact id: " + artifact.getId() + ", artifact path: " + artifact.getPath() + "." + e.getMessage() + "."; } else { msg = "Error in updating the artifact, artifact id: " + artifact.getId() + "." + e.getMessage() + "."; } log.error(msg, e); throw new GovernanceException(msg, e); } finally { if (succeeded) { try { registry.commitTransaction(); } catch (RegistryException e) { String msg; if (artifact.getPath() != null) { msg = "Error in committing transactions. Update artifact failed: artifact " + "id: " + artifact.getId() + ", path: " + artifact.getPath() + "."; } else { msg = "Error in committing transactions. Update artifact failed: artifact " + "id: " + artifact.getId() + "."; } log.error(msg, e); } } else { try { registry.rollbackTransaction(); } catch (RegistryException e) { String msg = "Error in rolling back transactions. Update artifact failed: " + "artifact id: " + artifact.getId() + ", path: " + artifact.getPath() + "."; log.error(msg, e); } } } } private boolean isInbuiltMediatype() { return CommonConstants.REST_SERVICE_MEDIA_TYPE.equals(mediaType) || CommonConstants.SOAP_SERVICE_MEDIA_TYPE.equals(mediaType) || CommonConstants.SERVICE_MEDIA_TYPE.equals( mediaType); } /** * Fetches the given artifact on the registry. * * @param artifactId the identifier of the artifact. * * @return the artifact. * @throws GovernanceException if the operation failed. */ public GovernanceArtifact getGovernanceArtifact(String artifactId) throws GovernanceException { return GovernanceUtils.retrieveGovernanceArtifactById(registry, artifactId); } /** * Removes the given artifact from the registry. * * @param artifactId the identifier of the artifact. * * @throws GovernanceException if the operation failed. */ public void removeGovernanceArtifact(String artifactId) throws GovernanceException { GovernanceUtils.removeArtifact(registry, artifactId); } /** * Sets content of the given artifact to the given resource on the registry. * * @param artifact the artifact. * @param resource the content resource. * @throws GovernanceException if the operation failed. */ public void setContent(Resource resource, GovernanceArtifact artifact) throws GovernanceException { this.setContent(artifact, resource); } /** * Sets content of the given artifact to the given resource on the registry. * * @param artifact the artifact. * @param resource the content resource. * * @throws GovernanceException if the operation failed. */ protected void setContent(GovernanceArtifact artifact, Resource resource) throws GovernanceException { try { if (artifact instanceof GenericArtifact) { Object content = ((GenericArtifact) artifact).getContent(); if (content != null) { setContentAndProperties(artifact, resource, content); return; } } OMNamespace namespace = OMAbstractFactory.getOMFactory().createOMNamespace(artifactElementNamespace, ""); Map<String, HashMap> mainElementMap = new HashMap<String, HashMap>(); final String defaultUUID = UUID.randomUUID().toString(); String[] attributeKeys = artifact.getAttributeKeys(); if (attributeKeys != null) { for (String aggregatedKey : attributeKeys) { String[] keys = aggregatedKey.split("_"); String key = null; for (int i = 0; i < keys.length; i++) { key = keys[i]; if (mainElementMap.get(key) == null) { mainElementMap.put(key, new HashMap<String, String[]>()); } // Handing the situations where we don't have '_' in aggregatedKey // and assume we hare having only one '_" in aggregatedKey and not more if (keys.length > 1) { break; } } String[] attributeValues = artifact.getAttributes(aggregatedKey); String elementName = keys[keys.length - 1]; if (keys.length > 1) { mainElementMap.get(key).put(elementName, attributeValues); } else { mainElementMap.get(key).put(defaultUUID, attributeValues); } } } OMElement contentElement = OMAbstractFactory.getOMFactory().createOMElement(artifactElementRoot, namespace); Iterator it = mainElementMap.entrySet().iterator(); while (it.hasNext()) { Map.Entry<String, HashMap> pairs = (Map.Entry)it.next(); Map<String, Map> subElementMap = pairs.getValue(); Iterator subit = subElementMap.entrySet().iterator(); int size = 0; boolean isOptionText = false; while (subit.hasNext()) { Map.Entry<String, String[]> subpairs = (Map.Entry) subit.next(); if (size < subpairs.getValue().length) { size = subpairs.getValue().length; } // TODO : This is temporary fix for option-text related issue, removing option-text next major release. if (subpairs.getKey().endsWith("entry")) { isOptionText = true; } } // TODO : This is temporary fix for option-text related issue, removing option-text next major release. if (isOptionText) { OMElement keyElement = OMAbstractFactory.getOMFactory().createOMElement(pairs.getKey(), namespace); for (int i = 0; i < size; i++) { keyElement = getSubElementContent(subElementMap, namespace, defaultUUID, keyElement, i); } contentElement.addChild(keyElement); } else { for (int i = 0; i < size; i++) { OMElement keyElement = OMAbstractFactory.getOMFactory().createOMElement(pairs.getKey(), namespace); keyElement = getSubElementContent(subElementMap, namespace, defaultUUID, keyElement, i); contentElement.addChild(keyElement); } } } String updatedContent = GovernanceUtils.serializeOMElement(contentElement); setContentAndProperties(artifact, resource, updatedContent); } catch (RegistryException e) { String msg; if (artifact.getPath() != null) { msg = "Error in saving attributes for the artifact. id: " + artifact.getId() + ", path: " + artifact.getPath() + "."; } else { msg = "Error in saving attributes for the artifact. id: " + artifact.getId() + "."; } log.error(msg, e); throw new GovernanceException(msg, e); } } private void setContentAndProperties(GovernanceArtifact artifact, Resource resource, Object content) throws RegistryException { resource.setContent(content); String[] propertyKeys = artifact.getPropertyKeys(); boolean hasSourceProperty = false; if (propertyKeys != null) { for (String propertyKey : propertyKeys) { if ("resource.source".equals(propertyKey)) { hasSourceProperty = true; } String[] propertyValues = artifact.getAttributes(propertyKey); resource.setProperty(propertyKey, Arrays.asList(propertyValues)); } } if (!hasSourceProperty) { //TODO ERROR resource.setProperty("resource.source", "remote"); } // Stop the attributes been added as properties /* String[] attributeKeys = artifact.getAttributeKeys(); if (attributeKeys != null) { for (String aggregatedKey : attributeKeys) { if (!aggregatedKey.equals(artifactNameAttribute) && !aggregatedKey.equals(artifactNamespaceAttribute)) { resource.setProperty(aggregatedKey, Arrays.asList(artifact.getAttributes(aggregatedKey))); } } }*/ } /** * Finds all artifacts matching the given filter criteria. * * @param criteria the filter criteria to be matched. * * @return the artifacts that match. * @throws GovernanceException if the operation failed. */ public GovernanceArtifact[] findGovernanceArtifacts(Map<String, List<String>> criteria) throws GovernanceException { List<GovernanceArtifact> artifacts; artifacts = GovernanceUtils.findGovernanceArtifacts(criteria != null ? criteria : Collections.<String, List<String>>emptyMap(), registry, mediaType); if (artifacts != null) { return artifacts.toArray(new GovernanceArtifact[artifacts.size()]); } else { return new GovernanceArtifact[0]; } } /** * Find all possible terms and its count for the given facet field and query criteria * @param criteria the filter criteria to be matched * @param facetField field used for faceting * @param authRequired authorization required flag * @return term results * @throws GovernanceException */ public TermData[] getTermData(Map<String, List<String>> criteria, String facetField, boolean authRequired) throws GovernanceException { List<TermData> termsList; termsList = GovernanceUtils.getTermDataList((criteria != null) ? criteria : Collections.<String, List<String>>emptyMap(), facetField, mediaType, authRequired); if (termsList != null) { return termsList.toArray(new TermData[termsList.size()]); } else { return new TermData[0]; } } /** * Finds and returns all GovernanceArtifacts that match the search query. * * @param query The query to search artifacts * @return Array of artifacts that match the query string * @throws GovernanceException if the operation failed */ public GovernanceArtifact[] findGovernanceArtifacts(String query) throws GovernanceException { List<GovernanceArtifact> artifacts; artifacts = GovernanceUtils.findGovernanceArtifacts(query, registry, mediaType); if (artifacts != null) { return artifacts.toArray(new GovernanceArtifact[artifacts.size()]); } else { return new GovernanceArtifact[0]; } } /** * Finds all artifacts matching the given filter criteria. * * @param criteria the filter criteria to be matched. * * @return the artifacts that match. * @throws GovernanceException if the operation failed. */ public GovernanceArtifact[] findGovernanceArtifacts(GovernanceArtifactFilter criteria) throws GovernanceException { List<GovernanceArtifact> artifacts = new ArrayList<GovernanceArtifact>(); for (GovernanceArtifact artifact : getAllGovernanceArtifacts()) { if (artifact != null) { if (criteria.matches(artifact)) { artifacts.add(artifact); } } } return artifacts.toArray(new GovernanceArtifact[artifacts.size()]); } /** * Finds all artifacts of a given type on the registry. * * @return all artifacts of the given type on the registry. * @throws GovernanceException if the operation failed. */ public GovernanceArtifact[] getAllGovernanceArtifacts() throws GovernanceException { List<String> paths = getPaginatedGovernanceArtifacts(); return getGovernanceArtifacts(paths.toArray(new String[paths.size()])); } @Paginate("getPaginatedGovernanceArtifacts") public List<String> getPaginatedGovernanceArtifacts() throws GovernanceException { List<String> paths = Arrays.asList(GovernanceUtils.getResultPaths(registry, mediaType)); Collections.sort(paths, new Comparator<String>() { public int compare(String o1, String o2) { Long l1 = -1l; Long l2 = -1l; String temp1 = RegistryUtils.getParentPath(o1); String temp2 = RegistryUtils.getParentPath(o2); try { l1 = Long.parseLong( RegistryUtils.getResourceName(temp1)); l2 = Long.parseLong( RegistryUtils.getResourceName(temp2)); } catch (NumberFormatException ignore) { } // First order by name int result = RegistryUtils.getResourceName(temp1).compareToIgnoreCase( RegistryUtils.getResourceName(temp2)); if (result != 0) { return result; } // Then order by namespace result = temp1.compareToIgnoreCase(temp2); if (result != 0) { return result; } // Finally by version return l2.compareTo(l1); } }); return paths; } /** * Finds all identifiers of the artifacts on the registry. * * @return an array of identifiers of the artifacts. * @throws GovernanceException if the operation failed. */ public String[] getAllGovernanceArtifactIds() throws GovernanceException { GovernanceArtifact[] artifacts = getAllGovernanceArtifacts(); String[] artifactIds = new String[artifacts.length]; for (int i = 0; i < artifacts.length; i++) { artifactIds[i] = artifacts[i].getId(); } return artifactIds; } private static class AssociationInteger { private List<Association> associations = new LinkedList<Association>(); private Integer integer; public List<Association> getAssociations() { return associations; } public Integer getInteger() { return integer; } public void setInteger(Integer integer) { this.integer = integer; } } /** * Retrieve all the governance artifacts which associated with the given lifecycle * * @param lcName Name of the lifecycle * * @return GovernanceArtifact array * @throws GovernanceException */ public GovernanceArtifact[] getAllGovernanceArtifactsByLifecycle(String lcName) throws GovernanceException { String[] paths = GovernanceUtils.getAllArtifactPathsByLifecycle(registry, lcName, mediaType); if (paths == null) { return new GovernanceArtifact[0]; } return getGovernanceArtifacts(paths); } /** * Retrieve all the governance artifacts which associated with the given lifecycle in the given lifecycle state * * @param lcName Name of the lifecycle * @param lcState Name of the current lifecycle state * * @return GovernanceArtifact array * @throws GovernanceException */ public GovernanceArtifact[] getAllGovernanceArtifactsByLIfecycleStatus(String lcName, String lcState) throws GovernanceException { String[] paths = GovernanceUtils.getAllArtifactPathsByLifecycleState(registry, lcName, lcState, mediaType); if (paths == null) { return new GovernanceArtifact[0]; } return getGovernanceArtifacts(paths); } private void validateArtifact(GovernanceArtifact artifact) throws GovernanceException{ if(validationAttributes == null){ return; } Map<String, Object> map; for (int i=0; i<validationAttributes.size(); ++i) { map = validationAttributes.get(i); String value = ""; String prop = (String)map.get("properties"); List<String> keys = (List<String>)map.get("keys"); if (prop != null && "unbounded".equals(prop)) { //assume there are only 1 key String[] values = artifact.getAttributes((String)keys.get(0)); if (values != null) { for (int j=0; j<values.length; ++j) { if (map.containsKey("isMandatory") && (boolean)map.get("isMandatory") && (values[j] == null || "".equals(values[j]))) { //return an exception to stop adding artifact throw new GovernanceException((String) map.get("name") + " is a required field, " + "Please provide a value for this parameter."); } if (map.containsKey("regexp") && !values[j].matches((String)map.get("regexp"))) { //return an exception to stop adding artifact throw new GovernanceException((String)map.get("name") + " doesn't match regex: " + (String)map.get("regexp")); } } } } else { for (int j=0; j<keys.size(); ++j) { String v = artifact.getAttribute(keys.get(j)); if (j != 0) value += ":"; value += (v == null ? "" : v); } if (map.containsKey("isMandatory") && (boolean)map.get("isMandatory") && (value == null || "".equals(value))) { //return an exception to stop adding artifact throw new GovernanceException((String) map.get("name") + " is a required field, " + "Please provide a value for this parameter."); } if (map.containsKey("regexp") && value != null && !value.equals("") && !value.matches((String)map.get("regexp"))) { //return an exception to stop adding artifact throw new GovernanceException((String)map.get("name") + " doesn't match regex: " + (String)map.get("regexp")); } } } } private OMElement getSubElementContent (Map<String, Map> subElementMap, OMNamespace namespace, String defaultUUID, OMElement keyElement, int posotion) { Iterator iterator = subElementMap.entrySet().iterator(); while (iterator.hasNext()) { Map.Entry<String, String[]> subpairs = (Map.Entry)iterator.next(); String value ; try { value = subpairs.getValue()[posotion]; } catch (Exception ex) { value = null; } //We have defaultUUID for non '_' scenario in this case remove defaultUUID and append it to the //parent element. if (subpairs.getKey().equals(defaultUUID)) { OMText textElement = OMAbstractFactory.getOMFactory().createOMText(value); keyElement.addChild(textElement); } else { OMElement subkeyElement = OMAbstractFactory.getOMFactory().createOMElement(subpairs.getKey(), namespace); OMText textElement = OMAbstractFactory.getOMFactory().createOMText(value); subkeyElement.addChild(textElement); keyElement.addChild(subkeyElement); } } return keyElement; } /** * This method is used to fetch all the {@link GovernanceArtifact} for a given set of paths. * If there are exceptions in retrieving artifacts for a given path, we ignore those exceptions. * If all the paths failed due to errors, then we throw a {@link GovernanceException} * * @param paths Array of paths of the governance artifacts * @return Array of {@link GovernanceArtifact} for the given paths * @throws GovernanceException if fetching artifacts for all the given paths failed */ private GovernanceArtifact[] getGovernanceArtifacts(String[] paths) throws GovernanceException { int errorCount = 0; List<GovernanceArtifact> artifactList = new ArrayList<GovernanceArtifact>(); for (String path : paths) { try { artifactList.add(GovernanceUtils.retrieveGovernanceArtifactByPath(registry, path)); } catch (GovernanceException e) { // We do not through any exception here. Only logging is done. // We increase the error count for each error. If all the paths failed, then we throw an error errorCount++; log.error("Error occurred while retrieving governance artifact by path : " + path, e); } } if (errorCount != 0 && errorCount == paths.length) { // This means that all the paths have failed. So we throw an error. throw new GovernanceException("Error occurred while retrieving all the governance artifacts"); } return artifactList.toArray(new GovernanceArtifact[artifactList.size()]); } private boolean addDefaultAttributeIfNotExists(final GovernanceArtifact artifact, Resource resource, final String artifactName) throws GovernanceException { GovernanceArtifact[] governanceArtifacts = searchArtifactsByGroupingAttribute(artifact, mediaType, artifactName); if(governanceArtifacts != null && governanceArtifacts.length == 0) { resource.addProperty("default", "true"); return true; } return false; } private void addDefaultAttributeToAssociations(final GovernanceArtifact artifact) throws GovernanceException { try { if(mediaType.equals("application/vnd.wso2-soap-service+xml")) { Association[] associations = registry.getAllAssociations(artifact.getPath()); for(Association association : associations) { String destinationPath = association.getDestinationPath(); if(destinationPath.contains("wsdl")) { String[] subPaths = destinationPath.split("/"); final String artifactName = subPaths[subPaths.length - 1]; GovernanceArtifact[] governanceArtifacts = searchArtifactsByGroupingAttribute(artifact, CommonConstants.WSDL_MEDIA_TYPE, artifactName); if(governanceArtifacts != null && governanceArtifacts.length == 0) { Resource wsdlResource = registry.get(destinationPath); wsdlResource.addProperty("default", "true"); registry.put(destinationPath, wsdlResource); } } } } } catch(RegistryException ex) { log.error("An error occurred while retrieving association of the resource " + artifact.getPath(), ex); } } private GovernanceArtifact[] searchArtifactsByGroupingAttribute(final GovernanceArtifact artifact, String mediaType, final String artifactName) throws GovernanceException { if(GovernanceUtils.getAttributeSearchService() == null) { return null; } Map<String, List<String>> listMap = new HashMap<String, List<String>>(); GovernanceArtifactConfiguration artifactConfiguration ; String groupingAttribute = null ; try { artifactConfiguration = GovernanceUtils.getArtifactConfigurationByMediaType(registry, mediaType); if(artifactConfiguration != null) { groupingAttribute = artifactConfiguration.getGroupingAttribute(); } else { log.debug("Artifact type with media type " + mediaType + " doesn't exist"); } } catch(RegistryException ex) { log.error("An error occurred while retrieving the artifact configuration ", ex); return null; } if(groupingAttribute != null) { if(groupingAttribute.equals(CommonConstants.SERVICE_NAME_ATTRIBUTE)) { listMap.put(groupingAttribute, new ArrayList<String>() {{ add(artifactName); }}); } else if(groupingAttribute.equals("overview_version")) { listMap.put(groupingAttribute, new ArrayList<String>() {{ add(artifact.getAttribute("overview_version")); }}); } } else { listMap.put(CommonConstants.SERVICE_NAME_ATTRIBUTE, new ArrayList<String>() {{ add(artifactName); }}); } return findGovernanceArtifacts(listMap); } /** * Check whether GovernanceArtifact is exists in the Registry without loading whole artifact into memory. * This method only work for Configurable Governance Artifacts and doe not work for Content Artifacts such * as WSDL, WADL, Swagger, XMLSchema etc. * * @param artifact GovernanceArtifact to check it's existence. * @return true or false * @throws GovernanceException if the operation failed. */ public boolean isExists(GovernanceArtifact artifact) throws GovernanceException { String path = GovernanceUtils.getPathFromPathExpression( pathExpression, artifact); try { return registry.resourceExists(path); } catch (RegistryException e) { throw new GovernanceException(e); } } public void removeGenericArtifact(GenericArtifact artifact) throws GovernanceException { String path = GovernanceUtils.getPathFromPathExpression( pathExpression, artifact); if (path != null) { try { GovernanceUtils.removeArtifactFromPath(registry, path); } catch (RegistryException e) { throw new GovernanceException(e); } } } }