Wiremock - Autoconfigure doesn't load stubs - java

My wiremock doesn't seem to work with autoconfigure. I have json files in a folder named stubs in the classpath and I ran the standalone jar on the port 8080.
#AutoConfigureWireMock(stubs="classpath:/stubs", port = 0)
public class TestResource {
#Autowired
private Service service;
#Test
public void contextLoads() throws Exception {
assertThat(this.service.go()).isEqualTo("Hello World!");
}
}
Example of a json file
{
"request" : {
"url" : "/api/users",
"method" : "GET",
"bodyPatterns" : [ {
"contains" : "some soap body"
}]
},
"response" : {
"status" : 200,
"body" : "Hello World",
"headers" : {
"X-Application-Context" : "application:-1",
"Content-Type" : "text/plain"
}
}
}
When I launch a request with GET -> localhost:8080/api/users/ It doesn't match with the json file.
Thanks in advance

I simply added all my json with a POST request on localhost:8080/__admin/mappings/import
http://wiremock.org/docs/stubbing/

Related

Mockserver fails to match expectation for received message

I am using
<dependency>
<groupId>org.mock-server</groupId>
<artifactId>mockserver-netty</artifactId>
<version>5.11.2</version>
<scope>test</scope>
</dependency>
for integration tests of a REST API. I've started with very basic expectations, to further ellaborate the tests later, once the minimum stuff passes the test. To my surpise, MockServer keeps telling me that no received requests match my expectations.
I am using the Java API, to write tests that use Mockito and PowerMock to deal with static methods. TestNG is the Test Freamework.
This is my code:
#PowerMockIgnore({"javax.xml.parsers.*", "org.apache.logging.log4j.*", "com.sun.org.apache.*", "sun.security.*", "javax.net.ssl.*"})
#PrepareForTest({K8sTarget.class, K8sApi.class})
public class DataAccessImplTest extends PowerMockTestCase {
private static final String HTTP_METHOD_GET = "GET";
private static final String USER_ID= "46756123123";
private static final String USERS_PATH = "/api/v1/users/%s";
private static final String CONTENT_TYPE_APP_JSON = "application/json";
#Mock
Target mockTarget;
#Mock
K8sClient mockK8sClient;
private DataAccessFactory dataAccessFactory;
private DataAccessImpl dataAccessUT;
private MockServerClient mockServer;
AutoCloseable closeable;
#BeforeClass
public void setup() {
// ensure all connection using HTTPS will use the SSL context defined by
// MockServer to allow dynamically generated certificates to be accepted
HttpsURLConnection.setDefaultSSLSocketFactory(
new KeyStoreFactory(new MockServerLogger()).sslContext().getSocketFactory());
this.mockServer = startClientAndServer(PortFactory.findFreePort());
this.closeable = MockitoAnnotations.openMocks(this);
dataAccessFactory = DataAccessFactory.getInstance();
assertNotNull(dataAccessFactory);
PowerMockito.mockStatic(K8sApi.class);
PowerMockito.mockStatic(K8sTarget.class);
PowerMockito.when(K8sApi.getK8sClient()).thenReturn(mockK8sClient);
PowerMockito.when(K8sTarget.of(Mockito.any(K8sClient.class), Mockito.any(Target.class))).thenReturn(mockTarget);
Mockito.when(mockTarget.getName()).thenReturn("localhost");
Mockito.when(mockTarget.getPort()).thenReturn(this.mockServer.getPort().intValue());
dataAccessUT = dataAccessFactory.createDataClient();
}
#BeforeMethod
public void prepareMocks() {
Mockito.when(mockTarget.getName()).thenReturn("localhost");
Mockito.when(mockTarget.getPort()).thenReturn(this.mockServer.getPort().intValue());
}
#AfterClass
public void teardown() throws Exception {
this.closeable.close();
this.mockServer.stop();
}
#Test
public void getUserTest_200_Ok() throws IOException {
dataAccessUT.getUserData(USER_ID);
mockServer.when(request()
.withMethod(HTTP_METHOD_GET)
.withPath(String.format(USERS_PATH, USER_ID))
)
.respond(
response()
.withStatusCode(HttpStatusCode.OK_200.code())
.withHeader(HttpHeaderNames.CONTENT_TYPE.toString(), CONTENT_TYPE_APP_JSON)
.withBody("some_response_body")
);
}
}
and these are the console logs:
10:06:24.067 [nioEventLoopGroup-2-1] DEBUG com.commonlibrary.httpclient.common.HttpConnectionListener:28 - 0.1 HttpConnectionListener::operationComplete: connected to [localhost:58136] from [/127.0.0.1:58204]
10:06:24.285 [MockServer-EventLog0] INFO org.mockserver.log.MockServerEventLog:108 - 58136 received request:
{
"method" : "GET",
"path" : "/api/v1/users/46756123123",
"headers" : {
"authorization" : [ "Bearer token" ],
"accept" : [ "application/json" ],
"host" : [ "localhost:58136" ],
"content-length" : [ "0" ]
},
"keepAlive" : true,
"secure" : false
}
10:06:24.350 [MockServer-EventLog0] INFO org.mockserver.log.MockServerEventLog:108 - 58136 no expectation for:
{
"method" : "GET",
"path" : "/api/v1/users/46756123123",
"headers" : {
"authorization" : [ "Bearer token" ],
"accept" : [ "application/json" ],
"host" : [ "localhost:58136" ],
"content-length" : [ "0" ]
},
"keepAlive" : true,
"secure" : false
}
returning response:
{
"statusCode" : 404,
"reasonPhrase" : "Not Found"
}
10:06:24.483 [MockServer-EventLog0] INFO org.mockserver.log.MockServerEventLog:108 - 58136 stopped for port: 58136
As you can see (unless I am missing something) request should match the expectation, but it doesn'. I have tried several things, all of them without success:
reduce the request expectation to the bare minimum, just calling request() without defining anything else. This shouls match EVERY incoming request. Same result.
introduce Times.exactly(1) in the expectation. Same result.
specify the headers I am sending in the request, even though my understanding is that if they are not set in the expectation, they are not used for matching. Same result.
After 2 days, I am running out of ideas, so any help or hint would be appreciated. Thanks!
Edition after following hint and checking code examples in MockServer site
Following #peter-rowth suggestion, I moved the request sent after creating expectations and it worked.
I am editing this issue also to make clear that it duplicates [https://stackoverflow.com/questions/63843619/mockserver-request-not-found][1], that I found later.
It looks like in your test you are creating the expectations in MockServer after executing the call to your code under test? The fact that your console output from MockServer does not output matched/not matched expectations (the default behavior) indicated to me that there are no expectations setup when the web request is made to MockServer and a 404 is default response by MockServer when there is no expectation for a request.
Try adding that expectation as the first line in your test.

How to upload Json Data or file in Elasticsearch using Java?

This is my sample Json Data coming from .json file now I want to do bulk_insert to elasticsearch dynamically so that I can perform operations on it ..can someone help me with java code to add this data dynamically ..this is just a piece of 5-6objects like this i have more then 500objects
[{
"data1" : "developer",
"data2" : "categorypos",
"data3" : "1001"
},
{
"data1" : "developer",
"data1" : "developerpos",
"data1" : "1002"
},
{
"data1" : "developer",
"data2" : "developpos",
"data3" : "1003"
},
{
"data1" : "support",
"data2" : "datapos",
"data3" : "1004"
}
]
There is a provision of bulk operations in elastic search following is the documentation this might help
https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-bulk.html
You need to read the file from your application, iterate over the array and for each document, send it to elasticsearch.
To do the latest, you should use the bulk processor class.
BulkProcessor bulkProcessor = BulkProcessor.builder(
(request, bulkListener) -> esClient.bulkAsync(request, RequestOptions.DEFAULT, bulkListener),
new BulkProcessor.Listener() {
#Override
public void beforeBulk(long executionId, BulkRequest request) { }
#Override
public void afterBulk(long executionId, BulkRequest request, BulkResponse response) { }
#Override
public void afterBulk(long executionId, BulkRequest request, Throwable failure) { }
})
.setBulkActions(10000)
.setFlushInterval(TimeValue.timeValueSeconds(5))
.build();
For each json document, call:
bulkProcessor.add(new IndexRequest("INDEXNAME").source(json, XContentType.JSON));

Wiremock error - there are no stub mappings in this WireMock instance

I have implemented a basic WireMock with a sample REST/HTTP request simulation. The server code implemented as below.
With this code, I get the following error when I issue the GET request from Postman (i.e. GET http://127.0.0.1:8089/some/thing).
No response could be served as there are no stub mappings in this WireMock instance.
What is missing in my setup/code?
import com.github.tomakehurst.wiremock.WireMockServer;
import com.github.tomakehurst.wiremock.core.WireMockConfiguration;
public class MockApp {
private WireMockServer wireMockServer;
public MockApp(String testSpec) {
wireMockServer = new WireMockServer(WireMockConfiguration.options().
port(8089).
usingFilesUnderDirectory(testSpec).
disableRequestJournal());
}
public void start() {
wireMockServer.start();
}
public void stop() {
wireMockServer.stop();
}
}
The main function is:
public class MockMain {
public static void main(String[] args) {
String baseDir = System.getProperty("user.dir");
String testResource = baseDir + "/resources/testconfig/";
MockAMS mockAMS = new MockAMS(testResource);
mockAMS.start();
}
}
Under 'resources/testconfig', there is a file called mapping.json containing:
{
"request": {
"method": "GET",
"url": "/some/thing"
},
"response": {
"status": 200,
"body": "Hello world!",
"headers": {
"Content-Type": "text/plain"
}
}
}
I found solution for this. So, basically we need create a folder called "mappings" (exact name) under the directory identified by "testResource" variable. So in above code example, the mapping.json file will be stored at location: "MockApp/resources/testconfig/mappings/mapping.json".
Once this, is done, it will print the following output. As can be seen in the logs, "Stub mapping size is 1". This will be printed once you add the following line in the code.
System.out.println("Stub mapping size: " + wireMockServer.getStubMappings().size());
Stub mapping size: 1
{
"id" : "da5735a6-b6cc-45aa-8256-fb88b5670610",
"request" : {
"url" : "/some/thing",
"method" : "GET"
},
"response" : {
"status" : 200,
"body" : "Hello world!",
"headers" : {
"Content-Type" : "text/plain"
}
},
"uuid" : "da5735a6-b6cc-45aa-8256-fb88b5670610"
}

How to create Spring Data Rest entities response format manually [duplicate]

This question already has answers here:
Calling spring data rest repository method doesn't return links
(2 answers)
Closed 6 years ago.
I'm using Spring Data Rest to create a RESTful api. I want to handle an exception returning an entity representation like the ones generated by the Spring Data Rest repositories (with HATEOAS links). The method from where I need to return the entity representation is the following:
#ExceptionHandler(value = {ExistentUGVException.class})
#ResponseBody
protected ResponseEntity<UGV> existentUGVHandler(HttpServletRequest request, HttpServletResponse response, ExistentUGVException ex) {
return new ResponseEntity<UGV>(ex.ugv, HttpStatus.OK);
}
This implementation returns the UGV representation without links:
{
"title" : "Golden Eagle Snatches Kid",
"publishDate" : "2012-12-19T13:55:28Z",
"url" : "https://www.youtube.com/watch?v=Xb0P5t5NQWM"
}
But it would be:
{
"title" : "Golden Eagle Snatches Kid",
"publishDate" : "2012-12-19T13:55:28Z",
"url" : "https://www.youtube.com/watch?v=Xb0P5t5NQWM",
"_links" : {
"self" : {
"href" : "http://localhost/youTubeVideos/Xb0P5t5NQWM"
},
"youTubeVideo" : {
"href" : "http://localhost/youTubeVideos/Xb0P5t5NQWM{?projection}",
"templated" : true
},
"user" : {
"href" : "http://localhost/youTubeVideos/Xb0P5t5NQWM/user"
}
}
}
You'll have to transform your ResponseEntity to Resource first and then add the links manually.
It should be something like this :
#ExceptionHandler(value = {ExistentUGVException.class})
#ResponseBody
protected ResponseEntity<Resource<UGV>> existentUGVHandler(HttpServletRequest request, HttpServletResponse response, ExistentUGVException ex) {
final Resource<UGV> resource = getResource(ex.ugv);
return new ResponseEntity<Resource<UGV>>(resource, HttpStatus.OK);
}
public Resource<T> getResource(T object, Link... links) throws Exception {
Object getIdMethod = object.getClass().getMethod("getId").invoke(object);
Resource<T> resource = new Resource<T>(object); // The main resource
final Link selfLink = entityLinks.linkToSingleResource(object.getClass(), getIdMethod).withSelfRel();
String mappingRel = CLASSMAPPING.getMapping(this.getClass());
final Link resourceLink = linkTo(this.getClass()).withRel(mappingRel);
resource.add(selfLink, resourceLink);
resource.add(links);
return resource;
}
Take a look here, there's all you need : spring hateoas documentation

Example of standalone Apache Qpid (amqp) Junit Test

Does anyone have an example of using Apache Qpid within a standalone junit test.
Ideally I want to be able to create a queue on the fly which I can put/get msgs within my test.
So I'm not testing QPid within my test, I'll use integration tests for that, however be very useful to test methods handling msgs with having to mock out a load of services.
Here is the setup method I use for QPID 0.30 (I use this in a Spock test but should be portable to Java of Junit with no problems). This supports SSL connection, the HTTP management, and uses only in-memory startup. Startup time is sub-second. Configuration for QPID is awkward compared to using ActiveMQ for the same purpose, but QPID is AMQP compliant and allows for a smooth, neutral testing for AMQP clients (obviously the use of exchanges can not mimic RabbitMQs implementation, but for basic purposes it is sufficient)
First I created a minimal test-config.json which I put in the resources folder:
{
"name": "${broker.name}",
"modelVersion": "2.0",
"defaultVirtualHost" : "default",
"authenticationproviders" : [ {
"name" : "passwordFile",
"type" : "PlainPasswordFile",
"path" : "${qpid.home_dir}${file.separator}etc${file.separator}passwd",
"preferencesproviders" : [{
"name": "fileSystemPreferences",
"type": "FileSystemPreferences",
"path" : "${qpid.work_dir}${file.separator}user.preferences.json"
}]
} ],
"ports" : [ {
"name" : "AMQP",
"port" : "${qpid.amqp_port}",
"authenticationProvider" : "passwordFile",
"keyStore" : "default",
"protocols": ["AMQP_0_10", "AMQP_0_8", "AMQP_0_9", "AMQP_0_9_1" ],
"transports" : [ "SSL" ]
}, {
"name" : "HTTP",
"port" : "${qpid.http_port}",
"authenticationProvider" : "passwordFile",
"protocols" : [ "HTTP" ]
}],
"virtualhostnodes" : [ {
"name" : "default",
"type" : "JSON",
"virtualHostInitialConfiguration" : "{ \"type\" : \"Memory\" }"
} ],
"plugins" : [ {
"type" : "MANAGEMENT-HTTP",
"name" : "httpManagement"
}],
"keystores" : [ {
"name" : "default",
"password" : "password",
"path": "${qpid.home_dir}${file.separator}keystore.jks"
}]
}
I
I also needed to create a keystore.jks file for localhost because the QPID broker and the RabbitMQ client do not like to communicate over an unencrypted channel. I also added a file called "passwd" in "integTest/resources/etc" that has this content:
guest:password
Here is the code from the unit test setup:
class level variables:
def tmpFolder = Files.createTempDir()
Broker broker
def amqpPort = PortFinder.findFreePort()
def httpPort = PortFinder.findFreePort()
def qpidHomeDir = 'src/integTest/resources/'
def configFileName = "/test-config.json"
code for the setup() method:
def setup() {
broker = new Broker();
def brokerOptions = new BrokerOptions()
File file = new File(qpidHomeDir)
String homePath = file.getAbsolutePath();
log.info(' qpid home dir=' + homePath)
log.info(' qpid work dir=' + tmpFolder.absolutePath)
brokerOptions.setConfigProperty('qpid.work_dir', tmpFolder.absolutePath);
brokerOptions.setConfigProperty('qpid.amqp_port',"${amqpPort}")
brokerOptions.setConfigProperty('qpid.http_port', "${httpPort}")
brokerOptions.setConfigProperty('qpid.home_dir', homePath);
brokerOptions.setInitialConfigurationLocation(homePath + configFileName)
broker.startup(brokerOptions)
log.info('broker started')
}
code for cleanup()
broker.shutdown()
To make an AMQP connection from a Rabbit MQ client:
ConnectionFactory factory = new ConnectionFactory();
factory.setUri("amqp://guest:password#localhost:${amqpPort}");
factory.useSslProtocol()
log.info('about to make connection')
def connection = factory.newConnection();
//get a channel for sending the "kickoff" message
def channel = connection.createChannel();
The Qpid project has a number of tests that use an embedded broker for testing. Whilst we use a base case to handle startup shutdown you could do the following to simply integrate a broker within your tests:
public void setUp()
{
int port=1;
// Config is actually a Configuaration File App Registry object, or Configuration Application Registry.
ApplicationRegistry.initialise(config, port);
TransportConnection.createVMBroker(port);
}
public void test()
{...}
public void tearDown()
{
TransportConnection.killVMBroker(port);
ApplicationRegistry.remove(port);
}
Then for the connection you need to specify the conectionURL for the broker. i.e. borkerlist='vm://1'
My solution on qpid-broker # 6.1.1, add below to pom.xml
<dependency>
<groupId>org.apache.qpid</groupId>
<artifactId>qpid-broker</artifactId>
<version>6.1.1</version>
<scope>test</scope>
</dependency>
qpid config file as:
{
"name" : "${broker.name}",
"modelVersion" : "6.1",
"defaultVirtualHost" : "default",
"authenticationproviders" : [ {
"name" : "anonymous",
"type" : "Anonymous"
} ],
"ports" : [ {
"name" : "AMQP",
"port" : "${qpid.amqp_port}",
"authenticationProvider" : "anonymous",
"virtualhostaliases" : [ {
"name" : "defaultAlias",
"type" : "defaultAlias"
} ]
} ],
"virtualhostnodes" : [ {
"name" : "default",
"type" : "JSON",
"defaultVirtualHostNode" : "true",
"virtualHostInitialConfiguration" : "{ \"type\" : \"Memory\" }"
} ]
}
code to start the qpid server
Broker broker = new Broker();
BrokerOptions brokerOptions = new BrokerOptions();
// I use fix port number
brokerOptions.setConfigProperty("qpid.amqp_port", "20179");
brokerOptions.setConfigurationStoreType("Memory");
// work_dir for qpid's log, configs, persist data
System.setProperty("qpid.work_dir", "/tmp/qpidworktmp");
// init config of qpid. Relative path for classloader resource or absolute path for non-resource
System.setProperty("qpid.initialConfigurationLocation", "qpid/qpid-config.json");
brokerOptions.setStartupLoggedToSystemOut(false);
broker.startup(brokerOptions);
code to stop qpid server
broker.shutdown();
Since I use anonymouse mode, client should do like:
SaslConfig saslConfig = new SaslConfig() {
public SaslMechanism getSaslMechanism(String[] mechanisms) {
return new SaslMechanism() {
public String getName() {
return "ANONYMOUS";
}
public LongString handleChallenge(LongString challenge, String username, String password) {
return LongStringHelper.asLongString("");
}
};
}
};
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("localhost");
factory.setPort(20179);
factory.setSaslConfig(saslConfig);
Connection connection = factory.newConnection();
Channel channel = connection.createChannel();
That's all.
A little more on how to do it on other version.
You can download qpid-broker binary package from official site. After download and unzip, you can run it to test as server against your case. After your case connected server well, using commandline to generate or just copy the initial config file in QPID_WORK, remove useless id filed and use it for embedded server like above.
The most complicated thing is the authentication. You can choose PLAIN mode but you have to add the username and password in initial config. I choose anonymous mode which need a little code when connecting. For other authentication mode you have specify the password file or key/cert store, which I didnt try.
If it still not working, you can read the qpid-borker doc and Main class code in qpid-broker artifact which show how command line works for each settings.
The best I could figure out was:
PropertiesConfiguration properties = new PropertiesConfiguration();
properties.addProperty("virtualhosts.virtualhost.name", "test");
properties.addProperty("security.principal-databases.principal-database.name", "testPasswordFile");
properties.addProperty("security.principal-databases.principal-database.class", "org.apache.qpid.server.security.auth.database.PropertiesPrincipalDatabase");
ServerConfiguration config = new ServerConfiguration(properties);
ApplicationRegistry.initialise(new ApplicationRegistry(config) {
#Override
protected void createDatabaseManager(ServerConfiguration configuration) throws Exception {
Properties users = new Properties();
users.put("guest","guest");
users.put("admin","admin");
_databaseManager = new PropertiesPrincipalDatabaseManager("testPasswordFile", users);
}
});
TransportConnection.createVMBroker(ApplicationRegistry.DEFAULT_INSTANCE);
With a URL of:
amqp://admin:admin#/test?brokerlist='vm://:1?sasl_mechs='PLAIN''
The big pain is with configuration and authorization. Milage may vary.

Categories