Skip to content

Commit 92acf5b

Browse files
committed
Added endpoint for getting book user rating
1 parent 3603e8e commit 92acf5b

17 files changed

+155
-30
lines changed

build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ dependencies {
7070
implementation group: 'org.apache.commons', name: 'commons-lang3', version: '3.3.2'
7171
implementation group: 'javax.xml.bind', name: 'jaxb-api', version: '2.3.1'
7272
implementation group: 'org.glassfish.jaxb', name: 'jaxb-runtime', version: '2.3.1'
73-
73+
implementation group: 'org.scala-lang.modules', name: 'scala-java8-compat_2.12', version: '0.9.0'
7474
testImplementation 'org.springframework.boot:spring-boot-starter-test'
7575
}
7676

build.sbt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ lazy val root = (project in file(".")).
3333
libraryDependencies += "org.apache.commons" % "commons-lang3" % "3.3.2",
3434
libraryDependencies += "javax.xml.bind" % "jaxb-api" % "2.3.1",
3535
libraryDependencies += "org.glassfish.jaxb" % "jaxb-runtime" % "2.3.1",
36+
libraryDependencies += "org.scala-lang.modules" % "scala-java8-compat_2.12" % "0.9.0",
37+
//libraryDependencies += "org.scala-lang.modules" % "scala-collection-compat_2.12" % "2.1.2",
3638

3739
libraryDependencies += "org.springframework.boot" % "spring-boot-starter-test" % springVersion
3840
)

src/main/resources/application.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ app:
22
name : BookService
33
log.tomcat-version : true
44

5-
logging.level.org.repl.springcloud: ${BOOK_SERVICE_LOGGING_LEVEL:DEBUG}
5+
logging.level.org.repl.poc.lmsdata: ${LMS_LOGGING_LEVEL:DEBUG}
66

77
server:
88
port: ${port:9090}

src/main/scala/org/repl/poc/lmsdata/config/OAuth2AuthorizationServerConfig.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@ class OAuth2AuthorizationServerConfig extends AuthorizationServerConfigurerAdapt
2323
@Autowired
2424
private var authenticationManager: AuthenticationManager = _
2525

26-
val CLIENT_ID: String = "defmacro-client";
27-
val CLIENT_SECRET = "$2y$12$nv64IvDN1P2EnNARkeYOgOdHSM4b7G5y97KuXG5sdv03HAqU6TNuW"; //defmacro-secret
26+
val CLIENT_ID: String = "devglan-client";
27+
val CLIENT_SECRET = "$2a$04$e/c1/RfsWuThaWFCrcCuJeoyvwCV0URN/6Pn9ZFlrtIWaU/vj/BfG"; //devglan-secret
2828
val GRANT_TYPE_PASSWORD = "password";
2929
val AUTHORIZATION_CODE = "authorization_code";
3030
val REFRESH_TOKEN = "refresh_token";
@@ -41,7 +41,7 @@ class OAuth2AuthorizationServerConfig extends AuthorizationServerConfigurerAdapt
4141
.withClient(CLIENT_ID)
4242
.secret(CLIENT_SECRET)
4343
.authorizedGrantTypes(GRANT_TYPE_PASSWORD, AUTHORIZATION_CODE, REFRESH_TOKEN, IMPLICIT)
44-
.scopes(SCOPE_READ, SCOPE_WRITE, TRUST)
44+
.scopes(SCOPE_READ, SCOPE_WRITE)
4545
.accessTokenValiditySeconds(ACCESS_TOKEN_VALIDITY_SECONDS).
4646
refreshTokenValiditySeconds(REFRESH_TOKEN_VALIDITY_SECONDS)
4747
}

