Pact JVM also needs install scala and scala related dependencies? - pact

When execute PACT JVM test case, got following error. Actually before this error, there's another scala error, after adding one scala dependency, that issue resolved, but come this one.
java.lang.NoClassDefFoundError: scala/Product$class
at au.com.dius.pact.model.RequestMatching.<init>(RequestMatching.scala:7)
at au.com.dius.pact.model.RequestMatching$.apply(RequestMatching.scala:7)
at au.com.dius.pact.model.RequestMatching.apply(RequestMatching.scala)
at au.com.dius.pact.consumer.BaseMockServer.<init>(MockHttpServer.kt:61)
at au.com.dius.pact.consumer.MockHttpServer.<init>(MockHttpServer.kt:202)
at au.com.dius.pact.consumer.MockHttpServerKt.mockServer(MockHttpServer.kt:34)
at au.com.dius.pact.consumer.ConsumerPactRunnerKt.runConsumerTest(ConsumerPactRunner.kt:12)
at au.com.dius.pact.consumer.ConsumerPactTestMk2.testPact(ConsumerPactTestMk2.java:26)
This is my code:
`public class ContractTest extends ConsumerPactTestMk2 {
#Rule
public PactProviderRuleMk2 mockProvider = new PactProviderRuleMk2("test_provider", "localhost", 5055, this);
#Override
#Pact(provider="test_provider", consumer="test_consumer")
protected RequestResponsePact createPact(PactDslWithProvider builder) {
Map<String, String> headers = new HashMap<String, String>();
headers.put("testreqheader", "testreqheadervalue");
JSONObject updateJsonObj = new JSONObject();
JSONObject updateVersion = new JSONObject();
updateVersion.put("version", "1.4");
updateJsonObj.put("update", updateVersion);
return builder.given("test state 1") // NOTE: Using provider states are optional, you can leave it out
.uponReceiving("ExampleJavaConsumerPactTest test interaction")
.path("/hostService/hosts/1")
.method("PUT")
.body(updateJsonObj)
.willRespondWith()
.status(200)
.body(updateJsonObj)
.given("test state 2") // NOTE: Using provider states are optional, you can leave it out
.uponReceiving("ExampleJavaConsumerPactTest second test interaction")
.method("GET")
.path("/hostService/hosts/1")
.body("")
.willRespondWith()
.status(200)
.body("")
.toPact();
}
#Override
protected String providerName() {
return "test_provider";
}
#Override
protected String consumerName() {
return "test_consumer";
}
#Override
protected void runTest(MockServer mockServer) throws IOException {
HttpClient httpClient = HttpClients.createDefault();
HttpPut putReq = new HttpPut(mockServer.getUrl());
HttpGet getReq = new HttpGet(mockServer.getUrl());
HttpResponse response = httpClient.execute(getReq);
Assert.assertEquals(response.getStatusLine().getStatusCode(), 200);
response = httpClient.execute(putReq);
Assert.assertEquals(getVersion(response.getEntity().toString()), "1.3");
}
`

It looks like the dependencies for version 3.5.5 are a little broken. For now, you have two options:
Work around it by downgrading to version 3.5.4
Include the missing dependencies explicitly. For me, this was:
pact-jvm-matchers_2.12 version 3.5.5 maven link
pact-jvm-model verison 3.5.5 maven link

Related

How to use spring-kafka for sending a message again

