diff --git a/.gitignore b/.gitignore
new file mode 100644
index 000000000..ad02a2599
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,5 @@
+.idea
+out
+target
+*.iml
+log
\ No newline at end of file
diff --git a/README.md b/README.md
index ed139bed8..a91c9ce3f 100644
--- a/README.md
+++ b/README.md
@@ -1,81 +1,172 @@
-#### Написание с нуля полнофункционального многомодульного Maven проекта:
-веб приложения (Tomcat, JSP, jQuery),
-многопоточного почтового сервиса (JavaMail, java.util.concurrent.*) и вспомогательных модулей связанных по Веб и REST сервисам (SOAP, JAX-WS, Axis, JAX-RS)
-c сохранением данных в RMDBS и динамическим конфигурирование модулей по JMX.
-
-## Сервис-ориентированная архитектура, Микросервисы
-- JMS, альтернативы
-- Варианты разворачивания сервисов. Работа с базой. Связывание сервисов.
-
-## Maven. Многомодульный Maven проект
-- Build Lifecycle
-- Dependency Mechanism
-- Зависимости, профили, написание плагина
-- The Reactor. Snapshots
-
-## Создание/тестирование веб-приложения.
-- Сборка, запуск, локальный и удаленный debug проекта, способы деплоя в Tomcat
-- tomcat7-maven-plugin
-
-### Веб-сервисы
-- Веб-сервисы. SOAP. Преимущества/недостатки веб-сервисов. Расширения.
-- Реализация веб-сервисов в Java. JAX-RPC, JAX-WS, CFX, Axis. Стили WSDL
-- Создание API и реализации веб-сервиса MailService.
-- Деплой и тестирование через SoapUI.
-
-## Доработка веб-сервиса. Кастомизация WSDL.
-- Работа с JAXB.
-- Передача по SOAP Exception
-- Включение wsdl в сервис для публикации.
-- Генерация java кода по WSDL
-
-## Реализация клиент веб-сервиса.
-- Публикация веб сервиса из main(). Дабавление wsdl
-- Выделение из wsdl общей части
-- Создание клиента почтового сервиса.
-- Тестирование с помощью JUnit 4
-- Интеграционное тестирование, maven-failsafe-plugin
-
-## JAX-WS Handlers
-- Logical/protocol handlers.
-- Логирование SOAP на стороне клиента.
-- Логирование и статистика трафика опубликованного веб-сервиса.
-- wsimport binding.
-- SoapHandler аутентификация.
-Добавляем файлы вложения. Mail-Service.
-
-## Создаем вложения почты
-- Генерация обновленного WSDL через wsgen
-- Веб-сервисы: JAX-WS attachment with MTOM
-- Тестирование вложений через SoapUi.
-
-## Загрузка файлов.
-- Стандарт MIME. Обрабатываем вложения на форме: commons-fileupload
-- Загрузка файла вместе в полями формы.
-- Вызов клиента с вложениями.
-
-## Персистентность.
-- NoSQL or RDBMS. Обзор NoSQL систем. CAP
-- Обзор Java persistence solution: commons-dbutils, Spring JdbcTemplate, MyBatis, JOOQ, ORM (Hibernate, TopLink, ElipseLink, EBean used in Playframework). JPA. JPA Performance Benchmark
-- Работа с базой: создание базы, настройка IDEA Database.
-- Работа с DB через DataSource, настройка tomcat. HikariCP
-- Настройка работы с DataSource из JUnit.
-
-## REST веб сервис.
-- JAX-RS. Интеграция с Jersey
-- Поддержка Json. Jackson
-
-## Асинхронность.
-- @OneWay vs Java Execution framework
-- Добавление в клиенте асинхронных вызовов.
-- Асинхронные сервлеты 3.x в Tomcat
+# Многомодульный maven. Многопоточность. XML. Веб сервисы. Удаленное взаимодействие
+## Регистрация
+## [Программа проекта](#Программа-проекта-1)
+
+### _Разработка полнофункционального многомодульного Maven проекта_
+- веб приложение (Tomcat, Thymleaf, jQuery)
+- модуль экспорта из XML (JAXB, StAX)
+- многопоточный почтовый сервис (JavaMail, java.util.concurrent.*)
+- связь модулей через веб-сервисы (SOAP, JAX-WS) и по REST (JAX-RS)
+- сохранение данных в RMDBS (postgresql)
+- библиотеки Guava, StreamEx, Lombook, Typesafe config, jDBI
+
+### Требование к участникам
+Опыт программирования на Java. Базовые знания Maven.
+
+### Необходимое ПО
+- JDK8
+- Git
+- IntelliJ IDEA
+
+> Выбирать Ultimate, 30 days trial (работа с JavaScript, Tomcat, JSP). Персональный ключ к Ultimate (на 6 месяцев) выдается на первом занятии.
+
+# Первое занятие: многопоточность.
+
+##  1. Вступление. Многопоточность и параллельность.
+
+
+##  2. Структура памяти Java. Ленивая инициализация.
+> В видео в `LazySingleton` ошибка: должно быть как в коде проекта `instance == null`
+
+### Структура памяти: куча, стек, permanent/metaspace
+ - JVM изнутри - оптимизация и профилирование.
+ - Stack and Heap
+ - Дополнительно:
+ - Из каких частей состоит память java процесса.
+ - Permanent область памяти
+ - Java thread stack
+ - Размер Java объектов
+
+### Ленивая инициализация
+- Реализация Singleton в JAVA
+- Double checked locking
+- Initialization-on-demand holder idiom
+- Подводные камни Singleton
+
+##  3. Реализация многопоточности в Java
+- Параллелизм в Java
+- Монитор (синхронизация)
+- Compare-and-swap
+- Java Memory Model
+- Синхронизация потоков
+- Обзор java.util.concurrent.*
+- Как работает ConcurrentHashMap
+- Справочник по синхронизаторам java.util.concurrent.*
+- Использование ThreadLocal переменных
+- Николай Алименков — Прикладная многопоточность
+- Can thread switching happen in the synchronized block?
+
+#### Tproger: Многопоточное программирование в Java 8
+- 1. Параллельное выполнение кода с помощью потоков
+- 2. Синхронизация доступа к изменяемым объектам
+- 3. Атомарные переменные и конкурентные таблицы
+
+##  4. Реализация многопоточной отправки писем. Execution Framework
+> правка к видео: `22: completionService.submit(..)`
-## Динамическое конфигурирование. JMX
-- Maven Groovy cкрптинг. groovy-maven-plugin
-- Настройка Tomcat на удаленное администрирование по JMX
+###  Все изменения в проекте будут делаться на основе патчей: скачайте [1_1_MailService.patch](https://drive.google.com/open?id=0B9Ye2auQ_NsFTE5ZV3pzWElxTWM), положите его в проект, правой мышкой на нем сделайте Apply Patch ...
-## Отправка email в многопоточном приложении
-- Initialization on demand holder / Double-checked locking
-- java.util.concurrent.*: Executors , Synchronizers, Concurrent Collections, Lock
+----------------------------
-## Проблема MemoryLeak. Поиск утечки памяти.
+### Ресурсы (основы)
+- Intuit, Потоки выполнения. Синхронизация
+- Алексей Владыкин, Основы многопоточность в Java
+- Виталий Чибриков, Java. Многопоточность
+- Computer Science Center, курс Параллельное программирование
+- Юрий Ткач, курс Advanced Java - Concurrency
+- Головач, курс Java Multithreading
+
+---
+##  Задание первого занятия
+
+Вычекать этот проект:
+```git clone https://github.com/JavaOPs/masterjava.git```
+
+- Применить оптимизацию к MatrixUtil.singleThreadMultiply
+- Реализовать метод `MatrixUtil.concurrentMultiply`, позволяющий многопоточно перемножать квадратные матрицы N*N.
+- Количество дочерних потоков ограничено `MainMatrix.THREAD_NUMBER`.
+- Добиться того, чтобы на матрице 1000*1000 многопоточная реализация была быстрее однопоточной
+
+-----
+##  Подсказки по HW1
+- не делайте 1000 000 тасок, лучше их сделать крупнее
+- у меня разница между 4 и 1000 тасками по времени незаметна, поэтому делайте просто и не делайте сложно
+- наконец: можно не считать значение элемента результирующей матрицы C за раз, а накапливать (`concurrentMultiply3`). Мои результаты:
+```
+Benchmark (matrixSize) Mode Cnt Score Error Units
+MatrixBenchmark.singleThreadMultiplyOpt 1000 ss 100 837,867 ± 25,530 ms/op
+MatrixBenchmark.concurrentMultiply2 1000 ss 100 394,294 ± 21,657 ms/op
+MatrixBenchmark.concurrentMultiply3 1000 ss 100 186,827 ± 11,882 ms/op
+```
+-----
+# Программа проекта
+
+## Занятие 2
+- Разбор ДЗ (многопоточная реализация умножения матриц)
+- Java Microbenchmark JMH (от Алексея Шипилева)
+- Обзор Guava
+- Формат XML. Создание схемы XSD.
+- Работа с XML в Java
+ - JAXB, JAXP
+ - StAX
+ - XPath
+ - XSLT
+
+## Занятие 3
+- Разбор ДЗ (работа с XML)
+- Обзор StreamEx (от Тагира Валеева)
+- Монады. flatMap
+- SOA и Микросервисы
+- Многомодульный Maven проект
+
+## Занятие 4
+- Разбор ДЗ (реализация структуры проекта, загрузка и разбор xml)
+- Thymleaf
+- Maven. Поиск и разрешение конфликтов зависимостей
+- Логирование
+- Выбор lightweight JDBC helper library. JDBI
+- Tomcat Class Loader. Memory Leaks
+
+## Занятие 5
+- Разбор ДЗ (реализуем модули persist, export и web)
+- Конфигурирование приложения (Typesafe config)
+- Lombook
+
+## Занятие 6
+- Разбор ДЗ (доработка модели и модуля export)
+- Миграция DB
+- Веб-сервисы (REST/SOAP)
+ - Java реализации SOAP
+ - Имплементируем Mail Service
+
+## Занятие 7
+- Разбор ДЗ (реализация MailSender, сохранение результатов отправки)
+- Стили WSDL. Кастомизация WSDL
+- Публикация кастомизированного WSDL. Автогенерация.
+- Деплой в Tomcat
+- Создание клиента почтового сервиса
+
+## Занятие 8
+- Разбор ДЗ (отправка почты через Executor из модуля web)
+- Доступ к переменным maven в приложении
+- SOAP Exception. Выделение общей части схемы
+- Передача двоичных данных в веб-сервисах. MTOM
+
+## Занятие 9
+- Разбор ДЗ (реализация загрузки и отправки вложений по почте)
+- JAX-WS Message Context
+- JAX-WS Handlers (логирование SOAP)
+
+## Занятие 10
+- Разбор ДЗ (реализация авторизации и статистики)
+- JavaEE
+ - CDI
+ - JAX-RS. Интеграция с Jersey
+ - EJB
+ - JMS
+
+## Занятие 11 (предварительно)
+- Асинхронные сервлеты 3.x в Tomcat
+- Maven Groovy cкрптинг (groovy-maven-plugin)
+- AKKA
+- Redis
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 000000000..39e811e08
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,44 @@
+
+ 4.0.0
+
+ ru.javaops
+ masterjava
+ jar
+
+ 1.0-SNAPSHOT
+
+ Master Java
+ https://github.com/JavaOPs/masterjava
+
+
+ 1.8
+ UTF-8
+ UTF-8
+
+
+
+ masterjava
+ install
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.1
+
+ ${java.version}
+ ${java.version}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/java/ru/javaops/masterjava/Main.java b/src/main/java/ru/javaops/masterjava/Main.java
new file mode 100644
index 000000000..a849258c4
--- /dev/null
+++ b/src/main/java/ru/javaops/masterjava/Main.java
@@ -0,0 +1,14 @@
+package ru.javaops.masterjava;
+
+/**
+ * User: gkislin
+ * Date: 05.08.2015
+ *
+ * @link http://caloriesmng.herokuapp.com/
+ * @link https://github.com/JavaOPs/topjava
+ */
+public class Main {
+ public static void main(String[] args) {
+ System.out.format("Hello MasterJava!");
+ }
+}
diff --git a/src/main/java/ru/javaops/masterjava/matrix/MainMatrix.java b/src/main/java/ru/javaops/masterjava/matrix/MainMatrix.java
new file mode 100644
index 000000000..ec1c8a691
--- /dev/null
+++ b/src/main/java/ru/javaops/masterjava/matrix/MainMatrix.java
@@ -0,0 +1,52 @@
+package ru.javaops.masterjava.matrix;
+
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+/**
+ * gkislin
+ * 03.07.2016
+ */
+public class MainMatrix {
+ private static final int MATRIX_SIZE = 1000;
+ private static final int THREAD_NUMBER = 10;
+
+ private final static ExecutorService executor = Executors.newFixedThreadPool(MainMatrix.THREAD_NUMBER);
+
+ public static void main(String[] args) throws ExecutionException, InterruptedException {
+ final int[][] matrixA = MatrixUtil.create(MATRIX_SIZE);
+ final int[][] matrixB = MatrixUtil.create(MATRIX_SIZE);
+
+ double singleThreadSum = 0.;
+ double concurrentThreadSum = 0.;
+ int count = 1;
+ while (count < 6) {
+ System.out.println("Pass " + count);
+ long start = System.currentTimeMillis();
+ final int[][] matrixC = MatrixUtil.singleThreadMultiply(matrixA, matrixB);
+ double duration = (System.currentTimeMillis() - start) / 1000.;
+ out("Single thread time, sec: %.3f", duration);
+ singleThreadSum += duration;
+
+ start = System.currentTimeMillis();
+ final int[][] concurrentMatrixC = MatrixUtil.concurrentMultiply(matrixA, matrixB, executor);
+ duration = (System.currentTimeMillis() - start) / 1000.;
+ out("Concurrent thread time, sec: %.3f", duration);
+ concurrentThreadSum += duration;
+
+ if (!MatrixUtil.compare(matrixC, concurrentMatrixC)) {
+ System.err.println("Comparison failed");
+ break;
+ }
+ count++;
+ }
+ executor.shutdown();
+ out("\nAverage single thread time, sec: %.3f", singleThreadSum / 5.);
+ out("Average concurrent thread time, sec: %.3f", concurrentThreadSum / 5.);
+ }
+
+ private static void out(String format, double ms) {
+ System.out.println(String.format(format, ms));
+ }
+}
diff --git a/src/main/java/ru/javaops/masterjava/matrix/MatrixUtil.java b/src/main/java/ru/javaops/masterjava/matrix/MatrixUtil.java
new file mode 100644
index 000000000..80a344ac2
--- /dev/null
+++ b/src/main/java/ru/javaops/masterjava/matrix/MatrixUtil.java
@@ -0,0 +1,61 @@
+package ru.javaops.masterjava.matrix;
+
+import java.util.Random;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+
+/**
+ * gkislin
+ * 03.07.2016
+ */
+public class MatrixUtil {
+
+ // TODO implement parallel multiplication matrixA*matrixB
+ public static int[][] concurrentMultiply(int[][] matrixA, int[][] matrixB, ExecutorService executor) throws InterruptedException, ExecutionException {
+ final int matrixSize = matrixA.length;
+ final int[][] matrixC = new int[matrixSize][matrixSize];
+
+ return matrixC;
+ }
+
+ // TODO optimize by https://habrahabr.ru/post/114797/
+ public static int[][] singleThreadMultiply(int[][] matrixA, int[][] matrixB) {
+ final int matrixSize = matrixA.length;
+ final int[][] matrixC = new int[matrixSize][matrixSize];
+
+ for (int i = 0; i < matrixSize; i++) {
+ for (int j = 0; j < matrixSize; j++) {
+ int sum = 0;
+ for (int k = 0; k < matrixSize; k++) {
+ sum += matrixA[i][k] * matrixB[k][j];
+ }
+ matrixC[i][j] = sum;
+ }
+ }
+ return matrixC;
+ }
+
+ public static int[][] create(int size) {
+ int[][] matrix = new int[size][size];
+ Random rn = new Random();
+
+ for (int i = 0; i < size; i++) {
+ for (int j = 0; j < size; j++) {
+ matrix[i][j] = rn.nextInt(10);
+ }
+ }
+ return matrix;
+ }
+
+ public static boolean compare(int[][] matrixA, int[][] matrixB) {
+ final int matrixSize = matrixA.length;
+ for (int i = 0; i < matrixSize; i++) {
+ for (int j = 0; j < matrixSize; j++) {
+ if (matrixA[i][j] != matrixB[i][j]) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+}
diff --git a/src/main/java/ru/javaops/masterjava/service/MailService.java b/src/main/java/ru/javaops/masterjava/service/MailService.java
new file mode 100644
index 000000000..2b6aeb294
--- /dev/null
+++ b/src/main/java/ru/javaops/masterjava/service/MailService.java
@@ -0,0 +1,75 @@
+package ru.javaops.masterjava.service;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+
+public class MailService {
+ private static final String OK = "OK";
+
+ private static final String INTERRUPTED_BY_FAULTS_NUMBER = "+++ Interrupted by faults number";
+ private static final String INTERRUPTED_BY_TIMEOUT = "+++ Interrupted by timeout";
+ private static final String INTERRUPTED_EXCEPTION = "+++ InterruptedException";
+
+ public GroupResult sendToList(final String template, final Set emails) throws Exception {
+ return new GroupResult(0, Collections.emptyList(), null);
+ }
+
+
+ // dummy realization
+ public MailResult sendToUser(String template, String email) throws Exception {
+ try {
+ Thread.sleep(500); //delay
+ } catch (InterruptedException e) {
+ // log cancel;
+ return null;
+ }
+ return Math.random() < 0.7 ? MailResult.ok(email) : MailResult.error(email, "Error");
+ }
+
+ public static class MailResult {
+ private final String email;
+ private final String result;
+
+ private static MailResult ok(String email) {
+ return new MailResult(email, OK);
+ }
+
+ private static MailResult error(String email, String error) {
+ return new MailResult(email, error);
+ }
+
+ public boolean isOk() {
+ return OK.equals(result);
+ }
+
+ private MailResult(String email, String cause) {
+ this.email = email;
+ this.result = cause;
+ }
+
+ @Override
+ public String toString() {
+ return '(' + email + ',' + result + ')';
+ }
+ }
+
+ public static class GroupResult {
+ private final int success; // number of successfully sent email
+ private final List failed; // failed emails with causes
+ private final String failedCause; // global fail cause
+
+ public GroupResult(int success, List failed, String failedCause) {
+ this.success = success;
+ this.failed = failed;
+ this.failedCause = failedCause;
+ }
+
+ @Override
+ public String toString() {
+ return "Success: " + success + '\n' +
+ "Failed: " + failed.toString() + '\n' +
+ (failedCause == null ? "" : "Failed cause" + failedCause);
+ }
+ }
+}
\ No newline at end of file