Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
memoriav
Memobase 2020
services
ExternalAPIs
OAI
Commits
57db067a
Commit
57db067a
authored
Aug 25, 2020
by
Günter Hipler
Browse files
more validation checks
parent
6858ecba
Pipeline
#13284
failed with stage
in 2 minutes and 12 seconds
Changes
8
Pipelines
1
Expand all
Hide whitespace changes
Inline
Side-by-side
app/controllers/OaiController.scala
View file @
57db067a
...
...
@@ -2,14 +2,10 @@ package controllers
import
javax.inject.Inject
import
modules.OaiRepository
import
org.swissbib.memobase.oai.request.
{
OaiRequest
,
OaiRequestIllegalVerb
}
import
org.swissbib.memobase.oai.common.verb.OaiVerb
import
org.swissbib.memobase.oai.common.verb.OaiVerb.
{
OaiVerb
,
WRONGVERB
}
import
play.api.Configuration
import
play.api.mvc.
{
AbstractController
,
Action
,
AnyContent
,
ControllerComponents
,
Rendering
}
import
scala.util.
{
Failure
,
Success
,
Try
}
class
OaiController
@Inject
()(
cc
:
ControllerComponents
,
config
:
Configuration
,
repository
:
OaiRepository
,
...
...
@@ -19,7 +15,8 @@ class OaiController @Inject()(cc: ControllerComponents,
//todo: better way might be to use a so called BindController - have a look into this type part of this package
// where I played around a little bit with it
//https://www.playframework.com/documentation/2.8.x/RequestBinders
def
handleRequest
(
verb
:
String
,
//todo: can we make the Action more type specific (not AnyContent)
def
handleRequest
(
verb
:
Option
[
String
],
metadataPrefix
:
Option
[
String
],
set
:
Option
[
String
],
from
:
Option
[
String
],
...
...
@@ -28,32 +25,20 @@ class OaiController @Inject()(cc: ControllerComponents,
resumptionToken
:
Option
[
String
])
:
Action
[
AnyContent
]
=
Action
{
implicit
request
=>
val
oaiRequest
=
Try
[
OaiVerb
](
OaiVerb
.
withName
(
verb
))
match
{
//only allowed are the OAI defined verb values
//additionally we have to exclude the WRONGVERB value which is used in the Failure pattern to instantiate
//the OaiRequestIllegalVerb type
case
Success
(
v
)
if
v
!=
WRONGVERB
=>
OaiRequest
(
v
,
metadataPrefix
,
set
,
from
,
until
,
identifier
,
resumptionToken
)
case
_
=>
OaiRequestIllegalVerb
(
//seems to be that Enumeration value and val identifier have to be written in a case sensitive equal way
OaiVerb
.
withName
(
"WRONGVERB"
),
metadataPrefix
,
set
,
from
,
until
,
identifier
,
resumptionToken
)
}
val
response
=
oaiRequest
.
execute
(
config
,
repository
).
createResponse
val
mappedRequest
:
Map
[
String
,
Seq
[
String
]]
=
request
.
queryString
val
oaiRequest
=
OaiVerb
.
getOaiRequest
(
verb
=
verb
,
metadataPrefix
=
metadataPrefix
,
set
=
set
,
from
=
from
,
until
=
until
,
identifier
=
identifier
,
resumptionToken
=
resumptionToken
)
val
response
=
oaiRequest
.
getRunner
(
config
,
repository
).
run
().
createResponse
/*
todo: make Writable for Node[Seq]
[info] Compiling 4 Scala sources to /home/swissbib/environment/code/swissbib.repositories/memoriav/gitlab/services/oai/target/scala-2.13/classes ...
...
...
app/org/swissbib/memobase/oai/common/validation/ValidationError.scala
0 → 100644
View file @
57db067a
package
org.swissbib.memobase.oai.common.validation
sealed
abstract
class
ValidationError
(
val
message
:
String
)
case
class
MissingQueryParameter
(
parameter
:
String
,
override
val
message
:
String
)
extends
ValidationError
(
message
)
case
class
WrongQueryParameterValue
(
parameter
:
String
,
override
val
message
:
String
)
extends
ValidationError
(
message
)
case
class
NotAllowedQueryParameter
(
override
val
message
:
String
,
parameter
:
String*
)
extends
ValidationError
(
message
)
case
class
SystemFailureRequestValidation
(
override
val
message
:
String
)
extends
ValidationError
(
message
)
app/org/swissbib/memobase/oai/common/verb/OaiVerb.scala
View file @
57db067a
package
org.swissbib.memobase.oai.common.verb
import
org.swissbib.memobase.oai.common.validation.
{
MissingQueryParameter
,
SystemFailureRequestValidation
,
WrongQueryParameterValue
}
import
org.swissbib.memobase.oai.request.
{
OaiRequest
,
UserRequest
,
WrongOaiRequest
}
import
scala.util.
{
Failure
,
Success
,
Try
}
object
OaiVerb
extends
Enumeration
{
type
OaiVerb
=
Value
...
...
@@ -17,10 +22,42 @@ object OaiVerb extends Enumeration {
val
GetRecord
:
OaiVal
=
OaiVal
(
"GetRecord"
)
val
ListMetadataFormats
:
OaiVal
=
OaiVal
(
"ListMetadataFormats"
)
val
Identify
:
OaiVal
=
OaiVal
(
"Identify"
)
val
WRONGVERB
:
OaiVal
=
OaiVal
(
"WRONGVERB"
)
def
getOaiRequest
(
verb
:
Option
[
String
],
metadataPrefix
:
Option
[
String
],
set
:
Option
[
String
],
from
:
Option
[
String
],
until
:
Option
[
String
],
identifier
:
Option
[
String
],
resumptionToken
:
Option
[
String
],
allQueryParameter
:
Map
[
String
,
Seq
[
String
]])
:
UserRequest
=
{
Try
[
OaiVerb
](
OaiVerb
.
withName
(
verb
.
getOrElse
(
throw
new
MissingParameterException
(
"mandatory parameter verb is missing"
))))
match
{
case
Success
(
v
)
=>
OaiRequest
(
Some
(
v
),
metadataPrefix
,
set
,
from
,
until
,
identifier
,
resumptionToken
)
case
Failure
(
_:
MissingParameterException
)
=>
WrongOaiRequest
(
MissingQueryParameter
(
"verb"
,
"query parameter verb is missing"
))
case
Failure
(
_:
NoSuchElementException
)
=>
WrongOaiRequest
(
WrongQueryParameterValue
(
"verb"
,
s
"value $verb.get for parameter verb is not allowed"
))
case
_
=>
WrongOaiRequest
(
SystemFailureRequestValidation
(
"something really weird happened while validating the verb of the request"
)
)
}
}
}
}
class
MissingParameterException
(
message
:
String
)
extends
Exception
(
message
)
app/org/swissbib/memobase/oai/request/OaiRequest.scala
View file @
57db067a
package
org.swissbib.memobase.oai.request
import
modules.OaiRepository
import
org.swissbib.memobase.oai.common.validation.ValidationError
import
org.swissbib.memobase.oai.response.OaiResponse
import
org.swissbib.memobase.oai.common.verb.OaiVerb
import
org.swissbib.memobase.oai.common.verb.OaiVerb.OaiVerb
import
org.swissbib.memobase.oai.runner.
{
GetExceptionRunner
,
GetRecordRunner
,
IdentifyRunner
,
ListIdentifiersRunner
,
ListMetadataFormatsRunner
,
ListRecordsRunner
,
ListSetsRunner
}
import
org.swissbib.memobase.oai.runner.
{
GetExceptionRunner
,
GetRecordRunner
,
IdentifyRunner
,
ListIdentifiersRunner
,
ListMetadataFormatsRunner
,
ListRecordsRunner
,
ListSetsRunner
,
OaiRequestRunner
}
import
play.api.Configuration
sealed
abstract
class
UserRequest
(
val
verb
:
OaiVerb
,
sealed
abstract
class
UserRequest
(
val
verb
:
Option
[
OaiVerb
]
,
val
metadataPrefix
:
Option
[
String
],
val
set
:
Option
[
String
],
val
from
:
Option
[
String
],
...
...
@@ -15,10 +16,10 @@ sealed abstract class UserRequest(val verb:OaiVerb,
val
identifier
:
Option
[
String
],
val
resumptionToken
:
Option
[
String
])
{
def
execute
(
config
:
Configuration
,
repository
:
OaiRepository
)
:
OaiRe
sponse
def
getRunner
(
config
:
Configuration
,
repository
:
OaiRepository
)
:
OaiRe
questRunner
}
case
class
OaiRequest
(
override
val
verb
:
OaiVerb
,
case
class
OaiRequest
(
override
val
verb
:
Option
[
OaiVerb
]
,
override
val
metadataPrefix
:
Option
[
String
],
override
val
set
:
Option
[
String
],
override
val
from
:
Option
[
String
],
...
...
@@ -167,30 +168,32 @@ case class OaiRequest(override val verb:OaiVerb,
}
verb
match
{
case
OaiVerb
.
GetRecord
=>
println
(
"Getrecord"
);
checkArgumentsGetRecord
case
OaiVerb
.
Identify
=>
println
(
"Identify"
);
checkArgumentsIdentify
case
OaiVerb
.
ListIdentifiers
=>
println
(
"ListIdentifieres"
);
checkArgumentsListIdentifiers
case
OaiVerb
.
ListMetadataFormats
=>
println
(
"ListMetadataFormats"
);
checkArgumentsListMetadaFormats
case
OaiVerb
.
ListRecords
=>
println
(
"ListRecords"
);
checkArgumentsListRecords
case
OaiVerb
.
ListSets
=>
println
(
"ListSets"
);
checkArgumentsListSets
case
Some
(
OaiVerb
.
GetRecord
)
=>
println
(
"Getrecord"
);
checkArgumentsGetRecord
case
Some
(
OaiVerb
.
Identify
)
=>
println
(
"Identify"
);
checkArgumentsIdentify
case
Some
(
OaiVerb
.
ListIdentifiers
)
=>
println
(
"ListIdentifieres"
);
checkArgumentsListIdentifiers
case
Some
(
OaiVerb
.
ListMetadataFormats
)
=>
println
(
"ListMetadataFormats"
);
checkArgumentsListMetadaFormats
case
Some
(
OaiVerb
.
ListRecords
)
=>
println
(
"ListRecords"
);
checkArgumentsListRecords
case
Some
(
OaiVerb
.
ListSets
)
=>
println
(
"ListSets"
);
checkArgumentsListSets
case
Some
(
_
)
=>
println
(
"illegal oai verb"
);
false
case
None
=>
println
(
"verb is none"
);
false
}
}
//todo: validation for supplied argument
def
areArgumentsValid
:
Boolean
=
true
override
def
execute
(
config
:
Configuration
,
repository
:
OaiRepository
)
:
OaiRe
sponse
=
{
override
def
getRunner
(
config
:
Configuration
,
repository
:
OaiRepository
)
:
OaiRe
questRunner
=
{
//todo: too much imperative programming, make it more functional!
if
(
hasNecessaryArguments
&&
areArgumentsValid
)
{
verb
match
{
case
_:
OaiVerb.GetRecord.
type
=>
GetRecordRunner
(
config
,
repository
,
this
)
.
run
()
case
_:
OaiVerb.ListRecords.
type
=>
ListRecordsRunner
(
config
,
repository
,
this
)
.
run
()
case
_:
OaiVerb.ListSets.
type
=>
ListSetsRunner
(
config
,
repository
,
this
)
.
run
()
case
_:
OaiVerb.Identify.
type
=>
IdentifyRunner
(
config
,
repository
,
this
)
.
run
()
case
_:
OaiVerb.ListIdentifiers.
type
=>
ListIdentifiersRunner
(
config
,
repository
,
this
)
.
run
()
case
_:
OaiVerb.ListMetadataFormats.
type
=>
ListMetadataFormatsRunner
(
config
,
repository
,
this
)
.
run
()
verb
.
get
match
{
case
_:
OaiVerb.GetRecord.
type
=>
GetRecordRunner
(
config
,
repository
,
this
)
case
_:
OaiVerb.ListRecords.
type
=>
ListRecordsRunner
(
config
,
repository
,
this
)
case
_:
OaiVerb.ListSets.
type
=>
ListSetsRunner
(
config
,
repository
,
this
)
case
_:
OaiVerb.Identify.
type
=>
IdentifyRunner
(
config
,
repository
,
this
)
case
_:
OaiVerb.ListIdentifiers.
type
=>
ListIdentifiersRunner
(
config
,
repository
,
this
)
case
_:
OaiVerb.ListMetadataFormats.
type
=>
ListMetadataFormatsRunner
(
config
,
repository
,
this
)
//case _ => IdentifyRunner(config, repository, this).run()
}
...
...
@@ -198,7 +201,7 @@ case class OaiRequest(override val verb:OaiVerb,
else
{
//todo: create not legal runner
ListMetadataFormatsRunner
(
config
,
repository
,
this
)
.
run
()
ListMetadataFormatsRunner
(
config
,
repository
,
this
)
}
}
...
...
@@ -206,22 +209,48 @@ case class OaiRequest(override val verb:OaiVerb,
}
case
class
OaiRequestIllegalVerb
(
override
val
verb
:
OaiVerb
,
override
val
metadataPrefix
:
Option
[
String
],
override
val
set
:
Option
[
String
],
override
val
from
:
Option
[
String
],
override
val
until
:
Option
[
String
],
override
val
identifier
:
Option
[
String
],
override
val
resumptionToken
:
Option
[
String
])
extends
UserRequest
(
verb
,
metadataPrefix
,
set
,
from
,
until
,
identifier
,
resumptionToken
)
{
override
def
execute
(
config
:
Configuration
,
repository
:
OaiRepository
)
:
OaiResponse
=
GetExceptionRunner
(
config
,
repository
,
this
).
run
()
}
\ No newline at end of file
case
class
WrongOaiRequest
(
validationError
:
ValidationError
)
extends
UserRequest
(
verb
=
None
,
metadataPrefix
=
None
,
set
=
None
,
from
=
None
,
until
=
None
,
identifier
=
None
,
resumptionToken
=
None
)
{
override
def
getRunner
(
config
:
Configuration
,
repository
:
OaiRepository
)
:
OaiRequestRunner
=
{
GetExceptionRunner
(
config
,
repository
,
this
)
}
}
case
class
FailedOaiRequest
(
validationError
:
ValidationError
)
extends
UserRequest
(
verb
=
None
,
metadataPrefix
=
None
,
set
=
None
,
from
=
None
,
until
=
None
,
identifier
=
None
,
resumptionToken
=
None
)
{
override
def
getRunner
(
config
:
Configuration
,
repository
:
OaiRepository
)
:
OaiRequestRunner
=
{
GetExceptionRunner
(
config
,
repository
,
this
)
}
}
case
class
SystemFailureOaiRequest
(
validationError
:
ValidationError
)
extends
UserRequest
(
verb
=
None
,
metadataPrefix
=
None
,
set
=
None
,
from
=
None
,
until
=
None
,
identifier
=
None
,
resumptionToken
=
None
)
{
override
def
getRunner
(
config
:
Configuration
,
repository
:
OaiRepository
)
:
OaiRequestRunner
=
{
GetExceptionRunner
(
config
,
repository
,
this
)
}
}
\ No newline at end of file
app/org/swissbib/memobase/oai/response/OaiResponse.scala
View file @
57db067a
...
...
@@ -6,7 +6,7 @@ import org.swissbib.memobase.oai.runner.OaiRequestRunner
import
scala.xml.
{
Elem
,
Node
,
Text
}
import
scala.xml.transform.
{
RewriteRule
,
RuleTransformer
}
class
OaiResponse
(
val
oaiRequestRunner
:
OaiRequestRunner
)
{
sealed
abstract
class
OaiResponse
(
val
oaiRequestRunner
:
OaiRequestRunner
)
{
def
makeHeader
(
del
:
Boolean
=
false
,
set
:
String
=
"memobaseSet"
,
...
...
@@ -41,8 +41,8 @@ class OaiResponse(val oaiRequestRunner:OaiRequestRunner) {
}
def
createResponse
:
Seq
[
Node
]
=
???
def
createRequestTag
:
Elem
=
???
def
createResponse
:
Seq
[
Node
]
def
createRequestTag
:
Elem
override
def
toString
:
String
=
s
"Ich bin eine OAI response mit Header für : ${oaiRequestRunner.request.verb} "
...
...
app/org/swissbib/memobase/oai/runner/OaiRequestRunner.scala
View file @
57db067a
...
...
@@ -7,7 +7,7 @@ import play.api.Configuration
import
scala.xml.
{
Elem
,
Node
}
abstract
class
OaiRequestRunner
(
val
config
:
Configuration
,
sealed
abstract
class
OaiRequestRunner
(
val
config
:
Configuration
,
val
repository
:
OaiRepository
,
val
request
:
UserRequest
){
var
result
:
Option
[(
String
,
Elem
)]
=
None
...
...
@@ -18,7 +18,7 @@ abstract class OaiRequestRunner (val config: Configuration,
//todo: this is wrong!
sealed
case
class
IdentifyRunner
(
override
val
config
:
Configuration
,
case
class
IdentifyRunner
(
override
val
config
:
Configuration
,
override
val
repository
:
OaiRepository
,
override
val
request
:
OaiRequest
)
extends
OaiRequestRunner
(
config
,
repository
,
...
...
@@ -107,8 +107,8 @@ case class ListSetsRunner(override val config: Configuration,
case
class
GetExceptionRunner
(
override
val
config
:
Configuration
,
override
val
repository
:
OaiRepository
,
override
val
request
:
UserRequest
)
extends
OaiRequestRunner
(
config
,
repository
,
request
)
{
repository
,
request
)
{
override
def
run
()
:
OaiResponse
=
???
}
...
...
conf/routes
View file @
57db067a
GET / controllers.OaiController.handleRequest(verb:String, metadataPrefix:Option[String], set:Option[String], from:Option[String], until:Option[String], identifier: Option[String], resumptionToken: Option[String])
GET / controllers.OaiController.handleRequest(verb:
Option[
String
]
, metadataPrefix:Option[String], set:Option[String], from:Option[String], until:Option[String], identifier: Option[String], resumptionToken: Option[String])
#Test with Bindcontroller
GET /testBinding controllers.BindController.age(age:controllers.BindController.AgeRange)
...
...
doc/oai.graphml
View file @
57db067a
This diff is collapsed.
Click to expand it.
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment