<|start_filename|>loc-autoconfigure/src/main/java/com/loc/framework/autoconfigure/kafka/LocKafkaAutoConfiguration.java<|end_filename|>
package com.loc.framework.autoconfigure.kafka;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.loc.framework.autoconfigure.ConditionalOnPrefixProperty;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.kafka.ConcurrentKafkaListenerContainerFactoryConfigurer;
import org.springframework.boot.autoconfigure.kafka.KafkaAutoConfiguration;
import org.springframework.boot.autoconfigure.kafka.KafkaProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.kafka.annotation.EnableKafka;
import org.springframework.kafka.config.ConcurrentKafkaListenerContainerFactory;
import org.springframework.kafka.core.ConsumerFactory;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.kafka.listener.ContainerProperties;
import org.springframework.kafka.listener.adapter.RecordFilterStrategy;
import org.springframework.kafka.support.converter.RecordMessageConverter;
import org.springframework.kafka.support.converter.StringJsonMessageConverter;

/**
 * Created on 2018/2/24.
 */
@Slf4j
@Configuration
@ConditionalOnPrefixProperty(prefix = "spring.kafka", value = KafkaProperties.class)
@ConditionalOnClass({KafkaTemplate.class, EnableKafka.class})
@AutoConfigureAfter({KafkaAutoConfiguration.class})
public class LocKafkaAutoConfiguration {

  private final ObjectMapper objectMapper;

  public LocKafkaAutoConfiguration(ObjectMapper objectMapper) {
    this.objectMapper = objectMapper;
  }

  @Bean
  @ConditionalOnMissingBean
  public LocKafkaProducer locKafkaProducer(KafkaTemplate<byte[], byte[]> kafkaTemplate,
      LocLoggingProducerListener<byte[], byte[]> locLoggingProducerListener) {
    kafkaTemplate.setProducerListener(locLoggingProducerListener);
    return new LocKafkaProducer(kafkaTemplate, objectMapper);
  }

  @Bean
  @ConditionalOnMissingBean
  public LocLoggingProducerListener<byte[], byte[]> locLoggingProducerListener() {
    return new LocLoggingProducerListener<>();
  }

  @Bean
  @ConditionalOnMissingBean
  public RecordMessageConverter recordMessageConverter() {
    return new StringJsonMessageConverter(objectMapper);
  }

  @Bean(name = "kafkaListenerContainerFactory")
  public ConcurrentKafkaListenerContainerFactory<?, ?> kafkaListenerContainerFactory(
      ConcurrentKafkaListenerContainerFactoryConfigurer configurer,
      ConsumerFactory<Object, Object> kafkaConsumerFactory) {
    ConcurrentKafkaListenerContainerFactory<Object, Object> factory = new ConcurrentKafkaListenerContainerFactory<>();
    ContainerProperties containerProperties = factory.getContainerProperties();
    factory.setRecordFilterStrategy(locMessageFilterStrategy());
    factory.setErrorHandler(new LocKafkaConsumerErrorHandler());
    factory.setMessageConverter(recordMessageConverter());
    configurer.configure(factory, kafkaConsumerFactory);
    return factory;
  }

  private RecordFilterStrategy<Object, Object> locMessageFilterStrategy() {
    return (consumerRecord) -> {
      Object value = consumerRecord.value();
      String message;
      if (value instanceof byte[]) {
        message = KafkaUtils.getMessage((byte[]) value, "consumer filter", consumerRecord);
        log.info(message);
        return false;
      } else {
        log.error("Only byte[] or string supported");
        return true;
      }
    };
  }
}


<|start_filename|>loc-autoconfigure/src/main/java/com/loc/framework/autoconfigure/okhttp/LocOkHttpClient.java<|end_filename|>
package com.loc.framework.autoconfigure.okhttp;

import static com.loc.framework.autoconfigure.common.LocConstants.OKHTTP_ERROR_CODE;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.base.Strings;
import com.loc.framework.autoconfigure.LocServiceException;
import com.loc.framework.autoconfigure.common.BaseResult;
import com.loc.framework.autoconfigure.utils.ProblemUtil;
import java.io.IOException;
import java.lang.reflect.Type;
import java.net.URI;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import okhttp3.FormBody;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Request.Builder;
import okhttp3.RequestBody;
import okhttp3.Response;
import org.apache.commons.lang3.ClassUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.CollectionUtils;
import org.zalando.problem.Problem;
import org.zalando.problem.Status;

/**
 * Created on 2018/9/5.
 */
@Slf4j
public class LocOkHttpClient {

  public static final MediaType JSON = MediaType.parse("application/json; charset=utf-8");
  @Getter
  private OkHttpClient okHttpClient;

  private ObjectMapper objectMapper;

  public LocOkHttpClient(OkHttpClient okHttpClient, ObjectMapper objectMapper) {
    this.okHttpClient = okHttpClient;
    this.objectMapper = objectMapper;
  }


