如何在 camel 上下文之外访问 Apache camel eh-cache?
How to access Apache camel eh-cache outside camel context?
我想使用来自网络服务的数据并将其放入 camel eh-cache 中。
后来我想通过 CacheManager 在 camel 上下文之外使用这个缓存。
我没有找到任何方法。
在下面的代码中,我跳过了 Web 服务的使用并使用了来自 Map 的数据并将其提供给 eh-cache,但我无法使用 CacheManager 访问此缓存。
CamelRouter class
package com.camel;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.component.ehcache.EhcacheConstants;
import org.apache.camel.main.Main;
import org.ehcache.Cache;
import org.ehcache.CacheManager;
import org.ehcache.config.Configuration;
import org.ehcache.config.builders.CacheManagerBuilder;
import org.ehcache.xml.XmlConfiguration;
public class Test {
private static Main main;
public static void main(String[] args) throws Exception {
main = new Main();
main.addRouteBuilder(new RouteBuilder() {
@Override
public void configure() throws Exception {
from("timer:foo?period=5s&repeatCount=1")
.process(exchange ->{
Map<String, String> inputMap = new HashMap<>();
inputMap.put("name", "murli");
inputMap.put("lastname", "hiware");
inputMap.put("city", "pune");
exchange.getIn().setBody(inputMap);
exchange.getIn().setHeader("CamelEhcacheAction", EhcacheConstants.ACTION_PUT_ALL);
})
.to("ehcache://testCache?configUri=ehcache.xml&keyType=java.lang.String&valueType=java.lang.String")
.process(exchange -> {
URL myUrl = getClass().getResource("/ehcache.xml");
Configuration xmlConfig = new XmlConfiguration(myUrl);
CacheManager myCacheManager = CacheManagerBuilder.newCacheManager(xmlConfig);
myCacheManager.init();
//here I want to access already created testCache component but it is creating new one.
Cache<String, String> cache = myCacheManager.getCache("testCache", String.class, String.class);
System.out.println("Cache Element:"+cache.get("name"));
System.out.println("Exchange Message:"+exchange.getIn().getBody());
});
}
});
main.run();
}
}
ehcache 配置文件
<config
xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
xmlns='http://www.ehcache.org/v3'
xsi:schemaLocation="http://www.ehcache.org/v3 http://www.ehcache.org/schema/ehcache-core.xsd">
<cache alias="testCache">
<key-type>java.lang.String</key-type>
<value-type>java.lang.String</value-type>
<resources>
<heap unit="entries">2000</heap>
<offheap unit="MB">100</offheap>
</resources>
</cache>
<cache-template name="myDefaults">
<key-type>java.lang.Long</key-type>
<value-type>java.lang.String</value-type>
<heap unit="entries">200</heap>
</cache-template>
<cache alias="bar" uses-template="myDefaults">
<key-type>java.lang.Number</key-type>
</cache>
<cache alias="simpleCache" uses-template="myDefaults" />
</config>
请告诉我我正在尝试实现的用例是否可以使用 camel eh-cache?
您要找的是:
- 您可以从任何地方(包括从 Camel 上下文)访问的
CacheManager
的存储库
- 或者您需要找到一种方法将
Cache
或 CacheManager
暴露在上下文之外。
第一个是 Ehcache 2.x 的默认设置,它是从 Ehcache 3.x 设计中删除的。
遗憾的是,我对 Camel 的了解不够深,无法推荐任何一种方法作为最佳方法。
您通常应该能够通过 from("ehcache://...)
检索值。
但是,我假设您确实想要访问缓存或缓存管理器。
方法是这样的:
public static void main(String[] args) throws Exception {
URL url = App.class.getResource("/ehcache.xml");
Configuration xmlConfig = new XmlConfiguration(url);
CacheManager cacheManager = CacheManagerBuilder.newCacheManager(xmlConfig);
cacheManager.init();
Main main = new Main();
main.bind("cacheManager", cacheManager);
main.addRouteBuilder(new RouteBuilder() {
@Override
public void configure() throws Exception {
from("timer:foo?period=5s&repeatCount=1")
.process(exchange ->{
Map<String, String> inputMap = new HashMap<>();
inputMap.put("name", "murli");
inputMap.put("lastname", "hiware");
inputMap.put("city", "pune");
exchange.getIn().setBody(inputMap);
exchange.getIn().setHeader("CamelEhcacheAction", EhcacheConstants.ACTION_PUT_ALL);
})
.to("ehcache://testCache?cacheManager=#cacheManager&keyType=java.lang.String&valueType=java.lang.String")
.process(exchange -> {
//here I want to access already created testCache component but it is creating new one.
Cache<String, String> cache = cacheManager.getCache("testCache", String.class, String.class);
System.out.println("Cache Element:"+cache.get("name"));
System.out.println("Exchange Message:"+exchange.getIn().getBody());
});
}
});
main.run();
}
您可以使用 uri 设置缓存管理器:
to("ehcache:myCache?cacheManager=#myCacheManager")
其中 myCacheManager 是您在 camel 注册表中的一个 bean 的引用,有关示例,请查看:
当从 Spring 引导 @Service
到达 Camel-context 缓存时,我想分享这个方法。因此,REST API 可以检索最新的值,通过路由流式传输:
首先,我们确实将缓存添加为路由的附加目标点,但是,我们转换传入数据以使其显式成为字符串 object,这是在最后一个之前的处理部分中完成的to()
:
from(
getMqttRouteConfiguration(
sourceId, mqttHost, mqttTopic, mqttPort, mqttProtocol, authenticated,
username, password, mqttVersion, maxReadRate, qualityOfService
)
)
.to("log:camel.proxy?level=INFO&groupInterval=500000")
.to(String.format("kafka:%s?brokers=%s", sourceId, kafkaBrokerUrls))
.process(new Processor() {
@Override
public void process(Exchange exchange) throws Exception {
exchange.getIn().setBody(exchange.getIn().getBody(String.class));
exchange.getIn().setHeader("CamelCacheKey",sourceId);
exchange.getIn().setHeader("CamelCacheOperation","Update");
}
})
.to(String.format("cache://%s?maxElementsInMemory=10&eternal=true", sourceId))
.routeId(sourceId);
在 @Service
我们调用 camelContext,然后使用“缓存”值检索所需的组件:
public Optional<String> cachedLastValue(String key) {
CacheManager cacheManager = ((CacheComponent) camelContext.getComponent("cache")).getCacheManagerFactory().getInstance();
Cache cache = cacheManager.getCache(key);
if (cache != null) {
Element valueElement = cache.
get(key);
if (valueElement != null) {
String value = (String) (valueElement.
getObjectValue());
return Optional.of(value);
} else {
logger.warn("Cached value for {} topic was requested, but can not be retrieved from the cache: {} with key: {}", key, key, key);
}
} else {
logger.info("Cached value for {} topic was requested, but not yet recorded from the source", key);
}
return Optional.empty();
}
因此我们到达 CacheManager 和 Cache objects,它们允许我们查看所需的缓存名称并检索留在此处的最后一个值。
在这个解决方案之后仍然不清楚,我们是否可以使用相同的方法在缓存中存储大约 10 个值并检索所有这些值。另外,不清楚为什么没有明确调用
就不行
exchange.getIn().setBody(exchange.getIn().getBody(String.class));
exchange.getIn().setHeader("CamelCacheKey",sourceId);
exchange.getIn().setHeader("CamelCacheOperation","Update");
在将字符串 object 放入缓存之前,我手动将其放置到交换 body 中,并显式设置 Headers (我相信它们应该由默认情况下是 Apache Camel Ehcache,但我必须明确添加它们)。
我想使用来自网络服务的数据并将其放入 camel eh-cache 中。 后来我想通过 CacheManager 在 camel 上下文之外使用这个缓存。 我没有找到任何方法。
在下面的代码中,我跳过了 Web 服务的使用并使用了来自 Map 的数据并将其提供给 eh-cache,但我无法使用 CacheManager 访问此缓存。
CamelRouter class
package com.camel;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.component.ehcache.EhcacheConstants;
import org.apache.camel.main.Main;
import org.ehcache.Cache;
import org.ehcache.CacheManager;
import org.ehcache.config.Configuration;
import org.ehcache.config.builders.CacheManagerBuilder;
import org.ehcache.xml.XmlConfiguration;
public class Test {
private static Main main;
public static void main(String[] args) throws Exception {
main = new Main();
main.addRouteBuilder(new RouteBuilder() {
@Override
public void configure() throws Exception {
from("timer:foo?period=5s&repeatCount=1")
.process(exchange ->{
Map<String, String> inputMap = new HashMap<>();
inputMap.put("name", "murli");
inputMap.put("lastname", "hiware");
inputMap.put("city", "pune");
exchange.getIn().setBody(inputMap);
exchange.getIn().setHeader("CamelEhcacheAction", EhcacheConstants.ACTION_PUT_ALL);
})
.to("ehcache://testCache?configUri=ehcache.xml&keyType=java.lang.String&valueType=java.lang.String")
.process(exchange -> {
URL myUrl = getClass().getResource("/ehcache.xml");
Configuration xmlConfig = new XmlConfiguration(myUrl);
CacheManager myCacheManager = CacheManagerBuilder.newCacheManager(xmlConfig);
myCacheManager.init();
//here I want to access already created testCache component but it is creating new one.
Cache<String, String> cache = myCacheManager.getCache("testCache", String.class, String.class);
System.out.println("Cache Element:"+cache.get("name"));
System.out.println("Exchange Message:"+exchange.getIn().getBody());
});
}
});
main.run();
}
}
ehcache 配置文件
<config
xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
xmlns='http://www.ehcache.org/v3'
xsi:schemaLocation="http://www.ehcache.org/v3 http://www.ehcache.org/schema/ehcache-core.xsd">
<cache alias="testCache">
<key-type>java.lang.String</key-type>
<value-type>java.lang.String</value-type>
<resources>
<heap unit="entries">2000</heap>
<offheap unit="MB">100</offheap>
</resources>
</cache>
<cache-template name="myDefaults">
<key-type>java.lang.Long</key-type>
<value-type>java.lang.String</value-type>
<heap unit="entries">200</heap>
</cache-template>
<cache alias="bar" uses-template="myDefaults">
<key-type>java.lang.Number</key-type>
</cache>
<cache alias="simpleCache" uses-template="myDefaults" />
</config>
请告诉我我正在尝试实现的用例是否可以使用 camel eh-cache?
您要找的是:
- 您可以从任何地方(包括从 Camel 上下文)访问的
CacheManager
的存储库 - 或者您需要找到一种方法将
Cache
或CacheManager
暴露在上下文之外。
第一个是 Ehcache 2.x 的默认设置,它是从 Ehcache 3.x 设计中删除的。 遗憾的是,我对 Camel 的了解不够深,无法推荐任何一种方法作为最佳方法。
您通常应该能够通过 from("ehcache://...)
检索值。
但是,我假设您确实想要访问缓存或缓存管理器。
方法是这样的:
public static void main(String[] args) throws Exception {
URL url = App.class.getResource("/ehcache.xml");
Configuration xmlConfig = new XmlConfiguration(url);
CacheManager cacheManager = CacheManagerBuilder.newCacheManager(xmlConfig);
cacheManager.init();
Main main = new Main();
main.bind("cacheManager", cacheManager);
main.addRouteBuilder(new RouteBuilder() {
@Override
public void configure() throws Exception {
from("timer:foo?period=5s&repeatCount=1")
.process(exchange ->{
Map<String, String> inputMap = new HashMap<>();
inputMap.put("name", "murli");
inputMap.put("lastname", "hiware");
inputMap.put("city", "pune");
exchange.getIn().setBody(inputMap);
exchange.getIn().setHeader("CamelEhcacheAction", EhcacheConstants.ACTION_PUT_ALL);
})
.to("ehcache://testCache?cacheManager=#cacheManager&keyType=java.lang.String&valueType=java.lang.String")
.process(exchange -> {
//here I want to access already created testCache component but it is creating new one.
Cache<String, String> cache = cacheManager.getCache("testCache", String.class, String.class);
System.out.println("Cache Element:"+cache.get("name"));
System.out.println("Exchange Message:"+exchange.getIn().getBody());
});
}
});
main.run();
}
您可以使用 uri 设置缓存管理器:
to("ehcache:myCache?cacheManager=#myCacheManager")
其中 myCacheManager 是您在 camel 注册表中的一个 bean 的引用,有关示例,请查看:
当从 Spring 引导 @Service
到达 Camel-context 缓存时,我想分享这个方法。因此,REST API 可以检索最新的值,通过路由流式传输:
首先,我们确实将缓存添加为路由的附加目标点,但是,我们转换传入数据以使其显式成为字符串 object,这是在最后一个之前的处理部分中完成的to()
:
from(
getMqttRouteConfiguration(
sourceId, mqttHost, mqttTopic, mqttPort, mqttProtocol, authenticated,
username, password, mqttVersion, maxReadRate, qualityOfService
)
)
.to("log:camel.proxy?level=INFO&groupInterval=500000")
.to(String.format("kafka:%s?brokers=%s", sourceId, kafkaBrokerUrls))
.process(new Processor() {
@Override
public void process(Exchange exchange) throws Exception {
exchange.getIn().setBody(exchange.getIn().getBody(String.class));
exchange.getIn().setHeader("CamelCacheKey",sourceId);
exchange.getIn().setHeader("CamelCacheOperation","Update");
}
})
.to(String.format("cache://%s?maxElementsInMemory=10&eternal=true", sourceId))
.routeId(sourceId);
在 @Service
我们调用 camelContext,然后使用“缓存”值检索所需的组件:
public Optional<String> cachedLastValue(String key) {
CacheManager cacheManager = ((CacheComponent) camelContext.getComponent("cache")).getCacheManagerFactory().getInstance();
Cache cache = cacheManager.getCache(key);
if (cache != null) {
Element valueElement = cache.
get(key);
if (valueElement != null) {
String value = (String) (valueElement.
getObjectValue());
return Optional.of(value);
} else {
logger.warn("Cached value for {} topic was requested, but can not be retrieved from the cache: {} with key: {}", key, key, key);
}
} else {
logger.info("Cached value for {} topic was requested, but not yet recorded from the source", key);
}
return Optional.empty();
}
因此我们到达 CacheManager 和 Cache objects,它们允许我们查看所需的缓存名称并检索留在此处的最后一个值。
在这个解决方案之后仍然不清楚,我们是否可以使用相同的方法在缓存中存储大约 10 个值并检索所有这些值。另外,不清楚为什么没有明确调用
就不行 exchange.getIn().setBody(exchange.getIn().getBody(String.class));
exchange.getIn().setHeader("CamelCacheKey",sourceId);
exchange.getIn().setHeader("CamelCacheOperation","Update");
在将字符串 object 放入缓存之前,我手动将其放置到交换 body 中,并显式设置 Headers (我相信它们应该由默认情况下是 Apache Camel Ehcache,但我必须明确添加它们)。