blueeyes russian
TRANSCRIPT
![Page 1: BlueEyes russian](https://reader034.vdocuments.net/reader034/viewer/2022042815/55649235d8b42ab8278b4728/html5/thumbnails/1.jpg)
BlueEyes
Michael Lagutko @mlagutko
![Page 2: BlueEyes russian](https://reader034.vdocuments.net/reader034/viewer/2022042815/55649235d8b42ab8278b4728/html5/thumbnails/2.jpg)
Цели
• Создание RESTful сервисов • Высокая производительность (асинхронная обработка запросов)
• Масштабируемость (отсутствие поддержки состояния)
• Автомотическое тестирование (Независимость от сервера)
![Page 3: BlueEyes russian](https://reader034.vdocuments.net/reader034/viewer/2022042815/55649235d8b42ab8278b4728/html5/thumbnails/3.jpg)
Service
• BlueEyesServiceBuilder • Комбинаторы оброботчиков запросов • Уникальное имя и версия • Жизненный цикл
• Контекст
![Page 4: BlueEyes russian](https://reader034.vdocuments.net/reader034/viewer/2022042815/55649235d8b42ab8278b4728/html5/thumbnails/4.jpg)
Жизненный цикл сервиса
• Старт • Обработка запросов • Остановка
![Page 5: BlueEyes russian](https://reader034.vdocuments.net/reader034/viewer/2022042815/55649235d8b42ab8278b4728/html5/thumbnails/5.jpg)
Комбинаторы оброботчиков запросов
• path(*padern*) { ... } • contentType(*mimeType*) { ... } • get { ... } • put { ... } • post { ... } • delete { ... } • … path("/emails"){ get { request => val response = H"pResponse(content = Some(emailIds)) Future.sync{response } } }
![Page 6: BlueEyes russian](https://reader034.vdocuments.net/reader034/viewer/2022042815/55649235d8b42ab8278b4728/html5/thumbnails/6.jpg)
Комбинаторы путей
• Строковый: "/foo/bar” • Символьный: "/foo/'fooId” • Но основе регулярных выражений:"/foo/bar/baz.(?
<extension>\w{3,4})” path("/emails"){ path('emailId) { path("(?<bar>[a‐z]+)"){ get { request => val fooId = request.parameters('fooId) val extension = request.parameters('extension) ... } } } }
![Page 7: BlueEyes russian](https://reader034.vdocuments.net/reader034/viewer/2022042815/55649235d8b42ab8278b4728/html5/thumbnails/7.jpg)
Комбинации оброботчиков запросов
produces(applicavon/json) { path("/users/") { get { request => // get list of all users ... } ~ path('userId) { parameter('userId) { userId => get { request => // get user ... } ~ put { request => // update user ... } } } } }
![Page 8: BlueEyes russian](https://reader034.vdocuments.net/reader034/viewer/2022042815/55649235d8b42ab8278b4728/html5/thumbnails/8.jpg)
Контекст
• Конфигурация • Имя сервиса • Версия сервиса
![Page 9: BlueEyes russian](https://reader034.vdocuments.net/reader034/viewer/2022042815/55649235d8b42ab8278b4728/html5/thumbnails/9.jpg)
Простой сервис trait EmailServices extends BlueEyesServiceBuilder { val emailService = service("email", "1.32") { context => startup { loadContactList(context.config("contactFile")) } ‐> request { contactList => path("/emails/") { produce(applicavon/json) { get { request => Future.async{ … H"pResponse(content = Some(JArray(emailIds))) } } } } ~ path('emailId) { produce(applicavon/json) { get { request => val emailId = request.parameters('emailId) ... Future.sync(H"pResponse(content = Some(emailObj))) } } } } ‐> shutdown { contactList => contactList.finalize } } }
![Page 10: BlueEyes russian](https://reader034.vdocuments.net/reader034/viewer/2022042815/55649235d8b42ab8278b4728/html5/thumbnails/10.jpg)
HdpRequest
• method: HdpMethod • uri: URI • parameters: Map[Symbol, String]
• headers: HdpHeaders • content: Op]on[ByteChunk] • …
![Page 11: BlueEyes russian](https://reader034.vdocuments.net/reader034/viewer/2022042815/55649235d8b42ab8278b4728/html5/thumbnails/11.jpg)
HdpResponse
• status: HdpStatus • headers: HdpHeaders • content: Op]on[ByteChunk] • …
![Page 12: BlueEyes russian](https://reader034.vdocuments.net/reader034/viewer/2022042815/55649235d8b42ab8278b4728/html5/thumbnails/12.jpg)
ByteChunk
trait Chunk[T]{ def data: T
def next: Opvon[Future[Chunk[T]]]
}
type ByteChunk = Chunk[Array[Byte]]
![Page 13: BlueEyes russian](https://reader034.vdocuments.net/reader034/viewer/2022042815/55649235d8b42ab8278b4728/html5/thumbnails/13.jpg)
Получение всего контента запроса
path("/emails/") { aggregate(None){ get { request: H"pRequest[ByteChunk] => Future.async{ … HdpResponse(content = Some(JArray(emailIds))) } } } }
![Page 14: BlueEyes russian](https://reader034.vdocuments.net/reader034/viewer/2022042815/55649235d8b42ab8278b4728/html5/thumbnails/14.jpg)
Бизнесс данные
• Explicitly: post { request: H"pRequest[ByteChunk] => val bijecvon = BijecvonsChunkJson.ChunkToJValue val emailId = request.content.map(bijec]on(_)) ... Future.sync(HdpResponse(content = Some(bijec]on.Inverse(emailObj)))) }
• Implicitly: trait EmailServices extends BlueEyesServiceBuilder with Bijec]onsChunkJson … contentType(MimeTypes.applica]on/MimeTypes.json) { post { request: H"pRequest[JValue] => val emailId = request.content ... Future.sync(HdpResponse(content = Some(emailObj))) } }
![Page 15: BlueEyes russian](https://reader034.vdocuments.net/reader034/viewer/2022042815/55649235d8b42ab8278b4728/html5/thumbnails/15.jpg)
Расширение сирвисов
• Фабрики сервис дескрипторов • Logging • Health monitors
• Request logging
![Page 16: BlueEyes russian](https://reader034.vdocuments.net/reader034/viewer/2022042815/55649235d8b42ab8278b4728/html5/thumbnails/16.jpg)
Logging trait LogDemo extends BlueEyesServiceBuilder { val logDemoService = service("logdemo", "1.32") { logging { log => context => startup { request { state => path("/foo") { contentType(applicavon/json) { get { request => log.info("request at /foo") ... } } } } } }
![Page 17: BlueEyes russian](https://reader034.vdocuments.net/reader034/viewer/2022042815/55649235d8b42ab8278b4728/html5/thumbnails/17.jpg)
Request Logging (W3C Extended Log format)
trait RequestLogDemo extends BlueEyesServiceBuilder { val requestLogDemoService = service("requestlogdemo", "1.32") { requestLogging{ context => startup { request { state => path("/foo") { contentType(applicavon/json) { get { request => ... } } } } } }
“requestLog” секция: "enabled = true | false" ( default = true ) "fields = see W3C Extended Log format" "roll = "never" | "hourly" | "daily" | "sunday" | "monday" | "tuesday" | "wednesday" | "thursday" | "friday" |
"saturday" " ( default = "never") "file = path to log file" "writeDelaySeconds = delay between flush to file" ( default = 1 )
![Page 18: BlueEyes russian](https://reader034.vdocuments.net/reader034/viewer/2022042815/55649235d8b42ab8278b4728/html5/thumbnails/18.jpg)
Health Monitor
• /blueeyes/services/[serviceName]/v[serviceMajorVersion]/health
trait HealthMonitorDemo extends BlueEyesServiceBuilder { val healthMonitorService = service("healthmon", "1.32") { healthMonitor { monitor => context => request { state => path("/foo") { contentType(applicavon/json) { get { request => monitor.vme(".requests.foo.vming") { ... } } } } } } }
![Page 19: BlueEyes russian](https://reader034.vdocuments.net/reader034/viewer/2022042815/55649235d8b42ab8278b4728/html5/thumbnails/19.jpg)
HdpClient
• HdpClient • HdpClientXLightWebEngines val responseFuture = client.get("hdp://myservice.com/foo")
responseFuture map {response => response.content.get}
def myService: HdpClient[JValue] = client.path("hdp://myservice.com/").contentType[JValue](applicavon/json)
val responseFuture = myService.get("api/v1")
responseFuture map {response => response.content.get}
![Page 20: BlueEyes russian](https://reader034.vdocuments.net/reader034/viewer/2022042815/55649235d8b42ab8278b4728/html5/thumbnails/20.jpg)
Тестирваоние
• Полная потдержка Scala Specs • Не требует старта сервера
![Page 21: BlueEyes russian](https://reader034.vdocuments.net/reader034/viewer/2022042815/55649235d8b42ab8278b4728/html5/thumbnails/21.jpg)
Пример простого теста
class EmailServicesSpec extends BlueEyesServiceSpecifica]on with EmailServices {
"EmailService" should {
"get emails" in {
val f = service.contentType[JValue](applicavon/json).get("/emails") f.value must eventually(beSomething)
val response = f.value.get
response.status mustEqual(HdpStatus(OK))
} }
}
![Page 22: BlueEyes russian](https://reader034.vdocuments.net/reader034/viewer/2022042815/55649235d8b42ab8278b4728/html5/thumbnails/22.jpg)
Запуск сервиса
object AppServer extends BlueEyesServer with EmailServices with OrderProcessingServices with LoginServices with CatalogServices
val startFuture = AppServer .start
val stopFuture = AppServer .stop
java ‐jar appserver.jar ‐‐configFile /etc/default/appserver.conf
![Page 23: BlueEyes russian](https://reader034.vdocuments.net/reader034/viewer/2022042815/55649235d8b42ab8278b4728/html5/thumbnails/23.jpg)
Данные
• Библиотека JSON
![Page 24: BlueEyes russian](https://reader034.vdocuments.net/reader034/viewer/2022042815/55649235d8b42ab8278b4728/html5/thumbnails/24.jpg)
MongoDB
• BlueEyes MongoDB QL • Потдержка Mock MongoDB