  public <T> BaseResult<T> get(OkHttpClientBuilder hnGetBuilder) {
    checkBasicParam(hnGetBuilder);
    Builder builder = createRequestBuilder(
        createGetUrl(hnGetBuilder.getUrl(), hnGetBuilder.getParams()), hnGetBuilder.getHeaders());
    return returnBaseResult(builder.get().build(), hnGetBuilder.getTypeReference());
  }


  public <T> BaseResult<T> post(OkHttpClientBuilder okHttpClientBuilder) {
    checkBasicParam(okHttpClientBuilder);
    Builder builder = createRequestBuilder(okHttpClientBuilder.getUrl(),
        okHttpClientBuilder.getHeaders());

    FormBody.Builder formBuilder = new FormBody.Builder();
    Optional.ofNullable(okHttpClientBuilder.getParams()).ifPresent(c -> c.forEach(
        (key, value) -> {
          if (value != null) {
            formBuilder.add(key, value);
          } else {
            log.warn("key:{} is null", key);
          }
        }
    ));

    return returnBaseResult(builder.post(formBuilder.build()).build(),
        okHttpClientBuilder.getTypeReference()
    );
  }

  public <T> BaseResult<T> postEncoded(OkHttpClientBuilder hnPostBuilder, List<String> excludeEncode) {
    checkBasicParam(hnPostBuilder);
    Builder builder = createRequestBuilder(hnPostBuilder.getUrl(), hnPostBuilder.getHeaders());

    FormBody.Builder formBuilder = new FormBody.Builder();
    Optional.ofNullable(hnPostBuilder.getParams()).ifPresent(c -> c.forEach(
        (key, value) -> {
          if (value != null) {
            if (!excludeEncode.contains(key)) {
              formBuilder.add(key, value);
            } else {
              formBuilder.addEncoded(key, value);
            }
          } else {
            log.warn("key:{} is null", key);
          }
        }
    ));

    return returnBaseResult(builder.post(formBuilder.build()).build(),
        hnPostBuilder.getTypeReference()
    );
  }

  public <T> BaseResult<T> postJson(OkHttpClientBuilder okHttpClientBuilder) {
    checkBasicParam(okHttpClientBuilder);
    Builder builder = createRequestBuilder(okHttpClientBuilder.getUrl(),
        okHttpClientBuilder.getHeaders());
    checkBody(okHttpClientBuilder.getBody());
    RequestBody body = RequestBody.create(JSON, okHttpClientBuilder.getBody());

    return returnBaseResult(builder.post(body)
        .build(), okHttpClientBuilder.getTypeReference());
  }

  @SuppressWarnings("unchecked")
  private <T> BaseResult<T> returnBaseResult(Request request, TypeReference typeReference) {
    try {
      Response response = this.okHttpClient.newCall(request).execute();
      if (response.isSuccessful()) {
        String result = response.body().string();
        checkResult(result);
        Type type = typeReference.getType();
        if (isPrimitiveType(type)) {
          return new BaseResult(result);
        }

        return BaseResult.success(objectMapper.readValue(result, typeReference));
      } else {
        log.error("request url: {} http status code:{}", request.url(), response.code());
        String result = Optional.ofNullable(response.body())
            .map(body -> {
              try {
                return Strings.emptyToNull(body.string());
              } catch (IOException e) {
                log.error("获取body失败:", e);
                return null;
              }
            })
            .orElse(Status.BAD_REQUEST.getReasonPhrase());
        return new BaseResult(Status.BAD_REQUEST.getStatusCode(), result);
      }
    } catch (Exception e) {
      throw new LocServiceException(OKHTTP_ERROR_CODE, e.getMessage());
    }
  }


  private boolean isPrimitiveType(Type type) {
    if (type instanceof Class) {
      Class clazz = (Class) type;
      if (ClassUtils.isPrimitiveOrWrapper(clazz) || ClassUtils
          .isAssignable(clazz, String.class)) {
        return true;
      }
    }
    return false;
  }

  private void checkBody(String body) {
    if (StringUtils.isBlank(body)) {
      throw new RuntimeException("response 不能为空!");
    }
  }


  private void checkResult(String result) {
    if (StringUtils.isBlank(result)) {
      throw new RuntimeException("返回值为空!");
    }
  }

  private Builder createRequestBuilder(String url, Map<String, String> headers) {
    Builder builder = new Request.Builder();
    builder.url(url);
    Optional.ofNullable(headers).ifPresent(c -> c.forEach(builder::addHeader));
    return builder;
  }

  private void checkBasicParam(OkHttpClientBuilder hnOkHttpBuilder) {
    if (StringUtils.isBlank(hnOkHttpBuilder.getUrl())) {
      throw new RuntimeException("不能为空!");
    }

    if (hnOkHttpBuilder.getTypeReference() == null) {
      throw new RuntimeException("typeReference!");
    }
  }

