/* * Copyright (c) 2008, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. * * Licensed 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.registry.extensions.handlers; import org.apache.axiom.om.OMElement; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.wso2.carbon.registry.core.*; import org.wso2.carbon.registry.core.config.Mount; import org.wso2.carbon.registry.core.config.RegistryContext; import org.wso2.carbon.registry.core.exceptions.RegistryException; import org.wso2.carbon.registry.core.jdbc.handlers.Handler; import org.wso2.carbon.registry.core.jdbc.handlers.RequestContext; import org.wso2.carbon.registry.core.utils.AuthorizationUtils; import org.wso2.carbon.registry.core.utils.RegistryUtils; import org.wso2.carbon.registry.extensions.handlers.utils.EndpointUtils; import org.wso2.carbon.registry.extensions.services.Utils; import org.wso2.carbon.registry.extensions.utils.CommonConstants; import org.wso2.carbon.registry.extensions.utils.CommonUtil; import org.wso2.carbon.user.mgt.UserMgtConstants; import javax.xml.namespace.QName; import java.util.*; public class EndpointMediaTypeHandler extends Handler { private static final Log log = LogFactory.getLog(EndpointMediaTypeHandler.class); private static final String LOCATION_TAG = "location"; OMElement endpointLocationElement; public void setEndpointLocationConfiguration(OMElement endpointLocationElement) throws RegistryException { String endpointLocation = null; Iterator configElements = endpointLocationElement.getChildElements(); while (configElements.hasNext()) { OMElement configElement = (OMElement)configElements.next(); if (configElement.getQName().equals(new QName(LOCATION_TAG))) { endpointLocation = configElement.getText(); if (!endpointLocation.startsWith(RegistryConstants.PATH_SEPARATOR)) { endpointLocation = RegistryConstants.PATH_SEPARATOR + endpointLocation; } if (!endpointLocation.endsWith(RegistryConstants.PATH_SEPARATOR)) { endpointLocation = endpointLocation + RegistryConstants.PATH_SEPARATOR; } } } EndpointUtils.setEndpointLocation(endpointLocation); this.endpointLocationElement = endpointLocationElement; } public OMElement getEndpointLocationConfiguration() { return endpointLocationElement; } public void setEndpointMediaType(String endpointMediaType) throws RegistryException { EndpointUtils.setEndpointMediaType(endpointMediaType); } public void setIncludeNamespaceInName(String includeNamespaceInName){ EndpointUtils.setIncludeNamespaceInName(Boolean.valueOf(includeNamespaceInName)); } public String getEndpointMediaType() throws RegistryException { return EndpointUtils.getEndpointMediaType(); } public void put(RequestContext requestContext) throws RegistryException { if (!CommonUtil.isUpdateLockAvailable()) { return; } CommonUtil.acquireUpdateLock(); try { // we are not allowing to update the resource content for any reason, but they can just update properties Registry registry = requestContext.getRegistry(); Resource resource = requestContext.getResource(); Object resourceContentObj = resource.getContent(); String resourceContent; // here the resource content is url if (resourceContentObj instanceof String) { resourceContent = (String)resourceContentObj; resource.setContent(RegistryUtils.encodeString(resourceContent)); } else { resourceContent = RegistryUtils.decodeBytes((byte[])resourceContentObj); } String endpointUrl = EndpointUtils.deriveEndpointFromContent(resourceContent); String urlToPath = EndpointUtils.deriveEndpointFromUrl(endpointUrl); // so here the absolute path. String basePath = RegistryUtils.getAbsolutePath(registry.getRegistryContext(), org.wso2.carbon.registry.core.RegistryConstants.GOVERNANCE_REGISTRY_BASE_PATH + EndpointUtils.getEndpointLocation()); if(basePath.endsWith(RegistryConstants.PATH_SEPARATOR)){ if(urlToPath.startsWith(RegistryConstants.PATH_SEPARATOR)){ urlToPath = urlToPath.replaceFirst(RegistryConstants.PATH_SEPARATOR,""); } }else{ if(!urlToPath.startsWith(RegistryConstants.PATH_SEPARATOR)){ urlToPath = RegistryConstants.PATH_SEPARATOR + urlToPath; } } String path = getEndpointPath(requestContext, resourceContent, endpointUrl); //String path = basePath + urlToPath; String endpointId = resource.getUUID(); if (registry.resourceExists(path)) { Resource oldResource = registry.get(path); byte[] oldContent = (byte[])oldResource.getContent(); if (oldContent != null && RegistryUtils.decodeBytes(oldContent).equals(resourceContent)) { requestContext.setActualPath(path); ((ResourceImpl) resource).setPath(path); requestContext.setResource(resource); registry.put(path, resource); requestContext.setProcessingComplete(true); return; } //Set the old resource properties to new resource //https://wso2.org/jira/browse/REGISTRY-799 Properties properties = oldResource.getProperties(); if (properties != null) { Set keySet = properties.keySet(); if (keySet != null) { for (Object keyObj : keySet) { String key = (String) keyObj; List values = (List) properties.get(key); if (values != null) { for (Object valueObj : values) { String value = (String) valueObj; resource.addProperty(key, value); } } } } } if (oldContent != null && !RegistryUtils.decodeBytes(oldContent).equals(resourceContent)) { // oops somebody trying to update the endpoint resource content. that should not happen // String msg = "Endpoint content for endpoint resource is not allowed to change, " + // "path: " + path + "."; // log.error(msg); // throw new RegistryException(msg); //This is for fixing REGISTRY-785. resource.setContent(RegistryUtils.encodeString(resourceContent)); } } else if (endpointId == null) { endpointId = UUID.randomUUID().toString(); resource.setUUID(endpointId); } // CommonUtil.addGovernanceArtifactEntryWithAbsoluteValues( // CommonUtil.getUnchrootedSystemRegistry(requestContext), // endpointId, path); String relativeArtifactPath = RegistryUtils.getRelativePath(registry.getRegistryContext(), path); // adn then get the relative path to the GOVERNANCE_BASE_PATH relativeArtifactPath = RegistryUtils.getRelativePathToOriginal(relativeArtifactPath, RegistryConstants.GOVERNANCE_REGISTRY_BASE_PATH); Registry systemRegistry = CommonUtil.getUnchrootedSystemRegistry(requestContext); if (!systemRegistry.resourceExists(basePath)) { systemRegistry.put(basePath, systemRegistry.newCollection()); } if (resource.getProperty(CommonConstants.SOURCE_PROPERTY) == null){ resource.setProperty(CommonConstants.SOURCE_PROPERTY, CommonConstants.SOURCE_AUTO); } registry.put(path, resource); // if (!(resource instanceof Collection) && // ((ResourceImpl) resource).isVersionableChange()) { // registry.createVersion(path); // } ((ResourceImpl)resource).setPath(relativeArtifactPath); requestContext.setActualPath(path); requestContext.setProcessingComplete(true); } finally { CommonUtil.releaseUpdateLock(); } } private String getEndpointPath(RequestContext requestContext, String resourceContent, String endpointUrl) throws RegistryException { String pathExpression = Utils.getRxtService().getStoragePath(CommonConstants.ENDPOINT_MEDIA_TYPE); pathExpression = CommonUtil.replaceExpressionOfPath(pathExpression, "name",getEndpointName(EndpointUtils.deriveNameFromContent(resourceContent),EndpointUtils.deriveEndpointNameWithNamespaceFromUrl(endpointUrl))); pathExpression = CommonUtil.getPathFromPathExpression(pathExpression, EndpointUtils.deriveOMElementContent(resourceContent),requestContext.getResource().getProperties()); String endpointPath = CommonUtil.getRegistryPath(requestContext.getRegistry().getRegistryContext(), pathExpression); return endpointPath; } private String getEndpointName(String name, String namespace) { if (EndpointUtils.isIncludeNamespaceInName() && !name.equals(namespace)) { return namespace +"-"+ name; } else { return name; } } public String rename(RequestContext requestContext) throws RegistryException { return move(requestContext); } public String move(RequestContext requestContext) throws RegistryException { Registry registry = requestContext.getRegistry(); String sourcePath = requestContext.getSourcePath(); checkEndpointDependency(registry, sourcePath); return requestContext.getTargetPath(); } public void delete(RequestContext requestContext) throws RegistryException { if (!CommonUtil.isDeleteLockAvailable()) { return; } CommonUtil.acquireDeleteLock(); Registry registry = requestContext.getRegistry(); String path = requestContext.getResourcePath().getPath(); try { if (path == null) { throw new RegistryException("The resource path is not available."); } //checkEndpointDependency(registry, path); Resource resource = registry.get(path); } finally { CommonUtil.releaseDeleteLock(); } } public void checkEndpointDependency(Registry registry, String path) throws RegistryException { // here we are getting the associations for the endpoint. Association[] endpointDependents = registry.getAssociations(path, CommonConstants.USED_BY); // for each endpoint we are checking what the resource type is, if it is service, we check the // endpoint service, if it is wsdl, we check the wsdl List<String> dependents = new ArrayList<String>(); for (Association endpointDependent: endpointDependents) { String targetPath = endpointDependent.getDestinationPath(); if (registry.resourceExists(targetPath)) { Resource targetResource = registry.get(targetPath); String mediaType = targetResource.getMediaType(); if (CommonConstants.WSDL_MEDIA_TYPE.equals(mediaType)) { // so there are dependencies for wsdl media dependents.add(targetPath); } else if ((CommonConstants.SERVICE_MEDIA_TYPE.equals(mediaType) || CommonConstants.SOAP_SERVICE_MEDIA_TYPE.equals(mediaType))) { dependents.add(targetPath); } } } if (dependents.size() > 0) { // so there are dependencies, we are not allowing to delete endpoints if there are dependents String msg = "Error in deleting the endpoint resource. Please make sure detach the associations " + "to the services and wsdls manually before deleting the endpoint. " + "endpoint path: " + path + "."; log.error(msg); throw new RegistryException(msg); } } // adding the association should have a different lock public void addAssociation(RequestContext requestContext) throws RegistryException { if (!CommonUtil.isAddingAssociationLockAvailable()) { return; } CommonUtil.acquireAddingAssociationLock(); try { // here whenever a service is associated to a endpoint it will add the endpoint entry String targetPath = requestContext.getTargetPath(); String sourcePath = requestContext.getSourcePath(); Registry registry = requestContext.getRegistry(); // get the target resource. Resource targetResource = registry.get(targetPath); if ((CommonConstants.SERVICE_MEDIA_TYPE.equals(targetResource.getMediaType()) || CommonConstants.SOAP_SERVICE_MEDIA_TYPE.equals(targetResource.getMediaType())) && CommonConstants.USED_BY.equals(requestContext.getAssociationType())) { // if so we are getting the service and add the endpoint to the source Resource sourceResource = registry.get(sourcePath); byte[] sourceContent = (byte[]) sourceResource.getContent(); if (sourceContent == null) { return; } String endpointUrl = EndpointUtils.deriveEndpointFromContent(RegistryUtils.decodeBytes(sourceContent)); String endpointEnv = sourceResource.getProperty(CommonConstants.ENDPOINT_ENVIRONMENT_ATTR); if (endpointEnv == null) { endpointEnv = ""; } if (endpointEnv.indexOf(",") > 0) { for (String env : endpointEnv.split(",")) { EndpointUtils.addEndpointToService(registry, targetPath, endpointUrl, env); } } else { EndpointUtils.addEndpointToService(registry, targetPath, endpointUrl, endpointEnv); } } } finally { CommonUtil.releaseAddingAssociationLock(); } } public void removeAssociation(RequestContext requestContext) throws RegistryException { if (!CommonUtil.isAddingAssociationLockAvailable()) { return; } CommonUtil.acquireAddingAssociationLock(); try { // here whenever a service is associated to a endpoint it will add the endpoint entry String targetPath = requestContext.getTargetPath(); String sourcePath = requestContext.getSourcePath(); Registry registry = requestContext.getRegistry(); // get the target resource. Resource targetResource = registry.get(targetPath); if ((CommonConstants.SERVICE_MEDIA_TYPE.equals(targetResource.getMediaType()) || CommonConstants.SOAP_SERVICE_MEDIA_TYPE.equals(targetResource.getMediaType())) && CommonConstants.USED_BY.equals(requestContext.getAssociationType())) { // if so we are getting the service and add the endpoint to the source Resource sourceResource = registry.get(sourcePath); byte[] sourceContent = (byte[]) sourceResource.getContent(); if (sourceContent == null) { return; } String endpointUrl = EndpointUtils.deriveEndpointFromContent(RegistryUtils.decodeBytes(sourceContent)); String endpointEnv = sourceResource.getProperty(CommonConstants.ENDPOINT_ENVIRONMENT_ATTR); if (endpointEnv == null) { endpointEnv = ""; } if (endpointEnv.indexOf(",") > 0) { for (String env : endpointEnv.split(",")) { EndpointUtils.removeEndpointFromService(registry, targetPath, endpointUrl, env); } } else { EndpointUtils.removeEndpointFromService(registry, targetPath, endpointUrl, endpointEnv); } } } finally { CommonUtil.releaseAddingAssociationLock(); } } }