/******************************************************************************* * * Copyright (c) 2012 GigaSpaces Technologies Ltd. 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 org.openspaces.grid.gsm.containers; import java.util.HashMap; import java.util.Map; import org.openspaces.admin.Admin; import org.openspaces.admin.pu.ProcessingUnit; import org.openspaces.grid.gsm.sla.ServiceLevelAgreementEnforcement; import org.openspaces.grid.gsm.sla.exceptions.ServiceLevelAgreementEnforcementEndpointAlreadyExistsException; /** * Starts and shutdowns grid service container based on the requested {@link ContainersSlaPolicy} * * Use {@link #createEndpoint(ProcessingUnit)} to enforce an SLA for a specific container zone. * * @see ContainersSlaEnforcementEndpoint * @see ContainersSlaPolicy * @author itaif */ public class ContainersSlaEnforcement implements ServiceLevelAgreementEnforcement<ContainersSlaEnforcementEndpoint> { private final ContainersSlaEnforcementState state; private final Map<ProcessingUnit, ContainersSlaEnforcementEndpoint> endpoints; public ContainersSlaEnforcement(Admin admin) { this.endpoints = new HashMap<ProcessingUnit, ContainersSlaEnforcementEndpoint>(); this.state = new ContainersSlaEnforcementState(); } /** * * @return a service that continuously maintains the specified number of containers for the * specified pu. */ public ContainersSlaEnforcementEndpoint createEndpoint(final ProcessingUnit pu) throws ServiceLevelAgreementEnforcementEndpointAlreadyExistsException { if (!isEndpointDestroyed(pu)) { throw new IllegalStateException("Cannot initialize a new ContainersSlaEnforcementEndpoint for pu " + pu.getName() + " since an endpoint for the pu already exists."); } ProcessingUnit otherPu1 = ContainersSlaUtils.findProcessingUnitWithSameName(endpoints.keySet(), pu); if (otherPu1 != null) { throw new IllegalStateException("Cannot initialize a new ContainersSlaEnforcementEndpoint for pu " + pu.getName() + " since an endpoint for a pu with the same name already exists."); } ProcessingUnit otherPu2 = ContainersSlaUtils.findProcessingUnitWithSameZone(endpoints.keySet(), pu); if (otherPu2 != null) { throw new IllegalStateException("Cannot initialize a new ContainersSlaEnforcementEndpoint for pu " + pu.getName() + " since an endpoint for a pu with the same (containers) zone already exists: " + otherPu2.getName()); } ContainersSlaEnforcementEndpoint endpoint = new DefaultContainersSlaEnforcementEndpoint(pu, state); endpoints.put(pu, endpoint); state.initProcessingUnit(pu); return endpoint; } public void destroyEndpoint(ProcessingUnit pu) { state.destroyProcessingUnit(pu); endpoints.remove(pu); } public void destroy() { for (ProcessingUnit pu : endpoints.keySet()) { destroyEndpoint(pu); } } private boolean isEndpointDestroyed(ProcessingUnit pu) { if (pu == null) { throw new IllegalArgumentException("pu cannot be null"); } return !endpoints.containsKey(pu) || state.isProcessingUnitDestroyed(pu); } }