├── .classpath ├── .gitignore ├── .project ├── README.md ├── challengesWeb ├── .classpath ├── .project ├── .springBeans ├── pom.xml └── src │ └── main │ ├── java │ └── com │ │ └── hitesh │ │ └── boot │ │ └── challenges │ │ ├── ChallengesApplication.java │ │ ├── controller │ │ └── ChallengesController.java │ │ ├── entity │ │ └── Challenges.java │ │ ├── repositories │ │ └── ChallengesRepository.java │ │ └── swagger │ │ └── SwaggerConfig.java │ └── resources │ ├── bootstrap.yml │ ├── challenges-server.yml │ ├── data.sql │ └── schema.sql ├── heroClient ├── .angular-cli.json ├── .classpath ├── .editorconfig ├── .project ├── .vscode │ └── launch.json ├── README.md ├── e2e │ ├── app.e2e-spec.ts │ ├── app.po.ts │ └── tsconfig.e2e.json ├── karma.conf.js ├── package.json ├── pom.xml ├── protractor.conf.js ├── src │ ├── app │ │ ├── app-routing │ │ │ └── app-routing.module.ts │ │ ├── app.component.css │ │ ├── app.component.html │ │ ├── app.component.spec.ts │ │ ├── app.component.ts │ │ ├── app.module.ts │ │ ├── auth.guard.spec.ts │ │ ├── auth.guard.ts │ │ ├── dashboard │ │ │ ├── dashboard.component.css │ │ │ ├── dashboard.component.html │ │ │ ├── dashboard.component.spec.ts │ │ │ └── dashboard.component.ts │ │ ├── hero-detail │ │ │ ├── hero-detail.component.css │ │ │ ├── hero-detail.component.html │ │ │ ├── hero-detail.component.spec.ts │ │ │ └── hero-detail.component.ts │ │ ├── heroes │ │ │ ├── heroes.component.css │ │ │ ├── heroes.component.html │ │ │ ├── heroes.component.spec.ts │ │ │ └── heroes.component.ts │ │ ├── models │ │ │ ├── hero.ts │ │ │ └── tweet.ts │ │ ├── services │ │ │ ├── auth.service.spec.ts │ │ │ ├── auth.service.ts │ │ │ ├── hero.service.ts │ │ │ ├── tweet.service.spec.ts │ │ │ └── tweet.service.ts │ │ ├── signup │ │ │ ├── signup.component.css │ │ │ ├── signup.component.html │ │ │ ├── signup.component.spec.ts │ │ │ └── signup.component.ts │ │ ├── udemy │ │ │ ├── authors │ │ │ │ ├── authors.component.css │ │ │ │ ├── authors.component.html │ │ │ │ ├── authors.component.spec.ts │ │ │ │ └── authors.component.ts │ │ │ ├── auto-grow.directive.spec.ts │ │ │ ├── auto-grow.directive.ts │ │ │ ├── change-password │ │ │ │ ├── change-password.component.css │ │ │ │ ├── change-password.component.html │ │ │ │ ├── change-password.component.spec.ts │ │ │ │ └── change-password.component.ts │ │ │ ├── contact-form │ │ │ │ ├── contact-form.component.css │ │ │ │ ├── contact-form.component.html │ │ │ │ ├── contact-form.component.spec.ts │ │ │ │ └── contact-form.component.ts │ │ │ ├── courses │ │ │ │ ├── courses.component.css │ │ │ │ ├── courses.component.html │ │ │ │ ├── courses.component.spec.ts │ │ │ │ └── courses.component.ts │ │ │ ├── github-profile │ │ │ │ ├── github-profile.component.css │ │ │ │ ├── github-profile.component.html │ │ │ │ ├── github-profile.component.spec.ts │ │ │ │ └── github-profile.component.ts │ │ │ ├── models │ │ │ │ ├── author.ts │ │ │ │ ├── course.ts │ │ │ │ └── githubprofile.ts │ │ │ ├── services │ │ │ │ ├── auth.service.spec.ts │ │ │ │ ├── auth.service.ts │ │ │ │ ├── author.service.ts │ │ │ │ ├── course.service.ts │ │ │ │ ├── github.service.spec.ts │ │ │ │ ├── github.service.ts │ │ │ │ ├── prevent-unsaved-changes.guard.spec.ts │ │ │ │ ├── prevent-unsaved-changes.guard.ts │ │ │ │ ├── spotify.service.spec.ts │ │ │ │ └── spotify.service.ts │ │ │ ├── spotify │ │ │ │ ├── spotify.component.css │ │ │ │ ├── spotify.component.html │ │ │ │ ├── spotify.component.spec.ts │ │ │ │ └── spotify.component.ts │ │ │ ├── udemy.module.ts │ │ │ └── udemy.routing.ts │ │ ├── util │ │ │ ├── bs-panels │ │ │ │ ├── bs-panels.component.css │ │ │ │ ├── bs-panels.component.html │ │ │ │ └── bs-panels.component.ts │ │ │ ├── favorite │ │ │ │ ├── favorite.component.css │ │ │ │ ├── favorite.component.html │ │ │ │ ├── favorite.component.spec.ts │ │ │ │ └── favorite.component.ts │ │ │ ├── heart │ │ │ │ ├── heart.component.css │ │ │ │ ├── heart.component.html │ │ │ │ ├── heart.component.spec.ts │ │ │ │ └── heart.component.ts │ │ │ ├── summarize.pipe.spec.ts │ │ │ ├── summarize.pipe.ts │ │ │ ├── tweets │ │ │ │ ├── tweets.component.css │ │ │ │ ├── tweets.component.html │ │ │ │ ├── tweets.component.spec.ts │ │ │ │ └── tweets.component.ts │ │ │ ├── util.module.ts │ │ │ ├── vote │ │ │ │ ├── vote.component.css │ │ │ │ ├── vote.component.html │ │ │ │ ├── vote.component.spec.ts │ │ │ │ └── vote.component.ts │ │ │ └── zippy │ │ │ │ ├── zippy.component.css │ │ │ │ ├── zippy.component.html │ │ │ │ ├── zippy.component.spec.ts │ │ │ │ └── zippy.component.ts │ │ └── validators │ │ │ ├── PasswordValidator.ts │ │ │ └── UserNameValidator.ts │ ├── assets │ │ └── .gitkeep │ ├── environments │ │ ├── environment.prod.ts │ │ └── environment.ts │ ├── favicon.ico │ ├── index.html │ ├── main.ts │ ├── polyfills.ts │ ├── styles.css │ ├── test.ts │ ├── tsconfig.app.json │ ├── tsconfig.spec.json │ └── typings.d.ts ├── tsconfig.json └── tslint.json ├── heroWeb ├── .gitignore ├── mvnw ├── mvnw.cmd ├── pom.xml └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── hitesh │ │ │ └── boot │ │ │ └── heroes │ │ │ ├── HeroesApplication.java │ │ │ ├── data │ │ │ ├── entity │ │ │ │ ├── Challenge.java │ │ │ │ ├── Guest.java │ │ │ │ ├── Hero.java │ │ │ │ ├── Reservation.java │ │ │ │ └── Room.java │ │ │ └── repository │ │ │ │ ├── GuestRepository.java │ │ │ │ ├── HeroRepository.java │ │ │ │ ├── ReservationRepository.java │ │ │ │ └── RoomRepository.java │ │ │ ├── facade │ │ │ └── IAuthenticationFacade.java │ │ │ ├── security │ │ │ ├── AppInfoContributor.java │ │ │ ├── AuthenticationFacade.java │ │ │ └── SecurityConfiguration.java │ │ │ ├── service │ │ │ ├── HeroChallengeService.java │ │ │ └── ReservationService.java │ │ │ ├── swagger │ │ │ └── SwaggerConfig.java │ │ │ └── webservice │ │ │ ├── AuthController.java │ │ │ ├── DownloadPDFController.java │ │ │ ├── HeroController.java │ │ │ └── RoomController.java │ └── resources │ │ ├── bootstrap.yml │ │ ├── data.sql │ │ ├── heroes-server.yml │ │ ├── schema.sql │ │ ├── static │ │ ├── hello_world_app.component.ts │ │ ├── hello_world_main.ts │ │ └── index.html │ │ └── test.pdf │ └── test │ └── java │ └── com │ └── hitesh │ └── boot │ └── reservations │ └── ReservationsApplicationTests.java ├── pom.xml ├── serviceRegistration ├── .classpath ├── .project ├── pom.xml └── src │ └── main │ ├── java │ └── serviceRegistration │ │ └── RegistrationServer.java │ └── resources │ └── registration-server.yml └── zuulGateway ├── pom.xml └── src └── main ├── java └── com │ └── hitesh │ ├── filters │ └── SimpleFilter.java │ └── zuulGateway │ └── GatewayApplication.java └── resources └── bootstrap.yml /.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | */node_modules/* 2 | jspm_packages 3 | npm-debug.log 4 | debug.log 5 | */dist/* 6 | */node/* 7 | */target/* 8 | */.settings/* 9 | .settings 10 | */.mvn/* 11 | .classpath 12 | .project -------------------------------------------------------------------------------- /.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | heroes 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.wst.common.project.facet.core.builder 10 | 11 | 12 | 13 | 14 | org.eclipse.jdt.core.javabuilder 15 | 16 | 17 | 18 | 19 | org.eclipse.m2e.core.maven2Builder 20 | 21 | 22 | 23 | 24 | org.springframework.ide.eclipse.core.springbuilder 25 | 26 | 27 | 28 | 29 | 30 | org.springframework.ide.eclipse.core.springnature 31 | org.eclipse.jdt.core.javanature 32 | org.eclipse.m2e.core.maven2Nature 33 | org.eclipse.wst.common.project.facet.core.nature 34 | 35 | 36 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

Spring Boot - Microservices - Netflix Eureka Server and client, Swagger, ZuulProxy

2 | 8 | 9 | 10 |

Learning objectives : Achieved -

11 | 19 | 20 |

Learning Objectives Pending -

21 | 27 | 28 | 29 | 30 | ![Basic Architecture Diagram](https://github.com/hiteshjoshi1/spring-boot-angular2/blob/images/Capture.PNG) 31 | 32 | 33 | --------------------------------------------------------------------------------------- 34 | 35 | Child Web Project has a dependency on the Client Project and by default opens it index.html. 36 | 37 | It uses https://github.com/eirslett/frontend-maven-plugin to download Node,NPM,install , 38 | and run the front end build lifecycle. 39 | 40 | Uses In memory DB for Data persistence. 41 | Has the complete Heroes App , official starter tutorial for Angular2 implemented. 42 | 43 | 44 | ---------------------------------------------------------------------------------------- 45 | 46 | Packaging --- 47 | mvn clean package 48 | 49 | 50 |

Start individual applications -

51 | 52 | Starting the Eureka Server 53 | java -jar serviceRegistration/target/serviceRegistration-0.0.1-SNAPSHOT.war 54 | 55 | 56 | Eureka Endpoint - 57 | http://localhost:1111/ 58 | 59 | Start the individual micro applications 60 | 61 | java -jar challengesWeb/target/challengesWeb-0.0.1-SNAPSHOT.war 62 | 63 | http://localhost:2222/ 64 | 65 | 66 | Start the same application in the same JVM different port 67 | Example - 68 | ava -jar target/app.jar --server.port=3331 69 | 70 | Basically to override any spring boot properties use -- followed by Spring boot property name seprate with . 71 | 72 | java -jar challengesWeb/target/challengesWeb-0.0.1-SNAPSHOT.war --server.port=3331 73 | 74 | Your Microservice should be up at 75 | http://localhost:3331/api/challenges 76 | 77 | 78 | 79 | Starting the Heroes Application 80 | 81 | java -jar heroWeb/target/heroesWeb-0.0.1-SNAPSHOT.war 82 | 83 | Your other microservice should be up at 84 | http://localhost:2222/heroes 85 | 86 | 87 | Replicated Heroes Micro Application 88 | 89 | java -jar heroWeb/target/heroesWeb-0.0.1-SNAPSHOT.war --server.port=2223 90 | 91 | Replicate Microservice should be up at 92 | http://localhost:2223/heroes 93 | 94 | 95 | Starting the zuul Proxy 96 | 97 | java -jar zuulGateway/target/zuulGateway-0.0.1-SNAPSHOT.jar 98 | 99 | Deployed at port 5555 100 | 101 | You should be able to access your API using the Zuul gateway 102 | 103 | Heroes API via proxy - [Secure end point- basic security , User Name - user. Password - password ] 104 | http://localhost:5555/heroes-service/heroes 105 | 106 | Challenges API via proxy - 107 | http://localhost:5555/challenges-service/api/challenges 108 | 109 | Swagger Documentation- 110 | http://localhost:2222/swagger-ui.html#/ 111 | 112 | http://localhost:3333/swagger-ui.html#/ 113 | -------------------------------------------------------------------------------- /challengesWeb/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /challengesWeb/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | challengesWeb 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.wst.common.project.facet.core.builder 10 | 11 | 12 | 13 | 14 | org.eclipse.jdt.core.javabuilder 15 | 16 | 17 | 18 | 19 | org.springframework.ide.eclipse.core.springbuilder 20 | 21 | 22 | 23 | 24 | org.eclipse.wst.validation.validationbuilder 25 | 26 | 27 | 28 | 29 | org.eclipse.m2e.core.maven2Builder 30 | 31 | 32 | 33 | 34 | 35 | org.eclipse.jem.workbench.JavaEMFNature 36 | org.eclipse.wst.common.modulecore.ModuleCoreNature 37 | org.springframework.ide.eclipse.core.springnature 38 | org.eclipse.jdt.core.javanature 39 | org.eclipse.m2e.core.maven2Nature 40 | org.eclipse.wst.common.project.facet.core.nature 41 | org.eclipse.wst.jsdt.core.jsNature 42 | 43 | 44 | -------------------------------------------------------------------------------- /challengesWeb/.springBeans: -------------------------------------------------------------------------------- 1 | 2 | 3 | 1 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | java:com.hitesh.boot.challenges.ChallengesApplication 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /challengesWeb/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | challengesWeb 7 | war 8 | 9 | Challenges WebApp 10 | Demo project for Spring Boot 11 | 12 | 13 | 14 | com.hitesh.boot 15 | heroes 16 | ${project.version} 17 | 18 | 19 | 20 | 21 | 22 | 27 | 28 | org.springframework.boot 29 | spring-boot-starter-actuator 30 | 31 | 32 | org.springframework.boot 33 | spring-boot-starter-data-jpa 34 | 35 | 36 | 37 | org.springframework.boot 38 | spring-boot-starter-web 39 | 40 | 41 | 42 | com.h2database 43 | h2 44 | runtime 45 | 46 | 47 | org.springframework.boot 48 | spring-boot-starter-test 49 | test 50 | 51 | 52 | com.thoughtworks.xstream 53 | xstream 54 | 1.4.9 55 | 56 | 60 | 61 | 62 | org.springframework.cloud 63 | spring-cloud-starter-eureka 64 | 65 | 66 | io.springfox 67 | springfox-swagger2 68 | 2.6.0 69 | compile 70 | 71 | 72 | io.springfox 73 | springfox-swagger-ui 74 | 2.6.1 75 | compile 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | org.springframework.boot 84 | spring-boot-maven-plugin 85 | 86 | 87 | 88 | 89 | 90 | 91 | -------------------------------------------------------------------------------- /challengesWeb/src/main/java/com/hitesh/boot/challenges/ChallengesApplication.java: -------------------------------------------------------------------------------- 1 | package com.hitesh.boot.challenges; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.boot.autoconfigure.web.HttpMessageConverters; 6 | import org.springframework.boot.web.support.SpringBootServletInitializer; 7 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient; 8 | import org.springframework.context.annotation.Bean; 9 | import org.springframework.data.jpa.repository.config.EnableJpaRepositories; 10 | import org.springframework.http.converter.ByteArrayHttpMessageConverter; 11 | 12 | 13 | /** 14 | * @author hitjoshi 15 | * 16 | */ 17 | @SpringBootApplication(scanBasePackages={"com.hitesh.boot.challenges.*"}) 18 | @EnableJpaRepositories(basePackages = "com.hitesh.boot.challenges.repositories") 19 | @EnableDiscoveryClient 20 | public class ChallengesApplication extends SpringBootServletInitializer { 21 | 22 | public static void main(String[] args) { 23 | System.setProperty("spring.config.name", "challenges-server"); 24 | SpringApplication.run(ChallengesApplication.class, args); 25 | } 26 | @Bean 27 | public HttpMessageConverters customConverters() { 28 | ByteArrayHttpMessageConverter arrayHttpMessageConverter = new ByteArrayHttpMessageConverter(); 29 | return new HttpMessageConverters(arrayHttpMessageConverter); 30 | } 31 | 32 | 33 | } 34 | -------------------------------------------------------------------------------- /challengesWeb/src/main/java/com/hitesh/boot/challenges/controller/ChallengesController.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.hitesh.boot.challenges.controller; 5 | 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | 9 | import org.springframework.beans.factory.annotation.Autowired; 10 | import org.springframework.web.bind.annotation.PathVariable; 11 | import org.springframework.web.bind.annotation.RequestMapping; 12 | import org.springframework.web.bind.annotation.RequestMethod; 13 | import org.springframework.web.bind.annotation.RestController; 14 | 15 | import com.hitesh.boot.challenges.entity.Challenges; 16 | import com.hitesh.boot.challenges.repositories.ChallengesRepository; 17 | 18 | 19 | 20 | 21 | /** 22 | * @author hitjoshi 23 | * change in convention 24 | * 25 | */ 26 | @RestController 27 | @RequestMapping(value="/api") 28 | public class ChallengesController { 29 | 30 | @Autowired 31 | private ChallengesRepository challengesRepository; 32 | 33 | 34 | @RequestMapping(value="/challenges", method= RequestMethod.GET) 35 | public List getAllChallenges(){ 36 | List challenges = new ArrayList(); 37 | Iterable results = this.challengesRepository.findAll(); 38 | results.forEach(challenge-> {challenges.add(challenge);}); 39 | return challenges; 40 | } 41 | 42 | /** 43 | * Get All Challenges at a challenge level 44 | * @param challengeLevel 45 | * @return 46 | */ 47 | @RequestMapping(value="/challenges/{challengeLevel}", method= RequestMethod.GET) 48 | public List getChallengeBySeverity(@PathVariable("challengeLevel") String challengeLevel){ 49 | List challengeList = this.challengesRepository.findByChallengeLevel(Integer.parseInt(challengeLevel)); 50 | return challengeList; 51 | } 52 | 53 | 54 | } 55 | -------------------------------------------------------------------------------- /challengesWeb/src/main/java/com/hitesh/boot/challenges/entity/Challenges.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.hitesh.boot.challenges.entity; 5 | 6 | import java.io.Serializable; 7 | 8 | import javax.persistence.Column; 9 | import javax.persistence.Entity; 10 | import javax.persistence.GeneratedValue; 11 | import javax.persistence.GenerationType; 12 | import javax.persistence.Id; 13 | import javax.persistence.Table; 14 | 15 | /** 16 | * @author hitjoshi 17 | * 18 | */ 19 | 20 | @Entity 21 | @Table(name = "CHALLENGES") 22 | public class Challenges implements Serializable { 23 | 24 | /** 25 | * 26 | */ 27 | private static final long serialVersionUID = -2641209952095853668L; 28 | 29 | @Id 30 | @Column(name = "CHALLENGES_ID") 31 | @GeneratedValue(strategy = GenerationType.AUTO) 32 | private long challengesId; 33 | 34 | @Column(name = "CHALLENGE_NAME") 35 | private String challengeName; 36 | 37 | @Column(name = "CHALLENGE_LEVEL") 38 | private int challengeLevel; 39 | 40 | @Column(name = "MAX_HEROES") 41 | private int maxNumOfHeroes; 42 | 43 | /** 44 | * @return the challengesId 45 | */ 46 | public long getChallengesId() { 47 | return challengesId; 48 | } 49 | 50 | /** 51 | * @param challengesId the challengesId to set 52 | */ 53 | public void setChallengesId(long challengesId) { 54 | this.challengesId = challengesId; 55 | } 56 | 57 | /** 58 | * @return the challengeName 59 | */ 60 | public String getChallengeName() { 61 | return challengeName; 62 | } 63 | 64 | /** 65 | * @param challengeName the challengeName to set 66 | */ 67 | public void setChallengeName(String challengeName) { 68 | this.challengeName = challengeName; 69 | } 70 | 71 | /** 72 | * @return the challengeLevel 73 | */ 74 | public int getChallengeLevel() { 75 | return challengeLevel; 76 | } 77 | 78 | /** 79 | * @param challengeLevel the challengeLevel to set 80 | */ 81 | public void setChallengeLevel(int challengeLevel) { 82 | this.challengeLevel = challengeLevel; 83 | } 84 | 85 | /** 86 | * @return the maxNumOfHeroes 87 | */ 88 | public int getMaxNumOfHeroes() { 89 | return maxNumOfHeroes; 90 | } 91 | 92 | /** 93 | * @param maxNumOfHeroes the maxNumOfHeroes to set 94 | */ 95 | public void setMaxNumOfHeroes(int maxNumOfHeroes) { 96 | this.maxNumOfHeroes = maxNumOfHeroes; 97 | } 98 | 99 | /* (non-Javadoc) 100 | * @see java.lang.Object#hashCode() 101 | */ 102 | @Override 103 | public int hashCode() { 104 | final int prime = 31; 105 | int result = 1; 106 | result = prime * result + challengeLevel; 107 | result = prime * result + ((challengeName == null) ? 0 : challengeName.hashCode()); 108 | result = prime * result + (int)(challengesId ^ (challengesId >>> 32)); 109 | result = prime * result + maxNumOfHeroes; 110 | return result; 111 | } 112 | 113 | /* (non-Javadoc) 114 | * @see java.lang.Object#equals(java.lang.Object) 115 | */ 116 | @Override 117 | public boolean equals(Object obj) { 118 | if (this == obj) 119 | return true; 120 | if (obj == null) 121 | return false; 122 | if (getClass() != obj.getClass()) 123 | return false; 124 | Challenges other = (Challenges)obj; 125 | if (challengeLevel != other.challengeLevel) 126 | return false; 127 | if (challengeName == null) { 128 | if (other.challengeName != null) 129 | return false; 130 | } 131 | else if (!challengeName.equals(other.challengeName)) 132 | return false; 133 | if (challengesId != other.challengesId) 134 | return false; 135 | if (maxNumOfHeroes != other.maxNumOfHeroes) 136 | return false; 137 | return true; 138 | } 139 | 140 | /* (non-Javadoc) 141 | * @see java.lang.Object#toString() 142 | */ 143 | @Override 144 | public String toString() { 145 | StringBuilder builder = new StringBuilder(); 146 | builder.append("Challenges [challengesId=").append(challengesId).append(", challengeName=") 147 | .append(challengeName).append(", challengeLevel=").append(challengeLevel) 148 | .append(", maxNumOfHeroes=").append(maxNumOfHeroes).append("]"); 149 | return builder.toString(); 150 | } 151 | 152 | 153 | } 154 | 155 | 156 | 157 | -------------------------------------------------------------------------------- /challengesWeb/src/main/java/com/hitesh/boot/challenges/repositories/ChallengesRepository.java: -------------------------------------------------------------------------------- 1 | package com.hitesh.boot.challenges.repositories; 2 | 3 | import java.util.List; 4 | 5 | import org.springframework.data.repository.CrudRepository; 6 | import org.springframework.stereotype.Repository; 7 | 8 | import com.hitesh.boot.challenges.entity.Challenges; 9 | 10 | 11 | /** 12 | * @author hitjoshi 13 | * 14 | */ 15 | @Repository 16 | public interface ChallengesRepository extends CrudRepository{ 17 | Challenges findByChallengesId(long challengesId); 18 | List findByChallengeLevel(int challengeLevel); 19 | } 20 | -------------------------------------------------------------------------------- /challengesWeb/src/main/java/com/hitesh/boot/challenges/swagger/SwaggerConfig.java: -------------------------------------------------------------------------------- 1 | package com.hitesh.boot.challenges.swagger; 2 | 3 | 4 | 5 | import org.springframework.boot.autoconfigure.EnableAutoConfiguration; 6 | import org.springframework.context.annotation.Bean; 7 | import org.springframework.context.annotation.Configuration; 8 | 9 | import springfox.documentation.builders.PathSelectors; 10 | import springfox.documentation.builders.RequestHandlerSelectors; 11 | import springfox.documentation.spi.DocumentationType; 12 | import springfox.documentation.spring.web.plugins.Docket; 13 | import springfox.documentation.swagger2.annotations.EnableSwagger2; 14 | 15 | @Configuration 16 | @EnableSwagger2 17 | @EnableAutoConfiguration 18 | public class SwaggerConfig { 19 | @Bean 20 | public Docket api() { 21 | return new Docket(DocumentationType.SWAGGER_2) 22 | .select() 23 | .apis(RequestHandlerSelectors.basePackage("com.hitesh.boot.challenges.controller")) 24 | .paths(PathSelectors.any()).build(); 25 | } 26 | } -------------------------------------------------------------------------------- /challengesWeb/src/main/resources/bootstrap.yml: -------------------------------------------------------------------------------- 1 | eureka: 2 | instance: 3 | non-secure-port: ${server.port:3333} # so that different instances of microservice have their own swagger Ui 4 | statusPageUrlPath: /swagger-ui.html 5 | 6 | client: 7 | serviceUrl: 8 | defaultZone: http://localhost:1111/eureka/ 9 | -------------------------------------------------------------------------------- /challengesWeb/src/main/resources/challenges-server.yml: -------------------------------------------------------------------------------- 1 | # Spring properties 2 | spring: 3 | application: 4 | name: challenges-service 5 | freemarker: 6 | enabled: false # Ignore Eureka dashboard FreeMarker templates 7 | datasource: 8 | initialize: true 9 | jpa: 10 | hibernate: 11 | ddl-auto: none 12 | # thymeleaf: 13 | # cache: false # Allow Thymeleaf templates to be reloaded at runtime 14 | # prefix: classpath:/challenges-server/templates/ # Trailing / mandatory 15 | # Template location for this application only 16 | 17 | # Map the error path to error template (for Thymeleaf) 18 | error: 19 | path: /error 20 | 21 | # HTTP Server 22 | server: 23 | port: 3333 # HTTP (Tomcat) port 24 | display-name: Challenges 25 | 26 | # Discovery Server Access 27 | # 1. DEV ONLY: Reduce the lease renewal interval to speed up registration 28 | # 2. Define URL of registration server (defaultZone) 29 | eureka: 30 | client: 31 | serviceUrl: 32 | defaultZone: http://localhost:1111/eureka/ 33 | instance: 34 | leaseRenewalIntervalInSeconds: 5 # DO NOT DO THIS IN PRODUCTION 35 | 36 | # 3. If using the Angel release-train ONLY, give the process a unique instance id 37 | # so that multiple instances can register when running on SAME host. This is 38 | # not needed since release-train Brixton. 39 | # NOTE-1: spring.application.instance_id is only set when run on Cloud Foundry, 40 | # so we fallback on the server-port when it is not defined 41 | # NOTE-2: Syntax ${x:${y}} = use $x if set, otherwise use $y 42 | # metadataMap: 43 | # instanceId: ${spring.application.name}:${spring.application.instance_id:${server.port}} 44 | security: 45 | user: 46 | password: password 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /challengesWeb/src/main/resources/data.sql: -------------------------------------------------------------------------------- 1 | INSERT INTO CHALLENGES (CHALLENGE_NAME, CHALLENGE_LEVEL, MAX_HEROES) VALUES ('Darth vader Attack', 2, 2); 2 | INSERT INTO CHALLENGES (CHALLENGE_NAME, CHALLENGE_LEVEL, MAX_HEROES) VALUES ('Death by Choclate', 5, 1); 3 | INSERT INTO CHALLENGES (CHALLENGE_NAME, CHALLENGE_LEVEL, MAX_HEROES) VALUES ('Stolen Tessarect', 1, 4); 4 | INSERT INTO CHALLENGES (CHALLENGE_NAME, CHALLENGE_LEVEL, MAX_HEROES) VALUES ('Jokers rampage', 3, 1); 5 | INSERT INTO CHALLENGES (CHALLENGE_NAME, CHALLENGE_LEVEL, MAX_HEROES) VALUES ('Riddler', 1, 4); 6 | INSERT INTO CHALLENGES (CHALLENGE_NAME, CHALLENGE_LEVEL, MAX_HEROES) VALUES ('Narcos', 3, 1); 7 | INSERT INTO CHALLENGES (CHALLENGE_NAME, CHALLENGE_LEVEL, MAX_HEROES) VALUES ('Hydra', 2, 2); 8 | INSERT INTO CHALLENGES (CHALLENGE_NAME, CHALLENGE_LEVEL, MAX_HEROES) VALUES ('Biblical armagaddon', 5, 1); 9 | INSERT INTO CHALLENGES (CHALLENGE_NAME, CHALLENGE_LEVEL, MAX_HEROES) VALUES ('Nuclear WAR', 1, 4); 10 | 11 | --INSERT INTO CHALLENGES (CHALLENGE_NAME, CHALLENGE_LEVEL, MAX_HEROES) VALUES ('Westminster', 'W1', '1K'); 12 | --INSERT INTO CHALLENGES (CHALLENGE_NAME, CHALLENGE_LEVEL, MAX_HEROES) VALUES ('Westminster', 'W2', '1K'); 13 | --INSERT INTO CHALLENGES (CHALLENGE_NAME, CHALLENGE_LEVEL, MAX_HEROES) VALUES ('Westminster', 'W3', '1K'); 14 | --INSERT INTO CHALLENGES (CHALLENGE_NAME, CHALLENGE_LEVEL, MAX_HEROES) VALUES ('Westminster', 'W4', '1K'); 15 | --INSERT INTO CHALLENGES (CHALLENGE_NAME, CHALLENGE_LEVEL, MAX_HEROES) VALUES ('Westminster', 'W5', '2D'); 16 | --INSERT INTO CHALLENGES (CHALLENGE_NAME, CHALLENGE_LEVEL, MAX_HEROES) VALUES ('Westminster', 'W6', '2D'); 17 | --INSERT INTO CHALLENGES (CHALLENGE_NAME, CHALLENGE_LEVEL, MAX_HEROES) VALUES ('Westminster', 'W7', '2D'); 18 | --INSERT INTO CHALLENGES (CHALLENGE_NAME, CHALLENGE_LEVEL, MAX_HEROES) VALUES ('Oxford', 'O1', '1K'); 19 | --INSERT INTO CHALLENGES (CHALLENGE_NAME, CHALLENGE_LEVEL, MAX_HEROES) VALUES ('Oxford', 'O2', '1K'); 20 | --INSERT INTO CHALLENGES (CHALLENGE_NAME, CHALLENGE_LEVEL, MAX_HEROES) VALUES ('Oxford', 'O3', '1Q'); 21 | --INSERT INTO CHALLENGES (CHALLENGE_NAME, CHALLENGE_LEVEL, MAX_HEROES) VALUES ('Oxford', 'O4', '1Q'); 22 | --INSERT INTO CHALLENGES (CHALLENGE_NAME, CHALLENGE_LEVEL, MAX_HEROES) VALUES ('Oxford', 'O5', '1Q'); 23 | --INSERT INTO CHALLENGES (CHALLENGE_NAME, CHALLENGE_LEVEL, MAX_HEROES) VALUES ('Victoria', 'V1', '1K'); 24 | --INSERT INTO CHALLENGES (CHALLENGE_NAME, CHALLENGE_LEVEL, MAX_HEROES) VALUES ('Victoria', 'V2', '2D'); 25 | --INSERT INTO CHALLENGES (CHALLENGE_NAME, CHALLENGE_LEVEL, MAX_HEROES) VALUES ('Victoria', 'V3', '2D'); 26 | --INSERT INTO CHALLENGES (CHALLENGE_NAME, CHALLENGE_LEVEL, MAX_HEROES) VALUES ('Manchester', 'M1', '1K'); 27 | --INSERT INTO CHALLENGES (CHALLENGE_NAME, CHALLENGE_LEVEL, MAX_HEROES) VALUES ('Manchester', 'M2', '1K'); 28 | --INSERT INTO CHALLENGES (CHALLENGE_NAME, CHALLENGE_LEVEL, MAX_HEROES) VALUES ('Manchester', 'M3', '1K'); 29 | --INSERT INTO CHALLENGES (CHALLENGE_NAME, CHALLENGE_LEVEL, MAX_HEROES) VALUES ('Manchester', 'M4', '1K'); 30 | 31 | -------------------------------------------------------------------------------- /challengesWeb/src/main/resources/schema.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE CHALLENGES( 2 | CHALLENGES_ID BIGINT AUTO_INCREMENT PRIMARY KEY, 3 | CHALLENGE_NAME VARCHAR(30) NOT NULL UNIQUE, 4 | CHALLENGE_LEVEL BIGINT NOT NULL, 5 | MAX_HEROES BIGINT 6 | ); 7 | 8 | -------------------------------------------------------------------------------- /heroClient/.angular-cli.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "./node_modules/@angular/cli/lib/config/schema.json", 3 | "project": { 4 | "name": "hero-client" 5 | }, 6 | "apps": [ 7 | { 8 | "root": "src", 9 | "outDir": "dist", 10 | "assets": [ 11 | "assets", 12 | "favicon.ico" 13 | ], 14 | "index": "index.html", 15 | "main": "main.ts", 16 | "polyfills": "polyfills.ts", 17 | "test": "test.ts", 18 | "tsconfig": "tsconfig.app.json", 19 | "testTsconfig": "tsconfig.spec.json", 20 | "prefix": "app", 21 | "styles": [ 22 | "../node_modules/bootstrap/dist/css/bootstrap.min.css", 23 | "styles.css" 24 | ], 25 | "scripts": [], 26 | "environmentSource": "environments/environment.ts", 27 | "environments": { 28 | "dev": "environments/environment.ts", 29 | "prod": "environments/environment.prod.ts" 30 | } 31 | } 32 | ], 33 | "e2e": { 34 | "protractor": { 35 | "config": "./protractor.conf.js" 36 | } 37 | }, 38 | "lint": [ 39 | { 40 | "project": "src/tsconfig.app.json" 41 | }, 42 | { 43 | "project": "src/tsconfig.spec.json" 44 | }, 45 | { 46 | "project": "e2e/tsconfig.e2e.json" 47 | } 48 | ], 49 | "test": { 50 | "karma": { 51 | "config": "./karma.conf.js" 52 | } 53 | }, 54 | "defaults": { 55 | "styleExt": "css", 56 | "component": {} 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /heroClient/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /heroClient/.editorconfig: -------------------------------------------------------------------------------- 1 | # Editor configuration, see http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | indent_style = space 7 | indent_size = 2 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | [*.md] 12 | max_line_length = off 13 | trim_trailing_whitespace = false 14 | -------------------------------------------------------------------------------- /heroClient/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | heroClient 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.wst.common.project.facet.core.builder 10 | 11 | 12 | 13 | 14 | org.eclipse.jdt.core.javabuilder 15 | 16 | 17 | 18 | 19 | org.eclipse.wst.validation.validationbuilder 20 | 21 | 22 | 23 | 24 | org.springframework.ide.eclipse.core.springbuilder 25 | 26 | 27 | 28 | 29 | org.eclipse.m2e.core.maven2Builder 30 | 31 | 32 | 33 | 34 | 35 | org.springframework.ide.eclipse.core.springnature 36 | org.eclipse.jem.workbench.JavaEMFNature 37 | org.eclipse.wst.common.modulecore.ModuleCoreNature 38 | org.eclipse.jdt.core.javanature 39 | org.eclipse.m2e.core.maven2Nature 40 | org.eclipse.wst.common.project.facet.core.nature 41 | 42 | 43 | -------------------------------------------------------------------------------- /heroClient/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible Node.js debug attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "type": "node", 9 | "request": "launch", 10 | "name": "Launch Program", 11 | "program": "${file}" 12 | } 13 | ] 14 | } -------------------------------------------------------------------------------- /heroClient/README.md: -------------------------------------------------------------------------------- 1 | # HeroClient 2 | 3 | This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 1.0.4. 4 | 5 | ## Development server 6 | 7 | Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files. 8 | 9 | ## Code scaffolding 10 | 11 | Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive|pipe|service|class|module`. 12 | 13 | ## Build 14 | 15 | Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory. Use the `-prod` flag for a production build. 16 | 17 | ## Running unit tests 18 | 19 | Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io). 20 | 21 | ## Running end-to-end tests 22 | 23 | Run `ng e2e` to execute the end-to-end tests via [Protractor](http://www.protractortest.org/). 24 | Before running the tests make sure you are serving the app via `ng serve`. 25 | 26 | ## Further help 27 | 28 | To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI README](https://github.com/angular/angular-cli/blob/master/README.md). 29 | -------------------------------------------------------------------------------- /heroClient/e2e/app.e2e-spec.ts: -------------------------------------------------------------------------------- 1 | import { HeroClientPage } from './app.po'; 2 | 3 | describe('hero-client App', () => { 4 | let page: HeroClientPage; 5 | 6 | beforeEach(() => { 7 | page = new HeroClientPage(); 8 | }); 9 | 10 | it('should display message saying app works', () => { 11 | page.navigateTo(); 12 | expect(page.getParagraphText()).toEqual('app works!'); 13 | }); 14 | }); 15 | -------------------------------------------------------------------------------- /heroClient/e2e/app.po.ts: -------------------------------------------------------------------------------- 1 | import { browser, by, element } from 'protractor'; 2 | 3 | export class HeroClientPage { 4 | navigateTo() { 5 | return browser.get('/'); 6 | } 7 | 8 | getParagraphText() { 9 | return element(by.css('app-root h1')).getText(); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /heroClient/e2e/tsconfig.e2e.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../out-tsc/e2e", 5 | "module": "commonjs", 6 | "target": "es5", 7 | "types": [ 8 | "jasmine", 9 | "node" 10 | ] 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /heroClient/karma.conf.js: -------------------------------------------------------------------------------- 1 | // Karma configuration file, see link for more information 2 | // https://karma-runner.github.io/0.13/config/configuration-file.html 3 | 4 | module.exports = function (config) { 5 | config.set({ 6 | basePath: '', 7 | frameworks: ['jasmine', '@angular/cli'], 8 | plugins: [ 9 | require('karma-jasmine'), 10 | require('karma-chrome-launcher'), 11 | require('karma-jasmine-html-reporter'), 12 | require('karma-coverage-istanbul-reporter'), 13 | require('@angular/cli/plugins/karma') 14 | ], 15 | client:{ 16 | clearContext: false // leave Jasmine Spec Runner output visible in browser 17 | }, 18 | files: [ 19 | { pattern: './src/test.ts', watched: false } 20 | ], 21 | preprocessors: { 22 | './src/test.ts': ['@angular/cli'] 23 | }, 24 | mime: { 25 | 'text/x-typescript': ['ts','tsx'] 26 | }, 27 | coverageIstanbulReporter: { 28 | reports: [ 'html', 'lcovonly' ], 29 | fixWebpackSourcePaths: true 30 | }, 31 | angularCli: { 32 | environment: 'dev' 33 | }, 34 | reporters: config.angularCli && config.angularCli.codeCoverage 35 | ? ['progress', 'coverage-istanbul'] 36 | : ['progress', 'kjhtml'], 37 | port: 9876, 38 | colors: true, 39 | logLevel: config.LOG_INFO, 40 | autoWatch: true, 41 | browsers: ['Chrome'], 42 | singleRun: false 43 | }); 44 | }; 45 | -------------------------------------------------------------------------------- /heroClient/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "hero-client", 3 | "version": "0.0.0", 4 | "license": "MIT", 5 | "scripts": { 6 | "ng": "ng", 7 | "start": "ng serve", 8 | "build": "ng build", 9 | "test": "ng test", 10 | "lint": "ng lint", 11 | "e2e": "ng e2e" 12 | }, 13 | "private": true, 14 | "dependencies": { 15 | "@angular/common": "^4.0.0", 16 | "@angular/compiler": "^4.0.0", 17 | "@angular/core": "^4.0.0", 18 | "@angular/forms": "^4.0.0", 19 | "@angular/http": "^4.0.0", 20 | "@angular/platform-browser": "^4.0.0", 21 | "@angular/platform-browser-dynamic": "^4.0.0", 22 | "@angular/router": "^4.0.0", 23 | "bootstrap": "^3.3.7", 24 | "core-js": "^2.4.1", 25 | "rxjs": "^5.1.0", 26 | "zone.js": "^0.8.4" 27 | }, 28 | "devDependencies": { 29 | "@angular/cli": "1.0.4", 30 | "@angular/compiler-cli": "^4.0.0", 31 | "@types/jasmine": "2.5.38", 32 | "@types/node": "~6.0.60", 33 | "codelyzer": "~2.0.0", 34 | "jasmine-core": "~2.5.2", 35 | "jasmine-spec-reporter": "~3.2.0", 36 | "karma": "~1.4.1", 37 | "karma-chrome-launcher": "~2.1.1", 38 | "karma-cli": "~1.0.1", 39 | "karma-jasmine": "~1.1.0", 40 | "karma-jasmine-html-reporter": "^0.2.2", 41 | "karma-coverage-istanbul-reporter": "^0.2.0", 42 | "protractor": "~5.1.0", 43 | "ts-node": "~2.0.0", 44 | "tslint": "~4.5.0", 45 | "typescript": "~2.2.0" 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /heroClient/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | com.hitesh.boot 6 | heroes 7 | ${project.version} 8 | 9 | 10 | heroClient 11 | 12 | 1.3 13 | v6.10.0 14 | 4.4.4 15 | 2.4.2 16 | Set via command line argument 17 | 18 | 19 | 20 | BUILD 21 | 22 | true 23 | 24 | 25 | 26 | 27 | META-INF/resources 28 | ${basedir}/dist 29 | 30 | 31 | 32 | 33 | com.github.eirslett 34 | frontend-maven-plugin 35 | ${frontend-maven-plugin.version} 36 | 37 | 38 | Installing node.js and npm locally 39 | 40 | install-node-and-npm 41 | 42 | 43 | 44 | ${node.version} 45 | ${npm.version} 46 | ${basedir} 47 | ${basedir} 48 | 49 | 50 | 51 | 70 | 71 | 72 | Running build 73 | 74 | npm 75 | 76 | 77 | run build 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | LINT 88 | 89 | 90 | 91 | META-INF/resources 92 | ${basedir}/dist 93 | 94 | 95 | 96 | 97 | com.github.eirslett 98 | frontend-maven-plugin 99 | ${frontend-maven-plugin.version} 100 | 101 | 102 | Running linter 103 | 104 | npm 105 | 106 | 107 | run lint 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | FUNCTIONAL_TESTS 118 | 119 | 120 | 121 | com.github.eirslett 122 | frontend-maven-plugin 123 | ${frontend-maven-plugin.version} 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | Running integration tests 136 | 137 | npm 138 | 139 | 140 | run e2e -- --params.SERVICE_PORT=${backendPortNbr} 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | UNIT_TESTS 150 | 151 | 152 | 153 | com.github.eirslett 154 | frontend-maven-plugin 155 | ${frontend-maven-plugin.version} 156 | 157 | 158 | Running unit tests 159 | 160 | npm 161 | 162 | 163 | run test 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | org.apache.maven.plugins 178 | maven-release-plugin 179 | ${maven-release-plugin.version} 180 | 181 | 182 | 183 | -------------------------------------------------------------------------------- /heroClient/protractor.conf.js: -------------------------------------------------------------------------------- 1 | // Protractor configuration file, see link for more information 2 | // https://github.com/angular/protractor/blob/master/lib/config.ts 3 | 4 | const { SpecReporter } = require('jasmine-spec-reporter'); 5 | 6 | exports.config = { 7 | allScriptsTimeout: 11000, 8 | specs: [ 9 | './e2e/**/*.e2e-spec.ts' 10 | ], 11 | capabilities: { 12 | 'browserName': 'chrome' 13 | }, 14 | directConnect: true, 15 | baseUrl: 'http://localhost:4200/', 16 | framework: 'jasmine', 17 | jasmineNodeOpts: { 18 | showColors: true, 19 | defaultTimeoutInterval: 30000, 20 | print: function() {} 21 | }, 22 | onPrepare() { 23 | require('ts-node').register({ 24 | project: 'e2e/tsconfig.e2e.json' 25 | }); 26 | jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } })); 27 | } 28 | }; 29 | -------------------------------------------------------------------------------- /heroClient/src/app/app-routing/app-routing.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { RouterModule, Routes } from '@angular/router'; 3 | import { DashboardComponent } from './../dashboard/dashboard.component'; 4 | import { HeroesComponent } from './../heroes/heroes.component'; 5 | import { HeroDetailComponent } from './../hero-detail/hero-detail.component'; 6 | import { SignupComponent } from './../signup/signup.component'; 7 | 8 | // Create a Route Array 9 | const routes: Routes = 10 | [ 11 | { path: '', redirectTo: '/dashboard', pathMatch: 'full' }, 12 | { path: 'dashboard', component: DashboardComponent }, 13 | { path: 'detail/:id', component: HeroDetailComponent }, 14 | { path: 'heroes', component: HeroesComponent }, 15 | { path : 'signup', component: SignupComponent} 16 | ]; 17 | 18 | // Router.forRoot returns a module 19 | // we create it and then export the same 20 | @NgModule({ 21 | imports: [RouterModule.forRoot(routes,{ enableTracing: true })], 22 | exports: [RouterModule] 23 | }) 24 | export class AppRoutingModule { } 25 | -------------------------------------------------------------------------------- /heroClient/src/app/app.component.css: -------------------------------------------------------------------------------- 1 | h1 { 2 | font-size: 1.2em; 3 | color: #999; 4 | margin-bottom: 0; 5 | } 6 | h2 { 7 | font-size: 2em; 8 | margin-top: 0; 9 | padding-top: 0; 10 | } 11 | nav a { 12 | padding: 5px 10px; 13 | text-decoration: none; 14 | margin-top: 10px; 15 | display: inline-block; 16 | background-color: #eee; 17 | border-radius: 4px; 18 | } 19 | nav a:visited, a:link { 20 | color: #607D8B; 21 | } 22 | nav a:hover { 23 | color: #039be5; 24 | background-color: #CFD8DC; 25 | } 26 | nav a.active { 27 | color: #039be5; 28 | } 29 | -------------------------------------------------------------------------------- /heroClient/src/app/app.component.html: -------------------------------------------------------------------------------- 1 |

