SimpleBuilder usage in camel - apache-camel

I have following processor, when I run it from my route I get the following error. I know exchange body is not null and you can see it in logs below. What is wrong with my usage of SimpleBuilder here ?
public class UpdateCustomerProcessor implements Processor {
public static final Logger log = LoggerFactory.getLogger(UpdateCustomerProcessor.class);
public void process(Exchange exchng) throws Exception {
Customer c = (Customer) exchng.getIn().getBody(Object[].class)[0];
System.out.println("Updating customer " + c.getFirstName() + " " + c.getLastName());
System.out.println(SimpleBuilder.simple("Hello ${body.getFirstName()}").evaluate(exchng, String.class));
exchng.getOut().setBody(new Object[] {});
}
}
log->Updating customer aaa bbb
error-> org.apache.cxf.interceptor.Fault: Failed to invoke method: .getFirstName() on null due to: org.apache.camel.language.bean.RuntimeBeanExpressionException: Failed to invoke method: getFirstName() on null

I can't make sense of the "null"-exception, since exchange in appears to be filled. Nevertheless, your expression looks incorrect - since your exchange.in seems to hold an array, it should be:
SimpleBuilder.simple("Hello ${body[0].firstname}").evaluate(exchng, String.class))

Related

Salesforce : Apex test class for the getting trending articles of Knowledge from Community

I need to get trending articles from the community. I created a apex class for that by using ConnectApi.Knowledge.getTrendingArticles(communityId, maxResult).
I need to create a test class for that. I am using test class method provided by Salesforce for that. setTestGetTrendingArticles(communityId, maxResults, result) but I am getting this error "System.AssertException: Assertion Failed: No matching test result found for Knowledge.getTrendingArticles(String communityId, Integer maxResults). Before calling this, call Knowledge.setTestGetTrendingArticles(String communityId, Integer maxResults, ConnectApi.KnowledgeArticleVersionCollection result) to set the expected test result."
public without sharing class ConnectTopicCatalogController {
#AuraEnabled(cacheable=true)
public static List<ConnectApi.KnowledgeArticleVersion> getAllTrendingArticles(){
string commId = [Select Id from Network where Name = 'Customer Community v5'].Id;
ConnectApi.KnowledgeArticleVersionCollection mtCollection = ConnectApi.Knowledge.getTrendingArticles(commId, 12);
System.debug('getAllTrendingTopics '+JSON.serializePretty(mtCollection.items));
List<ConnectApi.KnowledgeArticleVersion> topicList = new List<ConnectApi.KnowledgeArticleVersion>();
for(ConnectApi.KnowledgeArticleVersion mtopic : mtCollection.items)
{
topicList.add(mtopic);
}
return topicList;
}
}
Test class that I am using for this
public class ConnectTopicCatalogControllerTest {
public static final string communityId = [Select Id from Network where Name = 'Customer Community v5'].Id;
#isTest
static void getTrendingArticles(){
ConnectApi.KnowledgeArticleVersionCollection knowledgeResult = new ConnectApi.KnowledgeArticleVersionCollection();
List<ConnectApi.KnowledgeArticleVersion> know = new List<ConnectApi.KnowledgeArticleVersion>();
know.add(new ConnectApi.KnowledgeArticleVersion());
know.add(new ConnectApi.KnowledgeArticleVersion());
system.debug('know '+know);
knowledgeResult.items = know;
// Set the test data
ConnectApi.Knowledge.setTestGetTrendingArticles(null, 12, knowledgeResult);
List<ConnectApi.KnowledgeArticleVersion> res = ConnectTopicCatalogController.getAllTrendingArticles();
// The method returns the test page, which we know has two items in it.
Test.startTest();
System.assertEquals(12, res.size());
Test.stopTest();
}
}
I need help to solve the test class
Thanks.
Your controller expects the articles to be inside the 'Customer Community v5' community, but you are passing the communityId parameter as null to the setTestGetTrendingArticles method.

SimpleScheduledRoutePolicy does not work on the specific time

