Spring Cloud Stream Processor Unit Testing - #Autowire not working - spring

I am trying to write a spring cloud stream processor class that takes an XML in through using the #StreamListener(Processor.INPUT) annotation.
The processor then extracts smaller XML messages and sends them to the output via this.processor.output().send(message);
I have not yet deployed this to dataflow because I wanted to test it with junit. When I run this with junit I can not seem to get my Processor object to instantiate.
I have tried using #Autowired which is how I have seen it done in may examples but I can't seem to get it to work. Any ideas would be appreciated.
My code is below.
package io.spring.dataflow.sample.usagecostprocessor;
import java.io.File;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.stream.annotation.EnableBinding;
import org.springframework.cloud.stream.annotation.StreamListener;
import org.springframework.cloud.stream.messaging.Processor;
import org.springframework.messaging.Message;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.stereotype.Component;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import lombok.AllArgsConstructor;
#AllArgsConstructor
#EnableBinding(Processor.class)
public class REDACTXMLSplitter {
private Processor processor;
//#Autowired
//private SendingBean sendingBean;
#SuppressWarnings("unchecked")
#StreamListener(Processor.INPUT)
public void parseForREDACTApplications(String redactXML) {
InputSource doc = new InputSource( new StringReader( redactXML ) );
try
{
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true); // never forget this!
XPathFactory xfactory = XPathFactory.newInstance();
XPath xpath = xfactory.newXPath();
String xpathQuery = "//REDACT/Application";
xpath = xfactory.newXPath();
XPathExpression query = xpath.compile(xpathQuery);
NodeList productNodesFiltered = (NodeList) query.evaluate(doc, XPathConstants.NODESET);
for (int i=0; i<productNodesFiltered.getLength(); ++i)
{
Document suppXml = dBuilder.newDocument();
//we have to recreate the root node <products>
Element root = suppXml.createElement("REDACT");
Node productNode = productNodesFiltered.item(i);
//we append a product (cloned) to the new file
Node clonedNode = productNode.cloneNode(true);
suppXml.adoptNode(clonedNode); //We adopt the orphan :)
root.appendChild(clonedNode);
suppXml.appendChild(root);
//write out files
//At the end, we save the file XML on disk
// TransformerFactory transformerFactory = TransformerFactory.newInstance();
// Transformer transformer = transformerFactory.newTransformer();
// transformer.setOutputProperty(OutputKeys.INDENT, "yes");
// DOMSource source = new DOMSource(suppXml);
// StreamResult result = new StreamResult(new File("test_" + i + ".xml"));
// transformer.transform(source, result);
TransformerFactory tf = TransformerFactory.newInstance();
Transformer transformer = tf.newTransformer();
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
StringWriter writer = new StringWriter();
transformer.transform(new DOMSource(suppXml), new StreamResult(writer));
String output = writer.getBuffer().toString().replaceAll("\n|\r", "");
System.out.println(output);
Message<String> message = (Message<String>) suppXml;
this.processor.output().send(message);
}
}
catch (XPathExpressionException | ParserConfigurationException | TransformerException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
package io.spring.dataflow.sample.usagecostprocessor;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
#SpringBootApplication
public class REDACTXMLSplitterApplication {
public static void main(String[] args) {
SpringApplication.run(REDACTXMLSplitterApplication.class, args);
}
}
package io.spring.dataflow.sample.usagecostprocessor;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.stream.messaging.Processor;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.util.ResourceUtils;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
#RunWith(SpringRunner.class)
#SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
#DirtiesContext
public class MAIPXMLSplitterApplicationTests {
#Autowired
private Processor myProcessor;
#Test
public void contextLoads() {
}
#Test
public void parseXML() {
try {
String cmErrorPayloadXML = readFile(ResourceUtils.getFile(this.getClass().getResource("/XMLSamples/REDACTApplicationXMLSamples/redact.xml")));
REDACTXMLSplitter redactXMLSplitter = new REDACTXMLSplitter(myProcessor);
redactXMLSplitter.parseForREDACTApplications(cmErrorPayloadXML);
} catch (IOException e) {
e.printStackTrace();
}
}
public String readFile(File file) {
StringBuffer stringBuffer = new StringBuffer();
if (file.exists())
try {
//read data from file
FileInputStream fileInputStream = new FileInputStream(file);
int c;
while ((c = fileInputStream.read()) != -1){
stringBuffer.append((char) c);
}
} catch (IOException e) {
e.printStackTrace();
}
return stringBuffer.toString();
}
}
Update,
I tried this but myProcessor is still null
package io.spring.dataflow.sample.usagecostprocessor;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.stream.annotation.EnableBinding;
import org.springframework.cloud.stream.messaging.Processor;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.util.ResourceUtils;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
#RunWith(SpringRunner.class)
#SpringBootTest(classes = MAIPXMLSplitterApplicationTests.TestProcessor.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class MAIPXMLSplitterApplicationTests {
#Autowired
private Processor myProcessor;
#Test
public void contextLoads() {
}
#Test
public void parseXML() {
try {
String cmErrorPayloadXML = readFile(ResourceUtils.getFile(this.getClass().getResource("/XMLSamples/MAIPApplicationXMLSamples/354_20191126_MAIP.xml")));
MAIPXMLSplitter maipXMLSplitter = new MAIPXMLSplitter(myProcessor);
maipXMLSplitter.parseForMAIPApplications(cmErrorPayloadXML);
} catch (IOException e) {
e.printStackTrace();
}
}
public String readFile(File file) {
StringBuffer stringBuffer = new StringBuffer();
if (file.exists())
try {
//read data from file
FileInputStream fileInputStream = new FileInputStream(file);
int c;
while ((c = fileInputStream.read()) != -1){
stringBuffer.append((char) c);
}
} catch (IOException e) {
e.printStackTrace();
}
return stringBuffer.toString();
}
#EnableBinding(Processor.class)
#EnableAutoConfiguration
public static class TestProcessor {
}
}

You need to have #EnableBinding(Processor.class) in one of the configuration classes used by the Test class.
Typically, you can have a simple #Configuration subclass and have it part of the #SpringBootTest classes list. You can see an example here

Related

Spring boot Kafka integration test: Consumer always returns 0 records

For the following test I am always getting the error:
org.opentest4j.AssertionFailedError: expected: 10 but was : 0
What exactly I am trying to verify in scope of the test:
I am trying to send 10 messages to Kafka and after that immediately I am trying to read those messages from Kafka, but for some unknown reason KafkaConsumer returns 0 records, and I am struggling to understand why Consumer can't read messages that were sent earlier?
import lombok.extern.slf4j.Slf4j;
import org.apache.kafka.clients.consumer.ConsumerConfig;
import org.apache.kafka.clients.consumer.ConsumerRecords;
import org.apache.kafka.clients.consumer.KafkaConsumer;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.kafka.KafkaProperties;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.ContextConfiguration;
import java.time.Duration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ExecutionException;
import java.util.stream.IntStream;
#SpringBootTest
#ActiveProfiles("test")
#ContextConfiguration(initializers = TestKafkaContextInitializer.class)
#Slf4j
public class KafkaFlowVerificationITest {
#Autowired
private KafkaTemplate<String, String> kafkaTemplate;
#Autowired
private KafkaProperties kafkaProperties;
private final String kafkaTopic = "test.topic";
#Test
void testKafkaFlow() {
IntStream.range(0, 10)
.forEach(e -> {
try {
kafkaTemplate.send(kafkaTopic, UUID.randomUUID().toString()).get();
} catch (InterruptedException | ExecutionException ex) {
ex.printStackTrace();
}
});
checkKafkaForMessage();
}
private void checkKafkaForMessage() {
Map<String, Object> properties = new HashMap<>();
properties.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, kafkaProperties.getBootstrapServers());
properties.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, org.apache.kafka.common.serialization.StringDeserializer.class);
properties.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, org.apache.kafka.common.serialization.StringDeserializer.class);
properties.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest");
properties.put(ConsumerConfig.ENABLE_AUTO_COMMIT_CONFIG, "false");
properties.put(ConsumerConfig.GROUP_ID_CONFIG, "acme");
KafkaConsumer<String, String> consumer = new KafkaConsumer<>(properties);
consumer.subscribe(List.of(kafkaTopic));
ConsumerRecords<String, String> records = consumer.poll(Duration.ZERO);
Assertions.assertThat(records.count()).isEqualTo(10);
}
}
and TestKafkaContextInitializer:
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.test.util.TestPropertyValues;
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.ConfigurableApplicationContext;
import org.testcontainers.containers.KafkaContainer;
import org.testcontainers.utility.DockerImageName;
#Slf4j
public class TestKafkaContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
private final KafkaContainer kafkaContainer =
new KafkaContainer(DockerImageName.parse("confluentinc/cp-kafka:5.4.3"));
#Override
public void initialize(ConfigurableApplicationContext configurableApplicationContext) {
kafkaContainer.start();
var values = TestPropertyValues.of(
"spring.kafka.producer.bootstrap-servers=" + kafkaContainer.getBootstrapServers(),
"spring.kafka.consumer.bootstrap-servers=" + kafkaContainer.getBootstrapServers()
);
values.applyTo(configurableApplicationContext);
}
}
The root cause of the issue is:
I set TestContainer Kafka bootstrap server url for the following properties:
spring.kafka.producer.bootstrap-servers
spring.kafka.consumer.bootstrap-servers
but in the test I use:
spring.kafka.bootstrap-servers property, that why Consumer made attempt connect to localhost:9092 default URL instead of URL provided by TestContainer.

