diff --git a/docker-compose.test.yml b/docker-compose.test.yml
index 0e1e30b892c76f654a2596fb8415f891f05eedfb..398f1633077b69fdad5eda27883d2524ea31c141 100644
--- a/docker-compose.test.yml
+++ b/docker-compose.test.yml
@@ -12,6 +12,7 @@ services:
     container_name: 'test_corporate_builder2'
     depends_on:
       - test_db
+      - test_mbroker
     working_dir: '/app'
     networks:
       - test_corporate_network
@@ -31,4 +32,12 @@ services:
     networks:
       test_corporate_network:
         aliases:
-          - corporate_db2
\ No newline at end of file
+          - corporate_db2
+
+  test_mbroker:
+    image: 'rmohr/activemq:5.15.9'
+    container_name: 'test_corporate_broker2'
+    networks:
+      test_corporate_network:
+        aliases:
+          - actvemq
\ No newline at end of file
diff --git a/docker-compose.yml b/docker-compose.yml
index 09eba51bf484cfc2417414989601d199d170c9c5..c3b27178a1c4a2380333d6f8ff7320a6d953da01 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -1,5 +1,7 @@
 version: '3.7'
-
+networks:
+  corporate_app2_prod_net:
+    name: 'ca2pd'
 services:
 
   boot:
@@ -12,6 +14,8 @@ services:
     depends_on:
       - db
     working_dir: '/app'
+    networks:
+      - corporate_app2_prod_net
     volumes:
       - .:/app
       - m2:/root/.m2
@@ -31,6 +35,8 @@ services:
     image: 'postgres:10-alpine'
     container_name: 'corporate_db2'
     restart: always
+    networks:
+      - corporate_app2_prod_net
     environment:
       POSTGRES_DB: cinema
       POSTGRES_USER: postgres
@@ -40,6 +46,21 @@ services:
     volumes:
       - db_data:/var/lib/postgresql/data
 
+  mbroker:
+    image: 'rmohr/activemq:5.15.9'
+    container_name: 'corporate_broker2'
+    networks:
+      corporate_app2_prod_net:
+        aliases:
+          - actvemq
+    volumes:
+      - active_mq_data:/opt/activemq/data
+      - active_mq_conf:/opt/activemq/conf
+    ports:
+      - 8161:8161
+
 volumes:
   m2:
-  db_data:
\ No newline at end of file
+  db_data:
+  active_mq_data:
+  active_mq_conf:
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 46dd59469a2d448aa4bd8878f619a921ed2d1309..889e40ea4b08d480b43a9cc14bd4037184c0e272 100644
--- a/pom.xml
+++ b/pom.xml
@@ -32,6 +32,22 @@
             <groupId>org.postgresql</groupId>
             <artifactId>postgresql</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-jms</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-mail</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-activemq</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.activemq</groupId>
+            <artifactId>activemq-broker</artifactId>
+        </dependency>
         <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-web</artifactId>
@@ -89,26 +105,6 @@
                     <excludeDevtools>false</excludeDevtools>
                 </configuration>
             </plugin>
-            <plugin>
-                <groupId>org.jacoco</groupId>
-                <artifactId>jacoco-maven-plugin</artifactId>
-                <version>0.8.3</version>
-                <executions>
-                    <execution>
-                        <id>pre-unit-test</id>
-                        <goals>
-                            <goal>prepare-agent</goal>
-                        </goals>
-                    </execution>
-                    <execution>
-                        <id>post-unit-test</id>
-                        <phase>test</phase>
-                        <goals>
-                            <goal>report</goal>
-                        </goals>
-                    </execution>
-                </executions>
-            </plugin>
             <plugin>
                 <artifactId>exec-maven-plugin</artifactId>
                 <groupId>org.codehaus.mojo</groupId>
@@ -144,6 +140,25 @@
                     </dependency>
                 </dependencies>
             </plugin>
+            <plugin>
+                <groupId>org.jacoco</groupId>
+                <artifactId>jacoco-maven-plugin</artifactId>
+                <version>0.8.5</version>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>prepare-agent</goal>
+                        </goals>
+                    </execution>
+                    <execution>
+                        <id>report</id>
+                        <phase>test</phase>
+                        <goals>
+                            <goal>report</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
         </plugins>
     </build>
 
diff --git a/src/main/kotlin/com/s3ai/corporate_app2/CorporateApp2Application.kt b/src/main/kotlin/com/s3ai/corporate_app2/CorporateApp2Application.kt
index feef50de9919ca0ca70044ac405dc7c9a1bc1589..151fdcb95dfbfbd0da685dd500e733cc86de2088 100644
--- a/src/main/kotlin/com/s3ai/corporate_app2/CorporateApp2Application.kt
+++ b/src/main/kotlin/com/s3ai/corporate_app2/CorporateApp2Application.kt
@@ -2,8 +2,11 @@ package com.s3ai.corporate_app2
 
 import org.springframework.boot.autoconfigure.SpringBootApplication
 import org.springframework.boot.runApplication
+import org.springframework.jms.annotation.EnableJms
+
 
 @SpringBootApplication
