dslContract generated from spring restdocs not working with queryParameters - spring-cloud

When i create dslcontracts in my restdoc test with query parameters, it creates the groovy contract file as well as stub file. But when i deploy the contract using #EnableStubRunnerServer, i can never get the query parameters to match.
I realized that the stub file is generated with request looking like:
"request" : {
"url" : "/search",
"method" : "GET",
"queryParameters" : {
"query" : {
"equalTo" : "friday"
}
}
}
However if i change the stub file to :
"request" : {
"urlPathPattern" : "/search",
"method" : "GET",
"queryParameters" : {
"query" : {
"equalTo" : "friday"
}
}
}
it seems to work. Is there a way to make this work?
Here is how i'm writing the test:
#Test
public void searchWithQuery() throws Exception {
Map<String, Object> param = new HashMap<>();
param.put("query", "equalTo(\"friday\")");
mockMvc.perform(get(SEARCH_PATH + "?query=friday"))
.andExpect(status().isOk())
.andDo(document("search-query",
dslContract(param)
));
}

Related

how to get jbpm output variable?

I created the bpmn project and deployed it to the kieserver,how can I use the rest api of kieserver to call and obtain output variables ?
I have defined process variable in bpmn, but after calling and executing bpmn, I cannot get the process variable in the returned results.
The following are the request message and response message I called
Please help to see if there is a problem with the calling method or parameters
Url: http://127.0.0.1:8080/kie-server/services/rest/server/containers/instances/YgdPostLoanFinalResultDemo_1.0.0-SNAPSHOT
Request:
{
"commands":[
{
"set-global" : {
"identifier" : "output",
"object" : {
"com.ygdpostloan.OutputVariable" : {
"finalDecisionFlag" : "xxx",
"targetBehaviorStatus" : null
}
},
"out-identifier" : "output"
}
},
{
"start-process" : {
"processId" : "YgdPostLoanFinalResultProcess",
"data" : null,
"agendaFilter" : null,
"parameter" : [
{
"value" : {
"com.ygdpostloan.InputVariable":{
"sysCode" : "jyd",
"flagBQS" : null,
"flagRH" : null,
"flagXDXWJT" : null,
"resultBQS" : null,
"resultRH" : null,
"resultXDXWJT" : 3
}
},
"key" : "input"
}
],
"out-identifier" : "input"
}
}
]
}
Response:
{
"type" : "SUCCESS",
"msg" : "Container YgdPostLoanFinalResultDemo_1.0.0-SNAPSHOT successfully called.",
"result" : {
"execution-results" : {
"results" : [ {
"value" : {"com.ygdpostloan.OutputVariable":{
"finalDecisionFlag" : "xxx",
"targetBehaviorStatus" : null
}},
"key" : "output"
}, {
"value" : 13,
"key" : "input"
} ],
"facts" : [ ]
}
}
}
I receive result data through global variable , but I'm not sure whether this method is reasonable. I want to try to receive results through process variable
Variables alse cannot be obtained through the kie server client api
public static void main(String[] args) {
KieServices kieServices = KieServices.Factory.get();
CredentialsProvider credentialsProvider = new EnteredCredentialsProvider("kieserver", "kieserver");
KieServicesConfiguration kieServicesConfig = KieServicesFactory.newRestConfiguration("http://127.0.0.18080/kie-server/services/rest/server", credentialsProvider);
// Set the Marshaling Format to JSON. Other options are JAXB and XSTREAM
kieServicesConfig.setMarshallingFormat(MarshallingFormat.JSON);
KieServicesClient kieServicesClient = KieServicesFactory.newKieServicesClient(kieServicesConfig);
QueryServicesClient queryServicesClient = kieServicesClient.getServicesClient(QueryServicesClient.class);
List<ProcessDefinition> processes = queryServicesClient.findProcesses(0, 10);
System.out.println(processes);
// Retrieve the RuleServices Client.
ProcessServicesClient processServicesClient = kieServicesClient.getServicesClient(ProcessServicesClient.class);
ProcessDefinition processDefinition = processServicesClient.getProcessDefinition("YgdPostLoanFinalResultDemo_1.0.0-SNAPSHOT", "YgdPostLoanFinalResultProcess");
System.out.println(processDefinition);
Map<String, Object> inputMap = new HashMap<>();
Map<String, Object> intParamMap = new HashMap<>();
intParamMap.put("resultXDXWJT", 3);
intParamMap.put("sysCode", "111");
Map<String, Object> processParamMap = new HashMap<>();
InputVariable inputVariable = new InputVariable();
inputVariable.setResultXDXWJT(3);
inputVariable.setSysCode("111");
inputMap.put("com.ygdpostloan.InputVariable", inputVariable);
processParamMap.put("input", inputMap);
Long instanceId = processServicesClient.startProcess("YgdPostLoanFinalResultDemo_1.0.0-SNAPSHOT", "YgdPostLoanFinalResultProcess", processParamMap);
System.out.println(instanceId);
ProcessInstance processInstance1 = processServicesClient.getProcessInstance("YgdPostLoanFinalResultDemo_1.0.0-SNAPSHOT", instanceId, true);
System.out.println(processInstance1);
//Map<String, Object> processInstanceVariables = processServicesClient.getProcessInstanceVariables("YgdPostLoanFinalResultDemo_1.0.0-SNAPSHOT", instanceId);
//System.out.println(processInstanceVariables);
List<NodeInstance> completedNodeInstances = queryServicesClient.findCompletedNodeInstances(instanceId, 0, 10);
System.out.println(completedNodeInstances);
//Map<String, Object> processInstanceVariables = processServicesClient.getProcessInstanceVariables("YgdPostLoanFinalResultDemo_1.0.0-SNAPSHOT", instanceId);
ProcessInstance processInstance = queryServicesClient.findProcessInstanceById(instanceId);
System.out.println(processInstance);
Map<String, Object> variables = processInstance.getVariables();
System.out.println(variables); // return null
}

