package art.servers;
|
|
import art.library.gui.flat.FlatDialog;
|
import art.library.interop.serialization.Serialization;
|
import art.library.model.devices.Device;
|
import art.library.model.devices.DeviceAction;
|
import art.library.model.devices.DeviceInformation;
|
import art.library.model.devices.DevicePersistenceAction;
|
import art.library.model.devices.DevicePersistenceHistorical;
|
import art.library.model.devices.DevicePersistenceTimeless;
|
import art.library.model.devices.DeviceRealtime;
|
import art.library.model.devices.DeviceSymbol;
|
import art.library.model.devices.application.Application;
|
import art.library.model.devices.colors.controller.RTZ32.types.eventstrolley.EventTrolley;
|
import art.library.model.devices.colors.controller.RTZ32.types.eventstrolley.EventTrolleyResult;
|
import art.library.model.transactions.traces.Trace;
|
import art.library.model.transactions.traces.TracePersistance;
|
import art.library.model.transactions.traces.TraceResult;
|
import art.library.persistence.Persistence;
|
import art.library.utils.resources.Resources;
|
import art.library.utils.synchro.Mutex;
|
import art.servers.configuration.Configuration;
|
import java.io.File;
|
import java.io.FileOutputStream;
|
import java.io.PrintWriter;
|
import java.io.StringWriter;
|
import java.lang.reflect.Array;
|
import java.lang.reflect.Constructor;
|
import java.nio.file.Files;
|
import java.rmi.ServerException;
|
import java.sql.ResultSet;
|
import java.text.SimpleDateFormat;
|
import java.util.ArrayList;
|
import java.util.Arrays;
|
import java.util.Calendar;
|
import java.util.Collections;
|
import java.util.Comparator;
|
import java.util.HashMap;
|
import java.util.HashSet;
|
import java.util.List;
|
import java.util.Set;
|
|
|
public abstract class Model
|
{
|
public String filename = null;
|
public String deviceClassName = null;
|
public String deviceInformationClassName = null;
|
|
protected List<Device> ldevice = new ArrayList<Device>();
|
protected List<DeviceSymbol> lsymbols = new ArrayList<DeviceSymbol>();
|
protected HashMap<String, Device> mdevice = new HashMap<String, Device>();
|
protected long configurationSymbolsTimestamp = 0;
|
protected Mutex mutexListDevices = new Mutex();
|
protected Mutex mutexListSymbols = new Mutex();
|
protected HashMap<String, Mutex> mmutex = new HashMap<String, Mutex>();
|
|
|
|
public Model(Configuration configuration) throws Exception
|
{
|
}
|
|
|
|
public Model(Configuration configuration, String filename, String deviceClassName, String deviceInformationClassName) throws Exception
|
{
|
this.filename = filename;
|
this.deviceClassName = deviceClassName;
|
this.deviceInformationClassName = deviceInformationClassName;
|
readSymbols();
|
configurationSymbolsTimestamp = System.currentTimeMillis();
|
readDevices();
|
}
|
|
|
|
// <editor-fold defaultstate="collapsed" desc="Devices">
|
|
|
public void clearDevices()
|
{
|
mutexListDevices.lockWrite();
|
{
|
ldevice.clear();
|
mdevice.clear();
|
}
|
mutexListDevices.releaseWrite();
|
}
|
|
|
public void readDevices()
|
{
|
if (filename == null) return;
|
|
mutexListDevices.lockWrite();
|
|
try
|
{
|
|
ldevice.clear();
|
mdevice.clear();
|
|
// Read data from database file (--restore)
|
|
if (Shared.restoreDevices == true)
|
{
|
Class clazzDevice = Class.forName(deviceClassName);
|
Class<?> clazzArray = (Class<?>)Array.newInstance(clazzDevice, 0).getClass();
|
List<Device> ldevice = (List<Device>)Serialization.deserialize(clazzArray, new File(art.servers.Shared.getApplicationName() + "." + filename + ".database.json"));
|
|
for (Device device : ldevice)
|
{
|
if ((device instanceof Device) && (device.information.serverPort == Shared.configuration.listener.port) && (device.information.serverAddress.equalsIgnoreCase(Shared.configuration.listener.address)))
|
{
|
device.information.serverAddress = Shared.configuration.listener.address;
|
device.information.serverPort = Shared.configuration.listener.port;
|
device.information.serverAddressExternal = Shared.configuration.listener.addressExternal;
|
device.information.serverPortExternal = Shared.configuration.listener.portExternal;
|
this.ldevice.add(device);
|
this.mdevice.put(device.getIdentifier(), device);
|
}
|
}
|
}
|
|
// Read data from database
|
|
else if ((Shared.controllerDatabase != null) && (Shared.reloadDevices == false))
|
{
|
Class clazzDevice = Class.forName(deviceClassName);
|
|
List<Device> ldevice = (List<Device>)DevicePersistenceTimeless.getDevices((List<Object>)(List<?>)Shared.controllerDatabase.timeless_getObject(DevicePersistenceTimeless.class.getName(), "type = '" + clazzDevice.getName() + "'"));
|
|
for (Device device : ldevice)
|
{
|
try
|
{
|
if ((device instanceof Device) && (device.information.serverPort == Shared.configuration.listener.port) && (device.information.serverAddress.equalsIgnoreCase(Shared.configuration.listener.address)))
|
{
|
device.information.serverAddress = Shared.configuration.listener.address;
|
device.information.serverPort = Shared.configuration.listener.port;
|
device.information.serverAddressExternal = Shared.configuration.listener.addressExternal;
|
device.information.serverPortExternal = Shared.configuration.listener.portExternal;
|
this.ldevice.add(device);
|
this.mdevice.put(device.getIdentifier(), device);
|
}
|
}
|
catch (Exception exception)
|
{
|
Shared.println(device.getIdentifier(), exception.getMessage());
|
}
|
}
|
}
|
|
}
|
catch (Exception exception)
|
{
|
exception.printStackTrace();
|
StringWriter sw = new StringWriter();
|
exception.printStackTrace(new PrintWriter(sw));
|
FlatDialog.showDialog(null, Shared.getMessage("Error"), exception.getMessage() + "\n\n" + sw.toString(), true, FlatDialog.DIALOG_INFORMATION);
|
System.exit(0);
|
}
|
|
|
|
|
try
|
{
|
Class clazzDevice = Class.forName(deviceClassName);
|
Class clazzInformation = Class.forName(deviceInformationClassName);
|
|
DeviceInformation[] ldeviceInformation = null;
|
|
if (new File(Shared.getApplicationName() + "." + filename + ".json").exists())
|
{
|
Class<?> clazzArray = (Class<?>)Array.newInstance(clazzInformation, 0).getClass();
|
ldeviceInformation = Serialization.deserialize(clazzArray, new File(Shared.getApplicationName() + "." + filename + ".json"));
|
}
|
|
|
for (DeviceInformation deviceInformation : ldeviceInformation)
|
{
|
if (mdevice.containsKey(deviceInformation.getIdentifier()) == false)
|
{
|
addDevice(clazzDevice, deviceInformation);
|
}
|
}
|
}
|
catch (Exception exception)
|
{
|
exception.printStackTrace();
|
StringWriter sw = new StringWriter();
|
exception.printStackTrace(new PrintWriter(sw));
|
FlatDialog.showDialog(null, Shared.getMessage("Error"), exception.getMessage() + "\n\n" + sw.toString(), true, FlatDialog.DIALOG_INFORMATION);
|
System.exit(0);
|
}
|
|
|
|
for (Device device : ldevice)
|
{
|
device.information.serverServiceName = art.servers.Shared.controllerStatus.getApplication().getDeviceInformation().serverServiceName;
|
}
|
|
|
// Sort
|
|
Collections.sort(ldevice, new Comparator<Device>()
|
{
|
public int compare(Device device1, Device device2)
|
{
|
return Integer.valueOf(device1.information.number).compareTo(device2.information.number);
|
}
|
});
|
|
|
// Database file
|
|
if (Shared.restoreDevices == false)
|
{
|
try
|
{
|
|
FileOutputStream fos = new FileOutputStream(new File(art.servers.Shared.getApplicationName() + "." + filename + ".database.json"));
|
|
fos.write("[\n".getBytes());
|
|
for (Device device : ldevice)
|
{
|
fos.write(Serialization.toPrettyString(device).getBytes());
|
if (device != ldevice.get(ldevice.size() - 1)) fos.write(",".getBytes());
|
}
|
|
fos.write("]\n".getBytes());
|
fos.close();
|
}
|
catch (Exception e)
|
{
|
}
|
}
|
|
|
mutexListDevices.releaseWrite();
|
|
}
|
|
|
|
|
|
|
protected void addDevice(Class clazzDevice, DeviceInformation information) throws Exception
|
{
|
Device device = mdevice.get(information.getIdentifier());
|
|
long timestamp = System.currentTimeMillis();
|
|
if (device == null)
|
{
|
Constructor<?> constructor = clazzDevice.getConstructor(String.class);
|
Object object = constructor.newInstance(new Object[]{information.getIdentifier()});
|
device = (Device)object;
|
device.information = information;
|
device.information.setCreationTimestamp(timestamp);
|
device.information.serverAddress = Shared.configuration.listener.address;
|
device.information.serverPort = Shared.configuration.listener.port;
|
device.information.serverAddressExternal = Shared.configuration.listener.addressExternal;
|
device.information.serverPortExternal = Shared.configuration.listener.portExternal;
|
device.setLastTimestampInformationUpdate(timestamp);
|
if (Shared.controllerDatabase != null)
|
{
|
Shared.controllerDatabase.timeless_updateOrAddObject(new DevicePersistenceTimeless(device));
|
|
DevicePersistenceHistorical deviceHistorical = new DevicePersistenceHistorical(device);
|
|
try
|
{
|
Shared.controllerDatabase.historical_addOrUpdateObject(deviceHistorical);
|
}
|
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))
|
{
|
Calendar calendar1 = Calendar.getInstance();
|
calendar1.setTimeInMillis(device.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 TABLE IF NOT EXISTS " + tablename + " PARTITION OF devices FOR VALUES FROM ('" + startdate + "') TO ('" + enddate + "')";
|
try{Shared.controllerDatabase.historical_update(query1);} catch (Exception e){};
|
executeAlterTableDevicesVacuum(true, tablename);
|
|
// Do again the insert
|
try
|
{
|
Shared.controllerDatabase.historical_addOrUpdateObject(deviceHistorical);
|
}
|
catch (Exception e)
|
{
|
Shared.println(Shared.getMessage("Model"), e);
|
}
|
}
|
}
|
}
|
|
mdevice.put(device.getIdentifier(), device);
|
ldevice.add(device);
|
}
|
else
|
{
|
if (Serialization.equals(device.information, information) == false)
|
{
|
device.information = information;
|
device.setLastTimestampInformationUpdate(timestamp);
|
Shared.controllerDatabase.timeless_updateOrAddObject(new DevicePersistenceTimeless(device));
|
|
try
|
{
|
Shared.controllerDatabase.historical_addOrUpdateObject(new DevicePersistenceHistorical(device));
|
}
|
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))
|
{
|
Calendar calendar1 = Calendar.getInstance();
|
calendar1.setTimeInMillis(device.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 TABLE IF NOT EXISTS " + tablename + " PARTITION OF devices FOR VALUES FROM ('" + startdate + "') TO ('" + enddate + "')";
|
try{Shared.controllerDatabase.historical_update(query1);} catch (Exception e){};
|
executeAlterTableDevicesVacuum(true, tablename);
|
|
// Do again the insert
|
try
|
{
|
Shared.controllerDatabase.historical_addOrUpdateObject(new DevicePersistenceHistorical(device));
|
}
|
catch (Exception e)
|
{
|
Shared.println(Shared.getMessage("Model"), e);
|
}
|
}
|
}
|
}
|
}
|
}
|
|
|
public void addDevices(DeviceInformation[] linformation) throws Exception
|
{
|
// Es ineficiente, pero hay que tener en cuenta que es una operación residual
|
|
mutexListDevices.lockWrite();
|
|
try
|
{
|
for (DeviceInformation information : linformation)
|
{
|
addDevice(Class.forName(this.deviceClassName), information);
|
}
|
|
Collections.sort(ldevice, new Comparator<Device>()
|
{
|
public int compare(Device device1, Device device2)
|
{
|
return Integer.valueOf(device1.information.number).compareTo(device2.information.number);
|
}
|
});
|
|
}
|
finally
|
{
|
mutexListDevices.releaseWrite();
|
}
|
}
|
|
|
|
public boolean existsDevice(String identifier)
|
{
|
mutexListDevices.lockRead();
|
|
try
|
{
|
return (mdevice.containsKey(identifier));
|
}
|
finally
|
{
|
mutexListDevices.releaseRead();
|
}
|
}
|
|
|
|
|
|
public Device getDevice(String classname, int number)
|
{
|
for (Device device : ldevice)
|
{
|
if ((device.getClassName().equalsIgnoreCase(classname)) && (device.getDeviceInformation().number == number))
|
{
|
return device;
|
}
|
}
|
|
return null;
|
}
|
|
|
|
|
public Device getDevice(String identifier) throws ServerException
|
{
|
mutexListDevices.lockRead();
|
|
try
|
{
|
Device device = mdevice.get(identifier);
|
|
if (device == null)
|
{
|
throw new ServerException("Device does not exists");
|
}
|
|
return device;
|
}
|
finally
|
{
|
mutexListDevices.releaseRead();
|
}
|
}
|
|
|
|
|
public Device[] getDevices()
|
{
|
mutexListDevices.lockRead();
|
|
try
|
{
|
return ldevice.toArray(new Device[ldevice.size()]);
|
}
|
finally
|
{
|
mutexListDevices.releaseRead();
|
}
|
}
|
|
|
|
|
public Device[] getDevicesCopy()
|
{
|
mutexListDevices.lockRead();
|
|
try
|
{
|
List<Device> result = new ArrayList<Device>();
|
for (Device device : ldevice)
|
{
|
Device clone = Serialization.clone(device);
|
clone.realtime = device.getDeviceRealtime();
|
result.add(clone);
|
}
|
return result.toArray(new Device[result.size()]);
|
}
|
finally
|
{
|
mutexListDevices.releaseRead();
|
}
|
}
|
|
|
|
|
public List<Device> getDevices(String group)
|
{
|
mutexListDevices.lockRead();
|
|
try
|
{
|
List<Device> result = new ArrayList<Device>();
|
|
for (Device device : ldevice)
|
{
|
try
|
{
|
if (device.getDeviceInformation().group.equalsIgnoreCase(group))
|
{
|
result.add(device);
|
}
|
}
|
catch (Exception e)
|
{
|
}
|
}
|
|
return result;
|
|
}
|
finally
|
{
|
mutexListDevices.releaseRead();
|
}
|
}
|
|
|
|
|
public Device[] getDevices(String[] lgroup)
|
{
|
if (lgroup == null)
|
{
|
return new Device[0];
|
}
|
|
if (lgroup.length == 0)
|
{
|
return new Device[0];
|
}
|
|
|
mutexListDevices.lockRead();
|
|
try
|
{
|
List<Device> result = new ArrayList<Device>();
|
|
for (String group : lgroup)
|
{
|
result.addAll(getDevices(group));
|
}
|
|
return result.toArray(new Device[result.size()]);
|
}
|
finally
|
{
|
mutexListDevices.releaseRead();
|
}
|
}
|
|
|
|
public List<Device> getDevicesFromIdentifier(String[] lidentifier)
|
{
|
mutexListDevices.lockRead();
|
|
try
|
{
|
List<Device> result = new ArrayList<Device>();
|
|
for (String identifier : lidentifier)
|
{
|
try
|
{
|
Device device = getDevice(identifier);
|
|
if (device != null)
|
{
|
result.add(device);
|
}
|
}
|
catch (Exception exception)
|
{
|
}
|
}
|
|
return result;
|
}
|
finally
|
{
|
mutexListDevices.releaseRead();
|
}
|
}
|
|
|
|
public Device[] getDevices(long timestamp)
|
{
|
mutexListDevices.lockRead();
|
|
try
|
{
|
List<Device> result = new ArrayList<Device>();
|
|
for (Device device : ldevice)
|
{
|
if (device.getLastTimestampUpdate() > timestamp)
|
{
|
result.add(device);
|
}
|
}
|
|
return result.toArray(new Device[result.size()]);
|
}
|
finally
|
{
|
mutexListDevices.releaseRead();
|
}
|
}
|
|
|
|
public Device[] getDevices(String identifier, long timestamp)
|
{
|
if (identifier == null) return getDevices(timestamp);
|
|
mutexListDevices.lockRead();
|
|
try
|
{
|
List<Device> result = new ArrayList<Device>();
|
|
for (Device device : ldevice)
|
{
|
if (device.getIdentifier().equals(identifier))
|
{
|
if (device.getLastTimestampUpdate() > timestamp)
|
{
|
result.add(device);
|
}
|
}
|
}
|
|
return result.toArray(new Device[result.size()]);
|
}
|
finally
|
{
|
mutexListDevices.releaseRead();
|
}
|
}
|
|
|
|
|
|
public Device[] getDevices(String identifier, long timestamp1, long timestamp2) throws Exception
|
{
|
// Without mutex read, we are consulting historical database and creating new objects
|
|
long timestamp = getLastTimestamp(identifier, timestamp1);
|
String where = "type = '" + deviceClassName + "' AND timestamp >= " + timestamp + " AND timestamp < " + timestamp2;
|
|
if (identifier != null)
|
{
|
if (identifier.length() > 0)
|
{
|
where = where + " AND identifier = '" + identifier + "'";
|
}
|
}
|
|
List<Device> result = (List<Device>)DevicePersistenceHistorical.getDevices((List<Object>)(List<?>)Shared.controllerDatabase.historical_getObject(DevicePersistenceHistorical.class.getName(), where));
|
|
Collections.sort(result, new Comparator<Device>()
|
{
|
public int compare(Device device1, Device device2)
|
{
|
return Integer.valueOf(device1.information.number).compareTo(device2.information.number);
|
}
|
});
|
|
return result.toArray(new Device[result.size()]);
|
}
|
|
|
|
|
public Device[] getDevicesWhen(String identifier, long timestamp) throws Exception
|
{
|
if (identifier == null) return getDevicesWhen(timestamp);
|
|
// Without mutex read, we are consulting historical database and creating new objects
|
|
String where = "type = '" + deviceClassName + "' AND timestamp <= " + timestamp + " AND identifier = '" + identifier + "' ORDER BY timestamp DESC limit 1";
|
List<Device> result = (List<Device>)DevicePersistenceHistorical.getDevices((List<Object>)(List<?>)Shared.controllerDatabase.historical_getObject(DevicePersistenceHistorical.class.getName(), where));
|
|
Collections.sort(result, new Comparator<Device>()
|
{
|
public int compare(Device device1, Device device2)
|
{
|
return Integer.valueOf(device1.information.number).compareTo(device2.information.number);
|
}
|
});
|
|
return result.toArray(new Device[result.size()]);
|
}
|
|
|
|
|
|
public Device[] getDevicesNext(String identifier, long timestamp) throws Exception
|
{
|
if (identifier == null) return getDevicesWhen(timestamp);
|
|
// Without mutex read, we are consulting historical database and creating new objects
|
|
String where = "type = '" + deviceClassName + "' AND timestamp > " + timestamp + " AND identifier = '" + identifier + "' ORDER BY timestamp ASC limit 1";
|
List<Device> result = (List<Device>)DevicePersistenceHistorical.getDevices((List<Object>)(List<?>)Shared.controllerDatabase.historical_getObject(DevicePersistenceHistorical.class.getName(), where));
|
|
Collections.sort(result, new Comparator<Device>()
|
{
|
public int compare(Device device1, Device device2)
|
{
|
return Integer.valueOf(device1.information.number).compareTo(device2.information.number);
|
}
|
});
|
|
return result.toArray(new Device[result.size()]);
|
}
|
|
|
|
|
public Device[] getDevicesWhen(long timestamp) throws Exception
|
{
|
List<Device> result = new ArrayList<Device>();
|
for (Device device : getDevices()) result.addAll(Arrays.asList(getDevicesWhen(device.getIdentifier(), timestamp)));
|
|
Collections.sort(result, new Comparator<Device>()
|
{
|
public int compare(Device device1, Device device2)
|
{
|
return Integer.valueOf(device1.information.number).compareTo(device2.information.number);
|
}
|
});
|
|
return result.toArray(new Device[result.size()]);
|
}
|
|
|
|
|
/**
|
* Get device from external accesses, not from this server memory devices allocation.
|
*/
|
|
|
public Device getDeviceExternal(String identifier) throws Exception
|
{
|
mutexListDevices.lockRead();
|
|
// TODO: Timelessaccess for the moment. In the future we must include direct access to servers using Services pollsters
|
|
try
|
{
|
String where = "identifier = '" + identifier + "'";
|
List<Device> result = (List<Device>)DevicePersistenceTimeless.getDevices((List<Object>)(List<?>)Shared.controllerDatabase.timeless_getObject(DevicePersistenceTimeless.class.getName(), where));
|
return result.get(0);
|
}
|
finally
|
{
|
mutexListDevices.releaseRead();
|
}
|
}
|
|
|
|
/**
|
* Get devices from external accesses, not from this server memory devices allocation.
|
*/
|
|
|
public Device[] getDevicesExternal(String type) throws Exception
|
{
|
mutexListDevices.lockRead();
|
|
try
|
{
|
String where = "type = '" + type + "'";
|
List<Device> result = (List<Device>)DevicePersistenceTimeless.getDevices((List<Object>)(List<?>)Shared.controllerDatabase.timeless_getObject(DevicePersistenceTimeless.class.getName(), where));
|
|
Collections.sort(result, new Comparator<Device>()
|
{
|
public int compare(Device device1, Device device2)
|
{
|
return Integer.valueOf(device1.information.number).compareTo(device2.information.number);
|
}
|
});
|
|
return result.toArray(new Device[result.size()]);
|
}
|
finally
|
{
|
mutexListDevices.releaseRead();
|
}
|
}
|
|
|
|
|
|
public boolean updateDevice(Device currentdevice, Device newdevice)
|
{
|
getMutex(currentdevice).lockWrite();
|
|
boolean different = false;
|
|
try
|
{
|
newdevice.getDeviceInformation().serverAddress = Shared.configuration.listener.address;
|
newdevice.getDeviceInformation().serverPort = Shared.configuration.listener.port;
|
newdevice.getDeviceInformation().serverAddressExternal = Shared.configuration.listener.addressExternal;
|
newdevice.getDeviceInformation().serverPortExternal = Shared.configuration.listener.portExternal;
|
newdevice.getDeviceInformation().serverServiceName = Shared.controllerStatus.getApplication().getDeviceInformation().serverServiceName;
|
|
different = currentdevice.updateDevice(newdevice);
|
|
if ((different == true) && (Shared.configuration.database != null))
|
{
|
Shared.controllerDatabase.timeless_updateOrAddObject(new DevicePersistenceTimeless(currentdevice));
|
}
|
}
|
catch (Exception e)
|
{
|
}
|
finally
|
{
|
getMutex(currentdevice).releaseWrite();
|
}
|
|
// newdevice sabemos que no cambiara porque nadie mas tiene la referencia
|
|
try
|
{
|
if ((different == true) && (Shared.configuration.database != null))
|
{
|
Shared.controllerDatabase.historical_addObject(new DevicePersistenceHistorical(newdevice));
|
}
|
}
|
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))
|
{
|
Calendar calendar1 = Calendar.getInstance();
|
calendar1.setTimeInMillis(newdevice.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 TABLE IF NOT EXISTS " + tablename + " PARTITION OF devices FOR VALUES FROM ('" + startdate + "') TO ('" + enddate + "')";
|
try{Shared.controllerDatabase.historical_update(query1);} catch (Exception e){};
|
executeAlterTableDevicesVacuum(true, tablename);
|
|
// Do again the insert
|
try
|
{
|
Shared.controllerDatabase.historical_addObject(new DevicePersistenceHistorical(newdevice));
|
}
|
catch (Exception e)
|
{
|
Shared.println(Shared.getMessage("Model"), e);
|
}
|
}
|
}
|
catch (Exception e)
|
{
|
}
|
|
return different;
|
}
|
|
|
|
public void updateDevice(Device device)
|
{
|
updateDevice(device, System.currentTimeMillis());
|
}
|
|
|
public void updateDevice(Device device, long timestamp)
|
{
|
getMutex(device).lockWrite();
|
|
try
|
{
|
Device currentDevice = (Device)mdevice.get(device.getIdentifier());
|
|
if (currentDevice == null)
|
{
|
device.getDeviceInformation().setCreationTimestamp(timestamp);
|
device.setLastTimestampInformationUpdate(timestamp);
|
if (device.getDeviceConfiguration() != null)
|
{
|
device.setLastTimestampConfigurationUpdate(timestamp);
|
}
|
|
device.information.serverAddress = Shared.configuration.listener.address;
|
device.information.serverPort = Shared.configuration.listener.port;
|
|
if (Shared.configuration.database != null)
|
{
|
Shared.controllerDatabase.timeless_updateOrAddObject(new DevicePersistenceTimeless(device));
|
|
try
|
{
|
Shared.controllerDatabase.historical_updateOrAddObject(new DevicePersistenceHistorical(device));
|
}
|
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))
|
{
|
Calendar calendar1 = Calendar.getInstance();
|
calendar1.setTimeInMillis(device.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 TABLE IF NOT EXISTS " + tablename + " PARTITION OF devices FOR VALUES FROM ('" + startdate + "') TO ('" + enddate + "')";
|
try{Shared.controllerDatabase.historical_update(query1);} catch (Exception e){};
|
executeAlterTableDevicesVacuum(true, tablename);
|
|
// Do again the insert
|
try
|
{
|
Shared.controllerDatabase.historical_updateOrAddObject(new DevicePersistenceHistorical(device));
|
}
|
catch (Exception e)
|
{
|
Shared.println(Shared.getMessage("Model"), e);
|
}
|
}
|
}
|
}
|
|
mdevice.put(device.getIdentifier(), device);
|
ldevice.add(device);
|
}
|
else
|
{
|
System.out.println("3.UpdateDevice: " + currentDevice);
|
if (currentDevice.updateDevice(device) == true)
|
{
|
System.out.println("4.UpdateDevice: " + currentDevice);
|
if (Shared.configuration.database != null)
|
{
|
Shared.controllerDatabase.timeless_updateOrAddObject(new DevicePersistenceTimeless(device));
|
|
try
|
{
|
Shared.controllerDatabase.historical_updateOrAddObject(new DevicePersistenceHistorical(device));
|
}
|
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))
|
{
|
Calendar calendar1 = Calendar.getInstance();
|
calendar1.setTimeInMillis(device.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 TABLE IF NOT EXISTS " + tablename + " PARTITION OF devices FOR VALUES FROM ('" + startdate + "') TO ('" + enddate + "')";
|
try{Shared.controllerDatabase.historical_update(query1);} catch (Exception e){};
|
executeAlterTableDevicesVacuum(true, tablename);
|
|
// Do again the insert
|
try
|
{
|
Shared.controllerDatabase.historical_updateOrAddObject(new DevicePersistenceHistorical(device));
|
}
|
catch (Exception e)
|
{
|
Shared.println(Shared.getMessage("Model"), e);
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
catch (Exception e)
|
{
|
}
|
finally
|
{
|
getMutex(device).releaseWrite();
|
}
|
}
|
|
|
|
|
public void updateDeviceStatus(Device device, long timestamp)
|
{
|
try
|
{
|
if (device.getLastTimestampStatusUpdate() >= timestamp)
|
{
|
device.setLastTimestampStatusUpdate(device.getLastTimestampStatusUpdate() + 1);
|
}
|
else
|
{
|
device.setLastTimestampStatusUpdate(timestamp);
|
}
|
|
if (Shared.configuration.database != null)
|
{
|
try
|
{
|
Shared.controllerDatabase.historical_updateOrAddObject(new DevicePersistenceHistorical(device));
|
}
|
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))
|
{
|
Calendar calendar1 = Calendar.getInstance();
|
calendar1.setTimeInMillis(device.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 TABLE IF NOT EXISTS " + tablename + " PARTITION OF devices FOR VALUES FROM ('" + startdate + "') TO ('" + enddate + "')";
|
try{Shared.controllerDatabase.historical_update(query1);} catch (Exception e){};
|
executeAlterTableDevicesVacuum(true, tablename);
|
|
// Do again the insert
|
|
try
|
{
|
Shared.controllerDatabase.historical_updateOrAddObject(new DevicePersistenceHistorical(device));
|
}
|
catch (Exception e)
|
{
|
}
|
}
|
}
|
}
|
}
|
catch (Exception e)
|
{
|
}
|
}
|
|
|
|
|
public void forceUpdateDeviceStatus(Device device, long timestamp)
|
{
|
try
|
{
|
device.forceLastTimestampStatusUpdate(timestamp);
|
if (Shared.configuration.database != null)
|
{
|
try
|
{
|
Shared.controllerDatabase.historical_updateOrAddObject(new DevicePersistenceHistorical(device));
|
}
|
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))
|
{
|
Calendar calendar1 = Calendar.getInstance();
|
calendar1.setTimeInMillis(device.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 TABLE IF NOT EXISTS " + tablename + " PARTITION OF devices FOR VALUES FROM ('" + startdate + "') TO ('" + enddate + "')";
|
try{Shared.controllerDatabase.historical_update(query1);} catch (Exception e){};
|
executeAlterTableDevicesVacuum(true, tablename);
|
|
// Do again the insert
|
|
try
|
{
|
Shared.controllerDatabase.historical_updateOrAddObject(new DevicePersistenceHistorical(device));
|
}
|
catch (Exception e)
|
{
|
}
|
}
|
}
|
}
|
}
|
catch (Exception e)
|
{
|
}
|
}
|
|
|
|
|
public void updateDevice(Device[] ldevice)
|
{
|
mutexListDevices.lockWrite();
|
|
try
|
{
|
for (Device device : ldevice)
|
{
|
updateDevice(device);
|
}
|
}
|
catch (Exception e)
|
{
|
}
|
|
mutexListDevices.releaseWrite();
|
}
|
|
|
|
|
|
|
|
|
|
public void deleteDevices(String[] lidentifier) throws Exception
|
{
|
int errors = 0;
|
|
for (String identifier : lidentifier)
|
{
|
getMutex(identifier).lockWrite();
|
|
try
|
{
|
String where = "identifier = '" + identifier + "' AND type = '" + deviceClassName + "'";
|
Shared.controllerDatabase.timeless_deleteObject(DevicePersistenceTimeless.class.getName(), where);
|
|
mutexListDevices.lockWrite();
|
{
|
ldevice.remove(mdevice.remove(identifier));
|
}
|
mutexListDevices.releaseWrite();
|
}
|
catch (Exception e)
|
{
|
errors = errors + 1;
|
}
|
finally
|
{
|
getMutex(identifier).releaseWrite();
|
}
|
}
|
|
if (errors > 0)
|
{
|
throw new ServerException(Shared.getMessage("Error deleting devices"));
|
}
|
}
|
|
|
public Device cloneDevice(String identifier)
|
{
|
// No hace falta mutex porque los devices se cambia la referencia cada vez. No hay conflicto posible
|
|
Device clon = null;
|
|
try
|
{
|
clon = (Device)Serialization.clone(getDevice(identifier));
|
}
|
catch (Exception e)
|
{
|
}
|
|
try
|
{
|
clon.realtime = (DeviceRealtime)Serialization.clone(getDevice(identifier).getDeviceRealtime());
|
}
|
catch (Exception e)
|
{
|
}
|
|
|
|
return clon;
|
}
|
|
|
|
|
public Device cloneDevice(Device device)
|
{
|
try
|
{
|
return cloneDevice(device.getIdentifier());
|
}
|
catch (Exception e)
|
{
|
}
|
|
return null;
|
}
|
|
|
|
|
public List<String> getGroups()
|
{
|
mutexListDevices.lockRead();
|
|
try
|
{
|
Set<String> groups = new HashSet<>();
|
|
for (Device device : ldevice)
|
{
|
try
|
{
|
if (device.getDeviceInformation().group != null)
|
{
|
groups.add(device.getDeviceInformation().group);
|
}
|
}
|
catch (Exception e)
|
{
|
}
|
}
|
|
List<String> result = new ArrayList(groups);
|
result.sort(String::compareToIgnoreCase);
|
return result;
|
}
|
finally
|
{
|
mutexListDevices.releaseRead();
|
}
|
}
|
|
|
|
|
// </editor-fold>
|
|
|
// <editor-fold defaultstate="collapsed" desc="Traces">
|
|
public List<String> getTraceValues(String field, String application) throws Exception
|
{
|
ResultSet resultset = null;
|
Persistence persistence = Shared.controllerDatabase.getHistoricalPersistance().get(0);
|
List<String> result = new ArrayList<String>();
|
|
try
|
{
|
{
|
String command = "SELECT DISTINCT(" + field + ") FROM traces";
|
if (application != null) command = "SELECT DISTINCT(" + field + ") FROM traces WHERE application = '" + application + "'";
|
|
resultset = persistence.executeQuery(command);
|
while (resultset.next())
|
{
|
result.add(resultset.getString(1));
|
}
|
resultset.getStatement().close();
|
resultset.close();
|
}
|
}
|
catch (Exception exception)
|
{
|
throw exception;
|
}
|
finally
|
{
|
try{resultset.getStatement().close();} catch (Exception e){};
|
try{resultset.close();} catch (Exception e){};
|
}
|
|
return result;
|
}
|
|
public List<Trace> getTraces(String language, long timestampfrom, long timestampto, String application, int limit) throws Exception
|
{
|
ResultSet resultset = null;
|
Persistence persistence = Shared.controllerDatabase.getHistoricalPersistance().get(0);
|
|
List<Trace> traces = new ArrayList<Trace>();
|
|
try
|
{
|
String command = "SELECT value FROM traces WHERE timestamp >= " + timestampfrom + " AND timestamp < " + timestampto;
|
if (application != null) command = command + " AND application = '" + application + "'";
|
command = command + " ORDER BY timestamp ASC";
|
if (limit > 0) command = command + " LIMIT " + limit;
|
|
resultset = persistence.executeQuery(command);
|
|
while (resultset.next())
|
{
|
traces.add(((TracePersistance)Serialization.deserialize(TracePersistance.class, resultset.getString(1))).trace);
|
}
|
|
return traces;
|
}
|
finally
|
{
|
try{resultset.getStatement().close();} catch (Exception e){};
|
try{resultset.close();} catch (Exception e){};
|
}
|
}
|
|
|
|
private String getFilterEventController(String filter)
|
{
|
/*
|
|
*/
|
try
|
{
|
String result = filter;
|
|
|
return(result);
|
}
|
catch (Exception e)
|
{
|
e.printStackTrace();
|
}
|
|
return(filter);
|
}
|
|
|
public TraceResult getEventsController(String language, long timestampfrom, long timestampto, int type, int limit, int offset, String filter, boolean viewTrolleyEvents, boolean viewMasterSlaveEvents) throws Exception
|
{
|
ResultSet resultset = null;
|
Persistence persistence = Shared.controllerDatabase.getHistoricalPersistance().get(0);
|
|
TraceResult result = new TraceResult();
|
result.timestampfrom = timestampfrom;
|
result.timestampto = timestampto;
|
result.limit = limit;
|
result.offset = offset;
|
result.type = type;
|
result.traces = new ArrayList<Trace>();
|
|
try
|
{
|
String command = "SELECT COUNT(*) FROM traces WHERE timestamp >= " + timestampfrom + " AND timestamp < " + timestampto;
|
if (type > -1) command = command + " AND type = " + type;
|
// if (filter != null) command = command + " AND " + getFilterEventController(filter.substring(0, filter.indexOf("ORDER")));
|
|
resultset = persistence.executeQuery(command);
|
|
if (resultset.next())
|
{
|
result.total = resultset.getInt(1);
|
}
|
try{resultset.close();} catch (Exception e){};
|
|
command = "SELECT value FROM traces WHERE timestamp >= " + timestampfrom + " AND timestamp < " + timestampto;
|
if (type > -1) command = command + " AND type = " + type;
|
// if (order == 1) command = command + " ORDER BY timestamp ASC";
|
// else if (order == -1) command = command + " ORDER BY timestamp DESC";
|
command = command + " ORDER BY timestamp DESC";
|
// if (filter != null) command = command + " AND " + getFilterEventController(filter);
|
if (limit > 0) command = command + " LIMIT " + limit;
|
if (offset > -1) command = command + " OFFSET " + offset;
|
|
System.out.println(command);
|
|
resultset = persistence.executeQuery(command);
|
|
while (resultset.next())
|
{
|
TracePersistance tracePersistance = Serialization.deserialize(TracePersistance.class, resultset.getString(1));
|
if (tracePersistance.trace != null)
|
{
|
result.traces.add(tracePersistance.trace);
|
}
|
else
|
{
|
Trace trace = Serialization.deserialize(Trace.class, resultset.getString(1));
|
if (trace != null)
|
{
|
result.traces.add(trace);
|
}
|
}
|
}
|
|
return result;
|
}
|
finally
|
{
|
try{resultset.getStatement().close();} catch (Exception e){};
|
try{resultset.close();} catch (Exception e){};
|
}
|
}
|
|
|
|
public TraceResult getTraces(String language, long timestampfrom, long timestampto, int type, int limit, int offset, int order, boolean viewTrolleyEvents, boolean viewMasterSlaveEvents) throws Exception
|
{
|
ResultSet resultset = null;
|
Persistence persistence = Shared.controllerDatabase.getHistoricalPersistance().get(0);
|
|
TraceResult result = new TraceResult();
|
result.timestampfrom = timestampfrom;
|
result.timestampto = timestampto;
|
result.limit = limit;
|
result.offset = offset;
|
result.type = type;
|
result.traces = new ArrayList<Trace>();
|
|
try
|
{
|
String command = "SELECT COUNT(*) FROM traces WHERE timestamp >= " + timestampfrom + " AND timestamp < " + timestampto;
|
if (type > -1) command = command + " AND type = " + type;
|
|
resultset = persistence.executeQuery(command);
|
|
if (resultset.next())
|
{
|
result.total = resultset.getInt(1);
|
}
|
try{resultset.close();} catch (Exception e){};
|
|
command = "SELECT value FROM traces WHERE timestamp >= " + timestampfrom + " AND timestamp < " + timestampto;
|
if (type > -1) command = command + " AND type = " + type;
|
if (order == 1) command = command + " ORDER BY timestamp ASC";
|
else if (order == -1) command = command + " ORDER BY timestamp DESC";
|
if (limit > 0) command = command + " LIMIT " + limit;
|
if (offset > -1) command = command + " OFFSET " + offset;
|
|
System.out.println(command);
|
|
resultset = persistence.executeQuery(command);
|
|
while (resultset.next())
|
{
|
TracePersistance tracePersistance = Serialization.deserialize(TracePersistance.class, resultset.getString(1));
|
if (tracePersistance.trace != null)
|
{
|
result.traces.add(tracePersistance.trace);
|
}
|
else
|
{
|
Trace trace = Serialization.deserialize(Trace.class, resultset.getString(1));
|
if (trace != null)
|
{
|
result.traces.add(trace);
|
}
|
}
|
}
|
|
return result;
|
}
|
finally
|
{
|
try{resultset.getStatement().close();} catch (Exception e){};
|
try{resultset.close();} catch (Exception e){};
|
}
|
}
|
|
|
public TraceResult getTraces(TraceResult traceresult) throws Exception
|
{
|
ResultSet resultset = null;
|
Persistence persistence = Shared.controllerDatabase.getHistoricalPersistance().get(0);
|
|
try
|
{
|
{
|
String command = "SELECT COUNT(*) FROM traces WHERE timestamp >= " + traceresult.timestampfrom + " AND timestamp <= " + traceresult.timestampto;
|
if (traceresult.type != Trace.TRACE_NONE) command = command + " AND type = '" + traceresult.type + "'";
|
if (traceresult.username != null) command = command + " AND username = '" + traceresult.username + "'";
|
if (traceresult.application != null) command = command + " AND application = '" + traceresult.application + "'";
|
if (traceresult.service != null) command = command + " AND service = '" + traceresult.service + "'";
|
resultset = persistence.executeQuery(command);
|
resultset.next();
|
traceresult.total = resultset.getLong(1);
|
resultset.getStatement().close();
|
resultset.close();
|
}
|
{
|
String command = "SELECT value FROM traces WHERE timestamp >= " + traceresult.timestampfrom + " AND timestamp <= " + traceresult.timestampto;
|
if (traceresult.type != Trace.TRACE_NONE) command = command + " AND type = '" + traceresult.type + "'";
|
if (traceresult.username != null) command = command + " AND username = '" + traceresult.username + "'";
|
if (traceresult.application != null) command = command + " AND application = '" + traceresult.application + "'";
|
if (traceresult.service != null) command = command + " AND service = '" + traceresult.service + "'";
|
command = command + " ORDER BY timestamp ASC OFFSET " + traceresult.offset + " LIMIT " + traceresult.limit;
|
resultset = persistence.executeQuery(command);
|
while (resultset.next())
|
{
|
traceresult.traces.add(((TracePersistance)Serialization.deserialize(TracePersistance.class, resultset.getString(1))).trace);
|
}
|
resultset.getStatement().close();
|
resultset.close();
|
}
|
|
}
|
finally
|
{
|
try{resultset.getStatement().close();} catch (Exception e){};
|
try{resultset.close();} catch (Exception e){};
|
}
|
|
|
return traceresult;
|
}
|
|
|
|
|
|
public List<Trace> getLastTraces(String language, String application, int limit) throws Exception
|
{
|
ResultSet resultset = null;
|
Persistence persistence = Shared.controllerDatabase.getHistoricalPersistance().get(0);
|
|
List<Trace> traces = new ArrayList<Trace>();
|
|
try
|
{
|
String command = "SELECT value FROM traces ";
|
if (application != null) command = command + " WHERE application = '" + application + "'";
|
command = command + " ORDER BY timestamp DESC";
|
if (limit > 0) command = command + " LIMIT " + limit;
|
|
resultset = persistence.executeQuery(command);
|
|
while (resultset.next())
|
{
|
traces.add(((TracePersistance)Serialization.deserialize(TracePersistance.class, resultset.getString(1))).trace);
|
}
|
|
return traces;
|
}
|
finally
|
{
|
try{resultset.getStatement().close();} catch (Exception e){};
|
try{resultset.close();} catch (Exception e){};
|
}
|
}
|
|
|
|
|
// </editor-fold>
|
|
|
|
|
public EventTrolleyResult getEventsTrolley(String language, long timestampfrom, long timestampto, int type, int limit, int offset, int order) throws Exception
|
{
|
ResultSet resultset = null;
|
Persistence persistence = Shared.controllerDatabase.getHistoricalPersistance().get(0);
|
|
EventTrolleyResult result = new EventTrolleyResult();
|
result.timestampfrom = timestampfrom;
|
result.timestampto = timestampto;
|
result.limit = limit;
|
result.offset = offset;
|
result.type = type;
|
result.events = new ArrayList<EventTrolley>();
|
|
try
|
{
|
String command = "SELECT COUNT(*) FROM eventstrolley WHERE activation >= " + timestampfrom + " AND activation < " + timestampto;
|
if (type > -1) command = command + " AND type = " + type;
|
|
resultset = persistence.executeQuery(command);
|
|
if (resultset.next())
|
{
|
result.total = resultset.getInt(1);
|
}
|
try{resultset.close();} catch (Exception e){};
|
|
command = "SELECT value FROM eventstrolley WHERE activation >= " + timestampfrom + " AND activation < " + timestampto;
|
if (type > -1) command = command + " AND type = " + type;
|
if (order == 1) command = command + " ORDER BY activation ASC";
|
else if (order == -1) command = command + " ORDER BY activation DESC";
|
if (limit > 0) command = command + " LIMIT " + limit;
|
if (offset > -1) command = command + " OFFSET " + offset;
|
|
System.out.println(command);
|
|
resultset = persistence.executeQuery(command);
|
|
while (resultset.next())
|
{
|
result.events.add(((EventTrolley)Serialization.deserialize(EventTrolley.class, resultset.getString(1))));
|
}
|
|
return result;
|
}
|
finally
|
{
|
try{resultset.getStatement().close();} catch (Exception e){};
|
try{resultset.close();} catch (Exception e){};
|
}
|
}
|
|
|
// <editor-fold defaultstate="collapsed" desc="Symbols">
|
|
public void readSymbols() throws Exception
|
{
|
mutexListSymbols.lockWrite();
|
|
try
|
{
|
// for (int i=0; i<32; i++)
|
for (float i=0; i<32; i+=0.5f)
|
{
|
for (String symbolName : Shared.configuration.symbols)
|
{
|
DeviceSymbol symbol = new DeviceSymbol();
|
symbol.type = deviceClassName;
|
symbol.name = symbolName;
|
symbol.zoom = i;
|
int zoom = (int)i;
|
String resourceName = "data/" + Shared.getApplicationName() + "/symbols/" + i + "/" + symbolName + ".svg";
|
if (zoom == i)
|
{
|
resourceName = "data/" + Shared.getApplicationName() + "/symbols/" + zoom + "/" + symbolName + ".svg";
|
}
|
|
// String resourceName = "data/" + Shared.getApplicationName() + "/symbols/" + i + "/" + symbolName + ".svg";
|
File file = new File(resourceName);
|
|
if (file.exists() == true)
|
{
|
symbol.dataSVG = Files.readAllBytes(file.toPath());
|
}
|
else
|
{
|
symbol.dataSVG = Resources.getResourceBytes(resourceName);
|
}
|
|
if (symbol.dataSVG.length > 0)
|
{
|
lsymbols.add(symbol);
|
}
|
}
|
}
|
}
|
catch (Exception exception)
|
{
|
Shared.println(Shared.getMessage("Model"), exception);
|
}
|
finally
|
{
|
mutexListSymbols.releaseWrite();
|
}
|
}
|
|
|
|
|
public DeviceSymbol[] getSymbols()
|
{
|
mutexListSymbols.lockRead();
|
|
try
|
{
|
return lsymbols.toArray(new DeviceSymbol[lsymbols.size()]);
|
}
|
finally
|
{
|
mutexListSymbols.releaseRead();
|
}
|
}
|
|
|
|
|
public DeviceSymbol[] getSymbols(long timestamp)
|
{
|
if (configurationSymbolsTimestamp > timestamp)
|
{
|
return getSymbols();
|
}
|
else
|
{
|
return new DeviceSymbol[0];
|
}
|
}
|
|
|
|
|
public List<Object> getSymbolsNames(String type)
|
{
|
List<Object> result = new ArrayList<Object> ();
|
|
mutexListSymbols.lockRead();
|
|
try
|
{
|
result.add("");
|
|
for (DeviceSymbol symbol : lsymbols)
|
{
|
if (symbol.type.equalsIgnoreCase(type))
|
{
|
result.add(symbol.name);
|
}
|
}
|
}
|
finally
|
{
|
mutexListSymbols.releaseRead();
|
}
|
|
return result;
|
}
|
|
|
|
|
|
|
// </editor-fold>
|
|
|
// <editor-fold defaultstate="collapsed" desc="Application">
|
|
public Application getApplicationService(String serviceName)
|
{
|
try
|
{
|
Device[] devices = getDevicesExternal(Application.class.getName());
|
|
for (Device device : devices)
|
{
|
if (device instanceof Application)
|
{
|
Application application = (Application)device;
|
|
if (application.getDeviceInformation().serverServiceName.equalsIgnoreCase(serviceName) == true)
|
{
|
return(application);
|
}
|
}
|
}
|
}
|
catch (Exception exception)
|
{
|
}
|
|
return(null);
|
}
|
|
|
|
|
|
|
public Application[] getApplication(long timestamp) throws Exception
|
{
|
Application application = Shared.controllerStatus.getApplication();
|
|
if (application.getLastTimestampUpdate() > timestamp)
|
{
|
return new Application[]{application};
|
}
|
return new Application[0];
|
}
|
|
|
|
|
public Application[] getApplication(long timestamp1, long timestamp2) throws Exception
|
{
|
// Without mutex read, we are consulting historical database
|
|
String identifier = Shared.controllerStatus.getApplication().getIdentifier();
|
String where = "type = '" + deviceClassName + "' AND timestamp > " + timestamp1 + " AND timestamp < " + timestamp2;
|
|
if (identifier != null)
|
{
|
if (identifier.length() > 0)
|
{
|
where = where + " AND identifier = '" + identifier + "'";
|
}
|
}
|
|
List<Device> result = (List<Device>)DevicePersistenceHistorical.getDevices((List<Object>)(List<?>)Shared.controllerDatabase.historical_getObject(DevicePersistenceHistorical.class.getName(), where));
|
return result.toArray(new Application[result.size()]);
|
}
|
|
|
|
|
// A esta función sólo llama el servidor
|
|
public void updateApplication(Application application)
|
{
|
// No metemos en exclusion, no podemos tener varias llamadas a la vez
|
// Se controla en el ControllerStatus
|
|
if (Shared.configuration.database != null)
|
{
|
try { Shared.controllerDatabase.timeless_updateOrAddObject(new DevicePersistenceTimeless(application)); } catch (Exception e) { }
|
|
try
|
{
|
Shared.controllerDatabase.historical_updateOrAddObject(new DevicePersistenceHistorical(application));
|
}
|
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))
|
{
|
Calendar calendar1 = Calendar.getInstance();
|
calendar1.setTimeInMillis(application.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 TABLE IF NOT EXISTS " + tablename + " PARTITION OF devices FOR VALUES FROM ('" + startdate + "') TO ('" + enddate + "')";
|
try{Shared.controllerDatabase.historical_update(query1);} catch (Exception e){};
|
executeAlterTableDevicesVacuum(true, tablename);
|
|
// Do again the insert
|
try
|
{
|
Shared.controllerDatabase.historical_updateOrAddObject(new DevicePersistenceHistorical(application));
|
}
|
catch (Exception e)
|
{
|
Shared.println(Shared.getMessage("Model"), e);
|
}
|
}
|
}
|
catch (Exception e)
|
{
|
}
|
}
|
}
|
|
|
// </editor-fold>
|
|
|
|
// <editor-fold defaultstate="collapsed" desc="Actions">
|
|
public void addAction(DeviceAction action)
|
{
|
if (Shared.configuration.database != null)
|
{
|
// Insert action
|
|
try
|
{
|
DevicePersistenceAction persistenceAction = new DevicePersistenceAction(action);
|
|
try
|
{
|
Shared.controllerDatabase.historical_addObject(persistenceAction);
|
}
|
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))
|
{
|
Calendar calendar1 = Calendar.getInstance();
|
calendar1.setTimeInMillis(action.requestTimestamp);
|
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 = "actions_" + formato1.format(calendar1.getTimeInMillis());
|
long startdate = calendar1.getTimeInMillis();
|
calendar1.add(Calendar.MONTH, 1);
|
long enddate = calendar1.getTimeInMillis();
|
|
String query1 = "CREATE TABLE IF NOT EXISTS " + tablename + " PARTITION OF actions FOR VALUES FROM ('" + startdate + "') TO ('" + enddate + "')";
|
try{Shared.controllerDatabase.historical_update(query1);} catch (Exception e){};
|
executeAlterTableActionsVacuum(true, tablename);
|
|
// Do again the insert
|
try
|
{
|
Shared.controllerDatabase.historical_addObject(persistenceAction);
|
}
|
catch (Exception e)
|
{
|
Shared.println(Shared.getMessage("Model"), e);
|
}
|
}
|
}
|
catch (Exception e)
|
{
|
}
|
}
|
catch (Exception e)
|
{
|
}
|
}
|
}
|
|
|
|
public List<DeviceAction> getActions()
|
{
|
return getActions(null);
|
}
|
|
|
|
public List<DeviceAction> getActions(long timestamp1, long timestamp2)
|
{
|
String where = "timestamp > " + timestamp1 + " AND timestamp < " + timestamp2;
|
return getActions(where);
|
}
|
|
|
|
public List<DeviceAction> getActions(long timestamp1, long timestamp2, String where)
|
{
|
return getActions("timestamp > " + timestamp1 + " AND timestamp < " + timestamp2 + " AND " + where);
|
}
|
|
|
|
|
public List<DeviceAction> getActions(String where)
|
{
|
List<DeviceAction> result = null;
|
|
try
|
{
|
if (Shared.configuration.database != null)
|
{
|
if (where == null)
|
{
|
result = (List<DeviceAction>)DevicePersistenceAction.getActions((List<Object>)(List<?>)Shared.controllerDatabase.historical_getObject(DevicePersistenceAction.class.getName()));
|
}
|
else
|
{
|
result = (List<DeviceAction>)DevicePersistenceAction.getActions((List<Object>)(List<?>)Shared.controllerDatabase.historical_getObject(DevicePersistenceAction.class.getName(), where));
|
}
|
}
|
}
|
catch (Exception e)
|
{
|
}
|
|
return result;
|
}
|
|
// </editor-fold>
|
|
|
|
|
|
public void executeAlterTableDevicesVacuum(boolean vacuum, String tablename)
|
{
|
try
|
{
|
String enabled = "true";
|
if (vacuum == false) enabled = "false";
|
|
String autovacuum_enabled = art.servers.Shared.getPropertyValueString("devices.autovacuum_enabled");
|
String autovacuum_vacuum_scale_factor = art.servers.Shared.getPropertyValueString("devices.autovacuum_vacuum_scale_factor");
|
String autovacuum_vacuum_threshold = art.servers.Shared.getPropertyValueString("devices.autovacuum_vacuum_threshold");
|
String autovacuum_analyze_scale_factor = art.servers.Shared.getPropertyValueString("devices.autovacuum_analyze_scale_factor");
|
String autovacuum_analyze_threshold = art.servers.Shared.getPropertyValueString("devices.autovacuum_analyze_threshold");
|
|
if (autovacuum_enabled == null) autovacuum_enabled = enabled;
|
if (autovacuum_vacuum_scale_factor == null) autovacuum_vacuum_scale_factor = "0.0";
|
if (autovacuum_vacuum_threshold == null) autovacuum_vacuum_threshold = "1000";
|
if (autovacuum_analyze_scale_factor == null) autovacuum_analyze_scale_factor = "0.0";
|
if (autovacuum_analyze_threshold == null) autovacuum_analyze_threshold = "1000";
|
|
try{Shared.controllerDatabase.historical_update("ALTER TABLE " + tablename + " SET (autovacuum_enabled = " + enabled + ", toast.autovacuum_enabled = " + enabled + ")");} catch (Exception e){};
|
try{Shared.controllerDatabase.historical_update("ALTER TABLE " + tablename + " SET (autovacuum_vacuum_scale_factor = 0.0)");} catch (Exception e){};
|
try{Shared.controllerDatabase.historical_update("ALTER TABLE " + tablename + " SET (autovacuum_vacuum_threshold = 1000)");} catch (Exception e){};
|
try{Shared.controllerDatabase.historical_update("ALTER TABLE " + tablename + " SET (autovacuum_analyze_scale_factor = 0.0)");} catch (Exception e){};
|
try{Shared.controllerDatabase.historical_update("ALTER TABLE " + tablename + " SET (autovacuum_analyze_threshold = 1000)");} catch (Exception e){};
|
}
|
catch (Exception exception)
|
{
|
|
}
|
}
|
|
|
public void executeAlterTableActionsVacuum(boolean vacuum, String tablename)
|
{
|
try
|
{
|
String enabled = "true";
|
if (vacuum == false) enabled = "false";
|
|
String autovacuum_enabled = art.servers.Shared.getPropertyValueString("actions.autovacuum_enabled");
|
String autovacuum_vacuum_scale_factor = art.servers.Shared.getPropertyValueString("actions.autovacuum_vacuum_scale_factor");
|
String autovacuum_vacuum_threshold = art.servers.Shared.getPropertyValueString("actions.autovacuum_vacuum_threshold");
|
String autovacuum_analyze_scale_factor = art.servers.Shared.getPropertyValueString("actions.autovacuum_analyze_scale_factor");
|
String autovacuum_analyze_threshold = art.servers.Shared.getPropertyValueString("actions.autovacuum_analyze_threshold");
|
|
if (autovacuum_enabled == null) autovacuum_enabled = enabled;
|
if (autovacuum_vacuum_scale_factor == null) autovacuum_vacuum_scale_factor = "0.0";
|
if (autovacuum_vacuum_threshold == null) autovacuum_vacuum_threshold = "1000";
|
if (autovacuum_analyze_scale_factor == null) autovacuum_analyze_scale_factor = "0.0";
|
if (autovacuum_analyze_threshold == null) autovacuum_analyze_threshold = "1000";
|
|
try{Shared.controllerDatabase.historical_update("ALTER TABLE " + tablename + " SET (autovacuum_enabled = " + enabled + ", toast.autovacuum_enabled = " + enabled + ")");} catch (Exception e){};
|
try{Shared.controllerDatabase.historical_update("ALTER TABLE " + tablename + " SET (autovacuum_vacuum_scale_factor = 0.0)");} catch (Exception e){};
|
try{Shared.controllerDatabase.historical_update("ALTER TABLE " + tablename + " SET (autovacuum_vacuum_threshold = 1000)");} catch (Exception e){};
|
try{Shared.controllerDatabase.historical_update("ALTER TABLE " + tablename + " SET (autovacuum_analyze_scale_factor = 0.0)");} catch (Exception e){};
|
try{Shared.controllerDatabase.historical_update("ALTER TABLE " + tablename + " SET (autovacuum_analyze_threshold = 1000)");} catch (Exception e){};
|
}
|
catch (Exception exception)
|
{
|
|
}
|
}
|
|
|
public void executeAlterTableTracesVacuum(boolean vacuum, String tablename)
|
{
|
try
|
{
|
String enabled = "true";
|
if (vacuum == false) enabled = "false";
|
|
String autovacuum_enabled = art.servers.Shared.getPropertyValueString("traces.autovacuum_enabled");
|
String autovacuum_vacuum_scale_factor = art.servers.Shared.getPropertyValueString("traces.autovacuum_vacuum_scale_factor");
|
String autovacuum_vacuum_threshold = art.servers.Shared.getPropertyValueString("traces.autovacuum_vacuum_threshold");
|
String autovacuum_analyze_scale_factor = art.servers.Shared.getPropertyValueString("traces.autovacuum_analyze_scale_factor");
|
String autovacuum_analyze_threshold = art.servers.Shared.getPropertyValueString("traces.autovacuum_analyze_threshold");
|
|
if (autovacuum_enabled == null) autovacuum_enabled = enabled;
|
if (autovacuum_vacuum_scale_factor == null) autovacuum_vacuum_scale_factor = "0.0";
|
if (autovacuum_vacuum_threshold == null) autovacuum_vacuum_threshold = "1000";
|
if (autovacuum_analyze_scale_factor == null) autovacuum_analyze_scale_factor = "0.0";
|
if (autovacuum_analyze_threshold == null) autovacuum_analyze_threshold = "1000";
|
|
try{Shared.controllerDatabase.historical_update("ALTER TABLE " + tablename + " SET (autovacuum_enabled = " + enabled + ", toast.autovacuum_enabled = " + enabled + ")");} catch (Exception e){};
|
try{Shared.controllerDatabase.historical_update("ALTER TABLE " + tablename + " SET (autovacuum_vacuum_scale_factor = 0.0)");} catch (Exception e){};
|
try{Shared.controllerDatabase.historical_update("ALTER TABLE " + tablename + " SET (autovacuum_vacuum_threshold = 1000)");} catch (Exception e){};
|
try{Shared.controllerDatabase.historical_update("ALTER TABLE " + tablename + " SET (autovacuum_analyze_scale_factor = 0.0)");} catch (Exception e){};
|
try{Shared.controllerDatabase.historical_update("ALTER TABLE " + tablename + " SET (autovacuum_analyze_threshold = 1000)");} catch (Exception e){};
|
}
|
catch (Exception exception)
|
{
|
|
}
|
}
|
|
|
|
|
private long getLastTimestamp(String identifier, long timestamp1) throws ServerException, Exception
|
{
|
ResultSet result = null;
|
|
try
|
{
|
String where = "type = '" + deviceClassName + "' AND timestamp <= " + timestamp1;
|
|
if (identifier != null)
|
{
|
if (identifier.length() > 0)
|
{
|
where = where + " AND identifier = '" + identifier + "'";
|
}
|
}
|
|
String command = "SELECT timestamp FROM DEVICES WHERE " + where + " ORDER BY timestamp DESC limit 1";
|
result = Shared.controllerDatabase.getHistoricalPersistance().get(0).executeQuery(command);
|
result.next();
|
long timestamp = result.getLong(1);
|
return(timestamp);
|
}
|
catch (Exception e)
|
{
|
return(timestamp1);
|
}
|
finally
|
{
|
try { result.close(); } catch (Exception e) {};
|
}
|
}
|
|
|
|
|
protected Mutex getMutex(Device device)
|
{
|
return getMutex(device.getIdentifier());
|
}
|
|
|
|
protected Mutex getMutex(String identifier)
|
{
|
Mutex mutex = (Mutex)mmutex.get(identifier);
|
|
if (mutex == null)
|
{
|
mutex = new Mutex();
|
mmutex.put(identifier, mutex);
|
}
|
|
return mutex;
|
}
|
|
|
}
|