// Path: common/src/main/java/io/spring/cloud/samples/brewery/common/TestConfigurationHolder.java
// @Data
// @Builder
// public class TestConfigurationHolder {
// 	public static final String TEST_COMMUNICATION_TYPE_HEADER_NAME = "TEST-COMMUNICATION-TYPE";
// 	public static final ThreadLocal<TestConfigurationHolder> TEST_CONFIG = new ThreadLocal<>();
// 
// 	private TestCommunicationType testCommunicationType;
// 
// 	public enum TestCommunicationType {
// 		FEIGN, REST_TEMPLATE
// 	}
// }
// 
// Path: common/src/main/java/io/spring/cloud/samples/brewery/common/events/Event.java
// @Data
// public class Event implements Serializable {
// 	private String processId;
// 	private EventType eventType;
// 	private LocalDateTime eventTime = LocalDateTime.now();
// 
// 	public Event(String processId, EventType eventType) {
// 		this.processId = processId;
// 		this.eventType = eventType;
// 	}
// 
// 	public Event() {}
// 
// 	public static EventBuilder builder() {
// 		return new EventBuilder();
// 	}
// 
// 	public static class EventBuilder {
// 
// 		private String processId;
// 		private EventType eventType;
// 
// 		public EventBuilder eventType(EventType eventType) {
// 			this.eventType = eventType;
// 			return this;
// 		}
// 
// 		public EventBuilder processId(String processId) {
// 			this.processId = processId;
// 			return this;
// 		}
// 
// 		public Event build() {
// 			return new Event(this.processId, this.eventType);
// 		}
// 
// 	}
// }
// 
// Path: common/src/main/java/io/spring/cloud/samples/brewery/common/events/EventGateway.java
// @MessagingGateway
// public interface EventGateway {
// 
// 	@Gateway(requestChannel=EventSource.OUTPUT)
// 	void emitEvent(Event event);
// 
// }
// 
// Path: common/src/main/java/io/spring/cloud/samples/brewery/common/events/EventType.java
// public enum EventType {
// 	INGREDIENTS_ORDERED,
// 	BREWING_STARTED,
// 	BEER_MATURED,
// 	BEER_BOTTLED
// }
// 
// Path: common/src/main/java/io/spring/cloud/samples/brewery/common/model/Ingredients.java
// @ToString
// public class Ingredients {
// 
//     public Ingredients() {
//     }
// 
//     public Ingredients(Iterable<Ingredient> ingredients) {
//         this.ingredients = Lists.newArrayList(ingredients);
//     }
// 
//     public List<Ingredient> ingredients = Lists.newArrayList();
// 
// }
// 
// Path: common/src/main/java/io/spring/cloud/samples/brewery/common/model/Version.java
// public class Version {
//     public static final String BREWING_V1 = "application/vnd.io.spring.cloud.brewing.v1+json";
//     public static final String PRESENTING_V1 = "application/vnd.io.spring.cloud.presenting.v1+json";
// }
// 
// Path: common/src/main/java/io/spring/cloud/samples/brewery/common/model/Wort.java
// @Data
// public class Wort {
//     private int wort;
// 
//     public Wort(int wort) {
//         this.wort = wort;
//     }
// }
// 
// Path: common/src/main/java/io/spring/cloud/samples/brewery/common/TestRequestEntityBuilder.java
// public static TestRequestEntityBuilder requestEntity() {
// 	return new TestRequestEntityBuilder();
// }


