source: fedd/abac-src/ttg/process/StingyStrategy.java @ 2f14616

version-1.30
Last change on this file since 2f14616 was 8780cbec, checked in by Jay Jacobs <Jay.Jacobs@…>, 15 years ago

ABAC sources from Cobham

  • Property mode set to 100644
File size: 11.7 KB
Line 
1package com.nailabs.abac.process;
2
3import edu.stanford.peer.rbtm.credential.*;
4import com.nailabs.abac.trust.*;
5import com.nailabs.abac.test.*;
6import java.util.*;
7/**
8 * The strategy handles processing a working list of nodes in the trust target
9 * graph to be processed. This version uses a combination of heuristics with
10 * a depth first search method.
11 */
12public class StingyStrategy extends Strategy {
13    /** A queue for operations which need to delay */
14    protected Hashtable delayedOps = new Hashtable();
15   
16    /**
17     * A list of sibling children of the current node being processed. Note,
18     * this is an ordered stack. Node operations are added the bottom of the
19     * stack and implication edges are added to the top.
20     */
21    protected Vector siblings = new Vector();
22
23    /** The current node being processed. Null if no local processing. */
24    protected TTGNode current = null;
25   
26    /** Is this strategy currently processing locally? */
27    protected boolean isLocal = false;
28
29    /**
30     * A threshold for determining when isDone is high enough
31     */
32    public int threshold = 0;
33
34    public float successWeight = 0.0f;
35
36    public CountTable weights = null;
37
38    /** A count of how many criteria have been met for ending a turn */
39    protected int isDone = 0;
40
41    /** Check to see if  already saved weights, which should only occur once */
42    private boolean isSaved = false;
43
44    /** create a new stingy strategy instance */
45    public StingyStrategy(NegotiationContext conf, Properties props) {
46        super(conf);
47        try {
48            if(props.containsKey("successWeight")) {
49                successWeight = 
50                Float.parseFloat(props.getProperty("successWeight"));
51            }
52            if(props.containsKey("weightFile")) {
53                weights = new CountTable(props.getProperty("weightFile"));
54            } else {
55                weights = new CountTable("weights." + context.getSelf());
56            }
57            if(props.containsKey("init")) {
58                weights.INIT = 
59                    Float.parseFloat(props.getProperty("init"));
60            }
61            if(props.containsKey("sat")) {
62                weights.SAT = 
63                    Float.parseFloat(props.getProperty("sat"));
64            }
65            if(props.containsKey("training")) {
66                if(props.getProperty("training").equalsIgnoreCase("true")) {
67                    isSaved = false;
68                } else {
69                    isSaved = true;
70                }
71            }
72        } catch(Exception ex) {
73            ex.printStackTrace();
74        }
75    }
76
77    /**
78     * The stingy strategy needs to save weights when the primary trust target
79     * is satisfied. This is method tests the predicate and saves the weight
80     * states as a side effect.
81     */
82    public int getSatisfactionState() {
83        int state = super.getSatisfactionState();
84        if(state == SatisfactionState.UNKNOWN) {
85            return state;
86        }
87        if(isSaved) {
88            return state;
89        } 
90        isSaved = true;
91        Iterator i = context.getGraph().getNodes();
92        while(i.hasNext()) {
93            TTGNode node = (TTGNode)i.next();
94            EntityExpression expr = getWeightKey(node.getGoal());
95            if(node instanceof TargetNode) {
96                state = ((TargetNode)node).getSatisfactionValue();
97            } else {
98                continue;
99            }
100            if(state == SatisfactionState.SATISFIED) { // increment success
101                weights.addSatisfied(expr);
102            } else {
103                //if(state == SatisfactionState.FAILED) {   
104                //increment failure or unkown nodes
105                weights.addFailed(expr);
106            }
107        }
108        debug("strategy", "Saving weights for " + context.getSelf());
109        weights.save("weights." + context.getSelf());   
110        return state;
111    }
112   
113    /**
114     * Notify the strategy that a new edge needs to be added to the graph.
115     * The strategy is responsible for performing the operation on the graph,
116     * whether the strategy chooses to  defer the operation or not.
117     */
118    public void scheduleOperation(Operation op) {
119        if(!isLocal) {          // process remote operations directly
120            super.scheduleOperation(op);
121            return;
122        }
123        if(op instanceof NodeOperation) { // add node op to end of vector
124            siblings.add(op);
125        } else if(op instanceof ImplicationEdge) { // add  to front of vector
126            //linking implication edges should be performed NOW
127            if(op instanceof LinkingImplicationEdge) { 
128                super.scheduleOperation(op);
129                siblings.remove(op);
130            } else {
131                siblings.add(0, op);
132            }
133        } else {                // perform the operation immediately
134            super.scheduleOperation(op); 
135            siblings.remove(op);
136        }
137    }
138
139    /** Notify this strategy that a control child has been satisfied */
140    public void addSatisfiedControlChild(TTGNode node) {
141        Goal g = (Goal)node.getGoal();
142        Entity v = g.getVerifier();
143        if(!context.getSelf().equals(v)) {
144            //weights.addSatisfied(getWeightKey(g));
145            isDone++;
146        }
147    }
148
149    /** Notify this strategy that a new node has been added to the graph */
150    public void addNewNode(TTGNode node) {
151        if(!isLocal)return;
152        ProcessingState state = node.getProcessingState();
153        Entity v = node.getGoal().getVerifier();
154        if(context.getSelf().equals(v) && state.isVerifierProcessed()) {
155            //increment the isDone counter
156            isDone++;
157        }
158        debug("strategy", "node  = " + node.getGoal());
159        debug("strategy", "isDone = " + isDone);
160    }
161
162    /** iterate through the work list until it is empty */
163    public void iterate() {
164        isDone = 0;
165        while(true) {
166            debug("strategy", "beginning iteratiion");
167            super.iterate();
168            if(okToEndTurn()) {
169                debug("strategy", "ending turning now!");
170                return;
171            }
172            debug("strategy", "processing the delayed queue");
173            processDelayedOps();
174        }
175    }
176
177    /** utility function for getting the target expression out of a goal */
178    protected EntityExpression getWeightKey(Goal g) {
179        EntityExpression key = null;
180        if(g instanceof LinkingGoal) {
181            String roleName = 
182                ((LinkingGoal)g).getTargetRoleName().toString();
183            key = new Role("?X", roleName);
184        }
185        if(g instanceof TrustTarget) {
186            key = ((TrustTarget)g).getTargetRole();
187        }
188        return key;
189    }
190
191    /** Note the beginning of a new parent node being processed */
192    protected void setCurrentParent(TTGNode parent) {
193        //initialize the state variables
194        siblings = new Vector();
195        current = parent;
196        isLocal = true;
197        //isDone = 0;
198    }
199
200    /** Process all the nodes in the delayed queue */
201    protected void processDelayedOps() {
202        Iterator i = delayedOps.values().iterator();
203        while(i.hasNext()) {
204            Vector s = (Vector)i.next();
205            while(!s.isEmpty()) {
206                debug("strategy", "performing delayed op = " + s.get(0)); 
207                super.scheduleOperation((Operation)s.remove(0));
208            }
209            i.remove();
210        }
211    }
212
213    /** Note the conclusion of a new parent node being processed */
214    protected void scheduleOperationsForNode(TTGNode parent) {
215        Entity v = parent.getVerifier();
216        int doCount = 0;
217
218        // if self is not parent's verifier, perform all the operations now
219        if(!context.getSelf().equals(v)) {
220            while(!siblings.isEmpty()) {
221                super.scheduleOperation((Operation)siblings.remove(0));
222            }
223            current = null;
224            isLocal = false;
225            return;
226        }
227        // If the verifier finds itself processing a node it has already
228        // processed, it will not add any more operations on that node
229        // (this node has been fully processed; therefore, the delayed
230        //  operations can be ignored.)
231        if(delayedOps.containsKey(current.getGoal())) {
232            debug("strategy", "Already processed node " + current.getGoal());
233            debug("strategy", "siblings = " + siblings);
234            siblings = new Vector(); // potential memory leak--should be gc'ed
235            current = null;
236            isLocal = false;
237            return;
238        }
239        //otherwise perform at least one child
240        Iterator i = siblings.iterator();
241        while(i.hasNext()) {
242            Operation op = (Operation)i.next();
243
244            if(op instanceof ImplicationEdge) {
245                Goal g = ((EdgeOperation)op).getChild();
246                // embedded decision making heuristics
247                if(weights.getWeight(getWeightKey(g)) < successWeight) {
248                    //do nothing to delay the operation
249                    //super.scheduleOperation(op);                     
250                } else {
251                    super.scheduleOperation(op); 
252                    i.remove();
253                    doCount += 1;
254                }
255            }
256        }
257        // If no edges have been added, take the first implication edge (if
258        // any) and perform it.
259        i = siblings.iterator();
260        while(doCount == 0 && i.hasNext()) { // the while is redundant
261            // node operations are processed in the next loop below
262            Operation op = (Operation)i.next();
263            if(op instanceof ImplicationEdge) {
264                super.scheduleOperation(op);
265                i.remove();
266                doCount += 1;
267            }
268        }
269        //if there are no remaining edge operations, then perform the
270        //remaining node operation (to mark as processed).
271        //check for delayed ops and determine whether it's ok to add node op
272        if(!siblings.isEmpty()) {
273            if(siblings.get(0) instanceof NodeOperation) { 
274                // if all edges are done
275                NodeOperation nodeOp = (NodeOperation)siblings.remove(0);
276                super.scheduleOperation(nodeOp);       
277            }
278        }
279        //put the remaining child edges in the delayed queue
280        Goal g = current.getGoal();
281        if(!siblings.isEmpty()) {
282            delayedOps.put(g, siblings);
283        }
284        //clean up the state variables
285        current = null;
286        isLocal = false;
287    }
288
289    /** criteria for determining when to end this negotiators turn */
290    protected boolean okToEndTurn() {
291        // isDone = 0; // used this to check that delayedOps is really empty
292        // if there are no more delayed op's, then end this negotiator's turn
293        if(delayedOps.isEmpty()) {
294            isDone++;         
295        }
296        //if the negotiation has suceeded or failed, then return true
297        if(getSatisfactionState() != SatisfactionState.UNKNOWN) {
298            isDone++;
299        }
300        //if the threshold for end-turn criteria has been met then return true
301        if(isDone > threshold) {
302            return true;
303        }
304        // the end-turn criteria have not been met
305        return false;
306    }
307
308    /**
309     * convenience method for determining whether this negotiator has
310     * a deadlock in processing the negotiation. This method can be
311     * overridden is subsequent versions.
312     */
313    protected boolean isStuck() {
314        // if there's no history, we cannot be stuck yet
315        if(super.isStuck()) {
316            if(lastMessage != null) {
317                // if both messages contain no changes,
318                //then a deadlock has occurred
319                return (lastMessage.getOperationsCount() == 0 );
320            }
321        }
322        return false;
323   }
324
325
326
327}
Note: See TracBrowser for help on using the repository browser.