Skip to content

Commit

Permalink
pongasoft#71: fixed bounce plan
Browse files Browse the repository at this point in the history
turned out to be quite complicated to fix.. handle transitions has a set of deltas but issues was to generate the correct
delta in the first place!
  • Loading branch information
ypujante committed Jun 16, 2011
1 parent 5575651 commit c2abc90
Show file tree
Hide file tree
Showing 31 changed files with 2,178 additions and 863 deletions.
Expand Up @@ -44,27 +44,37 @@ class DeltaServiceImpl implements DeltaService
@Initializable
boolean notRunningOverridesVersionMismatch = false

String prettyPrint(SystemModelDelta delta)
{
computeDeltaAsJSON([delta: delta, prettyPrint: true])
}

@Override
String computeDeltaAsJSON(def params)
{
SystemModel expectedModel = params.expectedModel
SystemModelDelta delta = params.delta

if(!expectedModel)
return null
if(!delta)
{
SystemModel expectedModel = params.expectedModel

if(!expectedModel)
return null

SystemModel currentModel = params.currentModel
SystemModel currentModel = params.currentModel

if(currentModel == null)
{
Fabric fabric = fabricService.findFabric(expectedModel.fabric)
if(currentModel == null)
{
Fabric fabric = fabricService.findFabric(expectedModel.fabric)

if(!fabric)
throw new IllegalArgumentException("unknown fabric ${expectedModel.fabric}")
if(!fabric)
throw new IllegalArgumentException("unknown fabric ${expectedModel.fabric}")

currentModel = agentsService.getCurrentSystemModel(fabric)
}
currentModel = agentsService.getCurrentSystemModel(fabric)
}

SystemModelDelta delta = deltaMgr.computeDelta(expectedModel, currentModel)
delta = deltaMgr.computeDelta(expectedModel, currentModel)
}

boolean flatten = params.flatten?.toString() == "true"

Expand Down Expand Up @@ -102,7 +112,7 @@ class DeltaServiceImpl implements DeltaService

// build map for json
map = [
accuracy: currentModel.metadata.accuracy,
accuracy: delta.currentSystemModel.metadata.accuracy,
delta: map
]

Expand Down
Expand Up @@ -21,7 +21,6 @@ package org.linkedin.glu.orchestration.engine.planner
import org.linkedin.glu.orchestration.engine.action.descriptor.ActionDescriptor
import org.linkedin.glu.orchestration.engine.agents.AgentsService
import org.linkedin.glu.orchestration.engine.delta.DeltaMgr
import org.linkedin.glu.orchestration.engine.delta.SystemModelDelta
import org.linkedin.glu.orchestration.engine.fabric.Fabric
import org.linkedin.glu.orchestration.engine.fabric.FabricService
import org.linkedin.glu.provisioner.core.model.SystemEntry
Expand Down Expand Up @@ -57,9 +56,7 @@ class PlannerServiceImpl implements PlannerService
*/
Collection<Plan<ActionDescriptor>> computeDeployPlans(params, def metadata)
{
computeDeploymentPlans(params, metadata) { Type type, SystemModelDelta delta ->
planner.computeDeploymentPlan(type, delta)
}
computeDeploymentPlans(params, metadata, null)
}

@Override
Expand All @@ -81,9 +78,9 @@ class PlannerServiceImpl implements PlannerService
*/
private Collection<Plan<ActionDescriptor>> computeDeploymentPlans(params,
def metadata,
Closure closure)
Collection<String> toStates)
{
computeDeploymentPlans(params, metadata, null, null, closure)
computeDeploymentPlans(params, metadata, null, null, toStates)
}

