IPRateLimiterCapability.java

211 lines | 7.063 kB Blame History Raw Download
//----------------------------------------------------------------------------
// Copyright (C) 2011  Ingrid Nunes
// 
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
// 
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
// 
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
// 
// To contact the authors:
// http://inf.ufrgs.br/prosoft/bdi4jade/
//
//----------------------------------------------------------------------------
package br.ufrgs.inf.bdinetr.agent;

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

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import bdi4jade.annotation.Belief;
import bdi4jade.annotation.Parameter;
import bdi4jade.annotation.Parameter.Direction;
import bdi4jade.belief.Predicate;
import bdi4jade.extension.planselection.utilitybased.PlanContribution;
import bdi4jade.extension.planselection.utilitybased.SoftgoalPreferences;
import bdi4jade.extension.planselection.utilitybased.UtilityBasedPlanSelectionStrategy;
import bdi4jade.goal.BeliefGoal;
import bdi4jade.goal.Goal;
import bdi4jade.goal.GoalTemplateFactory;
import bdi4jade.goal.NamedSoftgoal;
import bdi4jade.goal.Softgoal;
import bdi4jade.plan.DefaultPlan;
import bdi4jade.plan.Plan;
import bdi4jade.plan.planbody.BeliefGoalPlanBody;
import bdi4jade.plan.planbody.PlanBody;
import br.ufrgs.inf.bdinetr.agent.goal.LimitIpGoal;
import br.ufrgs.inf.bdinetr.domain.Ip;
import br.ufrgs.inf.bdinetr.domain.RateLimiter;
import br.ufrgs.inf.bdinetr.domain.Role;
import br.ufrgs.inf.bdinetr.domain.predicate.IpRateLimited;

/**
 * @author Ingrid Nunes and Frederico Schardong
 */
public class IPRateLimiterCapability extends RouterAgentCapability {
	public interface Softgoals {
		public static final Softgoal INTRUSION = new NamedSoftgoal("INTRUSION");
		public static final Softgoal PROTECTION = new NamedSoftgoal("PROTECTION");	
	}
	
	public class LimitIPRatePlanBody extends BeliefGoalPlanBody {
		private static final long serialVersionUID = -3493377510830902861L;
		protected Log log;

		private Ip ip;
		
		ParameterizedIPPlan plan;
		
		private int getIPLimit(){
			int intrusion = (int)(this.plan.getIntrusion() * 50);
			int protection = (int)(this.plan.getProtection() * 50);
			
			return 50 + protection - intrusion;
		}

		@Override
		public void execute() {
			this.plan = (ParameterizedIPPlan) this.getPlan();
			this.log = LogFactory.getLog(getClass());
			
			log.info("LimitIPRatePlanBody->execute called, ip: " + ip.getAddress()
					+ " protection: " + this.plan.getProtection() + " intrusion: " + this.plan.getIntrusion() + " limiting at: " + this.getIPLimit());
			
			role.limitIp(ip, this.getIPLimit());
			belief(new IpRateLimited(ip), true);
		}

		@Parameter(direction = Direction.IN)
		public void setBeliefName(IpRateLimited ipRateLimited) {
			this.ip = ipRateLimited.getConcept();
		}
	}

	public class RestoreIPRatePlan extends BeliefGoalPlanBody {
		private static final long serialVersionUID = -3493377510830902961L;

		private Ip ip;

		@Override
		public void execute() {
			role.unlimitIp(ip);
			belief(new IpRateLimited(ip), false);
		}

		@Parameter(direction = Direction.IN)
		public void setBeliefName(IpRateLimited ipRateLimited) {
			this.ip = ipRateLimited.getConcept();
		}
	}

	public class ParameterizedIPPlan extends DefaultPlan {
		private double intrusion;
		private double protection;
		
