001/*
002 * VM-Operator
003 * Copyright (C) 2024 Michael N. Lipp
004 * 
005 * This program is free software: you can redistribute it and/or modify
006 * it under the terms of the GNU Affero General Public License as
007 * published by the Free Software Foundation, either version 3 of the
008 * License, or (at your option) any later version.
009 *
010 * This program is distributed in the hope that it will be useful,
011 * but WITHOUT ANY WARRANTY; without even the implied warranty of
012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
013 * GNU Affero General Public License for more details.
014 *
015 * You should have received a copy of the GNU Affero General Public License
016 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
017 */
018
019package org.jdrupes.vmoperator.common;
020
021import com.google.gson.Gson;
022import com.google.gson.JsonElement;
023import com.google.gson.JsonObject;
024import io.kubernetes.client.common.KubernetesListObject;
025import io.kubernetes.client.openapi.Configuration;
026import io.kubernetes.client.openapi.models.V1ListMeta;
027import java.lang.reflect.InvocationTargetException;
028import java.util.ArrayList;
029import java.util.List;
030import java.util.Objects;
031
032/**
033 * Represents a list of Kubernetes objects each of which is
034 * represented using a JSON data structure.
035 * Some information that is common to all Kubernetes objects,
036 * notably the metadata, is made available through the methods
037 * defined by {@link KubernetesListObject}.
038 */
039public class K8sDynamicModelsBase<T extends K8sDynamicModel>
040        implements KubernetesListObject {
041
042    private final JsonObject data;
043    private final V1ListMeta metadata;
044    private final List<T> items;
045
046    /**
047     * Initialize the object list using the given JSON data.
048     *
049     * @param itemClass the item class
050     * @param delegate the gson instance to use for extracting structured data
051     * @param data the data
052     */
053    public K8sDynamicModelsBase(Class<T> itemClass, Gson delegate,
054            JsonObject data) {
055        this.data = data;
056        metadata = delegate.fromJson(data.get("metadata"), V1ListMeta.class);
057        items = new ArrayList<>();
058        for (JsonElement e : data.get("items").getAsJsonArray()) {
059            try {
060                items.add(itemClass.getConstructor(Gson.class, JsonObject.class)
061                    .newInstance(delegate, e.getAsJsonObject()));
062            } catch (InstantiationException | IllegalAccessException
063                    | IllegalArgumentException | InvocationTargetException
064                    | NoSuchMethodException | SecurityException exc) {
065                throw new IllegalArgumentException(exc);
066            }
067        }
068    }
069
070    @Override
071    public String getApiVersion() {
072        return apiVersion();
073    }
074
075    /**
076     * Gets the API version. (Abbreviated method name for convenience.)
077     *
078     * @return the API version
079     */
080    public String apiVersion() {
081        return data.get("apiVersion").getAsString();
082    }
083
084    @Override
085    public String getKind() {
086        return kind();
087    }
088
089    /**
090     * Gets the kind. (Abbreviated method name for convenience.)
091     *
092     * @return the kind
093     */
094    public String kind() {
095        return data.get("kind").getAsString();
096    }
097
098    @Override
099    public V1ListMeta getMetadata() {
100        return metadata;
101    }
102
103    /**
104     * Gets the metadata. (Abbreviated method name for convenience.)
105     *
106     * @return the metadata
107     */
108    public V1ListMeta metadata() {
109        return metadata;
110    }
111
112    /**
113     * Returns the JSON representation of this object.
114     *
115     * @return the JOSN representation
116     */
117    public JsonObject data() {
118        return data;
119    }
120
121    @Override
122    public List<T> getItems() {
123        return items;
124    }
125
126    /**
127     * Sets the api version.
128     *
129     * @param apiVersion the new api version
130     */
131    public void setApiVersion(String apiVersion) {
132        data.addProperty("apiVersion", apiVersion);
133    }
134
135    /**
136     * Sets the kind.
137     *
138     * @param kind the new kind
139     */
140    public void setKind(String kind) {
141        data.addProperty("kind", kind);
142    }
143
144    /**
145     * Sets the metadata.
146     *
147     * @param objectMeta the new metadata
148     */
149    public void setMetadata(V1ListMeta objectMeta) {
150        data.add("metadata",
151            Configuration.getDefaultApiClient().getJSON().getGson()
152                .toJsonTree(objectMeta));
153    }
154
155    @Override
156    public int hashCode() {
157        return Objects.hash(data);
158    }
159
160    @Override
161    public boolean equals(Object obj) {
162        if (this == obj) {
163            return true;
164        }
165        if (obj == null) {
166            return false;
167        }
168        if (getClass() != obj.getClass()) {
169            return false;
170        }
171        K8sDynamicModelsBase<?> other = (K8sDynamicModelsBase<?>) obj;
172        return Objects.equals(data, other.data);
173    }
174}