package demo;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
import org.springframework.cloud.sleuth.sampler.AlwaysSampler;
import org.springframework.cloud.stream.annotation.EnableBinding;
import org.springframework.cloud.stream.annotation.Output;
import org.springframework.cloud.stream.messaging.Source;
import org.springframework.context.annotation.Bean;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.hateoas.Resources;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.support.MessageBuilder;
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.RestController;
import org.springframework.web.client.RestTemplate;
import java.util.Collection;
import java.util.Collections;
import java.util.stream.Collectors;
@EnableBinding(Source.class)
@EnableZuulProxy
@EnableCircuitBreaker
@EnableDiscoveryClient
@SpringBootApplication
public class DemoApplication {
@Bean
AlwaysSampler alwaysSampler() {
return new AlwaysSampler();
}
@Bean
CommandLineRunner runner(DiscoveryClient dc) {
return args ->
dc.getInstances("reservation-service")
.forEach(si -> System.out.println(String.format(
"%s %s:%s", si.getServiceId(), si.getHost(), si.getPort())));
}
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
@RestController
@RequestMapping("/reservations")
class ReservationApiGatewayRestController {
@Autowired
@LoadBalanced
private RestTemplate rt;
@Autowired
@Output(Source.OUTPUT)
private MessageChannel out;
public Collection<String> getReservationNamesFallback() {
return Collections.emptyList();
}
@RequestMapping(method = RequestMethod.POST)
public void accept(@RequestBody Reservation reservation) {
Message<String> build =
MessageBuilder.withPayload(reservation.getReservationName()).build();
this.out.send(build);
}
@RequestMapping("/names")
@HystrixCommand(fallbackMethod = "getReservationNamesFallback")
public Collection<String> getReservationNames() {
ParameterizedTypeReference<Resources<Reservation>> parameterizedTypeReference =
new ParameterizedTypeReference<Resources<Reservation>>() {
};
ResponseEntity<Resources<Reservation>> exchange = rt.exchange(
"http://reservation-service/reservations", HttpMethod.GET, null, parameterizedTypeReference);
return exchange
.getBody()
.getContent()
.stream()
.map(Reservation::getReservationName)
.collect(Collectors.toList());
}
}
class Reservation {
private Long id;
private String reservationName;
public Long getId() {
return id;
}
public String getReservationName() {
return reservationName;
}
}