Wiremock error: Request was not matched as there were no stubs registered

#ClassRule
public static WireMockRule wireMockRule = new WireMockRule(9898);
#Test
public void createXmlFile() {
stubFor(get(urlPathEqualTo("/data/racing/"))
.willReturn(aResponse()
.withBody(loadJSONFile("unibet-demo-input.json"))));
}
I don't know what is going wrong here!
2019-01-16 15:54:05.810 [qtp1929284175-20] INFO ROOT:2341 - RequestHandlerClass from context returned com.github.tomakehurst.wiremock.http.StubRequestHandler. Normalized mapped under returned 'null'
2019-01-16 15:54:05.822 [qtp1929284175-15] INFO __admin:2341 - RequestHandlerClass from context returned com.github.tomakehurst.wiremock.http.AdminRequestHandler. Normalized mapped under returned 'null'
2019-01-16 15:54:05.925 [qtp1929284175-20] ERROR WireMock:40 - Request was not matched as there were no stubs registered:
{
"url" : "/data/racing/",
"absoluteUrl" : "http://localhost:9898/data/racing/",
"method" : "GET",
"clientIp" : "127.0.0.1",
"headers" : {
"User-Agent" : "Jakarta Commons-HttpClient/3.1",
"Host" : "localhost:9898",
"batchID" : "1056178410254123336",
"breadcrumbId" : "ID-SBGML01938-1547654042343-0-1"
},
"cookies" : { },
"browserProxyRequest" : false,
"loggedDate" : 1547654045870,
"bodyAsBase64" : "",
"body" : "",
"scheme" : "http",
"host" : "localhost",
"port" : 9898,
"loggedDateString" : "2019-01-16T15:54:05Z",
"queryParams" : { }
}
Click to see the difference is stating Contents are identical.
com.github.tomakehurst.wiremock.client.VerificationException: A request was unmatched by any stub mapping. Closest stub mapping was: <Click to see difference>
at com.github.tomakehurst.wiremock.client.VerificationException.forSingleUnmatchedRequest(VerificationException.java:43)
at com.github.tomakehurst.wiremock.client.VerificationException.forUnmatchedNearMisses(VerificationException.java:48)
at com.github.tomakehurst.wiremock.junit.WireMockRule.checkForUnmatchedRequests(WireMockRule.java:92)
at com.github.tomakehurst.wiremock.junit.WireMockRule.access$000(WireMockRule.java:34)
at com.github.tomakehurst.wiremock.junit.WireMockRule$1.evaluate(WireMockRule.java:74)
at org.junit.rules.RunRules.evaluate(RunRules.java:20)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:190)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
I had to add wireMockRule on stubFor to make it work.
#ClassRule
public static WireMockRule wireMockRule = new WireMockRule(9898);
#Test
public void createXmlFile() {
wireMockRule.stubFor(get(urlPathEqualTo("/data/racing/"))
.willReturn(aResponse()
.withBody(loadJSONFile("unibet-demo-input.json"))));
}

Spring Cloud Contract provider return same as request