/**
Expand All @@ -100,7 +97,7 @@ class PlannerServiceImpl implements PlannerService
def metadata,
def expectedModelFilter,
def currentModelFiter,
Closure closure)
Collection<String> toStates)
{
SystemModel expectedModel = params.system

Expand All @@ -120,7 +117,7 @@ class PlannerServiceImpl implements PlannerService
if(currentModelFiter)
currentModel = currentModel.filterBy(currentModelFiter)

computeDeploymentPlans(params, expectedModel, currentModel, metadata, closure)
computeDeploymentPlans(params, expectedModel, currentModel, metadata, toStates)
}

/**
Expand All @@ -137,10 +134,17 @@ class PlannerServiceImpl implements PlannerService
SystemModel expectedModel,
SystemModel currentModel,
def metadata,
Closure closure)
Collection<String> toStates)
{
// 1. compute delta between expectedModel and currentModel
SystemModelDelta delta = deltaMgr.computeDelta(expectedModel, currentModel)
// 1. compute delta
def delta
if(toStates)
delta = deltaMgr.computeDeltas(expectedModel, currentModel, toStates)
else
delta = deltaMgr.computeDelta(expectedModel, currentModel)

// 2. compute the transition plan
TransitionPlan<ActionDescriptor> transitionPlan = planner.computeTransitionPlan(delta)

Collection<Type> types = []
if(params.type)
Expand All @@ -152,10 +156,10 @@ class PlannerServiceImpl implements PlannerService
metadata = [:]

types.collect { Type type ->
// 2. compute the deployment plan for the delta (and the given type)
Plan<ActionDescriptor> plan = closure(type, delta)
// 3. compute the deployment plan the given type
Plan<ActionDescriptor> plan = transitionPlan.buildPlan(type)

// 3. set name and metadata for the plan
// 4. set name and metadata for the plan
plan.setMetadata('fabric', expectedModel.fabric)
plan.setMetadata('systemId', expectedModel.id)
plan.setMetadata(metadata)
Expand Down Expand Up @@ -183,9 +187,7 @@ class PlannerServiceImpl implements PlannerService
*/
Collection<Plan<ActionDescriptor>> computeTransitionPlans(params, def metadata)
{
computeDeploymentPlans(params, metadata) { Type type, SystemModelDelta delta ->
planner.computeTransitionPlan(type, delta, [params.state])
}
computeDeploymentPlans(params, metadata, [params.state])
}

@Override
Expand All @@ -209,9 +211,8 @@ class PlannerServiceImpl implements PlannerService
computeDeploymentPlans(params,
metadata,
null,
bounceCurrentModelFilter) { Type type, SystemModelDelta delta ->
planner.computeTransitionPlan(type, delta, ['stopped', 'running'])
}
bounceCurrentModelFilter,
['stopped', 'running'])
}

@Override
Expand All @@ -227,9 +228,7 @@ class PlannerServiceImpl implements PlannerService
*/
Collection<Plan<ActionDescriptor>> computeUndeployPlans(params, def metadata)
{
computeDeploymentPlans(params, metadata) { Type type, SystemModelDelta delta ->
planner.computeTransitionPlan(type, delta, [null])
}
computeDeploymentPlans(params, metadata, [null])
}

@Override
Expand All @@ -254,9 +253,8 @@ class PlannerServiceImpl implements PlannerService
computeDeploymentPlans(params,
metadata,
null,
redeployCurrentModelFilter) { Type type, SystemModelDelta delta ->
planner.computeTransitionPlan(type, delta, [null, '<expected>'])
}
redeployCurrentModelFilter,
[null, '<expected>'])
}

@Override
Expand Down Expand Up @@ -306,9 +304,8 @@ class PlannerServiceImpl implements PlannerService
toSinglePlan(computeDeploymentPlans(params,
expectedModel,
currentModel,
metadata) { Type type, SystemModelDelta delta ->
planner.computeTransitionPlan(type, delta, ['<expected>', null])
})
metadata,
['<expected>', null]))
}