I'm developing a web application where user adds issue specifying the date and time on which he/she should get a notification mail. I'm new to apache camel and quartz scheduler.
I have written a sample code as below. IssueDTO is nothing but a POJO. If the issue is repetitive, I have configured a cron scheduler which works properly i.e. if I specify frequency as 5, I get the expected output which is a println statement to the console. But if the issue is not repetitive, I have used SimpleScheduledRoutePolicy and hardcoded the date and time at which process() method of the Processor should run. I simply change the date time to 2 min later of the current system time to check whether code is working. But it never enters the process method and does print this statement => System.out.println("*****************" + issueDTO.getIssueId() + " running at " + gc.getTime().toString());
#Override
public void configure() throws Exception
{
System.out.println("in ReminderRouteBuilder configure()");
System.out.println("Issue ID : " + issueDTO.getIssueId());
System.out.println("Issue Frequency : " + issueDTO.getFrequency());
System.out.println("Is Repetative : " + issueDTO.getIsRepetitive());
// if Repetitive
if (StringUtil.getBoolean(issueDTO.getIsRepetitive()))
{
String fromString = "quartz2://" + issueDTO.getIssueId() + "?cron=0/" + issueDTO.getFrequency() + "+*+*+*+*+?";
from(fromString).process(new Processor() {
#Override
public void process(Exchange exchange) throws Exception
{
System.out.println(issueDTO.getIssueId() + " running every " + issueDTO.getFrequency() + " sec...");
}
});
}
// if not Repetitive
else
{
SimpleScheduledRoutePolicy policy = new SimpleScheduledRoutePolicy();
GregorianCalendar gc = new GregorianCalendar(2019, Calendar.AUGUST, 31, 13, 45);
policy.setRouteStartDate(gc.getTime());
from("direct:start").routeId(issueDTO.getIssueId()).routePolicy(policy).process(new Processor() {
#Override
public void process(Exchange exchange) throws Exception
{
System.out.println("*****************" + issueDTO.getIssueId() + " running at " + gc.getTime().toString());
}
});
}
}
Am I missing something?
Direct endpoint needs to be triggered manualy with some event. If you need something, what is triggered automatically after start of route, you can use Timer endpoint with repeatCount=1 or Quartz endpoint with fireNow=true.
E.g. this will trigger Exchange only once, after route startup:
from("timer:start?repeatCount=1").routeId(issueDTO.getIssueId()).routePolicy(policy)
Ok.. I got the solution :).
I used the cron expression specifying exact date and time and it worked.
#Override
public void configure() throws Exception
{
System.out.println("in ReminderRouteBuilder configure()");
System.out.println("Issue ID : " + issueDTO.getIssueId());
System.out.println("Issue Frequency : " + issueDTO.getFrequency());
System.out.println("Is Repetative : " + issueDTO.getIsRepetitive());
// if Repetitive
if (StringUtil.getBoolean(issueDTO.getIsRepetitive()))
{
String fromString = "quartz2://" + issueDTO.getIssueId() + "?cron=0/" + issueDTO.getFrequency() + "+*+*+*+*+?";
from(fromString).process(new Processor() {
#Override
public void process(Exchange exchange) throws Exception
{
System.out.println(issueDTO.getIssueId() + " running every " + issueDTO.getFrequency() + " sec...");
}
});
}
// if not Repetitive
else
{
String fromString = "quartz2://" + issueDTO.getIssueId() + "?cron=0 40 12 4 SEP ? 2019";
from(fromString).process(new Processor() {
#Override
public void process(Exchange exchange) throws Exception
{
System.out.println(issueDTO.getIssueId() + " running now");
}
});
}
}

Can I print Individual elements of DataSteam<T> in Apache Flink without using inbuilt print() function

I am trying to Print the values of warnings that have been detected in Flink
// Generate temperature warnings for each matched warning pattern
DataStream<TemperatureEvent> warnings = tempPatternStream.select(
(Map<String, MonitoringEvent> pattern) -> {
TemperatureEvent first = (TemperatureEvent) pattern.get("first");
return new TemperatureEvent(first.getRackID(), first.getTemperature()) ;
}
);
// Print the warning and alert events to stdout
warnings.print();
I am getting output as below(as per toString of eventSource function)
Rack id = 99 and temprature = 76.0
Can someone tell me, if there is any way I can print the values of DataStream without using print? An example would be, if I only want to print temperature, how can I access Individual elements in DataStream.
Thanks in Advance
I have figured out a way to access individual elements, Lets assume we have a DataStream
HeartRate<Integer,Integer>
It has 2 attributes
private Integer Patient_id ;
private Integer HR;
// Generating a Datasteam using custom function
DataStream<HREvent> hrEventDataStream = envrionment
.addSource(new HRGenerator()).assignTimestampsAndWatermarks(new IngestionTimeExtractor<>());
Assuming that you have Generated a Datasteam using custom function ,now we can print the values of Individual Elements of HeartRateEvent as below
hrEventDataStream.keyBy(new KeySelector<HREvent, Integer>() {
#Override
public Integer getKey(HREvent hrEvent) throws Exception {
return hrEvent.getPatient_id();
}
})
.window(TumblingEventTimeWindows.of(milliseconds(10)))
.apply(new WindowFunction<HREvent, Object, Integer, TimeWindow>() {
#Override
public void apply(Integer integer, TimeWindow timeWindow, Iterable<HREvent> iterable, Collector<Object> collector) throws Exception {
for(HREvent in : iterable){
System.out.println("Patient id = " + in.getPatient_id() + " Heart Rate = " + in.getHR());
}//for
}//apply
});
Hope it Helps !

