Skip to content

File MigrationAggregate.java

File List > behaviour > migration > MigrationAggregate.java

Go to the documentation of this file

package skydata.behaviour.migration;

import java.util.HashMap;
import java.util.Map;
import java.util.Random;

import jade.core.behaviours.CyclicBehaviour;
import jade.core.behaviours.TickerBehaviour;
import jade.lang.acl.ACLMessage;
import jade.lang.acl.MessageTemplate;
import skydata.internal.agents.SKAgent;
import skydata.internal.agents.SKD;
import skydata.internal.behaviours.SKAgentBehaviour;
import skydata.internal.message.SKAID;
import skydata.internal.message.SKLMessage;

public class MigrationAggregate extends SKAgentBehaviour {

    Random rand = new Random();

    String propertyName = "available";

    private SKD skd;

    public MigrationAggregate(SKAgent agent) {
        super(agent);
        skd = (SKD) agent;
    }

    @SuppressWarnings({ "rawtypes", "unchecked" })
    private SKAID select(HashMap<SKAID, HashMap<String, Comparable>> harboursStats, String property) {
        SKAID myH = skd.myHarbour();
        if (!harboursStats.containsKey(myH))
            return null;
        Comparable myValue = harboursStats.get(myH).get(property);
        if (myValue == null)
            return null;

        SKAID bestH = null;
        Comparable bestValue = null;
        for (Map.Entry<SKAID, HashMap<String, Comparable>> harbourStats : harboursStats.entrySet()) {
            if (!harbourStats.getKey().equals(myH)) {
                Comparable value = harbourStats.getValue().get(property);
                if (value.compareTo(myValue) < 0) {
                    if ((Integer) harbourStats.getValue().get(property) >= skd.size) {
                        if (bestH == null) {
                            bestValue = value;
                            bestH = harbourStats.getKey();
                        } else if (value.compareTo(bestValue) < 0) {
                            bestValue = value;
                            bestH = harbourStats.getKey();
                        }
                    }
                }

            }
        }
        return bestH;
    }

    @Override
    public void action() {
        SKD agent = (SKD) this.agent;
        @SuppressWarnings("rawtypes")
        HashMap<SKAID, HashMap<String, Comparable>> harboursStats = agent.getHarboursStats();

        // Regularly, we check if we can find a best harbour
        TickerBehaviour tickerBehaviour = new TickerBehaviour(agent, 10000) {
            @Override
            public void onTick() {
                SKAID harbour = select(harboursStats, propertyName);
                if (harbour == null)
                    return;// Available harbour not found

                agent.debug("Je demande une migration à " + harbour.getName());

                final SKLMessage msg = new SKLMessage("LOCK_REQUEST", "HARBOUR");
                msg.setContent(agent.size);
                msg.addReceiver(harbour);
                agent.skSendReliable(msg);

            }
        };
        agent.addBehaviour(tickerBehaviour);

        // We receive a response from the harbour
        @SuppressWarnings("unused")
        MessageTemplate mtLock = MessageTemplate.and(
                MessageTemplate.MatchOntology("LOCK_RESPONSE"),
                MessageTemplate.and(
                        MessageTemplate.MatchConversationId("REPLICATION"),
                        MessageTemplate.MatchProtocol("HARBOUR")));
        agent.addBehaviour(new CyclicBehaviour(agent) {
            @Override
            public void action() {
                SKLMessage acl = agent.skReceive(mtLock);
                if (acl == null) {
                    block();
                    return;
                }
                if ((Boolean)acl.getContent()) {
                    agent.migrate(acl.getSender().toAID());
                    tickerBehaviour.reset(rand.nextInt(2000) + 9000);
                }
            }
        });

    }

}