private def agentsCleanupUpgradeExpectedModelFilter = { SystemEntry entry ->
Expand All @@ -326,9 +323,8 @@ class PlannerServiceImpl implements PlannerService
toSinglePlan(computeDeploymentPlans(params,
metadata,
agentsCleanupUpgradeExpectedModelFilter,
null) { Type type, SystemModelDelta delta ->
planner.computeDeploymentPlan(type, delta)
})
null,
null))
}

protected Plan<ActionDescriptor> toSinglePlan(Collection<Plan<ActionDescriptor>> plans)
Expand Down
Expand Up @@ -18,10 +18,25 @@

import org.linkedin.glu.provisioner.core.model.SystemModel;

import java.util.Collection;

/**
* @author yan@pongasoft.com
*/
public interface DeltaMgr
{
/**
* Computes the delta between the 2 models
*/
SystemModelDelta computeDelta(SystemModel expectedModel, SystemModel currentModel);

/**
* Computes N deltas to go from state to state. If <code>state==null</code> it means empty
* system, if <code>state==<expected></code> it means <code>expectedModel</code>.
*
* @return a collection of deltas (same size as <code>toStates</code>)
*/
Collection<SystemModelDelta> computeDeltas(SystemModel expectedModel,
SystemModel currentModel,
Collection<String> toStates);
}
@@ -0,0 +1,110 @@
/*
* Copyright (c) 2011 Yan Pujante
*
* 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.linkedin.glu.orchestration.engine.delta.impl;

import org.linkedin.glu.provisioner.core.model.SystemFilter;
import org.linkedin.glu.provisioner.core.model.SystemModel;

import java.util.HashSet;
import java.util.Set;

/**
* @author yan@pongasoft.com
*/
public class DeltaBuilder
{
protected final SystemModel _filteredExpectedModel;
protected final SystemModel _filteredCurrentModel;

private Set<String> _filteredKeys;

/**
* Constructor
*/
public DeltaBuilder(SystemModel filteredExpectedModel,
SystemModel filteredCurrentModel)
{
_filteredExpectedModel = filteredExpectedModel;
_filteredCurrentModel = filteredCurrentModel;
}

public SystemModel getFilteredCurrentModel()
{
return _filteredCurrentModel;
}

public SystemModel getFilteredExpectedModel()
{
return _filteredExpectedModel;
}

public Set<String> getFilteredKeys()
{
if(_filteredKeys == null)
_filteredKeys = computeFilteredKeys(_filteredExpectedModel, _filteredCurrentModel);

return _filteredKeys;
}

public void setFilteredKeys(Set<String> filteredKeys)
{
_filteredKeys = filteredKeys;
}

/**
* Compute the set of keys that will be part of the delta: the filters set on the model will
* be used as filter
*/
public static Set<String> computeFilteredKeys(SystemModel filteredExpectedModel,
SystemModel filteredCurrentModel)
{
Set<String> keys = new HashSet<String>();

SystemFilter currentModelFilters = filteredCurrentModel.getFilters();
SystemFilter expectedModelFilters = filteredExpectedModel.getFilters();

// 1. we make sure to exclude all entries from the current model where that were filtered
// out from the expected model
filteredCurrentModel = filteredCurrentModel.filterBy(expectedModelFilters);
Set<String> currentKeys = filteredCurrentModel.getKeys(new HashSet<String>());

// 2. we make sure to exclude all entries from the expected model where that were filtered
// out from the current model
filteredExpectedModel = filteredExpectedModel.filterBy(currentModelFilters);
Set<String> expectedKeys = filteredExpectedModel.getKeys(new HashSet<String>());

// if a filter was provided for the current model then we take only the keys from the
// current model (excluding the one not in the expected model!)
if(currentModelFilters != null)
{
for(String key : currentKeys)
{
if(expectedKeys.contains(key))
keys.add(key);
}
}
else
{
// otherwise we take keys from both
keys.addAll(currentKeys);
keys.addAll(expectedKeys);
}

return keys;
}

}

0 comments on commit c2abc90

Please sign in to comment.