/** * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF 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.apache.camel.component.redis.processor.idempotent; import java.util.ArrayList; import java.util.List; import java.util.concurrent.TimeUnit; import org.apache.camel.api.management.ManagedOperation; import org.apache.camel.api.management.ManagedResource; import org.springframework.dao.DataAccessException; import org.springframework.data.redis.connection.RedisConnection; import org.springframework.data.redis.core.Cursor; import org.springframework.data.redis.core.RedisCallback; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.ScanOptions; import org.springframework.data.redis.core.ValueOperations; @ManagedResource(description = "Spring Redis based message id repository") public class RedisStringIdempotentRepository extends RedisIdempotentRepository { private final ValueOperations<String, String> valueOperations; private long expiry; public RedisStringIdempotentRepository(RedisTemplate<String, String> redisTemplate, String processorName) { super(redisTemplate, processorName); this.valueOperations = redisTemplate.opsForValue(); } @ManagedOperation(description = "Does the store contain the given key") @Override public boolean contains(String key) { String value = valueOperations.get(createRedisKey(key)); return value != null; } @ManagedOperation(description = "Adds the key to the store") @Override public boolean add(String key) { boolean added = valueOperations.setIfAbsent(createRedisKey(key), key); if (expiry > 0) { valueOperations.getOperations().expire(createRedisKey(key), expiry, TimeUnit.SECONDS); } return added; } @ManagedOperation(description = "Remove the key from the store") @Override public boolean remove(String key) { valueOperations.getOperations().delete(createRedisKey(key)); return true; } @ManagedOperation(description = "Clear the store") @Override public void clear() { valueOperations.getOperations().execute(new RedisCallback<List<byte[]>>() { @Override public List<byte[]> doInRedis(RedisConnection connection) throws DataAccessException { List<byte[]> binaryKeys = new ArrayList<>(); Cursor<byte[]> cursor = connection.scan(ScanOptions.scanOptions().match("*" + createRedisKey("*")).build()); while (cursor.hasNext()) { byte[] key = cursor.next(); binaryKeys.add(key); } if (binaryKeys.size() > 0) { connection.del(binaryKeys.toArray(new byte[][]{})); } return binaryKeys; } }); } protected String createRedisKey(String key) { return getProcessorName() + ":" + key; } public long getExpiry() { return expiry; } /** * Expire all newly added items after the given number of seconds (0 means never expire) */ public void setExpiry(long expiry) { this.expiry = expiry; } }