001    /**
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     *
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    
018    package org.apache.camel.component.cache;
019    
020    import java.io.InputStream;
021    import java.io.Serializable;
022    
023    import net.sf.ehcache.Cache;
024    import net.sf.ehcache.CacheException;
025    import net.sf.ehcache.CacheManager;
026    import net.sf.ehcache.Ehcache;
027    import net.sf.ehcache.Element;
028    import org.apache.camel.Endpoint;
029    import org.apache.camel.Exchange;
030    import org.apache.camel.impl.DefaultProducer;
031    import org.apache.commons.logging.Log;
032    import org.apache.commons.logging.LogFactory;
033    
034    public class CacheProducer extends DefaultProducer {
035        private static final transient Log LOG = LogFactory.getLog(CacheProducer.class);
036        private CacheConfiguration config;
037        private CacheManager cacheManager;
038        private Ehcache cache;
039    
040        public CacheProducer(Endpoint endpoint, CacheConfiguration config) throws Exception {
041            super(endpoint);
042            this.config = config;
043        }
044    
045        @Override
046        protected void doStart() throws Exception {
047            cacheManager = getEndpoint().getCacheManagerFactory().instantiateCacheManager();
048            super.doStart();
049        }
050    
051        @Override
052        public CacheEndpoint getEndpoint() {
053            return (CacheEndpoint) super.getEndpoint();
054        }
055    
056        public void process(Exchange exchange) throws Exception {
057            if (LOG.isTraceEnabled()) {
058                LOG.trace("Cache Name: " + config.getCacheName());
059            }
060    
061            if (cacheManager.cacheExists(config.getCacheName())) {
062                if (LOG.isTraceEnabled()) {
063                    LOG.trace("Found an existing cache: " + config.getCacheName());
064                    LOG.trace("Cache " + config.getCacheName() + " currently contains "
065                            + cacheManager.getCache(config.getCacheName()).getSize() + " elements");
066                }
067                cache = cacheManager.getCache(config.getCacheName());
068            } else {
069                cache = new Cache(config.getCacheName(),
070                        config.getMaxElementsInMemory(),
071                        config.getMemoryStoreEvictionPolicy(),
072                        config.isOverflowToDisk(),
073                        config.getDiskStorePath(),
074                        config.isEternal(),
075                        config.getTimeToLiveSeconds(),
076                        config.getTimeToIdleSeconds(),
077                        config.isDiskPersistent(),
078                        config.getDiskExpiryThreadIntervalSeconds(),
079                        null);
080                cacheManager.addCache(cache);
081                if (LOG.isDebugEnabled()) {
082                    LOG.debug("Added a new cache: " + cache.getName());
083                }
084            }
085    
086            String key = exchange.getIn().getHeader(CacheConstants.CACHE_KEY, String.class);
087            String operation = exchange.getIn().getHeader(CacheConstants.CACHE_OPERATION, String.class);
088    
089            if (operation == null) {
090                throw new CacheException("Operation not specified in the message header [" + CacheConstants.CACHE_KEY + "]");
091            }
092            if ((key == null) && (!operation.equalsIgnoreCase(CacheConstants.CACHE_OPERATION_DELETEALL))) {
093                throw new CacheException("Cache Key is not specified in message header header or endpoint URL.");
094            }
095    
096            performCacheOperation(exchange, operation, key);
097        }
098    
099        private void performCacheOperation(Exchange exchange, String operation, String key) throws Exception {
100            Object element;
101    
102            Object body = exchange.getIn().getBody();
103            if (body instanceof Serializable) {
104                element = body;
105            } else {
106                InputStream is = exchange.getContext().getTypeConverter().mandatoryConvertTo(InputStream.class, body);
107                // Read InputStream into a byte[] buffer
108                element = exchange.getContext().getTypeConverter().mandatoryConvertTo(byte[].class, is);
109            }
110    
111            if (operation.equalsIgnoreCase(CacheConstants.CACHE_OPERATION_ADD)) {
112                if (LOG.isDebugEnabled()) {
113                    LOG.debug("Adding an element with key " + key + " into the Cache");
114                }
115                cache.put(new Element(key, element), true);
116            } else if (operation.equalsIgnoreCase(CacheConstants.CACHE_OPERATION_UPDATE)) {
117                if (LOG.isDebugEnabled()) {
118                    LOG.debug("Updating an element with key " + key + " into the Cache");
119                }
120                cache.put(new Element(key, element), true);
121            } else if (operation.equalsIgnoreCase(CacheConstants.CACHE_OPERATION_DELETEALL)) {
122                if (LOG.isDebugEnabled()) {
123                    LOG.debug("Deleting All elements from the Cache");
124                }
125                cache.removeAll();
126            } else if (operation.equalsIgnoreCase(CacheConstants.CACHE_OPERATION_DELETE)) {
127                if (LOG.isDebugEnabled()) {
128                    LOG.debug("Deleting an element with key " + key + " into the Cache");
129                }
130                cache.remove(key, true);
131            } else if (operation.equalsIgnoreCase(CacheConstants.CACHE_OPERATION_GET)) {
132                if (LOG.isDebugEnabled()) {
133                    LOG.debug("Quering an element with key " + key + " from the Cache");
134                }
135                if (cache.isKeyInCache(key)) {
136                    exchange.getIn().setHeader(CacheConstants.CACHE_ELEMENT_WAS_FOUND, true);
137                    exchange.getIn().setBody(cache.get(key).getValue());
138                } else {
139                    exchange.getIn().removeHeader(CacheConstants.CACHE_ELEMENT_WAS_FOUND);
140                }
141            } else if (operation.equalsIgnoreCase(CacheConstants.CACHE_OPERATION_CHECK)) {
142                if (LOG.isDebugEnabled()) {
143                    LOG.debug("Querying an element with key " + key + " from the Cache");
144                }
145                if (cache.isKeyInCache(key)) {
146                    exchange.getIn().setHeader(CacheConstants.CACHE_ELEMENT_WAS_FOUND, true);
147                } else {
148                    exchange.getIn().removeHeader(CacheConstants.CACHE_ELEMENT_WAS_FOUND);
149                }
150            } else {
151                throw new CacheException("Operation " + operation + " is not supported.");
152            }
153        }
154    
155    }