88import static io .stackgres .common .ClusterControllerProperty .CLUSTER_NAME ;
99import static io .stackgres .common .ClusterControllerProperty .CLUSTER_NAMESPACE ;
1010
11+ import java .nio .file .Files ;
12+ import java .nio .file .Path ;
13+ import java .nio .file .Paths ;
1114import java .util .List ;
1215import java .util .Optional ;
1316import java .util .function .Consumer ;
1417import java .util .stream .Stream ;
1518
19+ import com .fasterxml .jackson .databind .ObjectMapper ;
1620import io .fabric8 .kubernetes .api .model .HasMetadata ;
1721import io .fabric8 .kubernetes .client .KubernetesClient ;
1822import io .quarkus .runtime .ShutdownEvent ;
2327import io .stackgres .cluster .configuration .ClusterControllerPropertyContext ;
2428import io .stackgres .cluster .resource .ClusterResourceHandlerSelector ;
2529import io .stackgres .common .CdiUtil ;
30+ import io .stackgres .common .ClusterControllerProperty ;
31+ import io .stackgres .common .ClusterPath ;
2632import io .stackgres .common .crd .sgcluster .StackGresCluster ;
2733import io .stackgres .common .crd .sgcluster .StackGresClusterStatus ;
2834import io .stackgres .common .labels .LabelFactoryForCluster ;
3440import jakarta .enterprise .event .Observes ;
3541import jakarta .inject .Inject ;
3642import org .jooq .lambda .tuple .Tuple2 ;
43+ import org .slf4j .Logger ;
44+ import org .slf4j .LoggerFactory ;
3745import org .slf4j .helpers .MessageFormatter ;
3846
3947@ ApplicationScoped
4048public class ClusterControllerReconciliationCycle
4149 extends
4250 ReconciliationCycle <StackGresClusterContext , StackGresCluster , ClusterResourceHandlerSelector > {
4351
52+ private static final Logger LOGGER = LoggerFactory .getLogger (ClusterControllerReconciliationCycle .class );
53+
4454 private final ClusterControllerPropertyContext propertyContext ;
4555 private final EventController eventController ;
4656 private final LabelFactoryForCluster labelFactory ;
4757 private final CustomResourceFinder <StackGresCluster > clusterFinder ;
4858 private final Metrics metrics ;
59+ private final ObjectMapper objectMapper ;
4960 private long reconciliationStart ;
5061
5162 @ Dependent
@@ -66,6 +77,8 @@ public static class Parameters {
6677 CustomResourceFinder <StackGresCluster > clusterFinder ;
6778 @ Inject
6879 Metrics metrics ;
80+ @ Inject
81+ ObjectMapper objectMapper ;
6982 }
7083
7184 /**
@@ -81,6 +94,7 @@ public ClusterControllerReconciliationCycle(Parameters parameters) {
8194 this .labelFactory = parameters .labelFactory ;
8295 this .clusterFinder = parameters .clusterFinder ;
8396 this .metrics = parameters .metrics ;
97+ this .objectMapper = parameters .objectMapper ;
8498 }
8599
86100 public ClusterControllerReconciliationCycle () {
@@ -91,6 +105,7 @@ public ClusterControllerReconciliationCycle() {
91105 this .labelFactory = null ;
92106 this .clusterFinder = null ;
93107 this .metrics = null ;
108+ this .objectMapper = null ;
94109 }
95110
96111 public static ClusterControllerReconciliationCycle create (Consumer <Parameters > consumer ) {
@@ -174,22 +189,24 @@ protected StackGresClusterContext getContextWithExistingAndRequiredResources(
174189
175190 @ Override
176191 public List <StackGresCluster > getExistingContextResources () {
177- return clusterFinder .findByNameAndNamespace (
178- propertyContext .getString (CLUSTER_NAME ),
179- propertyContext .getString (CLUSTER_NAMESPACE ))
180- .stream ()
181- .toList ();
192+ return List .of (getExistingCustomResource (
193+ LOGGER ,
194+ clusterFinder ,
195+ objectMapper ,
196+ propertyContext .getString (CLUSTER_NAMESPACE ),
197+ propertyContext .getString (CLUSTER_NAME )));
182198 }
183199
184200 @ Override
185201 public StackGresCluster getExistingContextResource (StackGresCluster source ) {
186202 final String namespace = source .getMetadata ().getNamespace ();
187203 final String name = source .getMetadata ().getName ();
188- return clusterFinder .findByNameAndNamespace (
189- name ,
190- namespace )
191- .orElseThrow (() -> new IllegalArgumentException (StackGresCluster .KIND
192- + " " + name + "." + namespace + " not found" ));
204+ return getExistingCustomResource (
205+ LOGGER ,
206+ clusterFinder ,
207+ objectMapper ,
208+ namespace ,
209+ name );
193210 }
194211
195212 @ Override
@@ -204,4 +221,56 @@ protected StackGresClusterContext getContextFromResource(
204221 .build ();
205222 }
206223
224+ static StackGresCluster getExistingCustomResource (
225+ final Logger logger ,
226+ final CustomResourceFinder <StackGresCluster > clusterFinder ,
227+ final ObjectMapper objectMapper ,
228+ final String namespace ,
229+ final String name ) {
230+ final Path latestCustomResourcePath = getLatestCustomResourcePath (namespace , name );
231+ try {
232+ return clusterFinder .findByNameAndNamespace (name , namespace )
233+ .orElseThrow (() -> new IllegalArgumentException (StackGresCluster .KIND
234+ + " " + name + "." + namespace + " not found" ));
235+ } catch (Exception ex ) {
236+ if (Files .exists (latestCustomResourcePath )) {
237+ try {
238+ return objectMapper .readValue (latestCustomResourcePath .toFile (), StackGresCluster .class );
239+ } catch (Exception jex ) {
240+ ex .addSuppressed (jex );
241+ }
242+ }
243+ if (ex instanceof RuntimeException rex ) {
244+ throw rex ;
245+ }
246+ throw new RuntimeException (ex );
247+ }
248+ }
249+
250+ public static boolean existsContextResource () {
251+ return Files .exists (getLatestCustomResourcePath (
252+ ClusterControllerProperty .CLUSTER_NAMESPACE .getString (),
253+ ClusterControllerProperty .CLUSTER_NAME .getString ()));
254+ }
255+
256+ static void writeCustomResource (
257+ final Logger logger ,
258+ final ObjectMapper objectMapper ,
259+ final StackGresCluster cluster ) {
260+ final Path latestCustomResourcePath = getLatestCustomResourcePath (
261+ cluster .getMetadata ().getNamespace (),
262+ cluster .getMetadata ().getName ());
263+ try {
264+ objectMapper .writeValue (latestCustomResourcePath .toFile (), cluster );
265+ } catch (Exception jex ) {
266+ logger .warn ("Error while trying to store latest value of SGCluster to " + latestCustomResourcePath , jex );
267+ }
268+ }
269+
270+ private static Path getLatestCustomResourcePath (final String namespace , final String name ) {
271+ return Paths .get (
272+ ClusterPath .PG_BASE_PATH .path (),
273+ ".latest." + namespace + "." + name + ".sgcluster.json" );
274+ }
275+
207276}
0 commit comments