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 }