Skip to content
This repository was archived by the owner on Sep 1, 2024. It is now read-only.

Commit db0b02d

Browse files
committed
System resume and initialisation at time T implementation completed, not tested
1 parent fc1aeba commit db0b02d

21 files changed

Lines changed: 408 additions & 59 deletions

File tree

eu.dariolucia.reatmetric.api/src/main/java/eu/dariolucia/reatmetric/api/archive/IDataItemArchive.java

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,33 @@ public interface IDataItemArchive<T extends AbstractDataItem, K extends Abstract
101101
*/
102102
IUniqueId retrieveLastId(Class<? extends AbstractDataItem> type) throws ArchiveException;
103103

104+
/**
105+
* Retrieve the last (largest) stored generation time for the data item handled by this archive service.
106+
*
107+
* @return the last (largest) stored generation time or null if there is none
108+
* @throws ArchiveException in case of I/O problems, SQL problems or any other problem preventing the retrieval operation to be completed successfully
109+
*/
110+
Instant retrieveLastGenerationTime() throws ArchiveException;
111+
112+
/**
113+
* Retrieve the last (largest) stored generation time for the specified data item type handled by this archive service.
114+
*
115+
* @param type the class of the data item type
116+
* @return the last (largest) stored generation time or null if there is none
117+
* @throws ArchiveException in case of I/O problems, SQL problems or any other problem preventing the retrieval operation to be completed successfully
118+
*/
119+
Instant retrieveLastGenerationTime(Class<? extends AbstractDataItem> type) throws ArchiveException;
120+
121+
/**
122+
* Delete all entries in the archive strictly following (generationTime > referenceTime) or preceeding (generationTime < referenceTime)
123+
* the provided time.
124+
*
125+
* @param referenceTime the reference time
126+
* @param direction the delete direction: TO_FUTURE removes all data items with generationTime > referenceTime
127+
* @throws ArchiveException in case of I/O problems, SQL problems or any other problem preventing the purge operation to be completed successfully
128+
*/
129+
void purge(Instant referenceTime, RetrievalDirection direction) throws ArchiveException;
130+
104131
/**
105132
* Close and dispose this archive service. Further calls to store/retrieve operations will throw an exception.
106133
*

eu.dariolucia.reatmetric.core/src/main/java/eu/dariolucia/reatmetric/core/ServiceCoreImpl.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,11 @@ public List<ITransportConnector> getTransportConnectors() {
236236
return transportConnectorsImmutable;
237237
}
238238

239+
@Override
240+
public IArchive getArchive() {
241+
return archive;
242+
}
243+
239244
@Override
240245
public IProcessingModel getProcessingModel() {
241246
return processingModelManager.getProcessingModel();

eu.dariolucia.reatmetric.core/src/main/java/eu/dariolucia/reatmetric/core/api/IServiceCoreContext.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,13 @@
88
package eu.dariolucia.reatmetric.core.api;
99

1010
import eu.dariolucia.reatmetric.api.IReatmetricSystem;
11+
import eu.dariolucia.reatmetric.api.archive.IArchive;
1112
import eu.dariolucia.reatmetric.api.processing.IProcessingModel;
1213

1314
public interface IServiceCoreContext {
1415

16+
IArchive getArchive();
17+
1518
IProcessingModel getProcessingModel();
1619

1720
IReatmetricSystem getServiceFactory();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/*
2+
* Copyright (c) 2020. Dario Lucia (dario.lucia@gmail.com)
3+
* All rights reserved.
4+
*
5+
* Right to reproduce, use, modify and distribute (in whole or in part) this library for demonstrations/trainings/study/commercial purposes shall be granted by the author in writing.
6+
*/
7+
8+
package eu.dariolucia.reatmetric.core.configuration;
9+
10+
import javax.xml.bind.annotation.XmlAccessType;
11+
import javax.xml.bind.annotation.XmlAccessorType;
12+
import javax.xml.bind.annotation.XmlAttribute;
13+
14+
@XmlAccessorType(XmlAccessType.FIELD)
15+
public abstract class AbstractInitialisationConfiguration {
16+
17+
@XmlAttribute(name = "look-back-time")
18+
private int lookBackTime = 3600; // Number of seconds to look back (increase start-up performance)
19+
20+
public int getLookBackTime() {
21+
return lookBackTime;
22+
}
23+
24+
public void setLookBackTime(int lookBackTime) {
25+
this.lookBackTime = lookBackTime;
26+
}
27+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
/*
2+
* Copyright (c) 2020. Dario Lucia (dario.lucia@gmail.com)
3+
* All rights reserved.
4+
*
5+
* Right to reproduce, use, modify and distribute (in whole or in part) this library for demonstrations/trainings/study/commercial purposes shall be granted by the author in writing.
6+
*/
7+
8+
package eu.dariolucia.reatmetric.core.configuration;
9+
10+
public class ResumeInitialisationConfiguration extends AbstractInitialisationConfiguration {
11+
// No structure, marker
12+
}

eu.dariolucia.reatmetric.core/src/main/java/eu/dariolucia/reatmetric/core/configuration/ServiceCoreConfiguration.java

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,7 @@
1010
import javax.xml.bind.JAXBContext;
1111
import javax.xml.bind.JAXBException;
1212
import javax.xml.bind.Unmarshaller;
13-
import javax.xml.bind.annotation.XmlAccessType;
14-
import javax.xml.bind.annotation.XmlAccessorType;
15-
import javax.xml.bind.annotation.XmlElement;
16-
import javax.xml.bind.annotation.XmlRootElement;
13+
import javax.xml.bind.annotation.*;
1714
import java.io.InputStream;
1815
import java.util.LinkedList;
1916
import java.util.List;
@@ -42,17 +39,20 @@ public static ServiceCoreConfiguration load(InputStream is) throws JAXBException
4239
@XmlElement(name = "name")
4340
private String name;
4441

45-
@XmlElement(name = "logPropertyFile")
42+
@XmlElement(name = "log-property-file")
4643
private String logPropertyFile;
4744

48-
@XmlElement(name = "archiveLocation", required = true)
45+
@XmlElement(name = "archive-location", required = true)
4946
private String archiveLocation;
5047

51-
@XmlElement(name = "definitionsLocation", required = true)
48+
@XmlElement(name = "definitions-location", required = true)
5249
private String definitionsLocation;
5350

54-
@XmlElement(name = "initialisation")
55-
private StateInitialisationConfiguration initialisation;
51+
@XmlElements({
52+
@XmlElement(name="init-resume",type=ResumeInitialisationConfiguration.class),
53+
@XmlElement(name="init-from-time",type=TimeInitialisationConfiguration.class)
54+
})
55+
private AbstractInitialisationConfiguration initialisation;
5656

5757
@XmlElement(name = "driver", required = true)
5858
private List<DriverConfiguration> drivers = new LinkedList<>();
@@ -105,11 +105,11 @@ public ServiceCoreConfiguration setDrivers(List<DriverConfiguration> drivers) {
105105
return this;
106106
}
107107

108-
public StateInitialisationConfiguration getInitialisation() {
108+
public AbstractInitialisationConfiguration getInitialisation() {
109109
return initialisation;
110110
}
111111

112-
public void setInitialisation(StateInitialisationConfiguration initialisation) {
112+
public void setInitialisation(AbstractInitialisationConfiguration initialisation) {
113113
this.initialisation = initialisation;
114114
}
115115
}

eu.dariolucia.reatmetric.core/src/main/java/eu/dariolucia/reatmetric/core/configuration/StateInitialisationConfiguration.java renamed to eu.dariolucia.reatmetric.core/src/main/java/eu/dariolucia/reatmetric/core/configuration/TimeInitialisationConfiguration.java

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,14 @@
1313
import java.util.Date;
1414

1515
@XmlAccessorType(XmlAccessType.FIELD)
16-
public class StateInitialisationConfiguration {
16+
public class TimeInitialisationConfiguration extends AbstractInitialisationConfiguration {
1717

1818
@XmlAttribute(name = "time", required = true)
1919
private Date time;
2020

21-
@XmlAttribute(name = "archiveLocation", required = true)
21+
@XmlAttribute(name = "archive-location", required = true)
2222
private String archiveLocation;
2323

24-
public StateInitialisationConfiguration() {
25-
}
26-
2724
public Date getTime() {
2825
return time;
2926
}

eu.dariolucia.reatmetric.core/src/main/java/eu/dariolucia/reatmetric/core/impl/ArchiveInitialiser.java

Lines changed: 65 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,10 @@
1313
import eu.dariolucia.reatmetric.api.alarms.IAlarmParameterDataArchive;
1414
import eu.dariolucia.reatmetric.api.archive.IArchive;
1515
import eu.dariolucia.reatmetric.api.archive.IArchiveFactory;
16+
import eu.dariolucia.reatmetric.api.archive.IDataItemArchive;
1617
import eu.dariolucia.reatmetric.api.archive.exceptions.ArchiveException;
1718
import eu.dariolucia.reatmetric.api.common.AbstractDataItem;
19+
import eu.dariolucia.reatmetric.api.common.Pair;
1820
import eu.dariolucia.reatmetric.api.common.exceptions.ReatmetricException;
1921
import eu.dariolucia.reatmetric.api.events.EventData;
2022
import eu.dariolucia.reatmetric.api.events.EventDataFilter;
@@ -24,23 +26,61 @@
2426
import eu.dariolucia.reatmetric.api.parameters.ParameterData;
2527
import eu.dariolucia.reatmetric.api.parameters.ParameterDataFilter;
2628
import eu.dariolucia.reatmetric.api.processing.IProcessingModelInitialiser;
29+
import eu.dariolucia.reatmetric.core.configuration.AbstractInitialisationConfiguration;
30+
import eu.dariolucia.reatmetric.core.configuration.ResumeInitialisationConfiguration;
31+
import eu.dariolucia.reatmetric.core.configuration.TimeInitialisationConfiguration;
2732

33+
import java.time.Instant;
2834
import java.util.*;
2935

3036
public class ArchiveInitialiser implements IProcessingModelInitialiser {
3137

32-
private final Date initTime;
38+
private final Instant maxLookBackTime;
39+
private final Instant initTime;
3340
private final IArchive initArchive;
41+
private final boolean externalArchive;
3442

35-
public ArchiveInitialiser(Date time, String archiveLocation) throws ReatmetricException {
36-
this.initTime = time;
37-
ServiceLoader<IArchiveFactory> archiveLoader = ServiceLoader.load(IArchiveFactory.class);
38-
if(archiveLoader.findFirst().isPresent()) {
39-
initArchive = archiveLoader.findFirst().get().buildArchive(archiveLocation);
40-
initArchive.connect();
43+
public ArchiveInitialiser(IArchive processingArchive, AbstractInitialisationConfiguration configuration) throws ReatmetricException {
44+
if(configuration instanceof TimeInitialisationConfiguration) {
45+
this.externalArchive = true;
46+
this.initTime = ((TimeInitialisationConfiguration) configuration).getTime().toInstant();
47+
ServiceLoader<IArchiveFactory> archiveLoader = ServiceLoader.load(IArchiveFactory.class);
48+
if (archiveLoader.findFirst().isPresent()) {
49+
initArchive = archiveLoader.findFirst().get().buildArchive(((TimeInitialisationConfiguration) configuration).getArchiveLocation());
50+
initArchive.connect();
51+
} else {
52+
throw new ReatmetricException("Initialisation archive configured to " + ((TimeInitialisationConfiguration) configuration).getArchiveLocation() + ", but no archive factory deployed");
53+
}
54+
} else if(configuration instanceof ResumeInitialisationConfiguration) {
55+
this.externalArchive = false;
56+
initArchive = processingArchive;
57+
// In order to be optimal with the dates, let's get the latest stored generation time for each data type: events, parameters, activities
58+
Instant lastStoredGenerationTime = null;
59+
List<Pair<Class<? extends IDataItemArchive>, Class<? extends AbstractDataItem>>> toCheckPairs = Arrays.asList(
60+
Pair.of(IParameterDataArchive.class, ParameterData.class),
61+
Pair.of(IAlarmParameterDataArchive.class, AlarmParameterData.class),
62+
Pair.of(IEventDataArchive.class, EventData.class),
63+
Pair.of(IActivityOccurrenceDataArchive.class, ActivityOccurrenceReport.class),
64+
Pair.of(IActivityOccurrenceDataArchive.class, ActivityOccurrenceData.class)
65+
);
66+
for(Pair<Class<? extends IDataItemArchive>, Class<? extends AbstractDataItem>> pair : toCheckPairs) {
67+
IDataItemArchive arc = processingArchive.getArchive(pair.getFirst());
68+
if(arc != null) {
69+
Instant retrieved = arc.retrieveLastGenerationTime(pair.getSecond());
70+
if(retrieved != null && (lastStoredGenerationTime == null || lastStoredGenerationTime.isBefore(retrieved))) {
71+
lastStoredGenerationTime = retrieved;
72+
}
73+
}
74+
}
75+
// Still null? Use now
76+
if(lastStoredGenerationTime == null) {
77+
lastStoredGenerationTime = Instant.now();
78+
}
79+
initTime = lastStoredGenerationTime;
4180
} else {
42-
throw new ReatmetricException("Initialisation archive configured to " + archiveLocation + ", but no archive factory deployed");
81+
throw new IllegalArgumentException("Initialisation configuration " + configuration + " not supported");
4382
}
83+
this.maxLookBackTime = this.initTime.minusSeconds(configuration.getLookBackTime());
4484
}
4585

4686
@Override
@@ -60,7 +100,7 @@ public List<AbstractDataItem> getState(int externalId, SystemEntityType type) th
60100

61101
private List<AbstractDataItem> retrieveActivityOccurranceStates(int externalId) throws ArchiveException {
62102
IActivityOccurrenceDataArchive arc = initArchive.getArchive(IActivityOccurrenceDataArchive.class);
63-
List<ActivityOccurrenceData> activities = arc.retrieve(initTime.toInstant(), new ActivityOccurrenceDataFilter(null, null, null, null, null, Collections.singletonList(externalId)), null);
103+
List<ActivityOccurrenceData> activities = arc.retrieve(initTime, new ActivityOccurrenceDataFilter(null, null, null, null, null, Collections.singletonList(externalId)), maxLookBackTime);
64104
// Post processing: for each activity occurrence, remove the reports having verification time > initTime and rebuild the activity occurrence object
65105
List<AbstractDataItem> toReturn = new ArrayList<>(activities.size());
66106
for(ActivityOccurrenceData aod : activities) {
@@ -80,10 +120,10 @@ private List<AbstractDataItem> retrieveActivityOccurranceStates(int externalId)
80120

81121
private ActivityOccurrenceData sanitize(ActivityOccurrenceData aod) {
82122
ActivityOccurrenceReport lastReport = aod.getProgressReports().get(aod.getProgressReports().size());
83-
if(lastReport.getGenerationTime().compareTo(initTime.toInstant()) > 0) {
123+
if(lastReport.getGenerationTime().compareTo(initTime) > 0) {
84124
// At least one report is exceeding the init time
85125
List<ActivityOccurrenceReport> shrinkedReports = new LinkedList<>(aod.getProgressReports());
86-
shrinkedReports.removeIf(rep -> rep.getGenerationTime().compareTo(initTime.toInstant()) > 0);
126+
shrinkedReports.removeIf(rep -> rep.getGenerationTime().compareTo(initTime) > 0);
87127
return new ActivityOccurrenceData(aod.getInternalId(), aod.getGenerationTime(), aod.getExtension(), aod.getExternalId(), aod.getName(), aod.getPath(), aod.getType(), aod.getArguments(), aod.getProperties(), shrinkedReports, aod.getRoute(), aod.getSource());
88128
} else {
89129
return aod;
@@ -92,9 +132,9 @@ private ActivityOccurrenceData sanitize(ActivityOccurrenceData aod) {
92132

93133
private List<AbstractDataItem> retrieveParameterState(int externalId) throws ArchiveException {
94134
IParameterDataArchive arc = initArchive.getArchive(IParameterDataArchive.class);
95-
List<ParameterData> params = arc.retrieve(initTime.toInstant(), new ParameterDataFilter(null, null, null, null, null, Collections.singletonList(externalId)), null);
135+
List<ParameterData> params = arc.retrieve(initTime, new ParameterDataFilter(null, null, null, null, null, Collections.singletonList(externalId)), maxLookBackTime);
96136
IAlarmParameterDataArchive arc2 = initArchive.getArchive(IAlarmParameterDataArchive.class);
97-
List<AlarmParameterData> alarms = arc2.retrieve(initTime.toInstant(), new AlarmParameterDataFilter(null, null, null, Collections.singletonList(externalId)), null);
137+
List<AlarmParameterData> alarms = arc2.retrieve(initTime, new AlarmParameterDataFilter(null, null, null, Collections.singletonList(externalId)), maxLookBackTime);
98138
List<AbstractDataItem> toReturn = new ArrayList<>();
99139
if(params.size() > 0) {
100140
toReturn.add(params.get(0));
@@ -107,11 +147,22 @@ private List<AbstractDataItem> retrieveParameterState(int externalId) throws Arc
107147

108148
private List<AbstractDataItem> retrieveEventState(int externalId) throws ArchiveException {
109149
IEventDataArchive arc = initArchive.getArchive(IEventDataArchive.class);
110-
List<EventData> events = arc.retrieve(initTime.toInstant(), new EventDataFilter(null, null, null, null, null, null, Collections.singletonList(externalId)), null);
150+
List<EventData> events = arc.retrieve(initTime, new EventDataFilter(null, null, null, null, null, null, Collections.singletonList(externalId)), maxLookBackTime);
111151
List<AbstractDataItem> toReturn = new ArrayList<>();
112152
if(events.size() > 0) {
113153
toReturn.add(events.get(0));
114154
}
115155
return toReturn;
116156
}
157+
158+
public void dispose() {
159+
if(externalArchive) {
160+
try {
161+
initArchive.dispose();
162+
} catch (ArchiveException e) {
163+
// TODO log
164+
e.printStackTrace();
165+
}
166+
}
167+
}
117168
}

0 commit comments

Comments
 (0)