mirror of
https://github.com/corda/corda.git
synced 2025-01-31 08:25:50 +00:00
Merged in plt-17-api-server-infra (pull request #30)
Jersey / Jackson / JAX-RS added to nodes
This commit is contained in:
commit
00294e78cc
19
build.gradle
19
build.gradle
@ -16,7 +16,8 @@ buildscript {
|
||||
ext.quasar_version = '0.7.5-SNAPSHOT'
|
||||
ext.asm_version = '0.5.3'
|
||||
ext.artemis_version = '1.2.0'
|
||||
ext.jetty_version = '9.3.7.v20160115'
|
||||
ext.jetty_version = '9.1.1.v20140108'
|
||||
ext.jersey_version = '2.22.2'
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
@ -99,6 +100,22 @@ dependencies {
|
||||
compile "org.jolokia:jolokia-agent-war:2.0.0-M1"
|
||||
compile "commons-fileupload:commons-fileupload:1.3.1"
|
||||
|
||||
// Jersey for JAX-RS implementation for use in Jetty
|
||||
compile "org.glassfish.jersey.core:jersey-server:${jersey_version}"
|
||||
compile "org.glassfish.jersey.containers:jersey-container-servlet-core:${jersey_version}"
|
||||
compile "org.glassfish.jersey.containers:jersey-container-jetty-http:${jersey_version}"
|
||||
// NOTE there is a Jackson version clash between jersey-media-json-jackson (v2.5.4) and jackson-module-kotlin (v.2.5.5)
|
||||
// Have not found an Issue in the issue tracker for Jersey for this issue
|
||||
compile ("org.glassfish.jersey.media:jersey-media-json-jackson:${jersey_version}") {
|
||||
exclude group: 'com.fasterxml.jackson.core', module: 'jackson-annotations'
|
||||
exclude group: 'com.fasterxml.jackson.core', module: 'jackson-databind'
|
||||
exclude group: 'com.fasterxml.jackson.core', module: 'jackson-core'
|
||||
}
|
||||
compile ("com.fasterxml.jackson.module:jackson-module-kotlin:2.5.5-2") {
|
||||
exclude group: 'com.fasterxml.jackson.core', module: 'jackson-annotations'
|
||||
}
|
||||
compile "com.fasterxml.jackson.core:jackson-annotations:2.5.5"
|
||||
|
||||
// Unit testing helpers.
|
||||
testCompile 'junit:junit:4.12'
|
||||
testCompile 'com.google.jimfs:jimfs:1.1' // in memory java.nio filesystem.
|
||||
|
51
src/main/kotlin/api/Config.kt
Normal file
51
src/main/kotlin/api/Config.kt
Normal file
@ -0,0 +1,51 @@
|
||||
package api
|
||||
|
||||
import com.fasterxml.jackson.core.JsonGenerator
|
||||
import com.fasterxml.jackson.core.JsonParser
|
||||
import com.fasterxml.jackson.databind.*
|
||||
import com.fasterxml.jackson.databind.module.SimpleModule
|
||||
import com.fasterxml.jackson.module.kotlin.KotlinModule
|
||||
import java.time.LocalDate
|
||||
import javax.ws.rs.ext.ContextResolver
|
||||
import javax.ws.rs.ext.Provider
|
||||
|
||||
/**
|
||||
* Primary purpose is to install Kotlin extensions for Jackson ObjectMapper so data classes work
|
||||
* and to organise serializers / deserializers for java.time.* classes as necessary
|
||||
*/
|
||||
@Provider
|
||||
class Config: ContextResolver<ObjectMapper> {
|
||||
|
||||
val defaultObjectMapper = createDefaultMapper()
|
||||
|
||||
override fun getContext(type: java.lang.Class<*>): ObjectMapper {
|
||||
return defaultObjectMapper
|
||||
}
|
||||
|
||||
companion object {
|
||||
private fun createDefaultMapper(): ObjectMapper {
|
||||
val mapper = ObjectMapper()
|
||||
mapper.enable(SerializationFeature.INDENT_OUTPUT);
|
||||
mapper.enable(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS)
|
||||
mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false); // Although we shouldn't really use java.util.* but instead java.time.*
|
||||
val timeModule = SimpleModule("java.time")
|
||||
timeModule.addSerializer(LocalDate::class.java, ToStringSerializer)
|
||||
timeModule.addDeserializer(LocalDate::class.java, LocalDateDeserializer)
|
||||
mapper.registerModule(timeModule)
|
||||
mapper.registerModule(KotlinModule())
|
||||
return mapper
|
||||
}
|
||||
}
|
||||
|
||||
object ToStringSerializer: JsonSerializer<Any>() {
|
||||
override fun serialize(obj: Any, generator: JsonGenerator, provider: SerializerProvider) {
|
||||
generator.writeString(obj.toString())
|
||||
}
|
||||
}
|
||||
|
||||
object LocalDateDeserializer: JsonDeserializer<LocalDate>() {
|
||||
override fun deserialize(parser: JsonParser, context: DeserializationContext): LocalDate {
|
||||
return LocalDate.parse(parser.text)
|
||||
}
|
||||
}
|
||||
}
|
@ -8,6 +8,7 @@
|
||||
|
||||
package core.node
|
||||
|
||||
import api.Config
|
||||
import com.google.common.net.HostAndPort
|
||||
import core.messaging.LegallyIdentifiableNode
|
||||
import core.messaging.MessagingService
|
||||
@ -18,6 +19,9 @@ import core.utilities.loggerFor
|
||||
import org.eclipse.jetty.server.Server
|
||||
import org.eclipse.jetty.server.handler.HandlerCollection
|
||||
import org.eclipse.jetty.servlet.ServletContextHandler
|
||||
import org.eclipse.jetty.servlet.ServletHolder
|
||||
import org.glassfish.jersey.server.ServerProperties
|
||||
import org.glassfish.jersey.servlet.ServletContainer
|
||||
import org.eclipse.jetty.webapp.WebAppContext
|
||||
import java.io.RandomAccessFile
|
||||
import java.lang.management.ManagementFactory
|
||||
@ -25,6 +29,7 @@ import java.nio.channels.FileLock
|
||||
import java.nio.file.Files
|
||||
import java.nio.file.Path
|
||||
import java.nio.file.StandardOpenOption
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
class ConfigurationException(message: String) : Exception(message)
|
||||
|
||||
@ -73,12 +78,21 @@ class Node(dir: Path, val p2pAddr: HostAndPort, configuration: NodeConfiguration
|
||||
})
|
||||
}
|
||||
|
||||
// Data upload and download to services (attachments, rates oracles etc)
|
||||
// API, data upload and download to services (attachments, rates oracles etc)
|
||||
handlerCollection.addHandler(ServletContextHandler().apply {
|
||||
contextPath = "/"
|
||||
setAttribute("storage", storage)
|
||||
addServlet(DataUploadServlet::class.java, "/upload/*")
|
||||
addServlet(AttachmentDownloadServlet::class.java, "/attachments/*")
|
||||
|
||||
setAttribute("services", services)
|
||||
val jerseyServlet = addServlet(ServletContainer::class.java, "/api/*")
|
||||
// Give the app a slightly better name in JMX rather than a randomly generated one
|
||||
jerseyServlet.setInitParameter(ServerProperties.APPLICATION_NAME, "node.api")
|
||||
jerseyServlet.setInitParameter(ServerProperties.MONITORING_STATISTICS_MBEANS_ENABLED, "true")
|
||||
jerseyServlet.initOrder = 0 // Initialise at server start
|
||||
// Add your API provider classes (annotated for JAX-RS) here
|
||||
setProviders(jerseyServlet, Config::class)
|
||||
})
|
||||
|
||||
server.handler = handlerCollection
|
||||
@ -86,6 +100,11 @@ class Node(dir: Path, val p2pAddr: HostAndPort, configuration: NodeConfiguration
|
||||
return server
|
||||
}
|
||||
|
||||
private fun setProviders(jerseyServlet: ServletHolder, vararg providerClasses: KClass<out Any>) {
|
||||
val providerClassNames = providerClasses.map { it.java.canonicalName }.joinToString()
|
||||
jerseyServlet.setInitParameter(ServerProperties.PROVIDER_CLASSNAMES, providerClassNames)
|
||||
}
|
||||
|
||||
override fun start(): Node {
|
||||
alreadyRunningNodeCheck()
|
||||
super.start()
|
||||
|
Loading…
x
Reference in New Issue
Block a user