Moderators, please read through once before marking it as a duplicate.
This is my first time creating a custom Sampler in JMeter. I am trying a simple query.
public class CustomJavaSampler extends AbstractJavaSamplerClient implements Serializable {
/**
*
*/
private static final long serialVersionUID = 5838315675279087366L;
#Override
public SampleResult runTest(JavaSamplerContext arg0) {
SampleResult result = new SampleResult();
result.sampleStart(); // start stopwatch
JMeterVariables vars = JMeterContextService.getContext().getVariables();
vars.putObject("search", "DoASearch");
JMeterContextService.getContext().setVariables(vars);
result.sampleEnd(); // stop stopwatch
result.setSuccessful(true);
result.setResponseMessage("Successfull");
result.setResponseCodeOK(); // 200 code
return result;
}
}
I have created a jar and I've added it to the lib/ext folder in jmeter. But I am not able to see the class in Java Request sampler.
I have enabled debug logs.
log_level.jmeter=DEBUG
log_level.jmeter.junit=DEBUG
log_level.jmeter.control=DEBUG
log_level.jmeter.testbeans=DEBUG
log_level.jmeter.engine=DEBUG
log_level.jmeter.threads=DEBUG
log_level.jmeter.gui=WARN
log_level.jmeter.testelement=DEBUG
log_level.jmeter.util=DEBUG
log_level.jmeter.util.classfinder=DEBUG
log_level.jmeter.test=DEBUG
log_level.jmeter.protocol.http=DEBUG
# For CookieManager, AuthManager etc:
log_level.jmeter.protocol.http.control=DEBUG
log_level.jmeter.protocol.ftp=WARN
log_level.jmeter.protocol.jdbc=DEBUG
log_level.jmeter.protocol.java=WARN
log_level.jmeter.testelements.property=DEBUG
log_level.jorphan=DEBUG
log_file=jmeter-debug.log
The complete jmeter log is http://pastebin.com/T39iUhFW
And also why is the log showing a "did not find" message for the /lib jars?
Nothing is wrong with your code, CustomJavaSampler is displayed in Java Request classnames.
So perhaps it's something with your .jar file. Can you upload it somewhere so we could take a look? I guess it's samp.jar.
By the way, setting a variable is a very "light" operation which can be done via Beanshell Sampler which is almost Java compatible.
If you need to perform some load - next option is JSR223 Sampler and "groovy" which is a "balance" between simplicity and productivity so if you will need to make some changes in your code you won't have to recompile, replace jars, restart JMeter, etc.
Related
I want to use a MockServerContainer to mock a webhook site.
My current code will make a request to that webhook while I'm executing it. On the test, I do expect to get 3 requests to it with different bodies. The test I want to make is to run the code and check if I have the 3 requests to the MockServerContainer with the expected bodies.
I need a method from the test containers that retrieves all the requests registered on the Mockserver. Is there any?
In the end, it was not so hard to find the solution. But maybe I could save someone half an hour.
My main error was focusing on the MockServerContainer instead of the client. The client has a really nice method (retrieveRecordedRequests) that makes what I need.
In the end I do need to store the client:
public class NotificationContainer {
public static final MockServerContainer server =
new MockServerContainer(DockerImageName.parse("jamesdbloom/mockserver")
.withTag("mockserver-5.5.4"));
public static MockServerClient client;
public static String getUrl() {
return server.getEndpoint();
}
public void callAfterStartSever() {
ContainerUtils.waitFor(server, Duration.ofSeconds(10));
NotificationContainer.client = new MockServerClient(server.getHost(), server.getServerPort());
client.when(HttpRequest.request())
.respond(HttpResponse.response());
}
}
And then use it on the test so I get the responses
#Test
void checkWebhook(){
//Do the call that makes the webhooks
val responses = NotificationContainer.client.retrieveRecordedRequests(null);
//validate the request are the expected ones
}
I am developing a spring boot application with activiti as the workflow engine. The activiti-spring-boot-starter dependency version is 7.1.0.M6 and spring-boot-starter-parent version is 2.6.7.
I have defined a BPMN 2.0 diagram using activiti-modelling-app and I am now starting the process instance. After completing a task, I want to access its task local variables when processing the next task. I am unable to figure out the api for it.
I tried using the historyService as below but with no luck. I get the result list as empty everytime with different apis (finished(), unfinished() etc)
HistoricTaskInstance acceptMobile = historyService.createHistoricTaskInstanceQuery()
.processInstanceId(processInstanceId)
.taskName("my-task1")
.singleResult();
Can someone guide me on what could be the right api to use to get the local variables of a previously completed task?
Thanks.
The best way to transfer variables between tasks is to use execution variables with DelegateExecution
execution variables are specific pointers to where the process is active, for more information, see apiVariables
Let say you have Task-A and Task-B with different listeners
here's how to use execution variable from Task-A to Task-B:
#Component("TaskListenerA")
public class TaskListenerA implements TaskListener {
#Override
public void notify(DelegateTask task) {
DelegateExecution execution = task.getExecution();
if("complete".equals(task.getEventName()) {
String myTaskVar = (String) task.getVariable("taskAvariable")
execution.setVariable("exeVariable", myTaskVar);
}
}
}
#Component("TaskListenerB")
public class TaskListenerB implements TaskListener {
#Override
public void notify(DelegateTask task) {
DelegateExecution execution = task.getExecution();
String myVariable = execution.get("exeVariable");
}
}
I've a filter (OncePerRequestFilter) which basically intercepts incoming request and logs traceId, spanId etc. which works well,
this filter lies in a common module which is included in other projects to avoid including spring sleuth dependency in all of my micro-services, the reason why I've created it as a library because any changes to library will be common to all modules.
Now I've to add a new propagation key which need to be propagated to all services via http headers like trace and spanId for that I've extracted current span from HttpTracing and added a baggage key to it (as shown below)
Span span = httpTracing.tracing().tracer().currentSpan();
String corelationId =
StringUtils.isEmpty(request.getHeader(CORELATION_ID))
? "n/a"
: request.getHeader(CORELATION_ID);
ExtraFieldPropagation.set(CUSTOM_TRACE_ID_MDC_KEY_NAME, corelationId);
span.annotate("baggage_set");
span.tag(CUSTOM_TRACE_ID_MDC_KEY_NAME, corelationId);
I've added propagation-keys and whitelisted-mdc-keys to my application.yml (with my library) file like below
spring:
sleuth:
propagation-keys:
- x-corelationId
log:
slf4j:
whitelisted-mdc-keys:
- x-corelationId
After making this change in filter the corelationId is not available when I make a http call to another service with same app, basically keys are not getting propagated.
In your library you can implement ApplicationEnvironmentPreparedEvent listener and add the configuration you need there
Ex:
#Component
public class CustomApplicationListener implements ApplicationListener<ApplicationEvent> {
private static final Logger log = LoggerFactory.getLogger(LagortaApplicationListener.class);
public void onApplicationEvent(ApplicationEvent event) {
if (event instanceof ApplicationEnvironmentPreparedEvent) {
log.debug("Custom ApplicationEnvironmentPreparedEvent Listener");
ApplicationEnvironmentPreparedEvent envEvent = (ApplicationEnvironmentPreparedEvent) event;
ConfigurableEnvironment env = envEvent.getEnvironment();
Properties props = new Properties();
props.put("spring.sleuth.propagation-keys", "x-corelationId");
props.put("log.slf4j.whitelisted-mdc-keys:", "x-corelationId");
env.getPropertySources().addFirst(new PropertiesPropertySource("custom", props));
}
}
}
Then in your microservice you will register this custom listener
public static void main(String[] args) {
ConfigurableApplicationContext context = new SpringApplicationBuilder(MyApplication.class)
.listeners(new CustomApplicationListener()).run();
}
I've gone through documentation and seems like I need to add spring.sleuth.propagation-keys and whitelist them by using spring.sleuth.log.slf4j.whitelisted-mdc-keys
Yes you need to do this
is there another way to add these properties in common module so that I do not need to include them in each and every micro services.
Yes, you can use Spring Cloud Config server and a properties file called application.yml / application.properties that would set those properties for all microservices
The answer from Mahmoud works great when you want register the whitelisted-mdc-keys programatically.
An extra tip when you need these properties also in a test, then you can find the anwser in this post: How to register a ApplicationEnvironmentPreparedEvent in Spring Test
I have a flow that ends with sending a SOAP request. I'd like to write some kind of integration tests, for which I give 10 elements in input, and after going through the flow, I validate that 4 requests were fired for the 4 elements I expect (the 6 others got filtered and didn't make it through).
I'm using WebServiceTemplate, and I've read about MockWebServiceServer, but I am not sure it allows to do it out of the box. I'd like to maybe extend it, so that all sent requests are saved in a List that I can access to perform the assertions. I've looked at the source code, of MockWebServiceServer / MockWebServiceMessageSender but I don't see where I would do it.
Any ideas of how to achieve this ?
Thanks
One way of doing this is to extend RequestMatcher, not MockWebServiceServer. Here's an example of the class :
public class NeverFailingRequestMatcherWithMemory implements RequestMatcher {
List<WebServiceMessage> sentRequests=new ArrayList<WebServiceMessage>();
#Override
public void match(URI uri, WebServiceMessage request) throws IOException, AssertionError {
sentRequests.add(request);
}
public void clearMemory(){
sentRequests.clear();
}
public List<WebServiceMessage> getSentRequests(){
return sentRequests;
}
}
And you use it like this in your tests :
NeverFailingRequestMatcherWithMemory matcherWithMemory=new NeverFailingRequestMatcherWithMemory();
#Before
public void configureMockWsServer() {
WebServiceTemplate usedWebServiceTemplate = appCtx.getBean(WebServiceTemplate.class);
mockServer = MockWebServiceServer.createServer(usedWebServiceTemplate);
matcherWithMemory.clearMemory();
}
and later in your tests, something like :
mockServer.expect(matcherWithMemory).andRespond(withPayload(someResponsePayload));
assertThat(matcherWithMemory.getSentRequests()).hasSize(1);
Then you have access to the requests that were sent and can parse them the way you want.
I followed the gwt 2.4 validation sample and implemented the whole stuff into my own App. The client side works great.
private void verifyRegistrationData(final RegistrationTO registration) throws ConstraintViolationException {
final Validator validator = Validation.buildDefaultValidatorFactory().getValidator();
final Set<ConstraintViolation<RegistrationTO>> violations = validator.validate(registration);
if (violations.size() > 0) {
final Set<ConstraintViolation<?>> temp = new HashSet<ConstraintViolation<?>>(violations);
throw new ConstraintViolationException(temp);
...
but if I do the same on the server side:
public void update(final RegistrationTO registration) throws IllegalArgumentException, ConstraintViolationException, TestException {
final Set<ConstraintViolation<RegistrationTO>> violations = validator.validate(registration);
if (!violations.isEmpty()) {
final Set<ConstraintViolation<?>> temp = new HashSet<ConstraintViolation<?>>(violations);
throw new ConstraintViolationException(temp);
}
...
the whole thing crashes with the following exception:
javax.servlet.ServletContext log: Exception while dispatching incoming RPC call
com.google.gwt.user.client.rpc.SerializationException: Type 'org.hibernate.validator.engine.PathImpl' was not included in the set of types which can be serialized by this SerializationPolicy or its Class object could not be loaded. For security purposes, this type will not be serialized.
That's how PathImpl looks like hibernate-validator-4.1.0.Final-sources.jar
public class PathImpl implements Path, Serializable {
private static final long serialVersionUID = 7564511574909882392L;
...
looks OK (at least to me)
I am using GWT 2.4, validation-api-1.0.0.GA, hibernate-validator-4.1.0.Final, gwt-servlet-deps ...
Thanks in advance!
Is there an explicitly defined a default constructor? i.e.,
public PathImpl() { } ? This is required by GWT's serialization mechanism; if it isn't in the source, serializing an RPC response will fail.
A custom serializer does exist for PathImpl, it's just that unless that class is explicitly referenced in your service API, it's not going to be added to the serialization policy.
The current work around is to add a dummy PathImpl field somewhere in your service API. The ValidationSupport class exists to group this and other such classes together to make this a bit easier.
I change the whole thing to RequestFactory as Thomas Broyer recommended. It was by far not so easy as GWT-RPC. This was the reason for me to collect all kind of informations and to build a sample program. For those who are interested - here you can find a sample with documentation and source. (Single line client logger is also implemented) (Documentation is in German but logging-output aso. is in English...)