		public ParameterizedIPPlan(double intrusion, double protection,
				final Object beliefValue, Class<? extends PlanBody> planBodyClass) {
			super(id + new Random().nextDouble(), GoalTemplateFactory.hasBeliefOfTypeWithValue(
					IpRateLimited.class, beliefValue), planBodyClass);

			this.intrusion = intrusion;
			this.protection = protection;
			
			this.generateMetadata();
		}
		
		private void generateMetadata(){
			Map<Softgoal, List<PlanContribution>> contributions = new HashMap<Softgoal, List<PlanContribution>>();
			List<PlanContribution> sgContributions = new ArrayList<PlanContribution>();

			sgContributions = new ArrayList<PlanContribution>();
			sgContributions.add(new PlanContribution(Softgoals.INTRUSION, 1.0, intrusion));
			contributions.put(Softgoals.INTRUSION, sgContributions);
			
			sgContributions = new ArrayList<PlanContribution>();
			sgContributions.add(new PlanContribution(Softgoals.PROTECTION, 1.0, protection));
			contributions.put(Softgoals.PROTECTION, sgContributions);

			putMetadata(PlanContribution.METADATA_NAME, contributions);
		}
		
		public double getIntrusion(){
			return this.intrusion;
		}
		
		public double getProtection(){
			return this.protection;
		}
	}
	
	//public static final int IP_LIMIT_RATE = 50;

	@bdi4jade.annotation.Plan
	private Plan limitIpRateIntrusive;
	@bdi4jade.annotation.Plan
	private Plan limitIpRateProtective;
	@bdi4jade.annotation.Plan
	private Plan limitIpRateBoth;
	@bdi4jade.annotation.Plan
	private Plan restoreIpRate;
	
	@bdi4jade.annotation.TransientBelief
	private final RateLimiter role;
	
	@Belief(name = SoftgoalPreferences.NAME)
	private SoftgoalPreferences preferences;

	public IPRateLimiterCapability(RateLimiter rateLimiter) {
		super();
		
		this.preferences = new SoftgoalPreferences();
		this.preferences.setPreferenceForSoftgoal(Softgoals.INTRUSION, 0.1);
		this.preferences.setPreferenceForSoftgoal(Softgoals.PROTECTION, 0.9);
		
		this.limitIpRateProtective = new ParameterizedIPPlan(0.1, 0.9, Boolean.TRUE, LimitIPRatePlanBody.class);
		this.limitIpRateBoth = new ParameterizedIPPlan(0.5, 0.5, Boolean.TRUE, LimitIPRatePlanBody.class);
		this.limitIpRateIntrusive = new ParameterizedIPPlan(0.9, 0.1, Boolean.TRUE, LimitIPRatePlanBody.class);

		//somehow BDI4JADE didn't add my plans without getPlanLibrary().addPlan()
		getPlanLibrary().addPlan(this.limitIpRateIntrusive);
		getPlanLibrary().addPlan(this.limitIpRateProtective);
		getPlanLibrary().addPlan(this.limitIpRateBoth);

		this.role = rateLimiter;

		this.restoreIpRate = new ParameterizedIPPlan(1, 1, Boolean.FALSE, RestoreIPRatePlan.class) {
			public boolean isContextApplicable(Goal goal) {
				BeliefGoal<IpRateLimited> bg = (BeliefGoal<IpRateLimited>) goal;
				Predicate<IpRateLimited> rateLimited = (Predicate<IpRateLimited>) getBeliefBase()
						.getBelief(bg.getBeliefName());
				return rateLimited != null && rateLimited.getValue();
			};
		};
		
		setPlanSelectionStrategy(new UtilityBasedPlanSelectionStrategy());
	}
	
	protected void setup() {
		this.getMyAgent().addSoftgoal(Softgoals.INTRUSION);
		this.getMyAgent().addSoftgoal(Softgoals.PROTECTION);
	}

	@Override
	public Role getRole() {
		return Role.RATE_LIMITER;
	}

}