src/main/scala/org/repl/poc/lmsdata/config/SecurityConfig.scala

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ import javax.annotation.Resource
2222
@EnableWebSecurity
2323
@EnableGlobalMethodSecurity(prePostEnabled = true)
2424
class SecurityConfig extends WebSecurityConfigurerAdapter {
25+
26+
val ADMIN_ROLE: Any = "ROLE_ADMIN"
27+
2528
@Bean
2629
def accessTokenConverter(): AccessTokenConverter = {
2730
val jatc = new JwtAccessTokenConverter()
@@ -59,31 +62,28 @@ class SecurityConfig extends WebSecurityConfigurerAdapter {
5962

6063
/*@Autowired
6164
def configureGlobal(auth: AuthenticationManagerBuilder): Unit = {
62-
auth.inMemoryAuthentication().withUser("bugbug0102").password("0102").roles("USER", "ADMIN", "BUGBUG")
65+
auth.userDetailsService(userDetailsService).passwordEncoder(encoder)
6366
}
6467
6568
@throws[Exception]
6669
override protected def configure(auth: AuthenticationManagerBuilder): Unit = {
67-
//@formatter:off
68-
auth.inMemoryAuthentication.withUser("habuma")
69-
.password("password")
70-
.authorities("ROLE_USER", "ROLE_ADMIN")
71-
.and
72-
.withUser("izzy")
73-
.password("password")
74-
.authorities("ROLE_USER")
75-
//@formatter:on
70+
auth.userDetailsService(userDetailsService).passwordEncoder(encoder)
7671
}*/
7772

7873
@throws[Exception]
7974
override protected def configure(http: HttpSecurity): Unit = {
80-
http
81-
.csrf.disable
82-
.anonymous.disable
83-
//.sessionManagement.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
84-
.authorizeRequests
85-
.antMatchers(HttpMethod.GET, "/api/v1/movies", "/error").permitAll
86-
.antMatchers(HttpMethod.POST, "/api/v1/login", "/api/v1/register", "/api/v1/tickets").permitAll
75+
//@formatter:off
76+
http.csrf().disable()
77+
.authorizeRequests()
78+
.antMatchers(HttpMethod.GET, "/echo").permitAll()
79+
.antMatchers(HttpMethod.POST, "/oauth/token").permitAll()
80+
.antMatchers(HttpMethod.GET, "/api/v1/books/**").permitAll()
81+
.antMatchers(HttpMethod.POST, "/api/v1/users").permitAll()
82+
.antMatchers("/api/v1/admin/**").access("hasRole('" + ADMIN_ROLE + "')")
83+
//.anyRequest().authenticated().and().httpBasic()
84+
85+
//http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
86+
//@formatter:on
8787
}
8888

8989
/*@Bean def corsFilter: FilterRegistrationBean[CorsFilter] = {

src/main/scala/org/repl/poc/lmsdata/controller/BookController.scala

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,11 @@ class BookController @Autowired()(bookService: BookService) {
6060
return bookService.get(id);
6161
}
6262

63+
@GetMapping(value = Array("/v1/books/{id}/user-ratings"))
64+
def getBookRatings(@PathVariable("id") id: String): ServiceResponse[UserBookRatingSummaryDto] = {
65+
return bookService.getRatings(id);
66+
}
67+
6368
@PostMapping(value = Array("/v1/books/copy"), consumes = Array(MediaType.APPLICATION_JSON_VALUE), produces = Array(MediaType.APPLICATION_JSON_VALUE))
6469
@ResponseBody
6570
def createBook(@RequestBody input: BookCopyCreateDto): ServiceResponse[IdDto] = {
Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,37 @@
11
package org.repl.poc.lmsdata.controller
22

3-
import org.repl.poc.lmsdata.dto.{IdDto, ServiceResponse, UserCreateDto}
3+
import java.security.Principal
4+
5+
import org.repl.poc.lmsdata.dto.{IdDto, ServiceResponse, UserCreateDto, UserDto}
46
import org.repl.poc.lmsdata.service.UserService
7+
import org.slf4j.LoggerFactory
58
import org.springframework.beans.factory.annotation.Autowired
69
import org.springframework.http.MediaType
10+
import org.springframework.security.access.prepost.PreAuthorize
11+
import org.springframework.security.core.Authentication
712
import org.springframework.web.bind.annotation._
813

914
@RestController
1015
@RequestMapping(value = Array("/api"))
1116
class UserController @Autowired()(userService: UserService) {
17+
private val logger = LoggerFactory.getLogger(classOf[UserController])
18+
1219
@PostMapping(value = Array("/v1/user"), consumes = Array(MediaType.APPLICATION_JSON_VALUE), produces = Array(MediaType.APPLICATION_JSON_VALUE))
1320
@ResponseBody
1421
def createUser(@RequestBody input: UserCreateDto): ServiceResponse[IdDto] = {
1522
return userService.createUser(input);
1623
}
24+
25+
@GetMapping(value = Array("/v1/user/profile"))
26+
@PreAuthorize("authenticated")
27+
def getLoggedInProfile(auth:Authentication, user:Principal): ServiceResponse[UserDto] = {
28+
logger.debug("user {}", user)
29+
logger.debug("auth {}", auth)
30+
return new ServiceResponse[UserDto] //userService.getProfile(auth.)
31+
}
32+
33+
@GetMapping(value = Array("/v1/user/{id}"))
34+
def getProfile(@PathVariable("id") id: String): ServiceResponse[UserDto] = {
35+
userService.getUser(id)
36+
}
1737
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
package org.repl.poc.lmsdata.dto
2+
3+
case class UserBookRatingDto(userId: String, isbn: String, rating: Integer, firstname: String, lastname: String) {
4+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package org.repl.poc.lmsdata.dto
2+
3+
case class UserBookRatingSummaryDto(isbn: String) {
4+
var count: Long = _
5+
var highestRatings: List[UserBookRatingDto] = _
6+
var lowestRatings: List[UserBookRatingDto] = _
7+
}

src/main/scala/org/repl/poc/lmsdata/dto/UserDto.scala

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
package org.repl.poc.lmsdata.dto
22

33
case class UserDto(username: String) extends Item {
4+
var firstName: String = _
5+
var lastName: String = _
6+
47
var city: String = _
58
var state: String = _
69
var country: String = _
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package org.repl.poc.lmsdata.mongodb.model
2+
3+
import java.time.LocalDateTime
4+
5+
import org.bson.types.ObjectId
6+
import org.repl.poc.lmsdata.dto.UserBookRatingDto
7+
import org.springframework.data.annotation.Id
8+
import org.springframework.data.mongodb.core.index.Indexed
9+
import org.springframework.data.mongodb.core.mapping.{Document, Field}
10+
11+
@Document(collection = "UserBookRating")
12+
class UserBookRatingMdl {
13+
@Id
14+
var id: String = _
15+
@Indexed
16+
@Field("ISBN")
17+
var isbn: String = _
18+
var rating: Integer = _
19+
@Indexed
20+
var userId: String = _
21+
var firstname: String = _
22+
var lastname: String = _
23+
var uid: ObjectId = _
24+
25+
var createdDate: LocalDateTime = _
26+
var createdByUID: String = _
27+
var modifiedDate: LocalDateTime = _
28+
var modifiedByUID: String = _
29+
30+
def createDto(): UserBookRatingDto = {
31+
UserBookRatingDto(userId, isbn, rating, firstname, lastname)
32+
}
33+
}

src/main/scala/org/repl/poc/lmsdata/mongodb/model/UserMdl.scala

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import com.fasterxml.jackson.annotation.JsonIgnore
66
import org.repl.poc.lmsdata.dto.UserDto
77
import org.springframework.data.annotation.Id
88
import org.springframework.data.mongodb.core.index.Indexed
9-
import org.springframework.data.mongodb.core.mapping.Document
9+
import org.springframework.data.mongodb.core.mapping.{Document, Field}
1010

1111
@Document(collection = "User")
1212
class UserMdl {
@@ -17,12 +17,15 @@ class UserMdl {
1717
@JsonIgnore
1818
var password: String = _
1919
var usernum: Long = _
20+
@Field("firstname")
2021
var firstName: String = _
22+
@Field("lastname")
2123
var lastName: String = _
2224
var city: String = _
2325
var state: String = _
2426
var country: String = _
2527
var categories: List[String] = _
28+
var roles: List[String] = _
2629

2730
var createdDate: LocalDateTime = _
2831
var createdByUID: String = _
@@ -32,6 +35,8 @@ class UserMdl {
3235
def createDto(): UserDto = {
3336
val retDto = UserDto(username)
3437
retDto.id = id
38+
retDto.firstName = firstName
39+
retDto.lastName = lastName
3540
retDto.city = city
3641
retDto.state = state
3742
retDto.country = country

src/main/scala/org/repl/poc/lmsdata/mongodb/repository/BookRepository.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package org.repl.poc.lmsdata.mongodb.repository
22

33
import org.repl.poc.lmsdata.mongodb.model.BookMdl
4+
import org.springframework.data.mongodb.repository.MongoRepository
45
import org.springframework.data.repository.Repository
56

67
trait BookRepository extends Repository[BookMdl, String] {
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package org.repl.poc.lmsdata.mongodb.repository
2+
3+
import org.repl.poc.lmsdata.mongodb.model.{UserBookRatingMdl, UserMdl}
4+
import org.springframework.data.domain.Pageable
5+
import org.springframework.data.mongodb.repository.{MongoRepository, Query}
6+
7+
trait UserBookRatingRepository extends MongoRepository[UserBookRatingMdl, String] {
8+
@Query(value= "{'isbn' : ?0, rating: {$gt: 7} }", sort = "{ rating : -1 }")
9+
def getHighRatings(isbn: String, pageable: Pageable): java.util.List[UserBookRatingMdl]
10+
}
Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
package org.repl.poc.lmsdata.mongodb.repository
22

3-
import org.repl.poc.lmsdata.mongodb.model.UserMdl
3+
import org.repl.poc.lmsdata.mongodb.model.{UserMdl}
44
import org.springframework.data.mongodb.repository.MongoRepository
55
import org.springframework.data.repository.Repository
66

77
trait UserRepository extends MongoRepository[UserMdl, String] {
88
def findByUsername(userId: String): UserMdl
9-
109
}

src/main/scala/org/repl/poc/lmsdata/service/BookService.scala

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@ import java.time.LocalDateTime
55
import org.bson.types.ObjectId
66
import org.repl.poc.lmsdata.dto._
77
import org.repl.poc.lmsdata.mongodb.model.{BookCopyMdl, BookMdl}
8-
import org.repl.poc.lmsdata.mongodb.repository.{BookCopyRepository, BookRepository, LibraryBranchRepository}
8+
import org.repl.poc.lmsdata.mongodb.repository.{BookCopyRepository, BookRepository, LibraryBranchRepository, UserBookRatingRepository}
99
import org.springframework.beans.factory.annotation.Autowired
10+
import org.springframework.data.domain.PageRequest
1011
import org.springframework.data.mongodb.core.MongoTemplate
1112
import org.springframework.stereotype.Service
1213
import org.springframework.data.mongodb.core.aggregation.Aggregation._
@@ -20,7 +21,8 @@ import scala.collection.mutable
2021
class BookService @Autowired() (mongoTemplate: MongoTemplate,
2122
bookRepository: BookRepository,
2223
libraryBranchRepository: LibraryBranchRepository,
23-
bookCopyRepository: BookCopyRepository) {
24+
bookCopyRepository: BookCopyRepository,
25+
userBookRatingRepository: UserBookRatingRepository) {
2426

2527
def getCollection(requestDto: ListViewRequestDto): ServiceResponse[PaginatedListDto[BookDto]] = {
2628
val response = new ServiceResponse[PaginatedListDto[BookDto]]()
@@ -152,4 +154,23 @@ class BookService @Autowired() (mongoTemplate: MongoTemplate,
152154
}
153155
response
154156
}
157+
158+
def getRatings(id: String): ServiceResponse[UserBookRatingSummaryDto] = {
159+
val response = new ServiceResponse[UserBookRatingSummaryDto]()
160+
bookRepository.findById(id) match {
161+
case Some(mdl) => {
162+
val retValue = UserBookRatingSummaryDto(mdl.isbn)
163+
val highRatings = userBookRatingRepository.getHighRatings(mdl.isbn, new PageRequest(0, 10))
164+
retValue.highestRatings = highRatings.asScala.map( x => x.createDto()).toList
165+
166+
response.success = true
167+
response.data = Some(retValue)
168+
}
169+
case None => {
170+
response.success = false
171+
response.errors.+("No book found!")
172+
}
173+
}
174+
response
175+
}
155176
}

src/main/scala/org/repl/poc/lmsdata/service/UserService.scala

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,10 @@ package org.repl.poc.lmsdata.service
22

33
import java.time.LocalDateTime
44

5-
import org.springframework.beans.factory.annotation.Autowired
65
import org.springframework.stereotype.Service
76
import java.util
87

9-
import org.repl.poc.lmsdata.dto.{IdDto, LibraryBranchDto, ServiceResponse, ServiceResponseError, UserCreateDto, UserDto}
8+
import org.repl.poc.lmsdata.dto.{IdDto, ServiceResponse, ServiceResponseError, UserCreateDto, UserDto}
109
import org.repl.poc.lmsdata.mongodb.model.UserMdl
1110
import org.repl.poc.lmsdata.mongodb.repository.UserRepository
1211
import org.springframework.beans.factory.annotation.Autowired
@@ -15,6 +14,7 @@ import org.springframework.security.core.userdetails.{UserDetailsService, Userna
1514
import org.springframework.security.crypto.password.PasswordEncoder
1615

1716
import scala.collection.mutable
17+
import scala.compat.java8.OptionConverters._
1818

1919
@Service(value = "userService")
2020
class UserService extends UserDetailsService {
@@ -68,4 +68,19 @@ class UserService extends UserDetailsService {
6868
}
6969
errors
7070
}
71+
72+
def getUser(id: String): ServiceResponse[UserDto] = {
73+
val response = new ServiceResponse[UserDto]()
74+
userRepository.findById(id).asScala match {
75+
case Some(mdl) => {
76+
response.success = true
77+
response.data = Option(mdl.createDto())
78+
}
79+
case None => {
80+
response.success = false
81+
response.errors.+("No user found!")
82+
}
83+
}
84+
return response
85+
}
7186
}

0 commit comments

Comments
 (0)