package art.servers.transactionsserver; import art.library.gui.flat.FlatDialog; import art.library.interop.InteropParameter; import art.library.interop.InteropParameters; import art.library.interop.InteropResponse; import art.library.interop.serialization.Serialization; import art.library.interop.serialization.SerializationException; import art.library.model.devices.Device; import art.library.model.devices.DevicePersistenceHistorical; import art.library.model.devices.DevicePersistenceTimeless; import art.library.model.devices.application.Application; import art.library.model.devices.user.User; import art.library.model.devices.user.UserAlarmConfiguration; import art.library.model.devices.user.UserConfiguration; import art.library.model.devices.user.UserInformation; import art.library.model.devices.user.UserPermission; import art.library.model.transactions.alarms.AlarmInformation; import art.library.model.transactions.permissions.ListPermission; import art.library.model.transactions.permissions.PermissionFeature; import art.library.persistence.Persistence; import art.library.utils.licence.Licence; import art.library.utils.resources.Resources; import art.servers.ServerException; import art.servers.configuration.Configuration; import art.servers.transactionsserver.controller.ControllerTransactions; import art.servers.transactionsserver.model.access.ModelPermissions; import art.servers.transactionsserver.model.access.ModelSessions; import art.servers.transactionsserver.model.access.ModelUsers; import art.servers.transactionsserver.model.access.login.BlockingNotificationEmailSender; import art.servers.transactionsserver.model.access.login.LoginBlockedManager; import art.servers.transactionsserver.model.alarms.ModelAlarms; import art.servers.transactionsserver.model.configuration.ModelMessages; import art.servers.transactionsserver.model.gis.ModelConfigurationGeoline; import art.servers.transactionsserver.model.gis.ModelExternalLayers; import art.servers.transactionsserver.model.objects.ModelCrudObject; import art.servers.transactionsserver.model.video.ModelVideo; import art.servers.transactionsserver.model.vms.ModelVmsMessagesLibrary; import art.servers.transactionsserver.model.vms.ModelVmsPictogramsLibrary; import java.io.File; import java.io.PrintWriter; import java.io.StringWriter; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.Calendar; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; import java.util.stream.Collectors; public class Model extends art.servers.Model { public ModelUsers modelUsers; public ModelSessions modelSessions; public ModelPermissions modelPermissions; public ModelAlarms modelAlarms; public ModelMessages modelMessages; public ModelExternalLayers modelExternalLayers; public ModelConfigurationGeoline modelConfigurationGeoline; public ModelVmsMessagesLibrary modelVmsMessagesLibrary; public ModelVmsPictogramsLibrary modelVmsPictogramsLibrary; public ModelVideo modelVideo; public ModelCrudObject modelCrudObject; public LoginBlockedManager loginBlockedManager; public ControllerTransactions controllerTransactions; public BlockingNotificationEmailSender blockingNotificationEmailSender; public Model(Configuration configuration) throws Exception { super(configuration, null, User.class.getName(), UserInformation.class.getName()); try { modelUsers = new ModelUsers(); modelSessions = new ModelSessions(); modelPermissions = new ModelPermissions(); modelAlarms = new ModelAlarms(); modelMessages = new ModelMessages(); modelConfigurationGeoline = new ModelConfigurationGeoline(); modelExternalLayers = new ModelExternalLayers(); modelVmsMessagesLibrary = new ModelVmsMessagesLibrary(); modelVmsPictogramsLibrary = new ModelVmsPictogramsLibrary(); modelVideo = new ModelVideo(); modelCrudObject = new ModelCrudObject(); blockingNotificationEmailSender = new BlockingNotificationEmailSender(configuration.lsmtp, ((art.servers.transactionsserver.configuration.Configuration)configuration).loginBlockedManager.lnotificationMail); loginBlockedManager = new LoginBlockedManager(((art.servers.transactionsserver.configuration.Configuration)configuration).loginBlockedManager, blockingNotificationEmailSender); } catch (Exception e) { e.printStackTrace(); throw e; } } public void initializeRootUser() throws Exception { InteropParameters parameters = new InteropParameters(); parameters.addParameter(new InteropParameter("language", Shared.configuration.general.language)); InteropResponse response = modelPermissions.getPermissions(parameters); ListPermission lPermission = (ListPermission) response.getValue()[0]; //If user is not in the json configuration file do nothing //User user = Shared.getConfiguration().administrator; User user = (User) Shared.getModel().getDevice(Licence.encrypt("root")); if (user != null) { user.information.setCreationTimestamp(configurationSymbolsTimestamp); user.configuration = new UserConfiguration(); user.getDeviceConfiguration().permissions = new UserPermission(); //USER PERMISSIONS List lPermissionFeature = lPermission.permissionsFeature; user.getDeviceConfiguration().permissions.lPermissionFeature.addAll(lPermissionFeature); //USER ALARMS AlarmInformation[] aAlarm; try { response = modelAlarms.getAlarmsInformation(parameters); aAlarm = Arrays.copyOf(response.getValue(), response.getValue().length, AlarmInformation[].class); } catch (Exception e) { String msg = "error getting alarms configuration"; initializeAlarmsInformation(); } finally { response = modelAlarms.getAlarmsInformation(parameters); aAlarm = Arrays.copyOf(response.getValue(), response.getValue().length, AlarmInformation[].class); } user.getDeviceConfiguration().lalarmConfiguration = new ArrayList<>(); for (AlarmInformation alarmInformation : aAlarm) { UserAlarmConfiguration alarmUserConfiguration = new UserAlarmConfiguration(); alarmUserConfiguration.clazz = alarmInformation.clazz; alarmUserConfiguration.deviceIdentifier = alarmInformation.deviceIdentifier; alarmUserConfiguration.alarmName = alarmInformation.alarmName; user.getDeviceConfiguration().lalarmConfiguration.add(alarmUserConfiguration); } updateDevice(user); } } private void initializeAlarmsInformation() throws Exception { if (modelAlarms != null) { modelAlarms.generateAlarmsJson(); } } @SuppressWarnings("unchecked") public void readDevices() { mutexListDevices.lockWrite(); try { ldevice.clear(); mdevice.clear(); if (Shared.controllerDatabase != null) { List ldevice = (List) DevicePersistenceTimeless.getDevices((List) (List) Shared.controllerDatabase.timeless_getObject(DevicePersistenceTimeless.class.getName(), "type = '" + User.class.getName() + "'")); for (Device device : ldevice) { //if ((device instanceof User) // && (device.getDeviceInformation().serverPort == Shared.configuration.listener.port) // && (device.getDeviceInformation().serverAddress.equalsIgnoreCase(Shared.configuration.listener.address))) if (device instanceof User) { User user = (User) device; user.information = (UserInformation) user.getDeviceInformation(); user.information.serverAddress = Shared.configuration.listener.address; user.information.serverPort = Shared.configuration.listener.port; user.information.serverAddressExternal = Shared.configuration.listener.addressExternal; user.information.serverPortExternal = Shared.configuration.listener.portExternal; this.ldevice.add(device); this.mdevice.put(device.getIdentifier(), device); } } } } catch (Exception e) { e.printStackTrace(); } finally { } try { UserInformation[] luserInformation = null; if (new File(Shared.getApplicationName() + ".users.json").exists()) { try{luserInformation = (UserInformation[]) Serialization.deserialize(UserInformation[].class, new File(Shared.getApplicationName() + ".users.json"));} catch (Exception e) { Logger.getLogger(Model.class.getName()).log(Level.INFO, "message"); } } else { if (new File("data/" + Shared.getApplicationName() + ".users.json").exists()) { try{luserInformation = (UserInformation[]) Serialization.deserialize(UserInformation[].class, Resources.getResourceStream("data/" + Shared.getApplicationName() + ".users.json"));} catch (Exception e){} } } if (luserInformation != null) { for (UserInformation userInformation : luserInformation) { String password = Licence.encrypt(userInformation.password); String identifier = Licence.encrypt(userInformation.getIdentifier()); if (mdevice.containsKey(identifier) == false) { userInformation.setIdentifier(identifier); userInformation.password = password; addDevice(userInformation); } } } } catch (Exception e) { StringWriter sw = new StringWriter(); e.printStackTrace(new PrintWriter(sw)); FlatDialog.showDialog(null, Shared.getMessage("Error"), e.getMessage() + "\n\n" + sw.toString(), true, FlatDialog.DIALOG_INFORMATION); } mutexListDevices.releaseWrite(); } public void addDevices(UserInformation[] linformation) throws Exception { // Es ineficiente, pero hay que tener en cuenta que es una operación residual mutexListDevices.lockWrite(); try { for (UserInformation information : linformation) { addDevice(information); } } catch (Exception e) { } finally { mutexListDevices.releaseWrite(); } } private void addDevice(UserInformation information) throws Exception { User user = (User) mdevice.get(information.getIdentifier()); long timestamp = System.currentTimeMillis(); if (user == null) { user = new User(information.getIdentifier()); user.information = information; user.information.setCreationTimestamp(timestamp); user.information.serverAddress = Shared.configuration.listener.address; user.information.serverPort = Shared.configuration.listener.port; user.information.serverAddressExternal = Shared.configuration.listener.addressExternal; user.information.serverPortExternal = Shared.configuration.listener.portExternal; user.setLastTimestampInformationUpdate(timestamp); if (Shared.controllerDatabase != null) { Shared.controllerDatabase.timeless_updateOrAddObject(new DevicePersistenceTimeless(user)); try { Shared.controllerDatabase.historical_updateOrAddObject(new DevicePersistenceHistorical(user)); } catch (org.postgresql.util.PSQLException exception) { if ((exception.getMessage().toUpperCase().indexOf("NO PARTITION OF RELATION") > -1) || (exception.getMessage().toUpperCase().indexOf("NO SE ENCONTRÓ UNA PARTICIÓN") > -1)) { try { Calendar calendar1 = Calendar.getInstance(); calendar1.setTimeInMillis(user.getLastTimestampUpdate()); calendar1.set(Calendar.DATE, 1); calendar1.set(Calendar.HOUR_OF_DAY, 0); calendar1.set(Calendar.MINUTE, 0); calendar1.set(Calendar.SECOND, 0); calendar1.set(Calendar.MILLISECOND, 0); SimpleDateFormat formato1 = new SimpleDateFormat("yyyy_MM"); String tablename = "devices_" + formato1.format(calendar1.getTimeInMillis()); long startdate = calendar1.getTimeInMillis(); calendar1.add(Calendar.MONTH, 1); long enddate = calendar1.getTimeInMillis(); String query1 = "CREATE UNLOGGED TABLE IF NOT EXISTS " + tablename + " PARTITION OF devices FOR VALUES FROM ('" + startdate + "') TO ('" + enddate + "')"; try{art.servers.Shared.controllerDatabase.historical_update(query1);} catch (Exception e){}; executeAlterTableDevicesVacuum(true, tablename); // Do again the insert try { art.servers.Shared.controllerDatabase.historical_updateOrAddObject(new DevicePersistenceHistorical(user)); } catch (Exception e) { e.printStackTrace(); } } catch (Exception e) { e.printStackTrace(); } } } } mdevice.put(user.getIdentifier(), user); ldevice.add(user); } else { if (Serialization.equals(user.information, information) == false) { user.information = information; user.setLastTimestampInformationUpdate(timestamp); Shared.controllerDatabase.timeless_updateOrAddObject(new DevicePersistenceTimeless(user)); Shared.controllerDatabase.historical_updateOrAddObject(new DevicePersistenceHistorical(user)); } } } public User[] getDevices(String lusername[], long timestamp) { List luser = new ArrayList<>(); for (String username : lusername) { try { User nextUser = (User) getDevice(username); if ((nextUser.getLastTimestampUpdate() > timestamp) || (nextUser.getLastTimestampUpdate() == 0)) { luser.add(nextUser); } } catch (Exception ex) { } } return luser.toArray(new User[0]); } @SuppressWarnings("unchecked") public List getDevicesUserGenericGroup() { try { List luser = (List) (List) Arrays.asList(getDevices()); List luserAdmin = luser.stream() .filter(u -> u.getDeviceInformation().groupManager == true) .collect(Collectors.toList()); return luserAdmin; } catch (Exception e) { e.printStackTrace(); } return new ArrayList(); } private String decryptUsername(String username) { try { return Licence.decrypt(username); } catch (Exception ex) { Logger.getLogger(Model.class.getName()).log(Level.SEVERE, null, ex); } return ""; } @SuppressWarnings("unchecked") public Application[] getApplications(Long timestamp) throws SerializationException { try { List result = new ArrayList<>(); for (Persistence persistence : Shared.controllerDatabase.getTimelessPersistance()) { List ldevicePersistenceTimeless = (List) (List) persistence.getObject(DevicePersistenceTimeless.class.getName(), "type = '" + Application.class.getName() + "'"); for (DevicePersistenceTimeless devicePersistenceTimeless : ldevicePersistenceTimeless) { Application device = (Application) devicePersistenceTimeless.device; if ((device != null) && (device.getLastTimestampUpdate() > timestamp)) { result.add(device); } } } return result.toArray(new Application[0]); } catch (Exception e) { String msg = "error getting applications"; throw new SerializationException(e.getMessage()); } } }