/* * Copyright (c) 2015, 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.sequences.services; import org.apache.axiom.om.OMElement; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.synapse.SynapseException; import org.apache.synapse.config.SynapseConfiguration; import org.apache.synapse.config.xml.MediatorSerializerFinder; import org.apache.synapse.config.xml.SynapseXMLConfigurationFactory; import org.apache.synapse.config.xml.XMLConfigConstants; import org.apache.synapse.mediators.base.SequenceMediator; import org.wso2.carbon.context.PrivilegedCarbonContext; import org.wso2.carbon.mediation.initializer.ServiceBusConstants; import org.wso2.carbon.mediation.initializer.ServiceBusUtils; import org.wso2.carbon.mediation.initializer.persistence.MediationPersistenceManager; import org.wso2.carbon.sequences.SequenceAdminUtil; import org.wso2.carbon.sequences.common.SequenceEditorException; import javax.xml.namespace.QName; import java.util.concurrent.locks.Lock; public class SequenceAdminService { private static final Log log = LogFactory.getLog(SequenceAdminService.class); /** * Deletes the sequence with the given name from SynapseConfiguration * * @param sequenceName - Name of the sequence to delete * @throws org.wso2.carbon.sequences.common.SequenceEditorException * if the Sequence described by the given name doesn't * exist in the Synapse Configuration */ public void deleteSequence(String sequenceName) throws SequenceEditorException { final Lock lock = SequenceAdminUtil.getLock(); try { lock.lock(); SynapseConfiguration synCfg = SequenceAdminUtil.getSynapseConfiguration(); SequenceMediator sequence = synCfg.getDefinedSequences().get(sequenceName); if (sequence != null && sequence.getArtifactContainerName() == null) { synCfg.removeSequence(sequenceName); MediationPersistenceManager pm = SequenceAdminUtil.getMediationPersistenceManager(); pm.deleteItem(sequenceName, sequence.getFileName(), ServiceBusConstants.ITEM_TYPE_SEQUENCE); } else { handleException("No defined sequence with name " + sequenceName + " found to delete in the Synapse configuration"); } } catch (Exception fault) { handleException("Couldn't get the Synapse Configuration to delete the sequence", fault); } finally { lock.unlock(); } } /** * Set the tenant domain when a publisher deletes custom sequences in MT mode. When publisher * deletes the sequence, we login the gateway as supertenant. But we need to delete in the particular * tenant domain. * * @param sequenceName * @param tenantDomain * @throws SequenceEditorException */ public void deleteSequenceForTenant(String sequenceName, String tenantDomain) throws SequenceEditorException { try { PrivilegedCarbonContext.startTenantFlow(); PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain(tenantDomain, true); deleteSequence(sequenceName); } catch (Exception e) { handleException("Issue is in deleting the sequence definition"); } finally { PrivilegedCarbonContext.endTenantFlow(); } } /** * Add a sequence into the synapseConfiguration * * @param sequenceElement - Sequence object to be added as an OMElement * @throws SequenceEditorException if a sequence exists with the same name or if the * element provided is not a Sequence element */ public void addSequence(OMElement sequenceElement) throws SequenceEditorException { final Lock lock = SequenceAdminUtil.getLock(); try { lock.lock(); if (sequenceElement.getLocalName().equals( XMLConfigConstants.SEQUENCE_ELT.getLocalPart())) { String sequenceName = sequenceElement.getAttributeValue(new QName("name")); if ("".equals(sequenceName) || null == sequenceName) { handleException("sequence name is required."); } SynapseConfiguration config = SequenceAdminUtil.getSynapseConfiguration(); if (log.isDebugEnabled()) { log.debug("Adding sequence : " + sequenceName + " to the configuration"); } if (config.getLocalRegistry().get(sequenceName) != null) { handleException("The name '" + sequenceName + "' is already used within the configuration - a sequence or local entry with this " + "name already exists"); } else { SynapseXMLConfigurationFactory.defineSequence(config, sequenceElement, SequenceAdminUtil.getSynapseConfiguration().getProperties()); if (log.isDebugEnabled()) { log.debug("Added sequence : " + sequenceName + " to the configuration"); } SequenceMediator seq = config.getDefinedSequences().get(sequenceName); seq.setFileName(ServiceBusUtils.generateFileName(sequenceName)); seq.init(SequenceAdminUtil.getSynapseEnvironment()); //noinspection ConstantConditions persistSequence(seq); } } else { handleException("Invalid sequence definition"); } } catch (Exception fault) { handleException("Error adding sequence : " + fault.getMessage(), fault); } catch (Error error) { throw new SequenceEditorException("Unexpected error occured while " + "adding the sequence : " + error.getMessage(), error); } finally { lock.unlock(); } } /** * Set the tenant domain when a publisher deploys custom sequences in MT mode. When publisher * deploys the sequence, we login the gateway as supertenant. But we need to deploy in the particular * tenant domain. * * @param sequenceElement * @param tenantDomain * @throws SequenceEditorException */ public void addSequenceForTenant(OMElement sequenceElement, String tenantDomain) throws SequenceEditorException { try { PrivilegedCarbonContext.startTenantFlow(); PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain(tenantDomain, true); addSequence(sequenceElement); } catch (Exception e) { handleException("Issue in deploying the sequence definition"); } finally { PrivilegedCarbonContext.endTenantFlow(); } } public boolean isExistingSequence(String sequenceName) throws SequenceEditorException { SynapseConfiguration config = SequenceAdminUtil.getSynapseConfiguration(); return config.getLocalRegistry().get(sequenceName) != null; } public boolean isExistingSequenceForTenant(String sequenceName, String tenantDomain) throws SequenceEditorException { PrivilegedCarbonContext.startTenantFlow(); PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain(tenantDomain, true); return isExistingSequence(sequenceName); } /** * Returns the OMelement representation of the sequence given by sequence * name * * @param sequenceName - name of the sequence to get * @return OMElement representing the SequenceMediator of the given sequence * name * @throws SequenceEditorException if any error occured while getting the data from the * SynapseConfiguration */ public OMElement getSequence(String sequenceName) throws SequenceEditorException { final Lock lock = SequenceAdminUtil.getLock(); try { lock.lock(); SynapseConfiguration synapseConfiguration = SequenceAdminUtil.getSynapseConfiguration(); if (synapseConfiguration.getSequence(sequenceName) != null) { return MediatorSerializerFinder.getInstance().getSerializer( synapseConfiguration.getSequence(sequenceName)) .serializeMediator(null, synapseConfiguration .getSequence(sequenceName)); } else { handleException("Sequence with the name " + sequenceName + " does not exist"); } } catch (SynapseException syne) { handleException("Unable to get the sequence : " + sequenceName, syne); } catch (Exception fault) { handleException("Couldn't get the Synapse Configuration to get the sequence", fault); } finally { lock.unlock(); } return null; } /** * Set the tenant domain when a publisher tries to get custom sequences in MT mode. When publisher * tries to get the sequence, we login the gateway as supertenant. But we need to get in the particular * tenant domain. * * @param sequenceName * @param tenantDomain * @throws SequenceEditorException */ public OMElement getSequenceForTenant(String sequenceName, String tenantDomain) throws SequenceEditorException { try { PrivilegedCarbonContext.startTenantFlow(); PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain(tenantDomain, true); return getSequence(sequenceName); } catch (Exception e) { handleException("Issue is in getting the sequence definition"); } finally { PrivilegedCarbonContext.endTenantFlow(); } return null; } private void handleException(String message, Throwable cause) throws SequenceEditorException { log.error(message, cause); throw new SequenceEditorException(message, cause); } private void handleException(String message) throws SequenceEditorException { log.error(message); throw new SequenceEditorException(message); } private void persistSequence(SequenceMediator sequence) throws SequenceEditorException { MediationPersistenceManager pm = SequenceAdminUtil.getMediationPersistenceManager(); if (pm == null){ handleException("Cannot Persist sequence because persistence manager is null, " + "probably persistence is disabled"); } pm.saveItem(sequence.getName(), ServiceBusConstants.ITEM_TYPE_SEQUENCE); } }