use of com.serotonin.m2m2.module.Module 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 void uploadUpgrades(@ApiParam(value = "Restart after upload completes", required = false, defaultValue = "false", allowMultiple = false) @RequestParam(required = false, defaultValue = "false") boolean restart, MultipartHttpServletRequest multipartRequest) throws IOException {
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"));
}
}
try {
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.
File tempDir = new File(Common.MA_HOME, ModuleUtils.DOWNLOAD_DIR);
if (!tempDir.exists())
tempDir.mkdirs();
// Delete anything that is currently the temp directory.
FileUtils.cleanDirectory(tempDir);
try {
// Save the upload(s) to the temp dir
for (MultipartFile file : files) {
File newFile = new File(tempDir, file.getOriginalFilename());
try (FileOutputStream fos = new FileOutputStream(newFile)) {
org.springframework.util.StreamUtils.copy(file.getInputStream(), fos);
}
}
String[] potentialUpgrades = tempDir.list(new FilenameFilter() {
public boolean accept(File dir, String name) {
if (name.endsWith(".zip"))
return true;
else
return false;
}
});
boolean didUpgrade = false;
for (String potentialUpgrade : potentialUpgrades) {
File file = new File(tempDir, potentialUpgrade);
boolean core = false;
boolean hasWebModules = false;
try (FileInputStream fis = new FileInputStream(file)) {
// Test to see if it is a core or a bundle of only zips or many zip files
try (ZipInputStream is = new ZipInputStream(fis)) {
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 {
if ("release.signed".equals(entry.getName())) {
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, new File(coreDir, "m2m2-core-upgrade.zip"));
didUpgrade = true;
} else if (hasWebModules) {
// This is a zip with modules in web/modules move them all out into the MA_HOME/web/modules dir
try (FileInputStream fis = new FileInputStream(file)) {
try (ZipInputStream is = new ZipInputStream(fis)) {
ZipEntry entry;
while ((entry = is.getNextEntry()) != null) {
if (entry.getName().startsWith(WEB_MODULE_PREFIX)) {
File newModule = new File(coreDir, entry.getName());
try (FileOutputStream fos = new FileOutputStream(newModule)) {
org.springframework.util.StreamUtils.copy(is, fos);
}
didUpgrade = true;
}
}
}
}
} else {
// if its a module move it to the modules folder
if (potentialUpgrade.startsWith(ModuleUtils.Constants.MODULE_PREFIX)) {
// Its extra work but we better check that it is a module from the store:
didUpgrade = maybeCopyModule(file);
} else {
// Is this a zip of modules?
try (FileInputStream fis = new FileInputStream(file)) {
try (ZipInputStream is = new ZipInputStream(fis)) {
ZipEntry entry;
while ((entry = is.getNextEntry()) != null) {
if (entry.getName().startsWith(ModuleUtils.Constants.MODULE_PREFIX)) {
// Extract it and confirm it is a module
File newModule = new File(tempDir, entry.getName());
try (FileOutputStream fos = new FileOutputStream(newModule)) {
org.springframework.util.StreamUtils.copy(is, fos);
}
didUpgrade = maybeCopyModule(newModule);
}
}
}
}
}
}
}
// Ensure we have some upgrades
if (!didUpgrade)
throw new BadRequestException(new TranslatableMessage("rest.error.invalidUpgradeFile"));
} finally {
FileUtils.deleteDirectory(tempDir);
}
} finally {
// Release the lock
synchronized (UPLOAD_UPGRADE_LOCK) {
UPLOAD_UPGRADE_IN_PROGRESS = null;
}
}
if (restart)
ModulesDwr.scheduleRestart();
}
use of com.serotonin.m2m2.module.Module in project ma-modules-public by infiniteautomation.
the class ModulesRestController method getUpgrades.
@ApiOperation(value = "Get Available Upgrades", notes = "Check the store for Upgrades")
@RequestMapping(method = RequestMethod.GET, value = "/upgrades-available", produces = { "application/json" })
public ResponseEntity<ModuleUpgradesModel> getUpgrades(HttpServletRequest request) {
RestProcessResult<ModuleUpgradesModel> result = new RestProcessResult<ModuleUpgradesModel>(HttpStatus.OK);
User user = this.checkUser(request, result);
if (result.isOk()) {
if (Permissions.hasAdmin(user)) {
// Do the check
try {
JsonValue jsonResponse = ModulesDwr.getAvailableUpgrades();
if (jsonResponse instanceof JsonString) {
result.addRestMessage(getInternalServerErrorMessage(jsonResponse.toString()));
} else {
List<ModuleUpgradeModel> upgrades = new ArrayList<>();
List<ModuleUpgradeModel> newInstalls = new ArrayList<>();
ModuleUpgradesModel model = new ModuleUpgradesModel(upgrades, newInstalls);
JsonObject root = jsonResponse.toJsonObject();
JsonValue jsonUpgrades = root.get("upgrades");
JsonArray jsonUpgradesArray = jsonUpgrades.toJsonArray();
Iterator<JsonValue> it = jsonUpgradesArray.iterator();
while (it.hasNext()) {
JsonValue v = it.next();
if (v.getJsonValue("name") == null) {
it.remove();
continue;
}
String name = v.getJsonValue("name").toString();
Module module = "core".equals(name) ? ModuleRegistry.getCoreModule() : ModuleRegistry.getModule(name);
if (module == null) {
it.remove();
continue;
}
upgrades.add(new ModuleUpgradeModel(module, v));
}
JsonValue jsonInstalls = root.get("newInstalls");
JsonArray jsonInstallsArray = jsonInstalls.toJsonArray();
for (JsonValue v : jsonInstallsArray) {
newInstalls.add(new ModuleUpgradeModel(v));
}
return result.createResponseEntity(model);
}
} catch (SocketTimeoutException e) {
result.addRestMessage(HttpStatus.INTERNAL_SERVER_ERROR, new TranslatableMessage("rest.error.requestTimeout", Common.envProps.getString("store.url")));
} catch (UnknownHostException e) {
result.addRestMessage(HttpStatus.INTERNAL_SERVER_ERROR, new TranslatableMessage("rest.error.unknownHost", Common.envProps.getString("store.url")));
} catch (Exception e) {
result.addRestMessage(getInternalServerErrorMessage(e.getMessage()));
}
} else {
result.addRestMessage(this.getUnauthorizedMessage());
}
}
return result.createResponseEntity();
}
use of com.serotonin.m2m2.module.Module in project ma-modules-public by infiniteautomation.
the class ModulesRestController method listMissingModuleDependencies.
@ApiOperation(value = "List Current Missing Module Dependencies", notes = "List all installed")
@RequestMapping(method = RequestMethod.GET, value = "/list-missing-dependencies", produces = { "application/json" })
public ResponseEntity<Map<String, String>> listMissingModuleDependencies(HttpServletRequest request) {
RestProcessResult<Map<String, String>> result = new RestProcessResult<>(HttpStatus.OK);
User user = this.checkUser(request, result);
if (result.isOk()) {
if (Permissions.hasAdmin(user)) {
return result.createResponseEntity(ModuleRegistry.getMissingDependencies());
} else {
result.addRestMessage(this.getUnauthorizedMessage());
}
}
return result.createResponseEntity();
}
use of com.serotonin.m2m2.module.Module in project ma-modules-public by infiniteautomation.
the class ModulesRestController method getUpdateLicensePayload.
@PreAuthorize("isAdmin()")
@ApiOperation(value = "Get the update license payload, to make requests to store", notes = "Admin Only")
@RequestMapping(method = RequestMethod.GET, value = "/update-license-payload")
public ResponseEntity<UpdateLicensePayloadModel> getUpdateLicensePayload(@ApiParam(value = "Set content disposition to attachment", required = false, defaultValue = "true", allowMultiple = false) @RequestParam(required = false, defaultValue = "false") boolean download, HttpServletRequest request) {
Map<String, String> jsonModules = new HashMap<>();
List<Module> modules = ModuleRegistry.getModules();
Module.sortByName(modules);
Module core = ModuleRegistry.getCoreModule();
modules.add(0, core);
for (Module module : modules) {
if (!module.isMarkedForDeletion())
jsonModules.put(module.getName(), module.getVersion().toString());
}
// Add in the unloaded modules so we don't re-download them if we don't have to
for (Module module : ModuleRegistry.getUnloadedModules()) if (!module.isMarkedForDeletion())
jsonModules.put(module.getName(), module.getVersion().toString());
String storeUrl = Common.envProps.getString("store.url");
int upgradeVersionState = SystemSettingsDao.getIntValue(SystemSettingsDao.UPGRADE_VERSION_STATE);
int currentVersionState = UpgradeVersionState.DEVELOPMENT;
Properties props = new Properties();
File propFile = new File(Common.MA_HOME + File.separator + "release.properties");
try {
if (propFile.exists()) {
InputStream in;
in = new FileInputStream(propFile);
try {
props.load(in);
} finally {
in.close();
}
String versionState = props.getProperty("versionState");
try {
if (versionState != null)
currentVersionState = Integer.valueOf(versionState);
} catch (NumberFormatException e) {
}
}
} catch (IOException e1) {
// Ignore
}
HttpHeaders responseHeaders = new HttpHeaders();
responseHeaders.set(HttpHeaders.CONTENT_DISPOSITION, download ? "attachment" : "inline");
return new ResponseEntity<>(new UpdateLicensePayloadModel(Providers.get(ICoreLicense.class).getGuid(), SystemSettingsDao.getValue(SystemSettingsDao.INSTANCE_DESCRIPTION), Common.envProps.getString("distributor"), jsonModules, storeUrl, upgradeVersionState, currentVersionState), responseHeaders, HttpStatus.OK);
}
use of com.serotonin.m2m2.module.Module in project ma-modules-public by infiniteautomation.
the class ReportWorkItem method execute.
@Override
public void execute() {
try {
ReportLicenseChecker.checkLicense();
} catch (LicenseViolatedException e) {
LOG.error("Your core license doesn't permit you to use the reports module.");
reportInstance.setReportStartTime(Common.timer.currentTimeMillis());
reportInstance.setReportEndTime(Common.timer.currentTimeMillis());
reportInstance.setRecordCount(-1);
reportDao.saveReportInstance(reportInstance);
return;
}
LOG.debug("Running report with id " + reportConfig.getId() + ", instance id " + reportInstance.getId());
reportInstance.setRunStartTime(System.currentTimeMillis());
reportDao.saveReportInstance(reportInstance);
Translations translations = Common.getTranslations();
// Create a list of DataPointVOs to which the user has permission.
DataPointDao dataPointDao = DataPointDao.instance;
List<ReportDao.PointInfo> points = new ArrayList<ReportDao.PointInfo>(reportConfig.getPoints().size());
for (ReportPointVO reportPoint : reportConfig.getPoints()) {
DataPointVO point = dataPointDao.getDataPoint(reportPoint.getPointId());
if (point != null && Permissions.hasDataPointReadPermission(user, point)) {
String colour = null;
try {
if (!StringUtils.isBlank(reportPoint.getColour()))
colour = ColorUtils.toHexString(reportPoint.getColour()).substring(1);
} catch (InvalidArgumentException e) {
// Should never happen since the colour would have been validated on save, so just let it go
// as null.
}
points.add(new ReportDao.PointInfo(point, colour, reportPoint.getWeight(), reportPoint.isConsolidatedChart(), reportPoint.getPlotType()));
}
}
int recordCount = 0;
try {
if (!points.isEmpty()) {
if (Common.databaseProxy.getNoSQLProxy() == null)
recordCount = reportDao.runReportSQL(reportInstance, points);
else
recordCount = reportDao.runReportNoSQL(reportInstance, points);
}
} catch (RuntimeException e) {
recordCount = -1;
throw e;
} catch (Throwable e) {
recordCount = -1;
throw new RuntimeException("Report instance failed", e);
} finally {
reportInstance.setRunEndTime(System.currentTimeMillis());
reportInstance.setRecordCount(recordCount);
reportDao.saveReportInstance(reportInstance);
}
if (reportConfig.isEmail()) {
String inlinePrefix = "R" + System.currentTimeMillis() + "-" + reportInstance.getId() + "-";
// TODO should we create different instances of the email based upon language and timezone?
// We are creating an email from the result. Create the content.
final ReportChartCreator creator = new ReportChartCreator(translations, TimeZone.getDefault());
creator.createContent(host, port, reportInstance, reportDao, inlinePrefix, reportConfig.isIncludeData());
// Create the to list
Set<String> addresses = MailingListDao.instance.getRecipientAddresses(reportConfig.getRecipients(), new DateTime(reportInstance.getReportStartTime()));
String[] toAddrs = addresses.toArray(new String[0]);
// Create the email content object.
EmailContent emailContent = new EmailContent(null, creator.getHtml(), Common.UTF8);
// Add the consolidated chart
if (creator.getImageData() != null)
emailContent.addInline(new EmailInline.ByteArrayInline(inlinePrefix + ReportChartCreator.IMAGE_CONTENT_ID, creator.getImageData(), ImageChartUtils.getContentType()));
// Add the point charts
for (PointStatistics pointStatistics : creator.getPointStatistics()) {
if (pointStatistics.getImageData() != null)
emailContent.addInline(new EmailInline.ByteArrayInline(inlinePrefix + pointStatistics.getChartName(), pointStatistics.getImageData(), ImageChartUtils.getContentType()));
}
// Add optional images used by the template.
for (String s : creator.getInlineImageList()) addImage(emailContent, s);
// Check if we need to attach the data.
if (reportConfig.isIncludeData()) {
addFileAttachment(emailContent, reportInstance.getName() + ".csv", creator.getExportFile());
addFileAttachment(emailContent, reportInstance.getName() + "Events.csv", creator.getEventFile());
addFileAttachment(emailContent, reportInstance.getName() + "Comments.csv", creator.getCommentFile());
}
PostEmailRunnable[] postEmail = null;
if (reportConfig.isIncludeData()) {
// See that the temp file(s) gets deleted after the email is sent.
PostEmailRunnable deleteTempFile = new PostEmailRunnable() {
@Override
public void run() {
for (File file : filesToDelete) {
if (!file.delete())
LOG.warn("Temp file " + file.getPath() + " not deleted");
}
}
};
postEmail = new PostEmailRunnable[] { deleteTempFile };
}
try {
TranslatableMessage lm = new TranslatableMessage("ftl.scheduledReport", reportConfig.getName());
String subject = creator.getSubject();
if (subject == null)
subject = lm.translate(translations);
EmailWorkItem.queueEmail(toAddrs, subject, emailContent, postEmail);
} catch (AddressException e) {
LOG.error(e);
}
if (reportConfig.isSchedule()) {
// Delete the report instance.
reportDao.deleteReportInstance(reportInstance.getId(), user.getId());
}
}
LOG.debug("Finished running report with id " + reportConfig.getId() + ", instance id " + reportInstance.getId());
}
Aggregations