You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openmeetings.apache.org by so...@apache.org on 2021/03/16 15:18:02 UTC

[openmeetings] branch injected-fields created (now 5fe24e4)

This is an automated email from the ASF dual-hosted git repository.

solomax pushed a change to branch injected-fields
in repository https://gitbox.apache.org/repos/asf/openmeetings.git.


      at 5fe24e4  [OPENMEETINGS-2588] non-beans are injected, tests are green

This branch includes the following new commits:

     new 5fe24e4  [OPENMEETINGS-2588] non-beans are injected, tests are green

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



[openmeetings] 01/01: [OPENMEETINGS-2588] non-beans are injected, tests are green

Posted by so...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

solomax pushed a commit to branch injected-fields
in repository https://gitbox.apache.org/repos/asf/openmeetings.git

commit 5fe24e4ea4045af308f3668dc52096b68e6158cc
Author: Maxim Solodovnik <so...@gmail.com>
AuthorDate: Tue Mar 16 22:17:42 2021 +0700

    [OPENMEETINGS-2588] non-beans are injected, tests are green
---
 openmeetings-core/pom.xml                          |  5 ++
 .../org/apache/openmeetings/core/remote/KRoom.java | 59 ++++++++++++----------
 .../apache/openmeetings/core/remote/KStream.java   | 33 ++++++++----
 .../openmeetings/core/remote/KTestStream.java      | 16 ++++--
 .../openmeetings/core/remote/KurentoHandler.java   | 24 +--------
 .../openmeetings/core/remote/StreamProcessor.java  |  2 +-
 .../core/remote/StreamProcessorActions.java        |  2 +-
 .../core/remote/TestStreamProcessor.java           |  2 +-
 .../openmeetings/core/remote/BaseMockedTest.java   | 50 ++++++++++++++++++
 9 files changed, 125 insertions(+), 68 deletions(-)

diff --git a/openmeetings-core/pom.xml b/openmeetings-core/pom.xml
index dfb1100..7b61a40 100644
--- a/openmeetings-core/pom.xml
+++ b/openmeetings-core/pom.xml
@@ -77,6 +77,11 @@
 			<version>${wicket.version}</version>
 		</dependency>
 		<dependency>
+			<groupId>org.apache.wicket</groupId>
+			<artifactId>wicket-ioc</artifactId>
+			<version>${wicket.version}</version>
+		</dependency>
+		<dependency>
 			<groupId>org.apache.directory.api</groupId>
 			<artifactId>api-all</artifactId>
 			<version>${api-all.version}</version>
diff --git a/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/KRoom.java b/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/KRoom.java
index 3de644f..04c9a08 100644
--- a/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/KRoom.java
+++ b/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/KRoom.java
@@ -27,10 +27,12 @@ import java.util.Date;
 import java.util.Optional;
 import java.util.concurrent.atomic.AtomicBoolean;
 
+import javax.inject.Inject;
+
 import org.apache.commons.lang3.time.FastDateFormat;
 import org.apache.openmeetings.IApplication;
 import org.apache.openmeetings.core.util.WebSocketHelper;
-import org.apache.openmeetings.db.dao.record.RecordingChunkDao;
+import org.apache.openmeetings.db.dao.record.RecordingDao;
 import org.apache.openmeetings.db.entity.basic.Client;
 import org.apache.openmeetings.db.entity.basic.Client.Activity;
 import org.apache.openmeetings.db.entity.basic.Client.StreamDesc;
@@ -43,6 +45,7 @@ import org.apache.openmeetings.db.manager.IClientManager;
 import org.apache.openmeetings.db.util.FormatHelper;
 import org.apache.openmeetings.db.util.ws.RoomMessage;
 import org.apache.openmeetings.db.util.ws.TextRoomMessage;
