// Path: monolith/src/main/java/demo/model/Ad.java
// public class Ad {
// 
//   private String redirectUrl;
//   private String text;
// 
//   public Ad(AdBuilder builder) {
//     this.redirectUrl = builder.redirectUrl;
//     this.text = builder.text;
//   }
// 
//   public String getRedirectUrl() {
//     return redirectUrl;
//   }
// 
//   public void setRedirectUrl(String redirectUrl) {
//     this.redirectUrl = redirectUrl;
//   }
// 
//   public String getText() {
//     return text;
//   }
// 
//   public void setText(String text) {
//     this.text = text;
//   }
// 
//   // Builder Class
//   public static class AdBuilder {
// 
//     private String redirectUrl;
//     private String text;
// 
//     public AdBuilder setRedirectUrl(String redirectUrl) {
//       this.redirectUrl = redirectUrl;
//       return this;
//     }
// 
//     public AdBuilder setText(String text) {
//       this.text = text;
//       return this;
//     }
// 
//     public Ad build() {
//       return new Ad(this);
//     }
//   }
// }
// 
// Path: monolith/src/main/java/demo/model/Product.java
// public class Product implements Serializable {
// 
//   private static final long serialVersionUID = 5186013952828648626L;
// 
//   private String id;
//   private List<String> categories;
//   private String description;
//   private String name;
//   private String priceUsd;
//   private String picture;
// 
//   public Product() {
//     super();
//   }
// 
//   public String getId() {
//     return id;
//   }
// 
//   public List<String> getCategories() {
//     return categories;
//   }
// 
//   public String getDescription() {
//     return description;
//   }
// 
//   public String getName() {
//     return name;
//   }
// 
//   public String getPriceUsd() {
//     return priceUsd;
//   }
// 
//   public String getPicture() {
//     return picture;
//   }
// 
//   public void setId(String productId) {
//     this.id = productId;
//   }
// 
//   public void setCategories(List<String> productCategory) {
//     this.categories = productCategory;
//   }
// 
//   public void setDescription(String productDescription) {
//     this.description = productDescription;
//   }
// 
//   public void setName(String productName) {
//     this.name = productName;
//   }
// 
//   public void setPriceUsd(String productPrice) {
//     this.priceUsd = productPrice;
//   }
// 
//   public void setPicture(String productImage) {
//     this.picture = productImage;
//   }
// }
// 
// Path: microservices/src/main/java/demo/utils/HttpUtils.java
// public class HttpUtils {
//   private static final TextFormat textFormat = Tracing.getPropagationComponent().getB3Format();
// 
//   @SuppressWarnings("rawtypes")
//   private static final TextFormat.Setter setter =
//       new TextFormat.Setter<HttpURLConnection>() {
//         public void put(HttpURLConnection carrier, String key, String value) {
//           carrier.setRequestProperty(key, value);
//         }
//       };
// 
//   @SuppressWarnings("unchecked")
//   public static String callEndpoint(String url, HttpMethod method, Tracer tracer, JSONObject req)
//       throws Exception {
//     StringBuilder result = new StringBuilder();
//     HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection();
// 
//     textFormat.inject(tracer.getCurrentSpan().getContext(), conn, setter);
// 
//     conn.setDoOutput(true);
//     conn.setDoInput(true);
//     conn.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
//     conn.setRequestMethod(method.name());
//     OutputStream os = conn.getOutputStream();
//     os.write(req.toString().getBytes("UTF-8"));
//     os.close();
// 
//     BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
//     String line;
//     while ((line = rd.readLine()) != null) {
//       result.append(line);
//     }
//     rd.close();
// 
//     return result.toString();
//   }
// }
// 
// Path: microservices/src/main/java/demo/utils/SpanUtils.java
// public class SpanUtils {
// 
//   public static SpanBuilder buildSpan(Tracer tracer, String name) {
//     return tracer.spanBuilder(name).setRecordEvents(true).setSampler(Samplers.alwaysSample());
//   }
// }


