Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -376,7 +376,7 @@ <h4>update</h4>
<h4>delete</h4>
<pre class="methodSignature">@Transactional
public&nbsp;void&nbsp;delete&#8203;(long&nbsp;id)
throws javax.persistence.EntityNotFoundException</pre>
throws javax.persistence.ResourceNotFoundExeption</pre>
<div class="block"><span class="descfrmTypeLabel">Description copied from interface:&nbsp;<code><a href="ZooService.html#delete(long)">ZooService</a></code></span></div>
<div class="block">Deletes the course record, it student course combinations, and its telephone items from the database based off of the provided primary key</div>
<dl>
Expand All @@ -385,7 +385,7 @@ <h4>delete</h4>
<dt><span class="paramLabel">Parameters:</span></dt>
<dd><code>id</code> - id The primary key (long) of the course you seek.</dd>
<dt><span class="throwsLabel">Throws:</span></dt>
<dd><code>javax.persistence.EntityNotFoundException</code></dd>
<dd><code>javax.persistence.ResourceNotFoundExeption</code></dd>
</dl>
</li>
</ul>
Expand Down Expand Up @@ -438,7 +438,7 @@ <h4>saveZooAnimalCombo</h4>
<li class="blockList">
<h4>findZooByLikeName</h4>
<pre class="methodSignature">public&nbsp;java.util.ArrayList&lt;<a href="../models/Zoo.html" title="class in com.lambdaschool.schools.models">Zoo</a>&gt;&nbsp;findZooByLikeName&#8203;(java.lang.String&nbsp;name)
throws javax.persistence.EntityNotFoundException</pre>
throws javax.persistence.ResourceNotFoundExeption</pre>
<div class="block"><span class="descfrmTypeLabel">Description copied from interface:&nbsp;<code><a href="ZooService.html#findZooByLikeName(java.lang.String)">ZooService</a></code></span></div>
<div class="block">A list of all zoos whose name contains the given substring
A Stretch Goal</div>
Expand All @@ -450,7 +450,7 @@ <h4>findZooByLikeName</h4>
<dt><span class="returnLabel">Returns:</span></dt>
<dd>List of zoos whose name contains the given substring</dd>
<dt><span class="throwsLabel">Throws:</span></dt>
<dd><code>javax.persistence.EntityNotFoundException</code></dd>
<dd><code>javax.persistence.ResourceNotFoundExeption</code></dd>
</dl>
</li>
</ul>
Expand Down
23 changes: 23 additions & 0 deletions schools/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,29 @@
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>

<!-- Swagger Dependencies Start -->
<!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger2 -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>

<!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger-ui -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>

<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-bean-validators</artifactId>
<version>2.9.2</version>
</dependency>
<!-- Swagger Dependencies End -->

</dependencies>

<build>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,17 @@
package com.lambdaschool.schools;

import com.lambdaschool.schools.models.slip;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.client.RestTemplate;

import java.util.Collections;

/**
* Main class to start the application.
Expand All @@ -17,10 +26,36 @@ public class SchoolsApplication
*
* @param args Not used in this application.
*/

