Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
io.javaoperatorsdk.operator.sample.TomcatController Maven / Gradle / Ivy
package io.javaoperatorsdk.operator.sample;
import io.javaoperatorsdk.operator.api.Context;
import io.javaoperatorsdk.operator.api.Controller;
import io.javaoperatorsdk.operator.api.ResourceController;
import io.javaoperatorsdk.operator.api.UpdateControl;
import io.fabric8.kubernetes.api.model.DoneableService;
import io.fabric8.kubernetes.api.model.HasMetadata;
import io.fabric8.kubernetes.api.model.Service;
import io.fabric8.kubernetes.api.model.apps.Deployment;
import io.fabric8.kubernetes.api.model.apps.DoneableDeployment;
import io.fabric8.kubernetes.client.*;
import io.fabric8.kubernetes.client.dsl.MixedOperation;
import io.fabric8.kubernetes.client.dsl.Resource;
import io.fabric8.kubernetes.client.dsl.RollableScalableResource;
import io.fabric8.kubernetes.client.dsl.ServiceResource;
import io.fabric8.kubernetes.client.utils.Serialization;
import org.apache.commons.lang3.builder.EqualsBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
@Controller(customResourceClass = Tomcat.class,
crdName = "tomcats.tomcatoperator.io")
public class TomcatController implements ResourceController {
private final Logger log = LoggerFactory.getLogger(getClass());
private final KubernetesClient kubernetesClient;
private MixedOperation, CustomResourceDoneable, Resource>> tomcatOperations;
private final List watchedResources = new ArrayList<>();
public TomcatController(KubernetesClient client) {
this.kubernetesClient = client;
}
private void updateTomcatStatus(Context context, Tomcat tomcat, Deployment deployment) {
int readyReplicas = Optional.ofNullable(deployment.getStatus().getReadyReplicas()).orElse(0);
// Java 9+
// int readyReplicas = Objects.requireNonNullElse(deployment.getStatus().getReadyReplicas(), 0);
log.info("Updating status of Tomcat {} in namespace {} to {} ready replicas", tomcat.getMetadata().getName(),
tomcat.getMetadata().getNamespace(), readyReplicas);
tomcatOperations
.inNamespace(tomcat.getMetadata().getNamespace())
.withName(tomcat.getMetadata().getName())
.replace(tomcat);
}
@Override
public UpdateControl createOrUpdateResource(Tomcat tomcat, Context context) {
Deployment deployment = createOrUpdateDeployment(tomcat);
createOrUpdateService(tomcat);
if (!watchedResources.contains(WatchedResource.fromResource(deployment))) {
log.info("Attaching Watch to Deployment {}", deployment.getMetadata().getName());
kubernetesClient.apps().deployments().withName(deployment.getMetadata().getName()).watch(new Watcher() {
@Override
public void eventReceived(Action action, Deployment deployment) {
try {
Tomcat tomcat = tomcatOperations.inNamespace(deployment.getMetadata().getNamespace())
.withName(deployment.getMetadata().getLabels().get("created-by")).get();
updateTomcatStatus(context, tomcat, deployment);
} catch (Exception ex) {
log.error(ex.getMessage());
}
}
@Override
public void onClose(KubernetesClientException cause) {
}
});
watchedResources.add(WatchedResource.fromResource(deployment));
}
return UpdateControl.noUpdate();
}
@Override
public boolean deleteResource(Tomcat tomcat, Context context) {
deleteDeployment(tomcat);
deleteService(tomcat);
return true;
}
private Deployment createOrUpdateDeployment(Tomcat tomcat) {
String ns = tomcat.getMetadata().getNamespace();
Deployment existingDeployment = kubernetesClient.apps().deployments()
.inNamespace(ns).withName(tomcat.getMetadata().getName())
.get();
if (existingDeployment == null) {
Deployment deployment = loadYaml(Deployment.class, "deployment.yaml");
deployment.getMetadata().setName(tomcat.getMetadata().getName());
deployment.getMetadata().setNamespace(ns);
deployment.getMetadata().getLabels().put("created-by", tomcat.getMetadata().getName());
// set tomcat version
deployment.getSpec().getTemplate().getSpec().getContainers().get(0).setImage("tomcat:" + tomcat.getSpec().getVersion());
deployment.getSpec().setReplicas(tomcat.getSpec().getReplicas());
//make sure label selector matches label (which has to be matched by service selector too)
deployment.getSpec().getTemplate().getMetadata().getLabels().put("app", tomcat.getMetadata().getName());
deployment.getSpec().getSelector().getMatchLabels().put("app", tomcat.getMetadata().getName());
log.info("Creating or updating Deployment {} in {}", deployment.getMetadata().getName(), ns);
return kubernetesClient.apps().deployments().inNamespace(ns).create(deployment);
} else {
existingDeployment.getSpec().getTemplate().getSpec().getContainers().get(0).setImage("tomcat:" + tomcat.getSpec().getVersion());
existingDeployment.getSpec().setReplicas(tomcat.getSpec().getReplicas());
return kubernetesClient.apps().deployments().inNamespace(ns).createOrReplace(existingDeployment);
}
}
private void deleteDeployment(Tomcat tomcat) {
log.info("Deleting Deployment {}", tomcat.getMetadata().getName());
RollableScalableResource deployment = kubernetesClient.apps().deployments()
.inNamespace(tomcat.getMetadata().getNamespace())
.withName(tomcat.getMetadata().getName());
if (deployment.get() != null) {
deployment.delete();
}
}
private void createOrUpdateService(Tomcat tomcat) {
Service service = loadYaml(Service.class, "service.yaml");
service.getMetadata().setName(tomcat.getMetadata().getName());
String ns = tomcat.getMetadata().getNamespace();
service.getMetadata().setNamespace(ns);
service.getSpec().getSelector().put("app", tomcat.getMetadata().getName());
log.info("Creating or updating Service {} in {}", service.getMetadata().getName(), ns);
kubernetesClient.services().inNamespace(ns).createOrReplace(service);
}
private void deleteService(Tomcat tomcat) {
log.info("Deleting Service {}", tomcat.getMetadata().getName());
ServiceResource service = kubernetesClient.services()
.inNamespace(tomcat.getMetadata().getNamespace())
.withName(tomcat.getMetadata().getName());
if (service.get() != null) {
service.delete();
}
}
private T loadYaml(Class clazz, String yaml) {
try (InputStream is = getClass().getResourceAsStream(yaml)) {
return Serialization.unmarshal(is, clazz);
} catch (IOException ex) {
throw new IllegalStateException("Cannot find yaml on classpath: " + yaml);
}
}
public void setTomcatOperations(MixedOperation, CustomResourceDoneable, Resource>> tomcatOperations) {
this.tomcatOperations = tomcatOperations;
}
private static class WatchedResource {
private final String type;
private final String name;
public WatchedResource(String type, String name) {
this.type = type;
this.name = name;
}
public static WatchedResource fromResource(HasMetadata resource) {
return new WatchedResource(resource.getKind(), resource.getMetadata().getName());
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
WatchedResource that = (WatchedResource) o;
return new EqualsBuilder()
.append(type, that.type)
.append(name, that.name)
.isEquals();
}
@Override
public int hashCode() {
return Objects.hash(type, name);
}
@Override
public String toString() {
return "WatchedResource{" +
"type='" + type + '\'' +
", name='" + name + '\'' +
'}';
}
}
}