Implementing JUnit test cases in Spring batch Jobs calling from Controller

I am new to Junit. I am literally struggling to write Junit test cases for my code. I am working with Spring boot, Batch and JPA. I configured Jobs,file read and write in to DB everything working fine. But when it comes to JUnit, I don't even get an idea to write code. Can anyone help me. Below is my code
FileProcessController.java
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobParameter;
import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.batch.core.repository.JobInstanceAlreadyCompleteException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import com.sc.batchservice.model.StatusResponse;
import lombok.extern.slf4j.Slf4j;
#Slf4j
#RestController
#RequestMapping("/fileProcess")
public class FileProcessController {
#Autowired
private JobLauncher jobLauncher;
#Autowired
#Qualifier("euronetFileParseJob")
private Job job;
#GetMapping(path = "/process")
public #ResponseBody StatusResponse process() throws Exception {
try {
Map<String, JobParameter> parameters = new HashMap<>();
parameters.put("date", new JobParameter(new Date()));
jobLauncher.run(job, new JobParameters(parameters));
return new StatusResponse(true);
} catch (Exception e) {
log.error("Exception", e);
Throwable rootException = ExceptionUtils.getRootCause(e);
String errMessage = rootException.getMessage();
log.info("Root cause is instance of JobInstanceAlreadyCompleteException --> "+(rootException instanceof JobInstanceAlreadyCompleteException));
if(rootException instanceof JobInstanceAlreadyCompleteException){
log.info(errMessage);
return new StatusResponse(false, "This job has been completed already!");
} else{
throw e;
}
}
}
}
BatchConfig.java
import org.springframework.batch.core.Job;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.launch.support.RunIdIncrementer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.Resource;
import com.sc.batchservice.model.DetailsDTO;
#Configuration
#EnableBatchProcessing
public class BatchConfig {
private JobBuilderFactory jobBuilderFactory;
#Autowired
public void setJobBuilderFactory(JobBuilderFactory jobBuilderFactory) {
this.jobBuilderFactory = jobBuilderFactory;
}
#Autowired
StepBuilderFactory stepBuilderFactory;
#Value("file:${input.files.location}${input.file.pattern}")
private Resource[] fileInputs;
#Value("${euronet.file.column.names}")
private String filecolumnNames;
#Value("${euronet.file.column.lengths}")
private String fileColumnLengths;
#Value("${input.files.location}")
private String inputFileLocation;
#Value("${input.file.pattern}")
private String inputFilePattern;
#Autowired
FlatFileWriter flatFileWriter;
#Bean
public Job euronetFileParseJob() {
return jobBuilderFactory.get("euronetFileParseJob")
.incrementer(new RunIdIncrementer())
.start(fileStep())
.build();
}
public Step fileStep() {
return stepBuilderFactory.get("fileStep")
.<DetailsDTO, DetailsDTO>chunk(10)
.reader(new FlatFileReader(fileInputs, filecolumnNames, fileColumnLengths))
.writer(flatFileWriter)
.build();
}
}
FlatFileReader.java
import org.springframework.batch.item.file.FlatFileItemReader;
import org.springframework.batch.item.file.MultiResourceItemReader;
import org.springframework.batch.item.file.mapping.BeanWrapperFieldSetMapper;
import org.springframework.batch.item.file.mapping.DefaultLineMapper;
import org.springframework.batch.item.file.mapping.FieldSetMapper;
import org.springframework.batch.item.file.transform.FixedLengthTokenizer;
import org.springframework.core.io.Resource;
import com.sc.batchservice.model.DetailsDTO;
import com.sc.batchservice.util.CommonUtil;
import lombok.extern.slf4j.Slf4j;
#Slf4j
public class FlatFileReader extends MultiResourceItemReader<DetailsDTO> {
public EuronetFlatFileReader(Resource[] fileInputs, String filecolumnNames, String fileColumnLengths) {
setResources(fileInputs);
setDelegate(reader(filecolumnNames, fileColumnLengths));
setStrict(true);
}
private FlatFileItemReader<DetailsDTO> reader(String filecolumnNames, String fileColumnLengths) {
FlatFileItemReader<DetailsDTO> flatFileItemReader = new FlatFileItemReader<>();
FixedLengthTokenizer tokenizer = CommonUtil.fixedLengthTokenizer(filecolumnNames, fileColumnLengths);
FieldSetMapper<DetailsDTO> mapper = createMapper();
DefaultLineMapper<DetailsDTO> lineMapper = new DefaultLineMapper<>();
lineMapper.setLineTokenizer(tokenizer);
lineMapper.setFieldSetMapper(mapper);
flatFileItemReader.setLineMapper(lineMapper);
return flatFileItemReader;
}
/*
* Mapping column data to DTO
*/
private FieldSetMapper<DetailsDTO> createMapper() {
BeanWrapperFieldSetMapper<DetailsDTO> mapper = new BeanWrapperFieldSetMapper<>();
try {
mapper.setTargetType(DetailsDTO.class);
} catch(Exception e) {
log.error("Exception in mapping column data to dto ", e);
}
return mapper;
}
}
I have Writer,Entity and model classes also, But if any example or idea upto this code, I can proceed with those classes.

