package eu.betaas.taas.qosmanager.api.impl; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.Map.Entry; import java.util.concurrent.Callable; import org.apache.log4j.Logger; import org.osgi.framework.BundleContext; import eu.betaas.taas.bigdatamanager.database.hibernate.data.QoSMAssignmentStar; import eu.betaas.taas.bigdatamanager.database.hibernate.data.QoSMAssuredRequestStar; import eu.betaas.taas.bigdatamanager.database.hibernate.data.QoSMEquivalentThingServiceStar; import eu.betaas.taas.bigdatamanager.database.hibernate.data.QoSMRequestStar; import eu.betaas.taas.bigdatamanager.database.hibernate.data.QoSMThingServiceStar; import eu.betaas.taas.bigdatamanager.database.hibernate.data.QoSMThingStar; import eu.betaas.taas.bigdatamanager.database.service.IBigDataDatabaseService; import eu.betaas.taas.qosmanager.api.QoSManagerInternalIF; import eu.betaas.taas.qosmanager.api.QoSManagerNotificationIF; import eu.betaas.taas.qosmanager.api.QoSRankList; import eu.betaas.taas.qosmanager.api.QoSrequirements; import eu.betaas.taas.qosmanager.core.QoSManager; import eu.betaas.taas.qosmanager.heuristic.Reservation; import eu.betaas.taas.qosmanager.heuristic.ReservationResults; class HeuristicAssured implements Callable<QoSRankList>{ private static Logger LOG = Logger.getLogger("betaas.taas"); private static Logger LOGTest = Logger.getLogger("betaas.testplan"); private Map<String, QoSManagerNotificationIF> MapGw; private String serviceId; private ArrayList<ArrayList<String>> rank; private QoSrequirements req; private String gatewayId; boolean all; boolean pending; private QoSRankList allocation_schema; private Map<String, QoSMEquivalentThingServiceStar> equivalents; private Map<String, QoSMAssignmentStar> assignments; private Map<String, QoSMRequestStar> requests; private Map<String, QoSMAssuredRequestStar> assuredrequests; private Map<String, QoSMThingServiceStar> thingservices; private Map<String, QoSMThingStar> things; public HeuristicAssured( Map<String, QoSMEquivalentThingServiceStar> m_equivalents, Map<String, QoSMAssignmentStar> m_assignments, Map<String, QoSMRequestStar> m_requests, Map<String, QoSMAssuredRequestStar> m_assuredrequests, Map<String, QoSMThingServiceStar> m_thingservices, Map<String, QoSMThingStar> m_things, Map<String, QoSManagerNotificationIF> MapGw, String serviceId, ArrayList<ArrayList<String>> rank, QoSrequirements req, String gatewayId, boolean all, BundleContext context) { this.MapGw = MapGw; this.serviceId = serviceId; this.rank = rank; this.req = req; this.gatewayId = gatewayId; this.all = all; this.allocation_schema = new QoSRankList(true); setEquivalents(m_thingservices, m_equivalents); setAssignments(m_assignments); setRequests(m_requests); setAssuredrequests(m_assuredrequests); setThingservices(m_thingservices); setThings(m_things); } private void setRequests(Map<String, QoSMRequestStar> requestsMap) { requests = requestsMap; } private void setThings(Map<String, QoSMThingStar> thingsMap) { things = thingsMap; } public QoSRankList call() throws Exception { LOG.info("Perform allocation"); LOG.debug("serviceId:" + this.serviceId); LOG.debug("rank:" + this.rank); LOG.debug("req:" + this.req); LOG.debug("gatewayId:" + this.gatewayId); ReservationResults ris = null; QoSRankList response = new QoSRankList(); List<QoSMThingStar> B = new ArrayList<QoSMThingStar>(); List<QoSMAssuredRequestStar> K = new ArrayList<QoSMAssuredRequestStar>(); ArrayList<QoSMAssignmentStar> P = new ArrayList<QoSMAssignmentStar>(); Map<String, PS> PSs = new HashMap<String, PS>(); Map<QoSMAssuredRequestStar, Set<QoSMEquivalentThingServiceStar>> equivalent = new HashMap<QoSMAssuredRequestStar, Set<QoSMEquivalentThingServiceStar>>(); Map<String, QoSMEquivalentThingServiceStar> new_equivalents = new HashMap<String, QoSMEquivalentThingServiceStar>(); List<QoSMAssuredRequestStar> new_requests = new ArrayList<QoSMAssuredRequestStar>(); initiliaze_structures(B, K); if(rank!=null && req != null && serviceId != null){ LOGTest.debug("Heuristic Start - call add_new_request:1"); add_new_request(rank, req, serviceId, gatewayId, K, new_requests, equivalent, new_equivalents); LOGTest.debug("Heuristic End - call add_new_request:1"); } for(QoSMAssuredRequestStar request : K){ LOGTest.debug("Heuristic Start - call add_previous_equivalens:1"); add_previous_equivalens(equivalents, request, equivalent); LOGTest.debug("Heuristic End - call add_previous_equivalens:1"); LOG.debug("Request:" + request); LOG.debug("Equivalent:" + equivalent); } boolean gen = generate_PSs(K, equivalent, PSs); if(!gen) return null; double hyperperiod = allocation_schema.getHyperperiod(); for(QoSMAssuredRequestStar request : K){ /*LOG.debug("TS:"); for(Entry<String, QoSMThingServiceStar> ts : TS.entrySet()){ LOG.debug(ts.getKey()); }*/ try{ popolate_P(equivalent, request, P, hyperperiod); }catch(Exception e) { e.printStackTrace(); return null; } } for(QoSMThingStar t : B){ t.setBatteryLevel(t.getBatteryLevel()/100); //normalize Battery t.setTUsed(0.0); } for(QoSMThingServiceStar ts : thingservices.values()){ ts.setBatteryCost(ts.getBatteryCost() / 100); //normalize BatteryCost } //GRetrieve PSs parameters Map<String, Double> Cis = new HashMap<String, Double>(); Map<String, Double> Tis = new HashMap<String, Double>(); Map<String, Double> MRT = new HashMap<String, Double>(); for(String ts : thingservices.keySet()){ try{ Cis.put(ts, PSs.get(thingservices.get(ts).getDeviceId()).getCis()); Tis.put(ts, PSs.get(thingservices.get(ts).getDeviceId()).getTis()); MRT.put(ts, PSs.get(thingservices.get(ts).getDeviceId()).getMinMaxResonseTime()); }catch (Exception e) { continue; } } LOG.debug("Allocate"); Reservation res = new Reservation(); LOGTest.debug("Reservation Start - call:1"); ris = res.computeAssured(K, P, B, thingservices, 0.001, Cis, Tis, MRT); LOGTest.debug("Reservation End - call:1"); //debug_input_parametrs(K, P, ris); if(!ris.isFeasible()){ LOG.error("No feasible solution found!"); return null; } else{ LOG.info("Feasibile solution found"); LOGTest.debug("DB Start - starupdate_db:1"); update_data(ris, new_requests, new_equivalents); LOGTest.debug("DB End - starupdate_db:1"); LOG.info("Notify assignments"); if(rank!=null && req != null && serviceId != null) response = Utils.notify_assignment(LOG, serviceId, MapGw, ris, hyperperiod, things, assignments, equivalents, thingservices, null, assuredrequests, true); else response = Utils.notify_assignment(LOG, serviceId, MapGw, ris, hyperperiod, things, assignments, equivalents, thingservices, null, assuredrequests, false); } response.setThingsMap(things); response.setAssignmentsMap(assignments); response.setEquivalentsMap(equivalents); response.setThingServicesMap(thingservices); response.setRequestsMap(requests); response.setAssuredRequestsMap(assuredrequests); return response; } private void update_data(ReservationResults ris, List<QoSMAssuredRequestStar> new_requests, Map<String, QoSMEquivalentThingServiceStar> new_equivalents) { LOG.debug("Save new assignments"); for(QoSMAssignmentStar a : ris.getAss()){ a.setTotalBatteryCost(a.getTotalBatteryCost() * 100); assignments.put(a.getId().keyString(), a); } LOG.debug("Save new things' status"); for(QoSMThingStar t : ris.getB()){ t.setBatteryLevel(t.getBatteryLevel() * 100); things.put(t.getDeviceId(), t); } LOG.debug("Save new requests"); for(QoSMAssuredRequestStar r : new_requests){ assuredrequests.put(r.getId().keyString(), r); } LOG.debug("Save new equivalents"); for(String key : new_equivalents.keySet()){ equivalents.put(key, new_equivalents.get(key)); } } private void debug_input_parametrs(List<QoSMAssuredRequestStar> k, ArrayList<QoSMAssignmentStar> P, ReservationResults ris) { LOG.debug("INPUT REQUEST"); for(QoSMAssuredRequestStar r : k){ LOG.debug(r); LOG.debug("__________________________"); } LOG.debug("INPUT P"); for(QoSMAssignmentStar p : P) { LOG.debug(p); LOG.debug("__________________________"); } LOG.debug("RESULTS"); LOG.debug(ris.toString()); } private void popolate_P( Map<QoSMAssuredRequestStar, Set<QoSMEquivalentThingServiceStar>> equivalent, QoSMAssuredRequestStar request, ArrayList<QoSMAssignmentStar> p, double hyperperiod) { for(QoSMEquivalentThingServiceStar eq : equivalent.get(request)){ try{ LOGTest.debug("Heuristic Start - call popolate_P:1"); QoSMThingServiceStar ts = thingservices.get(eq.getId().getThingServiceId()); LOGTest.debug("Heuristic End - call popolate_P:1"); if(!ts.getReachable()) continue; LOGTest.debug("DB Start - popolate_P:1"); QoSMThingStar t = things.get(ts.getDeviceId()); LOGTest.debug("DB End - popolate_P:1"); LOGTest.debug("Heuristic Start - call popolate_P:2"); if(ts.getResponseTime() <= request.getMaxResponseTime()){ double factor = hyperperiod / request.getMinInterRequestTime(); // TODO correct double normalizedcost = ts.getBatteryCost() / t.getBatteryLevel(); //double normalizedcost = ts.getBatteryCost() / 100.0; double computationalCost = (request.getMinInterRequestTime() / hyperperiod) * ts.getComputationalCost(); /*double computationalCost = (request.getMinInterRequestTime() / hyperperiod) * ts.getResponseTime();*/ p.add(new QoSMAssignmentStar(request.getId().getServiceId(), request.getId().getRequestId(), ts.getThingServiceId(), normalizedcost * factor, computationalCost)); } else{ p.add(new QoSMAssignmentStar(request.getId().getServiceId(), request.getId().getRequestId(), ts.getThingServiceId(), Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY)); } LOGTest.debug("Heuristic End - call popolate_P:2"); }catch(NullPointerException e){ LOG.error(e.getMessage()); } } } private void add_previous_equivalens( Map<String, QoSMEquivalentThingServiceStar> equivalents, QoSMAssuredRequestStar request, Map<QoSMAssuredRequestStar, Set<QoSMEquivalentThingServiceStar>> equivalent) { for(QoSMEquivalentThingServiceStar e : equivalents.values()){ if(e.getId().getServiceId().equals(request.getId().getServiceId()) && e.getId().getRequestId() == request.getId().getRequestId()) { if(equivalent.containsKey(request)) { Set<QoSMEquivalentThingServiceStar> tmp = equivalent.get(request); tmp.add(e); equivalent.put(request, tmp); } else{ Set<QoSMEquivalentThingServiceStar> tmp = new HashSet<QoSMEquivalentThingServiceStar>(); tmp.add(e); equivalent.put(request, tmp); } } } } private boolean generate_PSs( List<QoSMAssuredRequestStar> k, Map<QoSMAssuredRequestStar, Set<QoSMEquivalentThingServiceStar>> equivalent, Map<String, PS> pss) { boolean PSdone = false; while(!PSdone){ PSdone = true; //List for each Thing for(QoSMAssuredRequestStar r : k) { if(!equivalent.containsKey(r)){ return false; } LOGTest.debug("Heuristic Start - generate_PSs:1"); Set<QoSMEquivalentThingServiceStar> eqList = equivalent.get(r); LOGTest.debug("Heuristic End - generate_PSs:1"); if(eqList.size() == 0) return false; for(QoSMEquivalentThingServiceStar eq : eqList){ try{ LOGTest.debug("DB Start - generate_PSs:1"); if(!thingservices.containsKey(eq.getId().getThingServiceId())){ LOG.error("No Thing service found."); return false; } QoSMThingServiceStar ts = thingservices.get(eq.getId().getThingServiceId()); LOGTest.debug("DB End - generate_PSs:1"); LOGTest.debug("Heuristic Start - generate_PSs:2"); if(allocation_schema.getHyperperiod() == 0.0) allocation_schema.setHyperperiod(r.getMinInterRequestTime()); double computationalCost = (r.getMinInterRequestTime() / allocation_schema.getHyperperiod()) * ts.getResponseTime(); LOGTest.debug("Heuristic End - generate_PSs:2"); if(pss.containsKey(ts.getDeviceId())){ LOGTest.debug("Heuristic Start - generate_PSs:3"); PS ps = pss.get(ts.getDeviceId()); Set<QoSMEquivalentThingServiceStar> lst = ps.getEq(); lst.add(eq); ps.setEq(lst); /*QoSMThingStar thing = service.searchQoSMThingStar(ts.getDeviceId()).get(0); ps.setThing(thing);*/ if(pss.get(ts.getDeviceId()).getMaxComputational() < computationalCost){ ps.setMaxComputational(computationalCost); ps.setMaxThingService(eq); } if(pss.get(ts.getDeviceId()).getMinTime() > r.getMinInterRequestTime()) ps.setMinTime(r.getMinInterRequestTime()); if(pss.get(ts.getDeviceId()).getMinMaxResonseTime() > r.getMaxResponseTime()) ps.setMinMaxResonseTime(r.getMaxResponseTime()); pss.put(ts.getDeviceId(), ps); LOGTest.debug("Heuristic End - generate_PSs:3"); } else { LOGTest.debug("DB Start - generate_PSs:2"); if(!things.containsKey(ts.getDeviceId())){ LOG.error("No Thing found."); return false; } QoSMThingStar thing = things.get(ts.getDeviceId()); LOGTest.debug("DB End - generate_PSs:2"); LOGTest.debug("Heuristic Start - generate_PSs:4"); PS ps = new PS(); Set<QoSMEquivalentThingServiceStar> lst = new HashSet<QoSMEquivalentThingServiceStar>(); lst.add(eq); ps.setEq(lst); ps.setThing(thing); ps.setRequest(r); ps.setMaxComputational(computationalCost); ps.setMaxThingService(eq); ps.setMinTime(r.getMinInterRequestTime()); ps.setMinMaxResonseTime(r.getMaxResponseTime()); pss.put(ts.getDeviceId(), ps); LOGTest.debug("Heuristic End - generate_PSs:4"); } } catch(IndexOutOfBoundsException e){ LOG.error("Exception: No Thing service found."); } } } LOGTest.debug("Heuristic Start - generate_PSs:5"); //PS for(String deviceId : pss.keySet()){ PS ps = pss.get(deviceId); QoSMThingStar t = ps.getThing(); double Uis = 1.0 - t.getCapacityUsed(); double Tis = ps.getMaxComputational() / Uis; if(Tis < ps.getMinTime()){ //OK ps.setCis(ps.getMaxComputational()); ps.setTis(Tis); } else{ //Remove equivalent.get(ps.getRequest()).remove(ps.getMaxThingService()); PSdone = false; break; } } LOGTest.debug("Heuristic End - generate_PSs:5"); } //check if all assured request can be satisfied for(QoSMAssuredRequestStar r : k) { if(!equivalent.containsKey(r)){ return false; } else{ if(equivalent.get(r).isEmpty()) return false; } } return true; } private void add_new_request(ArrayList<ArrayList<String>> rank, QoSrequirements req, String serviceId, String gatewayId, List<QoSMAssuredRequestStar> k, List<QoSMAssuredRequestStar> new_requests, Map<QoSMAssuredRequestStar, Set<QoSMEquivalentThingServiceStar>> equivalent, Map<String, QoSMEquivalentThingServiceStar> new_equivalents) { int requestId = 0; for(ArrayList<String> r: rank){ QoSMAssuredRequestStar request = new QoSMAssuredRequestStar(serviceId, requestId, req.getMaxResponseTime(), req.getMinInterRequestTime(), gatewayId, req.getMaxBurstSize(), req.getAverageRate()); k.add(request); new_requests.add(request); for(String eq : r){ QoSMEquivalentThingServiceStar ets = new QoSMEquivalentThingServiceStar(serviceId, requestId, eq); if(equivalent.containsKey(request)) { Set<QoSMEquivalentThingServiceStar> tmp = equivalent.get(request); tmp.add(ets); equivalent.put(request, tmp); new_equivalents.put(ets.getId().keyString(), ets); } else{ Set<QoSMEquivalentThingServiceStar> tmp = new HashSet<QoSMEquivalentThingServiceStar>(); tmp.add(ets); equivalent.put(request, tmp); new_equivalents.put(ets.getId().keyString(), ets); } } requestId++; } } private void initiliaze_structures(List<QoSMThingStar> B, List<QoSMAssuredRequestStar> K) { if(assuredrequests != null){ for(QoSMAssuredRequestStar req : assuredrequests.values()){ K.add(new QoSMAssuredRequestStar(req)); } } LOGTest.debug("Heuristic End - call initiliaze_structures:1"); Utils.update_batteryLevel(things, MapGw); LOGTest.debug("Heuristic Start - call initiliaze_structures:2"); if(things != null){ for(QoSMThingStar thing : things.values()){ B.add(new QoSMThingStar(thing.getDeviceId(), thing.getBatteryLevel(), 0, 0.0, thing.getGatewayId())); } } LOGTest.debug("Heuristic End - call initiliaze_structures:2"); } public Map<String, QoSMEquivalentThingServiceStar> getEquivalents() { return equivalents; } public void setEquivalents(Map<String, QoSMThingServiceStar> thingservices, Map<String, QoSMEquivalentThingServiceStar> equivalents) { this.equivalents = new HashMap<String, QoSMEquivalentThingServiceStar>(); for(Entry<String, QoSMEquivalentThingServiceStar> item : equivalents.entrySet()){ QoSMThingServiceStar ts = thingservices.get(item.getValue().getId().getThingServiceId()); if(ts.getReachable()) this.equivalents.put(item.getKey(), item.getValue()); } } public Map<String, QoSMAssignmentStar> getAssignments() { return assignments; } public void setAssignments(Map<String, QoSMAssignmentStar> assignments) { this.assignments = assignments; } public Map<String, QoSMThingServiceStar> getThingservices() { return thingservices; } public void setThingservices(Map<String, QoSMThingServiceStar> thingservices) { this.thingservices = new HashMap<String, QoSMThingServiceStar>(); for(Entry<String, QoSMThingServiceStar> item : thingservices.entrySet()){ if(item.getValue().getReachable()) this.thingservices.put(item.getKey(), item.getValue()); } } public Map<String, QoSMAssuredRequestStar> getAssuredrequests() { return assuredrequests; } public void setAssuredrequests(Map<String, QoSMAssuredRequestStar> assuredrequests) { this.assuredrequests = assuredrequests; } }