We are using spring-kafka 1.2.2.RELEASE.
What we want
1. As soon as a message is consumed and processed successfully, offset is committed in spring-kafka. I am using Manaul Commit/Acknowledgement for it, it is working fine.
2. In case of any exception we want spring-kafka to resend the same message. We are throwing RunTime exception on any system error, which was logged by spring-kafka and never committed.
This is fine as we don't want it to commit, but that message stays in spring-kafka and never comes back unless we restart the service. On restart message comes back and executes once again and then stay in spring-kafka
What we tried
1. I have tried both ErrorHandler and RetryingMessageListenerAdapter, but in both cases we have to code in service how to process the message again
This is my consumer
public class MyConsumer{
#KafkaListener
public void receive(...){
// application logic to return success/failure
if(success){
acknowledgement.acknowledge();
}else{
throw new RunTimeException();
}
}
}
Also I have following configurations for container factory
factory.getContainerProperties().setErrorHandler(new ErrorHandler(){
#Override
public void handle(...){
throw new RunTimeException("");
}
});
While executing the flow, control is coming inside both first to receive and then handle method. After that service waits for new message. However I was expecting, since we threw an exception, and message is not committed, same message should land in receive method again.
Is there any way, we can tell spring kafka "do not commit this message and send it again asap?"
1.2.x is no longer supported; 1.x users are recommended to upgrade to at least 1.3.x (currently 1.3.8) because of its much simpler threading model, thanks to KIP-62.
The current version is 2.2.2.
2.0.1 introduced the SeekToCurrentErrorHandler which re-seeks the failed record so that it is redelivered.
With earlier versions, you had to stop and restart the container to redeliver a failed message, or add retry to the listener adapter.
I suggest you upgrade to the newest possible release.
Unfortunately version available for us to use is 1.3.7.RELEASE.
I have tried implementing the ConsumerSeekAware interface. Below is how I am doing it and I can see message delivering repreatedly
Consumer
public class MyConsumer implements ConsumerSeekAware{
private ConsumerSeekCallback consumerSeekCallback;
if(condition) {
acknowledgement.acknowledge();
}else {
consumerSeekCallback.seek((String)headers.get("kafka_receivedTopic"),
(int) headers.get("kafka_receivedPartitionId"),
(int) headers.get("kafka_offset"));
}
}
#Override
public void registerSeekCallback(ConsumerSeekCallback consumerSeekCallback) {
this.consumerSeekCallback = consumerSeekCallback;
}
#Override
public void onIdleContainer(Map<TopicPartition, Long> arg0, ConsumerSeekCallback arg1) {
LOGGER.debug("onIdleContainer called");
}
#Override
public void onPartitionsAssigned(Map<TopicPartition, Long> arg0, ConsumerSeekCallback arg1) {
LOGGER.debug("onPartitionsAssigned called");
}
}
Config
public class MyConsumerConfig {
#Bean
public Map<String, Object> consumerConfigs() {
Map<String, Object> props = new HashMap<>();
// Set server, deserializer, group id
props.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "latest");
props.put(ConsumerConfig.ENABLE_AUTO_COMMIT_CONFIG, false);
return props;
}
#Bean
public ConcurrentKafkaListenerContainerFactory<String, MyModel> kafkaListenerContainerFactory() {
ConcurrentKafkaListenerContainerFactory<String, MyModel> factory = new ConcurrentKafkaListenerContainerFactory<>();
factory.setConsumerFactory(new DefaultKafkaConsumerFactory<>(consumerConfigs()));
factory.getContainerProperties().setAckMode(AckMode.MANUAL);
return factory;
}
#Bean
public MyConsumer receiver() {
return new MyConsumer();
}
}

Right way to do JMS Application with MDB and Glassfish 3