+import org.apache.wicket.injection.Injector;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -55,8 +58,15 @@ import com.github.openjson.JSONObject;
 public class KRoom {
 	private static final Logger log = LoggerFactory.getLogger(KRoom.class);
 
-	private final StreamProcessor processor;
-	private final RecordingChunkDao chunkDao;
+	@Inject
+	private KurentoHandler kHandler;
+	@Inject
+	private StreamProcessor processor;
+	@Inject
+	private RecordingDao recDao;
+	@Inject
+	private IClientManager cm;
+
 	private final Room room;
 	private final AtomicBoolean recordingStarted = new AtomicBoolean(false);
 	private final AtomicBoolean sharingStarted = new AtomicBoolean(false);
@@ -65,10 +75,9 @@ public class KRoom {
 	private JSONObject recordingUser = new JSONObject();
 	private JSONObject sharingUser = new JSONObject();
 
-	public KRoom(KurentoHandler handler, Room r) {
-		this.processor = handler.getStreamProcessor();
-		this.chunkDao = handler.getChunkDao();
+	public KRoom(Room r) {
 		this.room = r;
+		Injector.get().inject(this);
 		log.info("ROOM {} has been created", room.getId());
 	}
 
@@ -80,13 +89,9 @@ public class KRoom {
 		return recordingId;
 	}
 
-	public RecordingChunkDao getChunkDao() {
-		return chunkDao;
-	}
-
-	public KStream join(final StreamDesc sd, KurentoHandler kHandler) {
+	public KStream join(final StreamDesc sd) {
 		log.info("ROOM {}: join client {}, stream: {}", room.getId(), sd.getClient(), sd.getUid());
-		final KStream stream = new KStream(sd, this, kHandler);
+		final KStream stream = new KStream(sd, this);
 		processor.addStream(stream);
 		return stream;
 	}
@@ -144,11 +149,11 @@ public class KRoom {
 			Optional<StreamDesc> osd = c.getScreenStream();
 			if (osd.isPresent()) {
 				osd.get().addActivity(Activity.RECORD);
-				processor.getClientManager().update(c);
+				cm.update(c);
 				rec.setWidth(osd.get().getWidth());
 				rec.setHeight(osd.get().getHeight());
 			}
-			rec = processor.getRecordingDao().update(rec);
+			rec = recDao.update(rec);
 			// Receive recordingId
 			recordingId = rec.getId();
 			processor.getByRoom(room.getId()).forEach(KStream::startRecord);
@@ -163,9 +168,9 @@ public class KRoom {
 		if (recordingStarted.compareAndSet(true, false)) {
 			log.debug("##REC:: recording in room {} is stopping {} ::", room.getId(), recordingId);
 			processor.getByRoom(room.getId()).forEach(KStream::stopRecord);
-			Recording rec = processor.getRecordingDao().get(recordingId);
+			Recording rec = recDao.get(recordingId);
 			rec.setRecordEnd(new Date());
-			rec = processor.getRecordingDao().update(rec);
+			rec = recDao.update(rec);
 			recordingUser = new JSONObject();
 			recordingId = null;
 
@@ -178,8 +183,8 @@ public class KRoom {
 				Optional<StreamDesc> osd = c.getScreenStream();
 				if (osd.isPresent()) {
 					osd.get().removeActivity(Activity.RECORD);
-					processor.getClientManager().update(c);
-					processor.getHandler().sendShareUpdated(osd.get());
+					cm.update(c);
+					kHandler.sendShareUpdated(osd.get());
 				}
 			}
 			// Send notification to all users that the recording has been started
@@ -203,29 +208,28 @@ public class KRoom {
 		return new JSONObject(sharingUser.toString());
 	}
 
-	public void startSharing(StreamProcessor processor, IClientManager cm, Client c, Optional<StreamDesc> osd, JSONObject msg, Activity a) {
+	public void startSharing(Client c, Optional<StreamDesc> osd, JSONObject msg, Activity a) {
 		StreamDesc sd;
-		KurentoHandler h = processor.getHandler();
 		if (sharingStarted.compareAndSet(false, true)) {
 			sharingUser.put("sid", c.getSid());
 			sd = c.addStream(StreamType.SCREEN, a);
 			cm.update(c);
 			log.debug("Stream.UID {}: sharing has been started, activity: {}", sd.getUid(), a);
-			h.sendClient(sd.getSid(), newKurentoMsg()
+			kHandler.sendClient(sd.getSid(), newKurentoMsg()
 					.put("id", "broadcast")
 					.put("stream", sd.toJson()
 							.put("shareType", msg.getString("shareType"))
 							.put("fps", msg.getString("fps")))
-					.put(PARAM_ICE, h.getTurnServers(c)));
+					.put(PARAM_ICE, kHandler.getTurnServers(c)));
 		} else if (osd.isPresent() && !osd.get().hasActivity(a)) {
 			sd = osd.get();
 			sd.addActivity(a);
 			cm.update(c);
-			h.sendShareUpdated(sd);
+			kHandler.sendShareUpdated(sd);
 			WebSocketHelper.sendRoom(new TextRoomMessage(c.getRoomId(), c, RoomMessage.Type.RIGHT_UPDATED, c.getUid()));
 			WebSocketHelper.sendRoomOthers(room.getId(), c.getUid(), newKurentoMsg()
 					.put("id", "newStream")
-					.put(PARAM_ICE, processor.getHandler().getTurnServers(c))
+					.put(PARAM_ICE, kHandler.getTurnServers(c))
 					.put("stream", sd.toJson()));
 		}
 	}
@@ -245,17 +249,16 @@ public class KRoom {
 		if (count != sipCount) {
 			processor.getByRoom(room.getId()).forEach(stream -> stream.addSipProcessor(count));
 			if (sipCount == 0) {
-				processor.getClientManager()
-					.streamByRoom(room.getId())
+				cm.streamByRoom(room.getId())
 					.filter(Client::isSip)
 					.findAny()
 					.ifPresent(c -> {
 						StreamDesc sd = c.addStream(StreamType.WEBCAM, Activity.AUDIO);
 						sd.setWidth(120).setHeight(90);
 						c.restoreActivities(sd);
-						KStream stream = join(sd, processor.getHandler());
+						KStream stream = join(sd);
 						stream.startBroadcast(sd, "", () -> {});
-						processor.getClientManager().update(c);
+						cm.update(c);
 					});
 			}
 			sipCount = count;
diff --git a/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/KStream.java b/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/KStream.java
index 56f2a58..f461c6d 100644
--- a/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/KStream.java
+++ b/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/KStream.java
@@ -43,9 +43,13 @@ import java.util.concurrent.ConcurrentLinkedQueue;
 import java.util.concurrent.TimeUnit;
 import java.util.function.Consumer;
 
+import javax.inject.Inject;
+
 import org.apache.openmeetings.core.sip.ISipCallbacks;
+import org.apache.openmeetings.core.sip.SipManager;
 import org.apache.openmeetings.core.sip.SipStackProcessor;
 import org.apache.openmeetings.core.util.WebSocketHelper;
+import org.apache.openmeetings.db.dao.record.RecordingChunkDao;
 import org.apache.openmeetings.db.entity.basic.Client;
 import org.apache.openmeetings.db.entity.basic.Client.Activity;
 import org.apache.openmeetings.db.entity.basic.Client.StreamDesc;
@@ -54,6 +58,7 @@ import org.apache.openmeetings.db.entity.record.RecordingChunk.Type;
 import org.apache.openmeetings.db.util.ws.RoomMessage;
 import org.apache.openmeetings.db.util.ws.TextRoomMessage;
 import org.apache.openmeetings.util.OmFileHelper;
+import org.apache.wicket.injection.Injector;
 import org.kurento.client.BaseRtpEndpoint;
 import org.kurento.client.Continuation;
 import org.kurento.client.IceCandidate;
@@ -75,7 +80,15 @@ import com.github.openjson.JSONObject;
 public class KStream extends AbstractStream implements ISipCallbacks {
 	private static final Logger log = LoggerFactory.getLogger(KStream.class);
 
-	private final KurentoHandler kHandler;
+	@Inject
+	private KurentoHandler kHandler;
+	@Inject
+	private StreamProcessor processor;
+	@Inject
+	private RecordingChunkDao chunkDao;
+	@Inject
+	private SipManager sipManager;
+
 	private final KRoom kRoom;
 	private final Date connectedSince;
 	private final StreamType streamType;
@@ -96,12 +109,12 @@ public class KStream extends AbstractStream implements ISipCallbacks {
 	private boolean hasScreen;
 	private boolean sipClient;
 
-	public KStream(final StreamDesc sd, KRoom kRoom, KurentoHandler kHandler) {
+	public KStream(final StreamDesc sd, KRoom kRoom) {
 		super(sd.getSid(), sd.getUid());
 		this.kRoom = kRoom;
 		streamType = sd.getType();
 		this.connectedSince = new Date();
-		this.kHandler = kHandler;
+		Injector.get().inject(this);
 		//TODO Min/MaxVideoSendBandwidth
 		//TODO Min/Max Audio/Video RecvBandwidth
 	}
@@ -189,7 +202,7 @@ public class KStream extends AbstractStream implements ISipCallbacks {
 				flowoutFuture = Optional.of(new CompletableFuture<>().completeAsync(() -> {
 					log.warn("KStream will be dropped {}, sid {}, uid {}", sd, sid, uid);
 					if (StreamType.SCREEN == streamType) {
-						kHandler.getStreamProcessor().doStopSharing(sid, uid);
+						processor.doStopSharing(sid, uid);
 					}
 					stopBroadcast();
 					return null;
@@ -275,7 +288,7 @@ public class KStream extends AbstractStream implements ISipCallbacks {
 		listeners.put(uid, listener);
 
 		log.debug("PARTICIPANT {}: obtained endpoint for {}", uid, this.uid);
-		Client cur = kHandler.getStreamProcessor().getBySid(this.sid);
+		Client cur = processor.getBySid(this.sid);
 		if (cur == null) {
 			log.warn("Client for endpoint dooesn't exists");
 		} else {
@@ -338,9 +351,9 @@ public class KStream extends AbstractStream implements ISipCallbacks {
 		recorder = createRecorderEndpoint(pipeline, getRecUri(getRecordingChunk(getRoomId(), chunkUid)), profile);
 		setTags(recorder, uid);
 
-		recorder.addRecordingListener(evt -> chunkId = kRoom.getChunkDao().start(kRoom.getRecordingId(), type, chunkUid, sid));
+		recorder.addRecordingListener(evt -> chunkId = chunkDao.start(kRoom.getRecordingId(), type, chunkUid, sid));
 		recorder.addStoppedListener(evt -> {
-			kRoom.getChunkDao().stop(chunkId);
+			chunkDao.stop(chunkId);
 			chunkId = null;
 		});
 		switch (profile) {
@@ -459,7 +472,7 @@ public class KStream extends AbstractStream implements ISipCallbacks {
 
 	private void doRemove(boolean remove) {
 		if (remove) {
-			kHandler.getStreamProcessor().release(this, false);
+			processor.release(this, false);
 		}
 	}
 
@@ -606,7 +619,7 @@ public class KStream extends AbstractStream implements ISipCallbacks {
 		if (count > 0) {
 			if (sipProcessor.isEmpty()) {
 				try {
-					sipProcessor = kHandler.getSipManager().createSipStackProcessor(
+					sipProcessor = sipManager.createSipStackProcessor(
 							randomUUID().toString()
 							, kRoom.getRoom()
 							, this);
@@ -644,7 +657,7 @@ public class KStream extends AbstractStream implements ISipCallbacks {
 		answerConsumer.accept(answer);
 		log.debug(answer);
 		if (sipClient) {
-			StreamDesc sd = kHandler.getStreamProcessor().getBySid(sid).getStream(uid);
+			StreamDesc sd = processor.getBySid(sid).getStream(uid);
 			try {
 				outgoingMedia = rtpEndpoint;
 				internalStartBroadcast(sd, sdp);
diff --git a/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/KTestStream.java b/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/KTestStream.java
index 741c1f6..57111ed 100644
--- a/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/KTestStream.java
+++ b/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/KTestStream.java
@@ -36,9 +36,12 @@ import java.util.concurrent.ScheduledExecutorService;
 import java.util.concurrent.ScheduledFuture;
 import java.util.concurrent.TimeUnit;
 
+import javax.inject.Inject;
+
 import org.apache.openmeetings.core.util.WebSocketHelper;
 import org.apache.openmeetings.db.entity.basic.IWsClient;
 import org.apache.openmeetings.util.OmFileHelper;
+import org.apache.wicket.injection.Injector;
 import org.kurento.client.Continuation;
 import org.kurento.client.IceCandidate;
 import org.kurento.client.MediaPipeline;
@@ -55,7 +58,12 @@ import com.github.openjson.JSONObject;
 public class KTestStream extends AbstractStream {
 	private static final Logger log = LoggerFactory.getLogger(KTestStream.class);
 	private static final Map<String, String> TAGS = Map.of(TAG_MODE, MODE_TEST, TAG_ROOM, MODE_TEST);
-	private final KurentoHandler kHandler;
+
+	@Inject
+	private KurentoHandler kHandler;
+	@Inject
+	private TestStreamProcessor processor;
+
 	private MediaPipeline pipeline;
 	private WebRtcEndpoint webRtcEndpoint;
 	private PlayerEndpoint player;
@@ -65,9 +73,9 @@ public class KTestStream extends AbstractStream {
 	private ScheduledFuture<?> recHandle;
 	private int recTime;
 
-	public KTestStream(IWsClient c, JSONObject msg, KurentoHandler kHandler) {
+	public KTestStream(IWsClient c, JSONObject msg) {
 		super(null, c.getUid());
-		this.kHandler = kHandler;
+		Injector.get().inject(this);
 		createPipeline(() -> startTestRecording(c, msg));
 	}
 
@@ -251,7 +259,7 @@ public class KTestStream extends AbstractStream {
 		releasePlayer();
 		releaseRecorder();
 		if (remove) {
-			kHandler.getTestProcessor().release(this, true);
+			processor.release(this, true);
 		}
 	}
 }
diff --git a/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/KurentoHandler.java b/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/KurentoHandler.java
index 1e8ebb4..a301dce 100644
--- a/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/KurentoHandler.java
+++ b/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/KurentoHandler.java
@@ -41,9 +41,7 @@ import javax.annotation.PreDestroy;
 import javax.crypto.Mac;
 import javax.crypto.spec.SecretKeySpec;
 
-import org.apache.openmeetings.core.sip.SipManager;
 import org.apache.openmeetings.core.util.WebSocketHelper;
-import org.apache.openmeetings.db.dao.record.RecordingChunkDao;
 import org.apache.openmeetings.db.dao.room.RoomDao;
 import org.apache.openmeetings.db.entity.basic.Client;
 import org.apache.openmeetings.db.entity.basic.Client.Activity;
@@ -125,13 +123,9 @@ public class KurentoHandler {
 	@Autowired
 	private RoomDao roomDao;
 	@Autowired
-	private RecordingChunkDao chunkDao;
-	@Autowired
 	private TestStreamProcessor testProcessor;
 	@Autowired
 	private StreamProcessor streamProcessor;
-	@Autowired
-	private SipManager sipManager;
 
 	boolean isConnected() {
 		boolean connctd = connected.get() && client != null && !client.isClosed();
@@ -309,7 +303,7 @@ public class KurentoHandler {
 		return rooms.computeIfAbsent(roomId, k -> {
 			log.debug("Room {} does not exist. Will create now!", roomId);
 			Room r = roomDao.get(roomId);
-			return new KRoom(this, r);
+			return new KRoom(r);
 		});
 	}
 
@@ -397,22 +391,6 @@ public class KurentoHandler {
 		return kuid;
 	}
 
-	public TestStreamProcessor getTestProcessor() {
-		return testProcessor;
-	}
-
-	StreamProcessor getStreamProcessor() {
-		return streamProcessor;
-	}
-
-	SipManager getSipManager() {
-		return sipManager;
-	}
-
-	RecordingChunkDao getChunkDao() {
-		return chunkDao;
-	}
-
 	static int getFlowoutTimeout() {
 		return flowoutTimeout;
 	}
diff --git a/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/StreamProcessor.java b/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/StreamProcessor.java
index 3771c0c..d99edb9 100644
--- a/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/StreamProcessor.java
+++ b/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/StreamProcessor.java
@@ -322,7 +322,7 @@ public class StreamProcessor implements IStreamProcessor {
 
 	private void startSharing(Client c, Optional<StreamDesc> osd, JSONObject msg, Activity a) {
 		if (kHandler.isConnected() && c.getRoomId() != null) {
-			kHandler.getRoom(c.getRoomId()).startSharing(this, cm, c, osd, msg, a);
+			kHandler.getRoom(c.getRoomId()).startSharing(c, osd, msg, a);
 		}
 	}
 
diff --git a/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/StreamProcessorActions.java b/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/StreamProcessorActions.java
index 8608485..b80a290 100644
--- a/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/StreamProcessorActions.java
+++ b/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/StreamProcessorActions.java
@@ -107,7 +107,7 @@ public class StreamProcessorActions {
 		try {
 			if (sender == null) {
 				KRoom room = kHandler.getRoom(c.getRoomId());
-				sender = room.join(sd, kHandler);
+				sender = room.join(sd);
 			}
 			if (msg.has("width")) {
 				sd.setWidth(msg.getInt("width")).setHeight(msg.getInt("height"));
diff --git a/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/TestStreamProcessor.java b/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/TestStreamProcessor.java
index 499d772..3bd7bde 100644
--- a/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/TestStreamProcessor.java
+++ b/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/TestStreamProcessor.java
@@ -56,7 +56,7 @@ class TestStreamProcessor implements IStreamProcessor {
 				if (user != null) {
 					user.release();
 				}
-				user = new KTestStream(c, msg, kHandler);
+				user = new KTestStream(c, msg);
 				streamByUid.put(c.getUid(), user);
 				break;
 			case "iceCandidate":
diff --git a/openmeetings-core/src/test/java/org/apache/openmeetings/core/remote/BaseMockedTest.java b/openmeetings-core/src/test/java/org/apache/openmeetings/core/remote/BaseMockedTest.java
index 4d94aa0..86f0211 100644
--- a/openmeetings-core/src/test/java/org/apache/openmeetings/core/remote/BaseMockedTest.java
+++ b/openmeetings-core/src/test/java/org/apache/openmeetings/core/remote/BaseMockedTest.java
@@ -22,11 +22,18 @@ package org.apache.openmeetings.core.remote;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.lenient;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.mockStatic;
+import static org.mockito.Mockito.withSettings;
+import static org.mockito.internal.util.collections.Sets.newMockSafeHashSet;
 
+import java.lang.reflect.Field;
 import java.util.Locale;
+import java.util.Set;
+
+import javax.inject.Inject;
 
 import org.apache.openmeetings.IApplication;
 import org.apache.openmeetings.core.util.WebSocketHelper;
@@ -34,6 +41,7 @@ import org.apache.openmeetings.db.dao.label.LabelDao;
 import org.apache.openmeetings.db.entity.basic.IWsClient;
 import org.apache.openmeetings.db.entity.label.OmLanguage;
 import org.apache.openmeetings.db.util.ApplicationHelper;
+import org.apache.wicket.injection.Injector;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.extension.ExtendWith;
 import org.kurento.client.KurentoClient;
@@ -49,14 +57,18 @@ import org.mockito.InjectMocks;
 import org.mockito.Mock;
 import org.mockito.MockedStatic;
 import org.mockito.Spy;
+import org.mockito.internal.configuration.injection.scanner.MockScanner;
 import org.mockito.invocation.InvocationOnMock;
 import org.mockito.junit.jupiter.MockitoExtension;
 import org.mockito.stubbing.Answer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import com.github.openjson.JSONObject;
 
 @ExtendWith(MockitoExtension.class)
 public class BaseMockedTest {
+	private static final Logger log = LoggerFactory.getLogger(BaseMockedTest.class);
 	@Mock
 	protected RomManager romManager;
 	@Mock
@@ -90,8 +102,12 @@ public class BaseMockedTest {
 				MockedStatic<WebSocketHelper> wsHelperMock = mockStatic(WebSocketHelper.class);
 				MockedStatic<LabelDao> labelMock = mockStatic(LabelDao.class);
 				MockedStatic<ApplicationHelper> appHelpMock = mockStatic(ApplicationHelper.class);
+				MockedStatic<Injector> injectMock = mockStatic(Injector.class)
 				)
 		{
+			Set<Object> mocks = newMockSafeHashSet();
+			new MockScanner(this, BaseMockedTest.class).addPreparedMocks(mocks);
+			new MockScanner(this, this.getClass()).addPreparedMocks(mocks);
 			wsHelperMock.when(() -> WebSocketHelper.sendClient(any(IWsClient.class), any(JSONObject.class))).thenAnswer(new Answer<Void>() {
 				@Override
 				public Void answer(InvocationOnMock invocation) throws Throwable {
@@ -104,7 +120,41 @@ public class BaseMockedTest {
 
 			labelMock.when(() -> LabelDao.getLanguage(any(Long.class))).thenReturn(new OmLanguage(1L, Locale.ENGLISH));
 			appHelpMock.when(() -> ApplicationHelper.ensureApplication(any(Long.class))).thenReturn(mock(IApplication.class));
+			Injector injector = mock(Injector.class, withSettings().lenient());
+			doAnswer(new Answer<Void>() {
+				@Override
+				public Void answer(InvocationOnMock invocation) throws Throwable {
+					Object o = invocation.getArgument(0);
+					if (forInjection(o)) {
+						inject(o, mocks);
+					}
+					return null;
+				}
+			}).when(injector).inject(any());
+			injectMock.when(() -> Injector.get()).thenReturn(injector);
 			task.run();
 		}
 	}
+
+	private boolean forInjection(Object o) {
+		return o instanceof KRoom || o instanceof KStream || o instanceof KTestStream;
+	}
+
+	private void inject(Object o, Set<Object> mocks) {
+		for (Field f : o.getClass().getDeclaredFields()) {
+			if (f.isAnnotationPresent(Inject.class)) {
+				mocks.stream()
+						.filter(mock -> f.getType().isAssignableFrom(mock.getClass()))
+						.findAny()
+						.ifPresent(mock -> {
+							try {
+								f.setAccessible(true);
+								f.set(o, mock);
+							} catch (Exception e) {
+								log.error("Fail to set mock {} {}", f, mock);
+							}
+						});
+			}
+		}
+	}
 }