SEBSERV-445 code cleanup
This commit is contained in:
parent
b344ee22e5
commit
8cab729401
12 changed files with 65 additions and 132 deletions
|
@ -84,30 +84,6 @@ public class SEBServer {
|
|||
return firewall;
|
||||
}
|
||||
|
||||
// @Bean
|
||||
// public WebServerFactoryCustomizer<TomcatServletWebServerFactory> tomcatCustomizer() {
|
||||
// return (tomcat) -> tomcat.addConnectorCustomizers((connector) -> {
|
||||
// if (connector.getProtocolHandler() instanceof AbstractHttp11Protocol) {
|
||||
// System.out.println("*************** tomcatCustomizer");
|
||||
// final AbstractHttp11Protocol<?> protocolHandler = (AbstractHttp11Protocol<?>) connector
|
||||
// .getProtocolHandler();
|
||||
// protocolHandler.setKeepAliveTimeout(60000);
|
||||
// protocolHandler.setMaxKeepAliveRequests(3000);
|
||||
// protocolHandler.setUseKeepAliveResponseHeader(true);
|
||||
// protocolHandler.setMinSpareThreads(200);
|
||||
// protocolHandler.setProcessorCache(-1);
|
||||
// protocolHandler.setTcpNoDelay(true);
|
||||
// protocolHandler.setThreadPriority(Thread.NORM_PRIORITY + 1);
|
||||
// protocolHandler.setMaxConnections(2000);
|
||||
// if (protocolHandler instanceof Http11NioProtocol) {
|
||||
// System.out.println("*************** Http11NioProtocol");
|
||||
// ((Http11NioProtocol) protocolHandler).setPollerThreadPriority(Thread.MAX_PRIORITY);
|
||||
// }
|
||||
//
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
|
||||
private Connector redirectConnector(final Environment env) {
|
||||
final String sslPort = env.getRequiredProperty("server.port");
|
||||
final String httpPort = env.getProperty("sebserver.ssl.redirect.html.port", "80");
|
||||
|
|
|
@ -29,4 +29,28 @@ public class WebserviceConfig {
|
|||
return aes256jnCryptor;
|
||||
}
|
||||
|
||||
// @Bean
|
||||
// public WebServerFactoryCustomizer<TomcatServletWebServerFactory> tomcatCustomizer() {
|
||||
// return (tomcat) -> tomcat.addConnectorCustomizers((connector) -> {
|
||||
// if (connector.getProtocolHandler() instanceof AbstractHttp11Protocol) {
|
||||
// System.out.println("*************** tomcatCustomizer");
|
||||
// final AbstractHttp11Protocol<?> protocolHandler = (AbstractHttp11Protocol<?>) connector
|
||||
// .getProtocolHandler();
|
||||
// protocolHandler.setKeepAliveTimeout(60000);
|
||||
// protocolHandler.setMaxKeepAliveRequests(3000);
|
||||
// protocolHandler.setUseKeepAliveResponseHeader(true);
|
||||
// protocolHandler.setMinSpareThreads(200);
|
||||
// protocolHandler.setProcessorCache(-1);
|
||||
// protocolHandler.setTcpNoDelay(true);
|
||||
// protocolHandler.setThreadPriority(Thread.NORM_PRIORITY + 1);
|
||||
// protocolHandler.setMaxConnections(2000);
|
||||
// if (protocolHandler instanceof Http11NioProtocol) {
|
||||
// System.out.println("*************** Http11NioProtocol");
|
||||
// ((Http11NioProtocol) protocolHandler).setPollerThreadPriority(Thread.MAX_PRIORITY);
|
||||
// }
|
||||
//
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
|
||||
}
|
||||
|
|
|
@ -28,11 +28,10 @@ public interface SEBClientSessionService {
|
|||
/** Notify a ping for a certain client connection.
|
||||
*
|
||||
* @param connectionToken the connection token
|
||||
* @param timestamp the ping time-stamp
|
||||
* @param pingNumber the ping number
|
||||
* @param instructionConfirm instruction confirm sent by the SEB client or null
|
||||
* @return SEB instruction if available */
|
||||
String notifyPing(String connectionToken, long timestamp, int pingNumber, String instructionConfirm);
|
||||
String notifyPing(String connectionToken, int pingNumber, String instructionConfirm);
|
||||
|
||||
/** Notify a SEB client event for live indication and storing to database.
|
||||
*
|
||||
|
|
|
@ -378,6 +378,7 @@ public class ExamSessionServiceImpl implements ExamSessionService {
|
|||
|
||||
@Override
|
||||
public ClientConnectionDataInternal getConnectionDataInternal(final String connectionToken) {
|
||||
// TODO do we really need to synchronize here?
|
||||
synchronized (ExamSessionCacheService.CLIENT_CONNECTION_CREATION_LOCK) {
|
||||
return this.examSessionCacheService.getClientConnection(connectionToken);
|
||||
}
|
||||
|
|
|
@ -44,9 +44,9 @@ import ch.ethz.seb.sebserver.webservice.servicelayer.session.SEBClientNotificati
|
|||
@Lazy
|
||||
@Component
|
||||
@WebServiceProfile
|
||||
public class SEBClientEventBatchStore {
|
||||
public class SEBClientEventBatchService {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(SEBClientEventBatchStore.class);
|
||||
private static final Logger log = LoggerFactory.getLogger(SEBClientEventBatchService.class);
|
||||
|
||||
private final SEBClientNotificationService sebClientNotificationService;
|
||||
private final SqlSessionFactory sqlSessionFactory;
|
||||
|
@ -57,7 +57,7 @@ public class SEBClientEventBatchStore {
|
|||
private final SqlSessionTemplate sqlSessionTemplate;
|
||||
private final ClientEventRecordMapper clientEventMapper;
|
||||
|
||||
public SEBClientEventBatchStore(
|
||||
public SEBClientEventBatchService(
|
||||
final SEBClientNotificationService sebClientNotificationService,
|
||||
final SqlSessionFactory sqlSessionFactory,
|
||||
final PlatformTransactionManager transactionManager,
|
||||
|
@ -94,14 +94,12 @@ public class SEBClientEventBatchStore {
|
|||
|
||||
@Scheduled(
|
||||
fixedDelayString = "${sebserver.webservice.api.exam.session.event.batch.interval:1000}",
|
||||
initialDelay = 1000)
|
||||
initialDelay = 100)
|
||||
public void processEvents() {
|
||||
|
||||
final long startTime = Utils.getMillisecondsNow();
|
||||
|
||||
final int size = this.eventDataQueue.size();
|
||||
if (size > 1000) {
|
||||
log.warn("******* There are more then 1000 SEB client logs in the waiting queue: {}", size);
|
||||
log.warn("-----> There are more then 1000 SEB client logs in the waiting queue: {}", size);
|
||||
}
|
||||
|
||||
try {
|
||||
|
@ -130,15 +128,6 @@ public class SEBClientEventBatchStore {
|
|||
|
||||
this.sqlSessionTemplate.flushStatements();
|
||||
|
||||
if (log.isTraceEnabled()) {
|
||||
log.trace("Processing {} SEB events tuck: {}",
|
||||
this.events.size(),
|
||||
Utils.getMillisecondsNow() - startTime);
|
||||
}
|
||||
// TODO just for debugging
|
||||
System.out.println("***** Processing " + this.events.size() + " SEB events tuck: "
|
||||
+ (Utils.getMillisecondsNow() - startTime));
|
||||
|
||||
} catch (final Exception e) {
|
||||
log.error("Failed to process SEB events from eventDataQueue: ", e);
|
||||
}
|
|
@ -27,9 +27,9 @@ import ch.ethz.seb.sebserver.webservice.servicelayer.session.SEBClientInstructio
|
|||
@Lazy
|
||||
@Component
|
||||
@WebServiceProfile
|
||||
public class SEBClientPingService {
|
||||
public class SEBClientPingBatchService {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(SEBClientPingService.class);
|
||||
private static final Logger log = LoggerFactory.getLogger(SEBClientPingBatchService.class);
|
||||
|
||||
private final ExamSessionCacheService examSessionCacheService;
|
||||
private final SEBClientInstructionService sebClientInstructionService;
|
||||
|
@ -37,7 +37,7 @@ public class SEBClientPingService {
|
|||
private final Map<String, String> pings = new ConcurrentHashMap<>();
|
||||
private final Map<String, String> instructions = new ConcurrentHashMap<>();
|
||||
|
||||
public SEBClientPingService(
|
||||
public SEBClientPingBatchService(
|
||||
final ExamSessionCacheService examSessionCacheService,
|
||||
final SEBClientInstructionService sebClientInstructionService) {
|
||||
|
||||
|
@ -45,19 +45,15 @@ public class SEBClientPingService {
|
|||
this.sebClientInstructionService = sebClientInstructionService;
|
||||
}
|
||||
|
||||
@Scheduled(
|
||||
fixedDelayString = "${sebserver.webservice.api.exam.session.ping.batch.interval:500}",
|
||||
initialDelay = 1000)
|
||||
@Scheduled(fixedDelayString = "${sebserver.webservice.api.exam.session.ping.batch.interval:500}")
|
||||
public void processPings() {
|
||||
if (this.pings.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
final long startTime = Utils.getMillisecondsNow();
|
||||
|
||||
final int size = this.pings.size();
|
||||
if (size > 1000) {
|
||||
log.warn("******* There are more then 1000 SEB client logs in the waiting queue: {}", size);
|
||||
log.warn("----> There are more then 1000 SEB client logs in the waiting queue: {}", size);
|
||||
}
|
||||
|
||||
try {
|
||||
|
@ -68,17 +64,6 @@ public class SEBClientPingService {
|
|||
this.pings.remove(cid),
|
||||
Utils.getMillisecondsNow()));
|
||||
|
||||
// pp.entrySet()
|
||||
// .stream()
|
||||
// .forEach(entry -> processPing(entry.getKey(), entry.getValue(), startTime));
|
||||
|
||||
if (log.isTraceEnabled()) {
|
||||
log.trace("****** Processing {} SEB pings tuck: {}", Utils.getMillisecondsNow() - startTime);
|
||||
}
|
||||
// TODO just for debugging
|
||||
System.out.println("***** Processing " + size + " SEB pings tuck: "
|
||||
+ (Utils.getMillisecondsNow() - startTime));
|
||||
|
||||
} catch (final Exception e) {
|
||||
log.error("Failed to process SEB pings from pingDataQueue: ", e);
|
||||
}
|
|
@ -31,7 +31,7 @@ import ch.ethz.seb.sebserver.webservice.servicelayer.session.ExamSessionService;
|
|||
import ch.ethz.seb.sebserver.webservice.servicelayer.session.SEBClientInstructionService;
|
||||
import ch.ethz.seb.sebserver.webservice.servicelayer.session.SEBClientSessionService;
|
||||
import ch.ethz.seb.sebserver.webservice.servicelayer.session.SEBClientVersionService;
|
||||
import ch.ethz.seb.sebserver.webservice.servicelayer.session.impl.SEBClientEventBatchStore.EventData;
|
||||
import ch.ethz.seb.sebserver.webservice.servicelayer.session.impl.SEBClientEventBatchService.EventData;
|
||||
|
||||
@Lazy
|
||||
@Service
|
||||
|
@ -42,29 +42,27 @@ public class SEBClientSessionServiceImpl implements SEBClientSessionService {
|
|||
|
||||
private final ClientConnectionDAO clientConnectionDAO;
|
||||
private final ExamSessionService examSessionService;
|
||||
private final ExamSessionCacheService examSessionCacheService;
|
||||
private final SEBClientEventBatchStore sebClientEventBatchStore;
|
||||
private final SEBClientEventBatchService sebClientEventBatchStore;
|
||||
private final SEBClientInstructionService sebInstructionService;
|
||||
private final ClientIndicatorFactory clientIndicatorFactory;
|
||||
private final InternalClientConnectionDataFactory internalClientConnectionDataFactory;
|
||||
private final SecurityKeyService securityKeyService;
|
||||
private final SEBClientVersionService sebClientVersionService;
|
||||
private final SEBClientPingService sebClientPingService;
|
||||
private final SEBClientPingBatchService sebClientPingService;
|
||||
|
||||
public SEBClientSessionServiceImpl(
|
||||
final ClientConnectionDAO clientConnectionDAO,
|
||||
final ExamSessionService examSessionService,
|
||||
final SEBClientEventBatchStore sebClientEventBatchStore,
|
||||
final SEBClientEventBatchService sebClientEventBatchStore,
|
||||
final SEBClientInstructionService sebInstructionService,
|
||||
final ClientIndicatorFactory clientIndicatorFactory,
|
||||
final InternalClientConnectionDataFactory internalClientConnectionDataFactory,
|
||||
final SecurityKeyService securityKeyService,
|
||||
final SEBClientVersionService sebClientVersionService,
|
||||
final SEBClientPingService sebClientPingService) {
|
||||
final SEBClientPingBatchService sebClientPingService) {
|
||||
|
||||
this.clientConnectionDAO = clientConnectionDAO;
|
||||
this.examSessionService = examSessionService;
|
||||
this.examSessionCacheService = examSessionService.getExamSessionCacheService();
|
||||
this.sebClientEventBatchStore = sebClientEventBatchStore;
|
||||
this.sebInstructionService = sebInstructionService;
|
||||
this.clientIndicatorFactory = clientIndicatorFactory;
|
||||
|
@ -114,29 +112,12 @@ public class SEBClientSessionServiceImpl implements SEBClientSessionService {
|
|||
@Override
|
||||
public String notifyPing(
|
||||
final String connectionToken,
|
||||
final long timestamp,
|
||||
final int pingNumber,
|
||||
final String instructionConfirm) {
|
||||
|
||||
return this.sebClientPingService.notifyPing(connectionToken, instructionConfirm);
|
||||
}
|
||||
|
||||
// @Override
|
||||
// public String notifyPing(
|
||||
// final String connectionToken,
|
||||
// final long timestamp,
|
||||
// final int pingNumber,
|
||||
// final String instructionConfirm) {
|
||||
//
|
||||
// processPing(connectionToken, timestamp, pingNumber);
|
||||
//
|
||||
// if (instructionConfirm != null) {
|
||||
// this.sebInstructionService.confirmInstructionDone(connectionToken, instructionConfirm);
|
||||
// }
|
||||
//
|
||||
// return this.sebInstructionService.getInstructionJSON(connectionToken);
|
||||
// }
|
||||
|
||||
@Override
|
||||
public final void notifyClientEvent(final String connectionToken, final String jsonBody) {
|
||||
this.sebClientEventBatchStore.accept(connectionToken, jsonBody);
|
||||
|
@ -155,16 +136,6 @@ public class SEBClientSessionServiceImpl implements SEBClientSessionService {
|
|||
this.internalClientConnectionDataFactory.getGroupIds(clientConnection)));
|
||||
}
|
||||
|
||||
// private void processPing(final String connectionToken, final long timestamp, final int pingNumber) {
|
||||
//
|
||||
// final ClientConnectionDataInternal activeClientConnection = this.examSessionCacheService
|
||||
// .getClientConnection(connectionToken);
|
||||
//
|
||||
// if (activeClientConnection != null) {
|
||||
// activeClientConnection.notifyPing(timestamp);
|
||||
// }
|
||||
// }
|
||||
|
||||
private void missingPingUpdate(final ClientConnectionDataInternal connection) {
|
||||
if (connection.pingIndicator.changeOnIncident()) {
|
||||
|
||||
|
|
|
@ -344,10 +344,8 @@ public class DistributedIndicatorValueService implements DisposableBean {
|
|||
}
|
||||
|
||||
/** Update last ping time on persistent storage asynchronously within a defines thread pool with no
|
||||
* waiting queue to skip further ping updates if all update threads are busy
|
||||
*
|
||||
* TODO: we need a better handling strategy here.
|
||||
* Try to apply a batch update and store the pings in a concurrent hash map **/
|
||||
* waiting queue to skip further ping updates if all update threads are busy **/
|
||||
// TODO: we need a better handling strategy here. Try to apply a batch update managed by SEBClientPingBatchService
|
||||
void updatePingAsync(final Long pingRecord) {
|
||||
try {
|
||||
this.indicatorValueUpdateExecutor
|
||||
|
@ -363,6 +361,7 @@ public class DistributedIndicatorValueService implements DisposableBean {
|
|||
|
||||
/** Update indicator value on persistent storage asynchronously within a defined thread pool with no
|
||||
* waiting queue to skip further indicator value updates if all update threads are busy **/
|
||||
// TODO: we need a better handling strategy here. Try to apply a batch update managed by SEBClientEventBatchStore
|
||||
boolean updateIndicatorValueAsync(final Long pk, final Long value) {
|
||||
try {
|
||||
this.indicatorValueUpdateExecutor
|
||||
|
|
|
@ -325,32 +325,25 @@ public class ExamAPI_V1_Controller {
|
|||
method = RequestMethod.POST,
|
||||
consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE,
|
||||
produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
public CompletableFuture<Void> ping(final HttpServletRequest request, final HttpServletResponse response) {
|
||||
return CompletableFuture.runAsync(
|
||||
() -> {
|
||||
final String connectionToken = request.getHeader(API.EXAM_API_SEB_CONNECTION_TOKEN);
|
||||
//final String pingNumString = request.getParameter(API.EXAM_API_PING_NUMBER);
|
||||
final String instructionConfirm = request.getParameter(API.EXAM_API_PING_INSTRUCTION_CONFIRM);
|
||||
public void ping(final HttpServletRequest request, final HttpServletResponse response) {
|
||||
|
||||
final String instruction = this.sebClientSessionService
|
||||
.notifyPing(
|
||||
connectionToken,
|
||||
0,
|
||||
0,
|
||||
instructionConfirm);
|
||||
final String connectionToken = request.getHeader(API.EXAM_API_SEB_CONNECTION_TOKEN);
|
||||
//final String pingNumString = request.getParameter(API.EXAM_API_PING_NUMBER);
|
||||
final String instructionConfirm = request.getParameter(API.EXAM_API_PING_INSTRUCTION_CONFIRM);
|
||||
|
||||
if (instruction == null) {
|
||||
response.setStatus(HttpStatus.NO_CONTENT.value());
|
||||
} else {
|
||||
try {
|
||||
response.setStatus(HttpStatus.OK.value());
|
||||
response.getOutputStream().write(instruction.getBytes(StandardCharsets.UTF_8));
|
||||
} catch (final IOException e) {
|
||||
log.error("Failed to send instruction as response: {}", connectionToken, e);
|
||||
}
|
||||
}
|
||||
},
|
||||
this.executor);
|
||||
final String instruction = this.sebClientSessionService
|
||||
.notifyPing(connectionToken, 0, instructionConfirm);
|
||||
|
||||
if (instruction == null) {
|
||||
response.setStatus(HttpStatus.NO_CONTENT.value());
|
||||
} else {
|
||||
try {
|
||||
response.setStatus(HttpStatus.OK.value());
|
||||
response.getOutputStream().write(instruction.getBytes(StandardCharsets.UTF_8));
|
||||
} catch (final IOException e) {
|
||||
log.error("Failed to send instruction as response: {}", connectionToken, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@RequestMapping(
|
||||
|
|
|
@ -314,8 +314,6 @@ public class ExamMonitoringController {
|
|||
name = API.EXAM_MONITORING_CLIENT_GROUP_FILTER,
|
||||
required = false) final String hiddenClientGroups) {
|
||||
|
||||
final long now = Utils.getMillisecondsNow();
|
||||
|
||||
final Exam runningExam = checkPrivileges(institutionId, examId);
|
||||
|
||||
final MonitoringSEBConnectionData monitoringSEBConnectionData = this.examSessionService
|
||||
|
@ -342,8 +340,6 @@ public class ExamMonitoringController {
|
|||
Collections.emptyList());
|
||||
}
|
||||
|
||||
System.out.println("%%%%%%%% --> monitoring tuck: " + (Utils.getMillisecondsNow() - now));
|
||||
|
||||
return monitoringFullPageData;
|
||||
}
|
||||
|
||||
|
|
|
@ -42,7 +42,7 @@ import ch.ethz.seb.sebserver.webservice.servicelayer.lms.LmsAPIService;
|
|||
import ch.ethz.seb.sebserver.webservice.servicelayer.lms.LmsAPITemplate;
|
||||
import ch.ethz.seb.sebserver.webservice.servicelayer.session.impl.ClientConnectionDataInternal;
|
||||
import ch.ethz.seb.sebserver.webservice.servicelayer.session.impl.ExamSessionCacheService;
|
||||
import ch.ethz.seb.sebserver.webservice.servicelayer.session.impl.SEBClientEventBatchStore;
|
||||
import ch.ethz.seb.sebserver.webservice.servicelayer.session.impl.SEBClientEventBatchService;
|
||||
|
||||
@Sql(scripts = { "classpath:schema-test.sql", "classpath:data-test.sql", "classpath:data-test-additional.sql" })
|
||||
public class SebConnectionTest extends ExamAPIIntegrationTester {
|
||||
|
@ -58,7 +58,7 @@ public class SebConnectionTest extends ExamAPIIntegrationTester {
|
|||
@Autowired
|
||||
private LmsAPIService lmsAPIService;
|
||||
@Autowired
|
||||
private SEBClientEventBatchStore sebClientEventBatchStore;
|
||||
private SEBClientEventBatchService sebClientEventBatchStore;
|
||||
|
||||
@Before
|
||||
public void init() {
|
||||
|
|
|
@ -32,7 +32,7 @@ import ch.ethz.seb.sebserver.webservice.servicelayer.dao.FilterMap;
|
|||
import ch.ethz.seb.sebserver.webservice.servicelayer.session.ClientIndicator;
|
||||
import ch.ethz.seb.sebserver.webservice.servicelayer.session.SEBClientConnectionService;
|
||||
import ch.ethz.seb.sebserver.webservice.servicelayer.session.SEBClientSessionService;
|
||||
import ch.ethz.seb.sebserver.webservice.servicelayer.session.impl.SEBClientEventBatchStore;
|
||||
import ch.ethz.seb.sebserver.webservice.servicelayer.session.impl.SEBClientEventBatchService;
|
||||
import ch.ethz.seb.sebserver.webservice.servicelayer.session.impl.indicator.AbstractLogIndicator;
|
||||
import ch.ethz.seb.sebserver.webservice.servicelayer.session.impl.indicator.AbstractLogLevelCountIndicator;
|
||||
|
||||
|
@ -48,7 +48,7 @@ public class ClientEventServiceTest extends AdministrationAPIIntegrationTester {
|
|||
@Autowired
|
||||
private SEBClientSessionService sebClientSessionService;
|
||||
@Autowired
|
||||
private SEBClientEventBatchStore sebClientEventBatchStore;
|
||||
private SEBClientEventBatchService sebClientEventBatchStore;
|
||||
// @Autowired
|
||||
// @Qualifier(AsyncServiceSpringConfig.EXAM_API_EXECUTOR_BEAN_NAME)
|
||||
// private Executor executor;
|
||||
|
|
Loading…
Reference in a new issue