I am beginner with spring - boot and webservice, I have two exercises to do, they would know How to implement the client and the run () method; to send and receive strings trough In this webservice?
PROJECT CONSUMER
public class Service implements Runnable {
public static void main(String args[]) {
System.out.println("Send the messages....");
Thread thread = new Thread(new Service());
thread.start();
}
public void run() {
// Loop receiving messages
}
}
PROJECT PRODUCER
#Path("/greet")
#Component
public class GreetResource {
static Logger logger = LoggerFactory.getLogger(GreetResource.class);
#Autowired
Client client;
public GreetResource() {
logger.info("Resource Initialized");
}
#GET
#Path("/echo/{msg}")
#Produces({ MediaType.TEXT_PLAIN_VALUE })
public Response echo(#PathParam("msg") String message) {
return Response.ok().entity(message).build();
}
#POST
#Path("/send")
#Consumes({ MediaType.TEXT_PLAIN_VALUE })
public boolean sendMessage(String greeting) {
client.sendAMessage(greeting);
return true;
}
}
PROJECT PRODUCER
#EnableAutoConfiguration
public class Application {
private static final Logger logger = LoggerFactory.getLogger(Application.class);
#Autowired
private Environment env;
#PostConstruct
public void initApplication() throws IOException {
if (env.getActiveProfiles().length == 0) {
logger.warn("No Spring profile configured, running with default configuration");
} else {
logger.info("Running with Spring profile(s) : {}", Arrays.toString(env.getActiveProfiles()));
Collection<String> activeProfiles = Arrays.asList(env.getActiveProfiles());
if (activeProfiles.contains("dev") && activeProfiles.contains("prod")) {
logger.error("You have misconfigured your application! "
+ "It should not run with both the 'dev' and 'prod' profiles at the same time.");
}
}
}
public static void main(String[] args) {
logger.info("weather application service starting...");
SpringApplication.run(Application.class, args);
}
}
PROJECT PRODUCER
import org.springframework.stereotype.Component;
#Component
public class Client {
public boolean sendAMessage(String greeting) {
// Send the message
return false;
}
}
Any tips to implement method run () and sendAMessage()?
If you are using Spring Boot and want to implement web-service , then easiest way is to implement web service using RESTapi.
You can use #ResponseBody or #RestController annotations to expose service.
Related
I want my Spring Boot application to start regardless if it can connect to JMS or not. I have this minimal example:
#SpringBootApplication
#EnableJms
public class JmsActivemqFailoverApplication {
public static void main(String[] args) {
SpringApplication.run(JmsActivemqFailoverApplication.class, args);
}
#Component
public static class JmsReceiver {
#JmsListener(destination = "inbox")
public void receive(Message message) {
System.out.println("Received <" + message + ">");
}
}
#RestController
public static class HelloWorldController {
#GetMapping("/")
public String helloWorld() {
return "Hello world";
}
}
}
when application.properties contains:
spring.activemq.broker-url=tcp://non-existing-broker:61616
I can get response from helloWorld endpoint. When I change property to:
spring.activemq.broker-url=failover:(tcp://non-existing-broker:61616)
Application keeps trying to connect to broker and I can not get response from my REST endpoint.
Please advice, how can I have application running without waiting for ActiveMQ Failover transport to succeed.
Example code available at https://github.com/madoxas/jms-activemq-failover
One way to achieve this is:
Disable automatic JMS container startup with property spring.jms.listener.auto-startup=false
Start JMS container after application has started:
#Component
public class JmsStarter implements ApplicationRunner {
private final JmsListenerEndpointRegistry jmsRegistry;
public JmsStarter(JmsListenerEndpointRegistry jmsRegistry) {
this.jmsRegistry = jmsRegistry;
}
#Override
public void run(ApplicationArguments args) {
for (MessageListenerContainer listenerContainer : jmsRegistry.getListenerContainers()) {
listenerContainer.start();
}
}
}
I'm trying to write a simple WebSocket server app based on on Spring and Netty.
My application looks like this
#SpringBootApplication
public class DemoReactiveWSApp {
public static void main(String[] args) {
SpringApplication.run(DemoReactiveWSApp.class, args);
}
}
with the following configuration
#Configuration
public class WebSocketConfig {
#Bean
public HandlerMapping handlerMapping() {
final Map<String, WebSocketHandler> handlerMap = new HashMap<>();
// will be populated later with routes and handlers
SimpleUrlHandlerMapping mapping = new SimpleUrlHandlerMapping();
mapping.setUrlMap(handlerMap);
mapping.setOrder(-1);
return mapping;
}
#Bean
public RequestUpgradeStrategy requestUpgradeStrategy() {
return new ReactorNettyRequestUpgradeStrategy();
}
}
When I run it, everything boots up, and I can attempt (for now) to establish WS connection.
However, when I want to start it in a test
#SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class DemoReactiveWSAppTest {
#LocalServerPort
private String port;
#Test
public void givenContext_WhenStartingApplication_ThenItLoads() throws InterruptedException {
System.out.println("Port: " + port);
}
}
the server never seems to boot.
Am I forgetting something?
Stupid me, I forgot #RunWith(SpringRunner.class)
I'm in the process of learning how to use the Java Spring Framework and started experimenting with Spring Integration. I'm trying to use Spring Integration to connect my application to an MQTT broker both to publish and subscribe to messages but I'm having trouble finding a way to manually publish messages to an outbound channel. If possible I want to build it using notations in the java code exclusively rather than xml files defining beans and other related configuration.
In every example I've seen the solution to manually publishing a message seems to be to use a MessagingGateway Interface and then use the SpringApplicationBuilder to get the ConfigurableApplicationContext to get a reference to the gateway interface in the main method. The reference is then used to publish a message. Would it be possible to use AutoWired for the interface instead? In my attempts I just get a NullPointer.
My aim is to build a game where I subscribe to a topic to get game messages and then whenever the user is ready to make the next move, publish a new message to the topic.
Update:
This is one of the examples I've been looking at of how to setup an outbound channel: https://docs.spring.io/spring-integration/reference/html/mqtt.html
Update 2 after answer from Gary Russel:
This is some example code I wrote after looking at examples which gets me a NullPointer when using #AutoWired for the Gateway when running gateway.sendToMqtt in Controller.java. What I want to achieve here is to send an mqtt message manually when a GET request is handled by the controller.
Application.java
#SpringBootApplication
public class Application {
public static void main(String[] args){
SpringApplication.run(Application.class, args);
}
}
Controller.java
#RestController
#RequestMapping("/publishMessage")
public class Controller {
#Autowired
static Gateway gateway;
#RequestMapping(method = RequestMethod.GET)
public int request(){
gateway.sendToMqtt("Test Message!");
return 0;
}
}
MqttPublisher.java
#EnableIntegration
#Configuration
public class MqttPublisher {
#Bean
public MqttPahoClientFactory mqttClientFactory(){
DefaultMqttPahoClientFactory factory = new DefaultMqttPahoClientFactory();
factory.setServerURIs("tcp://localhost:1883");
return factory;
}
#Bean
#ServiceActivator(inputChannel = "mqttOutboundChannel")
public MessageHandler mqttOutbound(){
MqttPahoMessageHandler messageHandler =
new MqttPahoMessageHandler("clientPublisher", mqttClientFactory());
messageHandler.setAsync(true);
messageHandler.setDefaultTopic("topic");
return messageHandler;
}
#Bean
public MessageChannel mqttOutboundChannel(){
return new DirectChannel();
}
#MessagingGateway(defaultRequestChannel = "mqttOutboundChannel")
public interface Gateway {
void sendToMqtt(String data);
}
}
Update:
Not sure if this is the proper logging but it is what I get from adding:
logging.level.org.springframework.web=Debug
logging.level.org.hibernate=Error
to application.properties.
https://hastebin.com/cuvonufeco.hs
Use a Messaging Gateway or simply send a message to the channel.
EDIT
#SpringBootApplication
public class So47846492Application {
public static void main(String[] args) {
SpringApplication.run(So47846492Application.class, args).close();
}
#Bean
public ApplicationRunner runner(MyGate gate) {
return args -> {
gate.send("someTopic", "foo");
Thread.sleep(5_000);
};
}
#Bean
#ServiceActivator(inputChannel = "toMqtt")
public MqttPahoMessageHandler mqtt() {
MqttPahoMessageHandler handler = new MqttPahoMessageHandler("tcp://localhost:1883", "foo",
clientFactory());
handler.setDefaultTopic("myTopic");
handler.setQosExpressionString("1");
return handler;
}
#Bean
public MqttPahoClientFactory clientFactory() {
DefaultMqttPahoClientFactory factory = new DefaultMqttPahoClientFactory();
factory.setUserName("guest");
factory.setPassword("guest");
return factory;
}
#Bean
public MqttPahoMessageDrivenChannelAdapter mqttIn() {
MqttPahoMessageDrivenChannelAdapter adapter =
new MqttPahoMessageDrivenChannelAdapter("tcp://localhost:1883", "bar", "someTopic");
adapter.setOutputChannelName("fromMqtt");
return adapter;
}
#ServiceActivator(inputChannel = "fromMqtt")
public void in(String in) {
System.out.println(in);
}
#MessagingGateway(defaultRequestChannel = "toMqtt")
public interface MyGate {
void send(#Header(MqttHeaders.TOPIC) String topic, String out);
}
}
How does one invoke methods in a rest service that is not written in spring or java (its wcf rest service) using JUnit & Spring?
Note: I want to do HTTP-GET so mocking is not the case here.
Does Spring let me use restTemplate.getForObject(..) from JUnit? Cucumber?
So far I have a client written using Spring:
#SpringBootApplication
public class Application {
private static final Logger log = LoggerFactory.getLogger(Application.class);
private static final String SERVICE_URL="http://localhost:12345/PrivilegesService/IsAlive";
public static void main(String args[]) {
SpringApplication.run(Application.class);
}
#Bean
public RestTemplate restTemplate(RestTemplateBuilder builder) {
return builder.build();
}
#Bean
public CommandLineRunner run(RestTemplate restTemplate) throws Exception {
return args -> {
boolean response = restTemplate.getForObject(SERVICE_URL, boolean.class);
log.info("response: "+ response); // print : true
};
}
}
I want my tests look :
public class StepDefinitions {
#When("^application is up$")
public void the_client_issues_GET_version(){
}
#Then("^the server should be running$")
public void the_client_receives_status_code_of() {
boolean response = restTemplate.getForObject(SERVICE_URL, boolean.class);
AssertTrue(true,response);
}
}
RestTemplate works in Junit as well. It doesn't matter if its a source code or test code.
REST is based on HTTP, so it doesn't matter what framework is used to write a REST service. As long as it is a REST service, you should be able to call it
I try to use spring boot and angular spa app. I need to proxy some requests to another server. I've configured zuul proxy with this configuration
zuul.routes.api.path=/api/**
zuul.ignored-patterns=/api/products/**, /api/products-meta, /api/invoices, /api/products
zuul.routes.api.url=http://another-api-server/
It works perfectly in my case, some API are provided by my app, some by another server.
Next one I want to configure redirecting to the index page when user tries to access to my app via direct link, for example, http://localhost/products/1
For this case, I used this IndexController
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
#Controller
public class IndexController {
#RequestMapping("/**")
public String index() {
return "forward:/index.html";
}
}
But I got this error message
And this stack trace
Gist
My main app class
#EnableZuulProxy
#SpringBootApplication
public class Ng2bootApplication {
public static void main(String[] args) {
SpringApplication.run(Ng2bootApplication.class, args);
}
#Bean
public ApiGatewayFilter simpleFilter() {
return new ApiGatewayFilter();
}
}
ApiGatewayFilter just used for logging proxy requests, nothing else.
public class ApiGatewayFilter extends ZuulFilter {
private static Logger log = LoggerFactory.getLogger(ApiGatewayFilter.class);
#Override
public String filterType() {
return "pre";
}
#Override
public int filterOrder() {
return 0;
}
#Override
public boolean shouldFilter() {
return true;
}
#Override
public Object run() {
RequestContext ctx = RequestContext.getCurrentContext();
HttpServletRequest request = ctx.getRequest();
log.info(String.format("%s request to %s", request.getMethod(), request.getRequestURL().toString()));
return null;
}
}