I am new to JMS and I Wrote a Wrote a sender and receiver and it has worked fine . Now i want a MDB to be used for this. I have googled a lot for this but did not find any good website so i am summering the way i wrote. Please correct me if i am wrong and
This is not completely working so i think there is something wrong in my code.
Sender:
public class MySender {
/**
* #param args
*/
public static void main(String[] args) {
try
{ //Create and start connection
Hashtable hashTable = new Hashtable();
hashTable.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.enterprise.naming.impl.SerialInitContextFactory");
hashTable.put(Context.URL_PKG_PREFIXES, "com.sun.enterprise.naming");
hashTable.put(Context.PROVIDER_URL, "http://localhost:4848");
//1) Create and start connection
InitialContext ctx=new InitialContext(hashTable);
QueueConnectionFactory f=(QueueConnectionFactory)ctx.lookup("myQueueConnectionFactory");
QueueConnection con=f.createQueueConnection();
con.start();
//2) create queue session
QueueSession ses=con.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
//3) get the Queue object
Queue t=(Queue)ctx.lookup("myQueue");
//4)create QueueSender object
QueueSender sender=ses.createSender(t);
//5) create TextMessage object
//5) create TextMessage object
TextMessage msg=ses.createTextMessage();
msg.setText("Hello ************************************");
sender.send(msg);
con.close();
System.out.println("*****************end********************");
}catch(Exception e){System.out.println(e);} }
}
MDB and Listner:
#MessageDriven(mappedName="myQueue")
public class MyListener implements MessageListener {
public void onMessage(Message message) {
try{
if (message != null && TextMessage.class.isInstance(message)) {
System.out.println("((((((((((((((((((((((((((((((((((");
TextMessage msg=(TextMessage)message;
final XStream xsStream = new XStream();
final TextMessage textMessage = (TextMessage) message;
Reader xmlMessage = new StringReader(textMessage.getText());
Object obj = xsStream.fromXML(xmlMessage);
System.out.println("obj:::::::::::"+obj);
if (obj != null && LetterOutHeader.class.isInstance(obj)) {
LetterOutHeader letterObj = (LetterOutHeader)obj;
System.out.println("one:::::::"+letterObj.getState());
}
System.out.println("following message is received::::::::::::::::::"+msg.getText());
}
}catch(JMSException e){System.out.println(e);}
}
}
Have Created a EJB Project, added a class MyListener and has exported that as a jar and have deployed that to the server.
Wrote a normal java application and have added a class MySender.
Run the MySender as a java program.

Retrofit RxJava Simple test

