Permalink
Browse files

#260: added max parallel steps count

  • Loading branch information...
ypujante committed Mar 14, 2014
1 parent d94b7ac commit 9d9759ac5672bad2db5ed716eb065250ee181f9a
Showing with 386 additions and 83 deletions.
  1. +3 −1 ....console-webapp/grails-app/controllers/org/linkedin/glu/console/controllers/PlanController.groovy
  2. +2 −1 console/org.linkedin.glu.console-webapp/grails-app/views/agents/plans.gsp
  3. +2 −1 console/org.linkedin.glu.console-webapp/grails-app/views/dashboard/plans.gsp
  4. +7 −2 console/org.linkedin.glu.console-webapp/grails-app/views/plan/_selectPlan.gsp
  5. +56 −0 console/org.linkedin.glu.console-webapp/web-app/js/plan.js
  6. +32 −29 docs/manual/src/main/sphinx/source/orchestration-engine.rst
  7. +7 −2 ...on-engine/src/main/groovy/org/linkedin/glu/orchestration/engine/planner/PlannerServiceImpl.groovy
  8. +3 −2 ...hestration-engine/src/main/java/org/linkedin/glu/orchestration/engine/planner/TransitionPlan.java
  9. +4 −3 ...ne/src/main/java/org/linkedin/glu/orchestration/engine/planner/impl/MultiDeltaTransitionPlan.java
  10. +3 −2 ...stration-engine/src/main/java/org/linkedin/glu/orchestration/engine/planner/impl/PlannerImpl.java
  11. +4 −3 ...e/src/main/java/org/linkedin/glu/orchestration/engine/planner/impl/SingleDeltaTransitionPlan.java
  12. +8 −7 ...n-engine/src/main/java/org/linkedin/glu/orchestration/engine/planner/impl/TransitionPlanImpl.java
  13. +4 −3 ...glu.orchestration-engine/src/test/groovy/test/orchestration/engine/planner/TestPlannerImpl.groovy
  14. +69 −1 ....orchestration-engine/src/test/groovy/test/orchestration/engine/planner/TestPlannerService.groovy
  15. +16 −2 ...u.provisioner-core/src/main/groovy/org/linkedin/glu/provisioner/core/plan/impl/StepBuilder.groovy
  16. +25 −8 ...lu.provisioner-core/src/main/java/org/linkedin/glu/provisioner/plan/api/CompositeStepBuilder.java
  17. +2 −1 ...isioner-core/src/main/java/org/linkedin/glu/provisioner/plan/api/CompositeStepBuilderVisitor.java
  18. +6 −0 ...nkedin.glu.provisioner-core/src/main/java/org/linkedin/glu/provisioner/plan/api/IPlanBuilder.java
  19. +42 −5 ...glu.provisioner-core/src/main/java/org/linkedin/glu/provisioner/plan/api/ParallelStepBuilder.java
  20. +33 −5 ...r/org.linkedin.glu.provisioner-core/src/main/java/org/linkedin/glu/provisioner/plan/api/Plan.java
  21. +6 −4 ...inkedin.glu.provisioner-core/src/main/java/org/linkedin/glu/provisioner/plan/api/PlanBuilder.java
  22. +3 −1 ...u.provisioner-core/src/main/java/org/linkedin/glu/provisioner/plan/api/SequentialStepBuilder.java
  23. +49 −0 .../org.linkedin.glu.provisioner-core/src/test/groovy/test/provisioner/core/plan/impl/TestXml.groovy
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2010-2010 LinkedIn, Inc
* Portions Copyright (c) 2011-2013 Yan Pujante
* Portions Copyright (c) 2011-2014 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
@@ -182,6 +182,7 @@ public class PlanController extends ControllerBase
{
args = JsonUtils.fromJSON(params.json)
}
args.maxParallelStepsCount = params.maxParallelStepsCount
def system
@@ -388,6 +389,7 @@ public class PlanController extends ControllerBase
def args = [:]
args.system = request.system
args.fabric = request.fabric
args.maxParallelStepsCount = params.maxParallelStepsCount
try
{
@@ -1,5 +1,5 @@
%{--
- Copyright (c) 2011-2013 Yan Pujante
- Copyright (c) 2011-2014 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
@@ -36,6 +36,7 @@
display: none;
}
</style>
<script type="text/javascript" src="${resource(dir:'js',file:'plan.js')}"></script>
</head>
<body>
<g:if test="${agent}">
@@ -1,5 +1,5 @@
%{--
- Copyright (c) 2011-2013 Yan Pujante
- Copyright (c) 2011-2014 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
@@ -34,6 +34,7 @@
display: none;
}
</style>
<script type="text/javascript" src="${resource(dir:'js',file:'plan.js')}"></script>
</head>
<body>
<ul class="nav nav-tabs">
@@ -1,5 +1,5 @@
%{--
- Copyright (c) 2011-2013 Yan Pujante
- Copyright (c) 2011-2014 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
@@ -34,11 +34,16 @@
<td>${plan.displayName ?: plan.planType.capitalize()}</td>
<g:each in="${['SEQUENTIAL', 'PARALLEL']}" var="stepType">
<td>${stepType}</td>
<td><input type="radio" name="planDetails" value="${JsonUtils.compactPrint([*:plan, stepType: stepType, name: (plan.displayName ?: plan.planType.capitalize()) + ' - ' + title, systemFilter: filter]).encodeAsHTML()}" onclick="${remoteFunction(controller: 'plan', action:'create', update:[success:'plan-preview'], params: "'fabric=${request.fabric.name.encodeAsHTML()}&json=' + this.value")}" /></td>
<td><input type="radio" name="planDetails" value="${JsonUtils.compactPrint([*:plan, stepType: stepType, name: (plan.displayName ?: plan.planType.capitalize()) + ' - ' + title, systemFilter: filter]).encodeAsHTML()}" onclick="createPlan('${request.fabric.name}', '${g.createLink(controller: "plan", action: "create")}');" /></td>
</g:each>
</tr>
</g:if>
</g:each>
<tr>
<td colspan="6" style="text-align: center;">
Max Parallel Steps Count = <g:textField class="input-small" name="maxParallelStepsCount" onchange="createPlan('${request.fabric.name}', '${g.createLink(controller: "plan", action: "create")}');"/>
</td>
</tr>
<tr>
<td colspan="6" style="text-align: center;">
<input class="btn btn-primary" type="submit" name="view" value="Select this plan" onClick="document.getElementById('planIdSelector').value=document.getElementById('planId').value;return true;">
@@ -0,0 +1,56 @@
/*
* Copyright (c) 2014 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.
*/
/**
* Execute rest call to create the plan
*/
function createPlan(fabric,
url,
selectedPlanInputName,
maxParallelStepsCountSelector,
planPreviewSelector)
{
selectedPlanInputName = selectedPlanInputName || 'planDetails';
maxParallelStepsCountSelector = maxParallelStepsCountSelector || '#maxParallelStepsCount';
planPreviewSelector = planPreviewSelector || '#plan-preview';
var ajaxData = {
fabric: fabric
};
// first the selected plan
var planDetails = $('input[name=' + selectedPlanInputName + ']:checked').val();
if(planDetails)
ajaxData.json = planDetails;
else
return; // nothing selected yet...
var maxParallelStepsCount = parseInt($(maxParallelStepsCountSelector).val());
if(isNaN(maxParallelStepsCount))
maxParallelStepsCount = 0;
if(maxParallelStepsCount > 0)
ajaxData.maxParallelStepsCount = maxParallelStepsCount;
$.ajax({
type: 'POST',
data: ajaxData,
url: url,
success:function(data,textStatus){ $(planPreviewSelector).html(data);},
error:function(XMLHttpRequest,textStatus,errorThrown){}
});
}
@@ -1,4 +1,4 @@
.. Copyright (c) 2011-2013 Yan Pujante
.. Copyright (c) 2011-2014 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
@@ -1710,34 +1710,37 @@ The ``POST`` you issue must be of Content-Type ``application/x-www-form-urlencod
The body then contains a query string with the following parameters:
+--------------------+----------------------+--------------------+-----------------------------------------------------+
|name |value |required |example |
+--------------------+----------------------+--------------------+-----------------------------------------------------+
|``planAction`` |``start``, ``stop``, |One of |``planAction=start`` |
| |``bounce``, |``planAction`` or | |
| |``deploy``, |``planType`` | |
| |``undeploy``, | | |
| |``redeploy`` | | |
+--------------------+----------------------+--------------------+-----------------------------------------------------+
|``planType`` |``deploy``, |One of |``planType=transition&state=stopped`` |
| |``undeploy``, |``planAction`` or | |
| |``redeploy``, |``planType`` | |
| |``bounce``, | | |
| |``transition`` or | | |
| |anything custom | | |
| | | | |
+--------------------+----------------------+--------------------+-----------------------------------------------------+
|``systemFilter`` |a system filter as |No. It simply means |``systemFilter=and%7bagent%3d'ei2-app3-zone5.qa'%7d``|
| |described in the |don't filter at all.| |
| |previous section | | |
| |(remember that it | | |
| |**must** be properly | | |
| |url encoded. | | |
| | | | |
+--------------------+----------------------+--------------------+-----------------------------------------------------+
|``order`` |``parallel`` or |No. Default to |``order=parallel`` |
| |``sequential`` |``sequential`` | |
+--------------------+----------------------+--------------------+-----------------------------------------------------+
+--------------------------+----------------------+--------------------+-----------------------------------------------------+
|name |value |required |example |
+--------------------------+----------------------+--------------------+-----------------------------------------------------+
|``planAction`` |``start``, ``stop``, |One of |``planAction=start`` |
| |``bounce``, |``planAction`` or | |
| |``deploy``, |``planType`` | |
| |``undeploy``, | | |
| |``redeploy`` | | |
+--------------------------+----------------------+--------------------+-----------------------------------------------------+
|``planType`` |``deploy``, |One of |``planType=transition&state=stopped`` |
| |``undeploy``, |``planAction`` or | |
| |``redeploy``, |``planType`` | |
| |``bounce``, | | |
| |``transition`` or | | |
| |anything custom | | |
| | | | |
+--------------------------+----------------------+--------------------+-----------------------------------------------------+
|``systemFilter`` |a system filter as |No. It simply means |``systemFilter=and%7bagent%3d'ei2-app3-zone5.qa'%7d``|
| |described in the |don't filter at all.| |
| |previous section | | |
| |(remember that it | | |
| |**must** be properly | | |
| |url encoded. | | |
| | | | |
+--------------------------+----------------------+--------------------+-----------------------------------------------------+
|``order`` |``parallel`` or |No. Default to |``order=parallel`` |
| |``sequential`` |``sequential`` | |
+--------------------------+----------------------+--------------------+-----------------------------------------------------+
|``maxParallelStepsCount`` |a positive integer |No. |``maxParallelStepsCount=2`` defines parallel plan |
| | | |with no more than 2 steps in parallel |
+--------------------------+----------------------+--------------------+-----------------------------------------------------+
.. note:: ``planAction=stop`` is equivalent to ``planType=transition&state=stopped``. The ``planType`` notation is more generic and should be used when using your own state machine or creating your own custom plan types (in which case you can also pass as many parameters as you want).
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2011-2013 Yan Pujante
* Copyright (c) 2011-2014 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
@@ -29,6 +29,7 @@ import org.linkedin.glu.provisioner.core.model.SystemEntry
import org.linkedin.glu.provisioner.core.model.SystemEntryStateSystemFilter
import org.linkedin.glu.provisioner.core.model.SystemFilter
import org.linkedin.glu.provisioner.core.model.SystemModel
import org.linkedin.glu.provisioner.plan.api.IPlanBuilder
import org.linkedin.glu.provisioner.plan.api.IStep.Type
import org.linkedin.glu.provisioner.plan.api.Plan
import org.linkedin.util.annotations.Initializable
@@ -168,9 +169,13 @@ class PlannerServiceImpl implements PlannerService
if(metadata == null)
metadata = [:]
def config = new IPlanBuilder.Config()
if(params.maxParallelStepsCount)
config.maxParallelStepsCount = params.maxParallelStepsCount as Integer
Collection<Plan<ActionDescriptor>> allPlans = types.collect { Type type ->
// 3. compute the deployment plan the given type
Plan<ActionDescriptor> plan = transitionPlan.buildPlan(type)
Plan<ActionDescriptor> plan = transitionPlan.buildPlan(type, config)
// 4. set name and metadata for the plan
plan.setMetadata('fabric', expectedModel.fabric)
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2011 Yan Pujante
* Copyright (c) 2011-2014 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
@@ -16,6 +16,7 @@
package org.linkedin.glu.orchestration.engine.planner;
import org.linkedin.glu.provisioner.plan.api.IPlanBuilder;
import org.linkedin.glu.provisioner.plan.api.IStep;
import org.linkedin.glu.provisioner.plan.api.Plan;
@@ -24,5 +25,5 @@
*/
public interface TransitionPlan<T>
{
public Plan<T> buildPlan(IStep.Type type);
public Plan<T> buildPlan(IStep.Type type, IPlanBuilder.Config config);
}
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2011 Yan Pujante
* Copyright (c) 2011-2014 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
@@ -18,6 +18,7 @@
import org.linkedin.glu.orchestration.engine.action.descriptor.ActionDescriptor;
import org.linkedin.glu.orchestration.engine.planner.TransitionPlan;
import org.linkedin.glu.provisioner.plan.api.IPlanBuilder;
import org.linkedin.glu.provisioner.plan.api.IStep;
import org.linkedin.glu.provisioner.plan.api.Plan;
@@ -58,13 +59,13 @@ public MultiDeltaTransitionPlan(Collection<SingleDeltaTransitionPlan> transition
@Override
public Plan<ActionDescriptor> buildPlan(IStep.Type type)
public Plan<ActionDescriptor> buildPlan(IStep.Type type, IPlanBuilder.Config config)
{
TransitionPlan<ActionDescriptor> transitionPlan = getTransitionPlan();
if(transitionPlan == null)
return null;
else
return transitionPlan.buildPlan(type);
return transitionPlan.buildPlan(type, config);
}
protected TransitionPlan<ActionDescriptor> buildTransitionPlan()
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2011 Yan Pujante
* Copyright (c) 2011-2014 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
@@ -25,6 +25,7 @@
import org.linkedin.glu.orchestration.engine.planner.TransitionPlan;
import org.linkedin.glu.orchestration.engine.planner.Planner;
import org.linkedin.glu.provisioner.core.model.SystemModel;
import org.linkedin.glu.provisioner.plan.api.IPlanBuilder;
import org.linkedin.glu.provisioner.plan.api.IStep;
import org.linkedin.glu.provisioner.plan.api.Plan;
import org.linkedin.util.annotations.Initializer;
@@ -100,7 +101,7 @@ public void setSkipMissingAgents(boolean skipMissingAgents)
if(transitionPlan == null)
return null;
return transitionPlan.buildPlan(type);
return transitionPlan.buildPlan(type, new IPlanBuilder.Config());
}
@Override
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2011 Yan Pujante
* Copyright (c) 2011-2014 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
@@ -23,6 +23,7 @@
import org.linkedin.glu.orchestration.engine.delta.impl.InternalSystemEntryDelta;
import org.linkedin.glu.orchestration.engine.delta.impl.InternalSystemModelDelta;
import org.linkedin.glu.orchestration.engine.planner.TransitionPlan;
import org.linkedin.glu.provisioner.plan.api.IPlanBuilder;
import org.linkedin.glu.provisioner.plan.api.IStep;
import org.linkedin.glu.provisioner.plan.api.Plan;
import org.linkedin.groovy.util.state.StateMachine;
@@ -160,9 +161,9 @@ public ActionDescriptorAdjuster getActionDescriptorAdjuster()
return firstTransitions;
}
public Plan<ActionDescriptor> buildPlan(IStep.Type type)
public Plan<ActionDescriptor> buildPlan(IStep.Type type, IPlanBuilder.Config config)
{
return getTransitionPlan().buildPlan(type);
return getTransitionPlan().buildPlan(type, config);
}
/**
Oops, something went wrong.

0 comments on commit 9d9759a

Please sign in to comment.