public static void main(String[] args)
{
SpringApplication.run(SchoolsApplication.class,
args);
/*
* Creates the object that is needed to do a client side Rest API call.
* We are the client getting data from a remote API.
*/
RestTemplate restTemplate = new RestTemplate();

// we need to tell our RestTemplate what format to expect
MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
// a couple of common formats
// converter.setSupportedMediaTypes(Collections.singletonList(MediaType.TEXT_HTML));
// converter.setSupportedMediaTypes(Collections.singletonList(MediaType.APPLICATION_JSON));
// or we can accept all formats! Easiest but least secure
converter.setSupportedMediaTypes(Collections.singletonList(MediaType.ALL));
restTemplate.getMessageConverters().add(converter);

// create the url to access the API
String requestURL = "https://api.adviceslip.com/advice";
// create the responseType expected. Notice the YearFact is the data type we are expecting back from the API!
ParameterizedTypeReference<slip> responseType = new ParameterizedTypeReference<slip>()
{
};

ResponseEntity<slip> responseEntity = restTemplate.exchange(requestURL, HttpMethod.GET, null, responseType);
slip ourslip = responseEntity.getBody();
System.out.println(ourslip);

SpringApplication.run(SchoolsApplication.class, args);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package com.lambdaschool.schools.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import springfox.bean.validators.configuration.BeanValidatorPluginsConfiguration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

/**
* Configures the default Swagger Documentation
*/
@Configuration
@EnableSwagger2
@Import(BeanValidatorPluginsConfiguration.class)
public class Swagger2Config
{
/**
* Configures what to document using Swagger
*
* @return A Docket which is the primary interface for Swagger configuration
*/
@Bean
public Docket api()
{
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors
.basePackage("com.lambdaschool.schools"))
.paths(PathSelectors.regex("/.*"))
.build()
.apiInfo(apiEndPointsInfo());
}

/**
* Configures some information related to the Application for Swagger
*
* @return ApiInfo a Swagger object containing identification information for this application
*/
private ApiInfo apiEndPointsInfo()
{
return new ApiInfoBuilder().title("User Model Example")
.description("User Model Example")
.contact(new Contact("Lucas Steinmacher",
"http://www.lambdaschool.com",
"john@lambdaschool.com"))
.license("MIT")
.licenseUrl("https://github.com/LambdaSchool/java-usermodel/blob/master/LICENSE")
.version("1.0.0")
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package com.lambdaschool.schools.config;


import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**
* The application turns off any automatic web page generate done by Spring. This is done to improve exception handling.
* However, we do need some web page generate done for Swagger, so we do that here.
*/
@Configuration
public class SwaggerWebMVC
implements WebMvcConfigurer
{
/**
* Adds the Swagger web pages to Spring.
* This still gives the following warning
* <p>
* No mapping for GET /
* No mapping for GET /csrf
* <p>
* All works though
*
* @param registry the place that holds the web pages for Spring
*/
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry)
{
registry.addResourceHandler("swagger-ui.html")
.addResourceLocations("classpath:/META-INF/resources/");

registry.addResourceHandler("/webjars/**")
.addResourceLocations("classpath:/META-INF/resources/webjars/");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.lambdaschool.schools.controllers;

import com.lambdaschool.schools.models.Instructor;
import com.lambdaschool.schools.services.InstructorService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping(value = "instructors")
public class InstructorController
{
@Autowired
private InstructorService instructorService;

// http://localhost:2019/instructors/instructor/3/advice
@GetMapping(value = "/instructor/{instructorid}/advice", produces = "application/json")
public ResponseEntity<?> getInstructorAdvice(
@PathVariable Long instructorid)
{
Instructor i = instructorService.addAdvice(instructorid);
return new ResponseEntity<>(i, HttpStatus.OK);
}

}
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
package com.lambdaschool.schools.controllers;

import com.lambdaschool.schools.models.ErrorDetail;
import com.lambdaschool.schools.models.Student;
import com.lambdaschool.schools.services.StudentService;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
Expand Down Expand Up @@ -34,6 +39,7 @@ public class StudentController
* @return JSON list of all students with a status of OK
* @see StudentService#findAll() StudentService.findAll()
*/
@ApiOperation(value = "returns all students", response = Student.class, responseContainer = "List")
@GetMapping(value = "/students",
produces = {"application/json"})
public ResponseEntity<?> listAllStudents()
Expand All @@ -51,9 +57,16 @@ public ResponseEntity<?> listAllStudents()
* @return JSON object of the student you seek
* @see StudentService#findStudentById(long) StudentService.findStudentById(long)
*/
@ApiOperation(value = "Returns a student by id", response = Student.class)
@ApiResponses(value = {@ApiResponse(code = 200,
message = "Student found",
response = Student.class), @ApiResponse(code = 404,
message = "Student not found",
response = ErrorDetail.class)})
@GetMapping(value = "/student/{studentId}",
produces = {"application/json"})
public ResponseEntity<?> getStudentById(
@ApiParam(value = "Student id", required = true, example = "4")
@PathVariable
Long studentId)
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package com.lambdaschool.schools.exceptions;

import com.lambdaschool.schools.services.HelperFunctions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.servlet.error.DefaultErrorAttributes;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.WebRequest;

import java.util.Date;
import java.util.LinkedHashMap;
import java.util.Map;

@Component
public class CustomErrorDetails extends DefaultErrorAttributes
{
@Autowired
HelperFunctions helperFunctions;

@Override
public Map<String, Object> getErrorAttributes(
WebRequest webRequest,
boolean includeStackTrace)
{
Map<String, Object> errorAttributes = super.getErrorAttributes(webRequest, includeStackTrace);

Map<String, Object> rtnAttributes = new LinkedHashMap<>();

rtnAttributes.put("title", errorAttributes.get("error"));
rtnAttributes.put("status", errorAttributes.get("status"));
rtnAttributes.put("detail", errorAttributes.get("message"));
rtnAttributes.put("timestamp", new Date());
rtnAttributes.put("developer", "path: " + errorAttributes.get("path"));

rtnAttributes.put("errors", helperFunctions.getValidationErrors(this.getError(webRequest)));

return rtnAttributes;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.lambdaschool.schools.exceptions;

public class ResourceNotFoundExeption extends RuntimeException
{
public ResourceNotFoundExeption(String message)
{
super("Found an issue with School: " + message);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package com.lambdaschool.schools.handelers;

import com.lambdaschool.schools.exceptions.ResourceNotFoundExeption;
import com.lambdaschool.schools.models.ErrorDetail;
import com.lambdaschool.schools.services.HelperFunctions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.servlet.error.DefaultErrorAttributes;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;

import java.util.Date;
import java.util.Map;

@RestControllerAdvice
@Order(Ordered.HIGHEST_PRECEDENCE)
public class RestExceptionHandler extends ResponseEntityExceptionHandler
{
@Autowired
private HelperFunctions helperFunctions;

@ExceptionHandler(ResourceNotFoundExeption.class)
public ResponseEntity<?> handleResourceNotFoundException(ResourceNotFoundExeption rnfe)
{
ErrorDetail errorDetail = new ErrorDetail();
errorDetail.setTimestamp(new Date());
errorDetail.setTitle("Resource Not Found Bubba!");
errorDetail.setStatus(HttpStatus.NOT_FOUND.value());
errorDetail.setDetail(rnfe.getMessage());
errorDetail.setDeveloper(rnfe.getClass().getName());
errorDetail.setErrors(helperFunctions.getValidationErrors(rnfe));
return new ResponseEntity<>(errorDetail, null, HttpStatus.NOT_FOUND);
}

@Override
protected ResponseEntity<Object> handleExceptionInternal(
Exception ex,
Object body,
HttpHeaders headers,
HttpStatus status,
WebRequest request)
{
ErrorDetail errorDetail = new ErrorDetail();
errorDetail.setTimestamp(new Date());
errorDetail.setTitle("REST Internal Exception");
errorDetail.setStatus(status.value());
errorDetail.setDetail(ex.getMessage());
errorDetail.setDeveloper(ex.getClass().getName());
errorDetail.setErrors(helperFunctions.getValidationErrors(ex));
return new ResponseEntity<>(errorDetail,null,status);
}
}
Loading