+@EnableJms
 class CorporateApp2Application
 
 fun main(args: Array<String>) {
diff --git a/src/main/kotlin/com/s3ai/corporate_app2/controllers/CinemasController.kt b/src/main/kotlin/com/s3ai/corporate_app2/controllers/CinemasController.kt
index 7d6f4a938ff4621c66f54926ffab3b310bb9d2b4..0d17a4b4fcb76b8f76335734efdb00b570e3db8e 100644
--- a/src/main/kotlin/com/s3ai/corporate_app2/controllers/CinemasController.kt
+++ b/src/main/kotlin/com/s3ai/corporate_app2/controllers/CinemasController.kt
@@ -2,13 +2,18 @@ package com.s3ai.corporate_app2.controllers
 
 import com.s3ai.corporate_app2.Cinema
 import com.s3ai.corporate_app2.CinemaService
+import com.s3ai.corporate_app2.jms.JMSPublisher
 import org.springframework.beans.factory.annotation.Autowired
+import org.springframework.http.HttpStatus
 import org.springframework.stereotype.Controller
 import org.springframework.ui.Model
 import org.springframework.web.bind.annotation.*
+import org.springframework.web.client.HttpClientErrorException
+import org.springframework.web.server.ResponseStatusException
 import org.springframework.web.servlet.view.RedirectView
+import java.lang.IllegalArgumentException
+import java.util.*
 import java.util.UUID.fromString
-import java.util.UUID.randomUUID
 
 @Controller
 @RequestMapping("/cinemas")
@@ -16,9 +21,13 @@ class CinemasController {
     @Autowired
     lateinit var cinemaService: CinemaService
 
+    @Autowired
+    lateinit var publisher: JMSPublisher
+
     @GetMapping("/list")
     fun getCinemasBrowsePage(model: Model): String? {
-        model.addAttribute("cinemas", cinemaService.findAll())
+        val items = getAllItems(cinemaService, publisher)
+        model.addAttribute("cinemas", items)
         return "cinemas/list"
     }
 
@@ -27,10 +36,16 @@ class CinemasController {
         val cinema: Cinema?
         if (id.isEmpty()) {
             cinema = Cinema()
-            cinema.id = randomUUID()
             model.addAttribute("action", "Create")
         } else {
-            cinema = cinemaService.findById(fromString(id))
+            val idParsed: UUID
+            try {
+                idParsed = fromString(id)
+            }
+            catch (e: IllegalArgumentException){
+                throw ResponseStatusException(HttpStatus.BAD_REQUEST)
+            }
+            cinema = cinemaService.findById(idParsed)
             model.addAttribute("action", "Edit")
         }
         model.addAttribute("cinema", cinema)
@@ -39,7 +54,7 @@ class CinemasController {
 
     @PostMapping("/update")
     fun updateCinema(@ModelAttribute cinema: Cinema): RedirectView {
-        cinemaService.save(cinema)
+        updateItem(cinemaService, cinema, cinema.id, publisher)
         return RedirectView("/cinemas/list")
     }
 }
\ No newline at end of file
diff --git a/src/main/kotlin/com/s3ai/corporate_app2/controllers/SubscribersController.kt b/src/main/kotlin/com/s3ai/corporate_app2/controllers/SubscribersController.kt
new file mode 100644
index 0000000000000000000000000000000000000000..6974267b9402aeb68a6dac26ea51a983861091ad
--- /dev/null
+++ b/src/main/kotlin/com/s3ai/corporate_app2/controllers/SubscribersController.kt
@@ -0,0 +1,63 @@
+package com.s3ai.corporate_app2.controllers
+
+import com.s3ai.corporate_app2.jms.persistance.*
+import org.springframework.beans.factory.annotation.Autowired
+import org.springframework.stereotype.Controller
+import org.springframework.ui.Model
+import org.springframework.web.bind.annotation.*
+import org.springframework.web.servlet.view.RedirectView
+import java.util.*
+
+class FilterForm {
+    var actions: MutableList<JMSEntityAction> = mutableListOf()
+}
+
+@Controller
+@RequestMapping("/subscription")
+class SubscribersController {
+
+    @Autowired
+    lateinit var subscriberRepository: SubscribersRepository
+
+    @Autowired
+    lateinit var subTypeRepo: SubscriptionTypeRepository
+
+    @GetMapping("/subscribe")
+    fun getSubscribePage(model: Model): String? {
+        val subscriber: Subscriber?
+        subscriber = Subscriber()
+        subscriber.id = UUID.randomUUID()
+        model.addAttribute("subscriber", subscriber)
+        model.addAttribute("types", JMSEntityAction.values())
+        return "subscription/subscribe"
+    }
+
+    @GetMapping("/unsubscribe")
+    fun getUnsubscribePage(model: Model): String {
+        return "subscription/unsubscribe"
+    }
+
+
+    @PostMapping("/subscribe")
+    fun addSubscriber(@ModelAttribute sub: Subscriber, @ModelAttribute(name = "actions") actionsForm: FilterForm, model: Model): RedirectView {
+        if (actionsForm.actions.size < 1) return RedirectView("/")
+        val subscriber = subscriberRepository.save(sub)
+        for (action in actionsForm.actions) {
+            val newType = SubscriptionType()
+            newType.type = action
+            newType.subscriber = subscriber
+            subTypeRepo.save(newType)
+        }
+        return RedirectView("/")
+    }
+
+    @PostMapping("/unsubscribe")
+    fun unsubscribeByEmail(@RequestParam(name = "email", required = true) email: String, model: Model): RedirectView {
+        val user = subscriberRepository.findSubscriberByEmail(email)
+        if (user.isPresent) {
+            subscriberRepository.delete(user.get())
+        }
+        return RedirectView("/")
+    }
+
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/s3ai/corporate_app2/controllers/TicketsController.kt b/src/main/kotlin/com/s3ai/corporate_app2/controllers/TicketsController.kt
index 389362562e7f362a0ef9f33609ad32d32ce0fcd4..878cce6b4030d8f9a4ee6b1c50662c88ae215695 100644
--- a/src/main/kotlin/com/s3ai/corporate_app2/controllers/TicketsController.kt
+++ b/src/main/kotlin/com/s3ai/corporate_app2/controllers/TicketsController.kt
@@ -4,11 +4,15 @@ import com.s3ai.corporate_app2.CinemaService
 import com.s3ai.corporate_app2.Ticket
 import com.s3ai.corporate_app2.TicketService
 import com.s3ai.corporate_app2.UserService
+import com.s3ai.corporate_app2.jms.JMSPublisher
 import org.springframework.beans.factory.annotation.Autowired
+import org.springframework.http.HttpStatus
 import org.springframework.stereotype.Controller
 import org.springframework.ui.Model
 import org.springframework.web.bind.annotation.*
+import org.springframework.web.server.ResponseStatusException
 import org.springframework.web.servlet.view.RedirectView
+import java.lang.IllegalArgumentException
 import java.util.*
 
 @Controller
@@ -20,10 +24,13 @@ class TicketsController {
     lateinit var userService: UserService
     @Autowired
     lateinit var cinemaService: CinemaService
+    @Autowired
+    lateinit var publisher: JMSPublisher
 
     @GetMapping("/list")
     fun getTicketsBrowsePage(model: Model): String? {
-        model.addAttribute("tickets", ticketService.findAll())
+        val items = getAllItems(ticketService, publisher)
+        model.addAttribute("tickets", items)
         return "tickets/list"
     }
 
@@ -32,10 +39,16 @@ class TicketsController {
         val ticket: Ticket?
         if (id.isEmpty()) {
             ticket = Ticket()
-            ticket.id = UUID.randomUUID()
             model.addAttribute("action", "Create")
         } else {
-            ticket = ticketService.findById(UUID.fromString(id))
+            val idParsed: UUID
+            try {
+                idParsed = UUID.fromString(id)
+            }
+            catch (e: IllegalArgumentException){
+                throw ResponseStatusException(HttpStatus.BAD_REQUEST)
+            }
+            ticket = ticketService.findById(idParsed)
             model.addAttribute("action", "Edit")
         }
         model.addAttribute("ticket", ticket)
@@ -46,7 +59,7 @@ class TicketsController {
 
     @PostMapping("/update")
     fun updateTicket(@ModelAttribute ticket: Ticket): RedirectView {
-        ticketService.save(ticket)
+        updateItem(ticketService, ticket, ticket.id, publisher)
         return RedirectView("/tickets/list")
     }
 
diff --git a/src/main/kotlin/com/s3ai/corporate_app2/controllers/UsersController.kt b/src/main/kotlin/com/s3ai/corporate_app2/controllers/UsersController.kt
index 54179542bdaaead96f607c570c8f7046bb4dc781..5ea71ad523abf891aaf7d031fd42f35c0c481130 100644
--- a/src/main/kotlin/com/s3ai/corporate_app2/controllers/UsersController.kt
+++ b/src/main/kotlin/com/s3ai/corporate_app2/controllers/UsersController.kt
@@ -2,11 +2,15 @@ package com.s3ai.corporate_app2.controllers
 
 import com.s3ai.corporate_app2.User
 import com.s3ai.corporate_app2.UserService
+import com.s3ai.corporate_app2.jms.JMSPublisher
 import org.springframework.beans.factory.annotation.Autowired
+import org.springframework.http.HttpStatus
 import org.springframework.stereotype.Controller
 import org.springframework.ui.Model
 import org.springframework.web.bind.annotation.*
+import org.springframework.web.server.ResponseStatusException
 import org.springframework.web.servlet.view.RedirectView
+import java.lang.IllegalArgumentException
 import java.util.*
 
 @Controller
@@ -15,9 +19,13 @@ class UsersController {
     @Autowired
     lateinit var userService: UserService
 
+    @Autowired
+    lateinit var publisher: JMSPublisher
+
     @GetMapping("/list")
     fun getUsersBrowsePage(model: Model): String? {
-        model.addAttribute("users", userService.findAll())
+        val items = getAllItems(userService, publisher)
+        model.addAttribute("users", items)
         return "users/list"
     }
 
@@ -26,10 +34,16 @@ class UsersController {
         val user: User?
         if (id.isEmpty()) {
             user = User()
-            user.id = UUID.randomUUID()
             model.addAttribute("action", "Create")
         } else {
-            user = userService.findById(UUID.fromString(id))
+            val idParsed: UUID
+            try {
+                idParsed = UUID.fromString(id)
+            }
+            catch (e: IllegalArgumentException){
+                throw ResponseStatusException(HttpStatus.BAD_REQUEST)
+            }
+            user = userService.findById(idParsed)
             model.addAttribute("action", "Edit")
         }
         model.addAttribute("user", user)
@@ -38,7 +52,7 @@ class UsersController {
 
     @PostMapping("/update")
     fun updateUser(@ModelAttribute user: User): RedirectView {
-        userService.save(user)
+        updateItem(userService, user, user.id, publisher)
         return RedirectView("/users/list")
     }
 }
\ No newline at end of file
diff --git a/src/main/kotlin/com/s3ai/corporate_app2/controllers/controllerUtils.kt b/src/main/kotlin/com/s3ai/corporate_app2/controllers/controllerUtils.kt
index 1ae2e7b11f4484631bbdb02307aaec482838d2f5..f08a73a77c534d19c6978ea5b778ddda4b1c06aa 100644
--- a/src/main/kotlin/com/s3ai/corporate_app2/controllers/controllerUtils.kt
+++ b/src/main/kotlin/com/s3ai/corporate_app2/controllers/controllerUtils.kt
@@ -2,6 +2,9 @@ package com.s3ai.corporate_app2.controllers
 
 import com.fasterxml.jackson.dataformat.xml.XmlMapper
 import com.s3ai.corporate_app2.CinemaServices
+import com.s3ai.corporate_app2.jms.JMSPublisher
+import com.s3ai.corporate_app2.jms.persistance.JMSAction
+import com.s3ai.corporate_app2.jms.persistance.JMSEntityAction
 import org.springframework.util.ResourceUtils
 import java.io.StringReader
 import java.io.StringWriter
@@ -11,16 +14,25 @@ import javax.xml.transform.TransformerFactory
 import javax.xml.transform.stream.StreamResult
 import javax.xml.transform.stream.StreamSource
 
+fun publishMessage(publisher: JMSPublisher, entity: String, actionJMS: JMSEntityAction, description: String) {
+    val jmsAction = JMSAction()
+    jmsAction.entity = entity
+    jmsAction.actionJMS = actionJMS
+    jmsAction.actionDescription = description
+    publisher.publish(jmsAction)
+}
 
-fun <T> deleteInstance(id: String, instanceName: String, jpaService: CinemaServices<T>, response: HttpServletResponse): String? {
+fun <T> deleteInstance(id: String, jpaService: CinemaServices<T>, response: HttpServletResponse, publisher: JMSPublisher): String? {
     var responseString: String? = null
     try {
         val itemId = UUID.fromString(id)
-        val user = jpaService.findById(itemId)
-        if (null != user) jpaService.delete(user)
-        else {
+        val item = jpaService.findById(itemId)
+        if (null != item) {
+            jpaService.delete(item)
+            publishMessage(publisher, jpaService.itemName(), JMSEntityAction.DELETE, "Deleted object: $item")
+        } else {
             response.status = HttpServletResponse.SC_NOT_FOUND
-            responseString = "$instanceName was not Found"
+            responseString = "${jpaService.itemName()} was not Found"
         }
     } catch (e: IllegalArgumentException) {
         response.status = HttpServletResponse.SC_BAD_REQUEST
@@ -29,14 +41,30 @@ fun <T> deleteInstance(id: String, instanceName: String, jpaService: CinemaServi
     return responseString
 }
 
-fun <T> getInstance(id: UUID, jpaService: CinemaServices<T>, response: HttpServletResponse): T? {
+fun <T : Any> getInstance(id: UUID, jpaService: CinemaServices<T>, response: HttpServletResponse, publisher: JMSPublisher): T? {
     val item = jpaService.findById(id)
-    if (null != item) return item
-    else response.status = HttpServletResponse.SC_NOT_FOUND
+    publishMessage(publisher, jpaService.itemName(), JMSEntityAction.QUERY, "Queried object with id: $id, Found: $item")
+    if (null != item) {
+        return item
+    } else response.status = HttpServletResponse.SC_NOT_FOUND
     return null
 }
 
-fun XMLTransform(item: Any, resource_name: String): String {
+fun <T : Any> getAllItems(jpaService: CinemaServices<T>, publisher: JMSPublisher): MutableList<T> {
+    val items = jpaService.findAll()
+    publishMessage(publisher, jpaService.itemName(), JMSEntityAction.QUERY, "Queried all items, found ${items.size}.")
+    return items
+}
+
+fun <T : Any> updateItem(jpaService: CinemaServices<T>, item: T, item_id: UUID?, publisher: JMSPublisher) {
+    var action = JMSEntityAction.UPDATE
+    val updatedItem = jpaService.save(item)
+    val description = "New item data: $updatedItem"
+    if (null == item_id) action = JMSEntityAction.CREATE
+    publishMessage(publisher, jpaService.itemName(), action, description)
+}
+
+fun xsltTransform(item: Any, resource_name: String): String {
     val xmlMapper = XmlMapper()
     val xslt = StreamSource(ResourceUtils.getFile("classpath:xslt/$resource_name"))
     val xml = StreamSource(StringReader(xmlMapper.writeValueAsString(item)))
@@ -44,13 +72,4 @@ fun XMLTransform(item: Any, resource_name: String): String {
     val sw = StringWriter()
     transformer.transform(xml, StreamResult(sw))
     return sw.toString()
-}
-
-fun <T> getXSLTransformedInstance(id: UUID, jpaService: CinemaServices<T>, resource_name: String, response: HttpServletResponse): String {
-    val item = jpaService.findById(id)
-    if (null == item) response.status = HttpServletResponse.SC_NOT_FOUND
-    else {
-        return XMLTransform(item, resource_name)
-    }
-    return ""
-}
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/s3ai/corporate_app2/controllers/rest/CinemaApiController.kt b/src/main/kotlin/com/s3ai/corporate_app2/controllers/rest/CinemaApiController.kt
index b734aa12a01e7d566a5d02fcbb8693177abef7b1..a679374c9834c6eacf36c445c2b71c105e49b619 100644
--- a/src/main/kotlin/com/s3ai/corporate_app2/controllers/rest/CinemaApiController.kt
+++ b/src/main/kotlin/com/s3ai/corporate_app2/controllers/rest/CinemaApiController.kt
@@ -3,6 +3,7 @@ package com.s3ai.corporate_app2.controllers.rest
 import com.s3ai.corporate_app2.Cinema
 import com.s3ai.corporate_app2.CinemaService
 import com.s3ai.corporate_app2.controllers.deleteInstance
+import com.s3ai.corporate_app2.jms.JMSPublisher
 import org.springframework.beans.factory.annotation.Autowired
 import org.springframework.web.bind.annotation.*
 import java.util.*
@@ -15,6 +16,9 @@ class CinemaApiController {
     @Autowired
     lateinit var cinemaService: CinemaService
 
+    @Autowired
+    lateinit var publisher: JMSPublisher
+
     @GetMapping("/fill")
     fun fillCinemas(): String? {
         val locations: List<String> = listOf("Samara", "Izhevsk", "NeoTokyo", "Bangladesh", "Moscow", "Grozny");
@@ -34,7 +38,7 @@ class CinemaApiController {
 
     @DeleteMapping("/delete")
     fun deleteCinema(@RequestParam(name = "id", required = true) id: String, response: HttpServletResponse): String? {
-        return deleteInstance(id, "Cinema", cinemaService, response)
+        return deleteInstance(id, cinemaService, response, publisher)
     }
 
 }
\ No newline at end of file
diff --git a/src/main/kotlin/com/s3ai/corporate_app2/controllers/rest/TicketApiController.kt b/src/main/kotlin/com/s3ai/corporate_app2/controllers/rest/TicketApiController.kt
index d7b371151653b0989cb5c912c2e866a67b9d37a4..6de73ce6ee8c794673faa0be57b245872c870425 100644
--- a/src/main/kotlin/com/s3ai/corporate_app2/controllers/rest/TicketApiController.kt
+++ b/src/main/kotlin/com/s3ai/corporate_app2/controllers/rest/TicketApiController.kt
@@ -5,6 +5,7 @@ import com.s3ai.corporate_app2.Ticket
 import com.s3ai.corporate_app2.TicketService
 import com.s3ai.corporate_app2.UserService
 import com.s3ai.corporate_app2.controllers.deleteInstance
+import com.s3ai.corporate_app2.jms.JMSPublisher
 import org.springframework.beans.factory.annotation.Autowired
 import org.springframework.web.bind.annotation.*
 import java.util.*
@@ -15,11 +16,16 @@ import javax.servlet.http.HttpServletResponse
 class TicketApiController {
     @Autowired
     lateinit var userService: UserService
+
     @Autowired
     lateinit var ticketService: TicketService
+
     @Autowired
     lateinit var cinemaService: CinemaService
 
+    @Autowired
+    lateinit var publisher: JMSPublisher
+
     @GetMapping("/fill")
     fun fillTickets(): String? {
         val wordsFirst = arrayOf("Pirates", "Ladies", "Goblins", "Gangsters", "Programmers", "Hackers", "Wrestlers", "Animals", "Guardians")
@@ -44,7 +50,7 @@ class TicketApiController {
 
     @DeleteMapping("/delete")
     fun deleteTicket(@RequestParam(name = "id", required = true) id: String, response: HttpServletResponse): String? {
-        return deleteInstance(id, "Ticket", ticketService, response)
+        return deleteInstance(id, ticketService, response, publisher)
     }
 
 }
diff --git a/src/main/kotlin/com/s3ai/corporate_app2/controllers/rest/UserApiController.kt b/src/main/kotlin/com/s3ai/corporate_app2/controllers/rest/UserApiController.kt
index b9a0a8ca1612c25436ca6f78f8441506a585c79e..193396cb30d3d7f6645b849bbe15b576ec3ee871 100644
--- a/src/main/kotlin/com/s3ai/corporate_app2/controllers/rest/UserApiController.kt
+++ b/src/main/kotlin/com/s3ai/corporate_app2/controllers/rest/UserApiController.kt
@@ -3,6 +3,7 @@ package com.s3ai.corporate_app2.controllers.rest;
 import com.s3ai.corporate_app2.User
 import com.s3ai.corporate_app2.UserService
 import com.s3ai.corporate_app2.controllers.deleteInstance
+import com.s3ai.corporate_app2.jms.JMSPublisher
 import org.springframework.beans.factory.annotation.Autowired
 import org.springframework.web.bind.annotation.*
 import java.util.*
@@ -12,9 +13,13 @@ import kotlin.random.Random
 @RestController
 @RequestMapping("/api/users")
 class UserApiController {
+
     @Autowired
     lateinit var userService: UserService
 
+    @Autowired
+    lateinit var publisher: JMSPublisher
+
     @GetMapping("/fill")
     fun fillCinemas(): String? {
         val names = arrayOf("Jane", "Mary", "Paul", "Jason", "Keanu", "Andrew", "Joseph", "Jotaro", "Ivan", "Jolyne", "Walther");
@@ -25,7 +30,8 @@ class UserApiController {
             user.id = UUID.randomUUID();
             user.name = "${names.random()} ${surnames.random()}";
             generatedNames.add(user.name.toString())
-            user.age = Random.nextInt(15, 70);
+            user.age = Random.nextInt(15, 70)
+
             userService.save(user);
         }
         return generatedNames.toString()
@@ -33,6 +39,6 @@ class UserApiController {
 
     @DeleteMapping("/delete")
     fun deleteUser(@RequestParam(name = "id", required = true) id: String, response: HttpServletResponse): String? {
-        return deleteInstance(id, "User", userService, response)
+        return deleteInstance(id, userService, response, publisher)
     }
 }
diff --git a/src/main/kotlin/com/s3ai/corporate_app2/controllers/rest/json/CinemasJsonController.kt b/src/main/kotlin/com/s3ai/corporate_app2/controllers/rest/json/CinemasJsonController.kt
index 033ea39a4dc654989dd0656349f037526162a3c1..6cd1a4959c9e088f9fe85495ea532e83d70a219d 100644
--- a/src/main/kotlin/com/s3ai/corporate_app2/controllers/rest/json/CinemasJsonController.kt
+++ b/src/main/kotlin/com/s3ai/corporate_app2/controllers/rest/json/CinemasJsonController.kt
@@ -2,7 +2,9 @@ package com.s3ai.corporate_app2.controllers.rest.json
 
 import com.s3ai.corporate_app2.Cinema
 import com.s3ai.corporate_app2.CinemaService
+import com.s3ai.corporate_app2.controllers.getAllItems
 import com.s3ai.corporate_app2.controllers.getInstance
+import com.s3ai.corporate_app2.jms.JMSPublisher
 import org.springframework.beans.factory.annotation.Autowired
 import org.springframework.http.MediaType
 import org.springframework.web.bind.annotation.GetMapping
@@ -18,14 +20,17 @@ class CinemasJsonController {
     @Autowired
     lateinit var cinemaService: CinemaService
 
+    @Autowired
+    lateinit var publisher: JMSPublisher
+
     @GetMapping("/all", produces = [MediaType.APPLICATION_JSON_VALUE])
     fun getCinemas(response: HttpServletResponse): MutableList<Cinema> {
-        return cinemaService.findAll()
+        return getAllItems(cinemaService, publisher)
     }
 
     @GetMapping("/item/{id}", produces = [MediaType.APPLICATION_JSON_VALUE])
     fun getCinema(@PathVariable id: UUID, response: HttpServletResponse): Cinema? {
-        return getInstance(id, cinemaService, response)
+        return getInstance(id, cinemaService, response, publisher)
     }
 
 }
\ No newline at end of file
diff --git a/src/main/kotlin/com/s3ai/corporate_app2/controllers/rest/json/TicketsJsonController.kt b/src/main/kotlin/com/s3ai/corporate_app2/controllers/rest/json/TicketsJsonController.kt
index 12e7eec1804795371bfe8cd0a22c2b943da871c9..95474bdcaeb0976c7ace981adc14ffcd2c5d34e5 100644
--- a/src/main/kotlin/com/s3ai/corporate_app2/controllers/rest/json/TicketsJsonController.kt
+++ b/src/main/kotlin/com/s3ai/corporate_app2/controllers/rest/json/TicketsJsonController.kt
@@ -2,7 +2,9 @@ package com.s3ai.corporate_app2.controllers.rest.json
 
 import com.s3ai.corporate_app2.Ticket
 import com.s3ai.corporate_app2.TicketService
+import com.s3ai.corporate_app2.controllers.getAllItems
 import com.s3ai.corporate_app2.controllers.getInstance
+import com.s3ai.corporate_app2.jms.JMSPublisher
 import org.springframework.beans.factory.annotation.Autowired
 import org.springframework.http.MediaType
 import org.springframework.web.bind.annotation.GetMapping
@@ -18,14 +20,17 @@ class TicketsJsonController {
     @Autowired
     lateinit var ticketService: TicketService
 
+    @Autowired
+    lateinit var publisher: JMSPublisher
+
     @GetMapping("/all", produces = [MediaType.APPLICATION_JSON_VALUE])
     fun getTickets(response: HttpServletResponse): MutableList<Ticket> {
-        return ticketService.findAll()
+        return getAllItems(ticketService, publisher)
     }
 
     @GetMapping("/item/{id}", produces = [MediaType.APPLICATION_JSON_VALUE])
     fun getTicket(@PathVariable id: UUID, response: HttpServletResponse): Ticket? {
-        return getInstance(id, ticketService, response)
+        return getInstance(id, ticketService, response, publisher)
     }
 
 }
\ No newline at end of file
diff --git a/src/main/kotlin/com/s3ai/corporate_app2/controllers/rest/json/UsersJsonController.kt b/src/main/kotlin/com/s3ai/corporate_app2/controllers/rest/json/UsersJsonController.kt
index 72cb67d4e148604740d5f3d14a4526ca545bf35f..a6d10f556184aefd3a21acd28b65babd746fad1b 100644
--- a/src/main/kotlin/com/s3ai/corporate_app2/controllers/rest/json/UsersJsonController.kt
+++ b/src/main/kotlin/com/s3ai/corporate_app2/controllers/rest/json/UsersJsonController.kt
@@ -2,7 +2,9 @@ package com.s3ai.corporate_app2.controllers.rest.json
 
 import com.s3ai.corporate_app2.User
 import com.s3ai.corporate_app2.UserService
+import com.s3ai.corporate_app2.controllers.getAllItems
 import com.s3ai.corporate_app2.controllers.getInstance
+import com.s3ai.corporate_app2.jms.JMSPublisher
 import org.springframework.beans.factory.annotation.Autowired
 import org.springframework.http.MediaType
 import org.springframework.web.bind.annotation.GetMapping
@@ -18,14 +20,17 @@ class UsersJsonController {
     @Autowired
     lateinit var userService: UserService
 
+    @Autowired
+    lateinit var publisher: JMSPublisher
+
     @GetMapping("/all", produces = [MediaType.APPLICATION_JSON_VALUE])
     fun getUsers(response: HttpServletResponse): MutableList<User> {
-        return userService.findAll()
+        return getAllItems(userService, publisher)
     }
 
     @GetMapping("/item/{id}", produces = [MediaType.APPLICATION_JSON_VALUE])
     fun getUser(@PathVariable id: UUID, response: HttpServletResponse): User? {
-        return getInstance(id, userService, response)
+        return getInstance(id, userService, response, publisher)
     }
 
 }
\ No newline at end of file
diff --git a/src/main/kotlin/com/s3ai/corporate_app2/controllers/rest/xml/CinemasXmlController.kt b/src/main/kotlin/com/s3ai/corporate_app2/controllers/rest/xml/CinemasXmlController.kt
index c5664290c659e70456f6097df0a31c91e7bef535..295c82cc3a6d1ce712bd1a0634a0e0db42c4c5b9 100644
--- a/src/main/kotlin/com/s3ai/corporate_app2/controllers/rest/xml/CinemasXmlController.kt
+++ b/src/main/kotlin/com/s3ai/corporate_app2/controllers/rest/xml/CinemasXmlController.kt
@@ -2,7 +2,9 @@ package com.s3ai.corporate_app2.controllers.rest.xml
 
 import com.s3ai.corporate_app2.Cinema
 import com.s3ai.corporate_app2.CinemaService
+import com.s3ai.corporate_app2.controllers.getAllItems
 import com.s3ai.corporate_app2.controllers.getInstance
+import com.s3ai.corporate_app2.jms.JMSPublisher
 import org.springframework.beans.factory.annotation.Autowired
 import org.springframework.http.MediaType
 import org.springframework.web.bind.annotation.GetMapping
@@ -18,14 +20,17 @@ class CinemasXmlController {
     @Autowired
     lateinit var cinemaService: CinemaService
 
+    @Autowired
+    lateinit var publisher: JMSPublisher
+
     @GetMapping("/all", produces = [MediaType.APPLICATION_XML_VALUE])
     fun getCinemas(response: HttpServletResponse): MutableList<Cinema> {
-        return cinemaService.findAll()
+        return getAllItems(cinemaService, publisher)
     }
 
     @GetMapping("/item/{id}", produces = [MediaType.APPLICATION_XML_VALUE])
     fun getCinema(@PathVariable id: UUID, response: HttpServletResponse): Cinema? {
-        return getInstance(id, cinemaService, response)
+        return getInstance(id, cinemaService, response, publisher)
     }
 
 }
\ No newline at end of file
diff --git a/src/main/kotlin/com/s3ai/corporate_app2/controllers/rest/xml/TicketsXmlController.kt b/src/main/kotlin/com/s3ai/corporate_app2/controllers/rest/xml/TicketsXmlController.kt
index ddd5b7910103e9e6c005a47f3d4551ea08fd8c7f..4648abedae86ecea36b5d1d34a4b107c78516afb 100644
--- a/src/main/kotlin/com/s3ai/corporate_app2/controllers/rest/xml/TicketsXmlController.kt
+++ b/src/main/kotlin/com/s3ai/corporate_app2/controllers/rest/xml/TicketsXmlController.kt
@@ -2,7 +2,9 @@ package com.s3ai.corporate_app2.controllers.rest.xml
 
 import com.s3ai.corporate_app2.Ticket
 import com.s3ai.corporate_app2.TicketService
+import com.s3ai.corporate_app2.controllers.getAllItems
 import com.s3ai.corporate_app2.controllers.getInstance
+import com.s3ai.corporate_app2.jms.JMSPublisher
 import org.springframework.beans.factory.annotation.Autowired
 import org.springframework.http.MediaType
 import org.springframework.web.bind.annotation.GetMapping
@@ -18,13 +20,16 @@ class TicketsXmlController {
     @Autowired
     lateinit var ticketService: TicketService
 
+    @Autowired
+    lateinit var publisher: JMSPublisher
+
     @GetMapping("/all", produces = [MediaType.APPLICATION_XML_VALUE])
     fun getTickets(response: HttpServletResponse): MutableList<Ticket> {
-        return ticketService.findAll()
+        return getAllItems(ticketService, publisher)
     }
 
     @GetMapping("/item/{id}", produces = [MediaType.APPLICATION_XML_VALUE])
     fun getTicket(@PathVariable id: UUID, response: HttpServletResponse): Ticket? {
-        return getInstance(id, ticketService, response)
+        return getInstance(id, ticketService, response, publisher)
     }
 }
\ No newline at end of file
diff --git a/src/main/kotlin/com/s3ai/corporate_app2/controllers/rest/xml/UsersXmlController.kt b/src/main/kotlin/com/s3ai/corporate_app2/controllers/rest/xml/UsersXmlController.kt
index 4de521bf1ec6d54200eb2d943ab6d8b1082d3bc9..cb633d5bad351b0bb80098e838b866d942f6ed5f 100644
--- a/src/main/kotlin/com/s3ai/corporate_app2/controllers/rest/xml/UsersXmlController.kt
+++ b/src/main/kotlin/com/s3ai/corporate_app2/controllers/rest/xml/UsersXmlController.kt
@@ -2,7 +2,9 @@ package com.s3ai.corporate_app2.controllers.rest.xml
 
 import com.s3ai.corporate_app2.User
 import com.s3ai.corporate_app2.UserService
+import com.s3ai.corporate_app2.controllers.getAllItems
 import com.s3ai.corporate_app2.controllers.getInstance
+import com.s3ai.corporate_app2.jms.JMSPublisher
 import org.springframework.beans.factory.annotation.Autowired
 import org.springframework.http.MediaType
 import org.springframework.web.bind.annotation.GetMapping
@@ -18,13 +20,16 @@ class UsersXmlController {
     @Autowired
     lateinit var userService: UserService
 
+    @Autowired
+    lateinit var publisher: JMSPublisher
+
     @GetMapping("/all", produces = [MediaType.APPLICATION_XML_VALUE])
     fun getUsers(response: HttpServletResponse): MutableList<User> {
-        return userService.findAll()
+        return getAllItems(userService, publisher)
     }
 
     @GetMapping("/item/{id}", produces = [MediaType.APPLICATION_XML_VALUE])
     fun getUser(@PathVariable id: UUID, response: HttpServletResponse): User? {
-        return getInstance(id, userService, response)
+        return getInstance(id, userService, response, publisher)
     }
 }
\ No newline at end of file
diff --git a/src/main/kotlin/com/s3ai/corporate_app2/controllers/rest/xslt/CinemasXsltController.kt b/src/main/kotlin/com/s3ai/corporate_app2/controllers/rest/xslt/CinemasXsltController.kt
index 498cd0a4c3c3e7330ee2e3eb1e19bbbf61a68898..c7253791b17443e9dd538894f18ab78b12890eb3 100644
--- a/src/main/kotlin/com/s3ai/corporate_app2/controllers/rest/xslt/CinemasXsltController.kt
+++ b/src/main/kotlin/com/s3ai/corporate_app2/controllers/rest/xslt/CinemasXsltController.kt
@@ -1,8 +1,10 @@
 package com.s3ai.corporate_app2.controllers.rest.xslt
 
 import com.s3ai.corporate_app2.CinemaService
-import com.s3ai.corporate_app2.controllers.XMLTransform
-import com.s3ai.corporate_app2.controllers.getXSLTransformedInstance
+import com.s3ai.corporate_app2.controllers.xsltTransform
+import com.s3ai.corporate_app2.controllers.getAllItems
+import com.s3ai.corporate_app2.controllers.getInstance
+import com.s3ai.corporate_app2.jms.JMSPublisher
 import org.springframework.beans.factory.annotation.Autowired
 import org.springframework.http.MediaType
 import org.springframework.web.bind.annotation.GetMapping
@@ -18,16 +20,23 @@ class CinemasXsltController {
     @Autowired
     lateinit var cinemaService: CinemaService
 
+    @Autowired
+    lateinit var publisher: JMSPublisher
+
     val xsltResourceName: String = "cinema-process.xslt"
 
     @GetMapping("/all", produces = [MediaType.TEXT_HTML_VALUE])
     fun getCinemas(response: HttpServletResponse): String {
-        return XMLTransform(cinemaService.findAll(), xsltResourceName)
+        return xsltTransform(getAllItems(cinemaService, publisher), xsltResourceName)
     }
 
 
     @GetMapping("/item/{id}", produces = [MediaType.TEXT_HTML_VALUE])
     fun getCinema(@PathVariable id: UUID, response: HttpServletResponse): String? {
-        return getXSLTransformedInstance(id, cinemaService, xsltResourceName, response)
+        val item = getInstance(id, cinemaService, response, publisher)
+        if (null != item) {
+            return xsltTransform(item, xsltResourceName)
+        }
+        return ""
     }
 }
\ No newline at end of file
diff --git a/src/main/kotlin/com/s3ai/corporate_app2/controllers/rest/xslt/TicketsXsltController.kt b/src/main/kotlin/com/s3ai/corporate_app2/controllers/rest/xslt/TicketsXsltController.kt
index 896eca4cfa2307bd44cbbd5248e43eb0414dfc77..698b878de1173e24fa10ceb196b92e18a5b0bfd7 100644
--- a/src/main/kotlin/com/s3ai/corporate_app2/controllers/rest/xslt/TicketsXsltController.kt
+++ b/src/main/kotlin/com/s3ai/corporate_app2/controllers/rest/xslt/TicketsXsltController.kt
@@ -1,8 +1,10 @@
 package com.s3ai.corporate_app2.controllers.rest.xslt
 
 import com.s3ai.corporate_app2.TicketService
-import com.s3ai.corporate_app2.controllers.XMLTransform
-import com.s3ai.corporate_app2.controllers.getXSLTransformedInstance
+import com.s3ai.corporate_app2.controllers.xsltTransform
+import com.s3ai.corporate_app2.controllers.getAllItems
+import com.s3ai.corporate_app2.controllers.getInstance
+import com.s3ai.corporate_app2.jms.JMSPublisher
 import org.springframework.beans.factory.annotation.Autowired
 import org.springframework.http.MediaType
 import org.springframework.web.bind.annotation.GetMapping
@@ -18,16 +20,23 @@ class TicketsXsltController {
     @Autowired
     lateinit var ticketService: TicketService
 
+    @Autowired
+    lateinit var publisher: JMSPublisher
+
     val xsltResourceName: String = "ticket-process.xslt"
 
     @GetMapping("/all", produces = [MediaType.TEXT_HTML_VALUE])
-    fun getCinemas(response: HttpServletResponse): String {
-        return XMLTransform(ticketService.findAll(), xsltResourceName)
+    fun getTickets(response: HttpServletResponse): String {
+        return xsltTransform(getAllItems(ticketService, publisher), xsltResourceName)
     }
 
 
     @GetMapping("/item/{id}", produces = [MediaType.TEXT_HTML_VALUE])
-    fun getCinema(@PathVariable id: UUID, response: HttpServletResponse): String? {
-        return getXSLTransformedInstance(id, ticketService, xsltResourceName, response)
+    fun getTicket(@PathVariable id: UUID, response: HttpServletResponse): String? {
+        val item = getInstance(id, ticketService, response, publisher)
+        if (null != item) {
+            return xsltTransform(item, xsltResourceName)
+        }
+        return ""
     }
 }
\ No newline at end of file
diff --git a/src/main/kotlin/com/s3ai/corporate_app2/controllers/rest/xslt/UsersXsltController.kt b/src/main/kotlin/com/s3ai/corporate_app2/controllers/rest/xslt/UsersXsltController.kt
index f07ee83001d9f34d50759b285b85bfaac6f733d5..c798bd48b177065a54169a2dd6c0102d111fc233 100644
--- a/src/main/kotlin/com/s3ai/corporate_app2/controllers/rest/xslt/UsersXsltController.kt
+++ b/src/main/kotlin/com/s3ai/corporate_app2/controllers/rest/xslt/UsersXsltController.kt
@@ -1,8 +1,10 @@
 package com.s3ai.corporate_app2.controllers.rest.xslt
 
 import com.s3ai.corporate_app2.UserService
-import com.s3ai.corporate_app2.controllers.XMLTransform
-import com.s3ai.corporate_app2.controllers.getXSLTransformedInstance
+import com.s3ai.corporate_app2.controllers.getAllItems
+import com.s3ai.corporate_app2.controllers.getInstance
+import com.s3ai.corporate_app2.controllers.xsltTransform
+import com.s3ai.corporate_app2.jms.JMSPublisher
 import org.springframework.beans.factory.annotation.Autowired
 import org.springframework.http.MediaType
 import org.springframework.web.bind.annotation.GetMapping
@@ -18,16 +20,23 @@ class UsersXsltController {
     @Autowired
     lateinit var userService: UserService
 
+    @Autowired
+    lateinit var publisher: JMSPublisher
+
     val xsltResourceName: String = "user-process.xslt"
 
     @GetMapping("/all", produces = [MediaType.TEXT_HTML_VALUE])
-    fun getCinemas(response: HttpServletResponse): String {
-        return XMLTransform(userService.findAll(), xsltResourceName)
+    fun getUsers(response: HttpServletResponse): String {
+        return xsltTransform(getAllItems(userService, publisher), xsltResourceName)
     }
 
 
     @GetMapping("/item/{id}", produces = [MediaType.TEXT_HTML_VALUE])
-    fun getCinema(@PathVariable id: UUID, response: HttpServletResponse): String? {
-        return getXSLTransformedInstance(id, userService, xsltResourceName, response)
+    fun getUser(@PathVariable id: UUID, response: HttpServletResponse): String? {
+        val item = getInstance(id, userService, response, publisher)
+        if (null != item) {
+            return xsltTransform(item, xsltResourceName)
+        }
+        return ""
     }
 }
\ No newline at end of file
diff --git a/src/main/kotlin/com/s3ai/corporate_app2/entities.kt b/src/main/kotlin/com/s3ai/corporate_app2/entities.kt
index 28ceb6de27ba2516cba897c2e0c56c4c03ca1897..e3f4d8dee784b5ea2c71a427657120d78b4c9981 100644
--- a/src/main/kotlin/com/s3ai/corporate_app2/entities.kt
+++ b/src/main/kotlin/com/s3ai/corporate_app2/entities.kt
@@ -1,8 +1,6 @@
 package com.s3ai.corporate_app2
 
 import com.fasterxml.jackson.annotation.JsonAutoDetect
-import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty
-import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement
 import org.hibernate.annotations.OnDelete
 import org.hibernate.annotations.OnDeleteAction
 import java.util.*
@@ -73,5 +71,4 @@ class Ticket {
     override fun toString(): String {
         return "Ticket{id=$id, user=$user, cinema=$cinema, movie='$movie'}"
     }
-}
-
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/s3ai/corporate_app2/jms/Config.kt b/src/main/kotlin/com/s3ai/corporate_app2/jms/Config.kt
new file mode 100644
index 0000000000000000000000000000000000000000..55e003c54139624724f8ec4f96e279d4d46ad18e
--- /dev/null
+++ b/src/main/kotlin/com/s3ai/corporate_app2/jms/Config.kt
@@ -0,0 +1,29 @@
+package com.s3ai.corporate_app2.jms
+
+import org.apache.activemq.ActiveMQConnectionFactory
+import org.apache.activemq.command.ActiveMQQueue
+import org.springframework.beans.factory.annotation.Value
+import org.springframework.context.annotation.Bean
+import org.springframework.context.annotation.Configuration
+import org.springframework.jms.core.JmsTemplate
+import javax.jms.Queue
+
+@Configuration
+class Config {
+    @Value("\${spring.activemq.broker-url}")
+    lateinit var brokerURL: String
+
+    @Bean
+    fun queue(): Queue = ActiveMQQueue("cinemas.queue")
+
+    @Bean
+    fun connectionFactory(): ActiveMQConnectionFactory {
+        val factory = ActiveMQConnectionFactory()
+        factory.brokerURL = brokerURL
+        return factory
+    }
+
+    @Bean
+    fun jmsTemplate(): JmsTemplate = JmsTemplate(connectionFactory())
+
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/s3ai/corporate_app2/jms/JMSPublisher.kt b/src/main/kotlin/com/s3ai/corporate_app2/jms/JMSPublisher.kt
new file mode 100644
index 0000000000000000000000000000000000000000..631df1b2bc79efa432a5e63907aac8a4743aa6d8
--- /dev/null
+++ b/src/main/kotlin/com/s3ai/corporate_app2/jms/JMSPublisher.kt
@@ -0,0 +1,25 @@
+package com.s3ai.corporate_app2.jms
+
+import com.fasterxml.jackson.databind.ObjectMapper
+import com.s3ai.corporate_app2.jms.persistance.JMSAction
+import org.springframework.beans.factory.annotation.Autowired
+import org.springframework.jms.core.JmsTemplate
+import org.springframework.stereotype.Component
+import javax.jms.Queue
+
+@Component
+class JMSPublisher {
+    @Autowired
+    private lateinit var jmsTemplate: JmsTemplate
+
+
+    @Autowired
+    private lateinit var queue: Queue
+
+    private final val mapper: ObjectMapper = ObjectMapper()
+
+    fun publish(message_obj: JMSAction) {
+        val messageText = mapper.writeValueAsString(message_obj)
+        jmsTemplate.convertAndSend(queue, messageText)
+    }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/s3ai/corporate_app2/jms/JmsConsumer.kt b/src/main/kotlin/com/s3ai/corporate_app2/jms/JmsConsumer.kt
new file mode 100644
index 0000000000000000000000000000000000000000..a9b3b8a5218432d8025d952f340a4cb6e10b9e76
--- /dev/null
+++ b/src/main/kotlin/com/s3ai/corporate_app2/jms/JmsConsumer.kt
@@ -0,0 +1,63 @@
+package com.s3ai.corporate_app2.jms
+
+import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
+import com.fasterxml.jackson.module.kotlin.readValue
+import com.s3ai.corporate_app2.jms.persistance.JMSAction
+import com.s3ai.corporate_app2.jms.persistance.JMSActionRepository
+import com.s3ai.corporate_app2.jms.persistance.SubscriptionTypeRepository
+import org.springframework.beans.factory.annotation.Autowired
+import org.springframework.beans.factory.annotation.Value
+import org.springframework.jms.annotation.JmsListener
+import org.springframework.mail.javamail.JavaMailSender
+import org.springframework.mail.javamail.MimeMessageHelper
+import org.springframework.messaging.MessagingException
+import org.springframework.stereotype.Component
+
+
+@Component
+class JmsConsumer {
+
+    @Value("\${spring.mail.username}")
+    private lateinit var sourceUser: String
+
+    @Autowired
+    private lateinit var jmsActionService: JMSActionRepository
+
+    @Autowired
+    private lateinit var sender: JavaMailSender
+
+    @Autowired
+    private lateinit var subTypeRepo: SubscriptionTypeRepository
+
+    private final val mapper = jacksonObjectMapper()
+
+    fun sendEmail(action: JMSAction, targetUsers: Array<String>): Boolean {
+        val message = sender.createMimeMessage()
+        val helper = MimeMessageHelper(message)
+        try {
+            helper.setFrom(sourceUser)
+            helper.setTo(targetUsers)
+            helper.setText("Entity ${action.entity} was ${action.actionJMS.str}. ${action.actionDescription}")
+            helper.setSubject("Cinemas service notification")
+            sender.send(message)
+        } catch (e: MessagingException) {
+            e.printStackTrace()
+            return false
+        }
+        return true
+
+    }
+
+    fun notifySubscribers(action: JMSAction) {
+        val users = subTypeRepo.findSubscriptionTypeByType(action.actionJMS)
+        val emails = users.map { u -> u.subscriber.email!! }.distinct().toTypedArray()
+        if (emails.isNotEmpty()) sendEmail(action, emails)
+    }
+
+    @JmsListener(destination = "cinemas.queue")
+    fun consume(action_text: String) {
+        val action: JMSAction = mapper.readValue(action_text)
+        jmsActionService.save(action)
+        notifySubscribers(action)
+    }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/s3ai/corporate_app2/jms/persistance/entities.kt b/src/main/kotlin/com/s3ai/corporate_app2/jms/persistance/entities.kt
new file mode 100644
index 0000000000000000000000000000000000000000..5c221cd0e40c278ff0be4cddd7ac44702b8f7491
--- /dev/null
+++ b/src/main/kotlin/com/s3ai/corporate_app2/jms/persistance/entities.kt
@@ -0,0 +1,75 @@
+package com.s3ai.corporate_app2.jms.persistance
+
+import com.fasterxml.jackson.annotation.JsonAutoDetect
+import org.hibernate.annotations.CreationTimestamp
+import org.hibernate.annotations.OnDelete
+import org.hibernate.annotations.OnDeleteAction
+import java.time.LocalDateTime
+import java.util.*
+import javax.persistence.*
+
+
+enum class JMSEntityAction(val str: String) {
+    UPDATE("updated"),
+    QUERY("queried"),
+    CREATE("created"),
+    DELETE("deleted")
+}
+
+@Entity
+@Table(name = "jms_action")
+@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY)
+class JMSAction {
+    @Id
+    @Column(name = "ID")
+    @GeneratedValue(strategy = GenerationType.AUTO)
+    var id: UUID? = null
+    @Enumerated(EnumType.STRING)
+    @Column(length = 8, name = "action")
+    lateinit var actionJMS: JMSEntityAction
+    @Column(name = "entity")
+    lateinit var entity: String
+    @Column(name = "description", columnDefinition = "TEXT")
+    lateinit var actionDescription: String
+    @CreationTimestamp
+    private val createDateTime: LocalDateTime? = null
+    @Column(name = "delivered")
+    var delivered: Boolean = true
+
+    override fun toString(): String {
+        return "JMSAction{id=$id, action=$actionJMS, entity='$entity', actionDescription='$actionDescription'}"
+    }
+}
+
+@Entity
+@Table(name = "subscriber")
+class Subscriber {
+    @Id
+    @GeneratedValue(strategy = GenerationType.AUTO)
+    var id: UUID? = null
+
+    @Column(name = "email")
+    var email: String? = null
+
+    @CreationTimestamp
+    private val createDateTime: LocalDateTime? = null
+
+    @OneToMany
+    var types: List<SubscriptionType> = mutableListOf()
+}
+
+@Entity
+@Table(name = "subscription_type")
+class SubscriptionType {
+    @Id
+    @GeneratedValue(strategy = GenerationType.AUTO)
+    var id: Long? = null
+
+    @Enumerated(EnumType.STRING)
+    @Column(length = 8, name = "type")
+    lateinit var type: JMSEntityAction
+
+    @OneToOne
+    @OnDelete(action = OnDeleteAction.CASCADE)
+    lateinit var subscriber: Subscriber
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/s3ai/corporate_app2/jms/persistance/repositories.kt b/src/main/kotlin/com/s3ai/corporate_app2/jms/persistance/repositories.kt
new file mode 100644
index 0000000000000000000000000000000000000000..d33f03567beaa9979924620d23ba187a21152d81
--- /dev/null
+++ b/src/main/kotlin/com/s3ai/corporate_app2/jms/persistance/repositories.kt
@@ -0,0 +1,25 @@
+package com.s3ai.corporate_app2.jms.persistance
+
+import org.springframework.data.jpa.repository.JpaRepository
+import org.springframework.data.jpa.repository.Query
+import org.springframework.data.repository.query.Param
+import org.springframework.stereotype.Repository
+import java.util.*
+
+@Repository
+interface JMSActionRepository : JpaRepository<JMSAction, UUID> {
+    @Query(value = "SELECT * FROM public.jms_action WHERE delivered = FALSE", nativeQuery = true)
+    fun findUndelivered(): MutableList<JMSAction>
+}
+
+@Repository
+interface SubscribersRepository : JpaRepository<Subscriber, UUID> {
+    @Query("FROM Subscriber WHERE email = :email")
+    fun findSubscriberByEmail(@Param("email") email: String): Optional<Subscriber>
+}
+
+@Repository
+interface SubscriptionTypeRepository : JpaRepository<SubscriptionType, Long> {
+    @Query("FROM SubscriptionType WHERE type = :type")
+    fun findSubscriptionTypeByType(@Param("type") type: JMSEntityAction): List<SubscriptionType>
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/s3ai/corporate_app2/repositories.kt b/src/main/kotlin/com/s3ai/corporate_app2/repositories.kt
index 6077d0af27e30232e62504301f20b3cf4d1769ac..3eed32fda03c68a06b4a0df1d5d079b440b13d55 100644
--- a/src/main/kotlin/com/s3ai/corporate_app2/repositories.kt
+++ b/src/main/kotlin/com/s3ai/corporate_app2/repositories.kt
@@ -1,6 +1,7 @@
 package com.s3ai.corporate_app2
 
 import org.springframework.data.jpa.repository.JpaRepository
+import org.springframework.data.jpa.repository.Query
 import org.springframework.stereotype.Repository
 import java.util.*
 
diff --git a/src/main/kotlin/com/s3ai/corporate_app2/services.kt b/src/main/kotlin/com/s3ai/corporate_app2/services.kt
index 51cf0fbcd93065f44c259907c8861916d8f35ad9..0f51ab0ed7745a51432beed02dce246764129433 100644
--- a/src/main/kotlin/com/s3ai/corporate_app2/services.kt
+++ b/src/main/kotlin/com/s3ai/corporate_app2/services.kt
@@ -1,5 +1,6 @@
 package com.s3ai.corporate_app2
 
+import org.springframework.data.jpa.repository.Query
 import org.springframework.stereotype.Service
 import java.util.*
 
@@ -9,6 +10,7 @@ interface CinemaServices<T> {
     fun findById(id: UUID): T?
     fun save(item: T): T
     fun delete(item: T)
+    fun itemName(): String
 }
 
 @Service
@@ -17,6 +19,7 @@ class CinemaService(private val cinemaRepository: CinemaRepository) : CinemaServ
     override fun findById(id: UUID): Cinema? = cinemaRepository.findById(id).orElse(null)
     override fun save(item: Cinema): Cinema = cinemaRepository.save(item)
     override fun delete(item: Cinema) = cinemaRepository.delete(item)
+    override fun itemName(): String = "Cinema"
 }
 
 @Service
@@ -25,6 +28,7 @@ class UserService(private val userRepository: UserRepository) : CinemaServices<U
     override fun findById(id: UUID): User? = userRepository.findById(id).orElse(null)
     override fun save(item: User): User = userRepository.save(item)
     override fun delete(item: User) = userRepository.delete(item)
+    override fun itemName(): String = "User"
 }
 
 @Service
@@ -33,4 +37,5 @@ class TicketService(private val ticketRepository: TicketRepository) : CinemaServ
     override fun findById(id: UUID): Ticket? = ticketRepository.findById(id).orElse(null)
     override fun save(item: Ticket): Ticket = ticketRepository.save(item)
     override fun delete(item: Ticket) = ticketRepository.delete(item)
+    override fun itemName(): String = "Ticket"
 }
\ No newline at end of file
diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties
index 2b046747b6b61873c2a783b6c5240ea6750b4f25..174500c59db2965eb5978115e1fd81579a9e8390 100644
--- a/src/main/resources/application.properties
+++ b/src/main/resources/application.properties
@@ -1,10 +1,31 @@
 spring.thymeleaf.cache=false
+
 spring.datasource.driver-class-name=org.postgresql.Driver
 spring.datasource.url=jdbc:postgresql://corporate_db2:5432/cinema
 spring.datasource.username=postgres
 spring.datasource.password=postgres
 spring.datasource.platform=postgres
+
 spring.jpa.hibernate.ddl-auto=update
 spring.jpa.database=postgresql
 spring.jpa.database-platform=postgres
-spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQL10Dialect
\ No newline at end of file
+spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQL10Dialect
+
+spring.activemq.in-memory=false
+spring.activemq.pool.enabled=true
+spring.activemq.broker-url=tcp://actvemq:61616
+spring.activemq.user=admin
+spring.activemq.password=admin
+
+
+spring.mail.port=465
+spring.mail.host=smtp.yandex.com
+spring.mail.username=username
+spring.mail.password=password
+
+spring.mail.properties.mail.smtp.starttls.enable=true
+spring.mail.properties.mail.smtp.auth = true
+spring.mail.properties.mail.smtp.socketFactory.port = 465
+spring.mail.properties.mail.smtp.socketFactory.class = javax.net.ssl.SSLSocketFactory
+spring.mail.properties.mail.smtp.socketFactory.fallback = false
+spring.mail.properties.mail.smtp.ssl.enable=false
\ No newline at end of file
diff --git a/src/main/resources/static/css/index.css b/src/main/resources/static/css/index.css
index debb6d5093a78a712339848412fe77c5f4ad9378..2b1e279bc8a5e9ae24160b4489e0a8dcbc12ba5a 100644
--- a/src/main/resources/static/css/index.css
+++ b/src/main/resources/static/css/index.css
@@ -1 +1 @@
-.index-gradient{background:linear-gradient(to bottom, #283048 0%, #859398 100%)}.projects-section{padding:10rem 0}.projects-section .featured-text{padding:2rem}@media(min-width: 992px){.projects-section .featured-text{padding:0 0 0 2rem;border-left:.5rem solid #64a19d}}.projects-section .project-text{padding:3rem;font-size:90%}@media(min-width: 992px){.projects-section .project-text{padding:5rem}.projects-section .project-text hr{border-color:#64a19d;border-width:.25rem;width:30%}}.masthead{object-fit:cover !important;text-align:center !important;background-repeat:no-repeat !important;background-attachment:fixed !important;background-position:center !important}.masthead .white{color:#fff}.hide-y{overflow-y:hidden}.landing-info-row{height:100px}.landing-info-row .landing-info-image{height:100px;object-fit:cover;width:100%;text-align:center;background-repeat:no-repeat;background-attachment:fixed;background-position:center}.masthead{position:relative;width:100%;height:auto;min-height:35rem;padding:15rem 0;background-position:center;background-repeat:no-repeat;background-attachment:scroll;background-size:cover}.masthead h1{font-family:"Varela Round";font-size:2.5rem;line-height:2.5rem;letter-spacing:.8rem;background:-webkit-linear-gradient(rgba(255, 255, 255, 0.9), rgba(255, 255, 255, 0));-webkit-text-fill-color:transparent;-webkit-background-clip:text}.masthead h2{max-width:20rem;font-size:1rem}@media(min-width: 768px){.masthead h1{font-size:4rem;line-height:4rem}}@media(min-width: 992px){.masthead{height:100vh;padding:0}.masthead h1{font-size:6.5rem;line-height:6.5rem;letter-spacing:.8rem}.masthead h2{max-width:30rem;font-size:1.25rem}}.contact-section{padding:5rem 0 0}.contact-section .card{border:0;border-bottom:.25rem solid #64a19d}.contact-section .card h4{font-size:.8rem;font-family:"Varela Round";text-transform:uppercase;letter-spacing:.15rem}.contact-section .card hr{border-color:#64a19d;border-width:.25rem;width:3rem}.contact-section .social{margin-top:5rem}.contact-section .social a{text-align:center;height:3rem;width:3rem;background:rgba(255,255,255,.1);border-radius:100%;line-height:3rem;color:rgba(255,255,255,.3)}.contact-section .social a:hover{color:rgba(255,255,255,.5)}.contact-section .social a:active{color:#fff}.btn{box-shadow:0 .1875rem .1875rem 0 rgba(0,0,0,.1) !important;padding:1.25rem 2rem;font-family:"Varela Round";font-size:80%;text-transform:uppercase;letter-spacing:.15rem;border:0}.btn-interact{background-color:#64a19d}.btn-interact:hover{background-color:#4f837f}.btn-interact:focus{background-color:#4f837f;color:#fff}.btn-interact:active{background-color:#467370 !important}.about-section{padding-top:10rem}.about-section p{margin-bottom:5rem}/*# sourceMappingURL=index.css.map */
+.index-gradient{background:linear-gradient(to bottom, #283048 0%, #859398 100%)}.projects-section{padding:10rem 0}.projects-section .featured-text{padding:2rem}@media(min-width: 992px){.projects-section .featured-text{padding:0 0 0 2rem;border-left:.5rem solid #64a19d}}.projects-section .project-text{padding:3rem;font-size:90%}@media(min-width: 992px){.projects-section .project-text{padding:5rem}.projects-section .project-text hr{border-color:#64a19d;border-width:.25rem;width:30%}}.masthead{object-fit:cover !important;text-align:center !important;background-repeat:no-repeat !important;background-attachment:fixed !important;background-position:center !important}.masthead .white{color:#fff}.hide-y{overflow-y:hidden}.landing-info-row{height:100px}.landing-info-row .landing-info-image{height:100px;object-fit:cover;width:100%;text-align:center;background-repeat:no-repeat;background-attachment:fixed;background-position:center}.masthead{position:relative;width:100%;height:auto;min-height:35rem;padding:15rem 0;background-position:center;background-repeat:no-repeat;background-attachment:scroll;background-size:cover}.masthead h1{font-family:"Varela Round";font-size:2.5rem;line-height:2.5rem;letter-spacing:.8rem;background:-webkit-linear-gradient(rgba(255, 255, 255, 0.9), rgba(255, 255, 255, 0));-webkit-text-fill-color:transparent;-webkit-background-clip:text}.masthead h2{max-width:20rem;font-size:1rem}@media(min-width: 768px){.masthead h1{font-size:4rem;line-height:4rem}}@media(min-width: 992px){.masthead{height:100vh;padding:0}.masthead h1{font-size:6.5rem;line-height:6.5rem;letter-spacing:.8rem}.masthead h2{max-width:30rem;font-size:1.25rem}}.contact-section{padding:5rem 0 0}.contact-section .card{border:0;border-bottom:.25rem solid #64a19d}.contact-section .card h4{font-size:.8rem;font-family:"Varela Round";text-transform:uppercase;letter-spacing:.15rem}.contact-section .card hr{border-color:#64a19d;border-width:.25rem;width:3rem}.contact-section .social{margin-top:5rem}.contact-section .social a{text-align:center;height:3rem;width:3rem;background:rgba(255,255,255,.1);border-radius:100%;line-height:3rem;padding-top:1rem;color:rgba(255,255,255,.3)}.contact-section .social a:hover{color:rgba(255,255,255,.5)}.contact-section .social a:active{color:#fff}.btn{box-shadow:0 .1875rem .1875rem 0 rgba(0,0,0,.1) !important;padding:1.25rem 2rem;font-family:"Varela Round";font-size:80%;text-transform:uppercase;letter-spacing:.15rem;border:0}.btn-interact{background-color:#64a19d}.btn-interact:hover{background-color:#4f837f}.btn-interact:focus{background-color:#4f837f;color:#fff}.btn-interact:active{background-color:#467370 !important}.about-section{padding-top:10rem}.about-section p{margin-bottom:5rem}/*# sourceMappingURL=index.css.map */
diff --git a/src/main/resources/static/css/index.css.map b/src/main/resources/static/css/index.css.map
index ac5ec28cec5c7830247919fbb40389de5b05cde7..9de368993141b11db8c8f0765e5adb8c455ce2b7 100644
--- a/src/main/resources/static/css/index.css.map
+++ b/src/main/resources/static/css/index.css.map
@@ -1 +1 @@
-{"version":3,"sourceRoot":"","sources":["../scss/index.scss","../scss/_variables.scss"],"names":[],"mappings":"AAEA,gBACE,gEAGF,kBACE,gBAEA,iCACE,aACA,yBAFF,iCAGI,mBACA,iCAIJ,gCACE,aACA,cACA,yBAHF,gCAII,aACA,mCACE,aCXE,QDYF,oBACA,WAOR,UACE,4BACA,6BACA,uCACA,uCACA,sCAEA,iBACE,WAKJ,QACE,kBAGF,kBACE,aAEA,sCACE,aACA,iBACA,WACA,kBACA,4BACA,4BACA,2BAIJ,UACE,kBACA,WACA,YACA,iBACA,gBACA,2BACA,4BACA,6BACA,sBAEA,aACE,2BACA,iBACA,mBACA,qBACA,qFACA,oCACA,6BAGF,aACE,gBACA,eAGF,yBACE,aACE,eACA,kBAGJ,yBAhCF,UAiCI,aACA,UACA,aACE,iBACA,mBACA,qBAEF,aACE,gBACA,mBAKN,iBACE,iBAEA,uBACE,SACA,mCAEA,0BACE,gBACA,2BACA,yBACA,sBAGF,0BACE,aCjHI,QDkHJ,oBACA,WAIJ,yBACE,gBAEA,2BACE,kBACA,YACA,WACA,gCACA,mBACA,iBACA,2BAEA,iCACE,2BAGF,kCACE,MCpJA,KD0JR,KACE,2DACA,qBACA,2BACA,cACA,yBACA,sBACA,SAGF,cACE,iBCzJQ,QD2JR,oBACE,yBAGF,oBACE,yBACA,WAGF,qBACE,oCAIJ,eACE,kBAEA,iBACE","file":"index.css"}
\ No newline at end of file
+{"version":3,"sourceRoot":"","sources":["../scss/index.scss","../scss/_variables.scss"],"names":[],"mappings":"AAEA,gBACE,gEAGF,kBACE,gBAEA,iCACE,aACA,yBAFF,iCAGI,mBACA,iCAIJ,gCACE,aACA,cACA,yBAHF,gCAII,aACA,mCACE,aCXE,QDYF,oBACA,WAOR,UACE,4BACA,6BACA,uCACA,uCACA,sCAEA,iBACE,WAKJ,QACE,kBAGF,kBACE,aAEA,sCACE,aACA,iBACA,WACA,kBACA,4BACA,4BACA,2BAIJ,UACE,kBACA,WACA,YACA,iBACA,gBACA,2BACA,4BACA,6BACA,sBAEA,aACE,2BACA,iBACA,mBACA,qBACA,qFACA,oCACA,6BAGF,aACE,gBACA,eAGF,yBACE,aACE,eACA,kBAGJ,yBAhCF,UAiCI,aACA,UACA,aACE,iBACA,mBACA,qBAEF,aACE,gBACA,mBAKN,iBACE,iBAEA,uBACE,SACA,mCAEA,0BACE,gBACA,2BACA,yBACA,sBAGF,0BACE,aCjHI,QDkHJ,oBACA,WAIJ,yBACE,gBAEA,2BACE,kBACA,YACA,WACA,gCACA,mBACA,iBACA,iBACA,2BAEA,iCACE,2BAGF,kCACE,MCrJA,KD2JR,KACE,2DACA,qBACA,2BACA,cACA,yBACA,sBACA,SAGF,cACE,iBC1JQ,QD4JR,oBACE,yBAGF,oBACE,yBACA,WAGF,qBACE,oCAIJ,eACE,kBAEA,iBACE","file":"index.css"}
\ No newline at end of file
diff --git a/src/main/resources/static/css/subscribes.css b/src/main/resources/static/css/subscribes.css
new file mode 100644
index 0000000000000000000000000000000000000000..bddef40a2197a7b43b64c0b9862bb535176e25a8
--- /dev/null
+++ b/src/main/resources/static/css/subscribes.css
@@ -0,0 +1 @@
+.editing .container{height:100%;display:flex;justify-content:center;align-items:center}.table-padding{padding-top:56px}/*# sourceMappingURL=subscribes.css.map */
diff --git a/src/main/resources/static/css/subscribes.css.map b/src/main/resources/static/css/subscribes.css.map
new file mode 100644
index 0000000000000000000000000000000000000000..ca13f09148a7e341d71224b04abdbe028a09bfca
--- /dev/null
+++ b/src/main/resources/static/css/subscribes.css.map
@@ -0,0 +1 @@
+{"version":3,"sourceRoot":"","sources":["../scss/cinemas.scss"],"names":[],"mappings":"AAEE,oBACE,YACA,aACA,uBACA,mBAIJ,eACE","file":"subscribes.css"}
\ No newline at end of file
diff --git a/src/main/resources/static/images/email.jpg b/src/main/resources/static/images/email.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..1c0b5ad82dd76e3e7c7ad4c3f1e1e7ff8a2dcfa0
Binary files /dev/null and b/src/main/resources/static/images/email.jpg differ
diff --git a/src/main/resources/static/scss/index.scss b/src/main/resources/static/scss/index.scss
index 9cd61da7fde0cfeb33ccd958c7eafeecebf4dd4a..eca5788b5a44fa6f3c2588a6fe73a32fce11d3e4 100644
--- a/src/main/resources/static/scss/index.scss
+++ b/src/main/resources/static/scss/index.scss
@@ -139,6 +139,7 @@
       background: fade-out($white, 0.9);
       border-radius: 100%;
       line-height: 3rem;
+      padding-top: 1rem;
       color: fade-out($white, 0.7);
 
       &:hover {
diff --git a/src/main/resources/static/scss/subscribes.scss b/src/main/resources/static/scss/subscribes.scss
new file mode 100644
index 0000000000000000000000000000000000000000..5743cc609b56787d8ce5ee9d9d10e56fbdeaf990
--- /dev/null
+++ b/src/main/resources/static/scss/subscribes.scss
@@ -0,0 +1 @@
+@import "cinemas";
\ No newline at end of file
diff --git a/src/main/resources/templates/index.html b/src/main/resources/templates/index.html
index 81d4dfdba74410001268d4b148a786847b4ae90a..f61ebdb980d0fd115da98fa7d81fda45b34bd5cd 100644
--- a/src/main/resources/templates/index.html
+++ b/src/main/resources/templates/index.html
@@ -29,7 +29,8 @@
                     <h2 class="text-white mb-4">Built for cinema business. Built with passion for movies.</h2>
                     <p class="text-white-50">
                         We are glad to provide you the best possible instrument to manage your cinema network.
-                        Use it to control your cinemas, track tickets to movies, and gather precious data for your business.
+                        Use it to control your cinemas, track tickets to movies, and gather precious data for your
+                        business.
                         System is established to be user-friendly and easy to get on.
                     </p>
                 </div>
@@ -80,7 +81,7 @@
             </div>
 
             <!-- Project Two Row -->
-            <div class="row justify-content-center hide-y no-gutters">
+            <div class="row justify-content-center hide-y no-gutters mt-3">
                 <div class="col-lg-6">
                     <img class="pl-3 img-fluid landing-info-image"
                          src="/images/landing_users.jpg" alt="">
@@ -91,7 +92,8 @@
                             <div class="project-text w-100 my-auto text-center text-lg-left">
                                 <h4 class="text-white">User management</h4>
                                 <p class="mb-0 text-white-50">
-                                    Build up your customers database. Track popularity of certain titles and places basing
+                                    Build up your customers database. Track popularity of certain titles and places
+                                    basing
                                     on precious personal data of innocent people, and enjoy the world we live in.
                                 </p>
                                 <hr class="d-none d-lg-block mb-0 mr-0">
@@ -101,12 +103,36 @@
                 </div>
             </div>
 
+            <div class="row justify-content-center no-gutters mb-5 mt-3 mb-lg-0">
+                <div class="col-lg-6">
+                    <img class="img-fluid landing-info-image pr-3"
+                         src="/images/email.jpg" alt="">
+                </div>
+                <div class="col-lg-6 order-lg-first">
+                    <div class="bg-black text-center h-100 project">
+                        <div class="d-flex h-100">
+                            <div class="project-text w-100 my-auto text-center text-lg-right">
+                                <h4 class="text-white">Updates subscription</h4>
+                                <p class="mb-0 text-white-50">
+                                    Stay up to date with the latest site updates.
+                                    Track your database changes with only your email.
+                                    All updates will be instantly sent to you. </p>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+            </div>
         </div>
     </section>
 </div>
-
+<section class="subscribe-section pt-3 bg-dark">
+    <div class="row justify-content-center">
+        <a class="btn btn-light mr-2" href="/subscription/subscribe">Subscribe</a>
+        <a class="btn btn-light ml-2" href="/subscription/unsubscribe">Unsubscribe</a>
+    </div>
+</section>
 <!-- Contact Section -->
-<section class="contact-section mt-3 bg-black">
+<section class="contact-section pt-3 bg-dark">
     <div class="container">
 
         <div class="row">
@@ -158,7 +184,7 @@
             <a href="#" class="mx-2">
                 <i class="fab fa-vk"></i>
             </a>
-            <a href="https://gitlab.le-memese.com/s3rius/corporative_systems" class="mx-2">
+            <a href="https://gitlab.le-memese.com/s3rius/corporative_systems2" class="mx-2">
                 <i class="fab fa-gitlab"></i>
             </a>
         </div>
@@ -167,7 +193,7 @@
 </section>
 
 <!-- Footer -->
-<footer class="bg-black small text-center text-black-50">
+<footer class="bg-dark small text-center text-white-50">
     <div class="container">
         Copyright &copy; le-memese 2019
     </div>
diff --git a/src/main/resources/templates/subscription/subscribe.html b/src/main/resources/templates/subscription/subscribe.html
new file mode 100644
index 0000000000000000000000000000000000000000..a66314e387a21812513695d810f5a711f31abaec
--- /dev/null
+++ b/src/main/resources/templates/subscription/subscribe.html
@@ -0,0 +1,61 @@
+<html xmlns:th="http://www.thymeleaf.org">
+<head>
+    <title>Edit cinema</title>
+    <head th:include="commons/imports"></head>
+    <link rel="stylesheet" href="/css/subscribes.css">
+    <script src="/js/subscribe.js"></script>
+</head>
+<body class="themed-gradient">
+
+<!-- Navigation -->
+<body th:include="commons/header"></body>
+
+<div class="editing">
+    <div class="container justify-content-center">
+
+        <form id="cinemaForm" class="d-flex justify-content-center" th:object="${subscriber}" method="post"
+              action="/subscription/subscribe">
+            <fieldset>
+
+                <legend>
+                    <div class="text-center"><h2><b class="white">Subscribe to updates</b></h2></div>
+                </legend>
+                <br>
+                <input type="hidden" name="id" th:field="*{id}">
+
+                <div class="form-group">
+                    <div class="inputGroupContainer">
+                        <div class="input-group">
+                            <div class="input-group-prepend">
+                                <div class="input-group-text"><i class="fas fa-envelope"></i></div>
+                            </div>
+                            <input type="text"
+                                   class="form-control validate"
+                                   id="Email"
+                                   name="email"
+                                   placeholder="User's email" th:field="*{email}" required>
+                        </div>
+                    </div>
+                </div>
+                <div class="form-group">
+                    <div class="inputGroupContainer">
+                        <div class="input-group">
+<!--                            <div class="input-group-prepend">-->
+<!--                                <div class="input-group-text"><i class="fas fa-chair"></i></div>-->
+<!--                            </div>-->
+                            <div class="form-check" th:each="item: ${types}">
+                                <input type="checkbox" class="form-check-input" name="actions" th:value="${item}">
+                                <label th:text="${item.str}" class="text-white pr-2"></label>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+                <div class="justify-content-center">
+                    <button type="submit" class="btn btn-primary w-100"><i class="fas fa-check"></i>Submit</button>
+                </div>
+            </fieldset>
+        </form>
+    </div>
+</div>
+</body>
+</html>
diff --git a/src/main/resources/templates/subscription/unsubscribe.html b/src/main/resources/templates/subscription/unsubscribe.html
new file mode 100644
index 0000000000000000000000000000000000000000..3e625399c170d1a15bf9e121a62e38cb0d92e35b
--- /dev/null
+++ b/src/main/resources/templates/subscription/unsubscribe.html
@@ -0,0 +1,46 @@
+<html xmlns:th="http://www.thymeleaf.org">
+<head>
+    <title>Edit cinema</title>
+    <head th:include="commons/imports"></head>
+    <link rel="stylesheet" href="/css/subscribes.css">
+    <script src="/js/subscribe.js"></script>
+</head>
+<body class="themed-gradient">
+
+<!-- Navigation -->
+<body th:include="commons/header"></body>
+
+<div class="editing">
+    <div class="container justify-content-center">
+
+        <form id="cinemaForm" class="d-flex justify-content-center" method="post"
+              action="/subscription/unsubscribe">
+            <fieldset>
+
+                <legend>
+                    <div class="text-center"><h2><b class="white">Subscribe to updates</b></h2></div>
+                </legend>
+                <br>
+
+                <div class="form-group">
+                    <div class="inputGroupContainer">
+                        <div class="input-group">
+                            <div class="input-group-prepend">
+                                <div class="input-group-text"><i class="fas fa-envelope"></i></div>
+                            </div>
+                            <input type="text"
+                                   class="form-control validate"
+                                   id="Email"
+                                   placeholder="User's email" name="email" required>
+                        </div>
+                    </div>
+                </div>
+                <div class="justify-content-center">
+                    <button type="submit" class="btn btn-primary w-100"><i class="fas fa-check"></i>Submit</button>
+                </div>
+            </fieldset>
+        </form>
+    </div>
+</div>
+</body>
+</html>
diff --git a/src/test/kotlin/com/s3ai/corporate_app2/CinemasApiTest.kt b/src/test/kotlin/com/s3ai/corporate_app2/CinemasApiTest.kt
deleted file mode 100644
index 62638c0e392479447fc5b58bcfd215c8b9d24e5f..0000000000000000000000000000000000000000
--- a/src/test/kotlin/com/s3ai/corporate_app2/CinemasApiTest.kt
+++ /dev/null
@@ -1,108 +0,0 @@
-package com.s3ai.corporate_app2
-
-import com.s3ai.corporate_app2.controllers.CinemasController
-import com.s3ai.corporate_app2.controllers.rest.CinemaApiController
-import org.assertj.core.api.Assertions.assertThat
-import org.junit.jupiter.api.Test
-import org.springframework.beans.factory.annotation.Autowired
-import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc
-import org.springframework.boot.test.context.SpringBootTest
-import org.springframework.http.MediaType
-import org.springframework.test.context.jdbc.Sql
-import org.springframework.test.web.servlet.MockMvc
-import org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get
-import org.springframework.test.web.servlet.result.MockMvcResultMatchers.status
-import org.springframework.ui.ExtendedModelMap
-import java.util.*
-
-
-@SpringBootTest
-@AutoConfigureMockMvc
-class CinemasApiTest {
-    @Autowired
-    private lateinit var controller: CinemasController
-
-    @Autowired
-    private lateinit var mvc: MockMvc
-
-    @Autowired
-    private lateinit var apiController: CinemaApiController
-
-    @Test
-    @Throws(Exception::class)
-    fun contextLoads() {
-        assertThat(controller).isNotNull
-        assertThat(apiController).isNotNull
-    }
-
-    @Test
-    @Throws(Exception::class)
-    fun shouldUpdateCinema() {
-        val cinema = Cinema()
-        val id = UUID.randomUUID()
-        cinema.id = id
-        cinema.name = "test"
-        controller.updateCinema(cinema)
-        val cinemaFromBase = controller.cinemaService.findById(id)
-        assertThat(cinemaFromBase?.equals(cinema))
-    }
-
-    @Test
-    @Throws(Exception::class)
-    fun shouldRedirectToCreateCinemaIfIdNotExists() {
-        val model = ExtendedModelMap()
-        val redirect = controller.getCinemaEditPage(UUID.randomUUID().toString(), model)
-        assertThat(redirect.equals("cinemas/edit"))
-        assertThat(model.getValue("action") == "Create")
-    }
-
-    @Test
-    @Throws(Exception::class)
-    fun shouldRedirectToEditCinemaIfIdExists() {
-        val cinema = Cinema()
-        val id = UUID.randomUUID()
-        cinema.id = id
-        cinema.name = "test"
-        controller.updateCinema(cinema)
-        val model = ExtendedModelMap()
-        val redirect = controller.getCinemaEditPage(id.toString(), model)
-        assertThat(redirect.equals("cinemas/edit"))
-        assertThat(model.getValue("action") == "Edit")
-    }
-
-    @Test
-    @Throws(Exception::class)
-    fun shouldReturnCinemasBrowsePage() {
-        val cinema = Cinema()
-        val id = UUID.randomUUID()
-        cinema.id = id
-        cinema.name = "test"
-        controller.updateCinema(cinema)
-        val model = ExtendedModelMap()
-        val redirect = controller.getCinemasBrowsePage(model)
-        assertThat(redirect.equals("cinemas/list"))
-        assertThat(model.getValue("cinemas")).isNotNull
-    }
-
-    @Test
-    @Sql("/cinemasFill.sql")
-    fun mvcTest() {
-        mvc.perform(get("/api/json/cinemas/all")
-                .contentType(MediaType.APPLICATION_JSON))
-                .andExpect(status().isOk)
-    }
-
-//    @Test
-//    @Throws(Exception::class)
-//    fun shouldDeleteCinema() {
-//        val cinema = Cinema()
-//        val id = UUID.randomUUID()
-//        cinema.id = id
-//        cinema.name = "test"
-//        controller.updateCinema(cinema)
-//        var responce = HttpResponseFactory
-//        apiController.deleteCinema(id.toString(), Http)
-//        val cinemaFromBase = controller.cinemaService.findById(id)
-//        assertThat(cinemaFromBase?.equals(cinema))
-//    }
-}
diff --git a/src/test/kotlin/com/s3ai/corporate_app2/TestUtils.kt b/src/test/kotlin/com/s3ai/corporate_app2/TestUtils.kt
index ab3d40a1fe353957cd6572e1219fd29f7c3625c3..35ecbafd6d837aa4a297382b27b97436ee26f60c 100644
--- a/src/test/kotlin/com/s3ai/corporate_app2/TestUtils.kt
+++ b/src/test/kotlin/com/s3ai/corporate_app2/TestUtils.kt
@@ -1,3 +1,17 @@
 package com.s3ai.corporate_app2
 
+import com.fasterxml.jackson.databind.DeserializationFeature
+import com.fasterxml.jackson.databind.MapperFeature
+import com.fasterxml.jackson.dataformat.xml.JacksonXmlModule
+import com.fasterxml.jackson.dataformat.xml.XmlMapper
+import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
+import com.fasterxml.jackson.module.kotlin.registerKotlinModule
 
+
+internal val kotlinXmlMapper = XmlMapper(JacksonXmlModule().apply {
+    setDefaultUseWrapper(false)
+}).registerKotlinModule()
+        .configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES, true)
+        .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
+
+internal val kotlinJsonMapper = jacksonObjectMapper()
\ No newline at end of file
diff --git a/src/test/kotlin/com/s3ai/corporate_app2/TicketsApiTest.kt b/src/test/kotlin/com/s3ai/corporate_app2/TicketsApiTest.kt
deleted file mode 100644
index 1b91a80ea29649545401550f4d643d3edf59a5d1..0000000000000000000000000000000000000000
--- a/src/test/kotlin/com/s3ai/corporate_app2/TicketsApiTest.kt
+++ /dev/null
@@ -1,71 +0,0 @@
-package com.s3ai.corporate_app2
-
-import com.s3ai.corporate_app2.controllers.TicketsController
-import org.assertj.core.api.Assertions.assertThat
-import org.junit.jupiter.api.Test
-import org.springframework.beans.factory.annotation.Autowired
-import org.springframework.boot.test.context.SpringBootTest
-import org.springframework.ui.ExtendedModelMap
-import java.util.*
-
-
-@SpringBootTest
-class TicketsApiTest {
-    @Autowired
-    private lateinit var controller: TicketsController
-
-    @Test
-    @Throws(Exception::class)
-    fun contextLoads() {
-        assertThat(controller).isNotNull
-    }
-
-    @Test
-    @Throws(Exception::class)
-    fun shouldUpdateTicket() {
-        val ticket = Ticket()
-        val id = UUID.randomUUID()
-        ticket.id = id
-        ticket.movie = "test"
-        controller.updateTicket(ticket)
-        val ticketFromBase = controller.ticketService.findById(id)
-        assertThat(ticketFromBase?.equals(ticket))
-    }
-
-    @Test
-    @Throws(Exception::class)
-    fun shouldRedirectToCreateTicketIfIdNotExists() {
-        val model = ExtendedModelMap()
-        val redirect = controller.getTicketEditPage(UUID.randomUUID().toString(), model)
-        assertThat(redirect.equals("tickets/edit"))
-        assertThat(model.getValue("action") == "Create")
-    }
-
-    @Test
-    @Throws(Exception::class)
-    fun shouldRedirectToEditCinemaIfIdExists() {
-        val ticket = Ticket()
-        val id = UUID.randomUUID()
-        ticket.id = id
-        ticket.movie = "test"
-        controller.updateTicket(ticket)
-        val model = ExtendedModelMap()
-        val redirect = controller.getTicketEditPage(id.toString(), model)
-        assertThat(redirect.equals("tickets/edit"))
-        assertThat(model.getValue("action") == "Edit")
-    }
-
-    @Test
-    @Throws(Exception::class)
-    fun shouldReturnTicketsBrowsePage() {
-        val ticket = Ticket()
-        val id = UUID.randomUUID()
-        ticket.id = id
-        ticket.movie = "test"
-        controller.updateTicket(ticket)
-        val model = ExtendedModelMap()
-        val redirect = controller.getTicketsBrowsePage(model)
-        assertThat(redirect.equals("tickets/list"))
-        assertThat(model.getValue("tickets")).isNotNull
-    }
-}
\ No newline at end of file
diff --git a/src/test/kotlin/com/s3ai/corporate_app2/UsersApiTest.kt b/src/test/kotlin/com/s3ai/corporate_app2/UsersApiTest.kt
deleted file mode 100644
index 8ff981ce7a1460d4f2aa70771a06a0845e497a6f..0000000000000000000000000000000000000000
--- a/src/test/kotlin/com/s3ai/corporate_app2/UsersApiTest.kt
+++ /dev/null
@@ -1,71 +0,0 @@
-package com.s3ai.corporate_app2
-
-import com.s3ai.corporate_app2.controllers.UsersController
-import org.assertj.core.api.Assertions.assertThat
-import org.junit.jupiter.api.Test
-import org.springframework.beans.factory.annotation.Autowired
-import org.springframework.boot.test.context.SpringBootTest
-import org.springframework.ui.ExtendedModelMap
-import java.util.*
-
-
-@SpringBootTest
-class UsersApiTest {
-    @Autowired
-    private lateinit var controller: UsersController
-
-    @Test
-    @Throws(Exception::class)
-    fun contextLoads() {
-        assertThat(controller).isNotNull
-    }
-
-    @Test
-    @Throws(Exception::class)
-    fun shouldUpdateCinema() {
-        val user = User()
-        val id = UUID.randomUUID()
-        user.id = id
-        user.name = "test"
-        controller.updateUser(user)
-        val userFromBase = controller.userService.findById(id)
-        assertThat(userFromBase?.equals(user))
-    }
-
-    @Test
-    @Throws(Exception::class)
-    fun shouldRedirectToCreateUserIfIdNotExists() {
-        val model = ExtendedModelMap()
-        val redirect = controller.getUserEditPage(UUID.randomUUID().toString(), model)
-        assertThat(redirect.equals("users/edit"))
-        assertThat(model.getValue("action") == "Create")
-    }
-
-    @Test
-    @Throws(Exception::class)
-    fun shouldRedirectToEditCinemaIfIdExists() {
-        val user = User()
-        val id = UUID.randomUUID()
-        user.id = id
-        user.name = "test"
-        controller.updateUser(user)
-        val model = ExtendedModelMap()
-        val redirect = controller.getUserEditPage(id.toString(), model)
-        assertThat(redirect.equals("users/edit"))
-        assertThat(model.getValue("action") == "Edit")
-    }
-
-    @Test
-    @Throws(Exception::class)
-    fun shouldReturnUsersBrowsePage() {
-        val user = User()
-        val id = UUID.randomUUID()
-        user.id = id
-        user.name = "test"
-        controller.updateUser(user)
-        val model = ExtendedModelMap()
-        val redirect = controller.getUsersBrowsePage(model)
-        assertThat(redirect.equals("users/list"))
-        assertThat(model.getValue("users")).isNotNull
-    }
-}
diff --git a/src/test/kotlin/com/s3ai/corporate_app2/controllers/CinemasTest.kt b/src/test/kotlin/com/s3ai/corporate_app2/controllers/CinemasTest.kt
new file mode 100644
index 0000000000000000000000000000000000000000..a159c661f33daae4542306f98cb1d877a47d27c6
--- /dev/null
+++ b/src/test/kotlin/com/s3ai/corporate_app2/controllers/CinemasTest.kt
@@ -0,0 +1,104 @@
+package com.s3ai.corporate_app2.controllers
+
+import com.fasterxml.jackson.databind.ObjectMapper
+import com.s3ai.corporate_app2.Cinema
+import com.s3ai.corporate_app2.CinemaService
+import org.assertj.core.api.Assertions.assertThat
+import org.hamcrest.Matchers
+import org.hamcrest.CoreMatchers
+import org.junit.jupiter.api.Test
+import org.springframework.beans.factory.annotation.Autowired
+import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc
+import org.springframework.boot.test.context.SpringBootTest
+import org.springframework.http.MediaType
+import org.springframework.test.context.jdbc.Sql
+import org.springframework.test.web.servlet.MockMvc
+import org.springframework.test.web.servlet.request.MockMvcRequestBuilders
+import org.springframework.test.web.servlet.result.MockMvcResultMatchers
+import org.springframework.test.web.servlet.result.MockMvcResultMatchers.*
+import java.lang.reflect.GenericArrayType
+import java.util.*
+
+
+@SpringBootTest
+@AutoConfigureMockMvc
+class CinemasTest {
+    @Autowired
+    private lateinit var service: CinemaService
+
+    @Autowired
+    private lateinit var controller: CinemasController
+
+    @Autowired
+    private lateinit var mvc: MockMvc
+
+    @Test
+    @Throws(Exception::class)
+    fun contextLoads() {
+        assertThat(controller).isNotNull
+    }
+
+    @Test
+    @Throws(Exception::class)
+    @Sql("/cinemasFill.sql")
+    fun updateCinemaTest() {
+        val cinema = service.findAll().random()
+        print(cinema.id)
+
+        cinema.name = UUID.randomUUID().toString()
+
+        mvc.perform(MockMvcRequestBuilders.post("/cinemas/update")
+                .contentType(MediaType.APPLICATION_JSON)
+                .content(ObjectMapper().writeValueAsString(cinema)))
+                .andExpect(status().isFound)
+                .andExpect(redirectedUrl("/cinemas/list"))
+
+        val updatedCinema = service.findById(cinema.id!!)
+        assertThat(cinema == updatedCinema)
+    }
+
+    @Test
+    @Throws(Exception::class)
+    fun editNonExistingIdRedirectToCreateTest() {
+        mvc.perform(MockMvcRequestBuilders.get("/cinemas/edit"))
+                .andExpect(status().isOk)
+                .andExpect(model().attribute("action", Matchers.equalTo("Create")))
+                .andExpect(model().attribute("cinema", Matchers.notNullValue(Cinema::class.java)))
+    }
+
+    @Test
+    @Throws(Exception::class)
+    @Sql("/cinemasFill.sql")
+    fun editPageTest() {
+        val randomCinemaId = service.findAll().map { e -> e.id }.distinct().random()
+        mvc.perform(MockMvcRequestBuilders.get("/cinemas/edit?id=${randomCinemaId}"))
+                .andExpect(status().isOk)
+                .andExpect(model().attribute("action", Matchers.equalTo("Edit")))
+                .andExpect(model().attribute("cinema", Matchers.notNullValue(Cinema::class.java)))
+    }
+
+    @Test
+    @Throws(Exception::class)
+    @Sql("/cinemasFill.sql")
+    fun listPageTest() {
+        mvc.perform(MockMvcRequestBuilders.get("/cinemas/list"))
+                .andExpect(status().isOk)
+                .andExpect(model().attribute("cinemas", Matchers.notNullValue(MutableCollection::class.java)))
+                .andExpect(model().attribute("cinemas", CoreMatchers.everyItem(Matchers.notNullValue(Cinema::class.java))))
+    }
+
+    @Test
+    @Throws(Exception::class)
+    fun listEmptyPageTest() {
+        mvc.perform(MockMvcRequestBuilders.get("/cinemas/list"))
+                .andExpect(status().isOk)
+                .andExpect(model().attribute("cinemas", Matchers.notNullValue(MutableCollection::class.java)))
+    }
+
+    @Test
+    @Throws(Exception::class)
+    fun editInvalidUUIDTest() {
+        mvc.perform(MockMvcRequestBuilders.get("/cinemas/edit?id=totallyNotAnUUID"))
+                .andExpect(MockMvcResultMatchers.status().isBadRequest)
+    }
+}
diff --git a/src/test/kotlin/com/s3ai/corporate_app2/controllers/TicketsTest.kt b/src/test/kotlin/com/s3ai/corporate_app2/controllers/TicketsTest.kt
new file mode 100644
index 0000000000000000000000000000000000000000..9a0b14735ca98106de3271b0e7487d3f2c86111f
--- /dev/null
+++ b/src/test/kotlin/com/s3ai/corporate_app2/controllers/TicketsTest.kt
@@ -0,0 +1,102 @@
+package com.s3ai.corporate_app2.controllers
+
+import com.fasterxml.jackson.databind.ObjectMapper
+import com.s3ai.corporate_app2.Ticket
+import com.s3ai.corporate_app2.TicketService
+import com.s3ai.corporate_app2.User
+import org.assertj.core.api.Assertions.assertThat
+import org.hamcrest.CoreMatchers
+import org.hamcrest.Matchers
+import org.junit.jupiter.api.Test
+import org.springframework.beans.factory.annotation.Autowired
+import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc
+import org.springframework.boot.test.context.SpringBootTest
+import org.springframework.http.MediaType
+import org.springframework.test.context.jdbc.Sql
+import org.springframework.test.web.servlet.MockMvc
+import org.springframework.test.web.servlet.request.MockMvcRequestBuilders
+import org.springframework.test.web.servlet.result.MockMvcResultMatchers
+import java.util.*
+
+
+@SpringBootTest
+@AutoConfigureMockMvc
+class TicketsTest {
+    @Autowired
+    private lateinit var service: TicketService
+
+    @Autowired
+    private lateinit var controller: TicketsController
+
+    @Autowired
+    private lateinit var mvc: MockMvc
+
+    @Test
+    @Throws(Exception::class)
+    fun contextLoads() {
+        assertThat(controller).isNotNull
+    }
+
+    @Test
+    @Throws(Exception::class)
+    @Sql("/cinemasFill.sql", "/usersFill.sql", "/ticketsFill.sql")
+    fun updateTicketTest() {
+        val ticket = service.findAll().random()
+        print(ticket.id)
+
+        ticket.movie = UUID.randomUUID().toString()
+
+        mvc.perform(MockMvcRequestBuilders.post("/tickets/update")
+                .contentType(MediaType.APPLICATION_JSON)
+                .content(ObjectMapper().writeValueAsString(ticket)))
+                .andExpect(MockMvcResultMatchers.status().isFound)
+                .andExpect(MockMvcResultMatchers.redirectedUrl("/tickets/list"))
+
+        val updatedTicket = service.findById(ticket.id!!)
+        assertThat(ticket == updatedTicket)
+    }
+
+    @Test
+    @Throws(Exception::class)
+    fun editNonExistingIdRedirectToCreateTest() {
+        mvc.perform(MockMvcRequestBuilders.get("/tickets/edit"))
+                .andExpect(MockMvcResultMatchers.status().isOk)
+                .andExpect(MockMvcResultMatchers.model().attribute("action", Matchers.equalTo("Create")))
+                .andExpect(MockMvcResultMatchers.model().attribute("ticket", Matchers.notNullValue(Ticket::class.java)))
+    }
+
+    @Test
+    @Throws(Exception::class)
+    @Sql("/cinemasFill.sql", "/usersFill.sql", "/ticketsFill.sql")
+    fun editPageTest() {
+        val randomTicketId = service.findAll().map { e -> e.id }.distinct().random()
+        mvc.perform(MockMvcRequestBuilders.get("/tickets/edit?id=${randomTicketId}"))
+                .andExpect(MockMvcResultMatchers.status().isOk)
+                .andExpect(MockMvcResultMatchers.model().attribute("action", Matchers.equalTo("Edit")))
+                .andExpect(MockMvcResultMatchers.model().attribute("ticket", Matchers.notNullValue(Ticket::class.java)))
+    }
+
+    @Test
+    @Throws(Exception::class)
+    @Sql("/cinemasFill.sql", "/usersFill.sql", "/ticketsFill.sql")
+    fun listPageTest() {
+        mvc.perform(MockMvcRequestBuilders.get("/tickets/list"))
+                .andExpect(MockMvcResultMatchers.status().isOk)
+                .andExpect(MockMvcResultMatchers.model().attribute("tickets", CoreMatchers.everyItem(Matchers.notNullValue(Ticket::class.java))))
+    }
+
+    @Test
+    @Throws(Exception::class)
+    fun listEmptyPageTest() {
+        mvc.perform(MockMvcRequestBuilders.get("/tickets/list"))
+                .andExpect(MockMvcResultMatchers.status().isOk)
+                .andExpect(MockMvcResultMatchers.model().attribute("tickets", Matchers.notNullValue(MutableCollection::class.java)))
+    }
+
+    @Test
+    @Throws(Exception::class)
+    fun editInvalidUUIDTest() {
+        mvc.perform(MockMvcRequestBuilders.get("/tickets/edit?id=totallyNotAnUUID"))
+                .andExpect(MockMvcResultMatchers.status().isBadRequest)
+    }
+}
\ No newline at end of file
diff --git a/src/test/kotlin/com/s3ai/corporate_app2/controllers/UsersTest.kt b/src/test/kotlin/com/s3ai/corporate_app2/controllers/UsersTest.kt
new file mode 100644
index 0000000000000000000000000000000000000000..f58ead09f91aa5476fe0c571e19e434f58402951
--- /dev/null
+++ b/src/test/kotlin/com/s3ai/corporate_app2/controllers/UsersTest.kt
@@ -0,0 +1,103 @@
+package com.s3ai.corporate_app2.controllers
+
+import com.fasterxml.jackson.databind.ObjectMapper
+import com.s3ai.corporate_app2.Cinema
+import com.s3ai.corporate_app2.User
+import com.s3ai.corporate_app2.UserService
+import org.assertj.core.api.Assertions.assertThat
+import org.hamcrest.CoreMatchers
+import org.hamcrest.CoreMatchers.everyItem
+import org.hamcrest.Matchers
+import org.junit.jupiter.api.Test
+import org.springframework.beans.factory.annotation.Autowired
+import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc
+import org.springframework.boot.test.context.SpringBootTest
+import org.springframework.http.MediaType
+import org.springframework.test.context.jdbc.Sql
+import org.springframework.test.web.servlet.MockMvc
+import org.springframework.test.web.servlet.request.MockMvcRequestBuilders
+import org.springframework.test.web.servlet.result.MockMvcResultMatchers
+import java.util.*
+
+
+@SpringBootTest
+@AutoConfigureMockMvc
+class UsersTest {
+    @Autowired
+    private lateinit var service: UserService
+
+    @Autowired
+    private lateinit var controller: UsersController
+
+    @Autowired
+    private lateinit var mvc: MockMvc
+
+    @Test
+    @Throws(Exception::class)
+    fun contextLoads() {
+        assertThat(controller).isNotNull
+    }
+
+    @Test
+    @Throws(Exception::class)
+    @Sql("/usersFill.sql")
+    fun updateUserTest() {
+        val user = service.findAll().random()
+        print(user.id)
+
+        user.name = UUID.randomUUID().toString()
+
+        mvc.perform(MockMvcRequestBuilders.post("/users/update")
+                .contentType(MediaType.APPLICATION_JSON)
+                .content(ObjectMapper().writeValueAsString(user)))
+                .andExpect(MockMvcResultMatchers.status().isFound)
+                .andExpect(MockMvcResultMatchers.redirectedUrl("/users/list"))
+
+        val updatedUser = service.findById(user.id!!)
+        assertThat(user == updatedUser)
+    }
+
+    @Test
+    @Throws(Exception::class)
+    fun editNonExistingIdRedirectToCreateTest() {
+        mvc.perform(MockMvcRequestBuilders.get("/users/edit"))
+                .andExpect(MockMvcResultMatchers.status().isOk)
+                .andExpect(MockMvcResultMatchers.model().attribute("action", Matchers.equalTo("Create")))
+                .andExpect(MockMvcResultMatchers.model().attribute("user", Matchers.notNullValue(User::class.java)))
+    }
+
+    @Test
+    @Throws(Exception::class)
+    @Sql("/usersFill.sql")
+    fun editPageTest() {
+        val randomUserId = service.findAll().map { e -> e.id }.distinct().random()
+        mvc.perform(MockMvcRequestBuilders.get("/users/edit?id=${randomUserId}"))
+                .andExpect(MockMvcResultMatchers.status().isOk)
+                .andExpect(MockMvcResultMatchers.model().attribute("action", Matchers.equalTo("Edit")))
+                .andExpect(MockMvcResultMatchers.model().attribute("user", Matchers.notNullValue(User::class.java)))
+    }
+
+    @Test
+    @Throws(Exception::class)
+    @Sql("/usersFill.sql")
+    fun listPageTest() {
+        mvc.perform(MockMvcRequestBuilders.get("/users/list"))
+                .andExpect(MockMvcResultMatchers.status().isOk)
+                .andExpect(MockMvcResultMatchers.model().attribute("users", everyItem(Matchers.notNullValue(User::class.java))))
+    }
+
+    @Test
+    @Throws(Exception::class)
+    fun listEmptyPageTest() {
+        mvc.perform(MockMvcRequestBuilders.get("/users/list"))
+                .andExpect(MockMvcResultMatchers.status().isOk)
+                .andExpect(MockMvcResultMatchers.model().attribute("users", Matchers.notNullValue(MutableCollection::class.java)))
+    }
+
+    @Test
+    @Throws(Exception::class)
+    fun editInvalidUUIDTest() {
+        mvc.perform(MockMvcRequestBuilders.get("/users/edit?id=totallyNotAnUUID"))
+                .andExpect(MockMvcResultMatchers.status().isBadRequest)
+    }
+}
diff --git a/src/test/kotlin/com/s3ai/corporate_app2/controllers/rest/CinemaApiTest.kt b/src/test/kotlin/com/s3ai/corporate_app2/controllers/rest/CinemaApiTest.kt
new file mode 100644
index 0000000000000000000000000000000000000000..f2692518bd8857143bc1b807f8c49ae8bbac6f75
--- /dev/null
+++ b/src/test/kotlin/com/s3ai/corporate_app2/controllers/rest/CinemaApiTest.kt
@@ -0,0 +1,78 @@
+package com.s3ai.corporate_app2.controllers.rest
+
+import com.s3ai.corporate_app2.CinemaService
+import com.s3ai.corporate_app2.TicketService
+import org.assertj.core.api.Assertions
+import org.hamcrest.MatcherAssert.assertThat
+import org.hamcrest.Matchers.equalTo
+import org.hamcrest.Matchers.hasItem
+import org.hamcrest.core.IsNot.not
+import org.junit.jupiter.api.Test
+import org.springframework.beans.factory.annotation.Autowired
+import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc
+import org.springframework.boot.test.context.SpringBootTest
+import org.springframework.test.context.jdbc.Sql
+import org.springframework.test.web.servlet.MockMvc
+import org.springframework.test.web.servlet.MvcResult
+import org.springframework.test.web.servlet.request.MockMvcRequestBuilders
+import org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete
+import org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get
+import org.springframework.test.web.servlet.result.MockMvcResultMatchers
+import org.springframework.test.web.servlet.result.MockMvcResultMatchers.status
+import java.util.*
+
+@SpringBootTest
+@AutoConfigureMockMvc
+class CinemaApiTest {
+    @Autowired
+    private lateinit var service: CinemaService
+
+    @Autowired
+    private lateinit var ticketService: TicketService
+
+    @Autowired
+    private lateinit var mvc: MockMvc
+
+    @Test
+    @Throws(Exception::class)
+    fun contextLoads() {
+        Assertions.assertThat(mvc).isNotNull
+        Assertions.assertThat(service).isNotNull
+    }
+
+    @Test
+    @Sql("/cinemasFill.sql")
+    fun fillTest() {
+        mvc.perform(get("/api/cinemas/fill"))
+                .andDo { e: MvcResult -> println(e.response) }
+                .andExpect(status().isOk)
+        assertThat(service.findAll().size, equalTo(401))
+    }
+
+    @Test
+    @Sql("/cinemasFill.sql", "/usersFill.sql", "/ticketsFill.sql")
+    fun deleteTest() {
+        val randomCinemaId = ticketService.findAll().map { e -> e.cinema?.id }.distinct().random()
+        print(randomCinemaId)
+        mvc.perform(delete("/api/cinemas/delete?id=${randomCinemaId}"))
+                .andExpect(status().isOk)
+        val tickets = ticketService.findAll().map { e -> e.cinema!!.id }.distinct()
+        assertThat(tickets, not(hasItem(randomCinemaId)))
+    }
+
+    @Test
+    @Sql("/cinemasFill.sql", "/usersFill.sql", "/ticketsFill.sql")
+    fun deleteNonExistingIdReturns404Test() {
+        val randomCinemaId = UUID.randomUUID()
+        print(randomCinemaId)
+        mvc.perform(delete("/api/cinemas/delete?id=${randomCinemaId}"))
+                .andExpect(status().isNotFound)
+    }
+
+    @Test
+    @Throws(Exception::class)
+    fun deleteInvalidUUIDTest() {
+        mvc.perform(delete("/api/cinemas/delete?id=totallyNotAnUUID"))
+                .andExpect(status().isBadRequest)
+    }
+}
\ No newline at end of file
diff --git a/src/test/kotlin/com/s3ai/corporate_app2/controllers/rest/TicketApiTest.kt b/src/test/kotlin/com/s3ai/corporate_app2/controllers/rest/TicketApiTest.kt
new file mode 100644
index 0000000000000000000000000000000000000000..b493ac1a651e2107b84b98e66f3949e517039be7
--- /dev/null
+++ b/src/test/kotlin/com/s3ai/corporate_app2/controllers/rest/TicketApiTest.kt
@@ -0,0 +1,70 @@
+package com.s3ai.corporate_app2.controllers.rest
+
+import com.s3ai.corporate_app2.TicketService
+import org.assertj.core.api.Assertions
+import org.hamcrest.MatcherAssert
+import org.hamcrest.Matchers
+import org.hamcrest.core.IsNot
+import org.junit.jupiter.api.Test
+import org.springframework.beans.factory.annotation.Autowired
+import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc
+import org.springframework.boot.test.context.SpringBootTest
+import org.springframework.test.context.jdbc.Sql
+import org.springframework.test.web.servlet.MockMvc
+import org.springframework.test.web.servlet.MvcResult
+import org.springframework.test.web.servlet.request.MockMvcRequestBuilders
+import org.springframework.test.web.servlet.result.MockMvcResultMatchers
+import java.util.*
+
+@SpringBootTest
+@AutoConfigureMockMvc
+class TicketApiTest {
+    @Autowired
+    private lateinit var service: TicketService
+
+    @Autowired
+    private lateinit var mvc: MockMvc
+
+    @Test
+    @Throws(Exception::class)
+    fun contextLoads() {
+        Assertions.assertThat(mvc).isNotNull
+        Assertions.assertThat(service).isNotNull
+    }
+
+    @Test
+    @Sql("/cinemasFill.sql", "/usersFill.sql", "/ticketsFill.sql")
+    fun fillTest() {
+        mvc.perform(MockMvcRequestBuilders.get("/api/tickets/fill"))
+                .andDo { e: MvcResult -> println(e.response) }
+                .andExpect(MockMvcResultMatchers.status().isOk)
+        MatcherAssert.assertThat(service.findAll().size, Matchers.equalTo(401))
+    }
+
+    @Test
+    @Sql("/cinemasFill.sql", "/usersFill.sql", "/ticketsFill.sql")
+    fun deleteTest() {
+        val randomTicketId = service.findAll().map { e -> e.id }.distinct().random()
+        print(randomTicketId)
+        mvc.perform(MockMvcRequestBuilders.delete("/api/tickets/delete?id=${randomTicketId}"))
+                .andExpect(MockMvcResultMatchers.status().isOk)
+        val tickets = service.findAll().map { e -> e.id }.distinct()
+        MatcherAssert.assertThat(tickets, IsNot.not(Matchers.hasItem(randomTicketId)))
+    }
+
+    @Test
+    @Sql("/cinemasFill.sql", "/usersFill.sql", "/ticketsFill.sql")
+    fun deleteNonExistingIdReturns404Test() {
+        val randomTicketId = UUID.randomUUID()
+        print(randomTicketId)
+        mvc.perform(MockMvcRequestBuilders.delete("/api/tickets/delete?id=${randomTicketId}"))
+                .andExpect(MockMvcResultMatchers.status().isNotFound)
+    }
+
+    @Test
+    @Throws(Exception::class)
+    fun deleteInvalidUUIDTest() {
+        mvc.perform(MockMvcRequestBuilders.delete("/api/tickets/delete?id=totallyNotAnUUID"))
+                .andExpect(MockMvcResultMatchers.status().isBadRequest)
+    }
+}
\ No newline at end of file
diff --git a/src/test/kotlin/com/s3ai/corporate_app2/controllers/rest/UserApiTest.kt b/src/test/kotlin/com/s3ai/corporate_app2/controllers/rest/UserApiTest.kt
new file mode 100644
index 0000000000000000000000000000000000000000..55ee715ba587b189d34b3f930169adb6c6e7dbe4
--- /dev/null
+++ b/src/test/kotlin/com/s3ai/corporate_app2/controllers/rest/UserApiTest.kt
@@ -0,0 +1,74 @@
+package com.s3ai.corporate_app2.controllers.rest
+
+import com.s3ai.corporate_app2.UserService
+import com.s3ai.corporate_app2.TicketService
+import org.assertj.core.api.Assertions
+import org.hamcrest.MatcherAssert
+import org.hamcrest.Matchers
+import org.hamcrest.core.IsNot
+import org.junit.jupiter.api.Test
+import org.springframework.beans.factory.annotation.Autowired
+import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc
+import org.springframework.boot.test.context.SpringBootTest
+import org.springframework.test.context.jdbc.Sql
+import org.springframework.test.web.servlet.MockMvc
+import org.springframework.test.web.servlet.MvcResult
+import org.springframework.test.web.servlet.request.MockMvcRequestBuilders
+import org.springframework.test.web.servlet.result.MockMvcResultMatchers
+import java.util.*
+
+@SpringBootTest
+@AutoConfigureMockMvc
+class UserApiTest {
+    @Autowired
+    private lateinit var service: UserService
+
+    @Autowired
+    private lateinit var ticketService: TicketService
+
+    @Autowired
+    private lateinit var mvc: MockMvc
+
+    @Test
+    @Throws(Exception::class)
+    fun contextLoads() {
+        Assertions.assertThat(mvc).isNotNull
+        Assertions.assertThat(service).isNotNull
+    }
+
+    @Test
+    @Sql("/usersFill.sql")
+    fun fillTest() {
+        mvc.perform(MockMvcRequestBuilders.get("/api/users/fill"))
+                .andDo { e: MvcResult -> println(e.response) }
+                .andExpect(MockMvcResultMatchers.status().isOk)
+        MatcherAssert.assertThat(service.findAll().size, Matchers.equalTo(401))
+    }
+
+    @Test
+    @Sql("/usersFill.sql", "/cinemasFill.sql", "/ticketsFill.sql")
+    fun deleteTest() {
+        val randomUserId = ticketService.findAll().map { e -> e.user?.id }.distinct().random()
+        print(randomUserId)
+        mvc.perform(MockMvcRequestBuilders.delete("/api/users/delete?id=${randomUserId}"))
+                .andExpect(MockMvcResultMatchers.status().isOk)
+        val tickets = ticketService.findAll().map { e -> e.user!!.id }.distinct()
+        MatcherAssert.assertThat(tickets, IsNot.not(Matchers.hasItem(randomUserId)))
+    }
+
+    @Test
+    @Sql("/usersFill.sql", "/cinemasFill.sql", "/ticketsFill.sql")
+    fun deleteNonExistingIdReturns404Test() {
+        val randomUserId = UUID.randomUUID()
+        print(randomUserId)
+        mvc.perform(MockMvcRequestBuilders.delete("/api/users/delete?id=${randomUserId}"))
+                .andExpect(MockMvcResultMatchers.status().isNotFound)
+    }
+
+    @Test
+    @Throws(Exception::class)
+    fun deleteInvalidUUIDTest() {
+        mvc.perform(MockMvcRequestBuilders.delete("/api/users/delete?id=totallyNotAnUUID"))
+                .andExpect(MockMvcResultMatchers.status().isBadRequest)
+    }
+}
\ No newline at end of file
diff --git a/src/test/kotlin/com/s3ai/corporate_app2/controllers/rest/formats/CinemasFormattingTests.kt b/src/test/kotlin/com/s3ai/corporate_app2/controllers/rest/formats/CinemasFormattingTests.kt
new file mode 100644
index 0000000000000000000000000000000000000000..5428d37656617d791a2a8d38f3fdf0aab91e7e73
--- /dev/null
+++ b/src/test/kotlin/com/s3ai/corporate_app2/controllers/rest/formats/CinemasFormattingTests.kt
@@ -0,0 +1,84 @@
+package com.s3ai.corporate_app2.controllers.rest.formats
+
+import com.fasterxml.jackson.databind.DeserializationFeature
+import com.fasterxml.jackson.databind.MapperFeature
+import com.fasterxml.jackson.dataformat.xml.JacksonXmlModule
+import com.fasterxml.jackson.dataformat.xml.XmlMapper
+import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
+import com.fasterxml.jackson.module.kotlin.readValue
+import com.fasterxml.jackson.module.kotlin.registerKotlinModule
+import com.s3ai.corporate_app2.Cinema
+import com.s3ai.corporate_app2.CinemaService
+import com.s3ai.corporate_app2.kotlinJsonMapper
+import com.s3ai.corporate_app2.kotlinXmlMapper
+import org.assertj.core.api.Assertions
+import org.hamcrest.CoreMatchers.equalTo
+import org.hamcrest.MatcherAssert.assertThat
+import org.junit.jupiter.api.Test
+import org.springframework.beans.factory.annotation.Autowired
+import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc
+import org.springframework.boot.test.context.SpringBootTest
+import org.springframework.test.context.jdbc.Sql
+import org.springframework.test.web.servlet.MockMvc
+import org.springframework.test.web.servlet.request.MockMvcRequestBuilders
+import org.springframework.test.web.servlet.result.MockMvcResultMatchers
+
+
+@SpringBootTest
+@AutoConfigureMockMvc
+class CinemasFormattingTests {
+    @Autowired
+    private lateinit var service: CinemaService
+
+    @Autowired
+    private lateinit var mvc: MockMvc
+
+    @Test
+    @Throws(Exception::class)
+    fun contextLoads() {
+        Assertions.assertThat(mvc).isNotNull
+        Assertions.assertThat(service).isNotNull
+    }
+
+    @Test
+    @Sql("/cinemasFill.sql")
+    fun allJSONTest() {
+        val mvcResult = mvc.perform(MockMvcRequestBuilders.get("/api/json/cinemas/all"))
+                .andExpect(MockMvcResultMatchers.status().isOk)
+                .andReturn()
+        val cinemas: List<Cinema> = kotlinJsonMapper.readValue(mvcResult.response.contentAsString)
+        assertThat(cinemas.size, equalTo(100))
+    }
+
+    @Test
+    @Sql("/cinemasFill.sql")
+    fun itemJSONTest() {
+        val randomCinema = service.findAll().random()
+        val mvcResult = mvc.perform(MockMvcRequestBuilders.get("/api/json/cinemas/item/${randomCinema.id}"))
+                .andExpect(MockMvcResultMatchers.status().isOk)
+                .andReturn()
+        val parsedCinema: Cinema = kotlinJsonMapper.readValue(mvcResult.response.contentAsString)
+        assertThat(parsedCinema.toString(), equalTo(randomCinema.toString()))
+    }
+
+    @Test
+    @Sql("/cinemasFill.sql")
+    fun allXMLTest() {
+        val mvcResult = mvc.perform(MockMvcRequestBuilders.get("/api/xml/cinemas/all"))
+                .andExpect(MockMvcResultMatchers.status().isOk)
+                .andReturn()
+        val cinemas: List<Cinema> = kotlinXmlMapper.readValue(mvcResult.response.contentAsString)
+        assertThat(cinemas.size, equalTo(100))
+    }
+
+    @Test
+    @Sql("/cinemasFill.sql")
+    fun itemXMLTest() {
+        val randomCinema = service.findAll().random()
+        val mvcResult = mvc.perform(MockMvcRequestBuilders.get("/api/xml/cinemas/item/${randomCinema.id}"))
+                .andExpect(MockMvcResultMatchers.status().isOk)
+                .andReturn()
+        val parsedCinema: Cinema = kotlinXmlMapper.readValue(mvcResult.response.contentAsString)
+        assertThat(parsedCinema.toString(), equalTo(randomCinema.toString()))
+    }
+}
\ No newline at end of file
diff --git a/src/test/kotlin/com/s3ai/corporate_app2/controllers/rest/formats/TicketsFormattingTests.kt b/src/test/kotlin/com/s3ai/corporate_app2/controllers/rest/formats/TicketsFormattingTests.kt
new file mode 100644
index 0000000000000000000000000000000000000000..2af121d0cada32827f2dc4632132b4022b384778
--- /dev/null
+++ b/src/test/kotlin/com/s3ai/corporate_app2/controllers/rest/formats/TicketsFormattingTests.kt
@@ -0,0 +1,78 @@
+package com.s3ai.corporate_app2.controllers.rest.formats
+
+import com.fasterxml.jackson.module.kotlin.readValue
+import com.s3ai.corporate_app2.Ticket
+import com.s3ai.corporate_app2.TicketService
+import com.s3ai.corporate_app2.kotlinJsonMapper
+import com.s3ai.corporate_app2.kotlinXmlMapper
+import org.assertj.core.api.Assertions
+import org.hamcrest.CoreMatchers.equalTo
+import org.hamcrest.MatcherAssert.assertThat
+import org.junit.jupiter.api.Test
+import org.springframework.beans.factory.annotation.Autowired
+import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc
+import org.springframework.boot.test.context.SpringBootTest
+import org.springframework.test.context.jdbc.Sql
+import org.springframework.test.web.servlet.MockMvc
+import org.springframework.test.web.servlet.request.MockMvcRequestBuilders
+import org.springframework.test.web.servlet.result.MockMvcResultMatchers
+
+
+@SpringBootTest
+@AutoConfigureMockMvc
+class TicketsFormattingTests {
+    @Autowired
+    private lateinit var service: TicketService
+
+    @Autowired
+    private lateinit var mvc: MockMvc
+
+    @Test
+    @Throws(Exception::class)
+    fun contextLoads() {
+        Assertions.assertThat(mvc).isNotNull
+        Assertions.assertThat(service).isNotNull
+    }
+
+    @Test
+    @Sql("/cinemasFill.sql", "/usersFill.sql", "/ticketsFill.sql")
+    fun allJSONTest() {
+        val mvcResult = mvc.perform(MockMvcRequestBuilders.get("/api/json/tickets/all"))
+                .andExpect(MockMvcResultMatchers.status().isOk)
+                .andReturn()
+        val cinemas: List<Ticket> = kotlinJsonMapper.readValue(mvcResult.response.contentAsString)
+        assertThat(cinemas.size, equalTo(100))
+    }
+
+    @Test
+    @Sql("/cinemasFill.sql", "/usersFill.sql", "/ticketsFill.sql")
+    fun itemJSONTest() {
+        val randomTicket = service.findAll().random()
+        val mvcResult = mvc.perform(MockMvcRequestBuilders.get("/api/json/tickets/item/${randomTicket.id}"))
+                .andExpect(MockMvcResultMatchers.status().isOk)
+                .andReturn()
+        val parsedTicket: Ticket = kotlinJsonMapper.readValue(mvcResult.response.contentAsString)
+        assertThat(parsedTicket.toString(), equalTo(randomTicket.toString()))
+    }
+
+    @Test
+    @Sql("/cinemasFill.sql", "/usersFill.sql", "/ticketsFill.sql")
+    fun allXMLTest() {
+        val mvcResult = mvc.perform(MockMvcRequestBuilders.get("/api/xml/tickets/all"))
+                .andExpect(MockMvcResultMatchers.status().isOk)
+                .andReturn()
+        val cinemas: List<Ticket> = kotlinXmlMapper.readValue(mvcResult.response.contentAsString)
+        assertThat(cinemas.size, equalTo(100))
+    }
+
+    @Test
+    @Sql("/cinemasFill.sql", "/usersFill.sql", "/ticketsFill.sql")
+    fun itemXMLTest() {
+        val randomTicket = service.findAll().random()
+        val mvcResult = mvc.perform(MockMvcRequestBuilders.get("/api/xml/tickets/item/${randomTicket.id}"))
+                .andExpect(MockMvcResultMatchers.status().isOk)
+                .andReturn()
+        val parsedTicket: Ticket = kotlinXmlMapper.readValue(mvcResult.response.contentAsString)
+        assertThat(parsedTicket.toString(), equalTo(randomTicket.toString()))
+    }
+}
\ No newline at end of file
diff --git a/src/test/kotlin/com/s3ai/corporate_app2/controllers/rest/formats/UsersFormattingTests.kt b/src/test/kotlin/com/s3ai/corporate_app2/controllers/rest/formats/UsersFormattingTests.kt
new file mode 100644
index 0000000000000000000000000000000000000000..a6cd837e536d68cd4acbdde5c6bdbb0c998d45cc
--- /dev/null
+++ b/src/test/kotlin/com/s3ai/corporate_app2/controllers/rest/formats/UsersFormattingTests.kt
@@ -0,0 +1,83 @@
+package com.s3ai.corporate_app2.controllers.rest.formats
+
+import com.fasterxml.jackson.databind.DeserializationFeature
+import com.fasterxml.jackson.databind.MapperFeature
+import com.fasterxml.jackson.dataformat.xml.JacksonXmlModule
+import com.fasterxml.jackson.dataformat.xml.XmlMapper
+import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
+import com.fasterxml.jackson.module.kotlin.readValue
+import com.fasterxml.jackson.module.kotlin.registerKotlinModule
+import com.s3ai.corporate_app2.*
+import com.s3ai.corporate_app2.kotlinJsonMapper
+import com.s3ai.corporate_app2.kotlinXmlMapper
+import org.assertj.core.api.Assertions
+import org.hamcrest.CoreMatchers.equalTo
+import org.hamcrest.MatcherAssert.assertThat
+import org.junit.jupiter.api.Test
+import org.springframework.beans.factory.annotation.Autowired
+import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc
+import org.springframework.boot.test.context.SpringBootTest
+import org.springframework.test.context.jdbc.Sql
+import org.springframework.test.web.servlet.MockMvc
+import org.springframework.test.web.servlet.request.MockMvcRequestBuilders
+import org.springframework.test.web.servlet.result.MockMvcResultMatchers
+
+
+@SpringBootTest
+@AutoConfigureMockMvc
+class UsersFormattingTests {
+    @Autowired
+    private lateinit var service: UserService
+
+    @Autowired
+    private lateinit var mvc: MockMvc
+
+    @Test
+    @Throws(Exception::class)
+    fun contextLoads() {
+        Assertions.assertThat(mvc).isNotNull
+        Assertions.assertThat(service).isNotNull
+    }
+
+    @Test
+    @Sql("/usersFill.sql")
+    fun allJSONTest() {
+        val mvcResult = mvc.perform(MockMvcRequestBuilders.get("/api/json/users/all"))
+                .andExpect(MockMvcResultMatchers.status().isOk)
+                .andReturn()
+        val cinemas: List<User> = kotlinJsonMapper.readValue(mvcResult.response.contentAsString)
+        assertThat(cinemas.size, equalTo(100))
+    }
+
+    @Test
+    @Sql("/usersFill.sql")
+    fun itemJSONTest() {
+        val randomUser = service.findAll().random()
+        val mvcResult = mvc.perform(MockMvcRequestBuilders.get("/api/json/users/item/${randomUser.id}"))
+                .andExpect(MockMvcResultMatchers.status().isOk)
+                .andReturn()
+        val parsedUser: User = kotlinJsonMapper.readValue(mvcResult.response.contentAsString)
+        assertThat(parsedUser.toString(), equalTo(randomUser.toString()))
+    }
+
+    @Test
+    @Sql("/usersFill.sql")
+    fun allXMLTest() {
+        val mvcResult = mvc.perform(MockMvcRequestBuilders.get("/api/xml/users/all"))
+                .andExpect(MockMvcResultMatchers.status().isOk)
+                .andReturn()
+        val cinemas: List<User> = kotlinXmlMapper.readValue(mvcResult.response.contentAsString)
+        assertThat(cinemas.size, equalTo(100))
+    }
+
+    @Test
+    @Sql("/usersFill.sql")
+    fun itemXMLTest() {
+        val randomUser = service.findAll().random()
+        val mvcResult = mvc.perform(MockMvcRequestBuilders.get("/api/xml/users/item/${randomUser.id}"))
+                .andExpect(MockMvcResultMatchers.status().isOk)
+                .andReturn()
+        val parsedUser: User = kotlinXmlMapper.readValue(mvcResult.response.contentAsString)
+        assertThat(parsedUser.toString(), equalTo(randomUser.toString()))
+    }
+}
\ No newline at end of file