cf.service.ServiceGarbageCollector.java Source code

Java tutorial

Introduction

Here is the source code for cf.service.ServiceGarbageCollector.java

Source

/*
 *   Copyright (c) 2013 Intellectual Reserve, Inc.  All rights reserved.
 *
 *   Licensed under the Apache License, Version 2.0 (the "License");
 *   you may not use this file except in compliance with the License.
 *   You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *   Unless required by applicable law or agreed to in writing, software
 *   distributed under the License is distributed on an "AS IS" BASIS,
 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *   See the License for the specific language governing permissions and
 *   limitations under the License.
 *
 */
package cf.service;

import com.fasterxml.jackson.databind.JsonNode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import cf.client.CloudController;
import cf.client.Resource;
import cf.client.RestCollection;
import cf.client.TokenProvider;
import cf.client.model.ServiceBinding;
import cf.client.model.ServiceInstance;
import cf.client.model.ServicePlan;

import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * @author Mike Heath <elcapo@gmail.com>
 * @deprecated Use the V2 services.
 */
@Deprecated
public class ServiceGarbageCollector {

    private static final Logger LOGGER = LoggerFactory.getLogger(ServiceGarbageCollector.class);

    public static final long COLLECTION_RATE = TimeUnit.HOURS.toMillis(1);

    private final UUID serviceGuid;
    private final CloudController cloudController;
    private final TokenProvider token;
    private final Provisioner provisioner;

    public ServiceGarbageCollector(ScheduledExecutorService executorService, UUID serviceGuid,
            CloudController cloudController, TokenProvider token, Provisioner provisioner) {
        this.serviceGuid = serviceGuid;
        this.cloudController = cloudController;
        this.token = token;
        this.provisioner = provisioner;
        executorService.scheduleWithFixedDelay(new Runnable() {
            @Override
            public void run() {
                collect();
            }
        }, COLLECTION_RATE, COLLECTION_RATE, TimeUnit.MILLISECONDS);
    }

    protected void collect() {
        // Get all service instances known by service gateway
        final Iterable<String> knownInstanceIds = provisioner.serviceInstanceIds();
        if (knownInstanceIds == null) {
            return;
        }
        LOGGER.info("Checking for orphaned service instances");
        final Set<String> serviceInstanceIds = new HashSet<>();
        for (String serviceId : knownInstanceIds) {
            serviceInstanceIds.add(serviceId);
        }

        // Iterate over all service instances and remove ids known by Cloud Controller
        final RestCollection<ServicePlan> servicePlans = cloudController.getServicePlans(token.get(),
                CloudController.ServicePlanQueryAttribute.SERVICE_GUID, serviceGuid.toString());
        for (Resource<ServicePlan> servicePlan : servicePlans) {
            LOGGER.debug("Loading service instances under service plan '{}'", servicePlan.getEntity().getName());
            final RestCollection<ServiceInstance> serviceInstances = cloudController.getServiceInstances(
                    token.get(), CloudController.ServiceInstanceQueryAttribute.SERVICE_PLAN_GUID,
                    servicePlan.getGuid().toString());
            for (Resource<ServiceInstance> serviceInstance : serviceInstances) {
                final JsonNode gatewayData = serviceInstance.getEntity().getGatewayData();
                final String serviceInstanceId = gatewayData.get(ServiceBroker.SERVICE_INSTANCE_ID).asText();

                final boolean removed = serviceInstanceIds.remove(serviceInstanceId);
                if (removed) {
                    collectBindings(serviceInstance, serviceInstanceId);
                } else {
                    LOGGER.warn(
                            "Service instance {} in space {} is in the Cloud Controller but is not known by the broker",
                            serviceInstance.getEntity().getName(), serviceInstance.getEntity().getSpaceGuid());
                }
            }
        }

        if (serviceInstanceIds.size() > 0) {
            LOGGER.info("Found {} orphaned service instance(s) to be removed.");
            for (String instanceId : serviceInstanceIds) {
                try {
                    provisioner.removeOrphanedServiceInstance(instanceId);
                } catch (Exception e) {
                    LOGGER.error("Error removing service instance with id " + instanceId, e);
                }
            }
        }
    }

    private void collectBindings(Resource<ServiceInstance> serviceInstance, String serviceInstanceId) {
        final Iterable<String> knownBindingIds = provisioner.bindingIds(serviceInstanceId);
        if (knownBindingIds == null) {
            return;
        }
        final Set<String> bindingIds = new HashSet<>();
        for (String bindingId : knownBindingIds) {
            bindingIds.add(bindingId);
        }
        final RestCollection<ServiceBinding> serviceBindings = cloudController.getServiceBindings(token.get(),
                CloudController.ServiceBindingQueryAttribute.SERVICE_INSTANCE_GUID,
                serviceInstance.getGuid().toString());
        for (Resource<ServiceBinding> serviceBinding : serviceBindings) {
            final String bindingId = serviceBinding.getEntity().getGatewayData()
                    .get(ServiceBroker.SERVICE_BINDING_ID).asText();
            final boolean removed = bindingIds.remove(bindingId);
            if (!removed) {
                LOGGER.warn(
                        "Service binding {} for service {} is in the Cloud Controller but is not known by the broker",
                        bindingId, serviceInstanceId);
            }
        }

        if (bindingIds.size() > 0) {
            LOGGER.info("Found {} orphaned binding(s) for service instance {}", bindingIds, serviceInstanceId);
            for (String bindingId : bindingIds) {
                try {
                    LOGGER.debug("Removing binding {} for service instance {}", bindingId, serviceInstanceId);
                    provisioner.removeOrphanedBinding(serviceInstanceId, bindingId);
                } catch (Exception e) {
                    LOGGER.error("Error removing orphaned binding with id '" + bindingId + "' for service instance "
                            + serviceInstanceId, e);
                }
            }
        }

    }

}