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 @@ -3,6 +3,12 @@
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
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 @@ -19,6 +25,7 @@ public class SchoolsApplication
*/
public static void main(String[] args)
{

SpringApplication.run(SchoolsApplication.class,
args);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package com.lambdaschool.schools.controllers;


import com.lambdaschool.schools.models.Advice;
import com.lambdaschool.schools.models.Instructor;
import com.lambdaschool.schools.models.Slip;
import com.lambdaschool.schools.services.InstructorService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
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;
import org.springframework.web.client.RestTemplate;

import java.util.Collections;

@RestController
@RequestMapping(value = "/instructors")
public class InstructorController
{
/*
* Creates the object that is needed to do a client side Rest API call.
* We are the client getting data from a remote API.
* We can share this template among endpoints
*/
private RestTemplate restTemplate = new RestTemplate();

@Autowired
private InstructorService instructorService;

@GetMapping(value = "/instructor/{instid}/advice")
public ResponseEntity<?> getAdvice(
@PathVariable
long instid)
{
// 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 including adding the path variable
String requestURL = "https://api.adviceslip.com/advice";
// create the responseType expected. Notice the Advice is the data type we are expecting back from the API!
ParameterizedTypeReference<Advice> responseType = new ParameterizedTypeReference<>()
{
};

// create the response entity. do the get and get back information
ResponseEntity<Advice> responseEntity = restTemplate.exchange(requestURL,
HttpMethod.GET,
null,
responseType);
// we want to return the contents of the translation data. From the data that gets returned in the body,
// get the contents data only and return it.
// putting the data into its own object first, prevents the data from being reported to client inside of
// an embedded. So the response will look more like our clients are use to!
Instructor instructor = instructorService.addAdvice(instid,responseEntity.getBody().getSlip().getAdvice());

return new ResponseEntity<>(instructor,
HttpStatus.OK);
}

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

import com.lambdaschool.schools.services.HelperFunction;
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
private HelperFunction helperFunction;

@Override
public Map<String, Object> getErrorAttributes(
WebRequest webRequest,
boolean includeStackTrace)
{

Map<String,Object> errorAttributes = super.getErrorAttributes(webRequest,
includeStackTrace);

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

errorDetails.put("title",errorAttributes.get("error"));
errorDetails.put("status",errorAttributes.get("status"));
errorDetails.put("detail",errorAttributes.get("message"));
errorDetails.put("timestamp",new Date());
errorDetails.put("developerMessage","path "+errorAttributes.get("path"));
errorDetails.put("errors",helperFunction.getConstraintViolations(this.getError(webRequest)));

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

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

import com.lambdaschool.schools.exceptions.ResourceNotFoundException;
import com.lambdaschool.schools.models.ErrorDetail;
import com.lambdaschool.schools.services.HelperFunction;
import org.springframework.beans.factory.annotation.Autowired;
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.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;

@RestControllerAdvice
@Order(Ordered.HIGHEST_PRECEDENCE)
public class RestExceptionHandler extends ResponseEntityExceptionHandler
{

@Autowired
private HelperFunction helperFunction;

@ExceptionHandler(ResourceNotFoundException.class)
protected ResponseEntity<?> handleResourceNotFoundException(ResourceNotFoundException rnfe)
{
ErrorDetail errorDetail = new ErrorDetail();
errorDetail.setTitle("Resource not found");
errorDetail.setStatus(HttpStatus.NOT_FOUND.value());
errorDetail.setDetail(rnfe.getMessage());
errorDetail.setTimestamp(new Date());
errorDetail.setDeveloperMessage(rnfe.getClass().getName());
errorDetail.setErrors(helperFunction.getConstraintViolations(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.setTitle("Rest Internal Exception");
errorDetail.setStatus(status.value());
errorDetail.setDetail("Found an issue with School: "+ex.getMessage());
errorDetail.setTimestamp(new Date());
errorDetail.setDeveloperMessage(ex.getClass().getName());
errorDetail.setErrors(helperFunction.getConstraintViolations(ex));

return new ResponseEntity<>(errorDetail,headers,status);
}
}
19 changes: 19 additions & 0 deletions schools/src/main/java/com/lambdaschool/schools/models/Advice.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.lambdaschool.schools.models;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

@JsonIgnoreProperties(ignoreUnknown = true)
public class Advice
{
private Slip slip;

public Slip getSlip()
{
return slip;
}

public void setSlip(Slip slip)
{
this.slip = slip;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

import javax.persistence.*;
import javax.validation.constraints.Size;
import java.util.HashSet;
import java.util.Set;

Expand All @@ -27,6 +28,7 @@ public class Course
*/
@Column(nullable = true,
unique = true)
@Size(min = 2, max = 50)
private String coursename;

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package com.lambdaschool.schools.models;


import java.util.Date;
import java.util.List;

public class ErrorDetail
{
private String title;
private int status;
private String detail;
private Date timestamp;
private String developerMessage;
private List<ValidationError> errors;

public ErrorDetail()
{
}

public String getTitle()
{
return title;
}

public void setTitle(String title)
{
this.title = title;
}

public int getStatus()
{
return status;
}

public void setStatus(int status)
{
this.status = status;
}

public String getDetail()
{
return detail;
}

public void setDetail(String detail)
{
this.detail = detail;
}

public Date getTimestamp()
{
return timestamp;
}

public void setTimestamp(Date timestamp)
{
this.timestamp = timestamp;
}

public String getDeveloperMessage()
{
return developerMessage;
}

public void setDeveloperMessage(String developerMessage)
{
this.developerMessage = developerMessage;
}

public List<ValidationError> getErrors()
{
return errors;
}

public void setErrors(List<ValidationError> errors)
{
this.errors = errors;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

import javax.persistence.*;
import javax.validation.constraints.Size;
import java.util.ArrayList;
import java.util.List;

Expand All @@ -11,6 +12,7 @@
*/
@Entity
@Table(name = "instructors")
@JsonIgnoreProperties(ignoreUnknown = true)
public class Instructor
extends Auditable
{
Expand All @@ -25,8 +27,11 @@ public class Instructor
* The Instructor's name (String)
*/
@Column(nullable = false)
@Size(min=2,max = 30)
private String name;

@Transient
private String advice;
/**
* List of courses associated with this instructor. Does not get saved in the database directly.
* Forms a one to many relationship with courses. One instructor to many courses.
Expand Down Expand Up @@ -115,4 +120,14 @@ public void setCourses(List<Course> courses)
{
this.courses = courses;
}

public String getAdvice()
{
return advice;
}

public void setAdvice(String advice)
{
this.advice = advice;
}
}
19 changes: 19 additions & 0 deletions schools/src/main/java/com/lambdaschool/schools/models/Slip.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.lambdaschool.schools.models;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

@JsonIgnoreProperties(ignoreUnknown = true)
public class Slip
{
private String advice;

public String getAdvice()
{
return advice;
}

public void setAdvice(String advice)
{
this.advice = advice;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

import javax.persistence.*;
import javax.validation.constraints.Size;
import java.util.HashSet;
import java.util.Set;

Expand All @@ -26,6 +27,7 @@ public class Student
*/
@Column(nullable = false,
unique = true)
@Size(min= 2,max = 30)
private String name;

/**
Expand Down
Loading