I'm learning Retrofit and RxJava and I'v created test to connect github:
public class GitHubServiceTests {
RestAdapter restAdapter;
GitHubService service;
#Before
public void setUp(){
Gson gson = new GsonBuilder()
.setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES)
.create();
restAdapter = new RestAdapter.Builder()
.setEndpoint("https://api.github.com")
.setConverter(new GsonConverter(gson))
.build();
service = restAdapter.create(GitHubService.class);
}
#Test
public void GitHubUsersListObservableTest(){
service.getObservableUserList().flatMap(Observable::from)
.subscribe(user -> System.out.println(user.login));
}
when I execute test, I see nothing in my console. But when I execute another test
#Test
public void GitHubUsersListTest(){
List<User> users = service.getUsersList();
for (User user : users) {
System.out.println(user.login);
}
it works, and I see user's logins in my console
Here is my Interface for Retrofit:
public interface GitHubService {
#GET("/users")
List<User> getUsersList();
#GET("/users")
Observable<List<User>> getObservableUserList();
}
where I'm wrong?
Because of the asynchronous call your test completes before a result is downloaded. That's typical issue and you have to 'tell' test to wait for the result. In plain java it would be:
#Test
public void GitHubUsersListObservableTest(){
CountDownLatch latch = new CountDownLatch(N);
service.getObservableUserList()
.flatMap(Observable::from)
.subscribe(user -> {
System.out.println(user.login);
latch.countDown();
});
latch.await();
}
Or you can use BlockingObservable from RxJava:
// This does not block.
BlockingObservable<User> observable = service.getObservableUserList()
.flatMap(Observable::from)
.toBlocking();
// This blocks and is called for every emitted item.
observable.forEach(user -> System.out.println(user.login));

Unit Testing I18N RESTful Web Services with Spring, RestTemplate and Java Config

Trying to get Unit Tests to work when using Spring RestTemplate and I18N. Everything in the setup works fine for all the other test cases.
Based upon what I read, this is what I put into the Java Config:
#Bean
public LocaleChangeInterceptor localeChangeInterceptor() {
return new LocaleChangeInterceptor();
}
#Bean
public DefaultAnnotationHandlerMapping handlerMapping() {
DefaultAnnotationHandlerMapping mapping = new DefaultAnnotationHandlerMapping();
Object[] interceptors = new Object[1];
interceptors[0] = new LocaleChangeInterceptor();
mapping.setInterceptors(interceptors);
return mapping;
}
#Bean
public AnnotationMethodHandlerAdapter handlerAdapter() {
return new AnnotationMethodHandlerAdapter();
}
Then in my usage with RestTemplate I have:
public MyEntity createMyEntity(MyEntity bean) {
Locale locale = LocaleContextHolder.getLocale();
String localeString = "";
if (locale != Locale.getDefault()) {
localeString = "?locale=" + locale.getLanguage();
}
HttpEntity<MyEntity> req = new HttpEntity<MyEntity>(bean);
ResponseEntity<MyEntity> response = restTemplate.exchange(restEndpoint + "/url_path" + localeString, HttpMethod.POST, req, MyEntity.class);
return response.getBody();
}
While this could be cleaned up a bit, it should work - but the LocalChangeInterceptor never gets invoked. I am debugging this now and will post again as soon as I figure it out - but in the hope this is a race condition that I lose - does anyone know why?
Was lucky and stumbled upon this thread. One of the notes clued me into the right direction. You don't need all those beans in the Java Config. But if you are using #EnableWebMvc as I am, but I didn't know it was important enough to even mention, all you need to do in your Java Config is:
#Bean
public LocaleChangeInterceptor localeChangeInterceptor() {
return new LocaleChangeInterceptor();
}
#Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LocaleChangeInterceptor());
super.addInterceptors(registry);
}
Add the one bean for the Interceptor and then override the method to add the interceptor. Here my configuration class (annotated with #Configuration and #EnableWebMvc) also extends WebMvcConfigurerAdapter, which should be common usage.
This, at least, worked for me. Hope it may help someone else.

Java junit test change Locale in Spring SimpleFormController

For a SpringMVC, I have a SimpleFormController with a simple method which changes language for user by changing locale (i18n).
//localization
public void localize(HttpServletRequest request, HttpServletResponse response, String language) throws Exception {
LocaleResolver localeResolver = RequestContextUtils.getLocaleResolver(request);
if (localeResolver != null) {
LocaleEditor localeEditor = new LocaleEditor();
localeEditor.setAsText(language);
// set the new locale
localeResolver.setLocale(request, response,
(Locale) localeEditor.getValue());
}
}
And the code works fine while using the app. However I want to do the Junit test for this method and the following is what I have come up with so far:
public class LoginPostControllerTest extends TestCase {
public void testLocalize() throws Exception {
MockHttpServletRequest mockRequest = new MockHttpServletRequest();
MockHttpServletResponse mockResponse = new MockHttpServletResponse();
Locale frenchLocale = Locale.CANADA_FRENCH;
mockRequest.addPreferredLocale(frenchLocale);
SessionLocaleResolver localeResolver = new SessionLocaleResolver();
mockRequest.setAttribute(DispatcherServlet.LOCALE_RESOLVER_ATTRIBUTE, localeResolver);
String language = "zh_CN";
LoginPostController loginPostControllerTest = new LoginPostController();
loginPostControllerTest.localize(mockRequest, mockResponse, language);
System.out.println(mockRequest.getLocale().toString());
}
}
but it prints out "fr_CA" not "zh_CN". Can somebody provide a better Junit test strategy for this?
you need obtain again the localeResolver on your test
LocaleResolver resolver = RequestContextUtils.getLocaleResolver(mockRequest);
System.out.println(mockRequest.getLocale().toString());
System.out.println(resolver.resolveLocale(mockRequest).toString());
assertTrue(!mockRequest.getLocale().equals(resolver.resolveLocale(mockRequest)));

Resources