How can I register JSR-356 Websocket in PAX-Web? (In bundle, not WAR)

I have a problem with the PAX-Web. I've tried to register a Websocket service as declrarative, but it is unaccessible from web. I've tried the given websocket-jsr356-6.0.3.war and it works fine. As I see the WAR file handles differently the org.osgi.service.http.HttpContext. I've tried the following scenarios:
Scenario 1 - OSGi R6 Whiteboard HTTP method
Creating a ServletContextHelper:
package hu.blackbelt.judo.common.rest.regular;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Properties;
import org.apache.felix.scr.annotations.Property;
import org.apache.felix.scr.annotations.Service;
import org.osgi.service.http.context.ServletContextHelper;
import org.osgi.service.http.whiteboard.HttpWhiteboardConstants;
#Component(immediate = true)
#Service(ServletContextHelper.class)
#Properties(value = {
#Property(name = HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_NAME, value = "chat"),
#Property(name = HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_PATH, value = "/test")
})
public class ChatServletContext extends ServletContextHelper {
}
And adding the Websocket Endpoint:
package hu.blackbelt.judo.common.rest.regular;
import lombok.extern.slf4j.Slf4j;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Properties;
import org.apache.felix.scr.annotations.Property;
import org.apache.felix.scr.annotations.Service;
import javax.websocket.EncodeException;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
#Component(immediate = true)
#Service(Object.class)
#Properties(value = {
#Property(name = HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_SELECT,
value = "=(" + HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_NAME + "=chat)")
})
#Slf4j
public class ChatEndpoint {
public static final String ROOM = "room";
#OnOpen
public void onOpen(final Session session, #PathParam(ROOM) final String room) {
LOGGER.info("session openend and bound to room: " + room);
session.getUserProperties().put(ROOM, room);
}
#OnMessage
public void onMessage(final Session session, final ChatMessage chatMessage) {
String room = (String) session.getUserProperties().get(ROOM);
try {
for (Session s : session.getOpenSessions()) {
if (s.isOpen()
&& room.equals(s.getUserProperties().get(ROOM))) {
s.getBasicRemote().sendObject(chatMessage);
}
}
} catch (IOException | EncodeException e) {
LOGGER.warn("onMessage failed", e);
}
}
}
The logs show me that the Endpoint is catched. I've debugged and Pax-Web is registering it.
The log shows the following line:
2017-05-04 02:36:02,698 | INFO | Thread-70 | WebSocketTracker | 330 - org.ops4j.pax.web.pax-web-extender-whiteboard - 6.0.3 | found websocket endpoint!!
But the websocket is unaccessible with the following URL: ws://localost:8181/test/chat/testroom
Scenario 2 - Pax-Web properties on registered HttpContext (with JAX-RS it works)
Creating HttpContext instance: (Utilizing the OSGi given Helper abstract class):
package hu.blackbelt.judo.common.rest.regular;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Properties;
import org.apache.felix.scr.annotations.Property;
import org.apache.felix.scr.annotations.Service;
import org.osgi.service.http.HttpContext;
import org.osgi.service.http.context.ServletContextHelper;
#Component(immediate = true)
#Service(HttpContext.class)
#Properties(value = {
#Property(name = "httpContext.id", value = "chat"),
#Property(name = "httpContext.path", value = "test")
})
public class ChatHttpContext extends ServletContextHelper implements HttpContext {
}
And the Websocket Endpoint:
package hu.blackbelt.judo.common.rest.regular;
import lombok.extern.slf4j.Slf4j;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Properties;
import org.apache.felix.scr.annotations.Property;
import org.apache.felix.scr.annotations.Service;
import org.osgi.service.http.whiteboard.HttpWhiteboardConstants;
import javax.websocket.EncodeException;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
#SuppressWarnings({"checkstyle:missingctor", "checkstyle:illegaltoken"})
#Component(immediate = true)
#Service(Object.class)
#Properties(value = {
#Property(name = "httpContext.id", value = "chat")
})
#ServerEndpoint(value = "/chat/{room}", encoders = ChatMessageEncoder.class, decoders = ChatMessageDecoder.class)
#Slf4j
public class ChatEndpoint {
public static final String ROOM = "room";
#OnOpen
public void onOpen(final Session session, #PathParam(ROOM) final String room) {
LOGGER.info("session openend and bound to room: " + room);
session.getUserProperties().put(ROOM, room);
}
#OnMessage
public void onMessage(final Session session, final ChatMessage chatMessage) {
String room = (String) session.getUserProperties().get(ROOM);
try {
for (Session s : session.getOpenSessions()) {
if (s.isOpen()
&& room.equals(s.getUserProperties().get(ROOM))) {
s.getBasicRemote().sendObject(chatMessage);
}
}
} catch (IOException | EncodeException e) {
LOGGER.warn("onMessage failed", e);
}
}
}
But the websocket is unaccessible with the following URL: ws://localost:8181/test/chat/testroom
How can I achive that webcsocket be available? I do not want to repackage my bundle as WAB. Is there any way?