I'm working with two microservices using Spring Cloud Contract. One providing its contract, and the other one consuming it. In one scenario the provider response is the same that the request.
So the provider contract is like this:
Contract.make {
request {
method 'POST'
url '/provider/foo'
body(
"foo": $(regex("[a-zA-Z0-9]{20}"))
)
}
response {
status 200
body(
"fooResponse": fromRequest().body("\$.foo")
)
}
And the generated wiremock mapping:
{
"id" : "a80c0871-f4c0-49e3-8cc1-94de39899669",
"request" : {
"url" : "/provider/foo",
"method" : "POST",
"bodyPatterns" : [ {
"matchesJsonPath" : "$[?(#.['foo'] =~ /[a-zA-Z0-9]{20}/)]"
} ]
},
"response" : {
"status" : 200,
"body" : "{\"fooResponse\":\"{{{jsonpath this '$.foo'}}}\"}",
"transformers" : [ "response-template" ]
},
"uuid" : "a80c0871-f4c0-49e3-8cc1-94de39899669",
"scenarioName" : "scenarioReturnSameAsRequest",
"requiredScenarioState" : "Started"
}
But when my code calls to the provider, with foo as any text, the wiremock returns:
{
"fooResponse" : "{{{jsonpath this '$.foo'}}}"
}
How can I build a contract that responses the same parameters as the request body?
Edit
I tried with a fixed value on the response and works fine:
Contract.make {
request {
method 'POST'
url '/provider/foo'
body(
"foo": $(regex("[a-zA-Z0-9]{20}"))
)
}
response {
status 200
body(
"fooResponse": "fooValue"
)
}
Now wiremock return:
{
"fooResponse" : "fooValue"
}
Maybe is not supported getting from request a regex value?
I think the mapping should contain request.body instead of this. Also I wonder if you need to use 3 times a { or just 2 times. Or do you need to escape these?
Possible mapping:
"response" : {
"status" : 200,
"body" : "{\"fooResponse\":\"{{jsonpath request.body '$.foo'}}\"}",
"transformers" : [ "response-template" ]
},
See also the chapter JSONPath helper on http://wiremock.org/docs/response-templating
I had the same problem once. You can try to use value() like this:
"fooResponse": value(fromRequest().body('$.foo'))

Spring Boot, Spring Security - Prevent direct URL query of MongoDB

So, I'm working on a Spring Boot Web App that utilizes Spring Security for login authentication. Currently, we have three types of users who get redirected to the appropriate dashboard and when they try to access the other dashboards through a direct URL, they are denied access. Any unauthenticated user is also denied access to the rest of the site. While testing, I had found that once a user had successfully been authenticated, if they were to use a direct URL to "/", or localhost:8080 for testing, instead of being redirected to the login page as they would when not authenticated, a JSON with information of our tables in our MongoDB instance would be returned. Worse, if they appended a table name to the URL, they would receive the entire table in JSON form.
Example: http://localhost:8080/premios (Currently holding dummy values)
{
"_embedded" : {
"premios" : [ {
"title" : "hdlkfjgd",
"description" : "dflgkj",
"points" : 20,
"enabled" : false,
"_links" : {
"self" : {
"href" : "http://localhost:8080/premios/5a013a974833be43fa38dc53"
},
"premio" : {
"href" : "http://localhost:8080/premios/5a013a974833be43fa38dc53"
}
}
}, {
"title" : "dfdggd",
"description" : "dfgd",
"points" : 5,
"enabled" : false,
"_links" : {
"self" : {
"href" : "http://localhost:8080/premios/5a0a11964833be69a480a901"
},
"premio" : {
"href" : "http://localhost:8080/premios/5a0a11964833be69a480a901"
}
}
}, {
"title" : "alksksjlkakjf",
"description" : "sdlkfkjsdlfkj",
"points" : 5,
"enabled" : false,
"_links" : {
"self" : {
"href" : "http://localhost:8080/premios/5a0a12b24833be6a6e47a22a"
},
"premio" : {
"href" : "http://localhost:8080/premios/5a0a12b24833be6a6e47a22a"
}
}
} ]
},
"_links" : {
"self" : {
"href" : "http://localhost:8080/premios{?page,size,sort}",
"templated" : true
},
"profile" : {
"href" : "http://localhost:8080/profile/premios"
},
"search" : {
"href" : "http://localhost:8080/premios/search"
}
},
"page" : {
"size" : 20,
"totalElements" : 3,
"totalPages" : 1,
"number" : 0
}
}
How can I prevent this? Is this due to how I have Spring Security set up, or something I need to do on our mLab to only allow controllers on the backend to make queries? The above premios URL is not a defined request method in any of our controllers so I'm not sure why it's working. Here's how it's configured:
WebSecurityConfig.java
#Configuration
#EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private SimpleAuthenticationSuccessHandler successHandler;
#Autowired
public void configureGlobal(
AuthenticationManagerBuilder auth,
CustomUserDetailsService userDetailsService) throws Exception {
auth
.userDetailsService(userDetailsService);
}
#Override
protected void configure(HttpSecurity http)
throws Exception {
http
.csrf().disable()
.authorizeRequests()
.antMatchers("/css/**", "/js/**", "/images/**", "/script/**").permitAll()
.antMatchers("/signup").permitAll()
.antMatchers("/webapp/admin").hasRole("ADMIN")
.antMatchers("/webapp/sales").hasRole("SALES")
.antMatchers("/webapp/business").hasRole("USER")
.anyRequest().authenticated()
.and()
.formLogin()
.successHandler(successHandler)
.loginPage("/login")
.permitAll()
.and()
.logout()
.logoutRequestMatcher(new AntPathRequestMatcher(("/logout")))
.logoutSuccessUrl("/login")
.permitAll();
}
}
SimpleAuthenticationSuccessHandler.java
#Component
public class SimpleAuthenticationSuccessHandler implements AuthenticationSuccessHandler{
private RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
#Override
public void onAuthenticationSuccess(HttpServletRequest httpServletRequest,
HttpServletResponse httpServletResponse,
Authentication authentication) throws IOException, ServletException {
Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities();
authorities.forEach(authority -> {
if(authority.getAuthority().equals("ROLE_ADMIN")) {
try {
redirectStrategy.sendRedirect(httpServletRequest, httpServletResponse, "/webapp/admin");
} catch (Exception e) {
e.printStackTrace();
}
}
else if(authority.getAuthority().equals("ROLE_SALES")) {
try {
redirectStrategy.sendRedirect(httpServletRequest, httpServletResponse, "/webapp/sales");
} catch (Exception e) {
e.printStackTrace();
}
}
else if(authority.getAuthority().equals("ROLE_USER")) {
try {
redirectStrategy.sendRedirect(httpServletRequest, httpServletResponse, "/webapp/business");
} catch (Exception e) {
e.printStackTrace();
}
}
else {
throw new IllegalStateException();
}
});
}
}
Maybe, it's something to do with the success handler? I'm new to using Spring Boot and building a Web App so any help is much appreciated!
For anyone with a similar issue, I solved my problem by changing:
.anyRequest().authenticated()
to
.anyRequest().denyAll().
Once a user was authenticated, they were able to make any request of our Web App. By using denyAll, we could prevent all requests that were not specified in our antmatchers. I also modified antmatchers such as this:
.antMatchers("/webapp/business").hasRole("USER")
to
.antMatchers("/webapp/business").access("isFullyAuthenticated() and hasRole('USER')")
And just in case, I made sure to reroute any requests to "/" to our login page "/login".

Camel Rest-DSL (api-doc) - Potential bug

I've been using Rest-DSL (Camel v2.18.1) and trying to set up my own RestOperationResponseMsgDefinition so as to have a useful API doc. By setting a class to the responseModel to tell which object will be returned in case of success, its structure is properly shown in the API doc. However, if I create a class that has that object within, all endpoints which mention it as their outputType/responseModel stop showing the correct structure in the API doc and put "string" instead. Like this:
My outputType/responseModel:
class Address {
private Integer id;
private String descr;
}
API-doc snippet:
"/addresses" : {
"get" : {
"produces" : [ "application/json" ],
"responses" : {
"200" : {
"description" : "Success.",
"schema" : {
"$ref" : "#/definitions/Address"
}
}
...
In Swagger-UI, the response example value is shown as:
{
"id": "string",
"descr": "string"
}
Everything is alright till I create any class having an Address object within! For instance:
class Store {
private Integer id;
private String name;
private Address address;
}
Now, for the same endpoint mentioned before, I get...
"/addresses" : {
"get" : {
"produces" : [ "application/json" ],
"responses" : {
"200" : {
"description" : "Success.",
"schema" : {
"type" : "string",
"format" : "com.mycompany.integration.domain.Address"
}
}
...
And the following in Swagger-UI as example value:
"string"
Has anybody ever passed through and solved this? This seems a bug, though...