import demo.model.Ad;
import demo.model.Product;
import demo.utils.HttpUtils;
import demo.utils.SpanUtils;
import io.opencensus.common.Scope;
import io.opencensus.trace.Span;
import io.opencensus.trace.Status;
import io.opencensus.trace.Tracer;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpMethod;
import org.springframework.stereotype.Service;
/* Copyright 2020 Google LLC. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package demo.service;


@Service
public class AdsService {
  @Autowired private Tracer tracer;

  @Value("${ads-service-endpoint}")
  private String svcEndpoint;

  /**
   * Get recommended ads from a downstream Ads service. Ads service is called over HTTP. Trace span
   * is also instrumented to capture distributed span across service boundaries.
   *
   * @param product user selected product
   */
  public Ad getRecommendedAd(Product product) {
    // [START get_recommended_ad]
    Span span = SpanUtils.buildSpan(tracer, "Ad Service").startSpan();
    String result;
    String url = "http://" + svcEndpoint + "/servead";
    try (Scope ws = tracer.withSpan(span)) {
      result =
          HttpUtils.callEndpoint(
              url,
              HttpMethod.POST,
              tracer,
// Path: monolith/src/main/java/demo/model/Ad.java
// public class Ad {
// 
//   private String redirectUrl;
//   private String text;
// 
//   public Ad(AdBuilder builder) {
//     this.redirectUrl = builder.redirectUrl;
//     this.text = builder.text;
//   }
// 
//   public String getRedirectUrl() {
//     return redirectUrl;
//   }
// 
//   public void setRedirectUrl(String redirectUrl) {
//     this.redirectUrl = redirectUrl;
//   }
// 
//   public String getText() {
//     return text;
//   }
// 
//   public void setText(String text) {
//     this.text = text;
//   }
// 
//   // Builder Class
//   public static class AdBuilder {
// 
//     private String redirectUrl;
//     private String text;
// 
//     public AdBuilder setRedirectUrl(String redirectUrl) {
//       this.redirectUrl = redirectUrl;
//       return this;
//     }
// 
//     public AdBuilder setText(String text) {
//       this.text = text;
//       return this;
//     }
// 
//     public Ad build() {
//       return new Ad(this);
//     }
//   }
// }
// 
// Path: monolith/src/main/java/demo/model/Product.java
// public class Product implements Serializable {
// 
//   private static final long serialVersionUID = 5186013952828648626L;
// 
//   private String id;
//   private List<String> categories;
//   private String description;
//   private String name;
//   private String priceUsd;
//   private String picture;
// 
//   public Product() {
//     super();
//   }
// 
//   public String getId() {
//     return id;
//   }
// 
//   public List<String> getCategories() {
//     return categories;
//   }
// 
//   public String getDescription() {
//     return description;
//   }
// 
//   public String getName() {
//     return name;
//   }
// 
//   public String getPriceUsd() {
//     return priceUsd;
//   }
// 
//   public String getPicture() {
//     return picture;
//   }
// 
//   public void setId(String productId) {
//     this.id = productId;
//   }
// 
//   public void setCategories(List<String> productCategory) {
//     this.categories = productCategory;
//   }
// 
//   public void setDescription(String productDescription) {
//     this.description = productDescription;
//   }
// 
//   public void setName(String productName) {
//     this.name = productName;
//   }
// 
//   public void setPriceUsd(String productPrice) {
//     this.priceUsd = productPrice;
//   }
// 
//   public void setPicture(String productImage) {
//     this.picture = productImage;
//   }
// }
// 
// Path: microservices/src/main/java/demo/utils/HttpUtils.java
// public class HttpUtils {
//   private static final TextFormat textFormat = Tracing.getPropagationComponent().getB3Format();
// 
//   @SuppressWarnings("rawtypes")
//   private static final TextFormat.Setter setter =
//       new TextFormat.Setter<HttpURLConnection>() {
//         public void put(HttpURLConnection carrier, String key, String value) {
//           carrier.setRequestProperty(key, value);
//         }
//       };
// 
//   @SuppressWarnings("unchecked")
//   public static String callEndpoint(String url, HttpMethod method, Tracer tracer, JSONObject req)
//       throws Exception {
//     StringBuilder result = new StringBuilder();
//     HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection();
// 
//     textFormat.inject(tracer.getCurrentSpan().getContext(), conn, setter);
// 
//     conn.setDoOutput(true);
//     conn.setDoInput(true);
//     conn.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
//     conn.setRequestMethod(method.name());
//     OutputStream os = conn.getOutputStream();
//     os.write(req.toString().getBytes("UTF-8"));
//     os.close();
// 
//     BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
//     String line;
//     while ((line = rd.readLine()) != null) {
//       result.append(line);
//     }
//     rd.close();
// 
//     return result.toString();
//   }
// }
// 
// Path: microservices/src/main/java/demo/utils/SpanUtils.java
// public class SpanUtils {
// 
//   public static SpanBuilder buildSpan(Tracer tracer, String name) {
//     return tracer.spanBuilder(name).setRecordEvents(true).setSampler(Samplers.alwaysSample());
//   }
// }


// Path: microservices/src/main/java/demo/service/AdsService.java
import demo.model.Ad;
import demo.model.Product;
import demo.utils.HttpUtils;
import demo.utils.SpanUtils;
import io.opencensus.common.Scope;
import io.opencensus.trace.Span;
import io.opencensus.trace.Status;
import io.opencensus.trace.Tracer;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpMethod;
import org.springframework.stereotype.Service;

/* Copyright 2020 Google LLC. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package demo.service;


@Service
public class AdsService {
  @Autowired private Tracer tracer;

  @Value("${ads-service-endpoint}")
  private String svcEndpoint;

  /**
   * Get recommended ads from a downstream Ads service. Ads service is called over HTTP. Trace span
   * is also instrumented to capture distributed span across service boundaries.
   *
   * @param product user selected product
   */
  public Ad getRecommendedAd(Product product) {
    // [START get_recommended_ad]
    Span span = SpanUtils.buildSpan(tracer, "Ad Service").startSpan();
    String result;
    String url = "http://" + svcEndpoint + "/servead";
    try (Scope ws = tracer.withSpan(span)) {
      result =
          HttpUtils.callEndpoint(
              url,
              HttpMethod.POST,
              tracer,
              new JSONObject().put("category", product.getCategories().get(0)));