springboot InputStream

I have a controller
void upload(#RequestParam(value="file", MultiPartFile file, #RequestParam(value = "content", required = false) InputStream stream){}
I never get a handle to InputStream when user uploads a file through Stream.
How do i configure that?
The normal file upload works just fine.
I am sending Bzip2 content to upload and multipart default enabled in springboot.
I do get this error.
Caused by: java.lang.IllegalArgumentException: Could not retrieve
InputStream for class path resource [BZh91AY&SY90WT�A�%L
!���!��9D�����ܑN�$�L��]:
at
org.springframework.beans.propertyeditors.InputStreamEditor.setAsText(InputStreamEditor.java:77)
at
org.springframework.beans.TypeConverterDelegate.doConvertTextValue(TypeConverterDelegate.java:449)
at
org.springframework.beans.TypeConverterDelegate.doConvertValue(TypeConverterDelegate.java:422)
at
org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:195)
at
org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:107)
at
org.springframework.beans.TypeConverterSupport.doConvert(TypeConverterSupport.java:64)
Controller
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.Authentication;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import com.flasher.service.ImageService;
#RestController
public class ImageControllerRest {
#Autowired
ImageService imageService;
#PostMapping("/upload_img")
public ResponseEntity<?> uploadImage(#RequestParam("file") MultipartFile file, Authentication authentication) {
try {
imageService.store(file, authentication.getName());
return new ResponseEntity<>(HttpStatus.OK);
} catch (Exception e) {
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
}
}
}
Service
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import com.flasher.util.UUIDGenerator;
#Service
public class ImageService {
#Value("${flasher.absolute.img.path}")
String imageUploadPath;
#Autowired
UUIDGenerator uuidGenerator;
public void store(MultipartFile file, String username) {
try {
File uploadFolder = new File(imageUploadPath+username);
if (!uploadFolder.exists()) {
uploadFolder.mkdirs();
}
Files.copy(file.getInputStream(),
Paths.get(uploadFolder.getAbsolutePath()).resolve(uuidGenerator.generateUUID()+"."+file.getContentType().split("/")[1]));
} catch (IOException e) {
e.printStackTrace();
}
}
}
You can achive file upload by this way

