├── sss-ad-spring-cloud.iml ├── README.md ├── ad-gateway ├── target │ └── classes │ │ ├── com │ │ └── javaedge │ │ │ └── ad │ │ │ ├── ZuulGatewayApplication.class │ │ │ └── filter │ │ │ ├── AccessLogFilter.class │ │ │ └── PreRequestFilter.class │ │ └── application.yml ├── src │ └── main │ │ ├── resources │ │ └── application.yml │ │ └── java │ │ └── com │ │ └── javaedge │ │ └── ad │ │ ├── ZuulGatewayApplication.java │ │ └── filter │ │ ├── PreRequestFilter.java │ │ └── AccessLogFilter.java └── pom.xml ├── .idea ├── vcs.xml ├── dictionaries │ └── sss.xml ├── misc.xml ├── encodings.xml ├── compiler.xml └── inspectionProfiles │ └── Project_Default.xml ├── javaedge-ad-service ├── ad-search │ ├── src │ │ └── main │ │ │ ├── java │ │ │ └── com │ │ │ │ └── javaedge │ │ │ │ └── ad │ │ │ │ ├── search │ │ │ │ ├── vo │ │ │ │ │ ├── feature │ │ │ │ │ │ ├── FeatureRelation.java │ │ │ │ │ │ ├── ItFeature.java │ │ │ │ │ │ ├── KeywordFeature.java │ │ │ │ │ │ └── DistrictFeature.java │ │ │ │ │ ├── media │ │ │ │ │ │ ├── Geo.java │ │ │ │ │ │ ├── App.java │ │ │ │ │ │ ├── AdSlot.java │ │ │ │ │ │ └── Device.java │ │ │ │ │ ├── SearchRequest.java │ │ │ │ │ └── SearchResponse.java │ │ │ │ ├── ISearch.java │ │ │ │ └── controller │ │ │ │ │ └── SearchController.java │ │ │ │ ├── sender │ │ │ │ ├── ISender.java │ │ │ │ └── kafka │ │ │ │ │ └── KafkaSender.java │ │ │ │ ├── index │ │ │ │ ├── interest │ │ │ │ │ ├── UnitItObject.java │ │ │ │ │ └── UnitItIndex.java │ │ │ │ ├── keyword │ │ │ │ │ ├── UnitKeywordObject.java │ │ │ │ │ └── UnitKeywordIndex.java │ │ │ │ ├── creativeunit │ │ │ │ │ ├── CreativeUnitObject.java │ │ │ │ │ └── CreativeUnitIndex.java │ │ │ │ ├── CommonStatus.java │ │ │ │ ├── DataLevel.java │ │ │ │ ├── district │ │ │ │ │ ├── UnitDistrictObject.java │ │ │ │ │ └── UnitDistrictIndex.java │ │ │ │ ├── IndexAware.java │ │ │ │ ├── adunit │ │ │ │ │ ├── AdUnitConstants.java │ │ │ │ │ ├── AdUnitIndex.java │ │ │ │ │ └── AdUnitObject.java │ │ │ │ ├── adplan │ │ │ │ │ ├── AdPlanObject.java │ │ │ │ │ └── AdPlanIndex.java │ │ │ │ ├── creative │ │ │ │ │ ├── CreativeObject.java │ │ │ │ │ └── CreativeIndex.java │ │ │ │ ├── DataTable.java │ │ │ │ └── IndexFileLoader.java │ │ │ │ ├── client │ │ │ │ ├── vo │ │ │ │ │ ├── AdPlanGetRequest.java │ │ │ │ │ └── AdPlan.java │ │ │ │ ├── SponsorClientHystrix.java │ │ │ │ └── SponsorClient.java │ │ │ │ ├── mysql │ │ │ │ ├── dto │ │ │ │ │ ├── Template.java │ │ │ │ │ ├── BinlogRowData.java │ │ │ │ │ ├── MySqlRowData.java │ │ │ │ │ ├── JsonTable.java │ │ │ │ │ ├── TableTemplate.java │ │ │ │ │ └── ParseTemplate.java │ │ │ │ ├── listener │ │ │ │ │ ├── Ilistener.java │ │ │ │ │ ├── IncrementListener.java │ │ │ │ │ └── AggregationListener.java │ │ │ │ ├── constant │ │ │ │ │ ├── OpType.java │ │ │ │ │ └── Constant.java │ │ │ │ ├── BinlogConfig.java │ │ │ │ ├── BinlogClient.java │ │ │ │ └── TemplateHolder.java │ │ │ │ ├── runner │ │ │ │ └── BinlogRunner.java │ │ │ │ ├── SearchApplication.java │ │ │ │ ├── utils │ │ │ │ └── CommonUtils.java │ │ │ │ ├── controller │ │ │ │ └── SearchController.java │ │ │ │ ├── service │ │ │ │ └── BinlogServiceTest.java │ │ │ │ └── handler │ │ │ │ └── AdLevelDataHandler.java │ │ │ └── resources │ │ │ ├── application.yml │ │ │ ├── example.sql │ │ │ └── template.json │ └── pom.xml ├── ad-common │ ├── src │ │ └── main │ │ │ └── java │ │ │ └── com │ │ │ └── javaedge │ │ │ └── ad │ │ │ ├── conf │ │ │ ├── MyInterceptor.java │ │ │ └── WebConfiguration.java │ │ │ ├── exception │ │ │ └── AdException.java │ │ │ ├── dump │ │ │ ├── table │ │ │ │ ├── AdUnitItTable.java │ │ │ │ ├── AdCreativeUnitTable.java │ │ │ │ ├── AdUnitKeywordTable.java │ │ │ │ ├── AdUnitDistrictTable.java │ │ │ │ ├── AdUnitTable.java │ │ │ │ ├── AdCreativeTable.java │ │ │ │ └── AdPlanTable.java │ │ │ └── DConstant.java │ │ │ ├── annotation │ │ │ └── IgnoreResponseAdvice.java │ │ │ ├── vo │ │ │ └── CommonResponse.java │ │ │ └── advice │ │ │ ├── GlobalExceptionAdvice.java │ │ │ └── CommonResponseDataAdvice.java │ └── pom.xml ├── ad-sponsor │ ├── src │ │ ├── main │ │ │ ├── java │ │ │ │ └── com │ │ │ │ │ └── javaedge │ │ │ │ │ └── ad │ │ │ │ │ ├── dao │ │ │ │ │ ├── CreativeRepository.java │ │ │ │ │ ├── unitcondition │ │ │ │ │ │ ├── AdUnitItRepository.java │ │ │ │ │ │ ├── AdUnitKeywordRepository.java │ │ │ │ │ │ ├── CreativeUnitRepository.java │ │ │ │ │ │ └── AdUnitDistrictRepository.java │ │ │ │ │ ├── AdUserRepository.java │ │ │ │ │ ├── AdUnitRepository.java │ │ │ │ │ └── AdPlanRepository.java │ │ │ │ │ ├── vo │ │ │ │ │ ├── CreativeResponse.java │ │ │ │ │ ├── AdUnitItResponse.java │ │ │ │ │ ├── AdUnitDistrictResponse.java │ │ │ │ │ ├── AdUnitKeywordResponse.java │ │ │ │ │ ├── CreativeUnitResponse.java │ │ │ │ │ ├── AdUnitResponse.java │ │ │ │ │ ├── AdPlanResponse.java │ │ │ │ │ ├── CreateUserRequest.java │ │ │ │ │ ├── AdUnitItRequest.java │ │ │ │ │ ├── AdUnitKeywordRequest.java │ │ │ │ │ ├── CreateUserResponse.java │ │ │ │ │ ├── CreativeUnitRequest.java │ │ │ │ │ ├── AdUnitRequest.java │ │ │ │ │ ├── AdPlanGetRequest.java │ │ │ │ │ ├── AdUnitDistrictRequest.java │ │ │ │ │ ├── AdPlanRequest.java │ │ │ │ │ └── CreativeRequest.java │ │ │ │ │ ├── service │ │ │ │ │ ├── ICreativeService.java │ │ │ │ │ ├── IUserService.java │ │ │ │ │ ├── IAdUnitService.java │ │ │ │ │ ├── impl │ │ │ │ │ │ ├── CreativeServiceImpl.java │ │ │ │ │ │ ├── UserServiceImpl.java │ │ │ │ │ │ ├── AdPlanServiceImpl.java │ │ │ │ │ │ └── AdUnitServiceImpl.java │ │ │ │ │ └── IAdPlanService.java │ │ │ │ │ ├── constant │ │ │ │ │ ├── CommonStatus.java │ │ │ │ │ ├── CreativeType.java │ │ │ │ │ ├── CreativeMaterialType.java │ │ │ │ │ └── Constants.java │ │ │ │ │ ├── SponsorApplication.java │ │ │ │ │ ├── utils │ │ │ │ │ └── CommonUtils.java │ │ │ │ │ ├── entity │ │ │ │ │ ├── unitcondition │ │ │ │ │ │ ├── AdUnitIt.java │ │ │ │ │ │ ├── AdUnitKeyword.java │ │ │ │ │ │ ├── CreativeUnit.java │ │ │ │ │ │ ├── AdUnitDistrict.java │ │ │ │ │ │ └── AdUnit.java │ │ │ │ │ ├── AdUser.java │ │ │ │ │ ├── AdPlan.java │ │ │ │ │ └── Creative.java │ │ │ │ │ └── controller │ │ │ │ │ ├── CreativeOpController.java │ │ │ │ │ ├── UserOpController.java │ │ │ │ │ ├── AdPlanOpController.java │ │ │ │ │ └── AdUnitOpController.java │ │ │ └── resources │ │ │ │ ├── application.yml │ │ │ │ └── ad-sponsor.sql │ │ └── test │ │ │ ├── java │ │ │ └── com │ │ │ │ └── javaedge │ │ │ │ └── ad │ │ │ │ └── Application.java │ │ │ └── resources │ │ │ └── application.yml │ └── pom.xml └── pom.xml ├── ad-eureka ├── src │ └── main │ │ ├── resources │ │ └── application.yml │ │ └── java │ │ └── com │ │ └── javaedge │ │ └── ad │ │ └── EurekaApplication.java └── pom.xml └── pom.xml /sss-ad-spring-cloud.iml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 基于微服务架构的广告系统 2 | 3 | # 环境参数 4 | JDK 1.8 5 | SpringCloud: Finchley.RELEASE 6 | Kafka 2.0 7 | Maven 3.5.0 8 | MySQL 5.7 9 | IDE IntelliJ IDEA: 2018.3 10 | 11 | -------------------------------------------------------------------------------- /ad-gateway/target/classes/com/javaedge/ad/ZuulGatewayApplication.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Java-Edge/Ad/HEAD/ad-gateway/target/classes/com/javaedge/ad/ZuulGatewayApplication.class -------------------------------------------------------------------------------- /ad-gateway/target/classes/com/javaedge/ad/filter/AccessLogFilter.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Java-Edge/Ad/HEAD/ad-gateway/target/classes/com/javaedge/ad/filter/AccessLogFilter.class -------------------------------------------------------------------------------- /ad-gateway/target/classes/com/javaedge/ad/filter/PreRequestFilter.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Java-Edge/Ad/HEAD/ad-gateway/target/classes/com/javaedge/ad/filter/PreRequestFilter.class -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /ad-gateway/target/classes/application.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 9000 3 | spring: 4 | application: 5 | name: ad-gateway 6 | eureka: 7 | client: 8 | service-url: 9 | defaultZone: http://server1:8000/eureka/ -------------------------------------------------------------------------------- /javaedge-ad-service/ad-search/src/main/java/com/javaedge/ad/search/vo/feature/FeatureRelation.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.search.vo.feature; 2 | 3 | /** 4 | * @author sss 5 | * @date 2019-02-26 6 | */ 7 | public enum FeatureRelation { 8 | 9 | OR, 10 | AND 11 | } 12 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-common/src/main/java/com/javaedge/ad/conf/MyInterceptor.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.conf; 2 | 3 | import org.springframework.web.servlet.HandlerInterceptor; 4 | 5 | /** 6 | * @author sss 7 | * @date 2019/1/31 8 | */ 9 | public class MyInterceptor implements HandlerInterceptor { 10 | } 11 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-common/src/main/java/com/javaedge/ad/exception/AdException.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.exception; 2 | 3 | /** 4 | * @author sss 5 | * @date 2019/1/31 6 | */ 7 | public class AdException extends Exception { 8 | 9 | public AdException(String message) { 10 | super(message); 11 | } 12 | } -------------------------------------------------------------------------------- /ad-eureka/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | application: 3 | name: ad-eureka 4 | 5 | server: 6 | port: 8000 7 | 8 | eureka: 9 | instance: 10 | hostname: localhost 11 | client: 12 | fetch-registry: false 13 | register-with-eureka: false 14 | service-url: 15 | defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/ -------------------------------------------------------------------------------- /javaedge-ad-service/ad-sponsor/src/main/java/com/javaedge/ad/dao/CreativeRepository.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.dao; 2 | 3 | import com.javaedge.ad.entity.Creative; 4 | import org.springframework.data.jpa.repository.JpaRepository; 5 | 6 | /** 7 | * @author sss 8 | * @date 2019/2/5 9 | */ 10 | public interface CreativeRepository extends JpaRepository { 11 | } 12 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-search/src/main/java/com/javaedge/ad/sender/ISender.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.sender; 2 | 3 | import com.javaedge.ad.mysql.dto.MySqlRowData; 4 | 5 | /** 6 | * @author sss 7 | * @date 2019-02-26 8 | */ 9 | public interface ISender { 10 | 11 | /** 12 | * 发送消息到 MQ 13 | * 14 | * @param rowData 15 | */ 16 | void sender(MySqlRowData rowData); 17 | } 18 | -------------------------------------------------------------------------------- /.idea/dictionaries/sss.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | adconf 5 | creatives 6 | finchley 7 | getor 8 | javaedge 9 | kaiping 10 | pian 11 | shishusheng 12 | tiepian 13 | yyyy 14 | 15 | 16 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-sponsor/src/main/java/com/javaedge/ad/dao/unitcondition/AdUnitItRepository.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.dao.unitcondition; 2 | 3 | import com.javaedge.ad.entity.unitcondition.AdUnitIt; 4 | import org.springframework.data.jpa.repository.JpaRepository; 5 | 6 | /** 7 | * @author sss 8 | * @date 2019/2/5 9 | */ 10 | public interface AdUnitItRepository extends JpaRepository { 11 | } 12 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-sponsor/src/main/java/com/javaedge/ad/dao/unitcondition/AdUnitKeywordRepository.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.dao.unitcondition; 2 | 3 | import com.javaedge.ad.entity.unitcondition.AdUnitKeyword; 4 | import org.springframework.data.jpa.repository.JpaRepository; 5 | 6 | /** 7 | * @author sss 8 | * @date 2019/2/5 9 | */ 10 | public interface AdUnitKeywordRepository extends JpaRepository { 11 | } 12 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-sponsor/src/main/java/com/javaedge/ad/dao/unitcondition/CreativeUnitRepository.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.dao.unitcondition; 2 | 3 | import com.javaedge.ad.entity.unitcondition.CreativeUnit; 4 | import org.springframework.data.jpa.repository.JpaRepository; 5 | 6 | /** 7 | * @author sss 8 | * @date 2019/2/5 9 | */ 10 | public interface CreativeUnitRepository extends JpaRepository { 11 | } 12 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-sponsor/src/main/java/com/javaedge/ad/dao/unitcondition/AdUnitDistrictRepository.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.dao.unitcondition; 2 | 3 | import com.javaedge.ad.entity.unitcondition.AdUnitDistrict; 4 | import org.springframework.data.jpa.repository.JpaRepository; 5 | 6 | /** 7 | * @author sss 8 | * @date 2019/2/5 9 | */ 10 | public interface AdUnitDistrictRepository extends JpaRepository { 11 | } 12 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-sponsor/src/main/java/com/javaedge/ad/vo/CreativeResponse.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.vo; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | /** 8 | * @author sss 9 | * @date 2019/2/10 10 | */ 11 | @Data 12 | @NoArgsConstructor 13 | @AllArgsConstructor 14 | public class CreativeResponse { 15 | 16 | private Long id; 17 | private String name; 18 | } 19 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-sponsor/src/main/java/com/javaedge/ad/vo/AdUnitItResponse.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.vo; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | import java.util.List; 8 | 9 | /** 10 | * @author sss 11 | * @date 2019/2/7 12 | */ 13 | @Data 14 | @NoArgsConstructor 15 | @AllArgsConstructor 16 | public class AdUnitItResponse { 17 | 18 | private List ids; 19 | } 20 | 21 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-common/src/main/java/com/javaedge/ad/dump/table/AdUnitItTable.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.dump.table; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | /** 8 | * @author sss 9 | * @date 2019-02-12 10 | */ 11 | @Data 12 | @NoArgsConstructor 13 | @AllArgsConstructor 14 | public class AdUnitItTable { 15 | 16 | private Long unitId; 17 | private String itTag; 18 | } 19 | 20 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-search/src/main/java/com/javaedge/ad/index/interest/UnitItObject.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.index.interest; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | /** 8 | * @author sss 9 | * @date 2019-02-12 10 | */ 11 | @Data 12 | @NoArgsConstructor 13 | @AllArgsConstructor 14 | public class UnitItObject { 15 | 16 | private Long unitId; 17 | private String itTag; 18 | } 19 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-sponsor/src/main/java/com/javaedge/ad/vo/AdUnitDistrictResponse.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.vo; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | import java.util.List; 8 | 9 | /** 10 | * @author sss 11 | * @date 2019/2/7 12 | */ 13 | @Data 14 | @NoArgsConstructor 15 | @AllArgsConstructor 16 | public class AdUnitDistrictResponse { 17 | 18 | private List ids; 19 | } 20 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-sponsor/src/main/java/com/javaedge/ad/vo/AdUnitKeywordResponse.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.vo; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | import java.util.List; 8 | 9 | /** 10 | * @author sss 11 | * @date 2019/2/7 12 | */ 13 | @Data 14 | @NoArgsConstructor 15 | @AllArgsConstructor 16 | public class AdUnitKeywordResponse { 17 | 18 | private List id; 19 | } 20 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-search/src/main/java/com/javaedge/ad/search/ISearch.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.search; 2 | 3 | import com.javaedge.ad.search.vo.SearchRequest; 4 | import com.javaedge.ad.search.vo.SearchResponse; 5 | 6 | /** 7 | * @author sss 8 | * @date 2019-02-26 9 | */ 10 | public interface ISearch { 11 | 12 | /** 13 | * 14 | * @param request 15 | * @return 16 | */ 17 | SearchResponse fetchAds(SearchRequest request); 18 | } 19 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-sponsor/src/main/java/com/javaedge/ad/vo/CreativeUnitResponse.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.vo; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | import java.util.List; 8 | 9 | /** 10 | * @author sss 11 | * @date 2019/2/10 12 | */ 13 | @Data 14 | @NoArgsConstructor 15 | @AllArgsConstructor 16 | public class CreativeUnitResponse { 17 | 18 | private List ids; 19 | } 20 | 21 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-common/src/main/java/com/javaedge/ad/dump/table/AdCreativeUnitTable.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.dump.table; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | /** 8 | * @author sss 9 | * @date 2019-02-12 10 | */ 11 | @Data 12 | @NoArgsConstructor 13 | @AllArgsConstructor 14 | public class AdCreativeUnitTable { 15 | 16 | private Long adId; 17 | private Long unitId; 18 | } 19 | 20 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-search/src/main/java/com/javaedge/ad/index/keyword/UnitKeywordObject.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.index.keyword; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | /** 8 | * @author sss 9 | * @date 2019-02-11 10 | */ 11 | @Data 12 | @NoArgsConstructor 13 | @AllArgsConstructor 14 | public class UnitKeywordObject { 15 | 16 | private Long unitId; 17 | private String keyword; 18 | } 19 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-search/src/main/java/com/javaedge/ad/search/vo/feature/ItFeature.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.search.vo.feature; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | import java.util.List; 8 | 9 | /** 10 | * @author sss 11 | * @date 2019-02-26 12 | */ 13 | @Data 14 | @NoArgsConstructor 15 | @AllArgsConstructor 16 | public class ItFeature { 17 | 18 | private List its; 19 | } 20 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-common/src/main/java/com/javaedge/ad/dump/table/AdUnitKeywordTable.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.dump.table; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | /** 8 | * @author sss 9 | * @date 2019-02-12 10 | */ 11 | @Data 12 | @NoArgsConstructor 13 | @AllArgsConstructor 14 | public class AdUnitKeywordTable { 15 | 16 | private Long unitId; 17 | private String keyword; 18 | } 19 | 20 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-sponsor/src/main/java/com/javaedge/ad/vo/AdUnitResponse.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.vo; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | import java.util.List; 8 | 9 | /** 10 | * @author sss 11 | * @date 2019/2/6 12 | */ 13 | @Data 14 | @NoArgsConstructor 15 | @AllArgsConstructor 16 | public class AdUnitResponse { 17 | 18 | private Long id; 19 | private String unitName; 20 | } 21 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-search/src/main/java/com/javaedge/ad/search/vo/feature/KeywordFeature.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.search.vo.feature; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | import java.util.List; 8 | 9 | /** 10 | * @author sss 11 | * @date 2019-02-26 12 | */ 13 | @Data 14 | @NoArgsConstructor 15 | @AllArgsConstructor 16 | public class KeywordFeature { 17 | 18 | private List keywords; 19 | } 20 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-sponsor/src/main/java/com/javaedge/ad/vo/AdPlanResponse.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.vo; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | import org.apache.commons.lang.StringUtils; 7 | 8 | /** 9 | * @author sss 10 | * @date 2019/2/6 11 | */ 12 | @Data 13 | @NoArgsConstructor 14 | @AllArgsConstructor 15 | public class AdPlanResponse { 16 | 17 | private Long id; 18 | private String planName; 19 | } 20 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-sponsor/src/test/java/com/javaedge/ad/Application.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | /** 7 | * @author sss 8 | * @date 2019-02-12 9 | */ 10 | @SpringBootApplication 11 | public class Application { 12 | 13 | public static void main(String[] args) { 14 | 15 | SpringApplication.run(Application.class, args); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-search/src/main/java/com/javaedge/ad/index/creativeunit/CreativeUnitObject.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.index.creativeunit; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | /** 8 | * @author sss 9 | * @date 2019-02-12 10 | */ 11 | @Data 12 | @NoArgsConstructor 13 | @AllArgsConstructor 14 | public class CreativeUnitObject { 15 | 16 | private Long adId; 17 | private Long unitId; 18 | 19 | // adId-unitId 20 | } -------------------------------------------------------------------------------- /javaedge-ad-service/ad-sponsor/src/main/java/com/javaedge/ad/service/ICreativeService.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.service; 2 | 3 | import com.javaedge.ad.vo.CreativeRequest; 4 | import com.javaedge.ad.vo.CreativeResponse; 5 | 6 | /** 7 | * @author sss 8 | * @date 2019/2/9 9 | */ 10 | public interface ICreativeService { 11 | 12 | /** 13 | * 创建创意 14 | * 15 | * @param request 16 | * @return 17 | */ 18 | CreativeResponse createCreative(CreativeRequest request); 19 | } 20 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-common/src/main/java/com/javaedge/ad/dump/table/AdUnitDistrictTable.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.dump.table; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | /** 8 | * @author sss 9 | * @date 2019-02-12 10 | */ 11 | @Data 12 | @NoArgsConstructor 13 | @AllArgsConstructor 14 | public class AdUnitDistrictTable { 15 | 16 | private Long unitId; 17 | private String province; 18 | private String city; 19 | } 20 | 21 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-search/src/main/java/com/javaedge/ad/client/vo/AdPlanGetRequest.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.client.vo; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | import java.util.List; 8 | 9 | /** 10 | * @author sss 11 | * @date 2019-02-11 12 | */ 13 | @Data 14 | @NoArgsConstructor 15 | @AllArgsConstructor 16 | public class AdPlanGetRequest { 17 | 18 | private Long userId; 19 | private List ids; 20 | } 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-common/src/main/java/com/javaedge/ad/annotation/IgnoreResponseAdvice.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.annotation; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | /** 9 | * @author sss 10 | * @date 2019/1/31 11 | */ 12 | @Target({ElementType.METHOD, ElementType.TYPE}) 13 | @Retention(RetentionPolicy.RUNTIME) 14 | public @interface IgnoreResponseAdvice { 15 | } 16 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-search/src/main/java/com/javaedge/ad/index/CommonStatus.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.index; 2 | 3 | import lombok.Getter; 4 | 5 | /** 6 | * @author sss 7 | * @date 2019/2/27 8 | */ 9 | @Getter 10 | public enum CommonStatus { 11 | 12 | VALID(1, "有效状态"), 13 | INVALID(0, "无效状态"); 14 | 15 | private Integer status; 16 | private String desc; 17 | 18 | CommonStatus(Integer status, String desc) { 19 | this.status = status; 20 | this.desc = desc; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-search/src/main/java/com/javaedge/ad/search/vo/media/Geo.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.search.vo.media; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | /** 8 | * @author sss 9 | * @date 2019-02-26 10 | */ 11 | @Data 12 | @NoArgsConstructor 13 | @AllArgsConstructor 14 | public class Geo { 15 | 16 | private Float latitude; 17 | private Float longitude; 18 | 19 | private String city; 20 | private String province; 21 | } 22 | -------------------------------------------------------------------------------- /ad-gateway/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 9000 3 | spring: 4 | application: 5 | name: ad-gateway 6 | eureka: 7 | client: 8 | service-url: 9 | defaultZone: http://server1:8000/eureka/ 10 | 11 | zuul: 12 | prefix: /javaedge 13 | routes: 14 | sponsor: 15 | path: /ad-sponsor/** 16 | serviceId: eureka-client-ad-sponsor 17 | strip-prefix: false 18 | search: 19 | path: /ad-search/** 20 | serviceId: eureka-client-ad-search 21 | strip-prefix: false 22 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-search/src/main/java/com/javaedge/ad/mysql/dto/Template.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.mysql.dto; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | import java.util.List; 8 | 9 | /** 10 | * 表达整个模板文件 11 | * 12 | * @author sss 13 | * @date 2019-02-25 14 | */ 15 | @Data 16 | @NoArgsConstructor 17 | @AllArgsConstructor 18 | public class Template { 19 | 20 | private String database; 21 | private List tableList; 22 | } 23 | 24 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-sponsor/src/main/java/com/javaedge/ad/constant/CommonStatus.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.constant; 2 | 3 | import lombok.Getter; 4 | 5 | /** 6 | * @author sss 7 | * @date 2019/2/1 8 | */ 9 | @Getter 10 | public enum CommonStatus { 11 | 12 | VALID(1, "有效状态"), 13 | INVALID(0, "无效状态"); 14 | 15 | private Integer status; 16 | private String desc; 17 | 18 | CommonStatus(Integer status, String desc) { 19 | this.status = status; 20 | this.desc = desc; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-sponsor/src/main/java/com/javaedge/ad/constant/CreativeType.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.constant; 2 | 3 | import com.javaedge.ad.entity.Creative; 4 | 5 | /** 6 | * @author sss 7 | * @date 2019/2/4 8 | */ 9 | public enum CreativeType { 10 | 11 | IMAGE(1, "图片"), 12 | VIDEO(2, "视频"), 13 | TEXT(3, "文本"); 14 | 15 | private int type; 16 | private String desc; 17 | 18 | CreativeType(int type, String desc) { 19 | this.type = type; 20 | this.desc = desc; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-common/src/main/java/com/javaedge/ad/dump/table/AdUnitTable.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.dump.table; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | /** 8 | * @author sss 9 | * @date 2019-02-12 10 | */ 11 | @Data 12 | @NoArgsConstructor 13 | @AllArgsConstructor 14 | public class AdUnitTable { 15 | 16 | private Long unitId; 17 | private Integer unitStatus; 18 | private Integer positionType; 19 | 20 | private Long planId; 21 | } 22 | 23 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-search/src/main/java/com/javaedge/ad/index/DataLevel.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.index; 2 | 3 | import lombok.Getter; 4 | 5 | /** 6 | * @author sss 7 | * @date 2019-02-22 8 | */ 9 | @Getter 10 | public enum DataLevel { 11 | 12 | LEVEL2("2", "level 2"), 13 | LEVEL3("3", "level 3"), 14 | LEVEL4("4", "level 4"); 15 | 16 | private String level; 17 | private String desc; 18 | 19 | DataLevel(String level, String desc) { 20 | this.level = level; 21 | this.desc = desc; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-search/src/main/java/com/javaedge/ad/mysql/listener/Ilistener.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.mysql.listener; 2 | 3 | import com.javaedge.ad.mysql.dto.BinlogRowData; 4 | 5 | /** 6 | * 监听器 7 | * 8 | * @author sss 9 | * @date 2019-02-25 10 | */ 11 | public interface Ilistener { 12 | 13 | /** 14 | * 对应不同表定义不同的数据更新方法,即注册不同的监听器. 15 | */ 16 | void register(); 17 | 18 | /** 19 | * 事件监听 20 | * 21 | * @param eventData 对应于源码中的Event对象. 22 | */ 23 | void onEvent(BinlogRowData eventData); 24 | } 25 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-sponsor/src/main/java/com/javaedge/ad/dao/AdUserRepository.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.dao; 2 | 3 | import com.javaedge.ad.entity.AdUser; 4 | import org.springframework.data.jpa.repository.JpaRepository; 5 | 6 | /** 7 | * @author sss 8 | * @date 2019/2/4 9 | */ 10 | public interface AdUserRepository extends JpaRepository { 11 | 12 | /** 13 | * 根据用户名查找用户记录 14 | * 15 | * @param username 16 | * @return 17 | */ 18 | AdUser findByUsername(String username); 19 | 20 | 21 | 22 | 23 | 24 | } 25 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-search/src/main/java/com/javaedge/ad/index/district/UnitDistrictObject.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.index.district; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | /** 8 | * @author sss 9 | * @date 2019-02-12 10 | */ 11 | @Data 12 | @NoArgsConstructor 13 | @AllArgsConstructor 14 | public class UnitDistrictObject { 15 | 16 | private Long unitId; 17 | private String province; 18 | private String city; 19 | 20 | // > 21 | // province-city 22 | } 23 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-sponsor/src/main/java/com/javaedge/ad/constant/CreativeMaterialType.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.constant; 2 | 3 | /** 4 | * @author sss 5 | * @date 2019/2/4 6 | */ 7 | public enum CreativeMaterialType { 8 | 9 | JPG(1, "jpg"), 10 | BMP(2, "bmp"), 11 | 12 | MP4(3, "mp4"), 13 | AVI(4, "avi"), 14 | 15 | TXY(5, "txt"); 16 | 17 | 18 | private int type; 19 | private String desc; 20 | 21 | CreativeMaterialType(int type, String desc) { 22 | this.type = type; 23 | this.desc = desc; 24 | } 25 | } 26 | 27 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-sponsor/src/main/java/com/javaedge/ad/vo/CreateUserRequest.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.vo; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | import org.apache.commons.lang.StringUtils; 7 | 8 | /** 9 | * @author sss 10 | * @date 2019/2/5 11 | */ 12 | @Data 13 | @NoArgsConstructor 14 | @AllArgsConstructor 15 | public class CreateUserRequest { 16 | 17 | private String username; 18 | 19 | public boolean validate() { 20 | return StringUtils.isEmpty(username); 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /ad-eureka/src/main/java/com/javaedge/ad/EurekaApplication.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer; 6 | 7 | /** 8 | * @author sss 9 | * @date 2019/1/28 10 | */ 11 | @EnableEurekaServer 12 | @SpringBootApplication 13 | public class EurekaApplication { 14 | 15 | public static void main(String[] args) { 16 | SpringApplication.run(EurekaApplication.class, args); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-search/src/main/java/com/javaedge/ad/search/vo/media/App.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.search.vo.media; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | /** 8 | * @author sss 9 | * @date 2019-02-26 10 | */ 11 | @Data 12 | @NoArgsConstructor 13 | @AllArgsConstructor 14 | public class App { 15 | 16 | // 应用编码 17 | private String appCode; 18 | // 应用名称 19 | private String appName; 20 | // 应用包名 21 | private String packageName; 22 | // activity 名称 23 | private String activityName; 24 | } 25 | -------------------------------------------------------------------------------- /ad-gateway/src/main/java/com/javaedge/ad/ZuulGatewayApplication.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.cloud.client.SpringCloudApplication; 5 | import org.springframework.cloud.netflix.zuul.EnableZuulProxy; 6 | 7 | 8 | /** 9 | * @author sss 10 | * @date 2019/1/28 11 | */ 12 | @EnableZuulProxy 13 | @SpringCloudApplication 14 | public class ZuulGatewayApplication { 15 | 16 | public static void main(String[] args) { 17 | SpringApplication.run(ZuulGatewayApplication.class, args); 18 | } 19 | 20 | } 21 | 22 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-search/src/main/java/com/javaedge/ad/mysql/dto/BinlogRowData.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.mysql.dto; 2 | 3 | import com.github.shyiko.mysql.binlog.event.EventType; 4 | import lombok.Data; 5 | 6 | import java.util.List; 7 | import java.util.Map; 8 | 9 | /** 10 | * 日志文件相应的Java对象 11 | * 12 | * @author sss 13 | * @date 2019-02-25 14 | */ 15 | @Data 16 | public class BinlogRowData { 17 | 18 | private TableTemplate table; 19 | 20 | private EventType eventType; 21 | 22 | private List> after; 23 | 24 | private List> before; 25 | } 26 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-sponsor/src/main/java/com/javaedge/ad/service/IUserService.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.service; 2 | 3 | import com.javaedge.ad.exception.AdException; 4 | import com.javaedge.ad.vo.CreateUserRequest; 5 | import com.javaedge.ad.vo.CreateUserResponse; 6 | 7 | /** 8 | * @author sss 9 | * @date 2019/2/5 10 | */ 11 | public interface IUserService { 12 | 13 | /** 14 | * 创建用户 15 | * 16 | * @param request 17 | * @return 18 | * @throws AdException 19 | */ 20 | CreateUserResponse createUser(CreateUserRequest request) throws AdException; 21 | 22 | 23 | 24 | } 25 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-sponsor/src/main/java/com/javaedge/ad/vo/AdUnitItRequest.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.vo; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | import java.util.List; 8 | 9 | /** 10 | * @author sss 11 | * @date 2019/2/7 12 | */ 13 | @Data 14 | @NoArgsConstructor 15 | @AllArgsConstructor 16 | public class AdUnitItRequest { 17 | 18 | private List unitIts; 19 | 20 | @Data 21 | @NoArgsConstructor 22 | @AllArgsConstructor 23 | public static class UnitIt { 24 | 25 | private Long unitId; 26 | private String itTag; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-common/src/main/java/com/javaedge/ad/dump/table/AdCreativeTable.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.dump.table; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | /** 8 | * @author sss 9 | * @date 2019-02-12 10 | */ 11 | @Data 12 | @NoArgsConstructor 13 | @AllArgsConstructor 14 | public class AdCreativeTable { 15 | 16 | private Long adId; 17 | private String name; 18 | private Integer type; 19 | private Integer materialType; 20 | private Integer height; 21 | private Integer width; 22 | private Integer auditStatus; 23 | private String adUrl; 24 | } 25 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-sponsor/src/main/java/com/javaedge/ad/constant/Constants.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.constant; 2 | 3 | /** 4 | * @author sss 5 | * @date 2019/2/5 6 | */ 7 | public class Constants { 8 | 9 | public static class ErrorMsg { 10 | 11 | public static final String REQUEST_PARAM_ERROR = "请求参数错误"; 12 | public static final String SAME_NAME_ERROR = "存在同名用户"; 13 | 14 | public static final String RECORD_NOT_FOUND = "找不到数据记录"; 15 | public static final String SAME_NAME__PLAN_ERROR = "存在同名的推广计划 "; 16 | 17 | public static final String SAME_NAME_UNIT_ERROR = "存在同名的推广单元 "; 18 | 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-search/src/main/java/com/javaedge/ad/client/vo/AdPlan.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.client.vo; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | import java.util.Date; 8 | 9 | /** 10 | * @author sss 11 | * @date 2019-02-11 12 | */ 13 | @Data 14 | @NoArgsConstructor 15 | @AllArgsConstructor 16 | public class AdPlan { 17 | 18 | private Long id; 19 | private Long userId; 20 | private String planName; 21 | private Integer planStatus; 22 | private Date startDate; 23 | private Date endDate; 24 | private Date createTime; 25 | private Date updateTime; 26 | } 27 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-common/src/main/java/com/javaedge/ad/dump/table/AdPlanTable.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.dump.table; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | import java.util.Date; 8 | 9 | /** 10 | * @author sss 11 | * @date 2019-02-12 12 | */ 13 | @Data 14 | @NoArgsConstructor 15 | @AllArgsConstructor 16 | public class AdPlanTable { 17 | 18 | private Long id; 19 | private Long userId; 20 | private Integer planStatus; 21 | 22 | /** 23 | * 对于 Date 类型,由于将 binlog 转化为了字符串,需搞清楚 Date 的字符串表达形式 24 | */ 25 | private Date startDate; 26 | private Date endDate; 27 | } 28 | 29 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-common/src/main/java/com/javaedge/ad/vo/CommonResponse.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.vo; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | import java.io.Serializable; 8 | 9 | /** 10 | * @author sss 11 | * @date 2019/1/31 12 | */ 13 | @Data 14 | @AllArgsConstructor 15 | @NoArgsConstructor 16 | public class CommonResponse implements Serializable { 17 | 18 | private Integer code; 19 | private String message; 20 | private T data; 21 | 22 | public CommonResponse(Integer code, String message) { 23 | this.code=code; 24 | this.message = message; 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-sponsor/src/main/java/com/javaedge/ad/vo/AdUnitKeywordRequest.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.vo; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | import java.util.List; 8 | 9 | /** 10 | * @author sss 11 | * @date 2019/2/7 12 | */ 13 | @Data 14 | @NoArgsConstructor 15 | @AllArgsConstructor 16 | public class AdUnitKeywordRequest { 17 | 18 | private List unitKeywords; 19 | 20 | @Data 21 | @NoArgsConstructor 22 | @AllArgsConstructor 23 | public static class UnitKeyword { 24 | 25 | private Long unitId; 26 | private String keyword; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-sponsor/src/main/java/com/javaedge/ad/vo/CreateUserResponse.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.vo; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | import org.apache.commons.lang.StringUtils; 7 | 8 | import java.util.Date; 9 | 10 | /** 11 | * 返回给广告主的响应 12 | * 13 | * @author sss 14 | * @date 2019/2/5 15 | */ 16 | @Data 17 | @NoArgsConstructor 18 | @AllArgsConstructor 19 | public class CreateUserResponse { 20 | 21 | private Long userId; 22 | 23 | private String username; 24 | 25 | private String token; 26 | 27 | private Date createTime; 28 | 29 | private Date updateTime; 30 | 31 | } 32 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-sponsor/src/main/java/com/javaedge/ad/vo/CreativeUnitRequest.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.vo; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | import java.util.List; 8 | 9 | /** 10 | * @author sss 11 | * @date 2019/2/10 12 | */ 13 | @Data 14 | @NoArgsConstructor 15 | @AllArgsConstructor 16 | public class CreativeUnitRequest { 17 | 18 | private List unitItems; 19 | 20 | @Data 21 | @NoArgsConstructor 22 | @AllArgsConstructor 23 | public static class CreativeUnitItem { 24 | 25 | private Long creativeId; 26 | private Long unitId; 27 | } 28 | } 29 | 30 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-search/src/main/java/com/javaedge/ad/client/SponsorClientHystrix.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.client; 2 | 3 | import com.javaedge.ad.client.vo.AdPlan; 4 | import com.javaedge.ad.client.vo.AdPlanGetRequest; 5 | import com.javaedge.ad.vo.CommonResponse; 6 | import org.springframework.stereotype.Component; 7 | 8 | import java.util.List; 9 | 10 | /** 11 | * @author sss 12 | * @date 2019-02-11 13 | */ 14 | @Component 15 | public class SponsorClientHystrix implements SponsorClient{ 16 | 17 | @Override 18 | public CommonResponse> getAdPlans(AdPlanGetRequest request) { 19 | return new CommonResponse<>(-1, "eureka-client-ad-sponsor error"); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-search/src/main/java/com/javaedge/ad/search/vo/feature/DistrictFeature.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.search.vo.feature; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | import java.util.List; 8 | 9 | /** 10 | * @author sss 11 | * @date 2019-02-26 12 | */ 13 | @Data 14 | @NoArgsConstructor 15 | @AllArgsConstructor 16 | public class DistrictFeature { 17 | 18 | private List districts; 19 | 20 | @Data 21 | @NoArgsConstructor 22 | @AllArgsConstructor 23 | public static class ProvinceAndCity { 24 | 25 | private String province; 26 | private String city; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-search/src/main/java/com/javaedge/ad/index/IndexAware.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.index; 2 | 3 | /** 4 | * @author sss 5 | * @date 2019-02-11 6 | */ 7 | public interface IndexAware { 8 | 9 | /** 10 | * 11 | * @param key 12 | * @return 13 | */ 14 | V get(K key); 15 | 16 | /** 17 | * 18 | * @param key 19 | * @param value 20 | */ 21 | void add(K key, V value); 22 | 23 | 24 | /** 25 | * 26 | * @param key 27 | * @param value 28 | */ 29 | void update(K key, V value); 30 | 31 | /** 32 | * 33 | * @param key 34 | * @param value 35 | */ 36 | void delete(K key, V value); 37 | } 38 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-search/src/main/java/com/javaedge/ad/mysql/dto/MySqlRowData.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.mysql.dto; 2 | 3 | import com.javaedge.ad.mysql.constant.OpType; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | 8 | import java.util.ArrayList; 9 | import java.util.List; 10 | import java.util.Map; 11 | 12 | /** 13 | * @author sss 14 | * @date 2019-02-25 15 | */ 16 | @Data 17 | @NoArgsConstructor 18 | @AllArgsConstructor 19 | public class MySqlRowData { 20 | 21 | private String tableName; 22 | 23 | private String level; 24 | 25 | private OpType opType; 26 | 27 | private List> fieldValueMap = new ArrayList<>(); 28 | } 29 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-sponsor/src/main/java/com/javaedge/ad/vo/AdUnitRequest.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.vo; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | import org.apache.commons.lang.StringUtils; 7 | 8 | /** 9 | * @author sss 10 | * @date 2019/2/6 11 | */ 12 | @Data 13 | @NoArgsConstructor 14 | @AllArgsConstructor 15 | public class AdUnitRequest { 16 | 17 | private Long planId; 18 | private String unitName; 19 | 20 | private Integer positionType; 21 | private Long budget; 22 | 23 | public boolean createValidate() { 24 | 25 | return null != planId && !StringUtils.isEmpty(unitName) && positionType != null && budget != null; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 7 | 8 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-search/src/main/java/com/javaedge/ad/search/vo/media/AdSlot.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.search.vo.media; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | import java.util.List; 8 | 9 | /** 10 | * @author sss 11 | * @date 2019-02-26 12 | */ 13 | @Data 14 | @NoArgsConstructor 15 | @AllArgsConstructor 16 | public class AdSlot { 17 | 18 | // 广告位编码 19 | private String adSlotCode; 20 | 21 | // 流量类型 22 | private Integer positionType; 23 | 24 | // 宽和高 25 | private Integer width; 26 | private Integer height; 27 | 28 | // 广告物料类型: 图片, 视频 29 | private List type; 30 | 31 | // 最低出价 32 | private Integer minCpm; 33 | } 34 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-search/src/main/java/com/javaedge/ad/mysql/constant/OpType.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.mysql.constant; 2 | 3 | import com.github.shyiko.mysql.binlog.event.EventType; 4 | 5 | /** 6 | * @author sss 7 | * @date 2019-02-25 8 | */ 9 | public enum OpType { 10 | 11 | ADD, 12 | UPDATE, 13 | DELETE, 14 | OTHER; 15 | 16 | public static OpType to(EventType eventType) { 17 | 18 | switch (eventType) { 19 | case EXT_WRITE_ROWS: 20 | return ADD; 21 | case EXT_UPDATE_ROWS: 22 | return UPDATE; 23 | case EXT_DELETE_ROWS: 24 | return DELETE; 25 | 26 | default: 27 | return OTHER; 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-sponsor/src/main/java/com/javaedge/ad/dao/AdUnitRepository.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.dao; 2 | 3 | import com.javaedge.ad.entity.unitcondition.AdUnit; 4 | import org.springframework.data.jpa.repository.JpaRepository; 5 | 6 | import java.util.List; 7 | 8 | /** 9 | * @author sss 10 | * @date 2019/2/4 11 | */ 12 | public interface AdUnitRepository extends JpaRepository { 13 | 14 | /** 15 | * 16 | * @param planId 17 | * @param unitName 18 | * @return 19 | */ 20 | AdUnit findByPlanIdAndUnitName(Long planId, String unitName); 21 | 22 | /** 23 | * 24 | * @param unitStatus 25 | * @return 26 | */ 27 | List findAllByUnitStatus(Integer unitStatus); 28 | } 29 | 30 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-sponsor/src/main/java/com/javaedge/ad/vo/AdPlanGetRequest.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.vo; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | import org.apache.commons.lang.StringUtils; 7 | import org.springframework.util.CollectionUtils; 8 | import org.w3c.dom.stylesheets.LinkStyle; 9 | 10 | import java.util.List; 11 | 12 | /** 13 | * @author sss 14 | * @date 2019/2/6 15 | */ 16 | @Data 17 | @NoArgsConstructor 18 | @AllArgsConstructor 19 | public class AdPlanGetRequest { 20 | 21 | private Long userId; 22 | private List ids; 23 | 24 | public boolean validate() { 25 | return userId != null 26 | && CollectionUtils.isEmpty(ids); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-sponsor/src/main/java/com/javaedge/ad/vo/AdUnitDistrictRequest.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.vo; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | import java.util.List; 8 | 9 | /** 10 | * @author sss 11 | * @date 2019/2/7 12 | */ 13 | @Data 14 | @NoArgsConstructor 15 | @AllArgsConstructor 16 | public class AdUnitDistrictRequest { 17 | 18 | /** 19 | * 最好使用自定义的字典实现 20 | */ 21 | private List unitDistricts; 22 | 23 | @Data 24 | @NoArgsConstructor 25 | @AllArgsConstructor 26 | public static class UnitDistrict { 27 | 28 | private Long unitId; 29 | private String province; 30 | private String city; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-sponsor/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 7000 3 | servlet: 4 | # 所有 controller 的前缀 5 | context-path: /ad-sponsor 6 | 7 | spring: 8 | application: 9 | # 应用名称 10 | name: eureka-client-ad-sponsor 11 | jpa: 12 | show-sql: true 13 | hibernate: 14 | ddl-auto: none 15 | properties: 16 | hibernate.format_sql: true 17 | open-in-view: false 18 | datasource: 19 | url: jdbc:mysql://127.0.0.1:3306/javaedge_ad_data?autoReconnect=true 20 | username: root 21 | password: root 22 | tomcat: 23 | max-active: 4 24 | min-idle: 2 25 | initial-size: 2 26 | 27 | eureka: 28 | client: 29 | service-url: 30 | defaultZone: http://server1:8000/eureka/ 31 | 32 | 33 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-sponsor/src/test/resources/application.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 7000 3 | servlet: 4 | # 所有 controller 的前缀 5 | context-path: /ad-sponsor 6 | 7 | spring: 8 | application: 9 | # 应用名称 10 | name: eureka-client-ad-sponsor 11 | jpa: 12 | show-sql: true 13 | hibernate: 14 | ddl-auto: none 15 | properties: 16 | hibernate.format_sql: true 17 | open-in-view: false 18 | datasource: 19 | url: jdbc:mysql://127.0.0.1:3306/javaedge_ad_data?autoReconnect=true 20 | username: root 21 | password: root 22 | tomcat: 23 | max-active: 4 24 | min-idle: 2 25 | initial-size: 2 26 | 27 | eureka: 28 | client: 29 | service-url: 30 | defaultZone: http://server1:8000/eureka/ 31 | 32 | 33 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-search/src/main/java/com/javaedge/ad/search/vo/media/Device.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.search.vo.media; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | /** 8 | * @author sss 9 | * @date 2019-02-26 10 | */ 11 | @Data 12 | @NoArgsConstructor 13 | @AllArgsConstructor 14 | public class Device { 15 | 16 | // 设备 id 17 | private String deviceCode; 18 | 19 | // mac 20 | private String mac; 21 | 22 | // ip 23 | private String ip; 24 | 25 | // 机型编码 26 | private String model; 27 | 28 | // 分辨率尺寸 29 | private String displaySize; 30 | 31 | // 屏幕尺寸 32 | private String screenSize; 33 | 34 | // 设备序列号 35 | private String serialName; 36 | } 37 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-search/src/main/java/com/javaedge/ad/mysql/BinlogConfig.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.mysql; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | import org.springframework.boot.context.properties.ConfigurationProperties; 7 | import org.springframework.stereotype.Component; 8 | 9 | /** 10 | * @author sss 11 | * @date 2019-02-25 12 | */ 13 | @Component 14 | @ConfigurationProperties(prefix = "adconf.mysql") 15 | @Data 16 | @NoArgsConstructor 17 | @AllArgsConstructor 18 | public class BinlogConfig { 19 | 20 | private String host; 21 | private Integer port; 22 | private String username; 23 | private String password; 24 | 25 | private String binlogName; 26 | private Long position; 27 | } 28 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-search/src/main/java/com/javaedge/ad/mysql/dto/JsonTable.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.mysql.dto; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | import java.util.List; 8 | 9 | /** 10 | * 表达模板文件中的表 11 | * 12 | * @author sss 13 | * @date 2019-02-25 14 | */ 15 | @Data 16 | @AllArgsConstructor 17 | @NoArgsConstructor 18 | public class JsonTable { 19 | 20 | private String tableName; 21 | private Integer level; 22 | 23 | private List insert; 24 | private List update; 25 | private List delete; 26 | 27 | @Data 28 | @NoArgsConstructor 29 | @AllArgsConstructor 30 | public static class Column { 31 | 32 | private String column; 33 | } 34 | } 35 | 36 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-sponsor/src/main/java/com/javaedge/ad/SponsorApplication.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker; 6 | import org.springframework.cloud.netflix.eureka.EnableEurekaClient; 7 | import org.springframework.cloud.openfeign.EnableFeignClients; 8 | 9 | /** 10 | * @author sss 11 | * @date 2019/2/1 12 | */ 13 | @EnableFeignClients 14 | @EnableCircuitBreaker 15 | @EnableEurekaClient 16 | @SpringBootApplication 17 | public class SponsorApplication { 18 | 19 | public static void main(String[] args) { 20 | SpringApplication.run(SponsorApplication.class, args); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-common/src/main/java/com/javaedge/ad/dump/DConstant.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.dump; 2 | 3 | /** 4 | * @author sss 5 | * @date 2019-02-12 6 | */ 7 | public class DConstant { 8 | 9 | public static final String DATA_ROOT_DIR = "/Volume/doc/javaedge/mysql_data/"; 10 | 11 | // 各个表数据的存储文件名 12 | public static final String AD_PLAN = "ad_plan.data"; 13 | public static final String AD_UNIT = "ad_unit.data"; 14 | public static final String AD_CREATIVE = "ad_creative.data"; 15 | public static final String AD_CREATIVE_UNIT = "ad_creative_unit.data"; 16 | public static final String AD_UNIT_IT = "ad_unit_it.data"; 17 | public static final String AD_UNIT_DISTRICT = "ad_unit_district.data"; 18 | public static final String AD_UNIT_KEYWORD = "ad_unit_keyword.data"; 19 | } 20 | -------------------------------------------------------------------------------- /javaedge-ad-service/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | sss-ad 7 | com.sss.ad 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | javaedge-ad-service 13 | 1.0-SNAPSHOT 14 | 15 | ad-common 16 | ad-sponsor 17 | ad-search 18 | 19 | pom 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-search/src/main/java/com/javaedge/ad/mysql/dto/TableTemplate.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.mysql.dto; 2 | 3 | import com.javaedge.ad.mysql.constant.OpType; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | 8 | import java.util.HashMap; 9 | import java.util.List; 10 | import java.util.Map; 11 | 12 | /** 13 | * 表达模板文件中的 表&层级 14 | * 15 | * @author sss 16 | * @date 2019-02-25 17 | */ 18 | @Data 19 | @NoArgsConstructor 20 | @AllArgsConstructor 21 | public class TableTemplate { 22 | 23 | private String tableName; 24 | private String level; 25 | 26 | private Map> opTypeFieldSetMap = new HashMap<>(); 27 | 28 | /** 29 | * 字段索引 -> 字段名 的映射关系 30 | * */ 31 | private Map posMap = new HashMap<>(); 32 | } 33 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-search/src/main/java/com/javaedge/ad/index/adunit/AdUnitConstants.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.index.adunit; 2 | 3 | /** 4 | * @author sss 5 | * @date 2019-02-26 6 | */ 7 | public class AdUnitConstants { 8 | 9 | public static class POSITION_TYPE { 10 | 11 | /** 12 | * 开屏广告位 13 | */ 14 | public static final int KAIPING = 1; 15 | 16 | /** 17 | * 贴片广告 18 | */ 19 | public static final int TIEPIAN = 2; 20 | 21 | /** 22 | * 视频播放中显示的广告 23 | */ 24 | public static final int TIEPIAN_MIDDLE = 4; 25 | 26 | /** 27 | * 视频播放暂停时广告 28 | */ 29 | public static final int TIEPIAN_PAUSE = 8; 30 | 31 | /** 32 | * 视频播放后的广告位 33 | */ 34 | public static final int TIEPIAN_POST = 16; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-search/src/main/java/com/javaedge/ad/runner/BinlogRunner.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.runner; 2 | 3 | import com.javaedge.ad.mysql.BinlogClient; 4 | import lombok.extern.slf4j.Slf4j; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.boot.CommandLineRunner; 7 | import org.springframework.stereotype.Component; 8 | 9 | /** 10 | * @author sss 11 | * @date 2019-02-25 12 | */ 13 | @Slf4j 14 | @Component 15 | public class BinlogRunner implements CommandLineRunner { 16 | 17 | private final BinlogClient client; 18 | 19 | @Autowired 20 | public BinlogRunner(BinlogClient client) { 21 | this.client = client; 22 | } 23 | 24 | @Override 25 | public void run(String... strings) throws Exception { 26 | 27 | log.info("Coming in BinlogRunner..."); 28 | client.connect(); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-common/src/main/java/com/javaedge/ad/advice/GlobalExceptionAdvice.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.advice; 2 | 3 | import com.javaedge.ad.exception.AdException; 4 | import com.javaedge.ad.vo.CommonResponse; 5 | import org.springframework.web.bind.annotation.ExceptionHandler; 6 | import org.springframework.web.bind.annotation.RestControllerAdvice; 7 | 8 | import javax.servlet.http.HttpServletRequest; 9 | 10 | /** 11 | * @author sss 12 | * @date 2019/1/31 13 | */ 14 | @RestControllerAdvice 15 | public class GlobalExceptionAdvice { 16 | 17 | @ExceptionHandler(value = AdException.class) 18 | public CommonResponse handlerAdException(HttpServletRequest request, AdException ex) { 19 | CommonResponse response = new CommonResponse<>(-1, "business error"); 20 | response.setData(ex.getMessage()); 21 | return response; 22 | } 23 | } 24 | 25 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-sponsor/src/main/java/com/javaedge/ad/utils/CommonUtils.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.utils; 2 | 3 | import com.javaedge.ad.exception.AdException; 4 | import org.apache.commons.codec.digest.DigestUtils; 5 | import org.apache.commons.lang.time.DateUtils; 6 | 7 | import java.util.Date; 8 | 9 | /** 10 | * @author sss 11 | * @date 2019/2/5 12 | */ 13 | public class CommonUtils { 14 | 15 | private static String[] parsePatterns = { 16 | "yyyy-MM-dd", "yyyy/MM/dd", "yyyy.MM.dd" 17 | }; 18 | 19 | public static String md5(String value) { 20 | return DigestUtils.md5Hex(value).toUpperCase(); 21 | } 22 | 23 | public static Date parseStringDate(String dateString) throws AdException { 24 | try { 25 | return DateUtils.parseDate(dateString, parsePatterns); 26 | } catch (Exception e) { 27 | throw new AdException(e.getMessage()); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-search/src/main/java/com/javaedge/ad/client/SponsorClient.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.client; 2 | 3 | import com.javaedge.ad.client.vo.AdPlan; 4 | import com.javaedge.ad.client.vo.AdPlanGetRequest; 5 | import com.javaedge.ad.vo.CommonResponse; 6 | import org.springframework.cloud.openfeign.FeignClient; 7 | import org.springframework.web.bind.annotation.RequestBody; 8 | import org.springframework.web.bind.annotation.RequestMapping; 9 | import org.springframework.web.bind.annotation.RequestMethod; 10 | 11 | import java.util.List; 12 | 13 | /** 14 | * @author sss 15 | * @date 2019-02-11 16 | */ 17 | @FeignClient(value = "eureka-client-ad-sponsor", 18 | fallback = SponsorClientHystrix.class) 19 | public interface SponsorClient { 20 | 21 | /** 22 | * 获取广告计划 23 | * 24 | * @param request 25 | * @return 26 | */ 27 | @RequestMapping(value = "/ad-sponsor/get/adPlan", method = RequestMethod.POST) 28 | CommonResponse> getAdPlans(@RequestBody AdPlanGetRequest request); 29 | 30 | } 31 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-sponsor/src/main/java/com/javaedge/ad/vo/AdPlanRequest.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.vo; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | import org.apache.commons.lang.StringUtils; 7 | 8 | /** 9 | * @author sss 10 | * @date 2019/2/6 11 | */ 12 | @Data 13 | @NoArgsConstructor 14 | @AllArgsConstructor 15 | public class AdPlanRequest { 16 | 17 | private Long id; 18 | private Long userId; 19 | private String planName; 20 | 21 | private String startDate; 22 | private String endDate; 23 | 24 | public boolean createValidate() { 25 | return userId != null 26 | && !StringUtils.isEmpty(planName) 27 | && !StringUtils.isEmpty(startDate) 28 | && !StringUtils.isEmpty(endDate); 29 | } 30 | 31 | public boolean updateValidate() { 32 | return id != null && userId != null; 33 | } 34 | 35 | public boolean deleteValidate() { 36 | return id != null && userId != null; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-sponsor/src/main/java/com/javaedge/ad/entity/unitcondition/AdUnitIt.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.entity.unitcondition; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | import javax.persistence.*; 8 | 9 | /** 10 | * 11 | * @author sss 12 | * @date 2019/2/1 13 | */ 14 | @Data 15 | @AllArgsConstructor 16 | @NoArgsConstructor 17 | @Entity 18 | @Table(name = "ad_unit_it") 19 | public class AdUnitIt { 20 | 21 | @Id 22 | @GeneratedValue(strategy = GenerationType.IDENTITY) 23 | @Column(name = "id", nullable = false) 24 | private Long id; 25 | 26 | /** 27 | * 使用应用程序维护外键关系,而不是建立数据库的外键约束! 28 | */ 29 | @Basic 30 | @Column(name = "unit_id", nullable = false) 31 | private Long unitId; 32 | 33 | @Basic 34 | @Column(name = "it_tag", nullable = false) 35 | private String itTag; 36 | 37 | public AdUnitIt(Long unitId, String itTag) { 38 | this.unitId = unitId; 39 | this.itTag = itTag; 40 | } 41 | } 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-sponsor/src/main/java/com/javaedge/ad/entity/unitcondition/AdUnitKeyword.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.entity.unitcondition; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | import javax.persistence.*; 8 | 9 | /** 10 | * 11 | * @author sss 12 | * @date 2019/2/1 13 | */ 14 | @Data 15 | @AllArgsConstructor 16 | @NoArgsConstructor 17 | @Entity 18 | @Table(name = "ad_unit_keyword") 19 | public class AdUnitKeyword { 20 | 21 | @Id 22 | @GeneratedValue(strategy = GenerationType.IDENTITY) 23 | @Column(name = "id", nullable = false) 24 | private Long id; 25 | 26 | /** 27 | * 使用应用程序维护外键关系,而不是建立数据库的外键约束! 28 | */ 29 | @Basic 30 | @Column(name = "unit_id", nullable = false) 31 | private Long unitId; 32 | 33 | @Basic 34 | @Column(name = "keyword", nullable = false) 35 | private String keyword; 36 | 37 | public AdUnitKeyword(Long unitId, String keyword) { 38 | this.unitId = unitId; 39 | this.keyword = keyword; 40 | } 41 | } 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-sponsor/src/main/java/com/javaedge/ad/service/IAdUnitService.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.service; 2 | 3 | import com.javaedge.ad.exception.AdException; 4 | import com.javaedge.ad.vo.*; 5 | 6 | /** 7 | * @fun 推广单元接口 8 | * 9 | * @author sss 10 | * @date 2019/2/6 11 | */ 12 | public interface IAdUnitService { 13 | 14 | /** 15 | * 16 | * @param request 17 | * @return 18 | * @throws AdException 19 | */ 20 | AdUnitResponse createUnit(AdUnitRequest request) throws AdException; 21 | 22 | /** 23 | * 24 | * @param request 25 | * @return 26 | * @throws AdException 27 | */ 28 | AdUnitKeywordResponse createUnitKeyword(AdUnitKeywordRequest request) 29 | throws AdException; 30 | 31 | AdUnitItResponse createUnitIt(AdUnitItRequest request) 32 | throws AdException; 33 | 34 | AdUnitDistrictResponse createUnitDistrict(AdUnitDistrictRequest request) 35 | throws AdException; 36 | 37 | CreativeUnitResponse createCreativeUnit(CreativeUnitRequest request) 38 | throws AdException; 39 | 40 | } 41 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-sponsor/src/main/java/com/javaedge/ad/dao/AdPlanRepository.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.dao; 2 | 3 | import com.javaedge.ad.entity.AdPlan; 4 | import com.javaedge.ad.entity.AdUser; 5 | import org.springframework.data.jpa.repository.JpaRepository; 6 | 7 | import java.util.List; 8 | 9 | /** 10 | * @author sss 11 | * @date 2019/2/4 12 | */ 13 | public interface AdPlanRepository extends JpaRepository { 14 | 15 | /** 16 | * 17 | * @param id 18 | * @param userId 19 | * @return 20 | */ 21 | AdPlan findByIdAndUserId(Long id, Long userId); 22 | 23 | /** 24 | * 25 | * @param ids 26 | * @param userId 27 | * @return 28 | */ 29 | List findAllByIdInAnAndUserId(List ids, Long userId); 30 | 31 | /** 32 | * 33 | * @param userId 34 | * @param username 35 | * @return 36 | */ 37 | AdPlan findByUserIdaAndPlanName(Long userId, String username); 38 | 39 | /** 40 | * 41 | * @param status 42 | * @return 43 | */ 44 | List findAllByPlanStatus(Integer status); 45 | } 46 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-sponsor/src/main/java/com/javaedge/ad/entity/unitcondition/CreativeUnit.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.entity.unitcondition; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | import javax.persistence.*; 8 | import java.util.Date; 9 | 10 | /** 11 | * 推广创意与计划的多对多关系 12 | * 13 | * @author sss 14 | * @date 2019/2/1 15 | */ 16 | @Data 17 | @AllArgsConstructor 18 | @NoArgsConstructor 19 | @Entity 20 | @Table(name = "creative_unit") 21 | public class CreativeUnit { 22 | 23 | @Id 24 | @GeneratedValue(strategy = GenerationType.IDENTITY) 25 | @Column(name = "id", nullable = false) 26 | private Long id; 27 | 28 | @Id 29 | @GeneratedValue(strategy = GenerationType.IDENTITY) 30 | @Column(name = "creative_id", nullable = false) 31 | private Long creativeId; 32 | 33 | @Id 34 | @GeneratedValue(strategy = GenerationType.IDENTITY) 35 | @Column(name = "unit_id", nullable = false) 36 | private Long unitId; 37 | 38 | public CreativeUnit(Long creativeId, Long unitId) { 39 | this.creativeId = creativeId; 40 | this.unitId = unitId; 41 | } 42 | 43 | } 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-sponsor/src/main/java/com/javaedge/ad/service/impl/CreativeServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.service.impl; 2 | 3 | import com.javaedge.ad.dao.CreativeRepository; 4 | import com.javaedge.ad.entity.Creative; 5 | import com.javaedge.ad.service.ICreativeService; 6 | import com.javaedge.ad.vo.CreativeRequest; 7 | import com.javaedge.ad.vo.CreativeResponse; 8 | import org.springframework.beans.factory.annotation.Autowired; 9 | import org.springframework.stereotype.Service; 10 | 11 | /** 12 | * @author sss 13 | * @date 2019/2/10 14 | */ 15 | @Service 16 | public class CreativeServiceImpl implements ICreativeService { 17 | 18 | private final CreativeRepository creativeRepository; 19 | 20 | @Autowired 21 | public CreativeServiceImpl(CreativeRepository creativeRepository) { 22 | this.creativeRepository = creativeRepository; 23 | } 24 | 25 | @Override 26 | public CreativeResponse createCreative(CreativeRequest request) { 27 | 28 | Creative creative = creativeRepository.save( 29 | request.convertToEntity() 30 | ); 31 | 32 | return new CreativeResponse(creative.getId(), creative.getName()); 33 | } 34 | } 35 | 36 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-search/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 7001 3 | servlet: 4 | context-path: /ad-search 5 | 6 | spring: 7 | application: 8 | name: eureka-client-ad-search 9 | jpa: 10 | show-sql: true 11 | hibernate: 12 | ddl-auto: none 13 | properties: 14 | hibernate.format_sql: true 15 | open-in-view: false 16 | datasource: 17 | url: jdbc:mysql://127.0.0.1:3306/javaedge_ad_data?autoReconnect=true 18 | username: root 19 | password: root 20 | tomcat: 21 | max-active: 4 22 | min-idle: 2 23 | initial-size: 2 24 | kafka: 25 | bootstrap-servers: 127.0.0.1:9092 26 | listener: 27 | concurrency: 4 28 | 29 | eureka: 30 | client: 31 | service-url: 32 | defaultZone: http://server1:8000/eureka/ 33 | 34 | feign: 35 | hystrix: 36 | enabled: true 37 | 38 | # 监控信息 39 | management: 40 | endpoints: 41 | web: 42 | exposure: 43 | # 暴露全部信息 44 | include: "*" 45 | 46 | adconf: 47 | mysql: 48 | host: 127.0.0.1 49 | port: 3306 50 | username: root 51 | password: root 52 | binlogName: binlog.000038 53 | position: -1 54 | 55 | kafka: 56 | topic: ad-search-mysql-data 57 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-sponsor/src/main/java/com/javaedge/ad/entity/unitcondition/AdUnitDistrict.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.entity.unitcondition; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | import javax.persistence.*; 8 | 9 | /** 10 | * 11 | * @author sss 12 | * @date 2019/2/1 13 | */ 14 | @Data 15 | @AllArgsConstructor 16 | @NoArgsConstructor 17 | @Entity 18 | @Table(name = "ad_unit_district") 19 | public class AdUnitDistrict { 20 | 21 | @Id 22 | @GeneratedValue(strategy = GenerationType.IDENTITY) 23 | @Column(name = "id", nullable = false) 24 | private Long id; 25 | 26 | /** 27 | * 使用应用程序维护外键关系,而不是建立数据库的外键约束! 28 | */ 29 | @Basic 30 | @Column(name = "unit_id", nullable = false) 31 | private Long unitId; 32 | 33 | @Basic 34 | @Column(name = "city", nullable = false) 35 | private String province; 36 | 37 | @Basic 38 | @Column(name = "city", nullable = false) 39 | private String city; 40 | 41 | public AdUnitDistrict(Long unitId, String province, String city) { 42 | this.unitId = unitId; 43 | this.province = province; 44 | this.city = city; 45 | } 46 | } 47 | 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /ad-gateway/src/main/java/com/javaedge/ad/filter/PreRequestFilter.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.filter; 2 | 3 | import com.netflix.zuul.ZuulFilter; 4 | import com.netflix.zuul.context.RequestContext; 5 | import com.netflix.zuul.exception.ZuulException; 6 | import lombok.extern.slf4j.Slf4j; 7 | import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants; 8 | import org.springframework.stereotype.Component; 9 | 10 | /** 11 | * @author sss 12 | * @date 2019/1/28 13 | */ 14 | @Slf4j 15 | @Component 16 | public class PreRequestFilter extends ZuulFilter { 17 | @Override 18 | public String filterType() { 19 | return FilterConstants.PRE_TYPE; 20 | } 21 | 22 | /** 23 | * 数字越小,优先级越高 24 | * 25 | * @return 26 | */ 27 | @Override 28 | public int filterOrder() { 29 | return 0; 30 | } 31 | 32 | /** 33 | * 永远执行 34 | * 35 | * @return 36 | */ 37 | @Override 38 | public boolean shouldFilter() { 39 | return true; 40 | } 41 | 42 | @Override 43 | public Object run() throws ZuulException { 44 | RequestContext ctx = RequestContext.getCurrentContext(); 45 | ctx.set("startTime", System.currentTimeMillis()); 46 | return null; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-sponsor/src/main/java/com/javaedge/ad/controller/CreativeOpController.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.controller; 2 | 3 | import com.alibaba.fastjson.JSON; 4 | import com.javaedge.ad.service.ICreativeService; 5 | import com.javaedge.ad.vo.CreativeRequest; 6 | import com.javaedge.ad.vo.CreativeResponse; 7 | import lombok.extern.slf4j.Slf4j; 8 | import org.springframework.beans.factory.annotation.Autowired; 9 | import org.springframework.web.bind.annotation.PostMapping; 10 | import org.springframework.web.bind.annotation.RequestBody; 11 | import org.springframework.web.bind.annotation.RestController; 12 | 13 | /** 14 | * @author sss 15 | * @date 2019-02-11 16 | */ 17 | @Slf4j 18 | @RestController 19 | public class CreativeOpController { 20 | 21 | private final ICreativeService creativeService; 22 | 23 | @Autowired 24 | public CreativeOpController(ICreativeService creativeService) { 25 | this.creativeService = creativeService; 26 | } 27 | 28 | @PostMapping("/create/creative") 29 | public CreativeResponse createCreative(@RequestBody CreativeRequest request) { 30 | log.info("ad-sponsor: createCreative -> {}", JSON.toJSONString(request)); 31 | return creativeService.createCreative(request); 32 | } 33 | } 34 | 35 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-search/src/main/java/com/javaedge/ad/index/adplan/AdPlanObject.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.index.adplan; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | import java.util.Date; 8 | 9 | /** 10 | * 广告计划 索引对象 11 | * 12 | * @author sss 13 | * @date 2019-02-11 14 | */ 15 | @Data 16 | @NoArgsConstructor 17 | @AllArgsConstructor 18 | public class AdPlanObject { 19 | 20 | private Long planId; 21 | private Long userId; 22 | private Integer planStatus; 23 | private Date startDate; 24 | private Date endDate; 25 | 26 | public void update(AdPlanObject newObject) { 27 | if (null != newObject.getPlanId()) { 28 | this.planId = newObject.getPlanId(); 29 | } 30 | if (null != newObject.getUserId()) { 31 | this.userId = newObject.getUserId(); 32 | } 33 | if (null != newObject.getPlanStatus()) { 34 | this.planStatus = newObject.getPlanStatus(); 35 | } 36 | if (null != newObject.getStartDate()) { 37 | this.startDate = newObject.getStartDate(); 38 | } 39 | if (null != newObject.getEndDate()) { 40 | this.endDate = newObject.getEndDate(); 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-sponsor/src/main/java/com/javaedge/ad/controller/UserOpController.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.controller; 2 | 3 | import com.alibaba.fastjson.JSON; 4 | import com.javaedge.ad.exception.AdException; 5 | import com.javaedge.ad.service.IUserService; 6 | import com.javaedge.ad.vo.CreateUserRequest; 7 | import com.javaedge.ad.vo.CreateUserResponse; 8 | import lombok.extern.slf4j.Slf4j; 9 | import org.springframework.beans.factory.annotation.Autowired; 10 | import org.springframework.web.bind.annotation.PostMapping; 11 | import org.springframework.web.bind.annotation.RequestBody; 12 | import org.springframework.web.bind.annotation.RestController; 13 | 14 | /** 15 | * @author sss 16 | * @date 2019-02-11 17 | */ 18 | @RestController 19 | @Slf4j 20 | public class UserOpController { 21 | 22 | private final IUserService userService; 23 | 24 | @Autowired 25 | public UserOpController(IUserService userService) { 26 | this.userService = userService; 27 | } 28 | 29 | @PostMapping("/create/user") 30 | public CreateUserResponse createUser(@RequestBody CreateUserRequest request) throws AdException { 31 | log.info("ad-sponsor: createUser -> {}", JSON.toJSONString(request)); 32 | return userService.createUser(request); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-sponsor/src/main/java/com/javaedge/ad/service/IAdPlanService.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.service; 2 | 3 | import com.javaedge.ad.entity.AdPlan; 4 | import com.javaedge.ad.exception.AdException; 5 | import com.javaedge.ad.vo.AdPlanGetRequest; 6 | import com.javaedge.ad.vo.AdPlanRequest; 7 | import com.javaedge.ad.vo.AdPlanResponse; 8 | 9 | import java.util.List; 10 | 11 | /** 12 | * @fun 推广计划服务接口 13 | * 14 | * @author sss 15 | * @date 2019/2/6 16 | */ 17 | public interface IAdPlanService { 18 | 19 | /** 20 | * 创建推广计划 21 | * 22 | * @param request 23 | * @return 24 | * @throws AdException 25 | */ 26 | AdPlanResponse createAdPlan(AdPlanRequest request) throws AdException; 27 | 28 | /** 29 | * 获取推广计划 30 | * 31 | * @param request 32 | * @return 33 | * @throws AdException 34 | */ 35 | List getAdPlanByIds(AdPlanGetRequest request) throws AdException; 36 | 37 | /** 38 | * 更新推广计划 39 | * 40 | * @param request 41 | * @return 42 | * @throws AdException 43 | */ 44 | AdPlanResponse updateAdPlan(AdPlanRequest request) throws AdException; 45 | 46 | /** 47 | * 删除推广计划 48 | * 49 | * @param request 50 | * @throws AdException 51 | */ 52 | void deleteAdPlan(AdPlanRequest request) throws AdException; 53 | 54 | } 55 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-search/src/main/java/com/javaedge/ad/SearchApplication.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker; 6 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient; 7 | import org.springframework.cloud.client.loadbalancer.LoadBalanced; 8 | import org.springframework.cloud.netflix.eureka.EnableEurekaClient; 9 | import org.springframework.cloud.netflix.hystrix.EnableHystrix; 10 | import org.springframework.cloud.netflix.hystrix.dashboard.EnableHystrixDashboard; 11 | import org.springframework.cloud.openfeign.EnableFeignClients; 12 | import org.springframework.context.annotation.Bean; 13 | import org.springframework.web.client.RestTemplate; 14 | 15 | /** 16 | * @author sss 17 | * @date 2019-02-11 18 | */ 19 | @EnableFeignClients 20 | @EnableEurekaClient 21 | @EnableHystrix 22 | @EnableCircuitBreaker 23 | @EnableDiscoveryClient 24 | @EnableHystrixDashboard 25 | @SpringBootApplication 26 | public class SearchApplication { 27 | 28 | public static void main(String[] args) { 29 | 30 | SpringApplication.run(SearchApplication.class, args); 31 | } 32 | 33 | @Bean 34 | @LoadBalanced 35 | RestTemplate restTemplate() { 36 | 37 | return new RestTemplate(); 38 | } 39 | } 40 | 41 | -------------------------------------------------------------------------------- /ad-gateway/src/main/java/com/javaedge/ad/filter/AccessLogFilter.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.filter; 2 | 3 | import com.netflix.zuul.ZuulFilter; 4 | import com.netflix.zuul.context.RequestContext; 5 | import com.netflix.zuul.exception.ZuulException; 6 | import lombok.extern.slf4j.Slf4j; 7 | import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants; 8 | import org.springframework.stereotype.Component; 9 | 10 | import javax.servlet.http.HttpServletRequest; 11 | 12 | /** 13 | * @author sss 14 | * @date 2019/1/28 15 | */ 16 | @Slf4j 17 | @Component 18 | public class AccessLogFilter extends ZuulFilter { 19 | @Override 20 | public String filterType() { 21 | return FilterConstants.POST_TYPE; 22 | } 23 | 24 | @Override 25 | public int filterOrder() { 26 | return FilterConstants.SEND_RESPONSE_FILTER_ORDER - 1; 27 | } 28 | 29 | @Override 30 | public boolean shouldFilter() { 31 | return true; 32 | } 33 | 34 | @Override 35 | public Object run() throws ZuulException { 36 | RequestContext ctx = RequestContext.getCurrentContext(); 37 | HttpServletRequest request = ctx.getRequest(); 38 | Long startTime = (Long) ctx.get("startTime"); 39 | String uri = request.getRequestURI(); 40 | long duration = System.currentTimeMillis() - startTime; 41 | 42 | log.info("uri: " + uri + ", duration: " + duration / 100 + "ms"); 43 | 44 | return null; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 31 | 32 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-sponsor/src/main/java/com/javaedge/ad/entity/AdUser.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.entity; 2 | 3 | import com.javaedge.ad.constant.CommonStatus; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | 8 | import javax.persistence.*; 9 | import java.util.Date; 10 | 11 | /** 12 | * @author sss 13 | * @date 2019/2/1 14 | */ 15 | @Data 16 | @AllArgsConstructor 17 | @NoArgsConstructor 18 | @Entity 19 | @Table(name = "ad_user") 20 | public class AdUser { 21 | 22 | @Id 23 | @GeneratedValue(strategy = GenerationType.IDENTITY) 24 | @Column(name = "id", nullable = false) 25 | private Long id; 26 | 27 | @Basic 28 | @Column(name = "username", nullable = false) 29 | private String username; 30 | 31 | @Basic 32 | @Column(name = "token", nullable = false) 33 | private String token; 34 | 35 | @Basic 36 | @Column(name = "user_status", nullable = false) 37 | private Integer userStatus; 38 | 39 | @Basic 40 | @Column(name = "create_time", nullable = false) 41 | private Date createTime; 42 | 43 | @Basic 44 | @Column(name = "update_time", nullable = false) 45 | private Date updateTime; 46 | 47 | public AdUser(String username, String token) { 48 | this.username = username; 49 | this.token = token; 50 | this.userStatus = CommonStatus.VALID.getStatus(); 51 | this.createTime = new Date(); 52 | this.updateTime = this.createTime; 53 | } 54 | } 55 | 56 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-sponsor/src/main/java/com/javaedge/ad/vo/CreativeRequest.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.vo; 2 | 3 | import com.javaedge.ad.constant.CommonStatus; 4 | import com.javaedge.ad.entity.Creative; 5 | import lombok.AllArgsConstructor; 6 | import lombok.Data; 7 | import lombok.NoArgsConstructor; 8 | 9 | import java.util.Date; 10 | 11 | /** 12 | * @author sss 13 | * @date 2019/2/10 14 | */ 15 | @Data 16 | @NoArgsConstructor 17 | @AllArgsConstructor 18 | public class CreativeRequest { 19 | 20 | private String name; 21 | private Integer type; 22 | private Integer materialType; 23 | private Integer height; 24 | private Integer width; 25 | private Long size; 26 | private Integer duration; 27 | private Long userId; 28 | private String url; 29 | 30 | /** 31 | * 避免了在 service 层的代码实现 32 | * @return 33 | */ 34 | public Creative convertToEntity() { 35 | 36 | Creative creative = new Creative(); 37 | creative.setName(name); 38 | creative.setType(type); 39 | creative.setMaterialType(materialType); 40 | creative.setHeight(height); 41 | creative.setWidth(width); 42 | creative.setSize(size); 43 | creative.setDuration(duration); 44 | creative.setAuditStatus(CommonStatus.VALID.getStatus()); 45 | creative.setUserId(userId); 46 | creative.setUrl(url); 47 | creative.setCreateTime(new Date()); 48 | creative.setUpdateTime(creative.getCreateTime()); 49 | 50 | return creative; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /ad-eureka/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | sss-ad 8 | com.sss.ad 9 | 1.0-SNAPSHOT 10 | 11 | 4.0.0 12 | 13 | 14 | ad-eureka 15 | 1.0-SNAPSHOT 16 | jar 17 | 18 | 19 | ad-eureka 20 | Spring Cloud Eureka 21 | 22 | 23 | 24 | 25 | org.springframework.cloud 26 | spring-cloud-starter-netflix-eureka-server 27 | 28 | 29 | 30 | 34 | 35 | 36 | 37 | org.springframework.boot 38 | spring-boot-maven-plugin 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /.idea/inspectionProfiles/Project_Default.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 36 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-search/src/main/java/com/javaedge/ad/index/creative/CreativeObject.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.index.creative; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | /** 8 | * @author sss 9 | * @date 2019-02-12 10 | */ 11 | @Data 12 | @NoArgsConstructor 13 | @AllArgsConstructor 14 | public class CreativeObject { 15 | 16 | private Long adId; 17 | private String name; 18 | private Integer type; 19 | private Integer materialType; 20 | private Integer height; 21 | private Integer width; 22 | private Integer auditStatus; 23 | private String adUrl; 24 | 25 | public void update(CreativeObject newObject) { 26 | 27 | if (null != newObject.getAdId()) { 28 | this.adId = newObject.getAdId(); 29 | } 30 | if (null != newObject.getName()) { 31 | this.name = newObject.getName(); 32 | } 33 | if (null != newObject.getType()) { 34 | this.type = newObject.getType(); 35 | } 36 | if (null != newObject.getMaterialType()) { 37 | this.materialType = newObject.getMaterialType(); 38 | } 39 | if (null != newObject.getHeight()) { 40 | this.height = newObject.getHeight(); 41 | } 42 | if (null != newObject.getWidth()) { 43 | this.width = newObject.getWidth(); 44 | } 45 | if (null != newObject.getAuditStatus()) { 46 | this.auditStatus = newObject.getAuditStatus(); 47 | } 48 | if (null != newObject.getAdUrl()) { 49 | this.adUrl = newObject.getAdUrl(); 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-search/src/main/java/com/javaedge/ad/index/adplan/AdPlanIndex.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.index.adplan; 2 | 3 | import com.javaedge.ad.index.IndexAware; 4 | import lombok.extern.slf4j.Slf4j; 5 | import org.springframework.stereotype.Component; 6 | 7 | import java.util.Map; 8 | import java.util.concurrent.ConcurrentHashMap; 9 | 10 | /** 11 | * @author sss 12 | * @date 2019-02-11 13 | */ 14 | @Slf4j 15 | @Component 16 | public class AdPlanIndex implements IndexAware { 17 | 18 | private static Map objectMap; 19 | 20 | static { 21 | objectMap = new ConcurrentHashMap<>(); 22 | } 23 | 24 | 25 | @Override 26 | public AdPlanObject get(Long key) { 27 | return objectMap.get(key); 28 | } 29 | 30 | @Override 31 | public void add(Long key, AdPlanObject value) { 32 | log.info("before add: {}", objectMap); 33 | objectMap.put(key, value); 34 | log.info("after add: {}", objectMap); 35 | } 36 | 37 | @Override 38 | public void update(Long key, AdPlanObject value) { 39 | log.info("before update: {}", objectMap); 40 | 41 | AdPlanObject oldObject = objectMap.get(key); 42 | if (null == oldObject) { 43 | objectMap.put(key, value); 44 | } else { 45 | oldObject.update(value); 46 | } 47 | 48 | log.info("after update: {}", objectMap); 49 | } 50 | 51 | @Override 52 | public void delete(Long key, AdPlanObject value) { 53 | log.info("before delete: {}", objectMap); 54 | objectMap.remove(key); 55 | log.info("after delete: {}", objectMap); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-common/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | javaedge-ad-service 8 | com.sss.ad 9 | 1.0-SNAPSHOT 10 | 11 | 4.0.0 12 | 13 | 14 | ad-common 15 | 1.0-SNAPSHOT 16 | jar 17 | 18 | 19 | 20 | 21 | org.springframework.boot 22 | spring-boot-starter-web 23 | 24 | 25 | 26 | com.alibaba 27 | fastjson 28 | 1.2.31 29 | 30 | 31 | 32 | 36 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-search/src/main/java/com/javaedge/ad/sender/kafka/KafkaSender.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.sender.kafka; 2 | 3 | import com.alibaba.fastjson.JSON; 4 | import com.javaedge.ad.mysql.dto.MySqlRowData; 5 | import com.javaedge.ad.sender.ISender; 6 | import org.apache.kafka.clients.consumer.ConsumerRecord; 7 | import org.springframework.beans.factory.annotation.Value; 8 | import org.springframework.kafka.annotation.KafkaListener; 9 | import org.springframework.kafka.core.KafkaTemplate; 10 | import org.springframework.stereotype.Component; 11 | 12 | import javax.annotation.Resource; 13 | import java.util.Optional; 14 | 15 | /** 16 | * @author sss 17 | * @date 2019-02-26 18 | */ 19 | @Component("kafkaSender") 20 | public class KafkaSender implements ISender { 21 | 22 | @Value("${adconf.kafka.topic}") 23 | private String topic; 24 | 25 | @Resource 26 | private KafkaTemplate kafkaTemplate; 27 | 28 | @Override 29 | public void sender(MySqlRowData rowData) { 30 | kafkaTemplate.send(topic, JSON.toJSONString(rowData)); 31 | } 32 | 33 | @KafkaListener(topics = {"ad-search-mysql-data"}, groupId = "ad-search") 34 | public void processMysqlRowData(ConsumerRecord record) { 35 | Optional kafkaMessage = Optional.ofNullable(record.value()); 36 | if (kafkaMessage.isPresent()) { 37 | Object message = kafkaMessage.get(); 38 | MySqlRowData rowData = JSON.parseObject( 39 | message.toString(), 40 | MySqlRowData.class 41 | ); 42 | System.out.println("kafka processMysqlRowData: " + 43 | JSON.toJSONString(rowData)); 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-search/src/main/java/com/javaedge/ad/search/vo/SearchRequest.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.search.vo; 2 | 3 | import com.javaedge.ad.search.vo.feature.DistrictFeature; 4 | import com.javaedge.ad.search.vo.feature.FeatureRelation; 5 | import com.javaedge.ad.search.vo.feature.ItFeature; 6 | import com.javaedge.ad.search.vo.feature.KeywordFeature; 7 | import com.javaedge.ad.search.vo.media.AdSlot; 8 | import com.javaedge.ad.search.vo.media.App; 9 | import com.javaedge.ad.search.vo.media.Device; 10 | import com.javaedge.ad.search.vo.media.Geo; 11 | import lombok.AllArgsConstructor; 12 | import lombok.Data; 13 | import lombok.NoArgsConstructor; 14 | 15 | import java.util.List; 16 | 17 | /** 18 | * @author sss 19 | * @date 2019-02-26 20 | */ 21 | @Data 22 | @NoArgsConstructor 23 | @AllArgsConstructor 24 | public class SearchRequest { 25 | 26 | /** 27 | * 媒体方的请求标识 28 | */ 29 | private String mediaId; 30 | /** 31 | * 请求基本信息 32 | */ 33 | private RequestInfo requestInfo; 34 | /** 35 | * 匹配信息 36 | */ 37 | private FeatureInfo featureInfo; 38 | 39 | @Data 40 | @NoArgsConstructor 41 | @AllArgsConstructor 42 | public static class RequestInfo { 43 | 44 | private String requestId; 45 | 46 | private List adSlots; 47 | private App app; 48 | private Geo geo; 49 | private Device device; 50 | } 51 | 52 | @Data 53 | @NoArgsConstructor 54 | @AllArgsConstructor 55 | public static class FeatureInfo { 56 | 57 | private KeywordFeature keywordFeature; 58 | private DistrictFeature districtFeature; 59 | private ItFeature itFeature; 60 | 61 | private FeatureRelation relation = FeatureRelation.AND; 62 | } 63 | } 64 | 65 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-search/src/main/java/com/javaedge/ad/utils/CommonUtils.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.utils; 2 | 3 | import lombok.extern.slf4j.Slf4j; 4 | import org.apache.commons.lang.time.DateUtils; 5 | 6 | import java.text.DateFormat; 7 | import java.text.ParseException; 8 | import java.text.SimpleDateFormat; 9 | import java.util.Date; 10 | import java.util.Locale; 11 | import java.util.Map; 12 | import java.util.function.Supplier; 13 | 14 | /** 15 | * @author sss 16 | * @date 2019-02-11 17 | */ 18 | @Slf4j 19 | public class CommonUtils { 20 | 21 | public static V getorCreate(K key, Map map, Supplier factory) { 22 | return map.computeIfAbsent(key, k -> factory.get()); 23 | } 24 | 25 | public static String stringConcat(String... args) { 26 | 27 | StringBuilder result = new StringBuilder(); 28 | for (String arg : args) { 29 | result.append(arg); 30 | result.append("-"); 31 | } 32 | result.deleteCharAt(result.length() - 1); 33 | return result.toString(); 34 | } 35 | 36 | /** 37 | * Tue Jan 01 08:00:00 CST 2019 38 | * 39 | * @param dateString 40 | * @return 41 | */ 42 | public static Date parseStringDate(String dateString) { 43 | 44 | try { 45 | 46 | DateFormat dateFormat = new SimpleDateFormat( 47 | "EEE MMM dd HH:mm:ss zzz yyyy", 48 | Locale.US 49 | ); 50 | return DateUtils.addHours( 51 | dateFormat.parse(dateString), 52 | -8 53 | ); 54 | 55 | } catch (ParseException ex) { 56 | log.error("parseStringDate error: {}", dateString); 57 | return null; 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-search/src/main/java/com/javaedge/ad/index/DataTable.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.index; 2 | 3 | import org.springframework.beans.BeansException; 4 | import org.springframework.context.ApplicationContext; 5 | import org.springframework.context.ApplicationContextAware; 6 | import org.springframework.core.PriorityOrdered; 7 | import org.springframework.stereotype.Component; 8 | 9 | import java.util.Map; 10 | import java.util.concurrent.ConcurrentHashMap; 11 | 12 | /** 13 | * @author sss 14 | * @date 2019-02-12 15 | */ 16 | @Component 17 | public class DataTable implements ApplicationContextAware, PriorityOrdered { 18 | 19 | private static ApplicationContext applicationContext; 20 | 21 | public static final Map dataTableMap = new ConcurrentHashMap<>(); 22 | 23 | @Override 24 | public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { 25 | DataTable.applicationContext = applicationContext; 26 | } 27 | 28 | @Override 29 | public int getOrder() { 30 | return PriorityOrdered.HIGHEST_PRECEDENCE; 31 | } 32 | 33 | @SuppressWarnings("all") 34 | public static T of(Class clazz) { 35 | 36 | T instance = (T) dataTableMap.get(clazz); 37 | if (null != instance) { 38 | return instance; 39 | } 40 | 41 | dataTableMap.put(clazz, bean(clazz)); 42 | return (T) dataTableMap.get(clazz); 43 | } 44 | 45 | @SuppressWarnings("all") 46 | private static T bean(String beanName) { 47 | return (T) applicationContext.getBean(beanName); 48 | } 49 | 50 | @SuppressWarnings("all") 51 | private static T bean(Class clazz) { 52 | return (T) applicationContext.getBean(clazz); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-search/src/main/java/com/javaedge/ad/search/vo/SearchResponse.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.search.vo; 2 | 3 | import com.javaedge.ad.index.creative.CreativeObject; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | 8 | import java.util.Arrays; 9 | import java.util.HashMap; 10 | import java.util.List; 11 | import java.util.Map; 12 | 13 | /** 14 | * @author sss 15 | * @date 2019-02-26 16 | */ 17 | @Data 18 | @NoArgsConstructor 19 | @AllArgsConstructor 20 | public class SearchResponse { 21 | 22 | public Map> adSlot2Ads = new HashMap<>(); 23 | 24 | @Data 25 | @NoArgsConstructor 26 | @AllArgsConstructor 27 | public static class Creative { 28 | 29 | private Long adId; 30 | private String adUrl; 31 | private Integer width; 32 | private Integer height; 33 | private Integer type; 34 | private Integer materialType; 35 | 36 | /** 37 | * 展示监测 url 38 | */ 39 | private List showMonitorUrl = 40 | Arrays.asList("www.shishusheng.com", "www.shishusheng.com"); 41 | /** 42 | * 点击监测 url 43 | */ 44 | private List clickMonitorUrl = 45 | Arrays.asList("www.shishusheng.com", "www.shishusheng.com"); 46 | } 47 | 48 | public static Creative convert(CreativeObject object) { 49 | 50 | Creative creative = new Creative(); 51 | creative.setAdId(object.getAdId()); 52 | creative.setAdUrl(object.getAdUrl()); 53 | creative.setWidth(object.getWidth()); 54 | creative.setHeight(object.getHeight()); 55 | creative.setType(object.getType()); 56 | creative.setMaterialType(object.getMaterialType()); 57 | 58 | return creative; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-common/src/main/java/com/javaedge/ad/advice/CommonResponseDataAdvice.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.advice; 2 | 3 | import com.javaedge.ad.annotation.IgnoreResponseAdvice; 4 | import com.javaedge.ad.vo.CommonResponse; 5 | import org.springframework.core.MethodParameter; 6 | import org.springframework.http.MediaType; 7 | import org.springframework.http.server.ServerHttpRequest; 8 | import org.springframework.http.server.ServerHttpResponse; 9 | import org.springframework.lang.Nullable; 10 | import org.springframework.web.bind.annotation.RestControllerAdvice; 11 | import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice; 12 | 13 | /** 14 | * @author sss 15 | * @date 2019/1/31 16 | */ 17 | @RestControllerAdvice 18 | public class CommonResponseDataAdvice implements ResponseBodyAdvice { 19 | 20 | @Override 21 | @SuppressWarnings("all") 22 | public boolean supports(MethodParameter methodParameter, Class aClass) { 23 | if (methodParameter.getDeclaringClass().isAnnotationPresent(IgnoreResponseAdvice.class)) { 24 | return false; 25 | } 26 | 27 | if (methodParameter.getMethod().isAnnotationPresent(IgnoreResponseAdvice.class)) { 28 | return false; 29 | } 30 | return true; 31 | } 32 | 33 | 34 | @Nullable 35 | @Override 36 | @SuppressWarnings("all") 37 | public Object beforeBodyWrite(Object o, MethodParameter methodParameter, MediaType mediaType, Class aClass, ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) { 38 | CommonResponse response = new CommonResponse<>(0, ""); 39 | if (null == o) { 40 | return response; 41 | } else if (o instanceof CommonResponse) { 42 | response = (CommonResponse) o; 43 | } else { 44 | response.setData(o); 45 | } 46 | return response; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-sponsor/src/main/java/com/javaedge/ad/entity/AdPlan.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.entity; 2 | 3 | import com.javaedge.ad.constant.CommonStatus; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | 8 | import javax.persistence.*; 9 | import java.util.Date; 10 | 11 | /** 12 | * 推广计划 13 | * 14 | * @author sss 15 | * @date 2019/2/1 16 | */ 17 | @Data 18 | @AllArgsConstructor 19 | @NoArgsConstructor 20 | @Entity 21 | @Table(name = "ad_plan") 22 | public class AdPlan { 23 | 24 | @Id 25 | @GeneratedValue(strategy = GenerationType.IDENTITY) 26 | @Column(name = "id", nullable = false) 27 | private Long id; 28 | 29 | /** 30 | * 使用应用程序维护外键关系,而不是建立数据库的外键约束! 31 | */ 32 | @Basic 33 | @Column(name = "user_id", nullable = false) 34 | private Long userId; 35 | 36 | @Basic 37 | @Column(name = "plan_name", nullable = false) 38 | private String planName; 39 | 40 | @Basic 41 | @Column(name = "plan_status", nullable = false) 42 | private Integer planStatus; 43 | 44 | @Basic 45 | @Column(name = "start_date", nullable = false) 46 | private Date startDate; 47 | 48 | @Basic 49 | @Column(name = "end_date", nullable = false) 50 | private Date endDate; 51 | 52 | @Basic 53 | @Column(name = "create_time", nullable = false) 54 | private Date createTime; 55 | 56 | @Basic 57 | @Column(name = "update_time", nullable = false) 58 | private Date updateTime; 59 | 60 | public AdPlan(Long userId, String planName, Date startDate, Date endDate) { 61 | this.userId = userId; 62 | this.planName = planName; 63 | this.startDate = startDate; 64 | this.endDate = endDate; 65 | this.planStatus = CommonStatus.VALID.getStatus(); 66 | this.createTime = new Date(); 67 | this.updateTime = this.createTime; 68 | 69 | } 70 | } 71 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-search/src/main/resources/example.sql: -------------------------------------------------------------------------------- 1 | -- 更新, 插入, 删除 ad_plan 2 | update ad_plan set start_date = '2018-11-30 00:00:00' where id = 10; 3 | 4 | INSERT INTO `ad_plan` (`user_id`, `plan_name`, `plan_status`, `start_date`, `end_date`, `create_time`, `update_time`) 5 | VALUES (10, '第二个推广计划', 1, '2018-01-01 00:00:00', '2019-12-01 00:00:00', '2018-01-01 00:00:00', '2018-01-01 00:00:00'); 6 | 7 | delete from ad_plan where id = 12; 8 | 9 | 10 | -- 更新, 插入, 删除 ad_creative 11 | update ad_creative set url = 'https://www.shishusheng.com'; 12 | INSERT INTO `ad_creative` (`name`, `type`, `material_type`, `height`, `width`, `size`, `duration`, `audit_status`, `user_id`, `url`, `create_time`, `update_time`) VALUES ('第二个创意', 1, 1, 720, 1080, 1024, 0, 1, 10, 'www.shishusheng.com', '2018-01-01 00:00:00', '2018-01-01 00:00:00'); 13 | delete from ad_creative where id = 13; 14 | 15 | 16 | -- 更新, 插入, 删除 ad_unit 17 | update ad_unit set unit_status = 1 where id = 10; 18 | INSERT INTO `ad_unit` (`plan_id`, `unit_name`, `unit_status`, `position_type`, `budget`, `create_time`, `update_time`) VALUES (10, '第二个推广单元', 1, 1, 15000000, '2018-01-01 00:00:00', '2018-01-01 00:00:00'); 19 | delete from ad_unit where id = 11; 20 | 21 | 22 | -- 插入, 删除 creative_unit 23 | INSERT INTO `creative_unit` (`creative_id`, `unit_id`) VALUES (10, 12); 24 | delete from creative_unit where creative_id = 10 and unit_id = 12; 25 | 26 | 27 | -- 插入, 删除 ad_unit_district 28 | INSERT INTO `ad_unit_district` (`unit_id`, `province`, `city`) VALUES (10, '辽宁省', '大连市'); 29 | delete from ad_unit_district where unit_id = 10 and province = '辽宁省' and city = '大连市'; 30 | 31 | -- 插入, 删除 ad_unit_it 32 | INSERT INTO `ad_unit_it` (`unit_id`, `it_tag`) VALUES (10, '徒步'); 33 | delete from ad_unit_it where unit_id = 10 and it_tag = '徒步'; 34 | 35 | -- 插入, 删除 ad_unit_keyword 36 | INSERT INTO `ad_unit_keyword` (`unit_id`, `keyword`) VALUES (10, '标志'); 37 | delete from ad_unit_keyword where unit_id = 10 and keyword = '标志'; 38 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-sponsor/src/main/java/com/javaedge/ad/service/impl/UserServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.service.impl; 2 | 3 | import com.javaedge.ad.constant.Constants; 4 | import com.javaedge.ad.dao.AdUserRepository; 5 | import com.javaedge.ad.entity.AdUser; 6 | import com.javaedge.ad.exception.AdException; 7 | import com.javaedge.ad.service.IUserService; 8 | import com.javaedge.ad.utils.CommonUtils; 9 | import com.javaedge.ad.vo.CreateUserRequest; 10 | import com.javaedge.ad.vo.CreateUserResponse; 11 | import lombok.extern.slf4j.Slf4j; 12 | import org.springframework.beans.factory.annotation.Autowired; 13 | import org.springframework.stereotype.Service; 14 | import org.springframework.transaction.annotation.Transactional; 15 | 16 | /** 17 | * @author sss 18 | * @date 2019/2/5 19 | */ 20 | @Slf4j 21 | @Service 22 | public class UserServiceImpl implements IUserService { 23 | 24 | private final AdUserRepository userRepository; 25 | 26 | @Autowired 27 | public UserServiceImpl(AdUserRepository userRepository) { 28 | this.userRepository = userRepository; 29 | } 30 | 31 | @Override 32 | @Transactional 33 | public CreateUserResponse createUser(CreateUserRequest request) throws AdException { 34 | //校验参数 35 | if (!request.validate()) { 36 | throw new AdException(Constants.ErrorMsg.REQUEST_PARAM_ERROR); 37 | } 38 | 39 | //判断同名用户存在 40 | AdUser oldUser = userRepository.findByUsername(request.getUsername()); 41 | if (oldUser != null) { 42 | throw new AdException(Constants.ErrorMsg.SAME_NAME_ERROR); 43 | } 44 | 45 | // 开始创建用户 46 | AdUser newUser = userRepository.save(new AdUser(request.getUsername(), CommonUtils.md5(request.getUsername()) 47 | )); 48 | 49 | return new CreateUserResponse(newUser.getId(), newUser.getUsername(), newUser.getToken(), newUser.getCreateTime(), newUser.getUpdateTime()); 50 | 51 | } 52 | 53 | } 54 | 55 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-search/src/main/java/com/javaedge/ad/controller/SearchController.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.controller; 2 | 3 | import com.alibaba.fastjson.JSON; 4 | import com.javaedge.ad.annotation.IgnoreResponseAdvice; 5 | import com.javaedge.ad.client.SponsorClient; 6 | import com.javaedge.ad.client.vo.AdPlan; 7 | import com.javaedge.ad.client.vo.AdPlanGetRequest; 8 | import com.javaedge.ad.vo.CommonResponse; 9 | import lombok.extern.slf4j.Slf4j; 10 | import org.springframework.web.bind.annotation.PostMapping; 11 | import org.springframework.web.bind.annotation.RequestBody; 12 | import org.springframework.web.bind.annotation.RestController; 13 | import org.springframework.web.client.RestTemplate; 14 | 15 | import java.util.List; 16 | 17 | /** 18 | * @author sss 19 | * @date 2019-02-11 20 | */ 21 | @Slf4j 22 | @RestController 23 | public class SearchController { 24 | 25 | private final RestTemplate restTemplate; 26 | 27 | private final SponsorClient sponsorClient; 28 | 29 | public SearchController(RestTemplate restTemplate, SponsorClient sponsorClient) { 30 | this.restTemplate = restTemplate; 31 | this.sponsorClient = sponsorClient; 32 | } 33 | 34 | @IgnoreResponseAdvice 35 | @PostMapping("/getAdPlans") 36 | public CommonResponse> getAdPlans(@RequestBody AdPlanGetRequest request) { 37 | log.info("ad-search: getAdPlans -> {}", JSON.toJSONString(request)); 38 | return sponsorClient.getAdPlans(request); 39 | } 40 | 41 | @SuppressWarnings("all") 42 | @IgnoreResponseAdvice 43 | @PostMapping("/getAdPlanByRibbon") 44 | public CommonResponse> getAdPlanByRibbon(@RequestBody AdPlanGetRequest request) { 45 | log.info("ad-search: getAdPlanByRibbon -> {}", JSON.toJSONString(request)); 46 | return restTemplate.postForEntity("http://eureka-client-ad-sponsor/ad-sponsor/get/adPlan", 47 | request, 48 | CommonResponse.class).getBody(); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-sponsor/src/main/java/com/javaedge/ad/entity/unitcondition/AdUnit.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.entity.unitcondition; 2 | 3 | import com.javaedge.ad.constant.CommonStatus; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | 8 | import javax.persistence.*; 9 | import java.util.Date; 10 | 11 | /** 12 | * 推广单元 13 | * 14 | * @author sss 15 | * @date 2019/2/1 16 | */ 17 | @Data 18 | @AllArgsConstructor 19 | @NoArgsConstructor 20 | @Entity 21 | @Table(name = "ad_unit") 22 | public class AdUnit { 23 | 24 | @Id 25 | @GeneratedValue(strategy = GenerationType.IDENTITY) 26 | @Column(name = "id", nullable = false) 27 | private Long id; 28 | 29 | /** 30 | * 使用应用程序维护外键关系,而不是建立数据库的外键约束! 31 | */ 32 | @Basic 33 | @Column(name = "plan_id", nullable = false) 34 | private Long planId; 35 | 36 | @Basic 37 | @Column(name = "unit_name", nullable = false) 38 | private String unitName; 39 | 40 | @Basic 41 | @Column(name = "unit_status", nullable = false) 42 | private Integer unitStatus; 43 | 44 | 45 | /** 46 | * 广告位类型(开屏,贴片,中贴...) 47 | */ 48 | @Basic 49 | @Column(name = "position_type", nullable = false) 50 | private Integer positionType; 51 | 52 | @Basic 53 | @Column(name = "budget", nullable = false) 54 | private Long budget; 55 | 56 | @Basic 57 | @Column(name = "create_time", nullable = false) 58 | private Date createTime; 59 | 60 | @Basic 61 | @Column(name = "update_time", nullable = false) 62 | private Date updateTime; 63 | 64 | public AdUnit(Long planId, String unitName, Integer positionType, Long budget) { 65 | this.planId = planId; 66 | this.unitName = unitName; 67 | this.unitStatus = CommonStatus.VALID.getStatus(); 68 | this.positionType = positionType; 69 | this.budget = budget; 70 | this.createTime = new Date(); 71 | this.updateTime = this.createTime; 72 | } 73 | } 74 | 75 | 76 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-search/src/main/java/com/javaedge/ad/mysql/BinlogClient.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.mysql; 2 | 3 | import com.github.shyiko.mysql.binlog.BinaryLogClient; 4 | import com.javaedge.ad.mysql.listener.AggregationListener; 5 | import lombok.extern.slf4j.Slf4j; 6 | import org.apache.commons.lang.StringUtils; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.stereotype.Component; 9 | 10 | import java.io.IOException; 11 | 12 | /** 13 | * @author sss 14 | * @date 2019-02-25 15 | */ 16 | @Slf4j 17 | @Component 18 | public class BinlogClient { 19 | 20 | private BinaryLogClient client; 21 | 22 | private final BinlogConfig config; 23 | private final AggregationListener listener; 24 | 25 | @Autowired 26 | public BinlogClient(BinlogConfig config, AggregationListener listener) { 27 | this.config = config; 28 | this.listener = listener; 29 | } 30 | 31 | public void connect() { 32 | 33 | new Thread(() -> { 34 | client = new BinaryLogClient( 35 | config.getHost(), 36 | config.getPort(), 37 | config.getUsername(), 38 | config.getPassword() 39 | ); 40 | 41 | if (!StringUtils.isEmpty(config.getBinlogName()) && 42 | !config.getPosition().equals(-1L)) { 43 | client.setBinlogFilename(config.getBinlogName()); 44 | client.setBinlogPosition(config.getPosition()); 45 | } 46 | 47 | client.registerEventListener(listener); 48 | 49 | try { 50 | log.info("connecting to mysql start"); 51 | client.connect(); 52 | log.info("connecting to mysql done"); 53 | } catch (IOException ex) { 54 | ex.printStackTrace(); 55 | } 56 | 57 | }).start(); 58 | } 59 | 60 | public void close() { 61 | try { 62 | client.disconnect(); 63 | } catch (IOException ex) { 64 | ex.printStackTrace(); 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-sponsor/src/main/java/com/javaedge/ad/controller/AdPlanOpController.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.controller; 2 | 3 | import com.alibaba.fastjson.JSON; 4 | import com.javaedge.ad.entity.AdPlan; 5 | import com.javaedge.ad.exception.AdException; 6 | import com.javaedge.ad.service.IAdPlanService; 7 | import com.javaedge.ad.vo.AdPlanGetRequest; 8 | import com.javaedge.ad.vo.AdPlanRequest; 9 | import com.javaedge.ad.vo.AdPlanResponse; 10 | import lombok.extern.slf4j.Slf4j; 11 | import org.springframework.beans.factory.annotation.Autowired; 12 | import org.springframework.web.bind.annotation.*; 13 | 14 | import java.util.List; 15 | 16 | /** 17 | * @author sss 18 | * @date 2019-02-11 19 | */ 20 | @Slf4j 21 | @RestController 22 | public class AdPlanOpController { 23 | 24 | private final IAdPlanService adPlanService; 25 | 26 | @Autowired 27 | public AdPlanOpController(IAdPlanService adPlanService) { 28 | this.adPlanService = adPlanService; 29 | } 30 | 31 | @PostMapping("/create/adPlan") 32 | public AdPlanResponse createAdPlan(@RequestBody AdPlanRequest request) throws AdException { 33 | log.info("ad-sponsor: createAdPlan -> {}", JSON.toJSONString(request)); 34 | return adPlanService.createAdPlan(request); 35 | } 36 | 37 | @PostMapping("/get/adPlan") 38 | public List getAdPlanByIds(@RequestBody AdPlanGetRequest request) throws AdException { 39 | log.info("ad-sponsor: getAdPlanByIds -> {}", JSON.toJSONString(request)); 40 | return adPlanService.getAdPlanByIds(request); 41 | } 42 | 43 | @PutMapping("/update/adPlan") 44 | public AdPlanResponse updateAdPlan(@RequestBody AdPlanRequest request) throws AdException { 45 | log.info("ad-sponsor: updateAdPlan -> {}", JSON.toJSONString(request)); 46 | return adPlanService.updateAdPlan(request); 47 | } 48 | 49 | @DeleteMapping("/delete/adPlan") 50 | public void deleteAdPlan(@RequestBody AdPlanRequest request) throws AdException { 51 | log.info("ad-sponsor: deleteAdPlan -> {}", JSON.toJSONString(request)); 52 | adPlanService.deleteAdPlan(request); 53 | } 54 | } 55 | 56 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-sponsor/src/main/java/com/javaedge/ad/entity/Creative.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.entity; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | import javax.persistence.*; 8 | import java.util.Date; 9 | 10 | /** 11 | * 推广创意 12 | * 13 | * @author sss 14 | * @date 2019/2/1 15 | */ 16 | @Data 17 | @AllArgsConstructor 18 | @NoArgsConstructor 19 | @Entity 20 | @Table(name = "ad_creative") 21 | public class Creative { 22 | 23 | @Id 24 | @GeneratedValue(strategy = GenerationType.IDENTITY) 25 | @Column(name = "id", nullable = false) 26 | private Long id; 27 | 28 | /** 29 | * 使用应用程序维护外键关系,而不是建立数据库的外键约束! 30 | */ 31 | @Basic 32 | @Column(name = "name", nullable = false) 33 | private String name; 34 | 35 | @Basic 36 | @Column(name = "type", nullable = false) 37 | private Integer type; 38 | 39 | /** 40 | * 物料的类型,如图片可为 bmp,jpg 等 41 | */ 42 | @Basic 43 | @Column(name = "material_type", nullable = false) 44 | private Integer materialType; 45 | 46 | @Basic 47 | @Column(name = "height", nullable = false) 48 | private Integer height; 49 | 50 | @Basic 51 | @Column(name = "width", nullable = false) 52 | private Integer width; 53 | 54 | /** 55 | * 物料大小 56 | */ 57 | @Basic 58 | @Column(name = "size", nullable = false) 59 | private Long size; 60 | 61 | /** 62 | * 持续时长,只有视频不为0 63 | */ 64 | @Basic 65 | @Column(name = "duration", nullable = false) 66 | private Integer duration; 67 | 68 | /** 69 | * 审核状态 70 | */ 71 | @Basic 72 | @Column(name = "auditStatus", nullable = false) 73 | private Integer auditStatus; 74 | 75 | @Basic 76 | @Column(name = "user-id", nullable = false) 77 | private Long userId; 78 | 79 | @Basic 80 | @Column(name = "url", nullable = false) 81 | private String url; 82 | 83 | @Basic 84 | @Column(name = "create_time", nullable = false) 85 | private Date createTime; 86 | 87 | @Basic 88 | @Column(name = "update_time", nullable = false) 89 | private Date updateTime; 90 | } 91 | 92 | 93 | 94 | 95 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | com.sss.ad 8 | sss-ad 9 | pom 10 | 1.0-SNAPSHOT 11 | 12 | ad-eureka 13 | ad-gateway 14 | javaedge-ad-service 15 | 16 | 17 | sss-ad-spring-cloud 18 | Project For JavaEdge Ad SpringCloud 19 | 20 | 21 | org.springframework.boot 22 | spring-boot-starter-parent 23 | 2.0.2.RELEASE 24 | 25 | 26 | 27 | Finchley.RELEASE 28 | 29 | 30 | 31 | 32 | org.projectlombok 33 | lombok 34 | 1.18.4 35 | 36 | 37 | 38 | org.springframework.boot 39 | spring-boot-starter-test 40 | test 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | org.springframework.cloud 49 | spring-cloud-dependencies 50 | ${spring-cloud.version} 51 | pom 52 | import 53 | 54 | 55 | 56 | 57 | 58 | 59 | spring-milestone 60 | Spring Milestones 61 | https://repo.spring.io/milestones 62 | 63 | false 64 | 65 | 66 | 67 | 68 | 69 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-common/src/main/java/com/javaedge/ad/conf/WebConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.conf; 2 | 3 | import org.springframework.context.annotation.Configuration; 4 | import org.springframework.http.converter.HttpMessageConverter; 5 | import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; 6 | import org.springframework.web.servlet.config.annotation.*; 7 | 8 | import java.util.List; 9 | 10 | /** 11 | * @author sss 12 | * @date 2019/1/31 13 | */ 14 | @Configuration 15 | public class WebConfiguration implements WebMvcConfigurer { 16 | 17 | @Override 18 | public void configureMessageConverters(List> converters) { 19 | converters.clear(); 20 | converters.add(new MappingJackson2HttpMessageConverter()); 21 | } 22 | 23 | @Configuration 24 | public class MyWebMvcConfigurer implements WebMvcConfigurer { 25 | @Override 26 | public void addInterceptors(InterceptorRegistry registry) { 27 | registry.addInterceptor(new MyInterceptor()).addPathPatterns("/**") 28 | .excludePathPatterns("/emp/toLogin","/emp/login","/js/**","/css/**","/images/**"); 29 | } 30 | } 31 | 32 | /** 33 | * 以前要访问一个页面需要先创建个Controller控制类,再写方法跳转到页面 34 | * 在这里配置后就不需要那么麻烦了,直接访问 http://localhost:8080/toLogin 就跳转到 login.html 页面 35 | * @param registry 36 | */ 37 | @Override 38 | public void addViewControllers(ViewControllerRegistry registry) { 39 | registry.addViewController("/toLogin").setViewName("login"); 40 | 41 | } 42 | 43 | @Configuration 44 | public class MyWebMvcConfigurerAdapter implements WebMvcConfigurer { 45 | /** 46 | * 配置静态访问资源 47 | * @param registry 48 | */ 49 | @Override 50 | public void addResourceHandlers(ResourceHandlerRegistry registry) { 51 | registry.addResourceHandler("/my/**").addResourceLocations("classpath:/my/"); 52 | 53 | } 54 | } 55 | 56 | @Override 57 | public void addResourceHandlers(ResourceHandlerRegistry registry) { 58 | registry.addResourceHandler("/my/**").addResourceLocations("file:E:/my/"); 59 | 60 | } 61 | 62 | @Override 63 | public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) { 64 | configurer.enable(); 65 | configurer.enable("defaultServletName"); 66 | } 67 | 68 | 69 | 70 | 71 | 72 | } 73 | -------------------------------------------------------------------------------- /ad-gateway/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | sss-ad 9 | com.sss.ad 10 | 1.0-SNAPSHOT 11 | 12 | 4.0.0 13 | 14 | 15 | ad-gateway 16 | 1.0-SNAPSHOT 17 | jar 18 | 19 | 20 | ad-gateway 21 | ad-gateway 22 | 23 | 24 | 28 | 29 | org.springframework.cloud 30 | spring-cloud-starter-netflix-eureka-client 31 | 32 | 33 | 34 | org.springframework.cloud 35 | spring-cloud-starter-netflix-zuul 36 | 37 | 38 | 39 | org.springframework.cloud 40 | spring-cloud-starter-hystrix 41 | 42 | 43 | 44 | com.netflix.hystrix 45 | hystrix-javanica 46 | 47 | 48 | aspectj 49 | aspectjrt 50 | 1.5.4 51 | 52 | 53 | 54 | 58 | 59 | 60 | 61 | org.springframework.boot 62 | spring-boot-maven-plugin 63 | 64 | 65 | 66 | 67 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-search/src/main/java/com/javaedge/ad/index/creative/CreativeIndex.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.index.creative; 2 | 3 | import com.javaedge.ad.index.IndexAware; 4 | import lombok.extern.slf4j.Slf4j; 5 | import org.apache.commons.collections4.CollectionUtils; 6 | import org.springframework.stereotype.Component; 7 | 8 | import java.util.ArrayList; 9 | import java.util.Collection; 10 | import java.util.Collections; 11 | import java.util.List; 12 | import java.util.Map; 13 | import java.util.concurrent.ConcurrentHashMap; 14 | 15 | /** 16 | * @author sss 17 | * @date 2019-02-12 18 | */ 19 | @Slf4j 20 | @Component 21 | public class CreativeIndex implements IndexAware { 22 | 23 | private static Map objectMap; 24 | 25 | static { 26 | objectMap = new ConcurrentHashMap<>(); 27 | } 28 | 29 | public List fetch(Collection adIds) { 30 | if (CollectionUtils.isEmpty(adIds)) { 31 | return Collections.emptyList(); 32 | } 33 | 34 | List result = new ArrayList<>(); 35 | 36 | adIds.forEach(u -> { 37 | CreativeObject object = get(u); 38 | if (null == object) { 39 | log.error("CreativeObject not found: {}", u); 40 | return; 41 | } 42 | result.add(object); 43 | }); 44 | return result; 45 | } 46 | 47 | @Override 48 | public CreativeObject get(Long key) { 49 | return objectMap.get(key); 50 | } 51 | 52 | @Override 53 | public void add(Long key, CreativeObject value) { 54 | log.info("before add: {}", objectMap); 55 | objectMap.put(key, value); 56 | log.info("after add: {}", objectMap); 57 | } 58 | 59 | @Override 60 | public void update(Long key, CreativeObject value) { 61 | log.info("before update: {}", objectMap); 62 | 63 | CreativeObject oldObject = objectMap.get(key); 64 | if (null == oldObject) { 65 | objectMap.put(key, value); 66 | } else { 67 | oldObject.update(value); 68 | } 69 | 70 | log.info("after update: {}", objectMap); 71 | } 72 | 73 | @Override 74 | public void delete(Long key, CreativeObject value) { 75 | log.info("before delete: {}", objectMap); 76 | objectMap.remove(key); 77 | log.info("after delete: {}", objectMap); 78 | } 79 | } 80 | 81 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-search/src/main/java/com/javaedge/ad/service/BinlogServiceTest.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.service; 2 | 3 | import com.github.shyiko.mysql.binlog.BinaryLogClient; 4 | import com.github.shyiko.mysql.binlog.event.DeleteRowsEventData; 5 | import com.github.shyiko.mysql.binlog.event.EventData; 6 | import com.github.shyiko.mysql.binlog.event.UpdateRowsEventData; 7 | import com.github.shyiko.mysql.binlog.event.WriteRowsEventData; 8 | 9 | /** 10 | * @author sss 11 | * @date 2019-02-22 12 | */ 13 | public class BinlogServiceTest { 14 | 15 | // Write--------------- 16 | // WriteRowsEventData{tableId=85, includedColumns={0, 1, 2}, rows=[ 17 | // [10, 10, 宝马] 18 | //]} 19 | // Update-------------- 20 | // UpdateRowsEventData{tableId=85, includedColumnsBeforeUpdate={0, 1, 2}, 21 | // includedColumns={0, 1, 2}, rows=[ 22 | // {before=[10, 10, 宝马], after=[10, 11, 宝马]} 23 | //]} 24 | // Delete-------------- 25 | // DeleteRowsEventData{tableId=85, includedColumns={0, 1, 2}, rows=[ 26 | // [11, 10, 奔驰] 27 | //]} 28 | 29 | 30 | // Write--------------- 31 | // WriteRowsEventData{tableId=70, includedColumns={0, 1, 2, 3, 4, 5, 6, 7}, rows=[ 32 | // [12, 10, plan, 1, Tue Jan 01 08:00:00 CST 2019, Tue Jan 01 08:00:00 CST 2019, Tue Jan 01 08:00:00 CST 2019, Tue Jan 01 08:00:00 CST 2019] 33 | //]} 34 | 35 | // Tue Jan 01 08:00:00 CST 2019 36 | 37 | public static void main(String[] args) throws Exception { 38 | 39 | BinaryLogClient client = new BinaryLogClient( 40 | "127.0.0.1", 41 | 3306, 42 | "root", 43 | "root" 44 | ); 45 | // client.setBinlogFilename("binlog.000037"); 46 | // client.setBinlogPosition(); 47 | 48 | client.registerEventListener(event -> { 49 | 50 | EventData data = event.getData(); 51 | 52 | if (data instanceof UpdateRowsEventData) { 53 | System.out.println("Update--------------"); 54 | System.out.println(data.toString()); 55 | } else if (data instanceof WriteRowsEventData) { 56 | System.out.println("Write---------------"); 57 | System.out.println(data.toString()); 58 | } else if (data instanceof DeleteRowsEventData) { 59 | System.out.println("Delete--------------"); 60 | System.out.println(data.toString()); 61 | } 62 | }); 63 | 64 | client.connect(); 65 | } 66 | } 67 | 68 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-sponsor/src/main/java/com/javaedge/ad/controller/AdUnitOpController.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.controller; 2 | 3 | import com.alibaba.fastjson.JSON; 4 | import com.javaedge.ad.exception.AdException; 5 | import com.javaedge.ad.service.IAdUnitService; 6 | import com.javaedge.ad.vo.*; 7 | import lombok.extern.slf4j.Slf4j; 8 | import org.springframework.beans.factory.annotation.Autowired; 9 | import org.springframework.web.bind.annotation.PostMapping; 10 | import org.springframework.web.bind.annotation.RequestBody; 11 | import org.springframework.web.bind.annotation.RestController; 12 | 13 | /** 14 | * @author sss 15 | * @date 2019-02-11 16 | */ 17 | @Slf4j 18 | @RestController 19 | public class AdUnitOpController { 20 | 21 | private final IAdUnitService adUnitService; 22 | 23 | @Autowired 24 | public AdUnitOpController(IAdUnitService adUnitService) { 25 | this.adUnitService = adUnitService; 26 | } 27 | 28 | @PostMapping("/create/adUnit") 29 | public AdUnitResponse createUnit(@RequestBody AdUnitRequest request) throws AdException { 30 | log.info("ad-sponsor: createUnit -> {}", JSON.toJSONString(request)); 31 | return adUnitService.createUnit(request); 32 | } 33 | 34 | @PostMapping("/create/unitKeyword") 35 | public AdUnitKeywordResponse createUnitKeyword(@RequestBody AdUnitKeywordRequest request) throws AdException { 36 | log.info("ad-sponsor: createUnitKeyword -> {}", JSON.toJSONString(request)); 37 | return adUnitService.createUnitKeyword(request); 38 | } 39 | 40 | @PostMapping("/create/unitIt") 41 | public AdUnitItResponse createUnitIt(@RequestBody AdUnitItRequest request) throws AdException { 42 | log.info("ad-sponsor: createUnitIt -> {}", JSON.toJSONString(request)); 43 | return adUnitService.createUnitIt(request); 44 | } 45 | 46 | @PostMapping("/create/unitDistrict") 47 | public AdUnitDistrictResponse createUnitDistrict(@RequestBody AdUnitDistrictRequest request) throws AdException { 48 | log.info("ad-sponsor: createUnitDistrict -> {}", JSON.toJSONString(request)); 49 | return adUnitService.createUnitDistrict(request); 50 | } 51 | 52 | @PostMapping("/create/creativeUnit") 53 | public CreativeUnitResponse createCreativeUnit(@RequestBody CreativeUnitRequest request) throws AdException { 54 | log.info("ad-sponsor: createCreativeUnit -> {}", JSON.toJSONString(request)); 55 | return adUnitService.createCreativeUnit(request); 56 | } 57 | } 58 | 59 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-search/src/main/java/com/javaedge/ad/mysql/dto/ParseTemplate.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.mysql.dto; 2 | 3 | import com.javaedge.ad.mysql.constant.OpType; 4 | import lombok.Data; 5 | 6 | import java.util.ArrayList; 7 | import java.util.HashMap; 8 | import java.util.List; 9 | import java.util.Map; 10 | import java.util.function.Supplier; 11 | 12 | /** 13 | * 解析模板 14 | * 15 | * @author sss 16 | * @date 2019-02-25 17 | */ 18 | @Data 19 | public class ParseTemplate { 20 | 21 | private String database; 22 | 23 | private Map tableTemplateMap = new HashMap<>(); 24 | 25 | public static ParseTemplate parse(Template _template) { 26 | 27 | ParseTemplate template = new ParseTemplate(); 28 | template.setDatabase(_template.getDatabase()); 29 | 30 | for (JsonTable table : _template.getTableList()) { 31 | 32 | String name = table.getTableName(); 33 | Integer level = table.getLevel(); 34 | 35 | TableTemplate tableTemplate = new TableTemplate(); 36 | tableTemplate.setTableName(name); 37 | tableTemplate.setLevel(level.toString()); 38 | template.tableTemplateMap.put(name, tableTemplate); 39 | 40 | // 遍历操作类型对应的列 41 | Map> opTypeFieldSetMap = 42 | tableTemplate.getOpTypeFieldSetMap(); 43 | 44 | for (JsonTable.Column column : table.getInsert()) { 45 | getAndCreateIfNeed( 46 | OpType.ADD, 47 | opTypeFieldSetMap, 48 | ArrayList::new 49 | ).add(column.getColumn()); 50 | } 51 | for (JsonTable.Column column : table.getUpdate()) { 52 | getAndCreateIfNeed( 53 | OpType.UPDATE, 54 | opTypeFieldSetMap, 55 | ArrayList::new 56 | ).add(column.getColumn()); 57 | } 58 | for (JsonTable.Column column : table.getDelete()) { 59 | getAndCreateIfNeed( 60 | OpType.DELETE, 61 | opTypeFieldSetMap, 62 | ArrayList::new 63 | ).add(column.getColumn()); 64 | } 65 | } 66 | 67 | return template; 68 | } 69 | 70 | private static R getAndCreateIfNeed(T key, Map map, 71 | Supplier factory) { 72 | return map.computeIfAbsent(key, k -> factory.get()); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-search/src/main/java/com/javaedge/ad/index/interest/UnitItIndex.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.index.interest; 2 | 3 | import com.javaedge.ad.index.IndexAware; 4 | import com.javaedge.ad.index.district.UnitDistrictIndex; 5 | import com.javaedge.ad.utils.CommonUtils; 6 | import lombok.extern.slf4j.Slf4j; 7 | import org.apache.commons.collections4.CollectionUtils; 8 | import org.springframework.stereotype.Component; 9 | 10 | import java.util.List; 11 | import java.util.Map; 12 | import java.util.Set; 13 | import java.util.concurrent.ConcurrentHashMap; 14 | import java.util.concurrent.ConcurrentSkipListSet; 15 | 16 | /** 17 | * @author sss 18 | * @date 2019-02-12 19 | */ 20 | @Slf4j 21 | @Component 22 | public class UnitItIndex implements IndexAware> { 23 | 24 | /** 25 | * 反向索引 26 | */ 27 | private static Map> itUnitMap; 28 | 29 | /** 30 | * 正向索引 31 | */ 32 | private static Map> unitItMap; 33 | 34 | static { 35 | itUnitMap = new ConcurrentHashMap<>(); 36 | unitItMap = new ConcurrentHashMap<>(); 37 | } 38 | 39 | @Override 40 | public Set get(String key) { 41 | return itUnitMap.get(key); 42 | } 43 | 44 | @Override 45 | public void add(String key, Set value) { 46 | 47 | log.info("UnitItIndex, before add: {}", unitItMap); 48 | 49 | UnitDistrictIndex.changeADD(key, value, itUnitMap, unitItMap); 50 | 51 | log.info("UnitItIndex, after add: {}", unitItMap); 52 | } 53 | 54 | @Override 55 | public void update(String key, Set value) { 56 | 57 | log.error("it index can not support update"); 58 | } 59 | 60 | @Override 61 | public void delete(String key, Set value) { 62 | 63 | log.info("UnitItIndex, before delete: {}", unitItMap); 64 | 65 | // 先取出对应的推广 单元id 66 | UnitDistrictIndex.changeRM(key, value, itUnitMap, unitItMap); 67 | 68 | log.info("UnitItIndex, after delete: {}", unitItMap); 69 | } 70 | 71 | /** 72 | * 检索服务时会用到 73 | * 74 | * @param unitId 75 | * @param itTags 76 | * @return 77 | */ 78 | public boolean match(Long unitId, List itTags) { 79 | 80 | if (unitItMap.containsKey(unitId) && CollectionUtils.isNotEmpty(unitItMap.get(unitId))) { 81 | Set unitKeywords = unitItMap.get(unitId); 82 | 83 | return CollectionUtils.isSubCollection(itTags, unitKeywords); 84 | } 85 | 86 | return false; 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-search/src/main/java/com/javaedge/ad/index/adunit/AdUnitIndex.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.index.adunit; 2 | 3 | import com.javaedge.ad.index.IndexAware; 4 | import lombok.extern.slf4j.Slf4j; 5 | import org.apache.commons.collections4.CollectionUtils; 6 | import org.springframework.stereotype.Component; 7 | 8 | import java.util.*; 9 | import java.util.concurrent.ConcurrentHashMap; 10 | 11 | /** 12 | * @author sss 13 | * @date 2019-02-11 14 | */ 15 | @Slf4j 16 | @Component 17 | public class AdUnitIndex implements IndexAware { 18 | 19 | private static Map objectMap; 20 | 21 | static{ 22 | objectMap = new ConcurrentHashMap<>(); 23 | 24 | } 25 | 26 | public Set match(Integer positionType) { 27 | 28 | Set adUnitIds = new HashSet<>(); 29 | 30 | objectMap.forEach((k, v) -> { 31 | if (AdUnitObject.isAdSlotTypeOK(positionType, 32 | v.getPositionType())) { 33 | adUnitIds.add(k); 34 | } 35 | }); 36 | 37 | return adUnitIds; 38 | } 39 | 40 | public List fetch(Collection adUnitIds) { 41 | 42 | if (CollectionUtils.isEmpty(adUnitIds)) { 43 | return Collections.emptyList(); 44 | } 45 | 46 | List result = new ArrayList<>(); 47 | 48 | adUnitIds.forEach(u -> { 49 | AdUnitObject object = get(u); 50 | if (object == null) { 51 | log.error("AdUnitObject not found: {}", u); 52 | return; 53 | } 54 | result.add(object); 55 | }); 56 | 57 | return result; 58 | } 59 | 60 | 61 | @Override 62 | public AdUnitObject get(Long key) { 63 | return objectMap.get(key); 64 | } 65 | 66 | @Override 67 | public void add(Long key, AdUnitObject value) { 68 | log.info("before add: {}", objectMap); 69 | 70 | objectMap.put(key, value); 71 | 72 | log.info("after add: {}", objectMap); 73 | } 74 | 75 | @Override 76 | public void update(Long key, AdUnitObject value) { 77 | log.info("before update: {}", objectMap); 78 | 79 | AdUnitObject oldObject = objectMap.get(key); 80 | if (null == oldObject) { 81 | objectMap.put(key, value); 82 | } else { 83 | oldObject.update(value); 84 | } 85 | 86 | log.info("after update: {}", objectMap); 87 | } 88 | 89 | @Override 90 | public void delete(Long key, AdUnitObject value) { 91 | log.info("before delete: {}", objectMap); 92 | objectMap.remove(key); 93 | log.info("after delete: {}", objectMap); 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-search/src/main/java/com/javaedge/ad/search/controller/SearchController.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.search.controller; 2 | 3 | import com.alibaba.fastjson.JSON; 4 | import com.javaedge.ad.annotation.IgnoreResponseAdvice; 5 | import com.javaedge.ad.client.SponsorClient; 6 | import com.javaedge.ad.client.vo.AdPlan; 7 | import com.javaedge.ad.client.vo.AdPlanGetRequest; 8 | import com.javaedge.ad.search.ISearch; 9 | import com.javaedge.ad.search.vo.SearchRequest; 10 | import com.javaedge.ad.search.vo.SearchResponse; 11 | import com.javaedge.ad.vo.CommonResponse; 12 | import lombok.extern.slf4j.Slf4j; 13 | import org.springframework.beans.factory.annotation.Autowired; 14 | import org.springframework.web.bind.annotation.PostMapping; 15 | import org.springframework.web.bind.annotation.RequestBody; 16 | import org.springframework.web.bind.annotation.RestController; 17 | import org.springframework.web.client.RestTemplate; 18 | 19 | import java.util.List; 20 | 21 | /** 22 | * @author sss 23 | * @date 2019-02-26 24 | */ 25 | @Slf4j 26 | @RestController 27 | public class SearchController { 28 | 29 | private final ISearch search; 30 | 31 | private final RestTemplate restTemplate; 32 | 33 | private final SponsorClient sponsorClient; 34 | 35 | @Autowired 36 | public SearchController(RestTemplate restTemplate, 37 | SponsorClient sponsorClient, ISearch search) { 38 | this.restTemplate = restTemplate; 39 | this.sponsorClient = sponsorClient; 40 | this.search = search; 41 | } 42 | 43 | @PostMapping("/fetchAds") 44 | public SearchResponse fetchAds(@RequestBody SearchRequest request) { 45 | 46 | log.info("ad-search: fetchAds -> {}", 47 | JSON.toJSONString(request)); 48 | return search.fetchAds(request); 49 | } 50 | 51 | @IgnoreResponseAdvice 52 | @PostMapping("/getAdPlans") 53 | public CommonResponse> getAdPlans( 54 | @RequestBody AdPlanGetRequest request 55 | ) { 56 | log.info("ad-search: getAdPlans -> {}", 57 | JSON.toJSONString(request)); 58 | return sponsorClient.getAdPlans(request); 59 | } 60 | 61 | @SuppressWarnings("all") 62 | @IgnoreResponseAdvice 63 | @PostMapping("/getAdPlansByRibbon") 64 | public CommonResponse> getAdPlansByRebbon( 65 | @RequestBody AdPlanGetRequest request 66 | ) { 67 | log.info("ad-search: getAdPlansByRibbon -> {}", 68 | JSON.toJSONString(request)); 69 | return restTemplate.postForEntity( 70 | "http://eureka-client-ad-sponsor/ad-sponsor/get/adPlan", 71 | request, 72 | CommonResponse.class 73 | ).getBody(); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-search/src/main/java/com/javaedge/ad/mysql/listener/IncrementListener.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.mysql.listener; 2 | 3 | import com.github.shyiko.mysql.binlog.event.EventType; 4 | import com.javaedge.ad.mysql.constant.Constant; 5 | import com.javaedge.ad.mysql.constant.OpType; 6 | import com.javaedge.ad.mysql.dto.BinlogRowData; 7 | import com.javaedge.ad.mysql.dto.MySqlRowData; 8 | import com.javaedge.ad.mysql.dto.TableTemplate; 9 | import com.javaedge.ad.sender.ISender; 10 | import lombok.extern.slf4j.Slf4j; 11 | import org.springframework.beans.factory.annotation.Autowired; 12 | import org.springframework.stereotype.Component; 13 | 14 | import javax.annotation.PostConstruct; 15 | import javax.annotation.Resource; 16 | import java.util.HashMap; 17 | import java.util.List; 18 | import java.util.Map; 19 | 20 | /** 21 | * @author sss 22 | * @date 2019-02-26 23 | */ 24 | @Slf4j 25 | @Component 26 | public class IncrementListener implements Ilistener { 27 | 28 | @Resource(name = "kafkaSender") 29 | private ISender sender; 30 | 31 | private final AggregationListener aggregationListener; 32 | 33 | @Autowired 34 | public IncrementListener(AggregationListener aggregationListener) { 35 | this.aggregationListener = aggregationListener; 36 | } 37 | 38 | @Override 39 | @PostConstruct 40 | public void register() { 41 | 42 | log.info("IncrementListener register db and table info"); 43 | Constant.table2Db.forEach((k, v) -> 44 | aggregationListener.register(v, k, this)); 45 | } 46 | 47 | @Override 48 | public void onEvent(BinlogRowData eventData) { 49 | 50 | TableTemplate table = eventData.getTable(); 51 | EventType eventType = eventData.getEventType(); 52 | 53 | // 包装成最后需要投递的数据 54 | MySqlRowData rowData = new MySqlRowData(); 55 | 56 | rowData.setTableName(table.getTableName()); 57 | rowData.setLevel(eventData.getTable().getLevel()); 58 | OpType opType = OpType.to(eventType); 59 | rowData.setOpType(opType); 60 | 61 | // 取出模板中该操作对应的字段列表 62 | List fieldList = table.getOpTypeFieldSetMap().get(opType); 63 | if (null == fieldList) { 64 | log.warn("{} not support for {}", opType, table.getTableName()); 65 | return; 66 | } 67 | 68 | for (Map afterMap : eventData.getAfter()) { 69 | 70 | Map _afterMap = new HashMap<>(); 71 | 72 | for (Map.Entry entry : afterMap.entrySet()) { 73 | 74 | String colName = entry.getKey(); 75 | String colValue = entry.getValue(); 76 | 77 | _afterMap.put(colName, colValue); 78 | } 79 | 80 | rowData.getFieldValueMap().add(_afterMap); 81 | } 82 | 83 | sender.sender(rowData); 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-search/src/main/java/com/javaedge/ad/index/adunit/AdUnitObject.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.index.adunit; 2 | 3 | import com.javaedge.ad.index.adplan.AdPlanObject; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | 8 | /** 9 | * 推广单元 索引对象 10 | * 11 | * @author sss 12 | * @date 2019-02-11 13 | */ 14 | @Data 15 | @NoArgsConstructor 16 | @AllArgsConstructor 17 | public class AdUnitObject { 18 | 19 | private Long unitId; 20 | private Integer unitStatus; 21 | private Integer positionType; 22 | private Long planId; 23 | 24 | private AdPlanObject adPlanObject; 25 | 26 | void update(AdUnitObject newObject) { 27 | if (null != newObject.getUnitId()) { 28 | this.unitId = newObject.getUnitId(); 29 | } 30 | if (null != newObject.getUnitStatus()) { 31 | this.unitStatus = newObject.getUnitStatus(); 32 | } 33 | if (null != newObject.getPositionType()) { 34 | this.positionType = newObject.getPositionType(); 35 | } 36 | if (null != planId) { 37 | this.planId = newObject.getPlanId(); 38 | } 39 | if (null != newObject.getAdPlanObject()) { 40 | this.adPlanObject = newObject.getAdPlanObject(); 41 | } 42 | } 43 | 44 | private static boolean isKaiPing(int positionType) { 45 | return (positionType & AdUnitConstants.POSITION_TYPE.KAIPING) > 0; 46 | } 47 | 48 | private static boolean isTiePian(int positionType) { 49 | return (positionType & AdUnitConstants.POSITION_TYPE.TIEPIAN) > 0; 50 | } 51 | 52 | private static boolean isTiePianMiddle(int positionType) { 53 | return (positionType & AdUnitConstants.POSITION_TYPE.TIEPIAN_MIDDLE) > 0; 54 | } 55 | 56 | private static boolean isTiePianPause(int positionType) { 57 | return (positionType & AdUnitConstants.POSITION_TYPE.TIEPIAN_PAUSE) > 0; 58 | } 59 | 60 | private static boolean isTiePianPost(int positionType) { 61 | return (positionType & AdUnitConstants.POSITION_TYPE.TIEPIAN_POST) > 0; 62 | } 63 | 64 | public static boolean isAdSlotTypeOK(int adSlotType, int positionType) { 65 | 66 | switch (adSlotType) { 67 | case AdUnitConstants.POSITION_TYPE.KAIPING: 68 | return isKaiPing(positionType); 69 | case AdUnitConstants.POSITION_TYPE.TIEPIAN: 70 | return isTiePian(positionType); 71 | case AdUnitConstants.POSITION_TYPE.TIEPIAN_MIDDLE: 72 | return isTiePianMiddle(positionType); 73 | case AdUnitConstants.POSITION_TYPE.TIEPIAN_PAUSE: 74 | return isTiePianPause(positionType); 75 | case AdUnitConstants.POSITION_TYPE.TIEPIAN_POST: 76 | return isTiePianPost(positionType); 77 | default: 78 | return false; 79 | } 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-search/src/main/java/com/javaedge/ad/index/keyword/UnitKeywordIndex.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.index.keyword; 2 | 3 | import com.javaedge.ad.index.IndexAware; 4 | import com.javaedge.ad.index.district.UnitDistrictIndex; 5 | import com.javaedge.ad.utils.CommonUtils; 6 | import lombok.extern.slf4j.Slf4j; 7 | import org.apache.commons.collections4.CollectionUtils; 8 | import org.apache.commons.lang.StringUtils; 9 | import org.springframework.stereotype.Component; 10 | 11 | import java.util.Collections; 12 | import java.util.List; 13 | import java.util.Map; 14 | import java.util.Set; 15 | import java.util.concurrent.ConcurrentHashMap; 16 | import java.util.concurrent.ConcurrentSkipListSet; 17 | /** 18 | * @author sss 19 | * @date 2019-02-11 20 | */ 21 | @Slf4j 22 | @Component 23 | public class UnitKeywordIndex implements IndexAware> { 24 | 25 | private static Map> keywordUnitMap; 26 | private static Map> unitKeywordMap; 27 | 28 | static { 29 | keywordUnitMap = new ConcurrentHashMap<>(); 30 | unitKeywordMap = new ConcurrentHashMap<>(); 31 | } 32 | 33 | @Override 34 | public Set get(String key) { 35 | 36 | if (StringUtils.isEmpty(key)) { 37 | return Collections.emptySet(); 38 | } 39 | 40 | Set result = keywordUnitMap.get(key); 41 | if (result == null) { 42 | return Collections.emptySet(); 43 | } 44 | 45 | return result; 46 | } 47 | 48 | @Override 49 | public void add(String key, Set value) { 50 | 51 | log.info("UnitKeywordIndex, before add: {}", unitKeywordMap); 52 | 53 | UnitDistrictIndex.changeADD(key, value, keywordUnitMap, unitKeywordMap); 54 | 55 | log.info("UnitKeywordIndex, after add: {}", unitKeywordMap); 56 | } 57 | 58 | /** 59 | * 关键词的更新会导致两个 map 发生改变,且牵扯到 set 服务,成本过高 60 | * 推荐 先删后加 以实现更新. 61 | * 62 | * @param key 63 | * @param value 64 | */ 65 | @Override 66 | public void update(String key, Set value) { 67 | 68 | log.error("keyword index can not support update"); 69 | } 70 | 71 | @Override 72 | public void delete(String key, Set value) { 73 | 74 | log.info("UnitKeywordIndex, before delete: {}", unitKeywordMap); 75 | 76 | UnitDistrictIndex.changeRM(key, value, keywordUnitMap, unitKeywordMap); 77 | 78 | log.info("UnitKeywordIndex, after delete: {}", unitKeywordMap); 79 | } 80 | 81 | public boolean match(Long unitId, List keywords) { 82 | 83 | if (unitKeywordMap.containsKey(unitId) 84 | && CollectionUtils.isNotEmpty(unitKeywordMap.get(unitId))) { 85 | 86 | Set unitKeywords = unitKeywordMap.get(unitId); 87 | 88 | return CollectionUtils.isSubCollection(keywords, unitKeywords); 89 | } 90 | 91 | return false; 92 | } 93 | } 94 | 95 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-search/src/main/resources/template.json: -------------------------------------------------------------------------------- 1 | { 2 | "database": "javaedge_ad_data", 3 | "tableList": [ 4 | { 5 | "tableName": "ad_plan", 6 | "level": 2, 7 | "insert": [ 8 | {"column": "id"}, 9 | {"column": "user_id"}, 10 | {"column": "plan_status"}, 11 | {"column": "start_date"}, 12 | {"column": "end_date"} 13 | ], 14 | "update": [ 15 | {"column": "id"}, 16 | {"column": "user_id"}, 17 | {"column": "plan_status"}, 18 | {"column": "start_date"}, 19 | {"column": "end_date"} 20 | ], 21 | "delete": [ 22 | {"column": "id"} 23 | ] 24 | }, 25 | { 26 | "tableName": "ad_unit", 27 | "level": 3, 28 | "insert": [ 29 | {"column": "id"}, 30 | {"column": "unit_status"}, 31 | {"column": "position_type"}, 32 | {"column": "plan_id"} 33 | ], 34 | "update": [ 35 | {"column": "id"}, 36 | {"column": "unit_status"}, 37 | {"column": "position_type"}, 38 | {"column": "plan_id"} 39 | ], 40 | "delete": [ 41 | {"column": "id"} 42 | ] 43 | }, 44 | { 45 | "tableName": "ad_creative", 46 | "level": 2, 47 | "insert": [ 48 | {"column": "id"}, 49 | {"column": "type"}, 50 | {"column": "material_type"}, 51 | {"column": "height"}, 52 | {"column": "width"}, 53 | {"column": "audit_status"}, 54 | {"column": "url"} 55 | ], 56 | "update": [ 57 | {"column": "id"}, 58 | {"column": "type"}, 59 | {"column": "material_type"}, 60 | {"column": "height"}, 61 | {"column": "width"}, 62 | {"column": "audit_status"}, 63 | {"column": "url"} 64 | ], 65 | "delete": [ 66 | {"column": "id"} 67 | ] 68 | }, 69 | { 70 | "tableName": "creative_unit", 71 | "level": 3, 72 | "insert": [ 73 | {"column": "creative_id"}, 74 | {"column": "unit_id"} 75 | ], 76 | "update": [ 77 | ], 78 | "delete": [ 79 | {"column": "creative_id"}, 80 | {"column": "unit_id"} 81 | ] 82 | }, 83 | { 84 | "tableName": "ad_unit_district", 85 | "level": 4, 86 | "insert": [ 87 | {"column": "unit_id"}, 88 | {"column": "province"}, 89 | {"column": "city"} 90 | ], 91 | "update": [ 92 | ], 93 | "delete": [ 94 | {"column": "unit_id"}, 95 | {"column": "province"}, 96 | {"column": "city"} 97 | ] 98 | }, 99 | { 100 | "tableName": "ad_unit_it", 101 | "level": 4, 102 | "insert": [ 103 | {"column": "unit_id"}, 104 | {"column": "it_tag"} 105 | ], 106 | "update": [ 107 | ], 108 | "delete": [ 109 | {"column": "unit_id"}, 110 | {"column": "it_tag"} 111 | ] 112 | }, 113 | { 114 | "tableName": "ad_unit_keyword", 115 | "level": 4, 116 | "insert": [ 117 | {"column": "unit_id"}, 118 | {"column": "keyword"} 119 | ], 120 | "update": [ 121 | ], 122 | "delete": [ 123 | {"column": "unit_id"}, 124 | {"column": "keyword"} 125 | ] 126 | } 127 | ] 128 | } 129 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-search/src/main/java/com/javaedge/ad/mysql/constant/Constant.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.mysql.constant; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | /** 7 | * @author sss 8 | * @date 2019-02-25 9 | */ 10 | public class Constant { 11 | 12 | private static final String DB_NAME = "javaedge_ad_data"; 13 | 14 | public static class AD_PLAN_TABLE_INFO { 15 | 16 | public static final String TABLE_NAME = "ad_plan"; 17 | 18 | public static final String COLUMN_ID = "id"; 19 | public static final String COLUMN_USER_ID = "user_id"; 20 | public static final String COLUMN_PLAN_STATUS = "plan_status"; 21 | public static final String COLUMN_START_DATE = "start_date"; 22 | public static final String COLUMN_END_DATE = "end_date"; 23 | } 24 | 25 | public static class AD_CREATIVE_TABLE_INFO { 26 | 27 | public static final String TABLE_NAME = "ad_creative"; 28 | 29 | public static final String COLUMN_ID = "id"; 30 | public static final String COLUMN_TYPE = "type"; 31 | public static final String COLUMN_MATERIAL_TYPE = "material_type"; 32 | public static final String COLUMN_HEIGHT = "height"; 33 | public static final String COLUMN_WIDTH = "width"; 34 | public static final String COLUMN_AUDIT_STATUS = "audit_status"; 35 | public static final String COLUMN_URL = "url"; 36 | } 37 | 38 | public static class AD_UNIT_TABLE_INFO { 39 | 40 | public static final String TABLE_NAME = "ad_unit"; 41 | 42 | public static final String COLUMN_ID = "id"; 43 | public static final String COLUMN_UNIT_STATUS = "unit_status"; 44 | public static final String COLUMN_POSITION_TYPE = "position_type"; 45 | public static final String COLUMN_PLAN_ID = "plan_id"; 46 | } 47 | 48 | public static class AD_CREATIVE_UNIT_TABLE_INFO { 49 | 50 | public static final String TABLE_NAME = "creative_unit"; 51 | 52 | public static final String COLUMN_CREATIVE_ID = "creative_id"; 53 | public static final String COLUMN_UNIT_ID = "unit_id"; 54 | } 55 | 56 | public static class AD_UNIT_DISTRICT_TABLE_INFO { 57 | 58 | public static final String TABLE_NAME = "ad_unit_district"; 59 | 60 | public static final String COLUMN_UNIT_ID = "unit_id"; 61 | public static final String COLUMN_PROVINCE = "province"; 62 | public static final String COLUMN_CITY = "city"; 63 | } 64 | 65 | public static class AD_UNIT_IT_TABLE_INFO { 66 | 67 | public static final String TABLE_NAME = "ad_unit_it"; 68 | 69 | public static final String COLUMN_UNIT_ID = "unit_id"; 70 | public static final String COLUMN_IT_TAG = "it_tag"; 71 | } 72 | 73 | public static class AD_UNIT_KEYWORD_TABLE_INFO { 74 | 75 | public static final String TABLE_NAME = "ad_unit_keyword"; 76 | 77 | public static final String COLUMN_UNIT_ID = "unit_id"; 78 | public static final String COLUMN_KEYWORD = "keyword"; 79 | } 80 | 81 | public static Map table2Db; 82 | 83 | static { 84 | 85 | table2Db = new HashMap<>(); 86 | 87 | table2Db.put(AD_PLAN_TABLE_INFO.TABLE_NAME, DB_NAME); 88 | table2Db.put(AD_CREATIVE_TABLE_INFO.TABLE_NAME, DB_NAME); 89 | table2Db.put(AD_UNIT_TABLE_INFO.TABLE_NAME, DB_NAME); 90 | table2Db.put(AD_CREATIVE_UNIT_TABLE_INFO.TABLE_NAME, DB_NAME); 91 | table2Db.put(AD_UNIT_DISTRICT_TABLE_INFO.TABLE_NAME, DB_NAME); 92 | table2Db.put(AD_UNIT_IT_TABLE_INFO.TABLE_NAME, DB_NAME); 93 | table2Db.put(AD_UNIT_KEYWORD_TABLE_INFO.TABLE_NAME, DB_NAME); 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-search/src/main/java/com/javaedge/ad/mysql/TemplateHolder.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.mysql; 2 | 3 | import com.alibaba.fastjson.JSON; 4 | import com.javaedge.ad.mysql.constant.OpType; 5 | import com.javaedge.ad.mysql.dto.ParseTemplate; 6 | import com.javaedge.ad.mysql.dto.TableTemplate; 7 | import com.javaedge.ad.mysql.dto.Template; 8 | import lombok.extern.slf4j.Slf4j; 9 | import org.springframework.beans.factory.annotation.Autowired; 10 | import org.springframework.jdbc.core.JdbcTemplate; 11 | import org.springframework.stereotype.Component; 12 | 13 | import javax.annotation.PostConstruct; 14 | import java.io.IOException; 15 | import java.io.InputStream; 16 | import java.nio.charset.Charset; 17 | import java.util.List; 18 | import java.util.Map; 19 | 20 | /** 21 | * @author sss 22 | * @date 2019-02-25 23 | */ 24 | @Slf4j 25 | @Component 26 | public class TemplateHolder { 27 | 28 | private ParseTemplate template; 29 | private final JdbcTemplate jdbcTemplate; 30 | 31 | private String SQL_SCHEMA = "select table_schema, table_name, " + 32 | "column_name, ordinal_position from information_schema.columns " + 33 | "where table_schema = ? and table_name = ?"; 34 | 35 | @Autowired 36 | public TemplateHolder(JdbcTemplate jdbcTemplate) { 37 | this.jdbcTemplate = jdbcTemplate; 38 | } 39 | 40 | @PostConstruct 41 | private void init() { 42 | loadJson("template.json"); 43 | } 44 | 45 | public TableTemplate getTable(String tableName) { 46 | return template.getTableTemplateMap().get(tableName); 47 | } 48 | 49 | private void loadJson(String path) { 50 | 51 | ClassLoader cl = Thread.currentThread().getContextClassLoader(); 52 | InputStream inStream = cl.getResourceAsStream(path); 53 | 54 | try { 55 | Template template = JSON.parseObject( 56 | inStream, 57 | Charset.defaultCharset(), 58 | Template.class 59 | ); 60 | this.template = ParseTemplate.parse(template); 61 | loadMeta(); 62 | } catch (IOException ex) { 63 | log.error(ex.getMessage()); 64 | throw new RuntimeException("fail to parse json file"); 65 | } 66 | } 67 | 68 | private void loadMeta() { 69 | 70 | for (Map.Entry entry : 71 | template.getTableTemplateMap().entrySet()) { 72 | 73 | TableTemplate table = entry.getValue(); 74 | 75 | List updateFields = table.getOpTypeFieldSetMap().get( 76 | OpType.UPDATE 77 | ); 78 | List insertFields = table.getOpTypeFieldSetMap().get( 79 | OpType.ADD 80 | ); 81 | List deleteFields = table.getOpTypeFieldSetMap().get( 82 | OpType.DELETE 83 | ); 84 | 85 | jdbcTemplate.query(SQL_SCHEMA, new Object[]{ 86 | template.getDatabase(), table.getTableName() 87 | }, (rs, i) -> { 88 | 89 | int pos = rs.getInt("ORDINAL_POSITION"); 90 | String colName = rs.getString("COLUMN_NAME"); 91 | 92 | if ((null != updateFields && updateFields.contains(colName)) 93 | || (null != insertFields && insertFields.contains(colName)) 94 | || (null != deleteFields && deleteFields.contains(colName))) { 95 | table.getPosMap().put(pos - 1, colName); 96 | } 97 | 98 | return null; 99 | }); 100 | } 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-sponsor/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | javaedge-ad-service 9 | com.sss.ad 10 | 1.0-SNAPSHOT 11 | 12 | 4.0.0 13 | 14 | 15 | ad-sponsor 16 | 1.0-SNAPSHOT 17 | jar 18 | 19 | 20 | 21 | 22 | 23 | org.springframework.boot 24 | spring-boot-starter-web 25 | 26 | 27 | 31 | 32 | org.springframework.cloud 33 | spring-cloud-starter-netflix-eureka-client 34 | 35 | 36 | 37 | 38 | org.springframework.cloud 39 | spring-cloud-starter-openfeign 40 | 41 | 42 | 43 | 44 | org.springframework.cloud 45 | spring-cloud-starter-netflix-hystrix 46 | 47 | 48 | 49 | 50 | org.springframework.cloud 51 | spring-cloud-starter-netflix-ribbon 52 | 53 | 54 | 55 | 56 | org.springframework.boot 57 | spring-boot-starter-data-jpa 58 | 59 | 60 | 61 | 62 | org.springframework.boot 63 | spring-boot-starter-jdbc 64 | 65 | 66 | 67 | 68 | mysql 69 | mysql-connector-java 70 | 8.0.12 71 | runtime 72 | 73 | 74 | 75 | 76 | com.sss.ad 77 | ad-common 78 | 1.0-SNAPSHOT 79 | 80 | 81 | 82 | 83 | commons-codec 84 | commons-codec 85 | 1.9 86 | 87 | 88 | 89 | 90 | 94 | 95 | 96 | 97 | org.springframework.boot 98 | spring-boot-maven-plugin 99 | 100 | 101 | 102 | 103 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-search/src/main/java/com/javaedge/ad/index/creativeunit/CreativeUnitIndex.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.index.creativeunit; 2 | 3 | import com.javaedge.ad.index.IndexAware; 4 | import com.javaedge.ad.index.adunit.AdUnitObject; 5 | import lombok.extern.slf4j.Slf4j; 6 | import org.apache.commons.collections4.CollectionUtils; 7 | import org.springframework.stereotype.Component; 8 | 9 | import java.util.ArrayList; 10 | import java.util.Collections; 11 | import java.util.List; 12 | import java.util.Map; 13 | import java.util.Set; 14 | import java.util.concurrent.ConcurrentHashMap; 15 | import java.util.concurrent.ConcurrentSkipListSet; 16 | 17 | /** 18 | * 创意与推广单元关联索引 19 | * 20 | * @author sss 21 | * @date 2019-02-12 22 | */ 23 | @Slf4j 24 | @Component 25 | public class CreativeUnitIndex implements IndexAware { 26 | 27 | /** 28 | * 29 | */ 30 | private static Map objectMap; 31 | /** 32 | * 33 | */ 34 | private static Map> creativeUnitMap; 35 | /** 36 | * 37 | */ 38 | private static Map> unitCreativeMap; 39 | 40 | static { 41 | objectMap = new ConcurrentHashMap<>(); 42 | creativeUnitMap = new ConcurrentHashMap<>(); 43 | unitCreativeMap = new ConcurrentHashMap<>(); 44 | } 45 | 46 | @Override 47 | public CreativeUnitObject get(String key) { 48 | return objectMap.get(key); 49 | } 50 | 51 | @Override 52 | public void add(String key, CreativeUnitObject value) { 53 | log.info("before add: {}", objectMap); 54 | 55 | objectMap.put(key, value); 56 | 57 | Set unitSet = creativeUnitMap.get(value.getAdId()); 58 | if (CollectionUtils.isEmpty(unitSet)) { 59 | unitSet = new ConcurrentSkipListSet<>(); 60 | creativeUnitMap.put(value.getAdId(), unitSet); 61 | } 62 | unitSet.add(value.getUnitId()); 63 | 64 | Set creativeSet = unitCreativeMap.get(value.getUnitId()); 65 | if (CollectionUtils.isEmpty(creativeSet)) { 66 | creativeSet = new ConcurrentSkipListSet<>(); 67 | unitCreativeMap.put(value.getUnitId(), creativeSet); 68 | } 69 | creativeSet.add(value.getAdId()); 70 | 71 | log.info("after add: {}", objectMap); 72 | } 73 | 74 | @Override 75 | public void update(String key, CreativeUnitObject value) { 76 | log.error("CreativeUnitIndex not support update"); 77 | } 78 | 79 | @Override 80 | public void delete(String key, CreativeUnitObject value) { 81 | log.info("before delete: {}", objectMap); 82 | 83 | objectMap.remove(key); 84 | 85 | Set unitSet = creativeUnitMap.get(value.getAdId()); 86 | if (CollectionUtils.isNotEmpty(unitSet)) { 87 | unitSet.remove(value.getUnitId()); 88 | } 89 | 90 | Set creativeSet = unitCreativeMap.get(value.getUnitId()); 91 | if (CollectionUtils.isNotEmpty(creativeSet)) { 92 | creativeSet.remove(value.getAdId()); 93 | } 94 | 95 | log.info("after delete: {}", objectMap); 96 | } 97 | 98 | public List selectAds(List unitObjects) { 99 | if (CollectionUtils.isEmpty(unitObjects)) { 100 | return Collections.emptyList(); 101 | } 102 | 103 | List result = new ArrayList<>(); 104 | 105 | for (AdUnitObject unitObject : unitObjects) { 106 | Set adIds = unitCreativeMap.get(unitObject.getUnitId()); 107 | if (CollectionUtils.isNotEmpty(adIds)) { 108 | result.addAll(adIds); 109 | } 110 | } 111 | 112 | return result; 113 | } 114 | } 115 | 116 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-search/src/main/java/com/javaedge/ad/index/district/UnitDistrictIndex.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.index.district; 2 | 3 | import com.javaedge.ad.index.IndexAware; 4 | import com.javaedge.ad.search.vo.feature.DistrictFeature; 5 | import com.javaedge.ad.utils.CommonUtils; 6 | import lombok.extern.slf4j.Slf4j; 7 | import org.apache.commons.collections4.CollectionUtils; 8 | import org.springframework.stereotype.Component; 9 | 10 | import java.util.List; 11 | import java.util.Map; 12 | import java.util.Set; 13 | import java.util.concurrent.ConcurrentHashMap; 14 | import java.util.concurrent.ConcurrentSkipListSet; 15 | import java.util.stream.Collectors; 16 | 17 | /** 18 | * @author sss 19 | * @date 2019-02-12 20 | */ 21 | @Slf4j 22 | @Component 23 | public class UnitDistrictIndex implements IndexAware> { 24 | 25 | private static Map> districtUnitMap; 26 | private static Map> unitDistrictMap; 27 | 28 | static { 29 | districtUnitMap = new ConcurrentHashMap<>(); 30 | unitDistrictMap = new ConcurrentHashMap<>(); 31 | } 32 | 33 | @Override 34 | public Set get(String key) { 35 | return districtUnitMap.get(key); 36 | } 37 | 38 | @Override 39 | public void add(String key, Set value) { 40 | 41 | log.info("UnitDistrictIndex, before add: {}", unitDistrictMap); 42 | 43 | changeADD(key, value, districtUnitMap, unitDistrictMap); 44 | 45 | log.info("UnitDistrictIndex, after add: {}", unitDistrictMap); 46 | } 47 | 48 | public static void changeADD(String key, Set value, Map> districtUnitMap, Map> unitDistrictMap) { 49 | Set unitIds = CommonUtils.getorCreate(key, districtUnitMap, ConcurrentSkipListSet::new); 50 | unitIds.addAll(value); 51 | 52 | for (Long unitId : value) { 53 | Set districts = CommonUtils.getorCreate(unitId, unitDistrictMap, ConcurrentSkipListSet::new); 54 | districts.add(key); 55 | } 56 | } 57 | 58 | @Override 59 | public void update(String key, Set value) { 60 | 61 | log.error("district index can not support update"); 62 | } 63 | 64 | @Override 65 | public void delete(String key, Set value) { 66 | 67 | log.info("UnitDistrictIndex, before delete: {}", unitDistrictMap); 68 | 69 | changeRM(key, value, districtUnitMap, unitDistrictMap); 70 | 71 | log.info("UnitDistrictIndex, after delete: {}", unitDistrictMap); 72 | } 73 | 74 | public static void changeRM(String key, Set value, Map> districtUnitMap, Map> unitDistrictMap) { 75 | Set unitIds = CommonUtils.getorCreate(key, districtUnitMap, ConcurrentSkipListSet::new); 76 | unitIds.removeAll(value); 77 | 78 | for (Long unitId : value) { 79 | Set districts = CommonUtils.getorCreate(unitId, unitDistrictMap, ConcurrentSkipListSet::new); 80 | districts.remove(key); 81 | } 82 | } 83 | 84 | public boolean match(Long adUnitId, List districts) { 85 | 86 | if (unitDistrictMap.containsKey(adUnitId) && 87 | CollectionUtils.isNotEmpty(unitDistrictMap.get(adUnitId))) { 88 | 89 | Set unitDistricts = unitDistrictMap.get(adUnitId); 90 | 91 | List targetDistricts = districts.stream() 92 | .map( 93 | d -> CommonUtils.stringConcat( 94 | d.getProvince(), d.getCity() 95 | ) 96 | ).collect(Collectors.toList()); 97 | 98 | return CollectionUtils.isSubCollection(targetDistricts, unitDistricts); 99 | } 100 | 101 | return false; 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-search/src/main/java/com/javaedge/ad/index/IndexFileLoader.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.index; 2 | 3 | import com.alibaba.fastjson.JSON; 4 | import com.javaedge.ad.dump.DConstant; 5 | import com.javaedge.ad.dump.table.AdCreativeTable; 6 | import com.javaedge.ad.dump.table.AdCreativeUnitTable; 7 | import com.javaedge.ad.dump.table.AdPlanTable; 8 | import com.javaedge.ad.dump.table.AdUnitDistrictTable; 9 | import com.javaedge.ad.dump.table.AdUnitItTable; 10 | import com.javaedge.ad.dump.table.AdUnitKeywordTable; 11 | import com.javaedge.ad.dump.table.AdUnitTable; 12 | import com.javaedge.ad.handler.AdLevelDataHandler; 13 | import com.javaedge.ad.mysql.constant.OpType; 14 | import org.springframework.context.annotation.DependsOn; 15 | import org.springframework.stereotype.Component; 16 | 17 | import javax.annotation.PostConstruct; 18 | import java.io.BufferedReader; 19 | import java.io.IOException; 20 | import java.nio.file.Files; 21 | import java.nio.file.Paths; 22 | import java.util.List; 23 | import java.util.stream.Collectors; 24 | 25 | /** 26 | * @author sss 27 | * @date 2019-02-12 28 | */ 29 | @Component 30 | @DependsOn("dataTable") 31 | public class IndexFileLoader { 32 | 33 | @PostConstruct 34 | public void init() { 35 | 36 | List adPlanStrings = loadDumpData(String.format("%s%s", 37 | DConstant.DATA_ROOT_DIR, 38 | DConstant.AD_PLAN) 39 | ); 40 | 41 | adPlanStrings.forEach(p -> AdLevelDataHandler.handleLevel2( 42 | JSON.parseObject(p, AdPlanTable.class), 43 | OpType.ADD 44 | )); 45 | 46 | List adCreativeStrings = loadDumpData( 47 | String.format("%s%s", 48 | DConstant.DATA_ROOT_DIR, 49 | DConstant.AD_CREATIVE) 50 | ); 51 | adCreativeStrings.forEach(c -> AdLevelDataHandler.handleLevel2( 52 | JSON.parseObject(c, AdCreativeTable.class), 53 | OpType.ADD 54 | )); 55 | 56 | List adUnitStrings = loadDumpData( 57 | String.format("%s%s", 58 | DConstant.DATA_ROOT_DIR, 59 | DConstant.AD_UNIT) 60 | ); 61 | adUnitStrings.forEach(u -> AdLevelDataHandler.handleLevel3( 62 | JSON.parseObject(u, AdUnitTable.class), 63 | OpType.ADD 64 | )); 65 | 66 | List adCreativeUnitStrings = loadDumpData( 67 | String.format("%s%s", 68 | DConstant.DATA_ROOT_DIR, 69 | DConstant.AD_CREATIVE_UNIT) 70 | ); 71 | adCreativeUnitStrings.forEach(cu -> AdLevelDataHandler.handleLevel3( 72 | JSON.parseObject(cu, AdCreativeUnitTable.class), 73 | OpType.ADD 74 | )); 75 | 76 | List adUnitDistrictStrings = loadDumpData( 77 | String.format("%s%s", 78 | DConstant.DATA_ROOT_DIR, 79 | DConstant.AD_UNIT_DISTRICT) 80 | ); 81 | adUnitDistrictStrings.forEach(d -> AdLevelDataHandler.handleLevel4( 82 | JSON.parseObject(d, AdUnitDistrictTable.class), 83 | OpType.ADD 84 | )); 85 | 86 | List adUnitItStrings = loadDumpData( 87 | String.format("%s%s", 88 | DConstant.DATA_ROOT_DIR, 89 | DConstant.AD_UNIT_IT) 90 | ); 91 | adUnitItStrings.forEach(i -> AdLevelDataHandler.handleLevel4( 92 | JSON.parseObject(i, AdUnitItTable.class), 93 | OpType.ADD 94 | )); 95 | 96 | List adUnitKeywordStrings = loadDumpData( 97 | String.format("%s%s", 98 | DConstant.DATA_ROOT_DIR, 99 | DConstant.AD_UNIT_KEYWORD) 100 | ); 101 | adUnitKeywordStrings.forEach(k -> AdLevelDataHandler.handleLevel4( 102 | JSON.parseObject(k, AdUnitKeywordTable.class), 103 | OpType.ADD 104 | )); 105 | } 106 | 107 | private List loadDumpData(String fileName) { 108 | 109 | try (BufferedReader br = Files.newBufferedReader( 110 | Paths.get(fileName) 111 | )) { 112 | return br.lines().collect(Collectors.toList()); 113 | } catch (IOException ex) { 114 | throw new RuntimeException(ex.getMessage()); 115 | } 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-sponsor/src/main/resources/ad-sponsor.sql: -------------------------------------------------------------------------------- 1 | -- javaedge-ad 数据库 2 | drop DATABASE javaedge_ad_data; 3 | CREATE DATABASE javaedge_ad_data character set utf8; 4 | 5 | use javaedge_ad_data; 6 | 7 | -- 用户表 8 | CREATE TABLE `ad_user` ( 9 | `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '自增主键', 10 | `username` varchar(128) NOT NULL DEFAULT '' COMMENT '用户名', 11 | `token` varchar(256) NOT NULL DEFAULT '' COMMENT '给用户生成的 token', 12 | `user_status` tinyint(4) NOT NULL DEFAULT '0' COMMENT '用户状态', 13 | `create_time` datetime NOT NULL DEFAULT '1970-01-01 00:00:00' COMMENT '创建时间', 14 | `update_time` datetime NOT NULL DEFAULT '1970-01-01 00:00:00' COMMENT '更新时间', 15 | PRIMARY KEY (`id`), 16 | UNIQUE KEY `username` (`username`) 17 | ) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8 COMMENT='用户信息表'; 18 | 19 | 20 | -- 推广计划表 21 | CREATE TABLE `ad_plan` ( 22 | `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '自增主键', 23 | `user_id` bigint(20) NOT NULL DEFAULT '0' COMMENT '标记当前记录所属用户', 24 | `plan_name` varchar(48) NOT NULL COMMENT '推广计划名称', 25 | `plan_status` tinyint(4) NOT NULL DEFAULT '0' COMMENT '推广计划状态', 26 | `start_date` datetime NOT NULL COMMENT '推广计划开始时间;', 27 | `end_date` datetime NOT NULL COMMENT '推广计划结束时间;', 28 | `create_time` datetime NOT NULL DEFAULT '1970-01-01 00:00:00' COMMENT '创建时间', 29 | `update_time` datetime NOT NULL DEFAULT '1970-01-01 00:00:00' COMMENT '更新时间', 30 | PRIMARY KEY (`id`) 31 | ) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8 COMMENT='推广计划表'; 32 | 33 | 34 | -- 推广单元表 35 | CREATE TABLE `ad_unit` ( 36 | `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '自增主键', 37 | `plan_id` bigint(20) NOT NULL DEFAULT '0' COMMENT '关联推广计划 id', 38 | `unit_name` varchar(48) NOT NULL COMMENT '推广单元名称', 39 | `unit_status` tinyint(4) NOT NULL DEFAULT '0' COMMENT '推广单元状态', 40 | `position_type` tinyint(4) NOT NULL DEFAULT '0' COMMENT '广告位类型(开屏, 贴片, 中贴, 暂停帖, 后贴)', 41 | `budget` bigint(20) NOT NULL COMMENT '预算', 42 | `create_time` datetime NOT NULL DEFAULT '1970-01-01 00:00:00' COMMENT '创建时间', 43 | `update_time` datetime NOT NULL DEFAULT '1970-01-01 00:00:00' COMMENT '更新时间', 44 | PRIMARY KEY (`id`) 45 | ) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8 COMMENT='推广单元表'; 46 | 47 | 48 | -- 创意表 49 | CREATE TABLE `ad_creative` ( 50 | `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '自增主键', 51 | `name` varchar(48) NOT NULL COMMENT '创意名称', 52 | `type` tinyint(4) NOT NULL DEFAULT '0' COMMENT '物料类型(图片, 视频)', 53 | `material_type` tinyint(4) NOT NULL DEFAULT '0' COMMENT '物料子类型(图片: bmp, jpg 等等)', 54 | `height` int(10) NOT NULL DEFAULT '0' COMMENT '高度', 55 | `width` int(10) NOT NULL DEFAULT '0' COMMENT '宽度', 56 | `size` bigint(20) NOT NULL DEFAULT '0' COMMENT '物料大小, 单位是 KB', 57 | `duration` int(10) NOT NULL DEFAULT '0' COMMENT '持续时长, 只有视频才不为 0', 58 | `audit_status` tinyint(4) NOT NULL DEFAULT '0' COMMENT '审核状态', 59 | `user_id` bigint(20) NOT NULL DEFAULT '0' COMMENT '标记当前记录所属用户', 60 | `url` varchar(256) NOT NULL COMMENT '物料地址', 61 | `create_time` datetime NOT NULL DEFAULT '1970-01-01 00:00:00' COMMENT '创建时间', 62 | `update_time` datetime NOT NULL DEFAULT '1970-01-01 00:00:00' COMMENT '更新时间', 63 | PRIMARY KEY (`id`) 64 | ) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8 COMMENT='创意表'; 65 | 66 | 67 | -- 创意与推广单元的关联表 68 | CREATE TABLE `creative_unit` ( 69 | `id` bigint(20) NOT NULL AUTO_INCREMENT, 70 | `creative_id` bigint(20) NOT NULL DEFAULT '0' COMMENT '创意 id', 71 | `unit_id` bigint(20) NOT NULL DEFAULT '0' COMMENT '推广单元 id', 72 | PRIMARY KEY (`id`) 73 | ) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8 COMMENT='创意和推广单元关联表'; 74 | 75 | 76 | -- 推广单元关键词 Feature 77 | CREATE TABLE `ad_unit_keyword` ( 78 | `id` int(11) NOT NULL AUTO_INCREMENT, 79 | `unit_id` int(11) NOT NULL COMMENT '推广单元 id', 80 | `keyword` varchar(30) NOT NULL COMMENT '关键词', 81 | PRIMARY KEY (`id`) 82 | ) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8 COMMENT='推广单元关键词 Feature'; 83 | 84 | 85 | -- 推广单元兴趣 Feature 86 | CREATE TABLE `ad_unit_it` ( 87 | `id` int(11) NOT NULL AUTO_INCREMENT, 88 | `unit_id` int(11) NOT NULL COMMENT '推广单元 id', 89 | `it_tag` varchar(30) NOT NULL COMMENT '兴趣标签', 90 | PRIMARY KEY (`id`) 91 | ) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8 COMMENT='推广单元兴趣 Feature'; 92 | 93 | 94 | -- 推广单元地域 Feature 95 | CREATE TABLE `ad_unit_district` ( 96 | `id` int(11) NOT NULL AUTO_INCREMENT, 97 | `unit_id` int(11) NOT NULL COMMENT '推广单元 id', 98 | `province` varchar(30) NOT NULL COMMENT '省', 99 | `city` varchar(30) NOT NULL COMMENT '市', 100 | PRIMARY KEY (`id`) 101 | ) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8 COMMENT='推广单元地域 Feature'; 102 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-search/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | javaedge-ad-service 8 | com.sss.ad 9 | 1.0-SNAPSHOT 10 | 11 | 12 | 4.0.0 13 | 14 | 15 | ad-search 16 | 1.0-SNAPSHOT 17 | jar 18 | 19 | 20 | 21 | 22 | org.springframework.cloud 23 | spring-cloud-starter-netflix-hystrix-dashboard 24 | 25 | 26 | 27 | org.springframework.boot 28 | spring-boot-starter-actuator 29 | 30 | 31 | 32 | org.springframework.boot 33 | spring-boot-starter-web 34 | 35 | 39 | 40 | org.springframework.cloud 41 | spring-cloud-starter-netflix-eureka-client 42 | 43 | 44 | 45 | org.springframework.cloud 46 | spring-cloud-starter-openfeign 47 | 48 | 49 | 50 | org.springframework.cloud 51 | spring-cloud-starter-netflix-hystrix 52 | 53 | 54 | 55 | 56 | org.springframework.cloud 57 | spring-cloud-starter-netflix-ribbon 58 | 59 | 60 | 61 | 62 | org.springframework.boot 63 | spring-boot-starter-data-jpa 64 | 65 | 66 | 67 | org.springframework.boot 68 | spring-boot-starter-jdbc 69 | 70 | 71 | 72 | mysql 73 | mysql-connector-java 74 | 5.1.47 75 | runtime 76 | 77 | 78 | 79 | 80 | com.sss.ad 81 | ad-common 82 | 1.0-SNAPSHOT 83 | 84 | 85 | 86 | commons-codec 87 | commons-codec 88 | 1.9 89 | 90 | 91 | 92 | org.apache.commons 93 | commons-collections4 94 | 4.0 95 | 96 | 97 | 98 | 99 | com.github.shyiko 100 | mysql-binlog-connector-java 101 | 0.13.0 102 | 103 | 104 | 105 | org.springframework.boot 106 | spring-boot-configuration-processor 107 | 108 | 109 | 110 | org.springframework.kafka 111 | spring-kafka 112 | 2.1.5.RELEASE 113 | 114 | 115 | 116 | 120 | 121 | 122 | 123 | org.springframework.boot 124 | spring-boot-maven-plugin 125 | 126 | 127 | 128 | 129 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-sponsor/src/main/java/com/javaedge/ad/service/impl/AdPlanServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.service.impl; 2 | 3 | import com.javaedge.ad.constant.CommonStatus; 4 | import com.javaedge.ad.constant.Constants; 5 | import com.javaedge.ad.dao.AdPlanRepository; 6 | import com.javaedge.ad.dao.AdUserRepository; 7 | import com.javaedge.ad.entity.AdPlan; 8 | import com.javaedge.ad.entity.AdUser; 9 | import com.javaedge.ad.exception.AdException; 10 | import com.javaedge.ad.service.IAdPlanService; 11 | import com.javaedge.ad.utils.CommonUtils; 12 | import com.javaedge.ad.vo.AdPlanGetRequest; 13 | import com.javaedge.ad.vo.AdPlanRequest; 14 | import com.javaedge.ad.vo.AdPlanResponse; 15 | import org.springframework.beans.factory.annotation.Autowired; 16 | import org.springframework.stereotype.Service; 17 | import org.springframework.transaction.annotation.Transactional; 18 | 19 | import javax.swing.text.html.Option; 20 | import java.util.Date; 21 | import java.util.List; 22 | import java.util.Optional; 23 | 24 | /** 25 | * @fun 推广计划服务接口 26 | * 27 | * @author sss 28 | * @date 2019/2/6 29 | */ 30 | @Service 31 | public class AdPlanServiceImpl implements IAdPlanService { 32 | 33 | private final AdUserRepository userRepository; 34 | 35 | private final AdPlanRepository planRepository; 36 | 37 | @Autowired 38 | public AdPlanServiceImpl(AdUserRepository userRepository, AdPlanRepository planRepository) { 39 | this.userRepository = userRepository; 40 | this.planRepository = planRepository; 41 | } 42 | 43 | /** 44 | * 创建推广计划 45 | * 46 | * @param request 47 | * @return 48 | * @throws AdException 49 | */ 50 | @Override 51 | @Transactional 52 | public AdPlanResponse createAdPlan(AdPlanRequest request) throws AdException { 53 | if (!request.createValidate()) { 54 | throw new AdException(Constants.ErrorMsg.REQUEST_PARAM_ERROR); 55 | } 56 | 57 | //确保关联的 User 是否存在 58 | Optional adUser = userRepository.findById(request.getUserId()); 59 | 60 | if (!adUser.isPresent()) { 61 | throw new AdException(Constants.ErrorMsg.RECORD_NOT_FOUND); 62 | } 63 | 64 | AdPlan oldPlan = planRepository.findByUserIdaAndPlanName( 65 | request.getUserId(), request.getPlanName() 66 | ); 67 | if (oldPlan != null) { 68 | throw new AdException(Constants.ErrorMsg.SAME_NAME__PLAN_ERROR); 69 | } 70 | AdPlan newAdPlan = planRepository.save( 71 | new AdPlan( 72 | request.getUserId(), 73 | request.getPlanName(), 74 | CommonUtils.parseStringDate(request.getStartDate()), 75 | CommonUtils.parseStringDate(request.getEndDate()) 76 | ) 77 | ); 78 | 79 | return new AdPlanResponse(newAdPlan.getId(), 80 | newAdPlan.getPlanName()); 81 | } 82 | 83 | /** 84 | * 获取推广计划 85 | * 86 | * @param request 87 | * @return 88 | * @throws AdException 89 | */ 90 | @Override 91 | public List getAdPlanByIds(AdPlanGetRequest request) throws AdException { 92 | if (!request.validate()) { 93 | throw new AdException(Constants.ErrorMsg.REQUEST_PARAM_ERROR); 94 | } 95 | 96 | return planRepository.findAllByIdInAnAndUserId( 97 | request.getIds(), request.getUserId() 98 | ); 99 | } 100 | 101 | /** 102 | * 更新推广计划 103 | * 104 | * @param request 105 | * @return 106 | * @throws AdException 107 | */ 108 | @Override 109 | @Transactional 110 | public AdPlanResponse updateAdPlan(AdPlanRequest request) throws AdException { 111 | if (!request.updateValidate()) { 112 | throw new AdException(Constants.ErrorMsg.REQUEST_PARAM_ERROR); 113 | 114 | } 115 | 116 | AdPlan plan = planRepository.findByIdAndUserId( 117 | request.getId(), request.getUserId() 118 | ); 119 | 120 | if (request.getPlanName() != null) { 121 | plan.setPlanName(request.getPlanName()); 122 | } 123 | 124 | if (request.getStartDate() != null) { 125 | plan.setStartDate(CommonUtils.parseStringDate(request.getStartDate())); 126 | } 127 | 128 | if (request.getEndDate() != null) { 129 | plan.setEndDate(CommonUtils.parseStringDate(request.getEndDate())); 130 | } 131 | 132 | plan.setUpdateTime(new Date()); 133 | plan = planRepository.save(plan); 134 | 135 | return new AdPlanResponse(plan.getId(), plan.getPlanName()); 136 | } 137 | /** 138 | * 删除推广计划 139 | * 140 | * @param request 141 | * @throws AdException 142 | */ 143 | @Override 144 | @Transactional 145 | public void deleteAdPlan(AdPlanRequest request) throws AdException { 146 | if (!request.deleteValidate()) { 147 | throw new AdException(Constants.ErrorMsg.REQUEST_PARAM_ERROR); 148 | } 149 | 150 | AdPlan plan = planRepository.findByIdAndUserId(request.getId(), request.getUserId()); 151 | if (plan == null) { 152 | throw new AdException(Constants.ErrorMsg.RECORD_NOT_FOUND); 153 | } 154 | 155 | plan.setPlanStatus(CommonStatus.INVALID.getStatus()); 156 | plan.setUpdateTime(new Date()); 157 | planRepository.save(plan); 158 | 159 | } 160 | 161 | } 162 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-search/src/main/java/com/javaedge/ad/mysql/listener/AggregationListener.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.mysql.listener; 2 | 3 | import com.github.shyiko.mysql.binlog.BinaryLogClient; 4 | import com.github.shyiko.mysql.binlog.event.DeleteRowsEventData; 5 | import com.github.shyiko.mysql.binlog.event.Event; 6 | import com.github.shyiko.mysql.binlog.event.EventData; 7 | import com.github.shyiko.mysql.binlog.event.EventType; 8 | import com.github.shyiko.mysql.binlog.event.TableMapEventData; 9 | import com.github.shyiko.mysql.binlog.event.UpdateRowsEventData; 10 | import com.github.shyiko.mysql.binlog.event.WriteRowsEventData; 11 | import com.javaedge.ad.mysql.TemplateHolder; 12 | import com.javaedge.ad.mysql.dto.BinlogRowData; 13 | import com.javaedge.ad.mysql.dto.TableTemplate; 14 | import lombok.extern.slf4j.Slf4j; 15 | import org.apache.commons.lang.StringUtils; 16 | import org.springframework.beans.factory.annotation.Autowired; 17 | import org.springframework.stereotype.Component; 18 | 19 | import java.io.Serializable; 20 | import java.util.ArrayList; 21 | import java.util.Collections; 22 | import java.util.HashMap; 23 | import java.util.List; 24 | import java.util.Map; 25 | import java.util.stream.Collectors; 26 | 27 | /** 28 | * 监听&解析 Binlog 29 | * 30 | * @author sss 31 | * @date 2019-02-25 32 | */ 33 | @Slf4j 34 | @Component 35 | public class AggregationListener implements BinaryLogClient.EventListener { 36 | 37 | private String dbName; 38 | private String tableName; 39 | 40 | private Map listenerMap = new HashMap<>(); 41 | 42 | private final TemplateHolder templateHolder; 43 | 44 | @Autowired 45 | public AggregationListener(TemplateHolder templateHolder) { 46 | this.templateHolder = templateHolder; 47 | } 48 | 49 | private String genKey(String dbName, String tableName) { 50 | return dbName + ":" + tableName; 51 | } 52 | 53 | public void register(String _dbName, String _tableName, Ilistener ilistener) { 54 | log.info("register : {}-{}", _dbName, _tableName); 55 | this.listenerMap.put(genKey(_dbName, _tableName), ilistener); 56 | } 57 | 58 | @Override 59 | public void onEvent(Event event) { 60 | 61 | EventType type = event.getHeader().getEventType(); 62 | log.debug("event type: {}", type); 63 | 64 | if (type == EventType.TABLE_MAP) { 65 | TableMapEventData data = event.getData(); 66 | this.tableName = data.getTable(); 67 | this.dbName = data.getDatabase(); 68 | return; 69 | } 70 | 71 | if (type != EventType.EXT_UPDATE_ROWS 72 | && type != EventType.EXT_WRITE_ROWS 73 | && type != EventType.EXT_DELETE_ROWS) { 74 | return; 75 | } 76 | 77 | // 表名和库名是否已经完成填充 78 | if (StringUtils.isEmpty(dbName) || StringUtils.isEmpty(tableName)) { 79 | log.error("no meta data event"); 80 | return; 81 | } 82 | 83 | // 找出对应表有兴趣的监听器 84 | String key = genKey(this.dbName, this.tableName); 85 | Ilistener listener = this.listenerMap.get(key); 86 | if (null == listener) { 87 | log.debug("skip {}", key); 88 | return; 89 | } 90 | 91 | log.info("trigger event: {}", type.name()); 92 | 93 | try { 94 | 95 | BinlogRowData rowData = buildRowData(event.getData()); 96 | if (rowData == null) { 97 | return; 98 | } 99 | 100 | rowData.setEventType(type); 101 | listener.onEvent(rowData); 102 | 103 | } catch (Exception ex) { 104 | ex.printStackTrace(); 105 | log.error(ex.getMessage()); 106 | } finally { 107 | this.dbName = ""; 108 | this.tableName = ""; 109 | } 110 | } 111 | 112 | private List getAfterValues(EventData eventData) { 113 | 114 | if (eventData instanceof WriteRowsEventData) { 115 | return ((WriteRowsEventData) eventData).getRows(); 116 | } 117 | 118 | if (eventData instanceof UpdateRowsEventData) { 119 | return ((UpdateRowsEventData) eventData).getRows().stream() 120 | .map(Map.Entry::getValue) 121 | .collect(Collectors.toList()); 122 | } 123 | 124 | if (eventData instanceof DeleteRowsEventData) { 125 | return ((DeleteRowsEventData) eventData).getRows(); 126 | } 127 | 128 | return Collections.emptyList(); 129 | } 130 | 131 | private BinlogRowData buildRowData(EventData eventData) { 132 | 133 | TableTemplate table = templateHolder.getTable(tableName); 134 | 135 | if (null == table) { 136 | log.warn("table {} not found", tableName); 137 | return null; 138 | } 139 | 140 | List> afterMapList = new ArrayList<>(); 141 | 142 | for (Serializable[] after : getAfterValues(eventData)) { 143 | 144 | Map afterMap = new HashMap<>(); 145 | 146 | int colLen = after.length; 147 | 148 | for (int ix = 0; ix < colLen; ++ix) { 149 | 150 | // 取出当前位置对应的列名 151 | String colName = table.getPosMap().get(ix); 152 | 153 | // 如果没有则说明不关心这个列 154 | if (null == colName) { 155 | log.debug("ignore position: {}", ix); 156 | continue; 157 | } 158 | 159 | String colValue = after[ix].toString(); 160 | afterMap.put(colName, colValue); 161 | } 162 | 163 | afterMapList.add(afterMap); 164 | } 165 | 166 | BinlogRowData rowData = new BinlogRowData(); 167 | rowData.setAfter(afterMapList); 168 | rowData.setTable(table); 169 | 170 | return rowData; 171 | } 172 | } 173 | -------------------------------------------------------------------------------- /javaedge-ad-service/ad-sponsor/src/main/java/com/javaedge/ad/service/impl/AdUnitServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.service.impl; 2 | 3 | import com.javaedge.ad.constant.Constants; 4 | import com.javaedge.ad.dao.AdPlanRepository; 5 | import com.javaedge.ad.dao.AdUnitRepository; 6 | import com.javaedge.ad.dao.CreativeRepository; 7 | import com.javaedge.ad.dao.unitcondition.AdUnitDistrictRepository; 8 | import com.javaedge.ad.dao.unitcondition.AdUnitItRepository; 9 | import com.javaedge.ad.dao.unitcondition.AdUnitKeywordRepository; 10 | import com.javaedge.ad.dao.unitcondition.CreativeUnitRepository; 11 | import com.javaedge.ad.entity.AdPlan; 12 | import com.javaedge.ad.entity.unitcondition.*; 13 | import com.javaedge.ad.exception.AdException; 14 | import com.javaedge.ad.service.IAdUnitService; 15 | import com.javaedge.ad.vo.*; 16 | import org.springframework.beans.factory.annotation.Autowired; 17 | import org.springframework.stereotype.Service; 18 | import org.springframework.util.CollectionUtils; 19 | 20 | import java.util.*; 21 | import java.util.stream.Collectors; 22 | 23 | /** 24 | * @author sss 25 | * @fun 推广计划服务接口 26 | * @date 2019/2/6 27 | */ 28 | @Service 29 | public class AdUnitServiceImpl implements IAdUnitService { 30 | 31 | private final AdPlanRepository planRepository; 32 | private final AdUnitRepository unitRepository; 33 | 34 | private final AdUnitKeywordRepository unitKeywordRepository; 35 | private final AdUnitItRepository unitItRepository; 36 | private final AdUnitDistrictRepository unitDistrictRepository; 37 | 38 | private final CreativeRepository creativeRepository; 39 | private final CreativeUnitRepository creativeUnitRepository; 40 | 41 | @Autowired 42 | public AdUnitServiceImpl(AdPlanRepository planRepository, 43 | AdUnitRepository unitRepository, 44 | AdUnitKeywordRepository unitKeywordRepository, 45 | AdUnitItRepository unitItRepository, 46 | AdUnitDistrictRepository unitDistrictRepository, CreativeRepository creativeRepository, CreativeUnitRepository creativeUnitRepository) { 47 | this.planRepository = planRepository; 48 | this.unitRepository = unitRepository; 49 | this.unitKeywordRepository = unitKeywordRepository; 50 | this.unitItRepository = unitItRepository; 51 | this.unitDistrictRepository = unitDistrictRepository; 52 | this.creativeRepository = creativeRepository; 53 | this.creativeUnitRepository = creativeUnitRepository; 54 | } 55 | 56 | @Override 57 | public AdUnitResponse createUnit(AdUnitRequest request) 58 | throws AdException { 59 | 60 | if (!request.createValidate()) { 61 | throw new AdException(Constants.ErrorMsg.REQUEST_PARAM_ERROR); 62 | } 63 | 64 | Optional adPlan = planRepository.findById(request.getPlanId()); 65 | 66 | if (!adPlan.isPresent()) { 67 | throw new AdException(Constants.ErrorMsg.RECORD_NOT_FOUND); 68 | } 69 | 70 | AdUnit oldAdUnit = unitRepository.findByPlanIdAndUnitName(request.getPlanId(), request.getUnitName() 71 | ); 72 | 73 | if (oldAdUnit != null) { 74 | throw new AdException(Constants.ErrorMsg.SAME_NAME_UNIT_ERROR); 75 | } 76 | 77 | AdUnit newAdUnit = unitRepository.save( 78 | new AdUnit(request.getPlanId(), request.getUnitName(), request.getPositionType(), request.getBudget()) 79 | ); 80 | 81 | return new AdUnitResponse(newAdUnit.getId(), 82 | newAdUnit.getUnitName()); 83 | } 84 | 85 | @Override 86 | public AdUnitKeywordResponse createUnitKeyword(AdUnitKeywordRequest request) throws AdException { 87 | 88 | List unitIds = request.getUnitKeywords().stream() 89 | .map(AdUnitKeywordRequest.UnitKeyword::getUnitId) 90 | .collect(Collectors.toList()); 91 | if (!isRelatedUnitExist(unitIds)) { 92 | throw new AdException(Constants.ErrorMsg.REQUEST_PARAM_ERROR); 93 | } 94 | 95 | List ids = Collections.emptyList(); 96 | 97 | List unitKeywords = new ArrayList<>(); 98 | if (!CollectionUtils.isEmpty(request.getUnitKeywords())) { 99 | 100 | request.getUnitKeywords().forEach(i -> unitKeywords.add( 101 | new AdUnitKeyword(i.getUnitId(), i.getKeyword()) 102 | )); 103 | ids = unitKeywordRepository.saveAll(unitKeywords).stream() 104 | .map(AdUnitKeyword::getId) 105 | .collect(Collectors.toList()); 106 | } 107 | 108 | return new AdUnitKeywordResponse(ids); 109 | } 110 | 111 | @Override 112 | public AdUnitItResponse createUnitIt( 113 | AdUnitItRequest request) throws AdException { 114 | 115 | List unitIds = request.getUnitIts().stream() 116 | .map(AdUnitItRequest.UnitIt::getUnitId) 117 | .collect(Collectors.toList()); 118 | if (!isRelatedUnitExist(unitIds)) { 119 | throw new AdException(Constants.ErrorMsg.REQUEST_PARAM_ERROR); 120 | } 121 | 122 | List unitIts = new ArrayList<>(); 123 | request.getUnitIts().forEach(i -> unitIts.add( 124 | new AdUnitIt(i.getUnitId(), i.getItTag()) 125 | )); 126 | List ids = unitItRepository.saveAll(unitIts).stream() 127 | .map(AdUnitIt::getId) 128 | .collect(Collectors.toList()); 129 | 130 | return new AdUnitItResponse(ids); 131 | } 132 | 133 | @Override 134 | public AdUnitDistrictResponse createUnitDistrict(AdUnitDistrictRequest request) throws AdException { 135 | List unitIds = request.getUnitDistricts().stream() 136 | .map(AdUnitDistrictRequest.UnitDistrict::getUnitId) 137 | .collect(Collectors.toList()); 138 | if (!isRelatedUnitExist(unitIds)) { 139 | throw new AdException(Constants.ErrorMsg.REQUEST_PARAM_ERROR); 140 | } 141 | 142 | List unitDistricts = new ArrayList<>(); 143 | request.getUnitDistricts().forEach(d -> unitDistricts.add( 144 | new AdUnitDistrict(d.getUnitId(), d.getProvince(), 145 | d.getCity()) 146 | )); 147 | List ids = unitDistrictRepository.saveAll(unitDistricts) 148 | .stream().map(AdUnitDistrict::getId) 149 | .collect(Collectors.toList()); 150 | 151 | return new AdUnitDistrictResponse(ids); 152 | } 153 | 154 | private boolean isRelatedUnitExist(List unitIds) { 155 | 156 | if (CollectionUtils.isEmpty(unitIds)) { 157 | return false; 158 | } 159 | 160 | return unitRepository.findAllById(unitIds).size() == new HashSet<>(unitIds).size(); 161 | } 162 | 163 | @Override 164 | public CreativeUnitResponse createCreativeUnit(CreativeUnitRequest request) throws AdException { 165 | 166 | List unitIds = request.getUnitItems().stream() 167 | .map(CreativeUnitRequest.CreativeUnitItem::getUnitId) 168 | .collect(Collectors.toList()); 169 | List creativeIds = request.getUnitItems().stream() 170 | .map(CreativeUnitRequest.CreativeUnitItem::getCreativeId) 171 | .collect(Collectors.toList()); 172 | 173 | if (!(isRelatedUnitExist(unitIds) && isRelatedUnitExist(creativeIds))) { 174 | throw new AdException(Constants.ErrorMsg.REQUEST_PARAM_ERROR); 175 | } 176 | 177 | List creativeUnits = new ArrayList<>(); 178 | request.getUnitItems().forEach(i -> creativeUnits.add( 179 | new CreativeUnit(i.getCreativeId(), i.getUnitId()) 180 | )); 181 | 182 | List ids = creativeUnitRepository.saveAll(creativeUnits) 183 | .stream() 184 | .map(CreativeUnit::getId) 185 | .collect(Collectors.toList()); 186 | 187 | return new CreativeUnitResponse(ids); 188 | } 189 | 190 | private boolean isRelatedCreativeExist(List creativeIds) { 191 | 192 | if (CollectionUtils.isEmpty(creativeIds)) { 193 | return false; 194 | } 195 | 196 | return creativeRepository.findAllById(creativeIds).size() == 197 | new HashSet<>(creativeIds).size(); 198 | } 199 | } -------------------------------------------------------------------------------- /javaedge-ad-service/ad-search/src/main/java/com/javaedge/ad/handler/AdLevelDataHandler.java: -------------------------------------------------------------------------------- 1 | package com.javaedge.ad.handler; 2 | 3 | import com.alibaba.fastjson.JSON; 4 | import com.javaedge.ad.dump.table.AdCreativeTable; 5 | import com.javaedge.ad.dump.table.AdCreativeUnitTable; 6 | import com.javaedge.ad.dump.table.AdPlanTable; 7 | import com.javaedge.ad.dump.table.AdUnitDistrictTable; 8 | import com.javaedge.ad.dump.table.AdUnitItTable; 9 | import com.javaedge.ad.dump.table.AdUnitKeywordTable; 10 | import com.javaedge.ad.dump.table.AdUnitTable; 11 | import com.javaedge.ad.index.DataTable; 12 | import com.javaedge.ad.index.IndexAware; 13 | import com.javaedge.ad.index.adplan.AdPlanIndex; 14 | import com.javaedge.ad.index.adplan.AdPlanObject; 15 | import com.javaedge.ad.index.adunit.AdUnitIndex; 16 | import com.javaedge.ad.index.adunit.AdUnitObject; 17 | import com.javaedge.ad.index.creative.CreativeIndex; 18 | import com.javaedge.ad.index.creative.CreativeObject; 19 | import com.javaedge.ad.index.creativeunit.CreativeUnitIndex; 20 | import com.javaedge.ad.index.creativeunit.CreativeUnitObject; 21 | import com.javaedge.ad.index.district.UnitDistrictIndex; 22 | import com.javaedge.ad.index.interest.UnitItIndex; 23 | import com.javaedge.ad.index.keyword.UnitKeywordIndex; 24 | import com.javaedge.ad.mysql.constant.OpType; 25 | import com.javaedge.ad.utils.CommonUtils; 26 | import lombok.extern.slf4j.Slf4j; 27 | 28 | import java.util.Collections; 29 | import java.util.HashSet; 30 | import java.util.Set; 31 | /** 32 | * 1. 索引之间存在着层级的划分, 也就是依赖关系的划分 33 | * 2. 加载全量索引其实是增量索引 "添加" 的一种特殊实现 34 | * @author sss 35 | * @date 2019-02-12 36 | */ 37 | @Slf4j 38 | public class AdLevelDataHandler { 39 | 40 | public static void handleLevel2(AdPlanTable planTable, OpType type) { 41 | 42 | AdPlanObject planObject = new AdPlanObject( 43 | planTable.getId(), 44 | planTable.getUserId(), 45 | planTable.getPlanStatus(), 46 | planTable.getStartDate(), 47 | planTable.getEndDate() 48 | ); 49 | handleBinlogEvent( 50 | DataTable.of(AdPlanIndex.class), 51 | planObject.getPlanId(), 52 | planObject, 53 | type 54 | ); 55 | } 56 | 57 | public static void handleLevel2(AdCreativeTable creativeTable, OpType type) { 58 | 59 | CreativeObject creativeObject = new CreativeObject( 60 | creativeTable.getAdId(), 61 | creativeTable.getName(), 62 | creativeTable.getType(), 63 | creativeTable.getMaterialType(), 64 | creativeTable.getHeight(), 65 | creativeTable.getWidth(), 66 | creativeTable.getAuditStatus(), 67 | creativeTable.getAdUrl() 68 | ); 69 | handleBinlogEvent( 70 | DataTable.of(CreativeIndex.class), 71 | creativeObject.getAdId(), 72 | creativeObject, 73 | type 74 | ); 75 | } 76 | 77 | public static void handleLevel3(AdUnitTable unitTable, OpType type) { 78 | 79 | AdPlanObject adPlanObject = DataTable.of( 80 | AdPlanIndex.class 81 | ).get(unitTable.getPlanId()); 82 | if (null == adPlanObject) { 83 | log.error("handleLevel3 found AdPlanObject error: {}", 84 | unitTable.getPlanId()); 85 | return; 86 | } 87 | 88 | AdUnitObject unitObject = new AdUnitObject( 89 | unitTable.getUnitId(), 90 | unitTable.getUnitStatus(), 91 | unitTable.getPositionType(), 92 | unitTable.getPlanId(), 93 | adPlanObject 94 | ); 95 | 96 | handleBinlogEvent( 97 | DataTable.of(AdUnitIndex.class), 98 | unitTable.getUnitId(), 99 | unitObject, 100 | type 101 | ); 102 | } 103 | 104 | public static void handleLevel3(AdCreativeUnitTable creativeUnitTable, 105 | OpType type) { 106 | 107 | if (type == OpType.UPDATE) { 108 | log.error("CreativeUnitIndex not support update"); 109 | return; 110 | } 111 | 112 | AdUnitObject unitObject = DataTable.of( 113 | AdUnitIndex.class 114 | ).get(creativeUnitTable.getUnitId()); 115 | CreativeObject creativeObject = DataTable.of( 116 | CreativeIndex.class 117 | ).get(creativeUnitTable.getAdId()); 118 | 119 | if (null == unitObject || null == creativeObject) { 120 | log.error("AdCreativeUnitTable index error: {}", 121 | JSON.toJSONString(creativeUnitTable)); 122 | return; 123 | } 124 | 125 | CreativeUnitObject creativeUnitObject = new CreativeUnitObject( 126 | creativeUnitTable.getAdId(), 127 | creativeUnitTable.getUnitId() 128 | ); 129 | handleBinlogEvent( 130 | DataTable.of(CreativeUnitIndex.class), 131 | CommonUtils.stringConcat( 132 | creativeUnitObject.getAdId().toString(), 133 | creativeUnitObject.getUnitId().toString() 134 | ), 135 | creativeUnitObject, 136 | type 137 | ); 138 | } 139 | 140 | public static void handleLevel4(AdUnitDistrictTable unitDistrictTable, 141 | OpType type) { 142 | 143 | if (type == OpType.UPDATE) { 144 | log.error("district index can not support update"); 145 | return; 146 | } 147 | 148 | AdUnitObject unitObject = DataTable.of( 149 | AdUnitIndex.class 150 | ).get(unitDistrictTable.getUnitId()); 151 | if (unitObject == null) { 152 | log.error("AdUnitDistrictTable index error: {}", 153 | unitDistrictTable.getUnitId()); 154 | return; 155 | } 156 | 157 | String key = CommonUtils.stringConcat( 158 | unitDistrictTable.getProvince(), 159 | unitDistrictTable.getCity() 160 | ); 161 | Set value = new HashSet<>( 162 | Collections.singleton(unitDistrictTable.getUnitId()) 163 | ); 164 | handleBinlogEvent( 165 | DataTable.of(UnitDistrictIndex.class), 166 | key, value, 167 | type 168 | ); 169 | } 170 | 171 | public static void handleLevel4(AdUnitItTable unitItTable, OpType type) { 172 | 173 | if (type == OpType.UPDATE) { 174 | log.error("it index can not support update"); 175 | return; 176 | } 177 | 178 | AdUnitObject unitObject = DataTable.of( 179 | AdUnitIndex.class 180 | ).get(unitItTable.getUnitId()); 181 | if (unitObject == null) { 182 | log.error("AdUnitItTable index error: {}", 183 | unitItTable.getUnitId()); 184 | return; 185 | } 186 | 187 | Set value = new HashSet<>( 188 | Collections.singleton(unitItTable.getUnitId()) 189 | ); 190 | handleBinlogEvent( 191 | DataTable.of(UnitItIndex.class), 192 | unitItTable.getItTag(), 193 | value, 194 | type 195 | ); 196 | } 197 | 198 | public static void handleLevel4(AdUnitKeywordTable keywordTable, 199 | OpType type) { 200 | 201 | if (type == OpType.UPDATE) { 202 | log.error("keyword index can not support update"); 203 | return; 204 | } 205 | 206 | AdUnitObject unitObject = DataTable.of( 207 | AdUnitIndex.class 208 | ).get(keywordTable.getUnitId()); 209 | if (unitObject == null) { 210 | log.error("AdUnitKeywordTable index error: {}", 211 | keywordTable.getUnitId()); 212 | return; 213 | } 214 | 215 | Set value = new HashSet<>( 216 | Collections.singleton(keywordTable.getUnitId()) 217 | ); 218 | handleBinlogEvent( 219 | DataTable.of(UnitKeywordIndex.class), 220 | keywordTable.getKeyword(), 221 | value, 222 | type 223 | ); 224 | } 225 | 226 | private static void handleBinlogEvent( 227 | IndexAware index, 228 | K key, 229 | V value, 230 | OpType type) { 231 | 232 | switch (type) { 233 | case ADD: 234 | index.add(key, value); 235 | break; 236 | case UPDATE: 237 | index.update(key, value); 238 | break; 239 | case DELETE: 240 | index.delete(key, value); 241 | break; 242 | default: 243 | break; 244 | } 245 | } 246 | } 247 | --------------------------------------------------------------------------------