  private String createGetUrl(String url, Map<String, String> params) {
    if (CollectionUtils.isEmpty(params)) {
      return url;
    }
    StringBuilder sb = new StringBuilder();
    params.forEach((k, v) -> {
      if (sb.length() == 0) {
        sb.append("?");
      } else if (sb.length() > 0) {
        sb.append("&");
      }
      sb.append(k);
      sb.append("=").append(v);
    });
    return url + sb.toString();
  }

}


<|start_filename|>loc-autoconfigure/src/main/java/com/loc/framework/autoconfigure/springmvc/LocServiceAdviceTrait.java<|end_filename|>
package com.loc.framework.autoconfigure.springmvc;

import static com.loc.framework.autoconfigure.common.LocConstants.BIND_ERROR_CODE;
import static com.loc.framework.autoconfigure.common.LocConstants.CONSTRAINT_VIOLATION_ERROR_CODE;
import static com.loc.framework.autoconfigure.common.LocConstants.METHOD_ARGUMENT_NOT_VALID_ERROR_CODE;

import com.loc.framework.autoconfigure.LocServiceException;
import com.loc.framework.autoconfigure.common.BaseResultCode;
import com.loc.framework.autoconfigure.utils.ProblemUtil;
import java.util.List;
import java.util.stream.Collectors;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import org.apiguardian.api.API;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.BindException;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.context.request.NativeWebRequest;
import org.zalando.problem.Problem;
import org.zalando.problem.Status;
import org.zalando.problem.spring.web.advice.general.GeneralAdviceTrait;
import org.zalando.problem.spring.web.advice.http.HttpAdviceTrait;
import org.zalando.problem.spring.web.advice.io.IOAdviceTrait;
import org.zalando.problem.spring.web.advice.routing.RoutingAdviceTrait;

@API(status = API.Status.STABLE)
public interface LocServiceAdviceTrait extends GeneralAdviceTrait, HttpAdviceTrait, IOAdviceTrait,
    RoutingAdviceTrait {

  @API(status = API.Status.INTERNAL)
  @ExceptionHandler(value = LocServiceException.class)
  default ResponseEntity<Problem> handleHnServiceException(
      final LocServiceException hnServiceException, final NativeWebRequest request) {
    int code = hnServiceException.getCode();
    if(code < 0) {
      code *= -1;
    }

    if(code < 10000) {
      code += 10000;
    }
    return this.create(hnServiceException,
        ProblemUtil.createProblem(hnServiceException.getMsg(), code),
        request);
  }

  @API(status = API.Status.INTERNAL)
  @ExceptionHandler(value = ConstraintViolationException.class)
  default ResponseEntity<Problem> handleConstraintViolationException(
      final ConstraintViolationException constraintViolationException,
      final NativeWebRequest request) {
    return this.create(constraintViolationException, ProblemUtil.createProblem(
        constraintViolationException.getConstraintViolations().stream()
            .map(ConstraintViolation::getMessage).collect(Collectors.joining(",")),
        CONSTRAINT_VIOLATION_ERROR_CODE), request);
  }

  @API(status = API.Status.INTERNAL)
  @ExceptionHandler(value = BindException.class)
  default ResponseEntity<Problem> handleBindException(final BindException bindException,
      final NativeWebRequest request) {
    List<FieldError> fieldErrors = bindException.getBindingResult().getFieldErrors();
    return this.create(bindException, ProblemUtil.createProblem(
        fieldErrors.stream().map(e -> e.getField() + ":" + e.getDefaultMessage())
            .collect(Collectors.joining(",")), BIND_ERROR_CODE), request);
  }

  @API(status = API.Status.INTERNAL)
  @ExceptionHandler(value = MethodArgumentNotValidException.class)
  default ResponseEntity<Problem> handleMethodArgumentNotValidException(
      final MethodArgumentNotValidException methodArgumentNotValidException,
      final NativeWebRequest request) {
    List<FieldError> fieldErrors = methodArgumentNotValidException.getBindingResult().getFieldErrors();
    return this.create(methodArgumentNotValidException, ProblemUtil.createProblem(
        fieldErrors.stream().map(e -> e.getField() + ":" + e.getDefaultMessage())
            .collect(Collectors.joining(",")), METHOD_ARGUMENT_NOT_VALID_ERROR_CODE), request);
  }

  @API(status = API.Status.INTERNAL)
  @ExceptionHandler(value = Throwable.class)
  default ResponseEntity<Problem> handleThrowable(final Throwable throwable, final NativeWebRequest request) {
    return this.create(throwable, ProblemUtil.createProblem(BaseResultCode.UNKNOWN_THROWABLE_EXCEPTION_CODE.getMsg(),
        BaseResultCode.UNKNOWN_THROWABLE_EXCEPTION_CODE.getCode(), Status.INTERNAL_SERVER_ERROR), request);
  }
}