IllegalArgumentException: offset may not be above 1000 in GAE

I have this simple ednpoint method:
#ApiMethod(name = "createCategory")
public RCategory createCategory(#Named("userHash")String userHash, #Nullable #Named("synchronously")Boolean synchronously, Category category) throws AccessForbiddenException, DuplicateEntityNameException, SubscriptionRequiredException {
User user = OwlEndpoint.getUser(userHash);
if (!user.hasSubscriptionActive()) throw new SubscriptionRequiredException();
//Sprawdzam czy w profilu uzytkownika jest wiecej niz on sam (o ile w ogole ma profil)
List<Long> usersInProfileIds = getUsersInProfilesIds(user);
if (ofy().load().type(Category.class).filter("creatorId in", usersInProfileIds).filter("name", category.getName()).count() > 0) throw new DuplicateEntityNameException();
category.setCreatorId(user.getId());
if (synchronously != null && synchronously) ofy().save().entity(category).now();
else ofy().save().entity(category);
return new RCategory(category, user.getId());
}
It works just fine on the DEV server, but after uploading to GAE it started to fail. I found this in the logs, but that doesn't make sense to me:
Request URL: https://myapp.appspot.com/_ah/api/owlendpoint/v1/createCategory/0A71A4A761C2B0C49BE3CE4ED19E78E93911DAE1E53732BE5635B29F923DBBFD5C54DEBE7F80831364D8255861D46878ADB657D0DDA95EEAF19956A6C5967CADF903543D1DA577677FEAEC70F0019B055C4CBA168A4A188D41393A9BF08834A92F8BB13D5E03F7F901C1281878BE8B79
Method: myappendpoint.createCategory
Error Code: 400
Reason: badRequest
Message: java.lang.IllegalArgumentException: offset may not be above 1000
I made this method:
#SuppressWarnings("rawtypes")
public static boolean hasItems(Query query) {
Iterator it = query.iterator();
return it.hasNext();
}
I'm using it to define, if there is at least one element on the query without using count(). Still would like to know how can I use count() and how can not...

Autofixture test for invalid constructor parameter

I have the following class and test. I want to test passing a null value as a parameter to the constructor and are expecting an ArgumentNullException. But since I use the Autofixture's CreateAnonymous method I get a TargetInvocationException instead.
What is the correct way to write those kinds of tests?
public sealed class CreateObject : Command {
// Properties
public ObjectId[] Ids { get; private set; }
public ObjectTypeId ObjectType { get; private set; }
public UserId CreatedBy { get; private set; }
// Constructor
public CreateObject(ObjectId[] ids, ObjectTypeId objectType, UserId createdBy) {
Guard.NotNull(ids, "ids");
Guard.NotNull(objectType, "objectType");
Guard.NotNull(createdBy, "createdBy");
Ids = ids;
ObjectType = objectType;
CreatedBy = createdBy;
}
}
[TestMethod]
[ExpectedException(typeof(ArgumentNullException))]
public void constructor_with_null_ids_throw() {
fixture.Register<ObjectId[]>(() => null);
fixture.CreateAnonymous<CreateObject>();
}
IMO, Ruben Bartelink's comment is the best answer.
With AutoFixture.Idioms, you can do this instead:
var fixture = new Fixture();
var assertion = new GuardClauseAssertion(fixture);
assertion.Verify(typeof(CreateObject).GetConstructors());
The Verify method will provide you with a quite detailed exception message if any constructor argument in any constructor is lacking a Guard Clause.
FWIW, AutoFixture extensively uses Reflection, so I don't consider it a bug that it throws a TargetInvocationException. While it could unwrap all TargetInvocationException instances and rethrow their InnerException properties, that would also mean disposing of (potentially) valuable information (such as the AutoFixture stack trace). I've considered this, but don't want to take AutoFixture in that direction, for exactly that reason. A client can always filter out information, but if information is removed prematurely, no client can get it back.
If you prefer the other approach, it's not too hard to write a helper method that unwraps the exception - perhaps something like this:
public Exception Unwrap(this Exception e)
{
var tie = e as TargetInvocationException;
if (tie != null)
return tie.InnerException;
return e;
}
I came across this while I was searching for something similar. I would like to add that, combined with automoqcustomization and xunit, below code also works and its much cleaner.
[Theory, AutoMoqData]
public void Constructor_GuardClausesArePresent(GuardClauseAssertion assertion)
{
assertion.Verify(typeof(foo).GetConstructors());
}
You just need to create the AutoMoqData attribute as follows.
public class AutoMoqDataAttribute : AutoDataAttribute
{
public AutoMoqDataAttribute() : base(() => new Fixture().Customize(new AutoMoqCustomization()))
{
}
}

Resources