use of com.infiniteautomation.mango.rest.latest.exception.BadRequestException in project ma-modules-public by infiniteautomation.
the class ModulesRestController method uploadUpgrades.
@PreAuthorize("isAdmin()")
@ApiOperation(value = "Upload upgrade zip bundle, to be installed on restart", notes = "The bundle can be downloaded from the Mango Store")
@RequestMapping(method = RequestMethod.POST, value = "/upload-upgrades")
public UpgradeUploadResult uploadUpgrades(@ApiParam(value = "Perform Backup first", required = false, defaultValue = "false", allowMultiple = false) @RequestParam(required = false, defaultValue = "false") boolean backup, @ApiParam(value = "Restart after upload completes", required = false, defaultValue = "false", allowMultiple = false) @RequestParam(required = false, defaultValue = "false") boolean restart, MultipartHttpServletRequest multipartRequest) throws IOException {
if (env.getProperty("store.disableUpgrades", Boolean.class, false)) {
throw new FeatureDisabledException(new TranslatableMessage("modules.error.upgradesDisabled"));
}
synchronized (UPLOAD_UPGRADE_LOCK) {
if (UPLOAD_UPGRADE_IN_PROGRESS == null) {
UPLOAD_UPGRADE_IN_PROGRESS = new Object();
} else {
throw new BadRequestException(new TranslatableMessage("rest.error.upgradeUploadInProgress"));
}
}
UpgradeUploadResult result = new UpgradeUploadResult();
try {
if (backup) {
// Do the backups. They run async, so this returns immediately. The shutdown will
// wait for the
// background processes to finish though.
BackupWorkItem.queueBackup(SystemSettingsDao.getInstance().getValue(SystemSettingsDao.BACKUP_FILE_LOCATION));
DatabaseBackupWorkItem.queueBackup(SystemSettingsDao.getInstance().getValue(SystemSettingsDao.DATABASE_BACKUP_FILE_LOCATION));
}
List<MultipartFile> files = new ArrayList<>();
MultiValueMap<String, MultipartFile> filemap = multipartRequest.getMultiFileMap();
for (String nameField : filemap.keySet()) {
files.addAll(filemap.get(nameField));
}
// Validate the zip
if (files.size() == 0)
throw new BadRequestException(new TranslatableMessage("rest.error.noFileProvided"));
// Create the temp directory into which to download, if necessary.
Path tempDir = Common.getTempPath().resolve(ModuleUtils.DOWNLOAD_DIR);
Files.createDirectories(tempDir);
// Delete anything that is currently the temp directory.
FileUtils.cleanDirectory(tempDir.toFile());
try {
// Save the upload(s) to the temp dir
for (MultipartFile file : files) {
Path newFile = tempDir.resolve(file.getOriginalFilename());
try (InputStream is = file.getInputStream()) {
Files.copy(is, newFile);
}
}
List<Path> potentialUpgrades = Files.list(tempDir).filter(p -> p.toString().endsWith(".zip")).collect(Collectors.toList());
List<String> upgraded = new ArrayList<>();
List<String> unsigned = new ArrayList<>();
boolean developmentMode = env.getProperty("development.enabled", Boolean.class, false);
for (Path file : potentialUpgrades) {
boolean core = false;
boolean hasWebModules = false;
// Test to see if it is a core or a bundle of only zips or many zip files
try (ZipInputStream is = new ZipInputStream(Files.newInputStream(file))) {
ZipEntry entry = is.getNextEntry();
if (entry == null) {
// Not a zip file or empty, either way we don't care
throw new BadRequestException(new TranslatableMessage("rest.error.badUpgradeFile"));
} else {
do {
String entryName = entry.getName();
if ("release.signed".equals(entryName) || "release.properties".equals(entryName)) {
if (!developmentMode && "release.properties".equals(entryName)) {
throw new BadRequestException(new TranslatableMessage("modules.unsigned.core.development"));
}
core = true;
break;
} else if (entry.getName().startsWith(WEB_MODULE_PREFIX)) {
hasWebModules = true;
}
} while ((entry = is.getNextEntry()) != null);
}
}
if (core) {
// move file to core directory
Files.move(file, Common.MA_HOME_PATH.resolve("m2m2-core-upgrade.zip"));
upgraded.add(file.getFileName().toString());
} else if (hasWebModules) {
// This is a zip with modules in web/modules move them all out into the MA_HOME/web/modules dir
try (ZipInputStream is = new ZipInputStream(Files.newInputStream(file))) {
ZipEntry entry;
while ((entry = is.getNextEntry()) != null) {
if (entry.getName().startsWith(WEB_MODULE_PREFIX)) {
Path newModule = Common.MA_HOME_PATH.resolve(entry.getName());
Files.copy(is, newModule);
upgraded.add(newModule.getFileName().toString());
}
}
}
} else {
// if its a module move it to the modules folder
if (isModule(file, unsigned)) {
// Its extra work but we better check that it is a module from the store:
Files.move(file, Common.MODULES.resolve(file.getFileName()));
upgraded.add(file.getFileName().toString());
} else {
// Is this a zip of modules?
try (ZipInputStream is = new ZipInputStream(Files.newInputStream(file))) {
ZipEntry entry;
while ((entry = is.getNextEntry()) != null) {
if (entry.getName().startsWith(ModuleUtils.Constants.MODULE_PREFIX)) {
// Extract it and confirm it is a module
Path newModule = tempDir.resolve(entry.getName());
Files.copy(is, newModule);
if (isModule(newModule, unsigned)) {
Files.move(newModule, Common.MODULES.resolve(newModule.getFileName()));
upgraded.add(newModule.getFileName().toString());
}
}
}
}
}
}
}
// Ensure we have some upgrades
if (upgraded.size() == 0 && unsigned.size() == 0) {
throw new BadRequestException(new TranslatableMessage("rest.error.invalidUpgradeFile"));
} else if (upgraded.size() == 0 && unsigned.size() > 0) {
throw new BadRequestException(new TranslatableMessage("modules.unsigned.development"));
}
result.setToUpgrade(upgraded);
List<InvalidModule> invalid = new ArrayList<>();
result.setInvalid(invalid);
for (String u : unsigned) {
invalid.add(new InvalidModule(u, new TranslatableMessage("modules.unsigned.development")));
}
} finally {
FileUtils.deleteDirectory(tempDir.toFile());
}
} finally {
// Release the lock
synchronized (UPLOAD_UPGRADE_LOCK) {
UPLOAD_UPGRADE_IN_PROGRESS = null;
}
}
if (restart && result.getToUpgrade().size() > 0) {
IMangoLifecycle lifecycle = Providers.get(IMangoLifecycle.class);
lifecycle.scheduleShutdown(null, true, Common.getUser());
result.setRestart(restart);
}
return result;
}
use of com.infiniteautomation.mango.rest.latest.exception.BadRequestException in project ma-modules-public by infiniteautomation.
the class EventTypesRestController method getEventTypesForSubtype.
/**
* Generate a list of all event types generalized by sub-type
*/
private List<EventTypeVOModel<?, ?, ?>> getEventTypesForSubtype(String typeName, String subtype, PermissionHolder user) throws NotFoundException {
// track if the type was a default type
List<EventTypeVOModel<?, ?, ?>> types = new ArrayList<>();
boolean found = false;
switch(typeName) {
case EventTypeNames.DATA_POINT:
// There is no subtype for data points
if (subtype != null)
throw new BadRequestException();
// Get Event Detectors, ensure only 1 data point in list
// TODO via query instead
List<AbstractPointEventDetectorVO> detectors = this.eventDetectorDao.getAllPointEventDetectors();
Map<Integer, DataPointVO> uniquePointsMap = new HashMap<>();
for (AbstractPointEventDetectorVO detector : detectors) {
uniquePointsMap.put(detector.getDataPoint().getId(), detector.getDataPoint());
}
for (DataPointVO vo : uniquePointsMap.values()) {
// Shortcut to check permissions via event type
if (dataPointService.hasReadPermission(user, vo)) {
DataPointEventTypeModel model = new DataPointEventTypeModel(new DataPointEventType(vo.getDataSourceId(), vo.getId(), 0, null), modelMapper.map(vo, DataPointModel.class, user));
types.add(new EventTypeVOModel<DataPointEventType, DataPointModel, AbstractPointEventDetectorModel<?>>(model, new TranslatableMessage("event.eventsFor", vo.getName()), false, true, true));
}
}
found = true;
break;
case EventTypeNames.DATA_SOURCE:
// There is no subtype for data sources
if (subtype != null)
throw new BadRequestException();
for (DataSourceVO vo : dataSourceDao.getAll()) {
if (permissionService.hasPermission(user, vo.getReadPermission())) {
AbstractDataSourceModel<?> dsModel = modelMapper.map(vo, AbstractDataSourceModel.class, user);
DataSourceEventTypeModel model = new DataSourceEventTypeModel(new DataSourceEventType(vo.getId(), 0), dsModel);
types.add(new EventTypeVOModel<DataSourceEventType, AbstractDataSourceModel<?>, String>(model, new TranslatableMessage("event.eventsFor", vo.getName()), false, true, true));
}
}
found = true;
break;
case EventTypeNames.PUBLISHER:
// There is no subtype for publishers
if (subtype != null)
throw new BadRequestException();
// There are no permissions for publishers
if (!permissionService.hasAdminRole(user))
break;
for (PublisherVO vo : publisherDao.getAll()) {
AbstractPublisherModel<?, ?> publisherModel = modelMapper.map(vo, AbstractPublisherModel.class, user);
PublisherEventTypeModel model = new PublisherEventTypeModel(new PublisherEventType(vo.getId(), 0), publisherModel);
types.add(new EventTypeVOModel<PublisherEventType, AbstractPublisherModel<?, ?>, String>(model, new TranslatableMessage("event.eventsFor", vo.getName()), false, true, true));
}
found = true;
break;
case EventTypeNames.SYSTEM:
// System
for (SystemEventTypeDefinition def : ModuleRegistry.getDefinitions(SystemEventTypeDefinition.class)) {
if (!StringUtils.equals(def.getTypeName(), subtype))
continue;
found = true;
for (EventTypeVO type : def.generatePossibleEventTypesWithReferenceId1(user, subtype)) {
SystemEventType eventType = (SystemEventType) type.getEventType();
SystemEventTypeModel model = modelMapper.map(eventType, SystemEventTypeModel.class, user);
types.add(new EventTypeVOModel<>(model, type.getDescription(), type.getAlarmLevel(), true, def.supportsReferenceId1(), def.supportsReferenceId2()));
}
break;
}
break;
case EventTypeNames.AUDIT:
// Audit does not yet support reference id 1
throw new BadRequestException();
}
if (!found) {
// Module defined
for (EventTypeDefinition def : ModuleRegistry.getDefinitions(EventTypeDefinition.class)) {
if (StringUtils.equals(typeName, def.getTypeName())) {
found = true;
for (EventTypeVO type : def.generatePossibleEventTypesWithReferenceId1(user, subtype, permissionService)) {
EventType eventType = type.getEventType();
AbstractEventTypeModel<?, ?, ?> model = modelMapper.map(eventType, AbstractEventTypeModel.class, user);
types.add(new EventTypeVOModel<>(model, type.getDescription(), type.getAlarmLevel(), def.supportsSubType(), def.supportsReferenceId1(), def.supportsReferenceId2()));
}
break;
}
}
}
if (!found)
throw new NotFoundException();
return types;
}
use of com.infiniteautomation.mango.rest.latest.exception.BadRequestException in project ma-modules-public by infiniteautomation.
the class ServerRestController method acceptLicenseAgreement.
@ApiOperation(value = "Accept the current license agreement.", notes = "Only valid if the current license agreement has not been accepted. If you do not accept, Mango will restart in 15 seconds, giving you a 2nd chance in case you change your mind.")
@ApiResponses({ @ApiResponse(code = 400, message = "License already accepted.") })
@RequestMapping(method = { RequestMethod.POST }, value = "/accept-license-agreement")
public void acceptLicenseAgreement(@ApiParam(value = "Agree or not", required = true, allowMultiple = false) @RequestParam Boolean agree, @AuthenticationPrincipal PermissionHolder user) {
if (agree) {
systemSettingsDao.setIntValue(SystemSettingsDao.LICENSE_AGREEMENT_VERSION, Common.getLicenseAgreementVersion());
} else {
if (Common.getLicenseAgreementVersion() == systemSettingsDao.getIntValue(SystemSettingsDao.LICENSE_AGREEMENT_VERSION))
throw new BadRequestException(new TranslatableMessage("systemSettings.licenseAlreadyAgreed"));
// Start shutdown timer
log.error("Mango will restart in 15 seconds.");
Providers.get(IMangoLifecycle.class).scheduleShutdown(15000L, true, user);
}
}
use of com.infiniteautomation.mango.rest.latest.exception.BadRequestException in project ma-modules-public by infiniteautomation.
the class PublishedPointsRestController method bulkPublishedPointOperation.
@ApiOperation(value = "Bulk get/create/update/delete published points", notes = "User be superadmin")
@RequestMapping(method = RequestMethod.POST, value = "/bulk")
public ResponseEntity<TemporaryResource<PublishedPointBulkResponse, AbstractRestException>> bulkPublishedPointOperation(@RequestBody PublishedPointBulkRequest requestBody, UriComponentsBuilder builder) {
VoAction defaultAction = requestBody.getAction();
AbstractPublishedPointModel<?> defaultBody = requestBody.getBody();
List<PublishedPointIndividualRequest> requests = requestBody.getRequests();
if (requests == null) {
throw new BadRequestException(new TranslatableMessage("rest.error.mustNotBeNull", "requests"));
} else if (requests.isEmpty()) {
throw new BadRequestException(new TranslatableMessage("rest.error.cantBeEmpty", "requests"));
}
String resourceId = requestBody.getId();
Long expiration = requestBody.getExpiration();
Long timeout = requestBody.getTimeout();
TemporaryResource<PublishedPointBulkResponse, AbstractRestException> responseBody = resourceManager.newTemporaryResource(RESOURCE_TYPE_BULK_PUBLISHED_POINT, resourceId, expiration, timeout, (resource) -> {
PublishedPointBulkResponse bulkResponse = new PublishedPointBulkResponse();
int i = 0;
resource.progressOrSuccess(bulkResponse, i++, requests.size());
PermissionHolder resourceUser = Common.getUser();
for (PublishedPointIndividualRequest request : requests) {
UriComponentsBuilder reqBuilder = UriComponentsBuilder.newInstance();
PublishedPointIndividualResponse individualResponse = doIndividualRequest(request, defaultAction, defaultBody, resourceUser, reqBuilder);
bulkResponse.addResponse(individualResponse);
resource.progressOrSuccess(bulkResponse, i++, requests.size());
}
return null;
});
HttpHeaders headers = new HttpHeaders();
headers.setLocation(builder.path("/published-points/bulk/{id}").buildAndExpand(responseBody.getId()).toUri());
return new ResponseEntity<>(responseBody, headers, HttpStatus.CREATED);
}
use of com.infiniteautomation.mango.rest.latest.exception.BadRequestException in project ma-modules-public by infiniteautomation.
the class DataPointRestController method doIndividualRequest.
private DataPointIndividualResponse doIndividualRequest(DataPointIndividualRequest request, VoAction defaultAction, DataPointModel defaultBody, PermissionHolder user, UriComponentsBuilder builder) {
DataPointIndividualResponse result = new DataPointIndividualResponse();
try {
String xid = request.getXid();
result.setXid(xid);
VoAction action = request.getAction() == null ? defaultAction : request.getAction();
if (action == null) {
throw new BadRequestException(new TranslatableMessage("rest.error.mustNotBeNull", "action"));
}
result.setAction(action);
DataPointModel body = request.getBody() == null ? defaultBody : request.getBody();
switch(action) {
case GET:
if (xid == null) {
throw new BadRequestException(new TranslatableMessage("rest.error.mustNotBeNull", "xid"));
}
result.setBody(this.getDataPoint(xid, user));
break;
case CREATE:
if (body == null) {
throw new BadRequestException(new TranslatableMessage("rest.error.mustNotBeNull", "body"));
}
result.setBody(body);
result.setBody(this.createDataPoint(body, user, builder).getBody());
break;
case UPDATE:
if (xid == null) {
throw new BadRequestException(new TranslatableMessage("rest.error.mustNotBeNull", "xid"));
}
if (body == null) {
throw new BadRequestException(new TranslatableMessage("rest.error.mustNotBeNull", "body"));
}
result.setBody(body);
result.setBody(this.updateDataPoint(xid, body, user, builder).getBody());
break;
case DELETE:
if (xid == null) {
throw new BadRequestException(new TranslatableMessage("rest.error.mustNotBeNull", "xid"));
}
result.setBody(this.deleteDataPoint(xid, user));
break;
}
} catch (Exception e) {
result.exceptionCaught(e);
}
return result;
}
Aggregations