package carve.ribbonconsul;

import java.io.IOException;
import java.nio.charset.StandardCharsets;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;

import org.slf4j.MDC;

import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.netflix.ribbon.ClientOptions;
import com.netflix.ribbon.Ribbon;
import com.netflix.ribbon.http.HttpRequestBuilder;
import com.netflix.ribbon.http.HttpRequestTemplate;
import com.netflix.ribbon.http.HttpResourceGroup;

import io.netty.buffer.ByteBuf;

@Path("/ribbon")
public class RibbonConsulResource {

    private ObjectMapper mapper = new ObjectMapper();

    static {
        System.setProperty("ribbon.NIWSServerListClassName", "carve.ribbonconsul.ConsulServerList");
    }

    static HttpResourceGroup httpResourceGroup = Ribbon.createHttpResourceGroup("hello",
            ClientOptions.create()
                    .withMaxAutoRetriesNextServer(2)
                    .withConnectTimeout(10000)
                    .withReadTimeout(5000)
                    .withMaxConnectionsPerHost(2)
                    .withMaxTotalConnections(12));

    @SuppressWarnings("unchecked")
    static HttpRequestTemplate<ByteBuf> helloTemplate = httpResourceGroup.newTemplateBuilder("helloTemplate", ByteBuf.class)
            .withMethod("GET")
            .withUriTemplate("/hello/v1/hello/")
            .withFallbackProvider(new HelloFallback())
            .build();

    @SuppressWarnings("unchecked")
    static HttpRequestTemplate<ByteBuf> worldTemplate = httpResourceGroup.newTemplateBuilder("worldTemplate", ByteBuf.class)
            .withMethod("GET")
            .withUriTemplate("/hello/v1/hello/world")
            .build();

    @GET
    @Path("hello")
    @Produces("text/plain")
    public String hello() {
        ByteBuf resp = helloTemplate.requestBuilder().build().execute();
        return resp.toString(StandardCharsets.ISO_8859_1);
    }

    @GET
    @Path("world")
    @Produces("text/plain")
    public String world() throws JsonParseException, JsonMappingException, IOException {
        MDC.put("REQUEST-ID", "12345678");
        ByteBuf resp = requestBuilderWithHeaders(worldTemplate).build().execute();
        return mapper.readValue(resp.toString(StandardCharsets.ISO_8859_1), World.class).getHelloWorld();
    }

    public static HttpRequestBuilder<ByteBuf> requestBuilderWithHeaders(HttpRequestTemplate<ByteBuf> template) {
        HttpRequestBuilder<ByteBuf> builder = template.requestBuilder();
        MDC.getCopyOfContextMap().forEach((k, v) -> builder.withHeader("X-MDC-" + k, v));
        return builder;
    }
}

@@ -429,19 +429,160 @@
 ribbon.R
-ibb
+esponseValidator;%0Aimport com.netflix.ribbon.Ribbon;%0Aimport com.netflix.ribbon.ServerError;%0Aimport com.netflix.ribbon.UnsuccessfulResponseExcepti
 on;%0Aimpo
@@ -762,16 +762,83 @@
 ByteBuf;
+%0Aimport io.reactivex.netty.protocol.http.client.HttpClientResponse;
 %0A%0A@Path(
@@ -1324,24 +1324,75 @@
 meout(5000)%0A
+                    .withLoadBalancerEnabled(true)%0A
             
@@ -1426,17 +1426,18 @@
 PerHost(
-2
+10
 )%0A      
@@ -1475,18 +1475,18 @@
 ections(
-1
 2
+0
 ));%0A%0A   
@@ -1513,39 +1513,32 @@
 unchecked%22)%0A    
-static 
 HttpRequestTempl
@@ -1575,32 +1575,45 @@
 ttpResourceGroup
+%0A            
 .newTemplateBuil
@@ -1841,31 +1841,24 @@
 ecked%22)%0A    
-static 
 HttpRequestT
@@ -1907,16 +1907,29 @@
 rceGroup
+%0A            
 .newTemp
@@ -2053,24 +2053,492 @@
 llo/world%22)%0A
+            .withResponseValidator(new ResponseValidator%3CHttpClientResponse%3CByteBuf%3E%3E() %7B%0A                @Override%0A                public void validate(HttpClientResponse%3CByteBuf%3E response)%0A                        throws UnsuccessfulResponseException, ServerError %7B%0A                    if (response.getStatus().code() %3E= 500) %7B%0A                        throw new ServerError(response.getStatus().reasonPhrase());%0A                    %7D%0A                %7D%0A            %7D)%0A
             

handle errors, template must not be static