Add new counter (trap_id) field which increments by 1 - amazon-web-services

Code:
filter {
if ([trap_id]) {
mutate {
update => { "trap_id" => "trap_id"++ }
}
else
mutate {
add_field => { "trap_id" => 1 }
}
}
}
Scenario:
I'm trying to introduce a new field(trap_id) which needs to increment by 1 every time a trap is generated.
Error:
:ConfigurationError", :message=>"Expected one of #, {, } at line 26, column 50 (byte 1229) after filter {\n
which points to line : update => { "trap_id" => "trap_id"++ }
Question:
How do I fix the error? or Is this the right way to do for the given scenario.

You cannot increment a field using that syntax. You might be able to use the math filter (although you would need to install it, and it has not been updated for three years), or you could do it in ruby.
ruby {
init => '#trap_id = 0'
code => '
#trap_id += 1
event.set("trap_id", #trap_id)
'
}
You will need to set pipeline.workers to 1 for this to work reliably. If there are multiple pipeline worker threads then access to the instance variable will not be synchronised across them. It may work almost all of the time but it is not impossible for two threads to increment #trap_id before either of them calls event.set. If for some reason the call to event.set actually has to reference memory again (as opposed to a register) then this will get the wrong result.

Related

Using of if-else in Cypress test

Just learning how to write conditional tests using JS in Cypress. Write sample test as per Cypress.io
Test I trying to run:
describe ('sample tests', () => {
it('conditional test', () => {
cy.visit('https://example.cypress.io/commands/actions');
if (cy.get('input[placeholder*="Email"]')) => {
cy.type('email-1#mail.com')
} else {
cy.visit('https://www.google.com/')
}
})
})
Displayed error:
Error: Webpack Compilation Error
./cypress/e2e/4-home-page/test4.cy.js
Module build failed (from C:/Users/userName/AppData/Local/Cypress/Cache/12.3.0/Cypress/resources/app/node_modules/babel-loader/lib/index.js):
SyntaxError: C:\Users\userName\Desktop\Cypressinstall\cypress\e2e\4-home-page\test4.cy.js: Unexpected token (7:51)
5 | it('conditional test', () => {
6 | cy.visit('https://example.cypress.io/commands/actions');
> 7 | if (cy.get('input[placeholder*="Email"]')) => {
| ^
8 | cy.type('email-1#mail.com')
9 | } else {
10 | cy.visit('https://www.google.com/')
What I tried:
I moved "=>" in different location but Cypress display that "No tests found".
Expected behavior:
Cypress must run test without error, using condition if-else.
Understanding the use of "=>" is essential here and it has nothing to do with cypress.
The "=>" belongs to Javascript arrow functions
This is used to introduce shorter functions.
Now let's understand the then() method, reading this document
With the above, you should be able to understand how to use these principles correctly.
More to note:
If an element doesn't exist conditionally, we cannot use cy.get for that element (will trigger No Such Element Exception). Use
cy.get("body).then($body => {
//cy.get("body") returns the dom element which we can capture
with "then"
//Check if element exists
if($body.find("input[placeholder*=\"Email\"]").length > 0){
cy.get("input[placeholder*=\"Email\"]").type("email-1#mail.com");
}
else{
cy.visit('https://www.google.com/')
}
})
To learn more on cypress if conditions read the Cypress Documentations
Hope this helps!
As far as I understand you, the purpose in your given example is to verify if the element (email field) exists and if so, type there a value. In this case you'd better use conditional testing the following way and verify if the field is visible:
const emailField = 'input[placeholder*="Email"]';
cy.get('body').then(($email) => {
if ($email(emailField).is(':visible')) {
cy.type('email-1#mail.com')
}
else {
// Anything to do here
}
});
Or you can just check that element exist (if it's hidden for any reason):
const emailField = 'input[placeholder*="Email"]';
cy.get('body').then(($parent) => {
if ($parent.find(emailField).length > 0) {
cy.type('email-1#mail.com')
}
else {
// Anything to do here
}
});
Instead of cy.get('body').then... you can use any DOM element which is higher in the hierarchy than your desired element.

Parallel HTTP requests with limited concurrency in redux-observable epic using rxjs

Have been trying to solve the issue for a while.
Currently I have an array of objects (i call them tiles), which is pretty big.
I have an API endpoint where I should send this objects one by one, this API returns nothing, just status.
I need to send this objects to endpoint in parallel and concurrent manner and when the last of them is successful I should emit some string value which goes to redux store.
const tilesEpic =(action$, _state$) => {
action$.pipe(
ofType('TILE_ACTION'),
map(tilesArray => postTilesConcurrently(tilesArray),
map(someId => someReduxAction(someId),
)
const postTilesConcurrently = (tilesArray) => {
const tilesToObservables = tilesArray.map(tile => defer(() => postTile(tile))
return from(tileToObservables).pipe(mergeAll(concurrencyLimit))
}
The problem is that I have no idea how to emit someId from postTilesConcurrently, now it triggers action after each request is complete.
mergeAll() will subscribe to all sources in parallel but it will also emit each result immediatelly. So instead you could use for example forkJoin() (
you could use toArray() operator as well).
forkJoin(tilesToObservables)
.pipe(
map(results => results???), // Get `someId` somehow from results
);
forkJoin() will emit just once after all source Observables emit at least once and complete. This means for each source Observable you'll get only the last value it emitted.
After Martin's reply I have adjusted my code in order to use forkJoin
const tilesEpic =(action$, _state$) => {
action$.pipe(
ofType('TILE_ACTION'),
concatMap(tilesArray => postTilesConcurrently(tilesArray),
map(({someId}) => someReduxAction(someId),
)
const postTilesConcurrently = (tilesArray) => {
const tilesToObservables = tilesArray.map(tile => defer(() => postTile(tile))
return forkJoin({
images: from(tileToObservables).pipe(mergeAll(concurrencyLimit)),
someId: from([someId]),
}

How to test resubscriptions to RxJS Observable with TestScheduler?

I have an observable which might throw an error. When it throws, I want to resubscribe to that observable and try again. For example with the retry() operator.
To test this retry-logic I would need to create a test-observable which will throw an error the first 2 times it's subscribed to, and only on 3rd time would produce a value.
I tried the following:
import { Observable } from 'rxjs';
import { TestScheduler } from 'rxjs/testing';
import { retry } from 'rxjs/operators';
// Setup for TestScheduler
function basicTestScheduler() {
return new TestScheduler((actual, expected) => {
expect(actual).toEqual(expected);
});
}
// The function we're going to test
function retryMultipleTimes(observable$) {
return observable$.pipe(retry(2));
}
describe('retryMultipleTimes()', () => {
it('retries twice when observable throws an error', () => {
basicTestScheduler().run(({ hot, cold, expectObservable }) => {
const observable$ = hot('--#--#--Y');
const expected = ' --------Y'; // This is what I want to get
const unexpected = ' --# '; // This is what I get instead
expectObservable(retryMultipleTimes(observable$)).toBe(expected);
});
});
});
Seems that with a hot() observable it always resubscribes to the same frame that produced the error, resulting in immediately throwing again.
I also tried with cold() observable, in which case I get ------# - that is, at each retry the observable starts again from the beginning, resulting in --#, --#, --# - never reaching --Y.
It seems that there isn't a way to do such a thing with RxJS TestScheduler. Or perhaps there is?
If the hot() and cold() observable-creators aren't up to the task, perhaps I can create my own... but how?
I also tried adding a little delay between retries, so I wouldn't resubscribe immediately to the current frame by implementing the retry-logic using retryWhen:
function retryMultipleTimes(observable$) {
return observable$.pipe(
retryWhen(errors => errors.pipe(
delayWhen(() => timer(2)), // wait 2 frames before each retry
take(2), // do maximum of 2 retries
concat(throwError('error')), // finish with error when no success after 2 retries
)),
);
}
But this didn't work either. Looks like the resubscription still happens to the same frame as before.
How could I make this test pass?
Figured out a solution for this. I can use iif() to create an observable which chooses at subscription time between two observables:
describe('retryMultipleTimes()', () => {
it('retries twice when observable throws an error', () => {
basicTestScheduler().run(({ cold, expectObservable }) => {
let count = 0;
const observable$ = iif(
() => ++count <= 2,
cold('--#'),
cold('--Y'),
);
// --#
// --#
// --Y
expectObservable(retryMultipleTimes(observable$)).toBe('------Y');
});
});
});

Converting Promise[Option[Model]] to Promise[Option[String]] while making webservice calls

I have two webservice calls. Webservice1 returns Promise[Option[Model]] and Webservice2 should take Model as a parameter and then return a Promise[Option[String]]. This is how I have structured my code:
def call1: Promise[Option[Model]] = for {
response1 <- callService1(requestHolderForService1)
} yield {
for {
response <- response1
} yield ParserForResponse(response)
}
After, this I want to chain my call to service 2 that takes the result from service 1 as a parameter:
def call2:Promise[Option[String]] = call1.flatMap{
optionModel => optionModel.flatMap{
model => callService2(requestHolderForService2(model)).map{
service2Option => service2Option.map{
service2Result => ResultParse(service2Result)
}
}
}
}
The problem is that my call1 returns a Promise[Option[Model]] whereas the return from call2 needs to be Promise[Option[String]]. The issue stems from the intermediate service call
callService2
which returns Promise[Option[JsValue]] and I am unable to figure out the transition from Promise[Option[Model]] -> Promise[Option[JsValue]] -> Promise[Option[String]]
Can somebody point out how I might be able to chain these two calls together using map or flatMap?
Thanks
The "normal" way would not to be working with the promises directly, but futures for those promises, which you can access from scala.concurrent.Promise.future
First you map the future, think of it as when the option arrives, do this transformation with it, then you need to handle the fact that the option may not exist, which also is a map, think of it as if there is a value to this tranformation on it.
so:
val future1: Future[Option[Model]] = (...).future
val future2: Future[Option[String]] = future1.map { maybeModel =>
maybeModel.map(model => model.toString) // or hovewer you make it a string
}
Which you then can use in your second web service call

Moq SetUp.Return not working for repository mock

I am trying to mock my repository's Get() method to return an object in order to fake an update on that object, but my setup is not working:
Here is my Test:
[Test]
public void TestUploadDealSummaryReportUploadedExistingUpdatesSuccessfully()
{
var dealSummary = new DealSummary {FileName = "Test"};
_mockRepository.Setup(r => r.Get(x => x.FileName == dealSummary.FileName))
.Returns(new DealSummary {FileName = "Test"}); //not working for some reason...
var reportUploader = new ReportUploader(_mockUnitOfWork.Object, _mockRepository.Object);
reportUploader.UploadDealSummaryReport(dealSummary, "", "");
_mockRepository.Verify(r => r.Update(dealSummary));
_mockUnitOfWork.Verify(uow => uow.Save());
}
Here is the method that is being tested:
public void UploadDealSummaryReport(DealSummary dealSummary, string uploadedBy, string comments)
{
dealSummary.UploadedBy = uploadedBy;
dealSummary.Comments = comments;
// method should be mocked to return a deal summary but returns null
var existingDealSummary = _repository.Get(x => x.FileName == dealSummary.FileName);
if (existingDealSummary == null)
_repository.Insert(dealSummary);
else
_repository.Update(dealSummary);
_unitOfWork.Save();
}
And here is the error that I get when I run my unit test:
Moq.MockException :
Expected invocation on the mock at least once, but was never performed: r => r.Update(.dealSummary)
No setups configured.
Performed invocations:
IRepository1.Get(x => (x.FileName == value(FRSDashboard.Lib.Concrete.ReportUploader+<>c__DisplayClass0).dealSummary.FileName))
IRepository1.Insert(FRSDashboard.Data.Entities.DealSummary)
at Moq.Mock.ThrowVerifyException(MethodCall expected, IEnumerable1 setups, IEnumerable1 actualCalls, Expression expression, Times times, Int32 callCount)
at Moq.Mock.VerifyCalls(Interceptor targetInterceptor, MethodCall expected, Expression expression, Times times)
at Moq.Mock.Verify(Mock mock, Expression1 expression, Times times, String failMessage)
at Moq.Mock1.Verify(Expression`1 expression)
at FRSDashboard.Test.FRSDashboard.Lib.ReportUploaderTest.TestUploadDealSummaryReportUploadedExistingUpdatesSuccessfully
Through debugging I have found that the x => x.FileName is returning null, but even if i compare it to null I still get a null instead of the Deal Summary I want returned. Any ideas?
I'm guessing your setup isn't matching the call you make because they're two different anonymous lambdas. You may needs something like
_mockRepository.Setup(r => r.Get(It.IsAny<**whatever your get lambda is defined as**>()).Returns(new DealSummary {FileName = "Test"});
You could verify by setting a breakpoint in the Get() method of your repository and seeing if it is hit. It shouldn't be.