Skip to content

Commit

Permalink
Implementation of scheduler start/stop + refactoring #12
Browse files Browse the repository at this point in the history
- refactoring:
  removed static field OBJECT from all Jsonables, because this
  leads to misunderstanding - and wrong usage. Now parts using
  OBJECT.from(...) must use their own field for this.

- added services, rest controller
- added database tables

On behalf of Daimler TSS GmbH.
  • Loading branch information
de-jcup committed Oct 17, 2019
1 parent d405124 commit 18b8e60
Show file tree
Hide file tree
Showing 42 changed files with 933 additions and 123 deletions.
Expand Up @@ -26,6 +26,23 @@ private AdministrationAPIConstants() {
*/
public static final String API_ACCEPT_USER_SIGNUP = API_ADMINISTRATION + "signup/accept/{userId}";


/**
* Stop scheduling (pause)
*/
public static final String API_SCHEDULER_STOP = API_ADMINISTRATION + "scheduler/stop";

/**
* Stop scheduling (pause)
*/
public static final String API_SCHEDULER_START = API_ADMINISTRATION + "scheduler/start";


/**
* Refresh scheduler status
*/
public static final String API_SCHEDULER_STATUS_REFRESH = API_ADMINISTRATION + "scheduler/status/refresh";

/**
* show all users wanting to sign up
*/
Expand Down
Expand Up @@ -27,11 +27,6 @@ public class ProjectJsonInput implements JSONable<ProjectJsonInput> {
public static final String PROPERTY_DESCRIPTION = "description";
public static final String PROPERTY_WHITELIST = "whiteList";
public static final String PROPERTY_OWNER = "owner";
/**
* Just an reusable instance for JSON from calls - so we do not need to create
* always an empty object
*/
public static final ProjectJsonInput OBJECT = new ProjectJsonInput();

private String apiVersion;
private String name;
Expand Down
@@ -0,0 +1,69 @@
// SPDX-License-Identifier: MIT
package com.daimler.sechub.domain.administration.schedule;

import javax.annotation.security.RolesAllowed;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;

import com.daimler.sechub.domain.administration.AdministrationAPIConstants;
import com.daimler.sechub.sharedkernel.RoleConstants;
import com.daimler.sechub.sharedkernel.Step;
import com.daimler.sechub.sharedkernel.usecases.admin.schedule.UseCaseAdministratorStartScheduler;
import com.daimler.sechub.sharedkernel.usecases.admin.schedule.UseCaseAdministratorStopScheduler;
import com.daimler.sechub.sharedkernel.usecases.admin.schedule.UseCaseAdministratorTriggersRefreshOfSchedulerStatus;

/**
* The rest api for user administration done by a super admin.
*
* @author Albert Tregnaghi
*
*/
@RestController
@EnableAutoConfiguration
@RolesAllowed(RoleConstants.ROLE_SUPERADMIN)
public class SchedulerAdministrationRestController {

@Autowired
StartSchedulerService startSchedulerService;

@Autowired
StopSchedulerService stopSchedulerService;

@Autowired
TriggerSchedulerStatusRefreshService triggerRefreshService;

/* @formatter:off */
@UseCaseAdministratorStartScheduler(@Step(number=1,name="Rest call",description="Administrator wants to start (unpause) scheduler",needsRestDoc=true))
@RequestMapping(path = AdministrationAPIConstants.API_SCHEDULER_START, method = RequestMethod.POST, produces= {MediaType.APPLICATION_JSON_UTF8_VALUE,MediaType.APPLICATION_JSON_VALUE})
@ResponseStatus(HttpStatus.OK)
public void startScheduler() {
/* @formatter:on */
startSchedulerService.startScheduler();
}

/* @formatter:off */
@UseCaseAdministratorStopScheduler(@Step(number=1,name="Rest call",description="Administrator wants to stop (pause) scheduler",needsRestDoc=true))
@RequestMapping(path = AdministrationAPIConstants.API_SCHEDULER_STOP, method = RequestMethod.POST, produces= {MediaType.APPLICATION_JSON_UTF8_VALUE,MediaType.APPLICATION_JSON_VALUE})
@ResponseStatus(HttpStatus.OK)
public void stopScheduler() {
/* @formatter:on */
stopSchedulerService.stopScheduler();
}

/* @formatter:off */
@UseCaseAdministratorTriggersRefreshOfSchedulerStatus(@Step(number=1,name="Rest call",description="Administrator wants to refresh information about scheduler status",needsRestDoc=true))
@RequestMapping(path = AdministrationAPIConstants.API_SCHEDULER_STATUS_REFRESH, method = RequestMethod.POST, produces= {MediaType.APPLICATION_JSON_UTF8_VALUE,MediaType.APPLICATION_JSON_VALUE})
@ResponseStatus(HttpStatus.OK)
public void triggerSchedulerStatusRefresh() {
/* @formatter:on */
triggerRefreshService.triggerSchedulerStatusRefresh();
}

}
@@ -0,0 +1,74 @@
package com.daimler.sechub.domain.administration.schedule;

import java.util.Optional;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.daimler.sechub.domain.administration.status.StatusEntry;
import com.daimler.sechub.domain.administration.status.StatusEntryRepository;
import com.daimler.sechub.sharedkernel.messaging.AsynchronMessageHandler;
import com.daimler.sechub.sharedkernel.messaging.DomainMessage;
import com.daimler.sechub.sharedkernel.messaging.IsReceivingAsyncMessage;
import com.daimler.sechub.sharedkernel.messaging.MessageDataKeys;
import com.daimler.sechub.sharedkernel.messaging.MessageID;
import com.daimler.sechub.sharedkernel.messaging.SchedulerMessage;

@Component
public class SchedulerMessageHandler implements AsynchronMessageHandler{

private static final Logger LOG = LoggerFactory.getLogger(SchedulerMessageHandler.class);

@Autowired
StatusEntryRepository repository;

@Override
public void receiveAsyncMessage(DomainMessage request) {
MessageID messageId = request.getMessageId();
LOG.debug("received domain request: {}", request);

switch (messageId) {
case SCHEDULER_STATUS_UPDATE :
handleSchedulerStatusChange(request);
break;
default:
throw new IllegalStateException("unhandled message id:"+messageId);
}
}

@IsReceivingAsyncMessage(MessageID.SCHEDULER_STATUS_UPDATE)
private void handleSchedulerStatusChange(DomainMessage request) {
SchedulerMessage status = request.get(MessageDataKeys.SCHEDULER_STATUS_DATA);

StatusEntry enabled = fetchOrCreateEntry(SchedulerStatusEntryKeys.SCHEDULER_ENABLED);
enabled.setValue(Boolean.toString(status.isEnabled()));

StatusEntry jobsAll= fetchOrCreateEntry(SchedulerStatusEntryKeys.SCHEDULER_JOBS_ALL);
jobsAll.setValue(Integer.toString(status.getAmountOfAllJobs()));

StatusEntry jobsRunning = fetchOrCreateEntry(SchedulerStatusEntryKeys.SCHEDULER_JOBS_RUNNING);
jobsRunning.setValue(Integer.toString(status.getAmountOfRunningJobs()));

StatusEntry jobsWaiting = fetchOrCreateEntry(SchedulerStatusEntryKeys.SCHEDULER_JOBS_WAITING);
jobsWaiting.setValue(Integer.toString(status.getAmountOfWaitingJobs()));

/* persist */
repository.save(enabled);
repository.save(jobsAll);
repository.save(jobsRunning);
repository.save(jobsWaiting);

}

private StatusEntry fetchOrCreateEntry(SchedulerStatusEntryKeys key) {
Optional<StatusEntry> optional = repository.findByStatusEntryKey(key);
if (optional.isPresent()) {
return optional.get();
}
StatusEntry entry = new StatusEntry(key);
return entry;

}
}
@@ -0,0 +1,25 @@
package com.daimler.sechub.domain.administration.schedule;

import com.daimler.sechub.domain.administration.status.StatusEntryKey;

public enum SchedulerStatusEntryKeys implements StatusEntryKey{
SCHEDULER_ENABLED("status.scheduler.enabled"),

SCHEDULER_JOBS_ALL("status.scheduler.jobs.all"),

SCHEDULER_JOBS_RUNNING("status.scheduler.jobs.running"),

SCHEDULER_JOBS_WAITING("status.scheduler.jobs.waiting");

private String statusEntryKey;

private SchedulerStatusEntryKeys(String key) {
this.statusEntryKey=key;
}

@Override
public String getStatusEntryKey() {
return statusEntryKey;
}

}
@@ -0,0 +1,39 @@
// SPDX-License-Identifier: MIT
package com.daimler.sechub.domain.administration.schedule;

import javax.annotation.security.RolesAllowed;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.daimler.sechub.sharedkernel.RoleConstants;
import com.daimler.sechub.sharedkernel.Step;
import com.daimler.sechub.sharedkernel.messaging.DomainMessage;
import com.daimler.sechub.sharedkernel.messaging.DomainMessageFactory;
import com.daimler.sechub.sharedkernel.messaging.DomainMessageService;
import com.daimler.sechub.sharedkernel.messaging.IsSendingAsyncMessage;
import com.daimler.sechub.sharedkernel.messaging.MessageID;
import com.daimler.sechub.sharedkernel.usecases.admin.schedule.UseCaseAdministratorStartScheduler;

@Service
@RolesAllowed(RoleConstants.ROLE_SUPERADMIN)
public class StartSchedulerService {

@Autowired
DomainMessageService eventBusService;

/* @formatter:off */
@UseCaseAdministratorStartScheduler(@Step(number=2,name="Service call",description="Sends request to scheduler domain to start scheduler"))
public void startScheduler() {
/* @formatter:on */
sendStartSchedulerEvent();
}

@IsSendingAsyncMessage(MessageID.REQUEST_SCHEDULER_START)
private void sendStartSchedulerEvent() {
DomainMessage request = DomainMessageFactory.createRequestSchedulerStartMessage();
eventBusService.sendAsynchron(request);
}


}
@@ -0,0 +1,38 @@
// SPDX-License-Identifier: MIT
package com.daimler.sechub.domain.administration.schedule;

import javax.annotation.security.RolesAllowed;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.daimler.sechub.sharedkernel.RoleConstants;
import com.daimler.sechub.sharedkernel.Step;
import com.daimler.sechub.sharedkernel.messaging.DomainMessage;
import com.daimler.sechub.sharedkernel.messaging.DomainMessageFactory;
import com.daimler.sechub.sharedkernel.messaging.DomainMessageService;
import com.daimler.sechub.sharedkernel.messaging.IsSendingAsyncMessage;
import com.daimler.sechub.sharedkernel.messaging.MessageID;
import com.daimler.sechub.sharedkernel.usecases.admin.schedule.UseCaseAdministratorStopScheduler;

@Service
@RolesAllowed(RoleConstants.ROLE_SUPERADMIN)
public class StopSchedulerService {

@Autowired
DomainMessageService eventBusService;

/* @formatter:off */
@UseCaseAdministratorStopScheduler(@Step(number=2,name="Service call",description="Sends request to scheduler domain to stop scheduler"))
public void stopScheduler() {
/* @formatter:on */
sendStopSchedulerEvent();
}

@IsSendingAsyncMessage(MessageID.REQUEST_SCHEDULER_STOP)
private void sendStopSchedulerEvent() {
DomainMessage request = DomainMessageFactory.createRequestSchedulerStopMessage();
eventBusService.sendAsynchron(request);
}

}
@@ -0,0 +1,39 @@
// SPDX-License-Identifier: MIT
package com.daimler.sechub.domain.administration.schedule;

import javax.annotation.security.RolesAllowed;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.daimler.sechub.sharedkernel.RoleConstants;
import com.daimler.sechub.sharedkernel.Step;
import com.daimler.sechub.sharedkernel.messaging.DomainMessage;
import com.daimler.sechub.sharedkernel.messaging.DomainMessageFactory;
import com.daimler.sechub.sharedkernel.messaging.DomainMessageService;
import com.daimler.sechub.sharedkernel.messaging.IsSendingAsyncMessage;
import com.daimler.sechub.sharedkernel.messaging.MessageID;
import com.daimler.sechub.sharedkernel.usecases.admin.schedule.UseCaseAdministratorStopScheduler;

@Service
@RolesAllowed(RoleConstants.ROLE_SUPERADMIN)
public class TriggerSchedulerStatusRefreshService {

@Autowired
DomainMessageService eventBusService;

/* @formatter:off */
@UseCaseAdministratorStopScheduler(@Step(number=2,name="Service call",description="Sends request to scheduler to send updates about current status"))
public void triggerSchedulerStatusRefresh() {
/* @formatter:on */
sendUpdateSchedulerStatusEvent();
}

@IsSendingAsyncMessage(MessageID.REQUEST_SCHEDULER_STATUS_UPDATE)
private void sendUpdateSchedulerStatusEvent() {
DomainMessage request = DomainMessageFactory.createRequestSchedulerStatusUpdateMessage();
eventBusService.sendAsynchron(request);
}


}
Expand Up @@ -12,16 +12,11 @@ public class SignupJsonInput implements JSONable<SignupJsonInput> {
public static final String PROPERTY_API_VERSION = "apiVersion";
public static final String PROPERTY_USER_ID = "userId";
public static final String PROPERTY_EMAIL_ADRESS = "emailAdress";
/**
* Just an reusable instance for JSON from calls - so we do not need to create
* always an empty object
*/
public static final SignupJsonInput OBJECT = new SignupJsonInput();


private String apiVersion;
private String userId;
private String emailAdress;


@Override
public Class<SignupJsonInput> getJSONTargetClass() {
Expand Down

0 comments on commit 18b8e60

Please sign in to comment.