How to call a webservice in spring from the jersey client program

I have written the client program using the jersey framework but my webservice is of different project which uses spring framework. So I want to write the webservice using spring . When I wrote it something is going wrong .The webservice is not getting called.
Here is my code
ModelerServiceClient.java is written using jersey
ModelerServiceClient.java
package com.tcs.DataShare.Client;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.UriBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.WebResource;
import com.sun.jersey.api.client.config.ClientConfig;
import com.sun.jersey.api.client.config.DefaultClientConfig;
//import com.tcs.srl.smart.utility.PropertyReader;
import com.tcs.ngps.sip.modeler.utils.ProductConfiguration;
public class ModelerServiceClient {
static final Logger LOGGER = LoggerFactory
.getLogger(DataShareServiceClient.class);
private WebResource service;
private ClientResponse response;
private String serviceName;
private String vmAddress;
private String portNumber;
private String WAR_FILE_NAME_DATASHARE;
public ModelerServiceClient() {
try {
serviceName = "BPIngestorAppaaS";
vmAddress = ProductConfiguration
.getStringValueForProductProperty("vmAddress");
portNumber = ProductConfiguration
.getStringValueForProductProperty("portNumber");
System.out
.println("vm address:" + vmAddress + "port:" + portNumber);
ClientConfig config = new DefaultClientConfig();
Client client = Client.create(config);
WAR_FILE_NAME_DATASHARE = ProductConfiguration
.getStringValueForProductProperty("WAR_FILE_NAME_DATASHARE");
service = client.resource(UriBuilder.fromUri(
"http://" + vmAddress + ":" + portNumber + "/"
+ WAR_FILE_NAME_DATASHARE).build());
System.out.println("war name is: "+WAR_FILE_NAME_DATASHARE);
System.out.println("URL is: "+service);
} catch (NullPointerException nullex) {
LOGGER.error("Error occured - " + nullex.getMessage());
} catch (Exception ex) {
LOGGER.error("" + ex);
}
}
public ModelerServiceClient(String localhost, String port,
String serviceName) {
this.vmAddress = localhost;
this.portNumber = port;
this.serviceName = serviceName;
System.out.println("vm address:" + vmAddress + "port:" + portNumber);
ClientConfig config = new DefaultClientConfig();
Client client = Client.create(config);
WAR_FILE_NAME_DATASHARE = ProductConfiguration
.getStringValueForProductProperty("WAR_FILE_NAME_DATASHARE");
service = client.resource(UriBuilder.fromUri(
"http://" + vmAddress + ":" + portNumber + "/" + WAR_FILE_NAME_DATASHARE)
.build());
LOGGER.debug("WAR_FILE_NAME in the client program"+WAR_FILE_NAME_DATASHARE);
System.out.println("In the data share constructor"+WAR_FILE_NAME_DATASHARE);
System.out.println("service is" + service);
}
public HashMap createTable(String folderToBeZipped) {
LOGGER.debug("DataShareServiceClient :: zipFolder() : Calling zipFolderWithSubsequestFolder Service -> folderToBeZipped: "
+ folderToBeZipped);
HashMap map=new HashMap();
LOGGER.debug("before webservice ");
System.out.println("in the create table method in modelerServiceClient class");
response = service.path("dataModeler").path("ModelerService")
.path("createTablesFromEntity")
.type(MediaType.APPLICATION_JSON)
.post(ClientResponse.class, folderToBeZipped);
System.out.println("After calling response,in the create table method in modelerServiceClient class");
LOGGER.debug("INSIDE THE ZIP METHOD FOR CHECKING ZIP METHOD");
LOGGER.debug("after webservice ");
// InputStream inputStream = response.getEntityInputStream();
LOGGER.debug("DataShareServiceClient :: createTable() : Calling createTable() Service done");
return map;
}
}
DataShareCentralController.java is in spring
DataShareCentralController.java
package com.tcs.ngps.sip.restservices.controllers;
import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
import java.io.IOException;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import org.apache.log4j.Logger;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import org.quartz.JobDataMap;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.ee.servlet.QuartzInitializerListener;
import org.quartz.impl.StdSchedulerFactory;
import org.quartz.impl.matchers.GroupMatcher;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import com.tcs.ngps.sip.model.ModelerResponse;
import com.tcs.ngps.sip.modeler.Services.DataIngestionServices;
import com.tcs.ngps.sip.modeler.constants.IngesterConstants;
import com.tcs.ngps.sip.modeler.constants.ModelerConstants;
import com.tcs.ngps.sip.modeler.enumeration.TechnologyServices;
import com.tcs.ngps.sip.modeler.ingester.CreateTableUsingEntityJson;
import com.tcs.ngps.sip.modeler.tracker.StatusActivityTracker;
import com.tcs.ngps.sip.modeler.utils.Utilities;
import com.tcs.ngps.sip.restservices.viewmodels.AnalysisInputModel;
//import com.tcs.ngps.sip.Services.CIServices;
/*
import com.tcs.ngps.sip.Services.SearchServices;
import com.tcs.ngps.sip.commonUtitlities.CommonUtilities;
import com.tcs.ngps.sip.constants.RequestConstants;
import com.tcs.ngps.sip.model.RequestModel;
import com.tcs.ngps.sip.model.ResponceModel;
*/
import com.tcs.ngps.sip.restservices.viewmodels.ResponseModel;
//#Path("/ModelerService")
#RestController
#EnableWebMvc
public class DataShareCentralController {
static Logger logger = Logger.getLogger(ModelerCentralController.class);
DataShareCentralController()
{
System.out.println("In the DataShareCentralController ");
}
// #Path("/createTablesFromEntity")
//#POST
//#Produces("application/json")
#ResponseBody
#RequestMapping(value="/ModelerService/createTablesFromEntity", method= RequestMethod.GET,produces = APPLICATION_JSON_VALUE)
public void CreateTableFromEntity(#Context HttpServletRequest requestObj,String serviceData )
{
System.out.println("done dana done");
JSONParser parser = new JSONParser();
JSONObject object = new JSONObject();
try {
System.out.println("in the controller");
JSONObject serviceJSON = (JSONObject) parser.parse(serviceData);
String datashareURL = (String) serviceJSON
.get(ModelerConstants.DATASHARE_URL);
CreateTableUsingEntityJson createTableUsingEntityJson=new CreateTableUsingEntityJson();
createTableUsingEntityJson.getData();
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Please help me in resolving the issue....

Resources