import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import org.springframework.cloud.sleuth.Span;
import org.springframework.cloud.sleuth.Tracer;
import org.springframework.http.HttpMethod;
import org.springframework.scheduling.annotation.Async;
import org.springframework.util.Assert;
import org.springframework.web.client.RestTemplate;
import io.spring.cloud.samples.brewery.common.BottlingService;
import io.spring.cloud.samples.brewery.common.TestConfigurationHolder;
import io.spring.cloud.samples.brewery.common.events.Event;
import io.spring.cloud.samples.brewery.common.events.EventGateway;
import io.spring.cloud.samples.brewery.common.events.EventType;
import io.spring.cloud.samples.brewery.common.model.Ingredients;
import io.spring.cloud.samples.brewery.common.model.Version;
import io.spring.cloud.samples.brewery.common.model.Wort;
import lombok.extern.slf4j.Slf4j;
import static io.spring.cloud.samples.brewery.common.TestConfigurationHolder.TestCommunicationType.FEIGN;
import static io.spring.cloud.samples.brewery.common.TestRequestEntityBuilder.requestEntity;
			Thread.sleep(timeout);
		} catch (InterruptedException e) {
			log.error("Exception occurred while brewing beer", e);
		}
    }

    private void notifyPresentingService(String correlationId) {
        log.info("Calling presenting from maturing");
        Span scope = this.tracer.createSpan("calling_presenting_from_maturing");
        switch (TestConfigurationHolder.TEST_CONFIG.get().getTestCommunicationType()) {
            case FEIGN:
                callPresentingViaFeign(correlationId);
                break;
            default:
                useRestTemplateToCallPresenting(correlationId);
        }
        tracer.close(scope);
    }

    private void callPresentingViaFeign(String correlationId) {
        presentingServiceClient.maturingFeed(correlationId, FEIGN.name());
    }

	/**
     * [SLEUTH] HystrixCommand - Javanica integration
     */
    @HystrixCommand
    public void notifyBottlingService(Ingredients ingredients, String correlationId) {
        log.info("Calling bottling from maturing");
        Span scope = this.tracer.createSpan("calling_bottling_from_maturing");
// Path: common/src/main/java/io/spring/cloud/samples/brewery/common/TestConfigurationHolder.java
// @Data
// @Builder
// public class TestConfigurationHolder {
// 	public static final String TEST_COMMUNICATION_TYPE_HEADER_NAME = "TEST-COMMUNICATION-TYPE";
// 	public static final ThreadLocal<TestConfigurationHolder> TEST_CONFIG = new ThreadLocal<>();
// 
// 	private TestCommunicationType testCommunicationType;
// 
// 	public enum TestCommunicationType {
// 		FEIGN, REST_TEMPLATE
// 	}
// }
// 
// Path: common/src/main/java/io/spring/cloud/samples/brewery/common/events/Event.java
// @Data
// public class Event implements Serializable {
// 	private String processId;
// 	private EventType eventType;
// 	private LocalDateTime eventTime = LocalDateTime.now();
// 
// 	public Event(String processId, EventType eventType) {
// 		this.processId = processId;
// 		this.eventType = eventType;
// 	}
// 
// 	public Event() {}
// 
// 	public static EventBuilder builder() {
// 		return new EventBuilder();
// 	}
// 
// 	public static class EventBuilder {
// 
// 		private String processId;
// 		private EventType eventType;
// 
// 		public EventBuilder eventType(EventType eventType) {
// 			this.eventType = eventType;
// 			return this;
// 		}
// 
// 		public EventBuilder processId(String processId) {
// 			this.processId = processId;
// 			return this;
// 		}
// 
// 		public Event build() {
// 			return new Event(this.processId, this.eventType);
// 		}
// 
// 	}
// }
// 
// Path: common/src/main/java/io/spring/cloud/samples/brewery/common/events/EventGateway.java
// @MessagingGateway
// public interface EventGateway {
// 
// 	@Gateway(requestChannel=EventSource.OUTPUT)
// 	void emitEvent(Event event);
// 
// }
// 
// Path: common/src/main/java/io/spring/cloud/samples/brewery/common/events/EventType.java
// public enum EventType {
// 	INGREDIENTS_ORDERED,
// 	BREWING_STARTED,
// 	BEER_MATURED,
// 	BEER_BOTTLED
// }
// 
// Path: common/src/main/java/io/spring/cloud/samples/brewery/common/model/Ingredients.java
// @ToString
// public class Ingredients {
// 
//     public Ingredients() {
//     }
// 
//     public Ingredients(Iterable<Ingredient> ingredients) {
//         this.ingredients = Lists.newArrayList(ingredients);
//     }
// 
//     public List<Ingredient> ingredients = Lists.newArrayList();
// 
// }
// 
// Path: common/src/main/java/io/spring/cloud/samples/brewery/common/model/Version.java
// public class Version {
//     public static final String BREWING_V1 = "application/vnd.io.spring.cloud.brewing.v1+json";
//     public static final String PRESENTING_V1 = "application/vnd.io.spring.cloud.presenting.v1+json";
// }
// 
// Path: common/src/main/java/io/spring/cloud/samples/brewery/common/model/Wort.java
// @Data
// public class Wort {
//     private int wort;
// 
//     public Wort(int wort) {
//         this.wort = wort;
//     }
// }
// 
// Path: common/src/main/java/io/spring/cloud/samples/brewery/common/TestRequestEntityBuilder.java
// public static TestRequestEntityBuilder requestEntity() {
// 	return new TestRequestEntityBuilder();
// }


// Path: brewing/src/main/java/io/spring/cloud/samples/brewery/maturing/BottlingServiceUpdater.java
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import org.springframework.cloud.sleuth.Span;
import org.springframework.cloud.sleuth.Tracer;
import org.springframework.http.HttpMethod;
import org.springframework.scheduling.annotation.Async;
import org.springframework.util.Assert;
import org.springframework.web.client.RestTemplate;
import io.spring.cloud.samples.brewery.common.BottlingService;
import io.spring.cloud.samples.brewery.common.TestConfigurationHolder;
import io.spring.cloud.samples.brewery.common.events.Event;
import io.spring.cloud.samples.brewery.common.events.EventGateway;
import io.spring.cloud.samples.brewery.common.events.EventType;
import io.spring.cloud.samples.brewery.common.model.Ingredients;
import io.spring.cloud.samples.brewery.common.model.Version;
import io.spring.cloud.samples.brewery.common.model.Wort;
import lombok.extern.slf4j.Slf4j;
import static io.spring.cloud.samples.brewery.common.TestConfigurationHolder.TestCommunicationType.FEIGN;
import static io.spring.cloud.samples.brewery.common.TestRequestEntityBuilder.requestEntity;

			Thread.sleep(timeout);
		} catch (InterruptedException e) {
			log.error("Exception occurred while brewing beer", e);
		}
    }

    private void notifyPresentingService(String correlationId) {
        log.info("Calling presenting from maturing");
        Span scope = this.tracer.createSpan("calling_presenting_from_maturing");
        switch (TestConfigurationHolder.TEST_CONFIG.get().getTestCommunicationType()) {
            case FEIGN:
                callPresentingViaFeign(correlationId);
                break;
            default:
                useRestTemplateToCallPresenting(correlationId);
        }
        tracer.close(scope);
    }

    private void callPresentingViaFeign(String correlationId) {
        presentingServiceClient.maturingFeed(correlationId, FEIGN.name());
    }

	/**
     * [SLEUTH] HystrixCommand - Javanica integration
     */
    @HystrixCommand
    public void notifyBottlingService(Ingredients ingredients, String correlationId) {
        log.info("Calling bottling from maturing");
        Span scope = this.tracer.createSpan("calling_bottling_from_maturing");
        bottlingService.bottle(new Wort(getQuantity(ingredients)), correlationId, FEIGN.name());