1 /** 2 * Реализация приложения для содания приложения сервиса 3 * 4 * Copyright: (c) 2015-2017, Milofon Project. 5 * License: Subject to the terms of the BSD license, as written in the included LICENSE.txt file. 6 * Author: <m.galanin@milofon.org> Maksim Galanin 7 * Date: 2018-01-24 8 */ 9 10 module dango.service.application; 11 12 public 13 { 14 import proped : Properties; 15 import poodinis : DependencyContainer; 16 } 17 18 private 19 { 20 import std.format : fmt = format; 21 22 import dango.system.application; 23 import dango.system.container : resolveByName; 24 import dango.system.properties : getOrEnforce, getNameOrEnforce; 25 import dango.system.exception : configEnforce; 26 27 import dango.service.transport; 28 import dango.service.serializer; 29 import dango.service.protocol; 30 import dango.service.dispatcher; 31 import dango.service.controller; 32 } 33 34 35 abstract class ServiceApplication : DaemonApplication 36 { 37 private ServerTransport[] _transports; 38 39 40 this(string name, string release) 41 { 42 super(name, release); 43 } 44 45 46 override final void initDependencies(shared(DependencyContainer) container, Properties config) 47 { 48 container.registerContext!TransportContext; 49 container.registerContext!SerializerContext; 50 container.registerContext!ProtocolContext; 51 52 initServiceDependencies(container, config); 53 } 54 55 56 this(string name, SemVer release) 57 { 58 super(name, release); 59 } 60 61 62 override void initializeDaemon(Properties config) 63 { 64 initializeService(config); 65 66 auto sConfgs = config.getOrEnforce!Properties("service", 67 "Not found service configurations"); 68 69 foreach (Properties servConf; sConfgs.getArray()) 70 { 71 if (servConf.getOrElse("enabled", false)) 72 { 73 Properties trConf = servConf.getOrEnforce!Properties("transport", 74 "Not defined transport config"); 75 Properties serConf = servConf.getOrEnforce!Properties("serializer", 76 "Not defined serializer config"); 77 Properties protoConf = servConf.getOrEnforce!Properties("protocol", 78 "Not defined protocol config"); 79 80 string serviceName = servConf.getOrEnforce!string("name", 81 "Not defined service name"); 82 string serializerName = getNameOrEnforce(serConf, 83 "Not defined serializer name"); 84 string protoName = getNameOrEnforce(protoConf, 85 "Not defined protocol name"); 86 string transportName = getNameOrEnforce(trConf, 87 "Not defined transport name"); 88 89 Serializer serializer = container.resolveByName!Serializer(serializerName); 90 serializer.initialize(serConf); 91 configEnforce(serializer !is null, 92 "Serializer '%s' not register".fmt(serializerName)); 93 94 Dispatcher dispatcher = new Dispatcher(); 95 96 RpcServerProtocol protocol = container.resolveByName!RpcServerProtocol(protoName); 97 configEnforce(protocol !is null, 98 "Protocol '%s' not register".fmt(protoName)); 99 protocol.initialize(dispatcher, serializer, protoConf); 100 101 ServerTransport tr = container.resolveByName!ServerTransport(transportName); 102 configEnforce(tr !is null, 103 "Transport '%s' not register".fmt(transportName)); 104 105 foreach (Properties ctrConf; servConf.getArray("controller")) 106 { 107 string ctrName = getNameOrEnforce(ctrConf, 108 "Not defined controller name"); 109 110 Controller ctrl = container.resolveByName!Controller(ctrName); 111 configEnforce(ctrl !is null, "Controller '%s' not register".fmt(ctrName)); 112 113 ctrl.initialize(serializer, ctrConf); 114 if (ctrl.enabled) 115 { 116 ctrl.register(dispatcher); 117 logInfo("Register '%s' controller", ctrName); 118 } 119 } 120 121 tr.listen(protocol, trConf); 122 _transports ~= tr; 123 } 124 } 125 } 126 127 128 override int finalizeDaemon(int exitCode) 129 { 130 foreach (ServerTransport tr; _transports) 131 tr.shutdown(); 132 return finalizeService(exitCode); 133 } 134 135 protected: 136 137 /** 138 * Регистрация зависимостей сервиса 139 * Params: 140 * container = DI контейнер 141 * config = Общая конфигурация приложения 142 */ 143 void initServiceDependencies(shared(DependencyContainer) container, Properties config); 144 145 146 /** 147 * Инициализация сервиса 148 * Params: 149 * config = Общая конфигурация приложения 150 */ 151 void initializeService(Properties config); 152 153 154 /** 155 * Завершение работы сервиса 156 * Params: 157 * exitCode = Код возврата 158 */ 159 int finalizeService(int exitCode); 160 }