package com.packtpub.hibernatesearch.domain.test;

import java.util.Scanner;

import org.eclipse.jetty.annotations.AnnotationConfiguration;
import org.eclipse.jetty.plus.webapp.EnvConfiguration;
import org.eclipse.jetty.plus.webapp.PlusConfiguration;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.webapp.Configuration;
import org.eclipse.jetty.webapp.FragmentConfiguration;
import org.eclipse.jetty.webapp.JettyWebXmlConfiguration;
import org.eclipse.jetty.webapp.MetaInfConfiguration;
import org.eclipse.jetty.webapp.TagLibConfiguration;
import org.eclipse.jetty.webapp.WebAppContext;
import org.eclipse.jetty.webapp.WebInfConfiguration;
import org.eclipse.jetty.webapp.WebXmlConfiguration;
import org.junit.Test;

/**
 * W tej klasie inicjalizujemy dwuwęzłowy klaster oparty o serwery Jetty. Każdy z nich ładuje zawartość projektu. 
 * Jest alternatywą dla jednowęzłowego pluginu Jetty używanego w poprzednich rozdziałach.
 * 
 * Metoda "testCluster()" jest testem JUnit 4. W związku z tym Maven wywoła ją automatycznie po wywołaniu komendy 
 * "clean compile war:exploded test".
 * 
 * Węzły nadrzędne i podrzędne używają osobnych deskryptorów ("web.xml" and "web-slave.xml", respectively).
 * Każdy z deskryptorów deklaruje listener kontekstu servletu odpowiedniego typu (tj. MasterNodeInitializer lub 
 * SlaveNodeInitializer)... który buduje fabrykę sesji Hibernate używając własnego pliku konfiguracyjnego
 * (tj. "hibernate.cfg.xml" lub "hibernate-slave.cfg.xml").
 * 
 * W zależności od frameworka, którego używasz (tj. Spring, JEE, itp), możesz użyć rozmaitych technik wstrzykiwania zależności
 * lub innych technik do konfigurowania węzłów.  Ujmując w skrócie  "hibernate.cfg.xml" (lub "persistence.xml" dla JPA) 
 * ustawia ważne parametry istotne dla Hibernate Search.
 */
public class ClusterTest {

	@Test
	public void testCluster() throws Exception {
		
		String projectBaseDirectory = System.getProperty("user.dir");
		
		//
		// Utwórz węzeł nadrzędny
		//
		Server masterServer = new Server(8080);

		WebAppContext masterContext = new WebAppContext();
		masterContext.setDescriptor(projectBaseDirectory + "/target/bazar/WEB-INF/web.xml");
		masterContext.setResourceBase(projectBaseDirectory + "/target/bazar");
		masterContext.setContextPath("/");
		masterContext.setConfigurations(
				new Configuration[] { 
						new WebInfConfiguration(),
						new WebXmlConfiguration(),
						new MetaInfConfiguration(), 
						new FragmentConfiguration(),
						new EnvConfiguration(),
						new PlusConfiguration(),
						new AnnotationConfiguration(), 
						new JettyWebXmlConfiguration(),
						new TagLibConfiguration()
				}
		);
		masterContext.setParentLoaderPriority(true);

		masterServer.setHandler(masterContext);
		masterServer.start();
		//masterServer.join();

		//
		// Utwórz węzeł podrzędny
		//
		Server slaveServer = new Server(8181);

		WebAppContext slaveContext = new WebAppContext();
		slaveContext.setDescriptor(projectBaseDirectory + "/target/bazar/WEB-INF/web-slave.xml");
		slaveContext.setResourceBase(projectBaseDirectory + "/target/bazar");
		slaveContext.setContextPath("/");
		slaveContext.setConfigurations(
				new Configuration[] { 
						new WebInfConfiguration(),
						new WebXmlConfiguration(),
						new MetaInfConfiguration(), 
						new FragmentConfiguration(),
						new EnvConfiguration(),
						new PlusConfiguration(),
						new AnnotationConfiguration(), 
						new JettyWebXmlConfiguration(),
						new TagLibConfiguration()
				}
		);
		slaveContext.setParentLoaderPriority(true);

		slaveServer.setHandler(slaveContext);
		slaveServer.start();
		//slaveServer.join();
		
		// Spróbuj zamknąć serwer Jetty.  Ta metode nie zadziała w środowisku Eclipse ani innym w którym nie można wczytać,  
		// parametrów ze standardowego wejścia.  Możesz również zamknąć proces mavena aby zakończyć pracę serwera Jetty. 
		
		System.out.println("NACIŚNIJ <ENTER> BY ZATRZYMAĆ SERWERY (lub ubij proces mavena)...");
		Scanner scanner = new Scanner(System.in);
		String line = scanner.nextLine();
		System.out.println(line);
		scanner.close();
		masterServer.stop();
		slaveServer.stop();
		System.out.println("Serwery zatrzymane");
		
	}

}