{{title}}

2 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /heroClient/src/app/app.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed, async } from '@angular/core/testing'; 2 | 3 | import { AppComponent } from './app.component'; 4 | 5 | describe('AppComponent', () => { 6 | beforeEach(async(() => { 7 | TestBed.configureTestingModule({ 8 | declarations: [ 9 | AppComponent 10 | ], 11 | }).compileComponents(); 12 | })); 13 | 14 | it('should create the app', async(() => { 15 | const fixture = TestBed.createComponent(AppComponent); 16 | const app = fixture.debugElement.componentInstance; 17 | expect(app).toBeTruthy(); 18 | })); 19 | 20 | it(`should have as title 'app works!'`, async(() => { 21 | const fixture = TestBed.createComponent(AppComponent); 22 | const app = fixture.debugElement.componentInstance; 23 | expect(app.title).toEqual('app works!'); 24 | })); 25 | 26 | it('should render title in a h1 tag', async(() => { 27 | const fixture = TestBed.createComponent(AppComponent); 28 | fixture.detectChanges(); 29 | const compiled = fixture.debugElement.nativeElement; 30 | expect(compiled.querySelector('h1').textContent).toContain('app works!'); 31 | })); 32 | }); 33 | -------------------------------------------------------------------------------- /heroClient/src/app/app.component.ts: -------------------------------------------------------------------------------- 1 | import { Component,OnInit } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-root', 5 | templateUrl: './app.component.html', 6 | styleUrls: [ './app.component.css' ] 7 | }) 8 | export class AppComponent{ 9 | title = 'Tour of Heroes'; 10 | 11 | 12 | onFavChange($event){ 13 | console.log($event); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /heroClient/src/app/app.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { BrowserModule } from '@angular/platform-browser'; 3 | 4 | // import component here 5 | import { AppComponent } from './app.component'; 6 | // for ngModel 7 | import { FormsModule } from '@angular/forms'; 8 | import { HttpModule,JsonpModule } from '@angular/http'; 9 | import { HeroDetailComponent } from './hero-detail/hero-detail.component'; 10 | import { HeroesComponent } from './heroes/heroes.component'; 11 | import { DashboardComponent } from './dashboard/dashboard.component'; 12 | //Creating a Singleton service by adding the service as provider to app module 13 | import { HeroService } from './services/hero.service'; 14 | import {AuthService} from './services/auth.service'; 15 | import {UdemyModule} from './udemy/udemy.module'; 16 | import {UtilModule} from './util/util.module'; 17 | 18 | //Routing 19 | 20 | // Seprating it to its own file - Udemy Module is a child route 21 | import {UdemyRoutingModule} from './udemy/udemy.routing'; 22 | // Main Routing file 23 | import { AppRoutingModule } from './app-routing/app-routing.module'; 24 | 25 | import { SignupComponent } from './signup/signup.component'; 26 | import { ReactiveFormsModule } from '@angular/forms'; 27 | // import { SummarizePipe } from './util/summarize.pipe'; 28 | 29 | 30 | 31 | 32 | // This is actually an Annotation for the AppModule Class 33 | @NgModule({ 34 | imports: [ BrowserModule, 35 | FormsModule, 36 | UdemyRoutingModule, 37 | AppRoutingModule, 38 | HttpModule, 39 | UdemyModule, 40 | JsonpModule, 41 | UtilModule, 42 | ReactiveFormsModule 43 | ], 44 | // add components here 45 | declarations: [ AppComponent, HeroesComponent, HeroDetailComponent, 46 | DashboardComponent, 47 | SignupComponent 48 | ], 49 | bootstrap: [ AppComponent ], 50 | providers: [HeroService, AuthService], 51 | 52 | }) 53 | export class AppModule { 54 | } 55 | -------------------------------------------------------------------------------- /heroClient/src/app/auth.guard.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed, async, inject } from '@angular/core/testing'; 2 | 3 | import { AuthGuard } from './auth.guard'; 4 | 5 | describe('AuthGuard', () => { 6 | beforeEach(() => { 7 | TestBed.configureTestingModule({ 8 | providers: [AuthGuard] 9 | }); 10 | }); 11 | 12 | it('should ...', inject([AuthGuard], (guard: AuthGuard) => { 13 | expect(guard).toBeTruthy(); 14 | })); 15 | }); 16 | -------------------------------------------------------------------------------- /heroClient/src/app/auth.guard.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, Router } from '@angular/router'; 3 | import { Observable } from 'rxjs/Observable'; 4 | import {AuthService} from './udemy/services/auth.service'; 5 | 6 | @Injectable() 7 | export class AuthGuard implements CanActivate { 8 | 9 | constructor(private _authService: AuthService, private _router:Router){} 10 | canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot): 11 | Observable | Promise | boolean { 12 | console.log('AuthGuard#canActivate called'); 13 | if(this._authService.isLoggedIn) { 14 | return true; 15 | } 16 | this._router.navigate(['dashboard']); 17 | return false; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /heroClient/src/app/dashboard/dashboard.component.css: -------------------------------------------------------------------------------- 1 | [class*='col-'] { 2 | float: left; 3 | padding-right: 20px; 4 | padding-bottom: 20px; 5 | } 6 | [class*='col-']:last-of-type { 7 | padding-right: 0; 8 | } 9 | a { 10 | text-decoration: none; 11 | } 12 | *, *:after, *:before { 13 | -webkit-box-sizing: border-box; 14 | -moz-box-sizing: border-box; 15 | box-sizing: border-box; 16 | } 17 | h3 { 18 | text-align: center; margin-bottom: 0; 19 | } 20 | h4 { 21 | position: relative; 22 | } 23 | .grid { 24 | margin: 0; 25 | } 26 | .col-1-4 { 27 | width: 25%; 28 | } 29 | .module { 30 | padding: 20px; 31 | text-align: center; 32 | color: #eee; 33 | max-height: 120px; 34 | min-width: 120px; 35 | background-color: #607D8B; 36 | border-radius: 2px; 37 | } 38 | .module:hover { 39 | background-color: #EEE; 40 | cursor: pointer; 41 | color: #607d8b; 42 | } 43 | .grid-pad { 44 | padding: 10px 0; 45 | } 46 | .grid-pad > [class*='col-']:last-of-type { 47 | padding-right: 20px; 48 | } 49 | @media (max-width: 600px) { 50 | .module { 51 | font-size: 10px; 52 | max-height: 75px; } 53 | } 54 | @media (max-width: 1024px) { 55 | .grid { 56 | margin: 0; 57 | } 58 | .module { 59 | min-width: 60px; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /heroClient/src/app/dashboard/dashboard.component.html: -------------------------------------------------------------------------------- 1 |

