/* * 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.mediator.cache.ui; import org.apache.axiom.om.OMAttribute; import org.apache.axiom.om.OMElement; import org.apache.synapse.config.xml.XMLConfigConstants; import org.wso2.carbon.mediator.cache.CachingConstants; import org.wso2.carbon.mediator.service.MediatorException; import org.wso2.carbon.mediator.service.ui.AbstractListMediator; import javax.xml.namespace.QName; import java.util.Iterator; /** * Object of this class is used to store mediator information in UI side. */ public class CacheMediator extends AbstractListMediator { /** QName of the ID of cache configuration */ private static final QName ATT_ID = new QName("id"); /** QName of the collector */ private static final QName ATT_COLLECTOR = new QName("collector"); /** QName of the digest generator */ private static final QName ATT_HASH_GENERATOR = new QName("hashGenerator"); /** QName of the maximum message size */ private static final QName ATT_MAX_MSG_SIZE = new QName("maxMessageSize"); /** QName of the timeout */ private static final QName ATT_TIMEOUT = new QName("timeout"); /** QName of the cache scope */ private static final QName ATT_SCOPE = new QName("scope"); /** QName of the mediator sequence */ private static final QName ATT_SEQUENCE = new QName("sequence"); /** QName of the implementation type */ private static final QName ATT_TYPE = new QName("type"); /** QName of the maximum message size */ private static final QName ATT_SIZE = new QName("maxSize"); /** QName of the onCacheHit mediator sequence reference */ private static final QName ON_CACHE_HIT_Q = new QName(XMLConfigConstants.SYNAPSE_NAMESPACE, "onCacheHit"); /** QName of the cache implementation */ private static final QName IMPLEMENTATION_Q = new QName(XMLConfigConstants.SYNAPSE_NAMESPACE, "implementation"); /** This holds the default timeout of the mediator cache */ private static final long DEFAULT_TIMEOUT = 5000L; /** This holds the default disk cache size used in cache mediator */ private static final int DEFAULT_DISK_CACHE_SIZE = 200; /** * Cache configuration ID. */ private String id = null; /** * The scope of the cache */ private String scope = CachingConstants.SCOPE_PER_HOST; /** * This specifies whether the mediator should be in the incoming path (to check the request) or in the outgoing * path (to cache the response). */ private boolean collector = false; /** * This is used to define the logic used by the mediator to evaluate the hash values of incoming messages. */ private String digestGenerator = CachingConstants.DEFAULT_XML_IDENTIFIER.getClass().toString(); /** * The size of the messages to be cached in memory. If this is 0 then no disk cache, * and if there is no size specified in the config factory will asign a default value to enable disk based caching. */ private int inMemoryCacheSize = CachingConstants.DEFAULT_CACHE_SIZE; /** * The size of the messages to be cached in memory. Disk based and hirearchycal caching is not implemented yet. */ private int diskCacheSize = 0; /** * The time duration for which the cache is kept. */ private long timeout = 0L; /** * The reference to the onCacheHit sequence to be executed when an incoming message is identified as an * equivalent to a previously received message based on the value defined for the Hash Generator field. */ private String onCacheHitRef = null; /** * The maximum size of the messages to be cached. This is specified in bytes. */ private int maxMessageSize = 0; /** * This methods gives the ID of the cache configuration. * * @return string cache configuration ID. */ public String getId() { return id; } /** * This methods sets the ID of the cache configuration. * * @param id cache configuration ID to be set. */ public void setId(String id) { this.id = id; } /** * This method gives the scope of the cache. * * @return value of the cache scope. */ public String getScope() { return scope; } /** * This method sets the scope of the cache. * * @param scope cache scope to be set. */ public void setScope(String scope) { this.scope = scope; } /** * This method gives whether the mediator should be in the incoming path or in the outgoing path as a boolean. * * @return boolean true if incoming path false if outgoing path. */ public boolean isCollector() { return collector; } /** * This method sets whether the mediator should be in the incoming path or in the outgoing path as a boolean. * * @param collector boolean value to be set as collector. */ public void setCollector(boolean collector) { this.collector = collector; } /** * This method gives the DigestGenerator to evaluate the hash values of incoming messages. * * @return Name of the digestGenerator used evaluate hash values. */ public String getDigestGenerator() { return digestGenerator; } /** * This method sets the DigestGenerator to evaluate the hash values of incoming messages. * * @param digestGenerator Name of the digestGenerator to be set to evaluate hash values. */ public void setDigestGenerator(String digestGenerator) { this.digestGenerator = digestGenerator; } /** * This method gives the size of the messages to be cached in memory. * * @return memory cache size in bytes. */ public int getInMemoryCacheSize() { return inMemoryCacheSize; } /** * This method sets the size of the messages to be cached in memory. * * @param inMemoryCacheSize value(number of bytes) to be set as memory cache size. */ public void setInMemoryCacheSize(int inMemoryCacheSize) { this.inMemoryCacheSize = inMemoryCacheSize; } /** * This method gives the size of the messages to be cached in disk. * * @return disk cache size in bytes. */ public int getDiskCacheSize() { return diskCacheSize; } /** * This method sets the size of the messages to be cached in disk. * * @param diskCacheSize value(number of bytes) to be set as disk cache size. */ public void setDiskCacheSize(int diskCacheSize) { this.diskCacheSize = diskCacheSize; } /** * This method gives the timeout period in milliseconds. * * @return timeout in milliseconds */ public long getTimeout() { return timeout; } /** * This method sets the timeout period as milliseconds. * * @param timeout millisecond timeout period to be set. */ public void setTimeout(long timeout) { this.timeout = timeout; } /** * This method gives reference to the onCacheHit sequence to be executed. * * @return reference to the onCacheHit sequence. */ public String getOnCacheHitRef() { return onCacheHitRef; } /** * This method sets reference to the onCacheHit sequence to be executed. * * @param onCacheHitRef reference to the onCacheHit sequence to be set. */ public void setOnCacheHitRef(String onCacheHitRef) { this.onCacheHitRef = onCacheHitRef; } /** * This method gives the maximum size of the messages to be cached in bytes. * * @return maximum size of the messages to be cached in bytes. */ public int getMaxMessageSize() { return maxMessageSize; } /** * This method sets the maximum size of the messages to be cached in bytes. * * @param maxMessageSize maximum size of the messages to be set in bytes. */ public void setMaxMessageSize(int maxMessageSize) { this.maxMessageSize = maxMessageSize; } /** * This method gives the local name of the mediator. * * @return local name of mediator. */ public String getTagLocalName() { return "cache"; } /** * Creates XML representation of the cache mediator as an OMElement * * @param parent OMElement which take child as created OMElement */ public OMElement serialize(OMElement parent) { OMElement cache = fac.createOMElement("cache", synNS); saveTracingState(cache, this); if (id != null) { cache.addAttribute(fac.createOMAttribute("id", nullNS, id)); } if (scope != null) { cache.addAttribute(fac.createOMAttribute("scope", nullNS, scope)); } if (collector) { cache.addAttribute(fac.createOMAttribute("collector", nullNS, "true")); } else { cache.addAttribute(fac.createOMAttribute("collector", nullNS, "false")); if (digestGenerator != null) { cache.addAttribute(fac.createOMAttribute("hashGenerator", nullNS, digestGenerator)); } if (timeout != 0) { cache.addAttribute(fac.createOMAttribute("timeout", nullNS, Long.toString(timeout))); } if (maxMessageSize != 0) { cache.addAttribute(fac.createOMAttribute("maxMessageSize", nullNS, Integer.toString(maxMessageSize))); } if (onCacheHitRef != null) { OMElement onCacheHit = fac.createOMElement("onCacheHit", synNS); onCacheHit.addAttribute(fac.createOMAttribute("sequence", nullNS, onCacheHitRef)); cache.addChild(onCacheHit); } else if (getList().size() > 0) { OMElement onCacheHit = fac.createOMElement("onCacheHit", synNS); serializeChildren(onCacheHit, getList()); cache.addChild(onCacheHit); } if (inMemoryCacheSize != 0) { OMElement implElem = fac.createOMElement("implementation", synNS); implElem.addAttribute(fac.createOMAttribute("type", nullNS, "memory")); implElem.addAttribute(fac.createOMAttribute("maxSize", nullNS, Integer.toString(inMemoryCacheSize))); cache.addChild(implElem); } if (diskCacheSize != 0) { OMElement implElem = fac.createOMElement("implementation", synNS); implElem.addAttribute(fac.createOMAttribute("type", nullNS, "disk")); implElem.addAttribute(fac.createOMAttribute("maxSize", nullNS, Integer.toString(diskCacheSize))); cache.addChild(implElem); } } if (parent != null) { parent.addChild(cache); } return cache; } /** * Creates the cache mediator with given configuration XML as OMElement * * @param elem OMElement to be converted to cache mediator Object. */ public void build(OMElement elem) { OMAttribute idAttr = elem.getAttribute(ATT_ID); if (idAttr != null && idAttr.getAttributeValue() != null) { this.id = idAttr.getAttributeValue(); } OMAttribute scopeAttr = elem.getAttribute(ATT_SCOPE); if (scopeAttr != null && scopeAttr.getAttributeValue() != null && isValidScope(scopeAttr.getAttributeValue(), this.id)) { this.scope = scopeAttr.getAttributeValue(); } else { this.scope = CachingConstants.SCOPE_PER_HOST; } OMAttribute collectorAttr = elem.getAttribute(ATT_COLLECTOR); if (collectorAttr != null && collectorAttr.getAttributeValue() != null && "true".equals(collectorAttr.getAttributeValue())) { collector = true; } else { collector = false; OMAttribute hashGeneratorAttr = elem.getAttribute(ATT_HASH_GENERATOR); if (hashGeneratorAttr != null && hashGeneratorAttr.getAttributeValue() != null) { this.digestGenerator = hashGeneratorAttr.getAttributeValue(); } OMAttribute timeoutAttr = elem.getAttribute(ATT_TIMEOUT); if (timeoutAttr != null && timeoutAttr.getAttributeValue() != null) { this.timeout = Long.parseLong(timeoutAttr.getAttributeValue()); } else { this.timeout = DEFAULT_TIMEOUT; } OMAttribute maxMessageSizeAttr = elem.getAttribute(ATT_MAX_MSG_SIZE); if (maxMessageSizeAttr != null && maxMessageSizeAttr.getAttributeValue() != null) { this.maxMessageSize = Integer.parseInt(maxMessageSizeAttr.getAttributeValue()); } OMElement onCacheHitElem = elem.getFirstChildWithName(ON_CACHE_HIT_Q); if (onCacheHitElem != null) { OMAttribute sequenceAttr = onCacheHitElem.getAttribute(ATT_SEQUENCE); if (sequenceAttr != null && sequenceAttr.getAttributeValue() != null) { this.onCacheHitRef = sequenceAttr.getAttributeValue(); } else if (onCacheHitElem.getFirstElement() != null) { addChildren(onCacheHitElem, this); } } for (Iterator itr = elem.getChildrenWithName(IMPLEMENTATION_Q); itr.hasNext(); ) { OMElement implElem = (OMElement) itr.next(); OMAttribute typeAttr = implElem.getAttribute(ATT_TYPE); OMAttribute sizeAttr = implElem.getAttribute(ATT_SIZE); if (typeAttr != null && typeAttr.getAttributeValue() != null) { String type = typeAttr.getAttributeValue(); if (CachingConstants.TYPE_MEMORY.equals(type) && sizeAttr != null && sizeAttr.getAttributeValue() != null) { inMemoryCacheSize = Integer.parseInt(sizeAttr.getAttributeValue()); } else if (CachingConstants.TYPE_DISK.equals(type)) { if (sizeAttr != null && sizeAttr.getAttributeValue() != null) { this.diskCacheSize = Integer.parseInt(sizeAttr.getAttributeValue()); } else { this.diskCacheSize = DEFAULT_DISK_CACHE_SIZE; } } else { throw new MediatorException("unknown implementation type for the Cache mediator as there is " + "no type called " + typeAttr.getAttributeValue()); } } } } } /** * Checks the validity of the provided cache scope in cache mediator configuration * * @param scope value of the scope attribute parsed in configuration * @param id value of the id attribute parsed in configuration * @return boolean value whether the scope is valid or not */ private boolean isValidScope(String scope, String id) { if (CachingConstants.SCOPE_PER_HOST.equals(scope)) { return true; } else if (CachingConstants.SCOPE_PER_MEDIATOR.equals(scope)) { if (id != null) { return true; } else { throw new MediatorException("Id is required for a cache with scope : " + scope); } } else if (CachingConstants.SCOPE_DISTRIBUTED.equals(scope)) { return true; } else { throw new MediatorException("Unknown scope " + scope + " for the Cache mediator"); } } }