Cucumber with Spring Integration tests Multiple server restarts - spring

I have integrated cucumber tests with spring integration tests. I see that
#Suite
#IncludeEngines("cucumber")
#SelectClasspathResource("features")
#ConfigurationParameters({
#ConfigurationParameter(key = Constants.PLUGIN_PROPERTY_NAME,
value = "html:build/cucumber/cucumber.html"),
#ConfigurationParameter(key = Constants.GLUE_PROPERTY_NAME, value = "com.app.bdd"),
#ConfigurationParameter(key = Constants.FILTER_TAGS_PROPERTY_NAME, value = "not #Disabled"),
#ConfigurationParameter(key = Constants.PLUGIN_PUBLISH_QUIET_PROPERTY_NAME, value = "true"),
#ConfigurationParameter(key = Constants.JUNIT_PLATFORM_NAMING_STRATEGY_PROPERTY_NAME, value = "long")
})
public class MyBddFeatures {
}
#CucumberContextConfiguration
#SpringBootTest(classes = DealerConsumerApplication.class, webEnvironment = WebEnvironment.DEFINED_PORT)
#AutoConfigureMockMvc
#FlywayTest
#AutoConfigureWireMock
#AutoConfigureEmbeddedDatabase(type = AutoConfigureEmbeddedDatabase.DatabaseType.POSTGRES, provider = ZONKY)
#TestPropertySource("classpath:test-application.properties")
public class SpringGlue {
#TestConfiguration
public static class TestConfig {
// any mock beans would go here
}
}
And placed feature files under resources/features
Feature: Users Test
As a user
I want to test the changes in users
Scenario: Load to create the new users
Given I send request to create the new users
Then I receive response 200 and users created in database
Scenario: Load to update the users
Given I send request to update the old users
Then I receive response 200 and users updated in database
Scenario: Load to delete the users
Given I send request to delete the users
Then I receive response 200 and users deleted in database
What I am seeing is that cucumber
1. Server restart for every scenario, so I am loosing data between scenario in a single feature file
2. Server restart across feature files
Is there any way so that I can start my server once and run all tests in all feature files.

Related

is it possible to call a Microservice (spring boot) from a Camunda service Task?

