Hystrix Dashboard Issue in Spring Boot - spring

I am new to Hystrix Dashboard. I have written sample application with Hystrix.
I want to see the Hystrix chart (command metric stream). But I am getting the below error:
Circuit: Unable to connect to Command Metric Stream
Thread Pools: Loading...
I am using STS with Maven.
Below is the code used:
Simple server microservice application (Spring boot web running in port 8085)
package hello;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.RequestMapping;
#RestController
#SpringBootApplication
public class BookstoreApplication {
#RequestMapping(value = "/recommended")
public String readingList(){
return "Spring in Action (Manning), Cloud Native Java (O'Reilly), Learning Spring Boot (Packt)";
}
public static void main(String[] args) {
SpringApplication.run(BookstoreApplication.class, args);
}
}
Simple client microservice application (Spring boot web running in port 8095) I have included the dependency of Hystrix and Hystrix Dashboard along with Web, so all the Hystrix dependencies are in classpath
package hello;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import java.net.URI;
#Service
public class BookService {
private final RestTemplate restTemplate;
public BookService(RestTemplate rest) {
this.restTemplate = rest;
}
#HystrixCommand(fallbackMethod = "reliable")
public String readingList() {
URI uri = URI.create("http://localhost:8090/recommended");
return this.restTemplate.getForObject(uri, String.class);
}
public String reliable() {
return "Cloud Native Java (O'Reilly)";
}
}
package hello;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.web.client.RestTemplate;
#EnableHystrixDashboard
#EnableHystrix
#EnableCircuitBreaker
#RestController
#SpringBootApplication
public class ReadingApplication {
#Autowired
private BookService bookService;
#Bean
public RestTemplate rest(RestTemplateBuilder builder) {
return builder.build();
}
#RequestMapping("/to-read")
public String toRead() {
return bookService.readingList();
}
public static void main(String[] args) {
SpringApplication.run(ReadingApplication.class, args);
}
}
By running the above code, the hystrix is working fine, when the BooKStoreApplication is down, it is going to fallback method.
Both the urls are working fine.
Normal Case:
http://localhost:8085/recommended
Output: Spring in Action (Manning), Cloud Native Java (O'Reilly), Learning Spring Boot (Packt)
http://localhost:8095/to-read
Output: Spring in Action (Manning), Cloud Native Java (O'Reilly), Learning Spring Boot (Packt)
When BookStoreApplication is down (http://localhost:8085/recommended) accessing http://localhost:8095/to-read returns "Cloud Native Java (O'Reilly)" as expected.
But when I tried to invoke this url http://localhost:8095/hystrix, I am getting the Hystrix DashBoard Page and asking for the stream value.
I have tried given http://localhost:8095/ or http://localhost:8095/to-read, and clicked "Monitor Stream" and it is going to next page with error:
Circuit: Unable to connect to Command Metric Stream
Thread Pools: Loading...

I've experienced the same. The main problem was, that I didn't have the actuator dependency in my maven pom. So I could not get the hystrix stream.
Include the spring-boot-actuator.
Check if localhost:8085/health is running.
Try to enter localhost:8085/hystrix.stream to stream value in Hystrix Dashboard.
Execute the service few times -> the dashboard should show the monitored method/command.

Related

Spring Cloud APIGW and Open API Specification Integration issues

I am looking to develop a Spring Cloud APIGW and Open API Specification Integration example. I am following: https://piotrminkowski.com/2018/04/26/quick-guide-to-microservices-with-spring-boot-2-0-eureka-and-spring-cloud/, but use all latest dependency of Spring Boot which is 2.7.0
http://localhost:8011/swagger-ui.html is not working
gateway.properties
server.port=8011
spring.application.name=api-gateway
eureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka
spring.config.import=configserver:http://localhost:8012/
spring.cloud.gateway.discovery.locator.enabled=true
spring.cloud.gateway.discovery.locator.lower-case-service-id=true
# Actuator
# https://docs.spring.io/spring-boot/docs/current/reference/html/actuator.html#actuator.enabling
management.endpoint.gateway.enabled=true
management.endpoints.web.exposure.include=beans, health, metrics, mappings, env, info,configprops, caches, gateway
# All Microservices Routes
spring.cloud.gateway.routes[0].id=organization-service
spring.cloud.gateway.routes[0].uri=lb://organization-service
spring.cloud.gateway.routes[0].predicates[0]=Path=/organization/**
spring.cloud.gateway.routes[0].predicates[1]=Method=GET,POST,PUT,DELETE
spring.cloud.gateway.routes[1].id=department-service
spring.cloud.gateway.routes[1].uri=lb://department-service
spring.cloud.gateway.routes[1].predicates[0]=Path=/department/**
spring.cloud.gateway.routes[1].predicates[1]=Method=GET,POST,PUT,DELETE
spring.cloud.gateway.routes[2].id=employee-service
spring.cloud.gateway.routes[2].uri=lb://employee-service
spring.cloud.gateway.routes[2].predicates[0]=Path=/employee/**
spring.cloud.gateway.routes[2].predicates[1]=Method=GET,POST,PUT,DELETE
spring.cloud.gateway.routes[3].id=openapi
spring.cloud.gateway.routes[3].uri=http://localhost:${server.port}
spring.cloud.gateway.routes[3].predicates[0]=Path=/v3/api-docs/**
spring.cloud.gateway.routes[3].predicates[1]=Method=GET,POST,PUT,DELETE
spring.cloud.gateway.routes[4].id=openapi2
spring.cloud.gateway.routes[4].uri=http://localhost:${server.port}
spring.cloud.gateway.routes[4].predicates[0]=Path=/webjars/**
spring.cloud.gateway.routes[4].predicates[1]=Method=GET,POST,PUT,DELETE
# Open API Specification
springdoc.swagger-ui.urls[0].name=employee
springdoc.swagger-ui.urls[0].url=/v3/api-docs/employee
springdoc.swagger-ui.urls[1].name=department
springdoc.swagger-ui.urls[1].url=/v3/api-docs/department
springdoc.swagger-ui.urls[2].name=organization
springdoc.swagger-ui.urls[2].url=/v3/api-docs/organization
server.max-http-header-size=2000000
MainApp.java
package com.example.demo;
import java.util.ArrayList;
import java.util.List;
import org.springdoc.core.GroupedOpenApi;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.gateway.route.RouteDefinition;
import org.springframework.cloud.gateway.route.RouteDefinitionLocator;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.context.annotation.Bean;
#EnableEurekaClient
#SpringBootApplication
public class GatewayServiceApplication {
public static void main(String[] args) {
SpringApplication.run(GatewayServiceApplication.class, args);
}
#Autowired
RouteDefinitionLocator locator;
#Bean
public List<GroupedOpenApi> apis() {
List<GroupedOpenApi> groups = new ArrayList<>();
List<RouteDefinition> definitions = locator.getRouteDefinitions().collectList().block();
assert definitions != null;
definitions.stream().filter(routeDefinition -> routeDefinition.getId().matches(".*-service")).forEach(routeDefinition -> {
String name = routeDefinition.getId().replaceAll("-service", "");
groups.add(GroupedOpenApi.builder().pathsToMatch("/" + name + "/**").group(name).build());
});
return groups;
}
}
Note: I am showing for 1 microservice, I've done almost same for others
application.properties
server.port=${PORT:0}
spring.application.name=employee-service
spring.config.import=configserver:http://localhost:8012/
eureka.client.fetch-registry=true
eureka.client.register-with-eureka=true
springdoc.packages-to-scan=com.example.demo
and Added below to entry service main app.
MainApp.java
#OpenAPIDefinition(info = #Info(title = "Employee API", version = "1.0", description = "Documentation Employee API v1.0"))
#EnableEurekaClient
#SpringBootApplication
public class EmployeeServiceApplication {
public static void main(String[] args) {
SpringApplication.run(EmployeeServiceApplication.class, args);
}
}

How to close spring boot with routing properly

I'm trying to use a routing to stop my spring boot application with the code below
with
#GetMapping("/close/")
fun terminate() {
exitProcess(0)
}
but the test server has a different API, so I can't use this code (It's shutdown a whole system)
My question is: how to stop only my spring boot application (replace exitProcess(0))
You can do it using Actuator's shutdown for example.
Find an example here.
Or you can just close your Application Context and that will work.
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
#RestController
public class SomeRestController {
#Autowired
ApplicationContext applicationContext;
#GetMapping("/close")
public void terminate() {
((AbstractApplicationContext)applicationContext).close();
}
}

How do i connect my webMethods REStful service to my spring boot application

All i wanted to know is that if i have a flow service in SoftwareAG webMethods and i have converted it into a REStful service by making a rest resource and i have exposed it, so how do i make a call to that service via a spring boot appplication.
This is my code for the my spring application, Can someone please suggest me that how do i make a rest call to a webMethods Rest Resource flow service which is already been exposed.
A quick help is appreciated.
package com.scb.controller;
import java.util.ArrayList;
import java.util.List;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import com.scb.entity.ReadingEntity;
import java.util.concurrent.atomic.AtomicLong;
#RestController
public class PreProcessorController {
private List<ReadingEntity> myEntity=new ArrayList();
private final AtomicLong counter = new AtomicLong();
#GetMapping("/GetData")
public void getData(#RequestBody ReadingSCBMLEntity entity) {
//myEntity.add(entity);
final String uri="http://uklvadapp881.uk.dev.net:5555/invoke/scb.wb.fm.support.flow.ResourceGet/_get?";
RestTemplate template=new RestTemplate();
String result=template.getForObject(uri, String.class);
System.out.println(result);
}
}

Spring Boot REST API not reachable in GCP

I am deploying the Spring Boot Rest API in Google Cloud Platform. The Rest API is running fine in my local while running the application as Spring boot application. But the same REST API URL is not recognized while deploying in GCP.
Project Structure:
app.yaml:
runtime: java
env: flex
runtime_config:
  jdk: openjdk8
handlers:
- url: /.*
script: this field is required, but ignored
GreetingController.java
package com.designdreamers.rest.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.designdreamers.rest.vo.Greeting;
#RestController
public class GreetingController {
private int idValue;
#RequestMapping(value="/greet")
public Greeting greeting(#RequestParam(value="content", defaultValue = "Hello World!!")String content){
Greeting greeting=new Greeting();
greeting.setId(idValue++);
greeting.setContent(content);
return greeting;
}
}
Application.java
package com.designdreamers.rest.main;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
#SpringBootApplication
#ComponentScan(basePackages = "com.designdreamers.rest.controller")
public class Application {
public static void main(String args[]){
SpringApplication.run(Application.class,args);
}
}
Below is the REST API response that I get on running the application as Spring boot application in local.
URL :http://localhost:8080/greet
{"id":1,"content":"Hello World!!"}
I deployed the same application in GCP and on hitting the REST API URI, below is the error that we get.
URI: http://helloworld-001.appspot.com/greet
Error: Not Found
The requested URL /greet was not found on this server.
A helping hand on identifying the issue would be very helpful.

Spring cannot serve end point

I have a simple Spring back-end. It has a folder that contains controllers.
package com.movieseat.controllers;
// Java imports
import java.util.List;
// Spring imports
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
// Project imports
import com.movieseat.models.Movie;
import com.movieseat.services.MovieService;
#RestController
#RequestMapping("/api/movies")
public class MovieController {
#Autowired
private MovieService movieService;
#RequestMapping(value = "/allMovies", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
public List<Movie> getAllMovies() {
return movieService.getAllmovies();
}
}
In my Angular service I have a getAll() method:
public getAll<T>(): Observable<T[]> {
return this.http.get<T[]>('/api/movies/allMovies');
}
When I run the application I get a:
GET http://localhost:8090/api/movies/allMovies 404 ()
I have the server running on port 8090.
The following structure is used:
com
movieseat
Application.java
controllers
MovieController.java
models
MovieModel.java
repositories
MovieRepository.java
services
impl
MovieServiceImpl.java
MovieService.java
See if your controller class is picked up by spring scanning and performs mapping correctly. For example - If you are using Spring Boot, put a #SpringBootApplication on your main class that runs the app. The best way to know if your endpoint is scanned is to look for it when spring launches (in the log). You should look for something like
2017-09-17 14:45:49.522 INFO 2873 --- [main] RequestMappingHandlerMapping : Mapped "{[/allMovies],methods=[GET]}" onto public java.lang.String com.movieseat.controllers.MovieController.getAllMovies...

Resources