protected void init()

in openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java [209:377]


	protected void init() {
		setWicketApplicationName(super.getName());
		getSecuritySettings().setAuthenticationStrategy(new OmAuthenticationStrategy(rememberMeKey, rememberMeSalt));
		getApplicationSettings().setAccessDeniedPage(AccessDeniedPage.class);
		getApplicationSettings().setInternalErrorPage(InternalErrorPage.class);
		getExceptionSettings().setUnexpectedExceptionDisplay(ExceptionSettings.SHOW_INTERNAL_ERROR_PAGE);
		getComponentInstantiationListeners().add(new SpringComponentInjector(this, ctx, true));

		Config cfg = new XmlConfigBuilder().build();
		cfg.setClassLoader(getClass().getClassLoader());
		hazelcast = Hazelcast.getOrCreateHazelcastInstance(cfg);
		serverId = hazelcast.getName();
		hazelcast.getCluster().getMembers().forEach(m -> cm.serverAdded(m.getAttribute(NAME_ATTR_KEY), m.getAttribute(SERVER_URL_ATTR_KEY)));
		hazelWsTopic = hazelcast.getTopic("default");
		hazelWsTopic.addMessageListener(msg -> {
			String mServerId = msg.getPublishingMember().getAttribute(NAME_ATTR_KEY);
			if (mServerId.equals(serverId)) {
				return;
			}
			IClusterWsMessage wsMsg = msg.getMessageObject();
			if (WbWebSocketHelper.send(wsMsg)) {
				return;
			}
			if (ChatWebSocketHelper.send(msg.getMessageObject())) {
				return;
			}
			WebSocketHelper.send(msg.getMessageObject());
		});
		hazelcast.getCluster().addMembershipListener(new MembershipListener() {
			@Override
			public void memberRemoved(MembershipEvent evt) {
				//server down, need to remove all online clients, process persistent addresses
				String downId = evt.getMember().getAttribute(NAME_ATTR_KEY);
				cm.serverRemoved(downId);
				updateJpaAddresses();
			}

			@Override
			public void memberAdded(MembershipEvent evt) {
				//no-op
				//server added, need to process persistent addresses
				updateJpaAddresses();
				//check for duplicate instance-names
				Set<String> names = new HashSet<>();
				for (Member m : evt.getMembers()) {
					if (evt.getMember().getUuid().equals(m.getUuid())) {
						continue;
					}
					String duplicateId = m.getAttribute(NAME_ATTR_KEY);
					names.add(duplicateId);
				}
				String newServerId = evt.getMember().getAttribute(NAME_ATTR_KEY);
				log.warn("Name added: {}", newServerId);
				cm.serverAdded(newServerId, evt.getMember().getAttribute(SERVER_URL_ATTR_KEY));
				if (names.contains(newServerId)) {
					log.warn("Duplicate cluster instance with name {} found {}", newServerId, evt.getMember());
				}
			}
		});
		setPageManagerProvider(new DefaultPageManagerProvider(this) {
			@Override
			protected IPageStore newAsynchronousStore(IPageStore pageStore) {
				return new SerializingPageStore(
						new HazelcastDataStore(getName(), hazelcast)
						, getFrameworkSettings().getSerializer());
			}
		});
		//Add custom resource loader at the beginning, so it will be checked first in the
		//chain of Resource Loaders, if not found it will search in Wicket's internal
		//Resource Loader for a the property key
		getResourceSettings().getStringResourceLoaders().add(0, new LabelResourceLoader());
		getRequestCycleListeners().add(new WebSocketAwareResourceIsolationRequestCycleListener() {
			@Override
			public void onBeginRequest(RequestCycle cycle) {
				String wsUrl = getWsUrl(cycle.getRequest().getUrl());
				if (wsUrl != null && !wsUrls.contains(wsUrl)) {
					wsUrls.add(wsUrl);
					cfgDao.updateCsp();
				}
			}

			@Override
			public void onEndRequest(RequestCycle cycle) {
				Response resp = cycle.getResponse();
				if (resp instanceof WebResponse wresp && wresp.isHeaderSupported()) {
					wresp.setHeader("X-XSS-Protection", "1; mode=block");
					wresp.setHeader("Strict-Transport-Security", "max-age=31536000; includeSubDomains; preload");
					wresp.setHeader("X-Content-Type-Options", "nosniff");
				}
			}
		});
		final WebSocketContainer sc = (WebSocketContainer)getServletContext().getAttribute(SERVER_CONTAINER_SERVLET_CONTEXT_ATTRIBUTE);
		if (sc != null) {
			sc.setDefaultMaxSessionIdleTimeout(60 * 1000L); // should be enough, should it be configurable?
		}
		getHeaderResponseDecorators().add(FilteringHeaderResponse::new);
		super.init();
		final IBootstrapSettings settings = new BootstrapSettings().setAutoAppendResources(false);
		Bootstrap.builder().withBootstrapSettings(settings).install(this);
		WysiwygLibrarySettings.get().setBootstrapCssReference(null);
		WysiwygLibrarySettings.get().setBootstrapDropDownJavaScriptReference(null);
		WysiwygLibrarySettings.get().setPrettifyJavaScriptReference(null);

		// register some widgets
		final DashboardContext dashboardContext = getDashboardContext();
		dashboardContext.setDashboardPersister(new UserDashboardPersister());
		WidgetRegistry widgetRegistry = dashboardContext.getWidgetRegistry();
		widgetRegistry.registerWidget(new MyRoomsWidgetDescriptor());
		widgetRegistry.registerWidget(new RecentRoomsWidgetDescriptor());
		widgetRegistry.registerWidget(new WelcomeWidgetDescriptor());
		widgetRegistry.registerWidget(new StartWidgetDescriptor());
		widgetRegistry.registerWidget(new RssWidgetDescriptor());
		widgetRegistry.registerWidget(new AdminWidgetDescriptor());
		DashboardSettings dashboardSettings = DashboardSettings.get();
		dashboardSettings.setIncludeJQueryUI(false);

		getRootRequestMapperAsCompound().add(new NoVersionMapper(getHomePage()));
		getRootRequestMapperAsCompound().add(new NoVersionMapper(NOTINIT_MAPPING, NotInitedPage.class));
		getRootRequestMapperAsCompound().add(new NoVersionMapper("denied", AccessDeniedPage.class));
		getRootRequestMapperAsCompound().add(new NoVersionMapper(HASH_MAPPING, HashPage.class));
		getRootRequestMapperAsCompound().add(new NoVersionMapper(SIGNIN_MAPPING, getSignInPageClass()));
		getRootRequestMapperAsCompound().add(new NoVersionMapper("oauth/${oauthid}", getSignInPageClass()));
		getRootRequestMapperAsCompound().add(new NoVersionMapper("privacy", PrivacyPage.class));
		mountPage("install", InstallWizardPage.class);
		mountPage("activate", ActivatePage.class);
		mountPage("reset", ResetPage.class);
		mountPage("error", InternalErrorPage.class);
		mountResource("/recordings/mp4/${id}", new Mp4RecordingResourceReference());
		mountResource("/recordings/png/${id}", new PngRecordingResourceReference()); //should be in sync with VideoPlayer
		mountResource("/room/file/${id}", new RoomResourceReference());
		mountResource("/room/preview/${id}", new RoomPreviewResourceReference());
		mountResource("/room/file/upload", new RoomFileUploadResourceReference());
		mountResource("/admin/backup/upload", new BackupUploadResourceReference());
		mountResource("/profile/${id}", new ProfileImageResourceReference());
		mountResource("/group/${id}", new GroupLogoResourceReference());
		mountResource("/group/customcss/${id}", new GroupCustomCssResourceReference());
		mountResource("/ping", new PingResourceReference());

		log.debug("Application::init");
		try {
			if (OmFileHelper.getOmHome() == null) {
				OmFileHelper.setOmHome(new File(getServletContext().getRealPath("/")));
			}
			LabelDao.initLanguageMap();

			log.debug("webAppPath : {}", OmFileHelper.getOmHome());

			// Init all global config properties
			cfgDao.reinit();
			wbManager.init();
			cm.init();

			// Init properties
			updateJpaAddresses();
			setExtProcessTtl(cfgDao.getInt(CONFIG_EXT_PROCESS_TTL, getExtProcessTtl()));
			OmVersion.logOMStarted();
			recordingDao.resetProcessingStatus(); //we are starting so all processing recordings are now errors
			userManager.initHttpClient();
			setInitComplete(true);
			CompletableFuture.runAsync(() -> {
				ThreadContext.setApplication(Application.this);
				ApplicationHelper.ensureRequestCycle(Application.this);
				sipManager.setUserPicture(u -> ProfileImageResourceReference.getUrl(RequestCycle.get(), u));
			});
		} catch (Exception err) {
			log.error("[appStart]", err);
		}
		warmup();
	}