Workflow -> (https://i.stack.imgur.com/vgtiD.png)
Is it possible to call a microservice from a Camunda task?
1.The start event will received a Json with a client data .
2.The service task should connect to a microservice (spring boot) that stores the data in the database.-> just need to pass the json with the info to the micro and then should complete the task.
3. if the previous task is completed this task should run.
is there a way to do it? I am very new at camunda.
External Task but it didnt work
Yes you can, check for documentation :
#Component
#ExternalTaskSubscription("scoreProvider") // create a subscription for this topic name
public class ProvideScoreHandler implements ExternalTaskHandler {
#Override
public void execute(ExternalTask externalTask, ExternalTaskService externalTaskService) {
// only for the sake of this demonstration, we generate random data
// in a real-world scenario, we would load the data from a database
String customerId = "C-" + UUID.randomUUID().toString().substring(32);
int creditScore = (int) (Math.random() * 11);
VariableMap variables = Variables.createVariables();
variables.put("customerId", customerId);
variables.put("creditScore", creditScore);
// complete the external task
externalTaskService.complete(externalTask, variables);
Logger.getLogger("scoreProvider")
.log(Level.INFO, "Credit score {0} for customer {1} provided!", new Object[]{creditScore, customerId});
}
}
Spring boot with Camunda example

Fabric8 customResourceDefinitions test

I am working on Fabric8 unit test, now I am trying to create a CRD against KubernetesServer.
import io.fabric8.kubernetes.api.model.apiextensions.v1.CustomResourceDefinition;
public class TestCertManagerService {
#Rule
public KubernetesServer server = new KubernetesServer();
#Test
#DisplayName("Should list all CronTab custom resources")
public void testCronTabCrd() throws IOException {
// Given
//server.expect().get().withPath("/apis/stable.example.com/v1/namespaces/default/crontabs").andReturn(HttpURLConnection.HTTP_OK, ?????).once();
KubernetesClient client = server.getClient();
CustomResourceDefinition cronTabCrd = client.apiextensions().v1().customResourceDefinitions()
.load(new BufferedInputStream(new FileInputStream("src/test/resources/crontab-crd.yml")))
.get();
client.apiextensions().v1().customResourceDefinitions().create(cronTabCrd);
}
}
When I ran it, I got the following error
TestCertManagerService > testCronTabCrd FAILED
io.fabric8.kubernetes.client.KubernetesClientException: Failure executing: GET at: https://localhost:60690/apis/apiextensions.k8s.io/v1/customresourcedefinitions.
at app//io.fabric8.kubernetes.client.dsl.base.OperationSupport.requestFailure(OperationSupport.java:694)
at app//io.fabric8.kubernetes.client.dsl.base.OperationSupport.requestFailure(OperationSupport.java:673)
at app//io.fabric8.kubernetes.client.dsl.base.OperationSupport.assertResponseCode(OperationSupport.java:626)
at app//io.fabric8.kubernetes.client.dsl.base.OperationSupport.handleResponse(OperationSupport.java:566)
at app//io.fabric8.kubernetes.client.dsl.base.OperationSupport.handleResponse(OperationSupport.java:527)
at app//io.fabric8.kubernetes.client.dsl.base.OperationSupport.handleResponse(OperationSupport.java:510)
at app//io.fabric8.kubernetes.client.dsl.base.BaseOperation.listRequestHelper(BaseOperation.java:136)
at app//io.fabric8.kubernetes.client.dsl.base.BaseOperation.list(BaseOperation.java:505)
at app//io.fabric8.kubernetes.client.dsl.base.BaseOperation.list(BaseOperation.java:494)
at app//io.fabric8.kubernetes.client.dsl.base.BaseOperation.list(BaseOperation.java:87)
at app//com.ibm.si.qradar.cp4s.service.certmanager.TestCertManagerService.testCronTabCrd(TestCertManagerService.java:94)
I have a few of questions:
(1) In this case, I am using v1() interface, sometimes I saw example code is using v1beta1(), what decides this version? By the way, I am using Kubernetes-client library 5.9.0
(2) In my code , I comments out this line
server.expect().get().withPath("/apis/stable.example.com/v1/namespaces/default/crontabs").andReturn(HttpURLConnection.HTTP_OK, ?????).once();
What is this statement for? In my case, I want to load a CRD, then create a CR, what is "?????" in the statement?
Any ideas for stack trace? How to fix it?
I appreciate it in advance.
From the code which you shared, it looks like you're using Fabric8 Kubernetes Mock Server in expectations mode. Expectations mode requires the user to set the REST API expectations. So the code shown below is setting some expectations from Mock Server viewpoint.
// Given
server.expect().get()
.withPath("/apis/stable.example.com/v1/namespaces/default/crontabs")
.andReturn(HttpURLConnection.HTTP_OK, getCronTabList())
.once();
These are the expectations set:
Mock Server would be requested a GET request at this URL: /apis/stable.example.com/v1/namespaces/default/crontabs . From URL we can expect a resource under stable.example.com apigroup with v1 version, default namespace and crontabs as plural.
When this URL is being hit, you're also defining response code and response body in andReturn() method. First argument is the response code (200 in this case) and second argument is the response body (a List object of CronTab which would be serialized and sent as response by mock server).
This request is only hit .once(), if KubernetesClient created by Mock Server requests this endpoint more than once; the test would fail. If you want to hit the endpoint more than once, you can use .times(..) method instead.
But in your test I see you're loading a CustomResourceDefinition from YAML and creating it which doesn't seem to match the expectations you set earlier. If you're writing a test about creating a CustomResourceDefinition, it should look like this:
#Test
#DisplayName("Should Create CronTab CRD")
void testCronTabCrd() throws IOException {
// Given
KubernetesClient client = server.getClient();
CustomResourceDefinition cronTabCrd = client.apiextensions().v1()
.customResourceDefinitions()
.load(new BufferedInputStream(new FileInputStream("src/test/resources/crontab-crd.yml")))
.get();
server.expect().post()
.withPath("/apis/apiextensions.k8s.io/v1/customresourcedefinitions")
.andReturn(HttpURLConnection.HTTP_OK, cronTabCrd)
.once();
// When
CustomResourceDefinition createdCronTabCrd = client.apiextensions().v1()
.customResourceDefinitions()
.create(cronTabCrd);
// Then
assertNotNull(createdCronTabCrd);
}
Bdw, if you don't like setting REST expectations. Fabric8 Kubernetes Mock Server also has a CRUD mode which mock real Kubernetes APIServer. You can enable it like this:
#Rule
public KubernetesServer server = new KubernetesServer(true, true);
then use it in test like this:
#Test
#DisplayName("Should Create CronTab CRD")
void testCronTabCrd() throws IOException {
// Given
KubernetesClient client = server.getClient();
CustomResourceDefinition cronTabCrd = client.apiextensions().v1()
.customResourceDefinitions()
.load(new BufferedInputStream(new FileInputStream("src/test/resources/crontab-crd.yml")))
.get();
// When
CustomResourceDefinition createdCronTabCrd = client.apiextensions().v1()
.customResourceDefinitions()
.create(cronTabCrd);
// Then
assertNotNull(createdCronTabCrd);
}
I added CustomResourceLoadAndCreateTest and CustomResourceLoadAndCreateCrudTest tests in my demo repository: https://github.com/r0haaaan/kubernetes-mockserver-demo

In MVC, Workflow Service not working wihout any error

I am calling WF as a service (hosted as a Service Reference in client)from my MVC web client. After publish when I deploy and hosting WebClient and WF service in my local machine IIS it is working and workflow calls all the defined activity. But when I am deploying same build on Production Server (Windows Server 2012) then seems WF service not getting called without any error. Please find below code
[HttpPost]
public ActionResult NewFeed(FeedProcessViewmodel fpmodel)
{
//some database object creation and saving
waiting to save the data into database and use the generated request id
sBL.SaveFeedDetailAsync(m_objMasterSnapShot, m_objMasterFeed, m_objFeedDetail);
//calling windows workflow service
InputRequest objInputRequest = new InputRequest { RequestId = "requestid" };
ServiceClient objServiceClient = new ServiceClient();
OutputResponse outputResponse = objServiceClient.SubmitRequest(objInputRequest);
if (!outputResponse.Success)
{
oDic.Add("Error", outputResponse.Message);
jrResult.Data = oDic;
throw new Exception(outputResponse.Message);
}
else
{
//CALLING THIS LINE AFTER OUTRESPONSE LINE EXECUTION
// BUT ALL THE ACTIVITY WITHING WORKFLOW NOT EXECUTED
oDic.Add("Ok", outputResponse.Message);
jrResult.Data = oDic;
}
}
Any help
Thanks
Its too late to reply to this post as I actually forgot to add an update for this.
The reason for above issue was at InputRequest class constructor.
InputRequest objInputRequest = new InputRequest { RequestId = "requestid" };
Had code which was returning null and because InputRequest class had try-catch block, actual error was suppressed and not propagated to calling place.

Session management for a RESTful Web Service using Jersey

I am developing a Restful Web Service using Jersey between my Android, iPhone apps and MySQL. I also use Hibernate to map the data to the database.
I have a sessionId (key). it is generated when user Login to the system.
In User class:
public Session daoCreateSession() {
if (session == null) {
session = new Session(this);
} else {
session.daoUpdate();
}
return session;
}
In Session Class:
Session(User user) {
this.key = UUID.randomUUID().toString();
this.user = user;
this.date = new Date();
}
void daoUpdate() {
this.key = UUID.randomUUID().toString();
this.date = new Date();
}
When user Sign in to the system successfully, I send this sessionId to the Mobile app client. Then when I want to get some information from database based on the logged in user, I check this Session key as authentication in the REST Services for every request.
For example for the list of project that user is involved in, I use client.GET(SERVER_ADDRESS/project/get/{SessionID})
insetead of client.GET(SERVER_ADDRESS/project/get/{username}).
And if it is not a valid session key, I'll send back to the client a 403 forbidden code.
You can also take a look here
The thing is I am not sure about my approach. what do you think about cons in this approach considering for Jersey and a mobile app?
I still don't know if the Session key approach is a good idea in my case.
If you want to use SessionId then it should have a validation time, like this:
private static final int MINUTES = 90;
public boolean isValid() {
return System.currentTimeMillis() - date.getTime() < 1000 * 60 * MINUTES;
}
This is a solved problem - servlet containers like Tomcat already do session management, and can distribute session state to other containers in the cluster either by broadcasting over TCP, or by using a shared data source like memcache.
I'd suggest reading up on what's already available, rather than inadvertently reinventing the wheel. Additionally, this is going to become an incredibly hot table table if your application proves popular. How will you clear out old session IDs?

Cannot get session ID for "remember me" users inside spring security login event listener

I'm writing a web app using grails and spring-security 3.0.3 which requires me to keep a databse record of all successful logins, including the username, time, ip, and sessionId.
I have created a login listener as so(groovy code):
class DpLoginListener implements ApplicationListener<InteractiveAuthenticationSuccessEvent> {
void onApplicationEvent(InteractiveAuthenticationSuccessEvent event) {
def source = event.getSource()
def principal = source.principal
def details = source.details
TrafficLogin.withTransaction {
new TrafficLogin(userId: principal.id, ipAddress: details.remoteAddress, sessionId: details.sessionId ?: 'remember me').save(failOnError: true)
}
}
}
This fires as expected when a user logs in, but when someone comes back to a site as a "remember me" user, the sessionId is null. Is this the expected behavior? Shouldn't a session be created by the time login has succeeded?
I tried to workaround this by adding a separate SessionCreationEvent listener, which would find the latest databse login record for the user and update that row with the correct sessionId as soon as the session exists, but it seems that this session creation event never fires, and I can't figure out why.
The session creation listener looks like this:
class DpSessionCreatedListener implements ApplicationListener<SessionCreationEvent> {
void onApplicationEvent(SessionCreationEvent event) {
def source = event.getSource()
def principal = source.principal
def details = source.details
TrafficLogin.withTransaction {
def rememberMe = TrafficLogin.find("from TrafficLogin as t where t.userId=? and t.sessionId='remember me' order by t.dateCreated desc", principal.id)
if (rememberMe) {
rememberMe.sessionId = details.sessionId
rememberMe.save(failOnError:true)
}
}
}
}
And a bean is defined for it in my resources.groovy file, in the same manner as the login listener, which fires fine.
Any ideas how to correctly set this sessionId?
Not related to grails, but this SO question may offer a workaround if grails supports it.

Resources