Top Heroes

2 | 9 | -------------------------------------------------------------------------------- /heroClient/src/app/dashboard/dashboard.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { DashboardComponent } from './dashboard.component'; 4 | 5 | describe('DashboardComponent', () => { 6 | let component: DashboardComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ DashboardComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(DashboardComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should be created', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /heroClient/src/app/dashboard/dashboard.component.ts: -------------------------------------------------------------------------------- 1 | import { Component,OnInit } from '@angular/core'; 2 | import { Hero } from './../models/hero'; 3 | import { HeroService } from './../services/hero.service'; 4 | import { Observable } from 'rxjs/Observable'; 5 | import 'rxjs/add/operator/catch'; 6 | import 'rxjs/add/operator/map'; 7 | 8 | @Component({ 9 | selector: 'app-dashboard', 10 | templateUrl: './dashboard.component.html', 11 | styleUrls: ['./dashboard.component.css'] 12 | }) 13 | export class DashboardComponent implements OnInit { 14 | 15 | // heroes: Hero[] = []; 16 | 17 | heroes: Hero[]; 18 | constructor(private heroService: HeroService) { } 19 | 20 | ngOnInit(): void { 21 | this.heroService.getHeroes().subscribe( 22 | heroes => this.heroes = heroes.slice(heroes.length-4,heroes.length)); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /heroClient/src/app/hero-detail/hero-detail.component.css: -------------------------------------------------------------------------------- 1 | label { 2 | display: inline-block; 3 | width: 3em; 4 | margin: .5em 0; 5 | color: #607D8B; 6 | font-weight: bold; 7 | } 8 | input { 9 | height: 2em; 10 | font-size: 1em; 11 | padding-left: .4em; 12 | } 13 | button { 14 | margin-top: 20px; 15 | font-family: Arial; 16 | background-color: #eee; 17 | border: none; 18 | padding: 5px 10px; 19 | border-radius: 4px; 20 | cursor: pointer; cursor: hand; 21 | } 22 | button:hover { 23 | background-color: #cfd8dc; 24 | } 25 | button:disabled { 26 | background-color: #eee; 27 | color: #ccc; 28 | cursor: auto; 29 | } 30 | -------------------------------------------------------------------------------- /heroClient/src/app/hero-detail/hero-detail.component.html: -------------------------------------------------------------------------------- 1 |
2 |

{{hero.name}} details!

3 |
4 | {{hero.id}}
5 |
6 | 7 | 8 |
9 | 10 | 11 |
12 | -------------------------------------------------------------------------------- /heroClient/src/app/hero-detail/hero-detail.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { HeroDetailComponent } from './hero-detail.component'; 4 | 5 | describe('HeroDetailComponent', () => { 6 | let component: HeroDetailComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ HeroDetailComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(HeroDetailComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should be created', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /heroClient/src/app/hero-detail/hero-detail.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | // ActivatedRoute is needed to get Route Params 3 | import { ActivatedRoute, Params } from '@angular/router'; 4 | import { Location } from '@angular/common'; 5 | import { Hero } from './../models/hero'; 6 | import { HeroService } from './../services/hero.service'; 7 | //SwitchMap 8 | import 'rxjs/add/operator/switchMap'; 9 | 10 | 11 | @Component({ 12 | selector: 'app-hero-detail', 13 | templateUrl: './hero-detail.component.html', 14 | styleUrls: ['./hero-detail.component.css'] 15 | }) 16 | export class HeroDetailComponent implements OnInit { 17 | 18 | hero: Hero; 19 | 20 | constructor( 21 | private heroService: HeroService, 22 | private route: ActivatedRoute, 23 | private location: Location 24 | ) {} 25 | 26 | ngOnInit():void{ 27 | // capturing Route parameters 28 | this.route.params.switchMap((params: Params) => this.heroService.getHero(+params['id'])) 29 | .subscribe(hero => this.hero = hero); 30 | } 31 | 32 | 33 | goBack(): void { 34 | this.location.back(); 35 | } 36 | 37 | save(): void { 38 | this.heroService.update(this.hero) 39 | .subscribe(() => this.goBack()); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /heroClient/src/app/heroes/heroes.component.css: -------------------------------------------------------------------------------- 1 | .selected { 2 | background-color: #CFD8DC !important; 3 | color: white; 4 | } 5 | .heroes { 6 | margin: 0 0 2em 0; 7 | list-style-type: none; 8 | padding: 0; 9 | width: 15em; 10 | } 11 | .heroes li { 12 | cursor: pointer; 13 | position: relative; 14 | left: 0; 15 | background-color: #EEE; 16 | margin: .5em; 17 | padding: .3em 0; 18 | height: 1.6em; 19 | border-radius: 4px; 20 | } 21 | .heroes li:hover { 22 | color: #607D8B; 23 | background-color: #DDD; 24 | left: .1em; 25 | } 26 | .heroes li.selected:hover { 27 | background-color: #BBD8DC !important; 28 | color: white; 29 | } 30 | .heroes .text { 31 | position: relative; 32 | top: -3px; 33 | } 34 | .heroes .badge { 35 | display: inline-block; 36 | font-size: small; 37 | color: white; 38 | padding: 0.8em 0.7em 0 0.7em; 39 | background-color: #607D8B; 40 | line-height: 1em; 41 | position: relative; 42 | left: -1px; 43 | top: -4px; 44 | height: 1.8em; 45 | margin-right: .8em; 46 | border-radius: 4px 0 0 4px; 47 | } 48 | button { 49 | font-family: Arial; 50 | background-color: #eee; 51 | border: none; 52 | padding: 5px 10px; 53 | border-radius: 4px; 54 | cursor: pointer; 55 | cursor: hand; 56 | } 57 | button:hover { 58 | background-color: #cfd8dc; 59 | } 60 | -------------------------------------------------------------------------------- /heroClient/src/app/heroes/heroes.component.html: -------------------------------------------------------------------------------- 1 |

All Heroes Die

2 |
3 |
    4 |
  • 7 | {{hero.id}} {{hero.name}} 8 | 9 | 10 | 11 | 13 |
  • 14 |
15 |
16 |
17 |

18 | {{selectedHero.name | uppercase}} is my hero 19 |

20 | 21 |
22 | 23 |
24 | 25 | 28 |
29 | -------------------------------------------------------------------------------- /heroClient/src/app/heroes/heroes.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { HeroesComponent } from './heroes.component'; 4 | 5 | describe('HeroesComponent', () => { 6 | let component: HeroesComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ HeroesComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(HeroesComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should be created', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /heroClient/src/app/heroes/heroes.component.ts: -------------------------------------------------------------------------------- 1 | import { Component,OnInit } from '@angular/core'; 2 | import { Hero } from './../models/hero'; 3 | import { HeroService } from './../services/hero.service'; 4 | import { Router} from '@angular/router'; 5 | 6 | 7 | @Component({ 8 | selector: 'my-heroes', 9 | templateUrl: './heroes.component.html', 10 | styleUrls: [ './heroes.component.css' ] 11 | }) 12 | 13 | export class HeroesComponent implements OnInit { 14 | 15 | heroes: Hero[]; 16 | selectedHero: Hero; 17 | errorMessage: any; 18 | 19 | isActive = true; 20 | // injecting a Service 21 | constructor(private heroService: HeroService, private router: Router) { } 22 | 23 | ngOnInit(): void { 24 | this.getHeroes(); 25 | } 26 | 27 | 28 | getHeroes(): void { 29 | // this.heroService.getHeroes().then(heroesRet => this.heroes=heroesRet); 30 | this.heroService.getHeroes().subscribe( 31 | heroes => this.heroes = heroes, 32 | error => this.errorMessage = error); 33 | } 34 | 35 | gotoDetail(): void { 36 | // sending Route params - this requires using an array with path followed by Route Param 37 | this.router.navigate(['/detail', this.selectedHero.id]); 38 | } 39 | 40 | onSelect(hero: Hero): void { 41 | this.selectedHero = hero; 42 | } 43 | 44 | add(name: string, $event): void { 45 | console.log($event); 46 | name = name.trim(); 47 | if (!name) { return; } 48 | this.heroService.create(name) 49 | .subscribe(hero => { 50 | console.log(hero); 51 | this.heroes.push(hero); 52 | this.selectedHero = null; 53 | }); 54 | } 55 | 56 | delete(hero: Hero): void { 57 | this.heroService 58 | .delete(hero.id) 59 | .subscribe(() => { 60 | this.heroes = this.heroes.filter(h => h !== hero); 61 | if (this.selectedHero === hero) { this.selectedHero = null; } 62 | }); 63 | } 64 | 65 | 66 | } 67 | -------------------------------------------------------------------------------- /heroClient/src/app/models/hero.ts: -------------------------------------------------------------------------------- 1 | export class Hero { 2 | id: number; 3 | name: string; 4 | } 5 | -------------------------------------------------------------------------------- /heroClient/src/app/models/tweet.ts: -------------------------------------------------------------------------------- 1 | export class Tweet { 2 | tweetId: number; 3 | authorName: string; 4 | authorHandle:string; 5 | tweetMesg:string; 6 | numLikes: number; 7 | tweetImgUrl:string; 8 | } 9 | -------------------------------------------------------------------------------- /heroClient/src/app/services/auth.service.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed, inject } from '@angular/core/testing'; 2 | 3 | import { AuthService } from './auth.service'; 4 | 5 | describe('AuthService', () => { 6 | beforeEach(() => { 7 | TestBed.configureTestingModule({ 8 | providers: [AuthService] 9 | }); 10 | }); 11 | 12 | it('should be created', inject([AuthService], (service: AuthService) => { 13 | expect(service).toBeTruthy(); 14 | })); 15 | }); 16 | -------------------------------------------------------------------------------- /heroClient/src/app/services/auth.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | 3 | @Injectable() 4 | export class AuthService { 5 | 6 | constructor() { } 7 | 8 | } 9 | -------------------------------------------------------------------------------- /heroClient/src/app/services/hero.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | import { Hero } from './../models/hero'; 3 | // import { HEROES } from './mock-heroes'; 4 | import { Http,Response,URLSearchParams,RequestOptions,Headers } from '@angular/http'; 5 | import 'rxjs/add/operator/toPromise'; 6 | 7 | import { Observable } from 'rxjs/Observable'; 8 | import 'rxjs/add/operator/catch'; 9 | import 'rxjs/add/operator/map'; 10 | 11 | @Injectable() 12 | export class HeroService { 13 | private heroesUrl = 'http://localhost:2222/heroes'; 14 | 15 | constructor(private http : Http) { } 16 | 17 | getHeroes(): Observable { 18 | return this.http.get(this.heroesUrl) 19 | .map(this.extractData) 20 | .catch(this.handleError); 21 | } 22 | 23 | 24 | 25 | 26 | private extractData(res: Response) { 27 | let body = res.json(); 28 | return body || { }; 29 | } 30 | 31 | private extractAHero(res: Response) { 32 | let body = res.json(); 33 | return body[0] || { }; 34 | } 35 | 36 | private handleError (error: Response | any) { 37 | // In a real world app, you might use a remote logging infrastructure 38 | let errMsg: string; 39 | if (error instanceof Response) { 40 | const body = error.json() || ''; 41 | const err = body.error || JSON.stringify(body); 42 | errMsg = `${error.status} - ${error.statusText || ''} ${err}`; 43 | } else { 44 | errMsg = error.message ? error.message : error.toString(); 45 | } 46 | console.error(errMsg); 47 | return Observable.throw(errMsg); 48 | } 49 | 50 | 51 | // getHeroesSlowly(): Promise { 52 | // return new Promise(resolve => { 53 | // // Simulate server latency with 2 second delay 54 | // setTimeout(() => resolve(this.getHeroes()), 2000); 55 | // }); 56 | // } 57 | 58 | 59 | getHero(id: number): Observable { 60 | let params: URLSearchParams = new URLSearchParams(); 61 | params.set('heroId',id.toString()); 62 | 63 | return this.http.get(this.heroesUrl,{search: params}) 64 | .map(this.extractAHero) 65 | .catch(this.handleError); 66 | } 67 | 68 | update(hero: Hero): Observable { 69 | let headers = new Headers({ 'Content-Type': 'application/json' }); 70 | let options = new RequestOptions({ headers: headers }); 71 | return this.http 72 | .put(this.heroesUrl,JSON.stringify(hero),options) 73 | .map(res => res.json()) 74 | .catch(this.handleError); 75 | } 76 | 77 | create(name: string): Observable { 78 | let headers = new Headers({ 'Content-Type': 'application/json' }); 79 | let options = new RequestOptions({ headers: headers }); 80 | return this.http 81 | .post(this.heroesUrl, JSON.stringify({name: name}),options) 82 | .map(res => res.json() as Hero) 83 | .catch(this.handleError); 84 | } 85 | 86 | delete(id: number): Observable { 87 | console.log(id.toString()); 88 | let headers = new Headers({ 'Content-Type': 'application/json' }); 89 | let options = new RequestOptions({ headers: headers }); 90 | 91 | let url = this.heroesUrl+'/'+id.toString(); 92 | return this.http.delete(url,headers 93 | ) 94 | .map(() =>null) 95 | .catch(this.handleError); 96 | } 97 | 98 | } 99 | -------------------------------------------------------------------------------- /heroClient/src/app/services/tweet.service.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed, inject } from '@angular/core/testing'; 2 | 3 | import { TweetService } from './tweet.service'; 4 | 5 | describe('TweetService', () => { 6 | beforeEach(() => { 7 | TestBed.configureTestingModule({ 8 | providers: [TweetService] 9 | }); 10 | }); 11 | 12 | it('should be created', inject([TweetService], (service: TweetService) => { 13 | expect(service).toBeTruthy(); 14 | })); 15 | }); 16 | -------------------------------------------------------------------------------- /heroClient/src/app/services/tweet.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | import {Tweet} from './../models/tweet'; 3 | 4 | @Injectable() 5 | export class TweetService { 6 | 7 | constructor() { } 8 | 9 | getAllTweets():Tweet[] { 10 | return [{tweetId: 1, 11 | authorName: "Hitesh", 12 | authorHandle:"@joshiji", 13 | tweetMesg:"Start from basics, be a honest, clear headed and disciplined person first ", 14 | numLikes:1000, 15 | tweetImgUrl:"http://lorempixel.com/100/100/people?1" 16 | }, 17 | { 18 | tweetId: 2, 19 | authorName: "Deepika", 20 | authorHandle:"@dips", 21 | tweetMesg:"Then learn the basics of your trade, from typing to Problem Solving. Master them slowly", 22 | numLikes:900, 23 | tweetImgUrl:"http://lorempixel.com/100/100/people?2" 24 | }, 25 | { 26 | tweetId: 1, 27 | authorName: "Viktor Frankl", 28 | authorHandle:"@viklogos", 29 | tweetMesg:"Learn to live a happier and fuller life, do what you feel right in the long term and make aligned choices in the short term. Build your life and career consciously ", 30 | numLikes:10000, 31 | tweetImgUrl:"http://lorempixel.com/100/100/people?4"}]; 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /heroClient/src/app/signup/signup.component.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hiteshjoshi1/spring-boot-angular2/83da325097f123f4d99d02cfdc8f98ea7d1dec4c/heroClient/src/app/signup/signup.component.css -------------------------------------------------------------------------------- /heroClient/src/app/signup/signup.component.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | 4 | 9 | 10 | 11 |
12 | 13 |
14 |
15 | User Name has to be minimum 6 characters 16 |
17 |
18 | User Name cannot have space in between 19 |
20 |
User Name is invalid
21 |
22 | User Name is required 23 |
24 |
25 | User Name is Already Taken 26 |
27 | 28 |
29 |
30 |
31 | 32 | 36 |
37 | 38 |
-------------------------------------------------------------------------------- /heroClient/src/app/signup/signup.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { SignupComponent } from './signup.component'; 4 | 5 | describe('SignupComponent', () => { 6 | let component: SignupComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ SignupComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(SignupComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should be created', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /heroClient/src/app/signup/signup.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | import { FormControl, FormGroup, Validators, FormBuilder } from '@angular/forms'; 3 | import {UserNameValidator} from './../validators/UserNameValidator'; 4 | 5 | 6 | @Component({ 7 | selector: 'app-signup', 8 | templateUrl: './signup.component.html', 9 | styleUrls: ['./signup.component.css'] 10 | }) 11 | export class SignupComponent implements OnInit { 12 | 13 | form: FormGroup; 14 | 15 | // form = new FormGroup({ 16 | // userName: new FormControl('', Validators.required), 17 | // password: new FormControl('', Validators.required) 18 | // }); 19 | 20 | constructor( private fb: FormBuilder) { 21 | this.createForm(); 22 | } 23 | 24 | createForm() { 25 | this.form = this.fb.group({ 26 | userName: ['', Validators.compose([ 27 | Validators.required, 28 | Validators.minLength(4), 29 | Validators.maxLength(24), 30 | UserNameValidator.checkForSpaceInUserName]), 31 | UserNameValidator.shouldbeUnique // async validator 32 | ], 33 | password: ['', Validators.required] 34 | }); 35 | } 36 | 37 | ngOnInit() { 38 | } 39 | 40 | signUp(){ 41 | console.log(this.form); 42 | console.log(this.form.value.userName); 43 | // call a service- example like Login 44 | // if it fails explictly set an error here. 45 | this.form.get('userName').setErrors({ 46 | inValidLogin: true 47 | }); 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /heroClient/src/app/udemy/authors/authors.component.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hiteshjoshi1/spring-boot-angular2/83da325097f123f4d99d02cfdc8f98ea7d1dec4c/heroClient/src/app/udemy/authors/authors.component.css -------------------------------------------------------------------------------- /heroClient/src/app/udemy/authors/authors.component.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 |
Author NameVotesPublished Reasearch
{{author.name}} {{author.publishedReasearcName}}
22 | 23 | 24 | 25 | 26 | 27 | Cost per head : {{post.cost|currency:'INR':true:'2.2-2'}} 28 | 29 | Release Date : {{post.releaseDate | date:'MM:dd:yyyy'}} 30 | 31 | 32 | 33 |
Back Street Boys
34 |
Everybody !
35 |
rock your body
36 |
-------------------------------------------------------------------------------- /heroClient/src/app/udemy/authors/authors.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { AuthorsComponent } from './authors.component'; 4 | 5 | describe('AuthorsComponent', () => { 6 | let component: AuthorsComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ AuthorsComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(AuthorsComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should be created', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /heroClient/src/app/udemy/authors/authors.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | import {AuthorService} from './../services/author.service'; 3 | import {Author} from './../models/author'; 4 | 5 | @Component({ 6 | selector: 'app-authors', 7 | templateUrl: './authors.component.html', 8 | styleUrls: ['./authors.component.css'] 9 | }) 10 | export class AuthorsComponent implements OnInit { 11 | 12 | authors:Author[]; 13 | post = { 14 | voteCount:10, 15 | myVote : 0, 16 | cost:100000, 17 | releaseDate: new Date() 18 | } 19 | 20 | 21 | constructor (authorService:AuthorService) { 22 | this.authors = authorService.getAuthors(); 23 | } 24 | 25 | 26 | ngOnInit() { 27 | } 28 | 29 | onVote($event){ 30 | console.log($event); 31 | } 32 | 33 | 34 | 35 | } 36 | -------------------------------------------------------------------------------- /heroClient/src/app/udemy/auto-grow.directive.spec.ts: -------------------------------------------------------------------------------- 1 | import { AutoGrowDirective } from './auto-grow.directive'; 2 | 3 | describe('AutoGrowDirective', () => { 4 | it('should create an instance', () => { 5 | const directive = new AutoGrowDirective(); 6 | expect(directive).toBeTruthy(); 7 | }); 8 | }); 9 | -------------------------------------------------------------------------------- /heroClient/src/app/udemy/auto-grow.directive.ts: -------------------------------------------------------------------------------- 1 | import { Directive, ElementRef,Renderer } from '@angular/core'; 2 | 3 | @Directive({ 4 | selector: '[appAutoGrow]', 5 | host:{ 6 | '(focus)':'onFocus()', 7 | '(blur)':'onBlur()' 8 | } 9 | }) 10 | export class AutoGrowDirective { 11 | 12 | constructor(private el:ElementRef, private renderer:Renderer){ 13 | 14 | } 15 | onFocus(){ 16 | this.renderer.setElementStyle(this.el.nativeElement,'backgroundColor','yellow'); 17 | } 18 | 19 | onBlur(){ 20 | this.renderer.setElementStyle(this.el.nativeElement,'width','100'); 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /heroClient/src/app/udemy/change-password/change-password.component.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hiteshjoshi1/spring-boot-angular2/83da325097f123f4d99d02cfdc8f98ea7d1dec4c/heroClient/src/app/udemy/change-password/change-password.component.css -------------------------------------------------------------------------------- /heroClient/src/app/udemy/change-password/change-password.component.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 | 5 | 8 | 9 | 10 |
Checking ol Password ...
11 | 12 |
13 |
14 | Old Password is required 15 |
16 | 17 |
18 | Old Password is incorrect. 19 |
20 | 21 |
22 | Old Password should atleast have {{form.controls.oldPassword.errors.minlength.requiredLength}} characters
23 |
24 |
25 |
26 | 27 | 30 | 31 | 32 | 33 |
34 |
35 | New Password is required 36 |
37 |
38 | New Password should atleast have {{form.controls.newPassword.errors.minlength.requiredLength}} characters 39 |
40 |
41 | New Passwords do not match 42 |
43 |
44 |
45 | 46 | 47 |
48 | 49 | 52 |
53 |
54 | Retype Password should atleast have {{form.controls.reTypePassword.errors.minlength.requiredLength}} characters 55 |
56 |
57 | New Passwords do not match 58 |
59 |
60 | 61 |
62 | 63 |
64 |
-------------------------------------------------------------------------------- /heroClient/src/app/udemy/change-password/change-password.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { ChangePasswordComponent } from './change-password.component'; 4 | 5 | describe('ChangePasswordComponent', () => { 6 | let component: ChangePasswordComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ ChangePasswordComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(ChangePasswordComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should be created', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /heroClient/src/app/udemy/change-password/change-password.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | import { FormControl, FormGroup, Validators, FormBuilder } from '@angular/forms'; 3 | import {PasswordValidator} from './../../validators/PasswordValidator'; 4 | import {IformComponent} from './../services/prevent-unsaved-changes.guard'; 5 | 6 | @Component({ 7 | selector: 'app-change-password', 8 | templateUrl: './change-password.component.html', 9 | styleUrls: ['./change-password.component.css'] 10 | }) 11 | export class ChangePasswordComponent implements OnInit,IformComponent { 12 | 13 | form: FormGroup; 14 | 15 | constructor(private formBuilder: FormBuilder) { 16 | this.createForm(); 17 | } 18 | 19 | createForm() { 20 | this.form = this.formBuilder.group({ 21 | oldPassword: ['', 22 | Validators.compose([ 23 | Validators.required, 24 | Validators.minLength(4)]), 25 | PasswordValidator.passwordCheck 26 | ], 27 | newPassword: ['', 28 | Validators.compose([ 29 | Validators.required, 30 | Validators.minLength(4)]) 31 | ], 32 | reTypePassword: ['', 33 | Validators.compose([ 34 | Validators.required, 35 | Validators.minLength(4)]) 36 | ] 37 | }); 38 | } 39 | 40 | ngOnInit() { 41 | } 42 | 43 | changePwd() { 44 | console.log(this.form); 45 | if (this.form.value.newPassword !== this.form.value.reTypePassword){ 46 | 47 | this.form.get('reTypePassword').setErrors ({ 48 | passwordMismatch: true 49 | }); 50 | 51 | } 52 | } 53 | 54 | hasUnsavedChanges(){ 55 | if (this.form.dirty){ 56 | return true; 57 | } 58 | return false; 59 | } 60 | 61 | } 62 | -------------------------------------------------------------------------------- /heroClient/src/app/udemy/contact-form/contact-form.component.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hiteshjoshi1/spring-boot-angular2/83da325097f123f4d99d02cfdc8f98ea7d1dec4c/heroClient/src/app/udemy/contact-form/contact-form.component.css -------------------------------------------------------------------------------- /heroClient/src/app/udemy/contact-form/contact-form.component.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 | 5 | 7 | 8 |
9 | {{ formErrors.name }} 10 |
11 | 19 | 20 |
21 |
22 | 23 | 24 | 25 |
26 | {{ formErrors.email }} 27 |
28 | 36 | 37 |
38 |
39 | 40 | 43 |
44 | 45 | 46 |
47 |
48 | 49 | -------------------------------------------------------------------------------- /heroClient/src/app/udemy/contact-form/contact-form.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { ContactFormComponent } from './contact-form.component'; 4 | 5 | describe('ContactFormComponent', () => { 6 | let component: ContactFormComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ ContactFormComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(ContactFormComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should be created', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /heroClient/src/app/udemy/contact-form/contact-form.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit, AfterViewChecked, ViewChild } from '@angular/core'; 2 | import { FormsModule, NgForm } from '@angular/forms'; 3 | import { Router, CanActivate } from '@angular/router'; 4 | import { IformComponent } from './../services/prevent-unsaved-changes.guard'; 5 | 6 | 7 | @Component({ 8 | selector: 'app-contact-form', 9 | templateUrl: './contact-form.component.html', 10 | styleUrls: ['./contact-form.component.css'] 11 | }) 12 | export class ContactFormComponent implements OnInit, AfterViewChecked, IformComponent { 13 | 14 | freequency: string[]= ['Daily', 'Weekly', 'Monthly']; 15 | 16 | constructor(private _router:Router) { } 17 | 18 | validationMessages = { 19 | 'name': { 20 | 'required': 'Name is required.', 21 | 'minlength': 'Name must be at least 4 characters long.', 22 | 'maxlength': 'Name cannot be more than 24 characters long.', 23 | }, 24 | 'email': { 25 | 'required': 'Email is required.', 26 | 'minlength': 'Email must be at least 4 characters long.', 27 | 'maxlength': 'Email cannot be more than 24 characters long.', 28 | }, 29 | 'freequency': { 30 | 'required': 'Freequency is required.' 31 | } 32 | }; 33 | 34 | formErrors = { 35 | 'name': '', 36 | 'email': '' 37 | }; 38 | 39 | subscribeForm: NgForm; 40 | 41 | @ViewChild('subscribeForm') currentForm: NgForm; 42 | 43 | ngAfterViewChecked() { 44 | this.formChanged(); 45 | } 46 | 47 | formChanged() { 48 | if (this.currentForm === this.subscribeForm) { return; } 49 | this.subscribeForm = this.currentForm; 50 | if (this.subscribeForm) { 51 | this.subscribeForm.valueChanges 52 | .subscribe(data => this.onValueChanged(data)); 53 | } 54 | } 55 | 56 | onValueChanged(data?: any) { 57 | if (!this.subscribeForm) { return; } 58 | const form = this.subscribeForm.form; 59 | 60 | for (const field in this.formErrors) { 61 | this.formErrors[field] = ''; 62 | const control = form.get(field); 63 | if (control && control.dirty && !control.valid) { 64 | const messages = this.validationMessages[field]; 65 | for (const key in control.errors) { 66 | this.formErrors[field] += messages[key] + ' '; 67 | } 68 | } 69 | } 70 | } 71 | 72 | // canDeactivate(next, previous) { 73 | // } 74 | 75 | 76 | ngOnInit() { 77 | } 78 | log(x) { 79 | console.log(x); 80 | } 81 | // Two ways to submit form 82 | onSubmit(form) { 83 | console.log(form); 84 | } 85 | 86 | onSumitSub(f) { 87 | // printing form 88 | console.log(f.value); 89 | // Navigating to a new Route on success of this one 90 | this._router.navigate(['tweets']); 91 | } 92 | 93 | hasUnsavedChanges(){ 94 | if (this.subscribeForm.dirty){ 95 | return true; 96 | } 97 | return false; 98 | } 99 | 100 | } 101 | -------------------------------------------------------------------------------- /heroClient/src/app/udemy/courses/courses.component.css: -------------------------------------------------------------------------------- 1 | 2 | 3 | /*.custom_bullet li::after{ 4 | content: "\e007"; 5 | font-family: 'Glyphicons Halflings'; 6 | font-size: 12px; 7 | float: left; 8 | margin-top: 4px; 9 | margin-left: -17px; 10 | color: #CCCCCC; 11 | }*/ 12 | 13 | /*.courses { 14 | width:110px; 15 | }*/ 16 | 17 | .nav-pills:hover{ 18 | cursor: pointer; 19 | 20 | } 21 | 22 | .nav-pills{ 23 | display: block; 24 | } 25 | .nav-pills li{ 26 | background-color: dodgerblue; 27 | 28 | } 29 | 30 | 31 | .nav-pills li a{ 32 | font-weight: bold; 33 | color: white; 34 | } 35 | .content{ 36 | display: block; 37 | } 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /heroClient/src/app/udemy/courses/courses.component.html: -------------------------------------------------------------------------------- 1 |

{{title}}

2 | 3 | 4 | 5 |
6 |
    7 |
  • 8 | 9 | 10 | {{i+1}}. {{course.name}} 11 |
  • 12 |
13 |
14 | 15 |

Demonstrating Switch Case

16 | 17 | 21 |
22 |
Map View Content Test
23 |
List View Content Test
24 |
25 | 26 | 27 | -------------------------------------------------------------------------------- /heroClient/src/app/udemy/courses/courses.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { CoursesComponent } from './courses.component'; 4 | 5 | describe('CoursesComponent', () => { 6 | let component: CoursesComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ CoursesComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(CoursesComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should be created', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /heroClient/src/app/udemy/courses/courses.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | import {CourseService} from './../services/course.service'; 3 | import {Course} from './../models/course'; 4 | import {Observable} from 'rxjs/Observable'; 5 | import 'rxjs/add/observable/interval'; // note that this is an observable and not an operator 6 | 7 | 8 | @Component({ 9 | selector: 'app-courses', 10 | templateUrl: './courses.component.html', 11 | styleUrls: ['./courses.component.css'] 12 | }) 13 | export class CoursesComponent implements OnInit { 14 | 15 | viewMode = 'map'; 16 | 17 | isActive = false; 18 | title:String = "Demonstrating Two Way Binding"; 19 | courses : Course []; 20 | constructor(private courseService: CourseService) { 21 | 22 | this.courses = courseService.getCourses(); 23 | } 24 | 25 | ngOnInit() { 26 | } 27 | 28 | onLike(courseLiked:number){ 29 | this.courses[courseLiked].clicked = !this.courses[courseLiked].clicked; 30 | } 31 | 32 | // explicit 2 way binding 33 | onType($event){ 34 | this.title= $event.target.value; 35 | } 36 | 37 | onClick(clicked){ 38 | this.viewMode = clicked; 39 | 40 | // --- The functionality is not related to Onclick -- 41 | // mechanism to create a polling mechanism 42 | // interval :- Emits ascending numbers, one every second (1000ms) 43 | const observable = Observable.interval(1000); 44 | 45 | // Now use this to call our service , every 1000ms 46 | observable.subscribe(y => { 47 | // console.log(y); 48 | // the service is actually a forkJoin. internaly calling two services 49 | // the result is an observable 50 | const x = this.courseService.makeParallelCallsWithObservable(); 51 | x.subscribe(val => { 52 | console.log(val[0]); 53 | console.log(val[1]); 54 | }, error => { 55 | // do something if it errors out 56 | console.log(error); 57 | 58 | }); 59 | //handling error by returning another observable or throwing an error 60 | // x.catch(error => {return Observable.of([1, 2, 3]); }); 61 | }); 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /heroClient/src/app/udemy/github-profile/github-profile.component.css: -------------------------------------------------------------------------------- 1 | .avatar{ 2 | width:200px; 3 | height:200px; 4 | /*border-radius: 100%;*/ 5 | 6 | } 7 | 8 | -------------------------------------------------------------------------------- /heroClient/src/app/udemy/github-profile/github-profile.component.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 | 5 | 6 | 7 | 8 | 9 |
10 |
11 |
{{results}}
12 |
13 |
14 | 15 | 16 |
17 |

@{{user.login}}

18 | 19 |
20 | 21 |
22 |

Followers

23 |
24 |

@{{f.login}}

25 |
26 |
27 |
28 | 29 | 30 |
-------------------------------------------------------------------------------- /heroClient/src/app/udemy/github-profile/github-profile.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { GithubProfileComponent } from './github-profile.component'; 4 | 5 | describe('GithubProfileComponent', () => { 6 | let component: GithubProfileComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ GithubProfileComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(GithubProfileComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should be created', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /heroClient/src/app/udemy/github-profile/github-profile.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | import {GithubService} from './../services/github.service'; 3 | import {GitHubUser} from './../models/githubprofile'; 4 | import {FormGroup, FormBuilder} from '@angular/forms'; 5 | 6 | @Component({ 7 | selector: 'app-github-profile', 8 | templateUrl: './github-profile.component.html', 9 | styleUrls: ['./github-profile.component.css'] 10 | }) 11 | export class GithubProfileComponent implements OnInit { 12 | // user = new GitHubUser() ; 13 | user = {}; 14 | followers = []; 15 | isLoading = false; 16 | 17 | gitForm: FormGroup; 18 | 19 | constructor( private _formBuilder: FormBuilder,private _githubService: GithubService) { 20 | this.gitForm = this._formBuilder.group({ 21 | gitHubId: [''] 22 | }); 23 | } 24 | 25 | ngOnInit() { 26 | // this._githubService.getUsersAndFollowers('octocat').subscribe(res => { 27 | 28 | // this.user = res[0]; 29 | // this.followers = res[1]; 30 | // this.isLoading = false; 31 | // }); 32 | } 33 | 34 | getUser(){ 35 | console.log(this.gitForm.value.gitHubId); 36 | this.isLoading = true; 37 | this._githubService.getUsersAndFollowers(this.gitForm.value.gitHubId).subscribe(res => { 38 | 39 | this.user = res[0]; 40 | this.followers = res[1]; 41 | this.isLoading = false; 42 | }); 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /heroClient/src/app/udemy/models/author.ts: -------------------------------------------------------------------------------- 1 | export class Author{ 2 | id:number; 3 | name:string; 4 | isPublished:boolean; 5 | publishedReasearcName:string; 6 | } -------------------------------------------------------------------------------- /heroClient/src/app/udemy/models/course.ts: -------------------------------------------------------------------------------- 1 | export class Course{ 2 | id:number; 3 | name:string; 4 | clicked:boolean; 5 | } -------------------------------------------------------------------------------- /heroClient/src/app/udemy/models/githubprofile.ts: -------------------------------------------------------------------------------- 1 | export interface GitHubUser { 2 | userHandle: string; 3 | userAvatar: string; 4 | followers ?: Followers[]; 5 | } 6 | 7 | export interface Followers { 8 | followerHandle: string; 9 | followerAvatar: string; 10 | } -------------------------------------------------------------------------------- /heroClient/src/app/udemy/services/auth.service.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed, inject } from '@angular/core/testing'; 2 | 3 | import { AuthService } from './auth.service'; 4 | 5 | describe('AuthService', () => { 6 | beforeEach(() => { 7 | TestBed.configureTestingModule({ 8 | providers: [AuthService] 9 | }); 10 | }); 11 | 12 | it('should be created', inject([AuthService], (service: AuthService) => { 13 | expect(service).toBeTruthy(); 14 | })); 15 | }); 16 | -------------------------------------------------------------------------------- /heroClient/src/app/udemy/services/auth.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | 3 | @Injectable() 4 | export class AuthService { 5 | 6 | isLoggedIn = true; 7 | constructor() { } 8 | 9 | 10 | login(userName, password) { 11 | this.isLoggedIn = true; 12 | } 13 | 14 | logOut(){ 15 | this.isLoggedIn = false; 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /heroClient/src/app/udemy/services/author.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | import {Author} from './../models/author'; 3 | 4 | @Injectable() 5 | export class AuthorService { 6 | 7 | constructor() { } 8 | 9 | public getAuthors():Author[]{ 10 | return [ 11 | { 12 | id:0, 13 | name:"Jason Bourne", 14 | isPublished:false, 15 | publishedReasearcName:null 16 | }, 17 | { 18 | id:1, 19 | name:"Aaron Swartz", 20 | isPublished:true, 21 | publishedReasearcName:"RSS Spec" 22 | }, 23 | { 24 | id:2, 25 | name:"Dijkistra", 26 | isPublished:true, 27 | publishedReasearcName:"MST Algo" 28 | } 29 | ]; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /heroClient/src/app/udemy/services/course.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | import {Course} from './../models/course'; 3 | import {Observable} from 'rxjs/Observable'; 4 | import 'rxjs/add/observable/of'; 5 | import 'rxjs/add/observable/forkJoin'; 6 | import 'rxjs/add/operator/delay'; 7 | 8 | @Injectable() 9 | export class CourseService { 10 | 11 | constructor() { } 12 | 13 | getCourses():Course[]{ 14 | 15 | return [ 16 | {id:0,name:"Emotional Intelligence",clicked:false}, 17 | {id:1,name:"Health",clicked:false}, 18 | {id:2,name:"Data Structures",clicked:false}, 19 | {id:3,name:"Algorithms",clicked:false} 20 | ]; 21 | } 22 | 23 | 24 | testObservable1(x:number): Observable{ 25 | return Observable.of(x++); 26 | } 27 | 28 | 29 | makeParallelCallsWithObservable():Observable{ 30 | 31 | // call to userData service 32 | var userDataCall = Observable.of({"userId":1, "userName":'mosh'}).delay(2000); 33 | 34 | var tweetCall = Observable.of([1, 2, 3, 4]).delay(1500); 35 | 36 | return Observable.forkJoin(userDataCall, tweetCall); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /heroClient/src/app/udemy/services/github.service.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed, inject } from '@angular/core/testing'; 2 | 3 | import { GithubService } from './github.service'; 4 | 5 | describe('GithubService', () => { 6 | beforeEach(() => { 7 | TestBed.configureTestingModule({ 8 | providers: [GithubService] 9 | }); 10 | }); 11 | 12 | it('should be created', inject([GithubService], (service: GithubService) => { 13 | expect(service).toBeTruthy(); 14 | })); 15 | }); 16 | -------------------------------------------------------------------------------- /heroClient/src/app/udemy/services/github.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | import {GitHubUser} from './../models/githubprofile'; 3 | import {Observable} from 'rxjs/Observable'; 4 | import {Http} from '@angular/http'; 5 | 6 | @Injectable() 7 | export class GithubService { 8 | private _base_uri = "https://api.github.com/users/"; 9 | constructor(private _http: Http) { } 10 | 11 | getUser(userId){ 12 | return this._http.get(this._base_uri+userId).map(res => res.json()); 13 | } 14 | getFollowers(userId){ 15 | return this._http.get(this._base_uri+userId+'/followers').map(res => res.json()); 16 | } 17 | 18 | getUsersAndFollowers(userId):Observable{ 19 | 20 | const obsv1 = this.getUser(userId); 21 | 22 | const obsv2 = this.getFollowers(userId); 23 | 24 | return Observable.forkJoin(obsv1, obsv2); 25 | 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /heroClient/src/app/udemy/services/prevent-unsaved-changes.guard.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed, async, inject } from '@angular/core/testing'; 2 | 3 | import { PreventUnsavedChangesGuard } from './prevent-unsaved-changes.guard'; 4 | 5 | describe('PreventUnsavedChangesGuard', () => { 6 | beforeEach(() => { 7 | TestBed.configureTestingModule({ 8 | providers: [PreventUnsavedChangesGuard] 9 | }); 10 | }); 11 | 12 | it('should ...', inject([PreventUnsavedChangesGuard], (guard: PreventUnsavedChangesGuard) => { 13 | expect(guard).toBeTruthy(); 14 | })); 15 | }); 16 | -------------------------------------------------------------------------------- /heroClient/src/app/udemy/services/prevent-unsaved-changes.guard.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | import { CanDeactivate, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router'; 3 | import { Observable } from 'rxjs/Observable'; 4 | import {ContactFormComponent} from './../contact-form/contact-form.component'; 5 | import {FormGroup} from '@angular/forms'; 6 | 7 | @Injectable() 8 | export class PreventUnsavedChangesGuard implements CanDeactivate { 9 | 10 | canDeactivate(component: IformComponent){ 11 | if(component.hasUnsavedChanges()){ 12 | return confirm("Are you Sure"); 13 | } 14 | else return true; 15 | 16 | } 17 | } 18 | 19 | export interface IformComponent { 20 | //Model driven form case 21 | // form: FormGroup; 22 | 23 | // generic case 24 | 25 | hasUnsavedChanges(): Boolean; 26 | 27 | } -------------------------------------------------------------------------------- /heroClient/src/app/udemy/services/spotify.service.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed, inject } from '@angular/core/testing'; 2 | 3 | import { SpotifyService } from './spotify.service'; 4 | 5 | describe('SpotifyService', () => { 6 | beforeEach(() => { 7 | TestBed.configureTestingModule({ 8 | providers: [SpotifyService] 9 | }); 10 | }); 11 | 12 | it('should be created', inject([SpotifyService], (service: SpotifyService) => { 13 | expect(service).toBeTruthy(); 14 | })); 15 | }); 16 | -------------------------------------------------------------------------------- /heroClient/src/app/udemy/services/spotify.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | import { Http, Response, URLSearchParams, RequestOptions,Headers } from '@angular/http'; 3 | import { Observable } from 'rxjs/Observable'; 4 | 5 | @Injectable() 6 | export class SpotifyService { 7 | private url = "https://jsonplaceholder.typicode.com/users?username="; 8 | constructor(private _http: Http) { } 9 | 10 | getArtists(searchStr: string): Observable{ 11 | console.log(searchStr); 12 | 13 | 14 | return this._http.get(this.url+searchStr).map(response => { 15 | console.log(response.json()); 16 | return response.json(); 17 | }); 18 | // { 19 | // console.log(response.json()); 20 | // return response.json(); 21 | // } 22 | 23 | } 24 | 25 | getHeroes(searchStr: string): Observable { 26 | const sUrl = this.url + searchStr; 27 | console.log(sUrl); 28 | return this._http.get(sUrl) 29 | .map(res => res.json()|| { } 30 | ); 31 | } 32 | 33 | 34 | 35 | 36 | private extractData(res: Response) { 37 | let body = res.json(); 38 | console.log(body); 39 | return body || { }; 40 | } 41 | 42 | 43 | private handleError (error: Response | any) { 44 | // In a real world app, you might use a remote logging infrastructure 45 | let errMsg: string; 46 | if (error instanceof Response) { 47 | const body = error.json() || ''; 48 | const err = body.error || JSON.stringify(body); 49 | errMsg = `${error.status} - ${error.statusText || ''} ${err}`; 50 | } else { 51 | errMsg = error.message ? error.message : error.toString(); 52 | } 53 | console.error(errMsg); 54 | return Observable.throw(errMsg); 55 | } 56 | 57 | } 58 | -------------------------------------------------------------------------------- /heroClient/src/app/udemy/spotify/spotify.component.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hiteshjoshi1/spring-boot-angular2/83da325097f123f4d99d02cfdc8f98ea7d1dec4c/heroClient/src/app/udemy/spotify/spotify.component.css -------------------------------------------------------------------------------- /heroClient/src/app/udemy/spotify/spotify.component.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 | 5 | 6 |
7 |
8 |
{{results}}
9 |
-------------------------------------------------------------------------------- /heroClient/src/app/udemy/spotify/spotify.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { SpotifyComponent } from './spotify.component'; 4 | 5 | describe('SpotifyComponent', () => { 6 | let component: SpotifyComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ SpotifyComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(SpotifyComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should be created', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /heroClient/src/app/udemy/spotify/spotify.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | import {FormGroup, FormBuilder} from '@angular/forms'; 3 | import {Observable} from 'rxJs/Observable'; 4 | import 'rxjs/add/operator/debounceTime'; 5 | import 'rxjs/add/operator/filter'; 6 | import 'rxjs/add/operator/distinctUntilChanged'; 7 | import { SpotifyService } from './../services/spotify.service'; 8 | // import 'rxjs/Rx'; 9 | 10 | @Component({ 11 | selector: 'app-spotify', 12 | templateUrl: './spotify.component.html', 13 | styleUrls: ['./spotify.component.css'] 14 | }) 15 | export class SpotifyComponent implements OnInit { 16 | 17 | spotifyForm: FormGroup; 18 | 19 | private results:string; 20 | 21 | constructor(private formBuilder: FormBuilder, private spotifyService: SpotifyService) { 22 | this.spotifyForm = this.formBuilder.group({ 23 | artistName: [''] 24 | }); 25 | 26 | 27 | 28 | const search = this.spotifyForm.get('artistName'); 29 | var keyup = search. 30 | valueChanges.debounceTime(500) 31 | .distinctUntilChanged() 32 | .map(str => (str).replace(' ', "-")) 33 | .filter(text => text.length >= 4) 34 | .map(searchTerm => { 35 | return this.spotifyService.getHeroes(searchTerm).subscribe(res => {this.results = res[0].name}); 36 | }); 37 | 38 | keyup.subscribe(res => { 39 | console.log(res); 40 | }); 41 | 42 | 43 | } 44 | ngOnInit() { 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /heroClient/src/app/udemy/udemy.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { CommonModule } from '@angular/common'; 3 | import { FormsModule } from '@angular/forms'; 4 | import { CoursesComponent } from './courses/courses.component'; 5 | import { CourseService } from './services/course.service'; 6 | import { AuthorsComponent } from './authors/authors.component'; 7 | import { AuthorService } from './services/author.service'; 8 | import { SpotifyService } from './services/spotify.service'; 9 | import { GithubService } from './services/github.service'; 10 | import { AutoGrowDirective } from './auto-grow.directive'; 11 | import { UtilModule } from './../util/util.module'; 12 | import { ContactFormComponent } from './contact-form/contact-form.component'; 13 | import { ChangePasswordComponent } from './change-password/change-password.component'; 14 | import { ReactiveFormsModule } from '@angular/forms'; 15 | import { SpotifyComponent } from './spotify/spotify.component'; 16 | import { GithubProfileComponent } from './github-profile/github-profile.component'; 17 | import { AuthGuard } from './../auth.guard'; 18 | import { AuthService } from './services/auth.service'; 19 | import { PreventUnsavedChangesGuard } from './services/prevent-unsaved-changes.guard'; 20 | 21 | 22 | 23 | @NgModule({ 24 | imports: [ 25 | CommonModule, FormsModule, UtilModule, ReactiveFormsModule 26 | ], 27 | declarations: [ 28 | CoursesComponent, ContactFormComponent, 29 | AuthorsComponent, AutoGrowDirective, 30 | ChangePasswordComponent, SpotifyComponent, 31 | GithubProfileComponent 32 | ], 33 | providers: [ 34 | CourseService, AuthorService, SpotifyService, 35 | GithubService, AuthGuard, AuthService, PreventUnsavedChangesGuard 36 | ], 37 | exports: [ 38 | AuthorsComponent, AutoGrowDirective, ContactFormComponent 39 | ] 40 | }) 41 | export class UdemyModule { } 42 | -------------------------------------------------------------------------------- /heroClient/src/app/udemy/udemy.routing.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { RouterModule, Routes } from '@angular/router'; 3 | 4 | 5 | import { CoursesComponent } from './../udemy/courses/courses.component'; 6 | import { TweetsComponent } from './../util/tweets/tweets.component'; 7 | import { AuthorsComponent } from './../udemy/authors/authors.component'; 8 | import { ContactFormComponent } from './../udemy/contact-form/contact-form.component'; 9 | 10 | import { ChangePasswordComponent } from './../udemy/change-password/change-password.component'; 11 | import { SpotifyComponent } from './../udemy/spotify/spotify.component'; 12 | import { GithubProfileComponent } from './../udemy/github-profile/github-profile.component'; 13 | import { AuthGuard } from './../auth.guard'; 14 | import { PreventUnsavedChangesGuard } from './services/prevent-unsaved-changes.guard'; 15 | 16 | // Create a Route Array 17 | const routes: Routes = [ 18 | { path: '', redirectTo: '/dashboard', pathMatch: 'full' }, 19 | { path: 'courses', component: CoursesComponent }, 20 | { path: 'authors', component: AuthorsComponent }, 21 | { path: 'contact', component: ContactFormComponent, 22 | canDeactivate: [PreventUnsavedChangesGuard]}, 23 | { path: 'changePwd', component: ChangePasswordComponent, 24 | canDeactivate: [PreventUnsavedChangesGuard] }, 25 | { path: 'spotify', component: SpotifyComponent, canActivate: [AuthGuard] }, 26 | { path: 'tweets', component: TweetsComponent }, 27 | { path: 'github', component: GithubProfileComponent } 28 | ]; 29 | 30 | // Router.forRoot returns a main Module only 31 | // for Child we need to use forChild 32 | @NgModule({ 33 | // because these route is a child 34 | imports: [RouterModule.forChild(routes)], 35 | exports: [RouterModule] 36 | }) 37 | export class UdemyRoutingModule { } 38 | -------------------------------------------------------------------------------- /heroClient/src/app/util/bs-panels/bs-panels.component.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hiteshjoshi1/spring-boot-angular2/83da325097f123f4d99d02cfdc8f98ea7d1dec4c/heroClient/src/app/util/bs-panels/bs-panels.component.css -------------------------------------------------------------------------------- /heroClient/src/app/util/bs-panels/bs-panels.component.html: -------------------------------------------------------------------------------- 1 | 2 |
3 |
4 | 5 |
6 |
7 | 8 |
9 |
10 | -------------------------------------------------------------------------------- /heroClient/src/app/util/bs-panels/bs-panels.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-bs-panels', 5 | templateUrl: './bs-panels.component.html', 6 | styleUrls: ['./bs-panels.component.css'] 7 | }) 8 | export class BootStrapPanelsComponent implements OnInit { 9 | 10 | constructor() { } 11 | 12 | ngOnInit() { 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /heroClient/src/app/util/favorite/favorite.component.css: -------------------------------------------------------------------------------- 1 | .glyphicon-star{ 2 | color:lightskyblue 3 | } 4 | 5 | -------------------------------------------------------------------------------- /heroClient/src/app/util/favorite/favorite.component.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | -------------------------------------------------------------------------------- /heroClient/src/app/util/favorite/favorite.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { FavoriteComponent } from './favorite.component'; 4 | 5 | describe('FavoriteComponent', () => { 6 | let component: FavoriteComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ FavoriteComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(FavoriteComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should be created', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /heroClient/src/app/util/favorite/favorite.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit, Input, Output,EventEmitter } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-favorite', 5 | templateUrl: './favorite.component.html', 6 | styleUrls: ['./favorite.component.css'] 7 | }) 8 | export class FavoriteComponent implements OnInit { 9 | 10 | @Input() isFavorite = false; 11 | 12 | @Output() evntEmitted = new EventEmitter(); 13 | constructor() { } 14 | 15 | ngOnInit() { 16 | } 17 | onFavorite(){ 18 | this.isFavorite= !this.isFavorite; 19 | this.evntEmitted.emit({newValue : this.isFavorite}); 20 | } 21 | 22 | 23 | 24 | } 25 | -------------------------------------------------------------------------------- /heroClient/src/app/util/heart/heart.component.css: -------------------------------------------------------------------------------- 1 | .glyphicon-heart{ 2 | color: #ccc; 3 | cursor: pointer; 4 | } 5 | .highlighted{ 6 | color:deeppink; 7 | } 8 | -------------------------------------------------------------------------------- /heroClient/src/app/util/heart/heart.component.html: -------------------------------------------------------------------------------- 1 | {{likes}} -------------------------------------------------------------------------------- /heroClient/src/app/util/heart/heart.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { HeartComponent } from './heart.component'; 4 | 5 | describe('HeartComponent', () => { 6 | let component: HeartComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ HeartComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(HeartComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should be created', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /heroClient/src/app/util/heart/heart.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit,Input } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-heart', 5 | templateUrl: './heart.component.html', 6 | styleUrls: ['./heart.component.css'] 7 | }) 8 | export class HeartComponent implements OnInit { 9 | 10 | @Input() likes:number = 0; 11 | clicked:boolean=false; 12 | constructor() { } 13 | 14 | ngOnInit() { 15 | } 16 | 17 | onHeartClick(){ 18 | this.clicked = !this.clicked; 19 | this.likes += this.clicked ? 1:-1; 20 | 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /heroClient/src/app/util/summarize.pipe.spec.ts: -------------------------------------------------------------------------------- 1 | import { SummarizePipe } from './summarize.pipe'; 2 | 3 | describe('SummarizePipe', () => { 4 | it('create an instance', () => { 5 | const pipe = new SummarizePipe(); 6 | expect(pipe).toBeTruthy(); 7 | }); 8 | }); 9 | -------------------------------------------------------------------------------- /heroClient/src/app/util/summarize.pipe.ts: -------------------------------------------------------------------------------- 1 | import { Pipe, PipeTransform } from '@angular/core'; 2 | 3 | @Pipe({ 4 | name: 'summarize' 5 | }) 6 | export class SummarizePipe implements PipeTransform { 7 | 8 | transform(value: string, limit: any): any { 9 | limit = (limit)?limit:30; 10 | console.log(limit); 11 | if(value){ 12 | return value.substring(0,limit)+"..."; 13 | } 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /heroClient/src/app/util/tweets/tweets.component.css: -------------------------------------------------------------------------------- 1 | .media-heading{ 2 | display: inline; 3 | } 4 | 5 | .span{ 6 | font-family: 'Lucida Sans', 'Lucida Sans Regular', 'Lucida Grande', 'Lucida Sans Unicode', Geneva, Verdana, sans-serifs 7 | } 8 | 9 | .zipp{ 10 | padding-top: 20px; 11 | } -------------------------------------------------------------------------------- /heroClient/src/app/util/tweets/tweets.component.html: -------------------------------------------------------------------------------- 1 | 2 |
3 |
4 |
5 | 6 | Image 7 | 8 |
9 |
10 |

{{tweet.authorName|uppercase}}

{{tweet.authorHandle}} 11 |

12 | 13 | {{tweet.tweetMesg | summarize}} 14 |

15 | 16 |
17 |
18 |
19 | 20 |
21 | Creating a Zippy Component 22 | 23 | 24 |
Body of content passed from Tweet html
25 | 26 |
Body of content passed from Tweet html Number 2
27 | 28 | 29 |
-------------------------------------------------------------------------------- /heroClient/src/app/util/tweets/tweets.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { TweetsComponent } from './tweets.component'; 4 | 5 | describe('TweetsComponent', () => { 6 | let component: TweetsComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ TweetsComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(TweetsComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should be created', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /heroClient/src/app/util/tweets/tweets.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | import { TweetService } from "./../../services/tweet.service"; 3 | import { Tweet } from "./../../models/tweet"; 4 | 5 | 6 | @Component({ 7 | selector: 'app-tweets', 8 | templateUrl: './tweets.component.html', 9 | styleUrls: ['./tweets.component.css'] 10 | }) 11 | export class TweetsComponent implements OnInit { 12 | 13 | constructor(private _tweetService:TweetService) { } 14 | 15 | ngOnInit() { 16 | this.getAllTweets(); 17 | } 18 | 19 | tweets : Tweet[]; 20 | 21 | getAllTweets(){ 22 | this.tweets = this._tweetService.getAllTweets(); 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /heroClient/src/app/util/util.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { CommonModule } from '@angular/common'; 3 | import {FavoriteComponent} from './favorite/favorite.component'; 4 | import { HeartComponent } from './heart/heart.component'; 5 | import { VoteComponent } from './vote/vote.component'; 6 | import { TweetsComponent } from './tweets/tweets.component'; 7 | import {TweetService} from './../services/tweet.service'; 8 | import {SummarizePipe} from './summarize.pipe'; 9 | import { BootStrapPanelsComponent } from './bs-panels/bs-panels.component'; 10 | import { ZippyComponent } from './zippy/zippy.component'; 11 | 12 | @NgModule({ 13 | imports: [ 14 | CommonModule 15 | ], 16 | declarations: [FavoriteComponent, HeartComponent, VoteComponent, TweetsComponent, 17 | SummarizePipe,BootStrapPanelsComponent, ZippyComponent], 18 | exports:[FavoriteComponent,HeartComponent,VoteComponent,SummarizePipe, 19 | BootStrapPanelsComponent,ZippyComponent], 20 | providers: [TweetService], 21 | }) 22 | export class UtilModule { } 23 | -------------------------------------------------------------------------------- /heroClient/src/app/util/vote/vote.component.css: -------------------------------------------------------------------------------- 1 | .votingDiv{ 2 | width:20px; 3 | text-align: center; 4 | color: #999; 5 | display: inline; 6 | } 7 | 8 | .vote-button{ 9 | cursor: pointer; 10 | } 11 | 12 | .voted{ 13 | color: orange 14 | } -------------------------------------------------------------------------------- /heroClient/src/app/util/vote/vote.component.html: -------------------------------------------------------------------------------- 1 |
2 | 3 | {{ voteCount+myVote }} 4 | 5 |
-------------------------------------------------------------------------------- /heroClient/src/app/util/vote/vote.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { VoteComponent } from './vote.component'; 4 | 5 | describe('VoteComponent', () => { 6 | let component: VoteComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ VoteComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(VoteComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should be created', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /heroClient/src/app/util/vote/vote.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit, Input, Output,EventEmitter } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-vote', 5 | templateUrl: './vote.component.html', 6 | styleUrls: ['./vote.component.css'] 7 | }) 8 | export class VoteComponent implements OnInit { 9 | 10 | constructor() { } 11 | 12 | @Input() voteCount = 0; 13 | 14 | @Input() myVote:number = 0; 15 | 16 | @Output() vote = new EventEmitter(); 17 | 18 | ngOnInit() { 19 | } 20 | onUpvoteClick(){ 21 | console.log('Upvoted'); 22 | if(this.myVote==1)return; 23 | 24 | this.myVote++; 25 | this.vote.emit({"myVote":this.myVote}); 26 | 27 | } 28 | 29 | onDownvoteClick(){ 30 | console.log('dwn voted'); 31 | if(this.myVote==-1)return; 32 | this.myVote--; 33 | this.vote.emit({"myVote":this.myVote}); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /heroClient/src/app/util/zippy/zippy.component.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hiteshjoshi1/spring-boot-angular2/83da325097f123f4d99d02cfdc8f98ea7d1dec4c/heroClient/src/app/util/zippy/zippy.component.css -------------------------------------------------------------------------------- /heroClient/src/app/util/zippy/zippy.component.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |

{{title}}

8 |
9 | 10 | 11 |
12 | 13 |
14 |
-------------------------------------------------------------------------------- /heroClient/src/app/util/zippy/zippy.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { ZippyComponent } from './zippy.component'; 4 | 5 | describe('ZippyComponent', () => { 6 | let component: ZippyComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ ZippyComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(ZippyComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should be created', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /heroClient/src/app/util/zippy/zippy.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit, Input } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-zippy', 5 | templateUrl: './zippy.component.html', 6 | styleUrls: ['./zippy.component.css'] 7 | }) 8 | export class ZippyComponent implements OnInit { 9 | 10 | isExpanded:boolean; 11 | 12 | @Input() title : string; 13 | 14 | constructor() { } 15 | 16 | ngOnInit() { 17 | } 18 | 19 | toggle(){ 20 | this.isExpanded = !this.isExpanded; 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /heroClient/src/app/validators/PasswordValidator.ts: -------------------------------------------------------------------------------- 1 | import {FormControl} from '@angular/forms'; 2 | 3 | export class PasswordValidator { 4 | static passwordCheck(control: FormControl) { 5 | return new Promise((resolve, reject) => { 6 | setTimeout(function(){ 7 | console.log(control.value); 8 | if(control.value != "Hitesh") { 9 | resolve({"incorrect":true}); 10 | } 11 | else { 12 | resolve(null); 13 | } 14 | }, 3000); 15 | }); 16 | } 17 | } -------------------------------------------------------------------------------- /heroClient/src/app/validators/UserNameValidator.ts: -------------------------------------------------------------------------------- 1 | import {FormControl} from '@angular/forms'; 2 | export class UserNameValidator{ 3 | 4 | static checkForSpaceInUserName(control: FormControl){ 5 | if (control.value.indexOf(' ') >= 0) { 6 | return{cannotContainSpace: true}; 7 | } 8 | return null; 9 | } 10 | static shouldbeUnique(control: FormControl){ 11 | return new Promise((resolve, reject) => { 12 | setTimeout(function(){ 13 | if(control.value === "Hitesh"){ 14 | resolve({"uniqueConstraintViolation":true}); 15 | } 16 | else { 17 | resolve(null); 18 | } 19 | }, 3000); 20 | }); 21 | } 22 | 23 | 24 | } -------------------------------------------------------------------------------- /heroClient/src/assets/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hiteshjoshi1/spring-boot-angular2/83da325097f123f4d99d02cfdc8f98ea7d1dec4c/heroClient/src/assets/.gitkeep -------------------------------------------------------------------------------- /heroClient/src/environments/environment.prod.ts: -------------------------------------------------------------------------------- 1 | export const environment = { 2 | production: true 3 | }; 4 | -------------------------------------------------------------------------------- /heroClient/src/environments/environment.ts: -------------------------------------------------------------------------------- 1 | // The file contents for the current environment will overwrite these during build. 2 | // The build system defaults to the dev environment which uses `environment.ts`, but if you do 3 | // `ng build --env=prod` then `environment.prod.ts` will be used instead. 4 | // The list of which env maps to which file can be found in `.angular-cli.json`. 5 | 6 | export const environment = { 7 | production: false 8 | }; 9 | -------------------------------------------------------------------------------- /heroClient/src/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hiteshjoshi1/spring-boot-angular2/83da325097f123f4d99d02cfdc8f98ea7d1dec4c/heroClient/src/favicon.ico -------------------------------------------------------------------------------- /heroClient/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | HeroClient 6 | 7 | 8 | 9 | 10 | 11 | 12 | Loading... 13 | 14 | 15 | -------------------------------------------------------------------------------- /heroClient/src/main.ts: -------------------------------------------------------------------------------- 1 | import { enableProdMode } from '@angular/core'; 2 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; 3 | 4 | import { AppModule } from './app/app.module'; 5 | import { environment } from './environments/environment'; 6 | 7 | if (environment.production) { 8 | enableProdMode(); 9 | } 10 | 11 | platformBrowserDynamic().bootstrapModule(AppModule); 12 | -------------------------------------------------------------------------------- /heroClient/src/polyfills.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This file includes polyfills needed by Angular and is loaded before the app. 3 | * You can add your own extra polyfills to this file. 4 | * 5 | * This file is divided into 2 sections: 6 | * 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers. 7 | * 2. Application imports. Files imported after ZoneJS that should be loaded before your main 8 | * file. 9 | * 10 | * The current setup is for so-called "evergreen" browsers; the last versions of browsers that 11 | * automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera), 12 | * Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile. 13 | * 14 | * Learn more in https://angular.io/docs/ts/latest/guide/browser-support.html 15 | */ 16 | 17 | /*************************************************************************************************** 18 | * BROWSER POLYFILLS 19 | */ 20 | 21 | /** IE9, IE10 and IE11 requires all of the following polyfills. **/ 22 | // import 'core-js/es6/symbol'; 23 | // import 'core-js/es6/object'; 24 | // import 'core-js/es6/function'; 25 | // import 'core-js/es6/parse-int'; 26 | // import 'core-js/es6/parse-float'; 27 | // import 'core-js/es6/number'; 28 | // import 'core-js/es6/math'; 29 | // import 'core-js/es6/string'; 30 | // import 'core-js/es6/date'; 31 | // import 'core-js/es6/array'; 32 | // import 'core-js/es6/regexp'; 33 | // import 'core-js/es6/map'; 34 | // import 'core-js/es6/set'; 35 | 36 | /** IE10 and IE11 requires the following for NgClass support on SVG elements */ 37 | // import 'classlist.js'; // Run `npm install --save classlist.js`. 38 | 39 | /** IE10 and IE11 requires the following to support `@angular/animation`. */ 40 | // import 'web-animations-js'; // Run `npm install --save web-animations-js`. 41 | 42 | 43 | /** Evergreen browsers require these. **/ 44 | import 'core-js/es6/reflect'; 45 | import 'core-js/es7/reflect'; 46 | 47 | 48 | /** ALL Firefox browsers require the following to support `@angular/animation`. **/ 49 | // import 'web-animations-js'; // Run `npm install --save web-animations-js`. 50 | 51 | 52 | 53 | /*************************************************************************************************** 54 | * Zone JS is required by Angular itself. 55 | */ 56 | import 'zone.js/dist/zone'; // Included with Angular CLI. 57 | 58 | 59 | 60 | /*************************************************************************************************** 61 | * APPLICATION IMPORTS 62 | */ 63 | 64 | /** 65 | * Date, currency, decimal and percent pipes. 66 | * Needed for: All but Chrome, Firefox, Edge, IE11 and Safari 10 67 | */ 68 | // import 'intl'; // Run `npm install --save intl`. 69 | /** 70 | * Need to import at least one locale-data with intl. 71 | */ 72 | // import 'intl/locale-data/jsonp/en'; 73 | -------------------------------------------------------------------------------- /heroClient/src/styles.css: -------------------------------------------------------------------------------- 1 | /* You can add global styles to this file, and also import other style files */ 2 | /* Master Styles */ 3 | @import url('https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css'); 4 | @import url('https://maxcdn.bootstrapcdn.com/font-awesome/4.4.0/css/font-awesome.min.css'); 5 | 6 | h1 { 7 | color: #369; 8 | font-family: Arial, Helvetica, sans-serif; 9 | font-size: 250%; 10 | } 11 | h2, h3 { 12 | color: #444; 13 | font-family: Arial, Helvetica, sans-serif; 14 | font-weight: lighter; 15 | font-size: 250%; 16 | } 17 | body { 18 | margin: 2em; 19 | } 20 | body, input[text], button { 21 | color: #888; 22 | font-family: Cambria, Georgia; 23 | } 24 | /* . . . */ 25 | /* everywhere else */ 26 | * { 27 | font-family: Arial, Helvetica, sans-serif; 28 | } 29 | 30 | .custom_bullet li { 31 | display: block; 32 | } 33 | 34 | .ng-dirty .ng-touched { 35 | border:1px solid red; 36 | } 37 | 38 | .ng-touched .ng-valid { 39 | border:1px solid lightskyblue; 40 | } 41 | 42 | -------------------------------------------------------------------------------- /heroClient/src/test.ts: -------------------------------------------------------------------------------- 1 | // This file is required by karma.conf.js and loads recursively all the .spec and framework files 2 | 3 | import 'zone.js/dist/long-stack-trace-zone'; 4 | import 'zone.js/dist/proxy.js'; 5 | import 'zone.js/dist/sync-test'; 6 | import 'zone.js/dist/jasmine-patch'; 7 | import 'zone.js/dist/async-test'; 8 | import 'zone.js/dist/fake-async-test'; 9 | import { getTestBed } from '@angular/core/testing'; 10 | import { 11 | BrowserDynamicTestingModule, 12 | platformBrowserDynamicTesting 13 | } from '@angular/platform-browser-dynamic/testing'; 14 | 15 | // Unfortunately there's no typing for the `__karma__` variable. Just declare it as any. 16 | declare var __karma__: any; 17 | declare var require: any; 18 | 19 | // Prevent Karma from running prematurely. 20 | __karma__.loaded = function () {}; 21 | 22 | // First, initialize the Angular testing environment. 23 | getTestBed().initTestEnvironment( 24 | BrowserDynamicTestingModule, 25 | platformBrowserDynamicTesting() 26 | ); 27 | // Then we find all the tests. 28 | const context = require.context('./', true, /\.spec\.ts$/); 29 | // And load the modules. 30 | context.keys().map(context); 31 | // Finally, start Karma to run the tests. 32 | __karma__.start(); 33 | -------------------------------------------------------------------------------- /heroClient/src/tsconfig.app.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../out-tsc/app", 5 | "module": "es2015", 6 | "baseUrl": "", 7 | "types": [] 8 | }, 9 | "exclude": [ 10 | "test.ts", 11 | "**/*.spec.ts" 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /heroClient/src/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../out-tsc/spec", 5 | "module": "commonjs", 6 | "target": "es5", 7 | "baseUrl": "", 8 | "types": [ 9 | "jasmine", 10 | "node" 11 | ] 12 | }, 13 | "files": [ 14 | "test.ts" 15 | ], 16 | "include": [ 17 | "**/*.spec.ts", 18 | "**/*.d.ts" 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /heroClient/src/typings.d.ts: -------------------------------------------------------------------------------- 1 | /* SystemJS module definition */ 2 | declare var module: NodeModule; 3 | interface NodeModule { 4 | id: string; 5 | } 6 | -------------------------------------------------------------------------------- /heroClient/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compileOnSave": false, 3 | "compilerOptions": { 4 | "outDir": "./dist/out-tsc", 5 | "baseUrl": "src", 6 | "sourceMap": true, 7 | "declaration": false, 8 | "moduleResolution": "node", 9 | "emitDecoratorMetadata": true, 10 | "experimentalDecorators": true, 11 | "target": "es5", 12 | "typeRoots": [ 13 | "node_modules/@types" 14 | ], 15 | "lib": [ 16 | "es2016", 17 | "dom" 18 | ] 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /heroClient/tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "rulesDirectory": [ 3 | "node_modules/codelyzer" 4 | ], 5 | "rules": { 6 | "callable-types": true, 7 | "class-name": true, 8 | "comment-format": [ 9 | true, 10 | "check-space" 11 | ], 12 | "curly": true, 13 | "eofline": true, 14 | "forin": true, 15 | "import-blacklist": [ 16 | true, 17 | "rxjs" 18 | ], 19 | "import-spacing": true, 20 | "indent": [ 21 | true, 22 | "spaces" 23 | ], 24 | "interface-over-type-literal": true, 25 | "label-position": true, 26 | "max-line-length": [ 27 | true, 28 | 140 29 | ], 30 | "member-access": false, 31 | "member-ordering": [ 32 | true, 33 | "static-before-instance", 34 | "variables-before-functions" 35 | ], 36 | "no-arg": true, 37 | "no-bitwise": true, 38 | "no-console": [ 39 | true, 40 | "debug", 41 | "info", 42 | "time", 43 | "timeEnd", 44 | "trace" 45 | ], 46 | "no-construct": true, 47 | "no-debugger": true, 48 | "no-empty": false, 49 | "no-empty-interface": true, 50 | "no-eval": true, 51 | "no-inferrable-types": [ 52 | true, 53 | "ignore-params" 54 | ], 55 | "no-shadowed-variable": true, 56 | "no-string-literal": false, 57 | "no-string-throw": true, 58 | "no-switch-case-fall-through": true, 59 | "no-trailing-whitespace": true, 60 | "no-unused-expression": true, 61 | "no-use-before-declare": true, 62 | "no-var-keyword": true, 63 | "object-literal-sort-keys": false, 64 | "one-line": [ 65 | true, 66 | "check-open-brace", 67 | "check-catch", 68 | "check-else", 69 | "check-whitespace" 70 | ], 71 | "prefer-const": true, 72 | "quotemark": [ 73 | true, 74 | "single" 75 | ], 76 | "radix": true, 77 | "semicolon": [ 78 | "always" 79 | ], 80 | "triple-equals": [ 81 | true, 82 | "allow-null-check" 83 | ], 84 | "typedef-whitespace": [ 85 | true, 86 | { 87 | "call-signature": "nospace", 88 | "index-signature": "nospace", 89 | "parameter": "nospace", 90 | "property-declaration": "nospace", 91 | "variable-declaration": "nospace" 92 | } 93 | ], 94 | "typeof-compare": true, 95 | "unified-signatures": true, 96 | "variable-name": false, 97 | "whitespace": [ 98 | true, 99 | "check-branch", 100 | "check-decl", 101 | "check-operator", 102 | "check-separator", 103 | "check-type" 104 | ], 105 | "directive-selector": [ 106 | true, 107 | "attribute", 108 | "app", 109 | "camelCase" 110 | ], 111 | "component-selector": [ 112 | true, 113 | "element", 114 | "app", 115 | "kebab-case" 116 | ], 117 | "use-input-property-decorator": true, 118 | "use-output-property-decorator": true, 119 | "use-host-property-decorator": true, 120 | "no-input-rename": true, 121 | "no-output-rename": true, 122 | "use-life-cycle-interface": true, 123 | "use-pipe-transform-interface": true, 124 | "component-class-suffix": true, 125 | "directive-class-suffix": true, 126 | "no-access-missing-member": true, 127 | "templates-use-public": true, 128 | "invoke-injectable": true 129 | } 130 | } 131 | -------------------------------------------------------------------------------- /heroWeb/.gitignore: -------------------------------------------------------------------------------- 1 | target/ 2 | !.mvn/wrapper/maven-wrapper.jar 3 | 4 | ### STS ### 5 | .apt_generated 6 | .classpath 7 | .factorypath 8 | .project 9 | .settings 10 | .springBeans 11 | 12 | ### IntelliJ IDEA ### 13 | .idea 14 | *.iws 15 | *.iml 16 | *.ipr 17 | 18 | ### NetBeans ### 19 | nbproject/private/ 20 | build/ 21 | nbbuild/ 22 | dist/ 23 | nbdist/ 24 | .nb-gradle/ -------------------------------------------------------------------------------- /heroWeb/mvnw.cmd: -------------------------------------------------------------------------------- 1 | @REM ---------------------------------------------------------------------------- 2 | @REM Licensed to the Apache Software Foundation (ASF) under one 3 | @REM or more contributor license agreements. See the NOTICE file 4 | @REM distributed with this work for additional information 5 | @REM regarding copyright ownership. The ASF licenses this file 6 | @REM to you under the Apache License, Version 2.0 (the 7 | @REM "License"); you may not use this file except in compliance 8 | @REM with the License. You may obtain a copy of the License at 9 | @REM 10 | @REM http://www.apache.org/licenses/LICENSE-2.0 11 | @REM 12 | @REM Unless required by applicable law or agreed to in writing, 13 | @REM software distributed under the License is distributed on an 14 | @REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | @REM KIND, either express or implied. See the License for the 16 | @REM specific language governing permissions and limitations 17 | @REM under the License. 18 | @REM ---------------------------------------------------------------------------- 19 | 20 | @REM ---------------------------------------------------------------------------- 21 | @REM Maven2 Start Up Batch script 22 | @REM 23 | @REM Required ENV vars: 24 | @REM JAVA_HOME - location of a JDK home dir 25 | @REM 26 | @REM Optional ENV vars 27 | @REM M2_HOME - location of maven2's installed home dir 28 | @REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands 29 | @REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending 30 | @REM MAVEN_OPTS - parameters passed to the Java VM when running Maven 31 | @REM e.g. to debug Maven itself, use 32 | @REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 33 | @REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files 34 | @REM ---------------------------------------------------------------------------- 35 | 36 | @REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' 37 | @echo off 38 | @REM enable echoing my setting MAVEN_BATCH_ECHO to 'on' 39 | @if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% 40 | 41 | @REM set %HOME% to equivalent of $HOME 42 | if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") 43 | 44 | @REM Execute a user defined script before this one 45 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre 46 | @REM check for pre script, once with legacy .bat ending and once with .cmd ending 47 | if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" 48 | if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" 49 | :skipRcPre 50 | 51 | @setlocal 52 | 53 | set ERROR_CODE=0 54 | 55 | @REM To isolate internal variables from possible post scripts, we use another setlocal 56 | @setlocal 57 | 58 | @REM ==== START VALIDATION ==== 59 | if not "%JAVA_HOME%" == "" goto OkJHome 60 | 61 | echo. 62 | echo Error: JAVA_HOME not found in your environment. >&2 63 | echo Please set the JAVA_HOME variable in your environment to match the >&2 64 | echo location of your Java installation. >&2 65 | echo. 66 | goto error 67 | 68 | :OkJHome 69 | if exist "%JAVA_HOME%\bin\java.exe" goto init 70 | 71 | echo. 72 | echo Error: JAVA_HOME is set to an invalid directory. >&2 73 | echo JAVA_HOME = "%JAVA_HOME%" >&2 74 | echo Please set the JAVA_HOME variable in your environment to match the >&2 75 | echo location of your Java installation. >&2 76 | echo. 77 | goto error 78 | 79 | @REM ==== END VALIDATION ==== 80 | 81 | :init 82 | 83 | @REM Find the project base dir, i.e. the directory that contains the folder ".mvn". 84 | @REM Fallback to current working directory if not found. 85 | 86 | set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% 87 | IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir 88 | 89 | set EXEC_DIR=%CD% 90 | set WDIR=%EXEC_DIR% 91 | :findBaseDir 92 | IF EXIST "%WDIR%"\.mvn goto baseDirFound 93 | cd .. 94 | IF "%WDIR%"=="%CD%" goto baseDirNotFound 95 | set WDIR=%CD% 96 | goto findBaseDir 97 | 98 | :baseDirFound 99 | set MAVEN_PROJECTBASEDIR=%WDIR% 100 | cd "%EXEC_DIR%" 101 | goto endDetectBaseDir 102 | 103 | :baseDirNotFound 104 | set MAVEN_PROJECTBASEDIR=%EXEC_DIR% 105 | cd "%EXEC_DIR%" 106 | 107 | :endDetectBaseDir 108 | 109 | IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig 110 | 111 | @setlocal EnableExtensions EnableDelayedExpansion 112 | for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a 113 | @endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% 114 | 115 | :endReadAdditionalConfig 116 | 117 | SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" 118 | 119 | set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" 120 | set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 121 | 122 | %MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* 123 | if ERRORLEVEL 1 goto error 124 | goto end 125 | 126 | :error 127 | set ERROR_CODE=1 128 | 129 | :end 130 | @endlocal & set ERROR_CODE=%ERROR_CODE% 131 | 132 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost 133 | @REM check for post script, once with legacy .bat ending and once with .cmd ending 134 | if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" 135 | if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" 136 | :skipRcPost 137 | 138 | @REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' 139 | if "%MAVEN_BATCH_PAUSE%" == "on" pause 140 | 141 | if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% 142 | 143 | exit /B %ERROR_CODE% 144 | -------------------------------------------------------------------------------- /heroWeb/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | heroesWeb 7 | war 8 | 9 | Heroes WebApp 10 | Demo project for Spring Boot 11 | 12 | 13 | 14 | com.hitesh.boot 15 | heroes 16 | ${project.version} 17 | 18 | 19 | 20 | 21 | 22 | 23 | com.hitesh.boot 24 | heroClient 25 | ${project.version} 26 | 27 | 28 | org.springframework.boot 29 | spring-boot-starter-actuator 30 | 31 | 32 | org.springframework.boot 33 | spring-boot-starter-data-jpa 34 | 35 | 36 | org.springframework.boot 37 | spring-boot-starter-thymeleaf 38 | 39 | 40 | org.springframework.boot 41 | spring-boot-starter-web 42 | 43 | 44 | 45 | com.h2database 46 | h2 47 | runtime 48 | 49 | 50 | org.springframework.boot 51 | spring-boot-starter-test 52 | test 53 | 54 | 55 | com.thoughtworks.xstream 56 | xstream 57 | 1.4.9 58 | 59 | 60 | org.springframework.boot 61 | spring-boot-starter-security 62 | 63 | 64 | 65 | org.springframework.cloud 66 | spring-cloud-starter-eureka 67 | 68 | 69 | io.springfox 70 | springfox-swagger2 71 | 2.6.0 72 | compile 73 | 74 | 75 | io.springfox 76 | springfox-swagger-ui 77 | 2.6.1 78 | compile 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | org.springframework.boot 88 | spring-boot-maven-plugin 89 | 90 | 91 | 92 | 93 | 94 | 95 | -------------------------------------------------------------------------------- /heroWeb/src/main/java/com/hitesh/boot/heroes/HeroesApplication.java: -------------------------------------------------------------------------------- 1 | package com.hitesh.boot.heroes; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.boot.autoconfigure.web.HttpMessageConverters; 6 | import org.springframework.boot.web.client.RestTemplateBuilder; 7 | import org.springframework.boot.web.support.SpringBootServletInitializer; 8 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient; 9 | import org.springframework.cloud.client.loadbalancer.LoadBalanced; 10 | import org.springframework.context.annotation.Bean; 11 | import org.springframework.data.jpa.repository.config.EnableJpaRepositories; 12 | import org.springframework.http.converter.ByteArrayHttpMessageConverter; 13 | import org.springframework.web.client.RestTemplate; 14 | 15 | 16 | 17 | 18 | @SpringBootApplication(scanBasePackages={"com.hitesh.boot.heroes"}) 19 | @EnableJpaRepositories(basePackages = "com.hitesh.boot.heroes.data.repository") 20 | @EnableDiscoveryClient 21 | public class HeroesApplication extends SpringBootServletInitializer { 22 | 23 | // @Autowired 24 | // private DiscoveryClient discoveryClient; 25 | 26 | public static void main(String[] args) { 27 | System.setProperty("spring.config.name", "heroes-server"); 28 | SpringApplication.run(HeroesApplication.class, args); 29 | } 30 | @Bean 31 | public HttpMessageConverters customConverters() { 32 | ByteArrayHttpMessageConverter arrayHttpMessageConverter = new ByteArrayHttpMessageConverter(); 33 | return new HttpMessageConverters(arrayHttpMessageConverter); 34 | } 35 | 36 | // Case insensitive: could also use: http://accounts-service 37 | public static final String CHALLENGE_SERVICE_URL 38 | = "http://CHALLENGES-SERVICE"; 39 | 40 | // @RequestMapping("/service-instances/{applicationName}") 41 | // public List serviceInstancesByApplicationName( 42 | // @PathVariable String applicationName) { 43 | // return this.discoveryClient.getInstances(applicationName); 44 | // } 45 | @LoadBalanced 46 | @Bean 47 | RestTemplate restTemplate() { 48 | return new RestTemplate(); 49 | } 50 | 51 | 52 | 53 | } 54 | -------------------------------------------------------------------------------- /heroWeb/src/main/java/com/hitesh/boot/heroes/data/entity/Challenge.java: -------------------------------------------------------------------------------- 1 | package com.hitesh.boot.heroes.data.entity; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | import com.fasterxml.jackson.annotation.JsonAnyGetter; 6 | import com.fasterxml.jackson.annotation.JsonAnySetter; 7 | import com.fasterxml.jackson.annotation.JsonIgnore; 8 | import com.fasterxml.jackson.annotation.JsonInclude; 9 | import com.fasterxml.jackson.annotation.JsonProperty; 10 | import com.fasterxml.jackson.annotation.JsonPropertyOrder; 11 | 12 | @JsonInclude(JsonInclude.Include.NON_NULL) 13 | @JsonPropertyOrder({ 14 | "challengesId", 15 | "challengeName", 16 | "challengeLevel", 17 | "maxNumOfHeroes" 18 | }) 19 | public class Challenge { 20 | 21 | 22 | @JsonProperty("challengesId") 23 | private Integer challengesId; 24 | @JsonProperty("challengeName") 25 | private String challengeName; 26 | @JsonProperty("challengeLevel") 27 | private Integer challengeLevel; 28 | @JsonProperty("maxNumOfHeroes") 29 | private Integer maxNumOfHeroes; 30 | @JsonIgnore 31 | private Map additionalProperties = new HashMap(); 32 | 33 | @JsonProperty("challengesId") 34 | public Integer getChallengesId() { 35 | return challengesId; 36 | } 37 | 38 | @JsonProperty("challengesId") 39 | public void setChallengesId(Integer challengesId) { 40 | this.challengesId = challengesId; 41 | } 42 | 43 | @JsonProperty("challengeName") 44 | public String getChallengeName() { 45 | return challengeName; 46 | } 47 | 48 | @JsonProperty("challengeName") 49 | public void setChallengeName(String challengeName) { 50 | this.challengeName = challengeName; 51 | } 52 | 53 | @JsonProperty("challengeLevel") 54 | public Integer getChallengeLevel() { 55 | return challengeLevel; 56 | } 57 | 58 | @JsonProperty("challengeLevel") 59 | public void setChallengeLevel(Integer challengeLevel) { 60 | this.challengeLevel = challengeLevel; 61 | } 62 | 63 | @JsonProperty("maxNumOfHeroes") 64 | public Integer getMaxNumOfHeroes() { 65 | return maxNumOfHeroes; 66 | } 67 | 68 | @JsonProperty("maxNumOfHeroes") 69 | public void setMaxNumOfHeroes(Integer maxNumOfHeroes) { 70 | this.maxNumOfHeroes = maxNumOfHeroes; 71 | } 72 | 73 | @JsonAnyGetter 74 | public Map getAdditionalProperties() { 75 | return this.additionalProperties; 76 | } 77 | 78 | @JsonAnySetter 79 | public void setAdditionalProperty(String name, Object value) { 80 | this.additionalProperties.put(name, value); 81 | } 82 | /* (non-Javadoc) 83 | * @see java.lang.Object#hashCode() 84 | */ 85 | @Override 86 | public int hashCode() { 87 | final int prime = 31; 88 | int result = 1; 89 | result = prime * result + ((additionalProperties == null) ? 0 : additionalProperties.hashCode()); 90 | result = prime * result + ((challengeLevel == null) ? 0 : challengeLevel.hashCode()); 91 | result = prime * result + ((challengeName == null) ? 0 : challengeName.hashCode()); 92 | result = prime * result + ((challengesId == null) ? 0 : challengesId.hashCode()); 93 | result = prime * result + ((maxNumOfHeroes == null) ? 0 : maxNumOfHeroes.hashCode()); 94 | return result; 95 | } 96 | 97 | /* (non-Javadoc) 98 | * @see java.lang.Object#equals(java.lang.Object) 99 | */ 100 | @Override 101 | public boolean equals(Object obj) { 102 | if (this == obj) 103 | return true; 104 | if (obj == null) 105 | return false; 106 | if (getClass() != obj.getClass()) 107 | return false; 108 | Challenge other = (Challenge)obj; 109 | if (additionalProperties == null) { 110 | if (other.additionalProperties != null) 111 | return false; 112 | } 113 | else if (!additionalProperties.equals(other.additionalProperties)) 114 | return false; 115 | if (challengeLevel == null) { 116 | if (other.challengeLevel != null) 117 | return false; 118 | } 119 | else if (!challengeLevel.equals(other.challengeLevel)) 120 | return false; 121 | if (challengeName == null) { 122 | if (other.challengeName != null) 123 | return false; 124 | } 125 | else if (!challengeName.equals(other.challengeName)) 126 | return false; 127 | if (challengesId == null) { 128 | if (other.challengesId != null) 129 | return false; 130 | } 131 | else if (!challengesId.equals(other.challengesId)) 132 | return false; 133 | if (maxNumOfHeroes == null) { 134 | if (other.maxNumOfHeroes != null) 135 | return false; 136 | } 137 | else if (!maxNumOfHeroes.equals(other.maxNumOfHeroes)) 138 | return false; 139 | return true; 140 | } 141 | 142 | /* (non-Javadoc) 143 | * @see java.lang.Object#toString() 144 | */ 145 | @Override 146 | public String toString() { 147 | StringBuilder builder = new StringBuilder(); 148 | builder.append("Challenge [challengesId=").append(challengesId).append(", challengeName=") 149 | .append(challengeName).append(", challengeLevel=").append(challengeLevel) 150 | .append(", maxNumOfHeroes=").append(maxNumOfHeroes).append(", additionalProperties=") 151 | .append(additionalProperties).append("]"); 152 | return builder.toString(); 153 | } 154 | 155 | } 156 | -------------------------------------------------------------------------------- /heroWeb/src/main/java/com/hitesh/boot/heroes/data/entity/Guest.java: -------------------------------------------------------------------------------- 1 | package com.hitesh.boot.heroes.data.entity; 2 | 3 | 4 | 5 | import javax.persistence.Column; 6 | import javax.persistence.Entity; 7 | import javax.persistence.GeneratedValue; 8 | import javax.persistence.GenerationType; 9 | import javax.persistence.Id; 10 | import javax.persistence.Table; 11 | 12 | @Entity 13 | @Table(name="GUEST") 14 | public class Guest { 15 | @Id 16 | @GeneratedValue(strategy = GenerationType.AUTO) 17 | @Column(name="GUEST_ID") 18 | private long id; 19 | @Column(name="FIRST_NAME") 20 | private String firstName; 21 | @Column(name="LAST_NAME") 22 | private String lastName; 23 | @Column(name="EMAIL_ADDRESS") 24 | private String emailAddress; 25 | @Column(name="ADDRESS") 26 | private String address; 27 | @Column(name="COUNTRY") 28 | private String country; 29 | @Column(name="STATE") 30 | private String state; 31 | @Column(name="PHONE_NUMBER") 32 | private String phoneNumber; 33 | 34 | public long getId() { 35 | return id; 36 | } 37 | 38 | public void setId(long id) { 39 | this.id = id; 40 | } 41 | 42 | public String getFirstName() { 43 | return firstName; 44 | } 45 | 46 | public void setFirstName(String firstName) { 47 | this.firstName = firstName; 48 | } 49 | 50 | public String getLastName() { 51 | return lastName; 52 | } 53 | 54 | public void setLastName(String lastName) { 55 | this.lastName = lastName; 56 | } 57 | 58 | public String getEmailAddress() { 59 | return emailAddress; 60 | } 61 | 62 | public void setEmailAddress(String emailAddress) { 63 | this.emailAddress = emailAddress; 64 | } 65 | 66 | public String getAddress() { 67 | return address; 68 | } 69 | 70 | public void setAddress(String address) { 71 | this.address = address; 72 | } 73 | 74 | public String getCountry() { 75 | return country; 76 | } 77 | 78 | public void setCountry(String country) { 79 | this.country = country; 80 | } 81 | 82 | public String getState() { 83 | return state; 84 | } 85 | 86 | public void setState(String state) { 87 | this.state = state; 88 | } 89 | 90 | public String getPhoneNumber() { 91 | return phoneNumber; 92 | } 93 | 94 | public void setPhoneNumber(String phoneNumber) { 95 | this.phoneNumber = phoneNumber; 96 | } 97 | } -------------------------------------------------------------------------------- /heroWeb/src/main/java/com/hitesh/boot/heroes/data/entity/Hero.java: -------------------------------------------------------------------------------- 1 | package com.hitesh.boot.heroes.data.entity; 2 | 3 | import javax.persistence.Column; 4 | import javax.persistence.Entity; 5 | import javax.persistence.GeneratedValue; 6 | import javax.persistence.GenerationType; 7 | import javax.persistence.Id; 8 | import javax.persistence.Table; 9 | 10 | @Entity 11 | @Table(name = "HERO") 12 | public class Hero { 13 | 14 | @Id 15 | @Column(name = "ID") 16 | @GeneratedValue(strategy = GenerationType.AUTO) 17 | private long id; 18 | @Column(name = "NAME") 19 | private String name; 20 | 21 | @Column(name = "CHALLENGE_LEVEL") 22 | private int challengeLevel; 23 | 24 | /** 25 | * @return the challengeLevel 26 | */ 27 | public int getChallengeLevel() { 28 | return challengeLevel; 29 | } 30 | 31 | /** 32 | * @param challengeLevel the challengeLevel to set 33 | */ 34 | public void setChallengeLevel(int challengeLevel) { 35 | this.challengeLevel = challengeLevel; 36 | } 37 | 38 | /* 39 | * (non-Javadoc) 40 | * 41 | * @see java.lang.Object#toString() 42 | */ 43 | @Override 44 | public String toString() { 45 | StringBuilder builder = new StringBuilder(); 46 | builder.append("Hero [id=").append(id).append(", name=").append(name).append("]"); 47 | return builder.toString(); 48 | } 49 | 50 | /* 51 | * (non-Javadoc) 52 | * 53 | * @see java.lang.Object#hashCode() 54 | */ 55 | @Override 56 | public int hashCode() { 57 | final int prime = 31; 58 | int result = 1; 59 | result = prime * result + (int) (id ^ (id >>> 32)); 60 | result = prime * result + ((name == null) ? 0 : name.hashCode()); 61 | return result; 62 | } 63 | 64 | /* 65 | * (non-Javadoc) 66 | * 67 | * @see java.lang.Object#equals(java.lang.Object) 68 | */ 69 | @Override 70 | public boolean equals(Object obj) { 71 | if (this == obj) 72 | return true; 73 | if (obj == null) 74 | return false; 75 | if (getClass() != obj.getClass()) 76 | return false; 77 | Hero other = (Hero) obj; 78 | if (id != other.id) 79 | return false; 80 | if (name == null) { 81 | if (other.name != null) 82 | return false; 83 | } else if (!name.equals(other.name)) 84 | return false; 85 | return true; 86 | } 87 | 88 | /** 89 | * @return the id 90 | */ 91 | public long getId() { 92 | return id; 93 | } 94 | 95 | /** 96 | * @param id 97 | * the id to set 98 | */ 99 | public void setId(long id) { 100 | this.id = id; 101 | } 102 | 103 | /** 104 | * @return the name 105 | */ 106 | public String getName() { 107 | return name; 108 | } 109 | 110 | /** 111 | * @param name 112 | * the name to set 113 | */ 114 | public void setName(String name) { 115 | this.name = name; 116 | } 117 | 118 | } 119 | -------------------------------------------------------------------------------- /heroWeb/src/main/java/com/hitesh/boot/heroes/data/entity/Reservation.java: -------------------------------------------------------------------------------- 1 | package com.hitesh.boot.heroes.data.entity; 2 | 3 | 4 | 5 | import javax.persistence.Column; 6 | import javax.persistence.Entity; 7 | import javax.persistence.GeneratedValue; 8 | import javax.persistence.GenerationType; 9 | import javax.persistence.Id; 10 | import javax.persistence.Table; 11 | import java.sql.Date; 12 | 13 | @Entity 14 | @Table(name="RESERVATION") 15 | public class Reservation { 16 | 17 | @Id 18 | @GeneratedValue(strategy = GenerationType.AUTO) 19 | @Column(name="RESERVATION_ID") 20 | private long id; 21 | @Column(name="ROOM_ID") 22 | private long roomId; 23 | @Column(name="GUEST_ID") 24 | private long guestId; 25 | @Column(name="RES_DATE") 26 | private Date date; 27 | 28 | public long getId() { 29 | return id; 30 | } 31 | 32 | public void setId(long id) { 33 | this.id = id; 34 | } 35 | 36 | public long getRoomId() { 37 | return roomId; 38 | } 39 | 40 | public void setRoomId(long roomId) { 41 | this.roomId = roomId; 42 | } 43 | 44 | public long getGuestId() { 45 | return guestId; 46 | } 47 | 48 | public void setGuestId(long guestId) { 49 | this.guestId = guestId; 50 | } 51 | 52 | public Date getDate() { 53 | return date; 54 | } 55 | 56 | public void setDate(Date date) { 57 | this.date = date; 58 | } 59 | } -------------------------------------------------------------------------------- /heroWeb/src/main/java/com/hitesh/boot/heroes/data/entity/Room.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.hitesh.boot.heroes.data.entity; 5 | 6 | import javax.persistence.Column; 7 | import javax.persistence.Entity; 8 | import javax.persistence.GeneratedValue; 9 | import javax.persistence.GenerationType; 10 | import javax.persistence.Id; 11 | import javax.persistence.Table; 12 | 13 | /** 14 | * @author hitjoshi 15 | * 16 | */ 17 | 18 | 19 | @Entity 20 | @Table(name="ROOM") 21 | public class Room { 22 | @Id 23 | @Column(name="ROOM_ID") 24 | @GeneratedValue(strategy= GenerationType.AUTO) 25 | private long id; 26 | @Column(name="NAME") 27 | private String name; 28 | @Column(name="ROOM_NUMBER") 29 | private String number; 30 | @Column(name="BED_INFO") 31 | private String bedInfo; 32 | 33 | public long getId() { 34 | return id; 35 | } 36 | 37 | public void setId(long id) { 38 | this.id = id; 39 | } 40 | 41 | public String getName() { 42 | return name; 43 | } 44 | 45 | public void setName(String name) { 46 | this.name = name; 47 | } 48 | 49 | public String getNumber() { 50 | return number; 51 | } 52 | 53 | public void setNumber(String number) { 54 | this.number = number; 55 | } 56 | 57 | public String getBedInfo() { 58 | return bedInfo; 59 | } 60 | 61 | public void setBedInfo(String bedInfo) { 62 | this.bedInfo = bedInfo; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /heroWeb/src/main/java/com/hitesh/boot/heroes/data/repository/GuestRepository.java: -------------------------------------------------------------------------------- 1 | package com.hitesh.boot.heroes.data.repository; 2 | 3 | import org.springframework.data.repository.PagingAndSortingRepository; 4 | import org.springframework.stereotype.Repository; 5 | 6 | import com.hitesh.boot.heroes.data.entity.Guest; 7 | 8 | @Repository 9 | public interface GuestRepository extends PagingAndSortingRepository { 10 | 11 | } -------------------------------------------------------------------------------- /heroWeb/src/main/java/com/hitesh/boot/heroes/data/repository/HeroRepository.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.hitesh.boot.heroes.data.repository; 5 | 6 | import java.util.List; 7 | 8 | import org.springframework.data.repository.CrudRepository; 9 | 10 | import com.hitesh.boot.heroes.data.entity.Hero; 11 | 12 | /** 13 | * @author hitjoshi 14 | * 15 | */ 16 | public interface HeroRepository extends CrudRepository{ 17 | Hero findById(long id); 18 | List findByChallengeLevel(int challengeLevel); 19 | } 20 | 21 | 22 | -------------------------------------------------------------------------------- /heroWeb/src/main/java/com/hitesh/boot/heroes/data/repository/ReservationRepository.java: -------------------------------------------------------------------------------- 1 | package com.hitesh.boot.heroes.data.repository; 2 | 3 | 4 | 5 | import java.sql.Date; 6 | import java.util.List; 7 | 8 | import org.springframework.data.repository.CrudRepository; 9 | import org.springframework.stereotype.Repository; 10 | 11 | import com.hitesh.boot.heroes.data.entity.Reservation; 12 | 13 | @Repository 14 | public interface ReservationRepository extends CrudRepository { 15 | List findByDate(Date date); 16 | } -------------------------------------------------------------------------------- /heroWeb/src/main/java/com/hitesh/boot/heroes/data/repository/RoomRepository.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.hitesh.boot.heroes.data.repository; 5 | 6 | import org.springframework.data.repository.CrudRepository; 7 | import org.springframework.stereotype.Repository; 8 | 9 | import com.hitesh.boot.heroes.data.entity.Room; 10 | 11 | /** 12 | * @author hitjoshi 13 | * 14 | */ 15 | @Repository 16 | public interface RoomRepository extends CrudRepository{ 17 | Room findByNumber(String number); 18 | } 19 | -------------------------------------------------------------------------------- /heroWeb/src/main/java/com/hitesh/boot/heroes/facade/IAuthenticationFacade.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.hitesh.boot.heroes.facade; 5 | 6 | import org.springframework.security.core.Authentication; 7 | 8 | /** 9 | * @author hitjoshi 10 | * 11 | */ 12 | public interface IAuthenticationFacade { 13 | Authentication getAuthentication(); 14 | } 15 | -------------------------------------------------------------------------------- /heroWeb/src/main/java/com/hitesh/boot/heroes/security/AppInfoContributor.java: -------------------------------------------------------------------------------- 1 | package com.hitesh.boot.heroes.security; 2 | 3 | import java.util.Collections; 4 | 5 | import org.springframework.boot.actuate.info.Info; 6 | import org.springframework.boot.actuate.info.InfoContributor; 7 | import org.springframework.stereotype.Component; 8 | 9 | @Component 10 | public class AppInfoContributor implements InfoContributor { 11 | 12 | @Override 13 | public void contribute(Info.Builder builder) { 14 | builder.withDetail("example", Collections.singletonMap("Hitesh", "Test")); 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /heroWeb/src/main/java/com/hitesh/boot/heroes/security/AuthenticationFacade.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.hitesh.boot.heroes.security; 5 | 6 | import org.springframework.security.core.Authentication; 7 | import org.springframework.security.core.context.SecurityContextHolder; 8 | import org.springframework.stereotype.Component; 9 | 10 | import com.hitesh.boot.heroes.facade.IAuthenticationFacade; 11 | 12 | /** 13 | * @author hitjoshi 14 | * 15 | */ 16 | @Component 17 | public class AuthenticationFacade implements IAuthenticationFacade { 18 | 19 | /* (non-Javadoc) 20 | * @see com.hitesh.boot.heroes.facade.IAuthenticationFacade#getAuthentication() 21 | */ 22 | @Override 23 | public Authentication getAuthentication() { 24 | return SecurityContextHolder.getContext().getAuthentication(); 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /heroWeb/src/main/java/com/hitesh/boot/heroes/security/SecurityConfiguration.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.hitesh.boot.heroes.security; 5 | 6 | import org.springframework.boot.autoconfigure.security.SecurityProperties; 7 | import org.springframework.context.annotation.Configuration; 8 | import org.springframework.core.annotation.Order; 9 | import org.springframework.security.config.annotation.web.builders.HttpSecurity; 10 | import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; 11 | import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; 12 | import org.springframework.security.web.csrf.CookieCsrfTokenRepository; 13 | 14 | /** 15 | * @author hitjoshi 16 | * 17 | */ 18 | @Configuration 19 | @EnableWebSecurity 20 | @Order(SecurityProperties.ACCESS_OVERRIDE_ORDER) 21 | public class SecurityConfiguration extends WebSecurityConfigurerAdapter { 22 | @Override 23 | protected void configure(HttpSecurity http) throws Exception { 24 | http.authorizeRequests().antMatchers("/info").permitAll().and() 25 | .httpBasic() 26 | .and() 27 | .authorizeRequests() 28 | .antMatchers("/index.html", "/home.html", "/login.html", "/").permitAll() 29 | .anyRequest().authenticated().and() 30 | .csrf() 31 | .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()); 32 | } 33 | } 34 | 35 | -------------------------------------------------------------------------------- /heroWeb/src/main/java/com/hitesh/boot/heroes/service/HeroChallengeService.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.hitesh.boot.heroes.service; 5 | 6 | 7 | import java.util.Arrays; 8 | import java.util.List; 9 | import java.util.logging.Logger; 10 | 11 | import org.springframework.beans.factory.annotation.Autowired; 12 | import org.springframework.cloud.client.loadbalancer.LoadBalanced; 13 | import org.springframework.stereotype.Service; 14 | import org.springframework.web.client.RestTemplate; 15 | 16 | import com.hitesh.boot.heroes.data.entity.Challenge; 17 | 18 | /** 19 | * @author hitjoshi 20 | * 21 | */ 22 | @Service 23 | public class HeroChallengeService { 24 | 25 | @Autowired 26 | @LoadBalanced 27 | protected RestTemplate restTemplate; 28 | 29 | protected Logger logger = Logger.getLogger(HeroChallengeService.class 30 | .getName()); 31 | 32 | /** 33 | * Service that calls external API 34 | * Referred by a Logical Name 35 | * @param challengeLevel 36 | * @return 37 | */ 38 | public List findByChallengeLevel(String challengeLevel) { 39 | Challenge [] challenges = null; 40 | String serviceUrl = "http://CHALLENGES-SERVICE"; 41 | logger.info("findByNumber() invoked: for " + challengeLevel); 42 | challenges = restTemplate.getForObject(serviceUrl + "/api/challenges/{number}", 43 | Challenge[].class, challengeLevel); 44 | if (challenges == null || challenges.length == 0) 45 | return null; 46 | else 47 | return Arrays.asList(challenges); 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /heroWeb/src/main/java/com/hitesh/boot/heroes/service/ReservationService.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.hitesh.boot.heroes.service; 5 | 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.stereotype.Service; 8 | 9 | import com.hitesh.boot.heroes.data.repository.GuestRepository; 10 | import com.hitesh.boot.heroes.data.repository.ReservationRepository; 11 | import com.hitesh.boot.heroes.data.repository.RoomRepository; 12 | 13 | /** 14 | * @author hitjoshi 15 | * 16 | */ 17 | @Service 18 | public class ReservationService { 19 | private RoomRepository roomRepository; 20 | private GuestRepository guestRepository; 21 | private ReservationRepository reservationRepository; 22 | 23 | @Autowired 24 | public ReservationService(RoomRepository roomRepository, GuestRepository guestRepository, 25 | ReservationRepository reservationRepository) { 26 | this.roomRepository = roomRepository; 27 | this.guestRepository = guestRepository; 28 | this.reservationRepository = reservationRepository; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /heroWeb/src/main/java/com/hitesh/boot/heroes/swagger/SwaggerConfig.java: -------------------------------------------------------------------------------- 1 | package com.hitesh.boot.heroes.swagger; 2 | 3 | import org.springframework.boot.autoconfigure.EnableAutoConfiguration; 4 | import org.springframework.context.annotation.Bean; 5 | import org.springframework.context.annotation.Configuration; 6 | 7 | import springfox.documentation.builders.PathSelectors; 8 | import springfox.documentation.builders.RequestHandlerSelectors; 9 | import springfox.documentation.spi.DocumentationType; 10 | import springfox.documentation.spring.web.plugins.Docket; 11 | import springfox.documentation.swagger2.annotations.EnableSwagger2; 12 | 13 | @Configuration 14 | @EnableSwagger2 15 | @EnableAutoConfiguration 16 | public class SwaggerConfig { 17 | @Bean 18 | public Docket api() { 19 | return new Docket(DocumentationType.SWAGGER_2) 20 | .select() 21 | .apis(RequestHandlerSelectors.basePackage("com.hitesh.boot.heroes.webservice")) 22 | .paths(PathSelectors.any()).build(); 23 | } 24 | } -------------------------------------------------------------------------------- /heroWeb/src/main/java/com/hitesh/boot/heroes/webservice/AuthController.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.hitesh.boot.heroes.webservice; 5 | 6 | import java.security.Principal; 7 | import java.util.Collection; 8 | 9 | import org.springframework.beans.factory.annotation.Autowired; 10 | import org.springframework.beans.factory.annotation.Qualifier; 11 | import org.springframework.security.core.Authentication; 12 | import org.springframework.security.core.GrantedAuthority; 13 | import org.springframework.web.bind.annotation.RequestMapping; 14 | import org.springframework.web.bind.annotation.RequestMethod; 15 | import org.springframework.web.bind.annotation.RestController; 16 | 17 | import com.hitesh.boot.heroes.facade.IAuthenticationFacade; 18 | 19 | /** 20 | * @author hitjoshi 21 | * 22 | */ 23 | @RestController 24 | @RequestMapping(value = "/api/auth") 25 | public class AuthController { 26 | @Autowired 27 | @Qualifier("authenticationFacade") 28 | private IAuthenticationFacade authenticationFacade; 29 | 30 | @RequestMapping(value = "/roles", method = RequestMethod.GET) 31 | public Collection currentUserNameSimple() { 32 | Authentication authentication = authenticationFacade.getAuthentication(); 33 | Collection c = authentication.getAuthorities(); 34 | // GrantedAuthority 35 | // System.out.println(c.toArray(a)); 36 | System.out.println(c.toString()); 37 | return c; 38 | } 39 | @RequestMapping(value="/user",method= RequestMethod.GET) 40 | public Principal user(Principal user) { 41 | return user; 42 | } 43 | 44 | 45 | 46 | } 47 | -------------------------------------------------------------------------------- /heroWeb/src/main/java/com/hitesh/boot/heroes/webservice/DownloadPDFController.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.hitesh.boot.heroes.webservice; 5 | 6 | import java.io.IOException; 7 | 8 | import org.springframework.core.io.ClassPathResource; 9 | import org.springframework.core.io.InputStreamResource; 10 | import org.springframework.http.HttpHeaders; 11 | import org.springframework.http.MediaType; 12 | import org.springframework.http.ResponseEntity; 13 | import org.springframework.web.bind.annotation.CrossOrigin; 14 | import org.springframework.web.bind.annotation.RequestMapping; 15 | import org.springframework.web.bind.annotation.RequestMethod; 16 | import org.springframework.web.bind.annotation.RequestParam; 17 | import org.springframework.web.bind.annotation.RestController; 18 | 19 | /** 20 | * @author hitjoshi 21 | * Sample to show how to do a file download with Spring Boot and Angular 22 | */ 23 | @RestController 24 | public class DownloadPDFController { 25 | // don't use cross orgin in actual App 26 | @CrossOrigin 27 | @RequestMapping(value = "/file", method = RequestMethod.GET, produces = "application/pdf") 28 | public ResponseEntity downloadPdfFile(@RequestParam("data") String itemId) throws IOException { 29 | ClassPathResource pdfFile = new ClassPathResource("test.pdf"); 30 | 31 | HttpHeaders headers = new HttpHeaders(); 32 | headers.add("Cache-Control", "no-cache, no-store, must-revalidate"); 33 | headers.add("Pragma", "no-cache"); 34 | headers.add("Expires", "0"); 35 | 36 | return ResponseEntity.ok().headers(headers).contentLength(pdfFile.contentLength()) 37 | .contentType(MediaType.parseMediaType("application/pdf")) 38 | .body(new InputStreamResource(pdfFile.getInputStream())); 39 | 40 | } 41 | 42 | } -------------------------------------------------------------------------------- /heroWeb/src/main/java/com/hitesh/boot/heroes/webservice/HeroController.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.hitesh.boot.heroes.webservice; 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.logging.Logger; 11 | 12 | import org.springframework.beans.factory.annotation.Autowired; 13 | import org.springframework.web.bind.annotation.CrossOrigin; 14 | import org.springframework.web.bind.annotation.PathVariable; 15 | import org.springframework.web.bind.annotation.RequestBody; 16 | import org.springframework.web.bind.annotation.RequestMapping; 17 | import org.springframework.web.bind.annotation.RequestMethod; 18 | import org.springframework.web.bind.annotation.RequestParam; 19 | import org.springframework.web.bind.annotation.RestController; 20 | 21 | import com.hitesh.boot.heroes.data.entity.Challenge; 22 | import com.hitesh.boot.heroes.data.entity.Hero; 23 | import com.hitesh.boot.heroes.data.repository.HeroRepository; 24 | import com.hitesh.boot.heroes.service.HeroChallengeService; 25 | 26 | import io.swagger.annotations.Api; 27 | 28 | /** 29 | * @author hitjoshi 30 | * 31 | */ 32 | @CrossOrigin("*") 33 | @RestController 34 | @Api(value="heroAPI",description="For All your Superhero needs" ) 35 | public class HeroController { 36 | 37 | protected Logger logger = Logger.getLogger(HeroController.class 38 | .getName()); 39 | 40 | @Autowired 41 | private HeroRepository heroRepository; 42 | 43 | @Autowired 44 | protected HeroChallengeService heroChallengeService; 45 | 46 | 47 | @CrossOrigin("*") 48 | @RequestMapping(value="/heroes", method= RequestMethod.GET, produces = "application/json") 49 | public List findAll(@RequestParam(required=false) String heroId){ 50 | List heroes = new ArrayList(); 51 | if(null==heroId){ 52 | Iterable results = this.heroRepository.findAll(); 53 | results.forEach(hero-> {heroes.add(hero);}); 54 | }else{ 55 | long id = Long.parseLong(heroId); 56 | Hero hero = this.heroRepository.findById(id); 57 | if(null!=hero) { 58 | heroes.add(hero); 59 | } 60 | } 61 | return heroes; 62 | } 63 | @CrossOrigin 64 | @RequestMapping(value="/heroes", method= RequestMethod.PUT,produces = "application/json",consumes = "application/json") 65 | public Hero updateHero(@RequestBody Hero hero){ 66 | if(hero== null){ 67 | return null; 68 | } 69 | else{ 70 | Hero dbHero = this.heroRepository.findById(hero.getId()); 71 | System.out.println(dbHero); 72 | dbHero.setName(hero.getName()); 73 | return this.heroRepository.save(dbHero); 74 | } 75 | 76 | } 77 | 78 | @CrossOrigin 79 | @RequestMapping(value="/heroes", method= RequestMethod.POST,produces = "application/json",consumes = "application/json") 80 | public Hero addHero(@RequestBody Hero hero){ 81 | if(hero== null){ 82 | return null; 83 | } 84 | else{ 85 | Hero dbHero = new Hero(); 86 | dbHero.setName(hero.getName()); 87 | Hero test = this.heroRepository.save(dbHero); 88 | System.out.println(test); 89 | return test; 90 | } 91 | } 92 | 93 | @CrossOrigin 94 | @RequestMapping(value="/heroes/{id}", method= RequestMethod.DELETE,produces = "application/json") 95 | public boolean deleteHero(@PathVariable("id") String heroId){ 96 | if(null!=heroId){ 97 | System.out.println("hero Id "+heroId); 98 | Long id = Long.valueOf(heroId); 99 | Hero hero = this.heroRepository.findById(id); 100 | this.heroRepository.delete(hero); 101 | return true; 102 | 103 | }else{ 104 | return false; 105 | } 106 | 107 | } 108 | 109 | /** 110 | * This method depends on Another API deployed as another microservice. 111 | * The other API URL is not hard coded anywhere in the application 112 | * Instead its a logical name, which this Eureka client uses to get the actual URL from Euerka Server 113 | * Example - http://CHALLENGES-SERVICE 114 | * Even when one of the instance goes down, the API will not go down 115 | * @param challengeLevel 116 | * @return 117 | */ 118 | @CrossOrigin 119 | @RequestMapping(value="/heroes/{level}", method= RequestMethod.GET,produces = "application/json") 120 | public Map> getChallengesByHeroLevel(@PathVariable("level") String challengeLevel){ 121 | List challengeList = heroChallengeService.findByChallengeLevel(challengeLevel); 122 | List heroList = this.heroRepository.findByChallengeLevel(Integer.parseInt(challengeLevel)); 123 | Map> map = new HashMap<>(); 124 | for(Challenge challenge: challengeList){ 125 | map.put(challenge,heroList); 126 | } 127 | return map; 128 | } 129 | 130 | } 131 | -------------------------------------------------------------------------------- /heroWeb/src/main/java/com/hitesh/boot/heroes/webservice/RoomController.java: -------------------------------------------------------------------------------- 1 | package com.hitesh.boot.heroes.webservice; 2 | 3 | 4 | import java.util.ArrayList; 5 | import java.util.List; 6 | 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.web.bind.annotation.RequestMapping; 9 | import org.springframework.web.bind.annotation.RequestMethod; 10 | import org.springframework.web.bind.annotation.RequestParam; 11 | import org.springframework.web.bind.annotation.RestController; 12 | 13 | import com.hitesh.boot.heroes.data.entity.Room; 14 | import com.hitesh.boot.heroes.data.repository.RoomRepository; 15 | @RestController 16 | public class RoomController { 17 | @Autowired 18 | private RoomRepository repository; 19 | 20 | @RequestMapping(value="/rooms", method= RequestMethod.GET, produces = "application/json") 21 | List findAll(@RequestParam(required=false) String roomNumber){ 22 | System.out.println("HItesh Joshi ---------------------------------> "+roomNumber); 23 | List rooms = new ArrayList<>(); 24 | if(null==roomNumber){ 25 | Iterable results = this.repository.findAll(); 26 | results.forEach(room-> {rooms.add(room);}); 27 | }else{ 28 | Room room = this.repository.findByNumber(roomNumber); 29 | if(null!=room) { 30 | System.out.println(room); 31 | rooms.add(room); 32 | } 33 | } 34 | return rooms; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /heroWeb/src/main/resources/bootstrap.yml: -------------------------------------------------------------------------------- 1 | eureka: 2 | instance: 3 | non-secure-port: ${server.port:2222} 4 | statusPageUrlPath: /swagger-ui.html 5 | leaseRenewalIntervalInSeconds: 5 6 | client: 7 | serviceUrl: 8 | defaultZone: http://localhost:1111/eureka/ 9 | 10 | -------------------------------------------------------------------------------- /heroWeb/src/main/resources/heroes-server.yml: -------------------------------------------------------------------------------- 1 | # Spring properties 2 | spring: 3 | application: 4 | name: heroes-service # Service registers under this name 5 | freemarker: 6 | enabled: false # Ignore Eureka dashboard FreeMarker templates 7 | datasource: 8 | initialize: true 9 | jpa: 10 | hibernate: 11 | ddl-auto: none 12 | 13 | 14 | 15 | # Map the error path to error template (for Thymeleaf) 16 | error: 17 | path: /error 18 | 19 | # HTTP Server 20 | server: 21 | port: 2222 22 | display-name: Heroes 23 | statusPageUrlPath: /heroes 24 | 25 | #eureka: 26 | # client: 27 | # serviceUrl: 28 | # defaultZone: http://localhost:1111/eureka/ 29 | # instance: 30 | # leaseRenewalIntervalInSeconds: 5 # DO NOT DO THIS IN PRODUCTION 31 | 32 | 33 | # 3. If using the Angel release-train ONLY, give the process a unique instance id 34 | # so that multiple instances can register when running on SAME host. This is 35 | # not needed since release-train Brixton. 36 | # NOTE-1: spring.application.instance_id is only set when run on Cloud Foundry, 37 | # so we fallback on the server-port when it is not defined 38 | # NOTE-2: Syntax ${x:${y}} = use $x if set, otherwise use $y 39 | # metadataMap: 40 | # instanceId: ${spring.application.name}:${spring.application.instance_id:${server.port}} 41 | security: 42 | user: 43 | password: password 44 | 45 | #--- 46 | #spring: 47 | # profiles: cloud 48 | #eureka: 49 | # instance: 50 | # hostname: ${APPLICATION_DOMAIN} 51 | # nonSecurePort: 80 52 | 53 | -------------------------------------------------------------------------------- /heroWeb/src/main/resources/schema.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE ROOM( 2 | ROOM_ID BIGINT AUTO_INCREMENT PRIMARY KEY, 3 | NAME VARCHAR(16) NOT NULL, 4 | ROOM_NUMBER CHAR(2) NOT NULL UNIQUE, 5 | BED_INFO CHAR(2) NOT NULL 6 | ); 7 | 8 | CREATE TABLE GUEST( 9 | GUEST_ID BIGINT AUTO_INCREMENT PRIMARY KEY, 10 | FIRST_NAME VARCHAR(64), 11 | LAST_NAME VARCHAR(64), 12 | EMAIL_ADDRESS VARCHAR(64), 13 | ADDRESS VARCHAR(64), 14 | COUNTRY VARCHAR(32), 15 | STATE VARCHAR(12), 16 | PHONE_NUMBER VARCHAR(24) 17 | ); 18 | 19 | CREATE TABLE RESERVATION( 20 | RESERVATION_ID BIGINT AUTO_INCREMENT PRIMARY KEY, 21 | ROOM_ID BIGINT NOT NULL, 22 | GUEST_ID BIGINT NOT NULL, 23 | RES_DATE DATE 24 | ); 25 | 26 | CREATE TABLE HERO( 27 | ID BIGINT AUTO_INCREMENT PRIMARY KEY, 28 | NAME VARCHAR(64), 29 | CHALLENGE_LEVEL BIGINT 30 | ); 31 | 32 | 33 | 34 | ALTER TABLE RESERVATION ADD FOREIGN KEY (ROOM_ID) REFERENCES ROOM(ROOM_ID); 35 | ALTER TABLE RESERVATION ADD FOREIGN KEY (GUEST_ID) REFERENCES GUEST(GUEST_ID); 36 | CREATE INDEX IDX_RES_DATE_ ON RESERVATION(RES_DATE); 37 | -------------------------------------------------------------------------------- /heroWeb/src/main/resources/static/hello_world_app.component.ts: -------------------------------------------------------------------------------- 1 | import {Component, View} from "angular2/core"; 2 | 3 | @Component({ 4 | selector: 'my-app' 5 | }) 6 | 7 | @View({ 8 | template: '

Hello World !!

' 9 | }) 10 | 11 | export class MyHelloWorldClass { 12 | 13 | } -------------------------------------------------------------------------------- /heroWeb/src/main/resources/static/hello_world_main.ts: -------------------------------------------------------------------------------- 1 | import {bootstrap} from "angular2/platform/browser" 2 | import {MyHelloWorldClass} from "./hello_world_app.component" 3 | 4 | bootstrap(MyHelloWorldClass); -------------------------------------------------------------------------------- /heroWeb/src/main/resources/static/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Welcome to reservations ! 6 | 7 | 8 | 9 |

Hello There

10 | Download 11 | 12 | -------------------------------------------------------------------------------- /heroWeb/src/main/resources/test.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hiteshjoshi1/spring-boot-angular2/83da325097f123f4d99d02cfdc8f98ea7d1dec4c/heroWeb/src/main/resources/test.pdf -------------------------------------------------------------------------------- /heroWeb/src/test/java/com/hitesh/boot/reservations/ReservationsApplicationTests.java: -------------------------------------------------------------------------------- 1 | //package com.hitesh.boot.reservations; 2 | // 3 | //import org.junit.Test; 4 | //import org.junit.runner.RunWith; 5 | //import org.springframework.boot.test.context.SpringBootTest; 6 | //import org.springframework.test.context.junit4.SpringRunner; 7 | // 8 | //@RunWith(SpringRunner.class) 9 | //@SpringBootTest 10 | //public class ReservationsApplicationTests { 11 | // 12 | // @Test 13 | // public void contextLoads() { 14 | // } 15 | // 16 | //} 17 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | 5 | org.springframework.boot 6 | spring-boot-starter-parent 7 | 1.5.3.RELEASE 8 | 9 | 10 | 11 | com.hitesh.boot 12 | heroes 13 | ${project.version} 14 | pom 15 | 16 | heroesParent 17 | Demo project for Spring Boot 18 | 19 | 20 | heroWeb 21 | heroClient 22 | serviceRegistration 23 | challengesWeb 24 | zuulGateway 25 | 26 | 27 | 28 | UTF-8 29 | UTF-8 30 | 1.8 31 | 0.0.1-SNAPSHOT 32 | 33 | 34 | 35 | 36 | 37 | spring-snapshot 38 | Spring Snapshot Repository 39 | http://repo.spring.io/snapshot 40 | 41 | 42 | 43 | 44 | 45 | org.springframework.boot 46 | spring-boot-devtools 47 | 48 | 49 | 50 | 51 | 52 | 53 | org.springframework.cloud 54 | spring-cloud-dependencies 55 | Camden.SR6 56 | pom 57 | import 58 | 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /serviceRegistration/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /serviceRegistration/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | serviceRegistration 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.wst.common.project.facet.core.builder 10 | 11 | 12 | 13 | 14 | org.eclipse.jdt.core.javabuilder 15 | 16 | 17 | 18 | 19 | org.springframework.ide.eclipse.core.springbuilder 20 | 21 | 22 | 23 | 24 | org.eclipse.wst.validation.validationbuilder 25 | 26 | 27 | 28 | 29 | org.eclipse.m2e.core.maven2Builder 30 | 31 | 32 | 33 | 34 | 35 | org.eclipse.jem.workbench.JavaEMFNature 36 | org.eclipse.wst.common.modulecore.ModuleCoreNature 37 | org.springframework.ide.eclipse.core.springnature 38 | org.eclipse.jdt.core.javanature 39 | org.eclipse.m2e.core.maven2Nature 40 | org.eclipse.wst.common.project.facet.core.nature 41 | org.eclipse.wst.jsdt.core.jsNature 42 | 43 | 44 | -------------------------------------------------------------------------------- /serviceRegistration/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | serviceRegistration 7 | war 8 | Service Registry 9 | Demo project for Spring Boot 10 | 11 | 12 | 13 | com.hitesh.boot 14 | heroes 15 | ${project.version} 16 | 17 | 18 | 19 | 20 | 21 | 22 | org.springframework.boot 23 | spring-boot-starter-web 24 | 25 | 26 | 27 | org.springframework.boot 28 | spring-boot-starter-test 29 | test 30 | 31 | 32 | 34 | 36 | 37 | 38 | 39 | org.springframework.cloud 40 | spring-cloud-starter 41 | 42 | 43 | 44 | 45 | org.springframework.cloud 46 | spring-cloud-starter-eureka-server 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | org.springframework.boot 56 | spring-boot-maven-plugin 57 | 58 | 59 | 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /serviceRegistration/src/main/java/serviceRegistration/RegistrationServer.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package serviceRegistration; 5 | 6 | import org.springframework.boot.SpringApplication; 7 | import org.springframework.boot.autoconfigure.SpringBootApplication; 8 | import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer; 9 | 10 | /** 11 | * @author hitjoshi 12 | * 13 | */ 14 | @SpringBootApplication 15 | @EnableEurekaServer 16 | public class RegistrationServer { 17 | 18 | /** 19 | * Run the application using Spring Boot and an embedded servlet engine. 20 | * 21 | * @param args 22 | * Program arguments - ignored. 23 | */ 24 | public static void main(String[] args) { 25 | // Tell server to look for registration.properties or registration.yml 26 | // by default it looks for application.properties or application.yml 27 | System.setProperty("spring.config.name", "registration-server"); 28 | 29 | SpringApplication.run(RegistrationServer.class, args); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /serviceRegistration/src/main/resources/registration-server.yml: -------------------------------------------------------------------------------- 1 | # Configure this Discovery Server 2 | eureka: 3 | instance: 4 | hostname: localhost 5 | client: # Not a client, don't register with yourself 6 | registerWithEureka: false 7 | fetchRegistry: false 8 | 9 | server: 10 | port: 1111 # HTTP (Tomcat) port 11 | 12 | # Discovery Server Dashboard uses FreeMarker. Don't want Thymeleaf templates 13 | spring: 14 | thymeleaf: 15 | enabled: false # Disable Thymeleaf -------------------------------------------------------------------------------- /zuulGateway/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4.0.0 3 | 4 | com.hitesh.boot 5 | heroes 6 | ${project.version} 7 | 8 | zuulGateway 9 | jar 10 | zuulProxy 11 | Edge service for applying filters 12 | 13 | 14 | UTF-8 15 | 1.8 16 | 17 | 18 | 19 | 20 | org.springframework.cloud 21 | spring-cloud-starter-zuul 22 | 23 | 24 | org.springframework.boot 25 | spring-boot-starter-web 26 | 27 | 28 | 29 | org.springframework.boot 30 | spring-boot-starter-test 31 | test 32 | 33 | 34 | org.springframework.cloud 35 | spring-cloud-starter-eureka 36 | 37 | 38 | 39 | 40 | 41 | 42 | org.springframework.boot 43 | spring-boot-maven-plugin 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /zuulGateway/src/main/java/com/hitesh/filters/SimpleFilter.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.hitesh.filters; 5 | 6 | import javax.servlet.http.HttpServletRequest; 7 | 8 | import org.slf4j.Logger; 9 | import org.slf4j.LoggerFactory; 10 | import org.springframework.stereotype.Component; 11 | 12 | import com.netflix.zuul.ZuulFilter; 13 | import com.netflix.zuul.context.RequestContext; 14 | 15 | /** 16 | * @author hitjoshi 17 | * 18 | */ 19 | @Component 20 | public class SimpleFilter extends ZuulFilter { 21 | 22 | private static Logger log = LoggerFactory.getLogger(SimpleFilter.class); 23 | 24 | @Override 25 | public String filterType() { 26 | return "pre"; 27 | } 28 | 29 | @Override 30 | public int filterOrder() { 31 | return 1; 32 | } 33 | 34 | @Override 35 | public boolean shouldFilter() { 36 | return true; 37 | } 38 | 39 | @Override 40 | public Object run() { 41 | RequestContext ctx = RequestContext.getCurrentContext(); 42 | HttpServletRequest request = ctx.getRequest(); 43 | 44 | log.info(String.format("%s Hitesh is requesting to %s", request.getMethod(), request.getRequestURL().toString())); 45 | return null; 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /zuulGateway/src/main/java/com/hitesh/zuulGateway/GatewayApplication.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.hitesh.zuulGateway; 5 | 6 | import org.springframework.boot.SpringApplication; 7 | import org.springframework.boot.autoconfigure.SpringBootApplication; 8 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient; 9 | import org.springframework.cloud.netflix.zuul.EnableZuulProxy; 10 | 11 | /** 12 | * @author hitjoshi 13 | * 14 | */ 15 | @EnableZuulProxy 16 | @EnableDiscoveryClient 17 | @SpringBootApplication(scanBasePackages={"com.hitesh.filters"}) 18 | public class GatewayApplication { 19 | 20 | public static void main(String[] args) { 21 | SpringApplication.run(GatewayApplication.class, args); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /zuulGateway/src/main/resources/bootstrap.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 5555 3 | 4 | spring: 5 | application: 6 | name: zuul-proxy 7 | 8 | 9 | eureka: 10 | client: 11 | serviceUrl: 12 | defaultZone: http://localhost:1111/eureka 13 | 14 | #to allow authentication headers to be passed to downsream microservices 15 | #zuul.sensitive-headers: Cookie,Set-Cookie,Authorization 16 | # will stop Authorization from happening 17 | zuul: 18 | sensitive-headers: Cookie,Set-Cookie 19 | 20 | hystrix: 21 | command: 22 | default: 23 | execution: 24 | isolation: 25 | thread: 26 | timeoutInMilliseconds: 60000 27 | 28 | 29 | 30 | --------------------------------------------------------------------------------