diff --git a/aggregator/commons-math3-3.6.1-javadoc.jar b/aggregator/commons-math3-3.6.1-javadoc.jar new file mode 100644 index 000000000..905343c4a Binary files /dev/null and b/aggregator/commons-math3-3.6.1-javadoc.jar differ diff --git a/aggregator/commons-math3-3.6.1-sources.jar b/aggregator/commons-math3-3.6.1-sources.jar new file mode 100644 index 000000000..4e06ff8e1 Binary files /dev/null and b/aggregator/commons-math3-3.6.1-sources.jar differ diff --git a/aggregator/commons-math3-3.6.1-test-sources.jar b/aggregator/commons-math3-3.6.1-test-sources.jar new file mode 100644 index 000000000..766e4c90a Binary files /dev/null and b/aggregator/commons-math3-3.6.1-test-sources.jar differ diff --git a/aggregator/commons-math3-3.6.1-tests.jar b/aggregator/commons-math3-3.6.1-tests.jar new file mode 100644 index 000000000..23a963352 Binary files /dev/null and b/aggregator/commons-math3-3.6.1-tests.jar differ diff --git a/aggregator/commons-math3-3.6.1-tools.jar b/aggregator/commons-math3-3.6.1-tools.jar new file mode 100644 index 000000000..b4dfb2ec8 Binary files /dev/null and b/aggregator/commons-math3-3.6.1-tools.jar differ diff --git a/aggregator/commons-math3-3.6.1.jar b/aggregator/commons-math3-3.6.1.jar new file mode 100644 index 000000000..0ff582cfc Binary files /dev/null and b/aggregator/commons-math3-3.6.1.jar differ diff --git a/aggregator/javacsv.jar b/aggregator/javacsv.jar new file mode 100644 index 000000000..ceb59eb46 Binary files /dev/null and b/aggregator/javacsv.jar differ diff --git a/aggregator/pom.xml b/aggregator/pom.xml index be97e6812..9b9483241 100644 --- a/aggregator/pom.xml +++ b/aggregator/pom.xml @@ -72,6 +72,16 @@ flowgate-worker ${flowgate.version} + + org.apache.commons + commons-math3 + 3.6.1 + + + net.sourceforge.javacsv + javacsv + 2.0 + org.springframework.boot spring-boot-starter-test diff --git a/aggregator/src/main/java/com/vmware/flowgate/aggregator/config/ServiceKeyConfig.java b/aggregator/src/main/java/com/vmware/flowgate/aggregator/config/ServiceKeyConfig.java index 1ba04e127..fe8e315c7 100644 --- a/aggregator/src/main/java/com/vmware/flowgate/aggregator/config/ServiceKeyConfig.java +++ b/aggregator/src/main/java/com/vmware/flowgate/aggregator/config/ServiceKeyConfig.java @@ -18,6 +18,6 @@ public ServiceKeyConfig() { } public String getServiceKey() { - return serviceKey; + return serviceKey; } } diff --git a/aggregator/src/main/java/com/vmware/flowgate/aggregator/scheduler/job/AggregatorJobDispatcher.java b/aggregator/src/main/java/com/vmware/flowgate/aggregator/scheduler/job/AggregatorJobDispatcher.java index 104d7d088..d13ac24af 100644 --- a/aggregator/src/main/java/com/vmware/flowgate/aggregator/scheduler/job/AggregatorJobDispatcher.java +++ b/aggregator/src/main/java/com/vmware/flowgate/aggregator/scheduler/job/AggregatorJobDispatcher.java @@ -36,6 +36,7 @@ public void execute(JobExecutionContext context) throws JobExecutionException { } long execount = Long.valueOf(execountString); //will execute weekly? + if (execount++ % 168 == 0) { try { EventMessage eventMessage = EventMessageUtil.createEventMessage(EventType.Aggregator, @@ -76,7 +77,17 @@ public void execute(JobExecutionContext context) throws JobExecutionException { }catch(IOException e) { logger.error("Failed to Send sync summary data command", e); } - }else { + }else if(execount % 24 == 0){ + try { + EventMessage eventMessage = EventMessageUtil.createEventMessage(EventType.Aggregator, + EventMessageUtil.SYNC_FITTING, ""); + String jobmessage = EventMessageUtil.convertEventMessageAsString(eventMessage); + publisher.publish(EventMessageUtil.AggregatorTopic, jobmessage); + logger.info("Send sync fitting command"); + }catch(IOException e) { + logger.error("Failed to Send sync fitting command", e); + } + }else { //will execute hourly? try { EventMessage eventMessage = EventMessageUtil.createEventMessage(EventType.Aggregator, diff --git a/aggregator/src/main/java/com/vmware/flowgate/aggregator/scheduler/job/AggregatorService.java b/aggregator/src/main/java/com/vmware/flowgate/aggregator/scheduler/job/AggregatorService.java index 9a6b7b0c5..888f23c07 100644 --- a/aggregator/src/main/java/com/vmware/flowgate/aggregator/scheduler/job/AggregatorService.java +++ b/aggregator/src/main/java/com/vmware/flowgate/aggregator/scheduler/job/AggregatorService.java @@ -4,9 +4,15 @@ */ package com.vmware.flowgate.aggregator.scheduler.job; +import java.io.FileNotFoundException; +import com.vmware.flowgate.aggregator.tool.*; +import com.vmware.flowgate.aggregator.tool.basic.*; import java.io.IOException; +import com.csvreader.CsvReader; + import java.util.ArrayList; import java.util.Arrays; +import java.util.Comparator; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; @@ -21,7 +27,11 @@ import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; +import org.apache.commons.math3.fitting.PolynomialCurveFitter; +import org.apache.commons.math3.fitting.WeightedObservedPoints; +import org.apache.commons.math3.util.Pair; import com.fasterxml.jackson.core.JsonProcessingException; + import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; import com.vmware.flowgate.aggregator.config.ServiceKeyConfig; @@ -31,6 +41,7 @@ import com.vmware.flowgate.common.MetricName; import com.vmware.flowgate.common.model.Asset; import com.vmware.flowgate.common.model.FacilitySoftwareConfig; +import com.vmware.flowgate.common.model.MetricData; import com.vmware.flowgate.common.model.FacilitySoftwareConfig.SoftwareType; import com.vmware.flowgate.common.model.SDDCSoftwareConfig; import com.vmware.flowgate.common.model.ServerMapping; @@ -40,6 +51,9 @@ import com.vmware.flowgate.common.model.redis.message.EventUser; import com.vmware.flowgate.common.model.redis.message.impl.EventMessageUtil; +import io.netty.handler.codec.string.StringDecoder; + + @Service public class AggregatorService implements AsyncService { @@ -65,10 +79,9 @@ public void executeAsync(EventMessage message) { logger.warn("Drop none aggregator message " + message.getType()); return; } - logger.info(message.getContent()); + logger.info("message: " + message.getContent()); Set users = message.getTarget().getUsers(); for (EventUser command : users) { - logger.info(command.getId()); switch (command.getId()) { case EventMessageUtil.FullMappingCommand: mergeServerMapping(); @@ -92,6 +105,10 @@ public void executeAsync(EventMessage message) { case EventMessageUtil.CleanRealtimeData: cleanRealtimeData(); break; + case EventMessageUtil.SYNC_FITTING: + syncFitting(); + recommend(); + break; case EventMessageUtil.AggregateAndCleanPowerIQPDU: aggregateAndCleanPDUFromPowerIQ(); break; @@ -103,7 +120,163 @@ public void executeAsync(EventMessage message) { } } } + + public List collectData(int saperate_num, long StartTime, String assetId) { + long Two_Hours = 305000 * 24; + List ret = new ArrayList<>(0); + long duration = Two_Hours * 60 / saperate_num; + logger.info("StartTime: " + String.valueOf(StartTime / Two_Hours * 2)); + long duration_right = StartTime; + long duration_left = StartTime - Two_Hours * 24; + long duration_start; + for (int i = 0; i < saperate_num - 1; i++) { + duration_start = StartTime - duration * (i + 1); + if (i == 0) + duration_right = StartTime; + else + duration_right = duration_left; + if (i == saperate_num - 2) + duration_left = StartTime - Two_Hours * 60; + else + duration_left = duration_start - duration/2; + + long cursor = duration_start; + MetricData[] metric_datas = null; + + while (cursor < duration_right) { + if (cursor + Two_Hours > duration_right) + { + try { + metric_datas = restClient.getServerRealtimeDataByServerID(assetId, duration_right, Two_Hours).getBody(); + } catch (Exception e) { + metric_datas = null; + } + } + else { + try { + metric_datas = restClient.getServerRealtimeDataByServerID(assetId, cursor + Two_Hours, Two_Hours).getBody(); + } catch (Exception e) { + metric_datas = null; + } + } + if (metric_datas == null) + break; + else { + ret.addAll(Arrays.asList(metric_datas)); + cursor += Two_Hours; + } + } + cursor = duration_start; + long loc = duration_left; + while (cursor - Two_Hours>= duration_left) { + try { + metric_datas = restClient.getServerRealtimeDataByServerID(assetId, cursor, Two_Hours).getBody(); + } catch (Exception e) { + metric_datas = null; + } + if (metric_datas == null) { + loc = duration_left; + break; + } + else { + ret.addAll(Arrays.asList(metric_datas)); + cursor -= Two_Hours; + loc = cursor; + } + } + duration_left = loc; + } + return ret; + } + + public void syncFitting() { + + List MetricDatas; + List> results = new ArrayList<>(); + SyncFittingTool tool = new SyncFittingTool(); + + long Five_Miniutes = 305000; + restClient.setServiceKey(serviceKeyConfig.getServiceKey()); + MetricData[] raw_MetricDatas = null; + Asset[] servers = restClient.getMappedAsset(AssetCategory.Server).getBody(); + for (int i = 0; i < servers.length; i++) + { + String assetId = servers[i].getId(); + MetricDatas = collectData(10, System.currentTimeMillis(), assetId); + List fitting_result = tool.doFitting(MetricDatas); + results.add(fitting_result); + servers[i].setFittingResults(fitting_result); + Asset asset = new Asset(); + asset.setFittingResults(fitting_result); + //asset.setAssetName("fitting_results"); + restClient.saveAssets(asset); + } + } + + public void recommend() { + + Asset[] servers = restClient.getMappedAsset(AssetCategory.Server).getBody(); + + //TODO: use vc api to create bags. + Bag[] bags = new Bag[]; + bags[i] = new Bag(memory, cpu, fitting_result, i); + // + + long Two_Hours = 305000 * 24; + long now_time = System.currentTimeMillis(); + ArrayList items = new ArrayList<>(); + for (int i = 0; i < servers.length; i++) { + List fitting_result = servers[i].getFittingResults(); + String assetId = servers[i].getId(); + MetricData[] metric_datas = null; + long start = now_time; + while (metric_datas == null && start > now_time - Two_Hours * 60) { + metric_datas = restClient.getServerRealtimeDataByServerID(assetId, start, Two_Hours).getBody(); + start = start - Two_Hours; + } + if (metric_datas == null) + continue; + List< Double> raw_CPU_list = new ArrayList<>(); + List raw_cpuMhz_list = new ArrayList<>(); + List< Double> raw_memory_list = new ArrayList<>(); + List raw_memoryKb_list = new ArrayList<>(); + Double cpu_sum = 0.0; + Double cpu_mhz_sum = 0.0; + Double memory_sum = 0.0; + Double memory_kb_sum = 0.0; + + for (int j = 0; j < metric_datas.length; j++) { + if (metric_datas[j].getMetricName() == "CpuUsage") { + raw_CPU_list.add(metric_datas[j].getValueNum()); + cpu_sum += metric_datas[j].getValueNum(); + } + else if (metric_datas[j].getMetricName() == "CpuUsedInMhz") { + raw_cpuMhz_list.add(metric_datas[j].getValueNum()); + cpu_mhz_sum += metric_datas[j].getValueNum(); + } + else if (metric_datas[j].getMetricName() == "MemoryUsage") { + raw_memory_list.add(metric_datas[j].getValueNum()); + memory_sum += metric_datas[j].getValueNum(); + } + else if (metric_datas[j].getMetricName() == "ActiveMemory") { + raw_memoryKb_list.add(metric_datas[j].getValueNum()); + memory_kb_sum += metric_datas[j].getValueNum(); + } + + } + Double avg_cpu = cpu_sum / raw_CPU_list.size(); + Double avg_cpu_mhz = cpu_mhz_sum / raw_cpuMhz_list.size(); + Double avg_memory = memory_sum / raw_memory_list.size(); + Double avg_memory_kb = memory_kb_sum / raw_memoryKb_list.size(); + items.add(new Item(assetId, avg_memory_kb/avg_memory, avg_cpu_mhz, avg_cpu_mhz/avg_cpu)); + + + } + NeighborhoodSearch ns = new NeighborhoodSearch(bags, items); + ns.search(); + } + public void syncSummaryData() { restClient.setServiceKey(serviceKeyConfig.getServiceKey()); restClient.getSystemSummary(false); diff --git a/aggregator/src/main/java/com/vmware/flowgate/aggregator/scheduler/job/VCenterJobDispatcher.java b/aggregator/src/main/java/com/vmware/flowgate/aggregator/scheduler/job/VCenterJobDispatcher.java index 1e33a7fdb..4e51d6a60 100644 --- a/aggregator/src/main/java/com/vmware/flowgate/aggregator/scheduler/job/VCenterJobDispatcher.java +++ b/aggregator/src/main/java/com/vmware/flowgate/aggregator/scheduler/job/VCenterJobDispatcher.java @@ -52,6 +52,7 @@ public void execute(JobExecutionContext context) throws JobExecutionException { //every 12 hour we will trigger a sync host metadata job. //every 1 day we will trigger a sync CustomerAttrsData job. //every 10 days we will trigger a sync CustomAttributes job. + //every 1 day we will trigger a fitting job. restClient.setServiceKey(serviceKeyConfig.getServiceKey()); SDDCSoftwareConfig[] vcServers = restClient.getVCServers().getBody(); @@ -110,7 +111,7 @@ public void execute(JobExecutionContext context) throws JobExecutionException { generateSDDCMessageListByType(EventMessageUtil.VCENTER_SyncCustomerAttrs, vcServersActiveArray)); } - + publisher.publish(EventMessageUtil.VCTopic, EventMessageUtil.generateSDDCNotifyMessage(EventType.VCenter)); } catch (IOException e) { diff --git a/aggregator/src/main/java/com/vmware/flowgate/aggregator/tool/Greedy.java b/aggregator/src/main/java/com/vmware/flowgate/aggregator/tool/Greedy.java new file mode 100644 index 000000000..495ac45a0 --- /dev/null +++ b/aggregator/src/main/java/com/vmware/flowgate/aggregator/tool/Greedy.java @@ -0,0 +1,144 @@ +package com.vmware.flowgate.aggregator.tool; +import com.vmware.flowgate.aggregator.tool.basic.*; +import org.apache.commons.math3.util.Pair; + +import java.util.ArrayList; + +public class Greedy { + private Bag[] bags; + private ArrayList items = new ArrayList(); + private ArrayList unusedItems = new ArrayList<>(); + + public Greedy(Item[] items, Bag[] bags) { + + this.bags = bags; + + for (int i = 0; i < items.length; i++) { + items[i].setValueAndBenefitInBag(bags); + this.items.add(items[i]); + } + } + + /* + Selects "best" item to add based on calculated benefit (value/weight) + If that item can't be added it is discarded. + Solution is terminated when no items can be added or all items have already been added to the knapsacks. + + */ + public void solve() { + + for (int i = 0; i < this.items.size(); i++) { + addToKnapsack(items.get(i)); + } + + } + + /** + * + * Adds incoming item to the knapsack with the least amount of remaining space but enough space to fit the item + * If item can not be added to any knapsack it is removed from the items list and added to the unused items list. + * + * @param item item to be added to knapsack or discarded + */ + private void addToKnapsack(Item item) { + + Bag bestFit = null; + Pair[] valueInBag = item.getPower(); + int finalBag = -1; + for (int i = 0; i < valueInBag.length; i++) { + int bagIndex = valueInBag[i].getSecond(); + if (bags[bagIndex].availableMemory() >= item.getMemory() && bags[bagIndex].availableCPU() >= item.getCPU_capacity()) { + + if (bestFit == null) { + bestFit = bags[bagIndex]; + finalBag = i; + break; + + } + } + + } + + if (bestFit != null) { + bestFit.addItem(item, finalBag); + + } else { + unusedItems.add(item); + + } + + } + + public void printResult() { + + System.out.println("Knapsacks: "); + + for (int i = 0; i < bags.length; i++) { + System.out.println(); + + System.out.println("Capacity " + bags[i].getMemory()); + System.out.println("Space left " + bags[i].availableMemory()); + System.out.println("Number of items " + bags[i].getItems().size()); + System.out.println("Total value " + bags[i].getTotalPower()); + for (int j = 0; j < bags[i].getItems().size(); j++) { + Pair[] valueInBag = bags[i].getItems().get(j).getPower(); + for (int m = 0; m < valueInBag.length; m++) { + if (valueInBag[m].getSecond() == i) + System.out.println("in bag value " + valueInBag[m].getFirst()); + else + System.out.println(valueInBag[m].getFirst()); + + } + } + + } + + } + + public static void main(String[] args) { + + int nbrOfItems = 5; + int nbrOfBags = 2; + + Bag[] test_bags; + Item[] test_items; + + Samples samples = new Samples(); + + //samples.generateRandomValues(nbrOfItems, nbrOfBags); + + test_bags = new Bag[nbrOfBags]; + test_items = new Item[nbrOfItems]; + test_items[0] = new Item("1", 10, 2, 2); + test_items[1] = new Item("2", 20, 3, 3); + test_items[2] = new Item("3", 18, 4, 4); + test_items[3] = new Item("4", 15, 3, 3); + test_items[4] = new Item("5", 22, 5, 5); + double[] params0 = new double[5], params1 = new double[5]; + params0[0] = 50; + params0[1] = 2; + params0[2] = -2.4; + params0[3] = -0.8; + params0[4] = 0.2; + params1[0] = 99; + params1[1] = -4; + params1[2] = -1.2; + params1[3] = 0.5; + params1[4] = -0.1; + test_bags[0] = new Bag(70, 10, params0, 0); + test_bags[1] = new Bag(50, 10, params1, 1); + Greedy greedy = new Greedy(test_items, test_bags); + greedy.solve(); + greedy.printResult(); + + + } + + public Bag[] getBags() { + return bags; + } + + public ArrayList getUnusedItems() { + return unusedItems; + } +} diff --git a/aggregator/src/main/java/com/vmware/flowgate/aggregator/tool/NeighborhoodSearch.java b/aggregator/src/main/java/com/vmware/flowgate/aggregator/tool/NeighborhoodSearch.java new file mode 100644 index 000000000..c31059aad --- /dev/null +++ b/aggregator/src/main/java/com/vmware/flowgate/aggregator/tool/NeighborhoodSearch.java @@ -0,0 +1,266 @@ +package com.vmware.flowgate.aggregator.tool; +import com.vmware.flowgate.aggregator.tool.basic.*; +import java.util.ArrayList; +import java.util.Arrays; +public class NeighborhoodSearch { + Bag[] bags; + ArrayList items; //Dynamic so we can use the list for storing an retrieving unused items + Neighborhood globalOptima; + ArrayList closestNeighbours; + static final int SEARCHES = 100; //amount of searches to perform before termination + Greedy greedy; + int totalItemNumber = 0; + + public NeighborhoodSearch(Bag[] bags, ArrayList items) { + + this.bags = bags; + this.items =items; + this.totalItemNumber = this.items.size(); + } + + public Bag[] getBags() { + return this.globalOptima.getBags(); + } + + public ArrayList getItems() { + return this.items; + } + + /** + * Main method of the neighborhood search + */ + public void search() { + greedy = new Greedy(items.toArray(new Item[items.size()]), bags); + greedy.solve(); //Starting solution solved using greedy algorithm + + Neighborhood initial = new Neighborhood(greedy.getUnusedItems(), bags); //Starting point + + + globalOptima = initial; //First solution has to be the best one so far + items = greedy.getUnusedItems(); + + Neighborhood lowestNeighbour = null; + Neighborhood temp; + + //Amount of searches, outer loop + for (int i = 0; i <= SEARCHES; i++) { + closestNeighbours = new ArrayList<>(); //generate the neighborhood + + temp = new Neighborhood(items, bags); //generate a neighbour for each rotation type + rotateBags(temp.getBags(), 1); + closestNeighbours.add(temp); + + temp = new Neighborhood(items, bags); + rotateBags(temp.getBags(), 2); + closestNeighbours.add(temp); + + temp = new Neighborhood(items, bags); + rotateBags(temp.getBags(), 3); + closestNeighbours.add(temp); + + temp = new Neighborhood(items, bags); + rotateUnused(temp.getBags(), temp.getUnusedItems(), 1); + closestNeighbours.add(temp); + + temp = new Neighborhood(items, bags); + rotateUnused(temp.getBags(), temp.getUnusedItems(), 2); + closestNeighbours.add(temp); + + temp = new Neighborhood(items, bags); + rotateUnused(temp.getBags(), temp.getUnusedItems(), 3); + closestNeighbours.add(temp); + + + lowestNeighbour = closestNeighbours.get(0); //initial neighbour to compare to + + for (int j = 0; j < closestNeighbours.size(); j++) { //After generating neighborhood, compare which has lowest value + + + if (closestNeighbours.get(j).getTotalPower() <= lowestNeighbour.getTotalPower() && closestNeighbours.get(j).getBagsItemsNumber() == this.totalItemNumber) { + + lowestNeighbour = closestNeighbours.get(j); + + bags = lowestNeighbour.getBags(); + items = lowestNeighbour.getUnusedItems(); + + + + } + } + + if (lowestNeighbour.getTotalPower() < globalOptima.getTotalPower()) { + globalOptima = lowestNeighbour; //set new global optima if the local optima is < than previous global + } + + closestNeighbours.clear(); + + } + System.out.println("\n\n\n----------------------------------------------------------"); + System.out.println("initial result:\n" + initial.toString()); + System.out.println("after neighborhoodsearch:\n" + globalOptima.toString()); + + + } + + + //Utils - maybe move to a new class + + /** + * Removes an item from a bag and puts it at the end of unused items-list + * + * @param bag + * @param item + */ + private void removeFromBagToUnused(Bag bag, Item item, ArrayList unused) { + + Item itemToAdd = bag.removeItem(item, item.getValueIdxThroughBagIdx(bag.getIndex())); + + unused.add(itemToAdd); + } + + /** + * Swaps items between bags by first attempting 30 times to remove + * an random item in the first bag to insert it to the second bag by + * also removing a random item from that bag (2nd bag). If 30 attempts + * passed and no swap is made, method ends. If a swap is made, we try + * to take the removed item from the 2nd bag and insert in the first bag + * (in order to swap between the two bags) if that cant be made due to lack of + * space, we will attempt to fit an item from the unused items-list to the first bag. + * + * @param bagFrom + * @param bagTo + * @return + */ + private boolean moveFromBagToBag(Bag bagFrom, Bag bagTo) { + for (int i = 0; i < 30; i++) { + Item itemToAdd = bagFrom.getRandomItem(); + Item itemToRemove = bagTo.getRandomItem(); + + if (itemToRemove == null || itemToAdd == null) { + return false; + } + + Item temp = null; + if ((bagTo.availableMemory() + itemToRemove.getMemory()) >= itemToAdd.getMemory() && bagTo.availableCPU() + itemToRemove.getCPU_capacity() >= itemToAdd.getCPU_capacity()) { + temp = bagTo.removeItem(itemToRemove, itemToRemove.getValueIdxThroughBagIdx(bagTo.getIndex())); + + bagTo.addItem(itemToAdd, itemToAdd.getValueIdxThroughBagIdx(bagTo.getIndex())); + bagFrom.removeItem(itemToAdd, itemToAdd.getValueIdxThroughBagIdx(bagFrom.getIndex())); + //try to move the item removed from first bag to the second bag + if (bagFrom.availableMemory() >= temp.getMemory() && bagFrom.availableCPU() >= temp.getCPU_capacity()) { + bagFrom.addItem(temp, temp.getValueIdxThroughBagIdx(bagFrom.getIndex())); + + } + else { + bagTo.getItems().add(temp); //we have to put it into the unused list if we cant fit it into the other bag + addFromUnusedToBag(bagFrom, bagFrom.getItems()); + } + return true; + } + } + return false; + } + + /** + * Adds the first item of the unused-items list to a specified bag. If it doesnt fit, + * it tries the whole list. + * + * @param bag + * @return + */ + private boolean addFromUnusedToBag(Bag bag, ArrayList unused) { + for (int i = 0; i < unused.size(); i++) { + if (bag.availableMemory() >= unused.get(i).getMemory() && bag.availableCPU() >= unused.get(i).getCPU_capacity()) { + Item itemRemove = unused.remove(i); + bag.addItem(itemRemove, itemRemove.getValueIdxThroughBagIdx(bag.getIndex())); + return true; + } + } + return false; + } + + //ROTATIONS + + /** + * Rotate x items between all bags, requires at lest 2 bags + * if an item doesnt fit, it will just take the next one in list until it goes through the whole list + * if no item fits, it skips. + * + * @param bags + */ + private boolean rotateBags(Bag[] bags, int times) { + if (bags.length == 2) { + Bag bag1 = bags[0], bag2 = bags[1]; + for (int i = 0; i < times; i++) + moveFromBagToBag(bag1, bag2); + } else if (bags.length >= 2) { + //Handle the first bag to swap with the last bag (in list) + Bag bag1 = bags[0], bag2 = bags[bags.length - 1]; + for (int i = 0; i < times; i++) + moveFromBagToBag(bag1, bag2); + //Handle the rest of the bags + for (int j = 1; j < bags.length; j++) { + bag1 = bags[j]; + bag2 = bags[j - 1]; + for (int i = 0; i < times; i++) + moveFromBagToBag(bag1, bag2); + } + + } + return false; + } + + /** + * Removes first item in bag and places it last on the unused-items list, then take + * the first item in the unused-items list, if the items doesnt fit it just skips + * + * @param bags + * @return + */ + private boolean rotateUnused(Bag[] bags, ArrayList unused, int times) { + for (int i = 0; i < bags.length; i++) { + for (int j = 0; j < times; j++) { + + Item randomItem = bags[i].getRandomItem(); + + if (randomItem != null) { + removeFromBagToUnused(bags[i], randomItem, unused); + addFromUnusedToBag(bags[i], unused); + } + + + } + } + return false; + } + + + //For testing purposes + /*public static void main(String[] args) { + Samples sample = new Samples(); + int nbrOfItems = 5; + int nbrOfBags = 2; + Item[] items = new Item[nbrOfItems]; + Bag[] bags = new Bag[nbrOfBags]; + items[0] = new Item("1", 10, 2, 2.2); + items[1] = new Item("2", 20, 3, 3.1); + items[2] = new Item("3", 18, 4, 4.3); + items[3] = new Item("4", 15, 3, 3.4); + items[4] = new Item("5", 22, 5, 5.1); + double[] params0 = new double[5], params1 = new double[5]; + params0[0] = 50; + params0[1] = 2; + params0[2] = -2.4; + params0[3] = -0.8; + params0[4] = 0.2; + params1[0] = 99; + params1[1] = -4; + params1[2] = -1.2; + params1[3] = 0.5; + params1[4] = -0.1; + bags[0] = new Bag(70, 10, params0, 0); + bags[1] = new Bag(50, 10, params1, 1); + NeighborhoodSearch ns = new NeighborhoodSearch(bags, new ArrayList<>(Arrays.asList(items))); + ns.search(); + }*/ +} diff --git a/aggregator/src/main/java/com/vmware/flowgate/aggregator/tool/SyncFittingTool.java b/aggregator/src/main/java/com/vmware/flowgate/aggregator/tool/SyncFittingTool.java new file mode 100644 index 000000000..789e0bae0 --- /dev/null +++ b/aggregator/src/main/java/com/vmware/flowgate/aggregator/tool/SyncFittingTool.java @@ -0,0 +1,197 @@ +package com.vmware.flowgate.aggregator.tool; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Comparator; +import java.util.List; + +import org.apache.commons.math3.fitting.PolynomialCurveFitter; +import org.apache.commons.math3.fitting.WeightedObservedPoints; +import org.apache.commons.math3.util.Pair; + +import com.vmware.flowgate.common.model.MetricData; + +public class SyncFittingTool { + + public List doubleToList(double[] arr_double) { + List list = new ArrayList(); + int num = arr_double.length; + Double [] arr_Double = new Double[num]; + for(int i = 0; i < num; i++) { + arr_Double[i] = arr_double[i]; + } + list = Arrays.asList(arr_Double); + return list; + } + + + + public List> MAD(List> dataset, double n) { + List> new_data = new ArrayList<>(); + List CPU = new ArrayList<>(); + for (int i = 0; i < dataset.size(); i++) { + CPU.add(dataset.get(i).getFirst()); + } + double median = median(CPU); + List deviations = new ArrayList<>(); + for (int i = 0; i < dataset.size(); i++) { + deviations.add(i, Math.abs(dataset.get(i).getFirst() - median)); + } + double mad = median(deviations); + for (int i = 0; i < dataset.size(); i++) + { + if (Math.abs(dataset.get(i).getFirst() - median) <= n * mad) + { + new_data.add(dataset.get(i)); + } + } + return new_data; + } + public static int partition(List nums, int start, int end){ + int left = start; + int right = end; + double pivot = nums.get(left); + while (left < right){ + while (left < right && nums.get(right) >= pivot) { + right--; + } + if (left < right) { + nums.set(left, nums.get(right)); + left++; + } + while (left < right && nums.get(left) <= pivot){ + left++; + } + if (left < right) { + nums.set(right, nums.get(left)); + right--; + } + } + nums.set(left, pivot); + return left; + } + + + public static double median(List nums){ + if (nums.size() == 0) + return 0; + int start = 0; + int end = nums.size() - 1; + int index = partition(nums, start, end); + if (nums.size() % 2 == 0){ + while (index != nums.size() / 2 - 1){ + if (index > nums.size() / 2 - 1){ + index = partition(nums, start, index - 1); + } else { + index=partition(nums, index+1, end); + } + } + } else { + while (index != nums.size() / 2) { + if (index > nums.size() / 2) { + index = partition(nums, start, index - 1); + } else { + index = partition(nums, index + 1, end); + } + } + } + return nums.get(index); + } + + + public List doFitting(List MetricDatas) { + + List CPU = new ArrayList<>(); + List power = new ArrayList<>(); + List> raw_CPU_list = new ArrayList<>(); + List> raw_power_list = new ArrayList<>(); + + for (int i = 0; i < MetricDatas.size(); i++) { + if (MetricDatas.get(i).getMetricName() == "CpuUsage") { + raw_CPU_list.add(new Pair (MetricDatas.get(i).getTimeStamp(), MetricDatas.get(i).getValueNum())); + } + else if (MetricDatas.get(i).getMetricName() == "Power") { + raw_power_list.add(new Pair (MetricDatas.get(i).getTimeStamp(), MetricDatas.get(i).getValueNum())); + } + } + Pair[] raw_CPU = new Pair[raw_CPU_list.size()]; + Pair[] raw_power = new Pair[raw_power_list.size()]; + for (int i = 0; i < raw_CPU_list.size(); i++) { + raw_CPU[i] = raw_CPU_list.get(i); + } + for (int i = 0; i < raw_power_list.size(); i++) { + raw_power[i] = raw_power_list.get(i); + } + + //Sort the pair list according the time in reverse order. + Arrays.sort(raw_CPU, new Comparator>() { + @Override + public int compare(Pair o1, Pair o2) { + if(o1.getFirst()==o2.getFirst()){ + return 0; + }else if (o1.getFirst() > o2.getFirst()){ + return -1; + } + else return 1; + } + }); + Arrays.sort(raw_power, new Comparator>() { + @Override + public int compare(Pair o1, Pair o2) { + if(o1.getFirst()==o2.getFirst()){ + return 0; + }else if (o1.getFirst() > o2.getFirst()){ + return -1; + } + else return 1; + } + }); + + int idx_CPU = 0, idx_power = 0; + List> raw_data = new ArrayList<>(); + while (idx_CPU < raw_CPU.length && idx_power < raw_power.length) { + if (raw_CPU[idx_CPU].getFirst().compareTo(raw_power[idx_power].getFirst()) == 0) { + raw_data.add(new Pair(raw_CPU[idx_CPU].getSecond(), raw_power[idx_power].getSecond())); + idx_CPU +=1; + idx_power +=1; + } + else if (raw_CPU[idx_CPU].getFirst().compareTo(raw_power[idx_power].getFirst()) == 1) { + idx_CPU += 1; + } + else if (raw_CPU[idx_CPU].getFirst().compareTo(raw_power[idx_power].getFirst()) == -1) { + idx_power += 1; + } + } + + + List> new_data = new ArrayList<>(); + WeightedObservedPoints points = new WeightedObservedPoints(); + while (raw_data.size() != 0) { + int count = 0; + for (int i = 1; i < raw_data.size(); i++) { + + if (raw_data.get(i).getSecond() >= raw_data.get(i-1).getSecond() + 1) + break; + count += 1; + if (count > 0) { + List> tmp = raw_data.subList(0, count + 1); + new_data.addAll(MAD(tmp, 1.5)); + } + raw_data = raw_data.subList(count + 1, raw_data.size()); + } + } + for(int i = 0; i < new_data.size(); i++) + { + points.add(new_data.get(i).getFirst(), new_data.get(i).getSecond()); + } + int degree = 4; + PolynomialCurveFitter fitter = PolynomialCurveFitter.create(degree); + double[] result = fitter.fit(points.toList()); + List fitting_result = doubleToList(result); + + + + return fitting_result; + } + +} diff --git a/aggregator/src/main/java/com/vmware/flowgate/aggregator/tool/basic/Bag.java b/aggregator/src/main/java/com/vmware/flowgate/aggregator/tool/basic/Bag.java new file mode 100644 index 000000000..367e53f07 --- /dev/null +++ b/aggregator/src/main/java/com/vmware/flowgate/aggregator/tool/basic/Bag.java @@ -0,0 +1,127 @@ +package com.vmware.flowgate.aggregator.tool.basic; +import java.util.ArrayList; +import java.util.Random; +public class Bag { + int Memory; + double currentMemory; + int CPU; + double currentCPU; + int index; + double totalPower; + double[] params; + ArrayList items; + Random random = new Random(); + + public Bag(int memory, int cpu, double[] params, int idx) { + this.Memory = memory; + this.CPU = cpu; + this.currentMemory = 0; + this.currentCPU = 0; + this.params = params; + this.index = idx; + items = new ArrayList<>(); + } + + public int getIndex() { + return index; + } + + public int getCPU() { + return CPU; + } + + public double getCurrentCPU() { + return currentCPU; + } + + public int getMemory() { + return Memory; + } + + public double getValueInBag(double value) { + double res = 0; + for (int i = 0; i < params.length; i++) { + res += params[i] * Math.pow(value, i); + } + return res; + } + + public double getCurrentMemory() { + return currentMemory; + } + + + + public double getTotalPower() { + return totalPower; + } + + public ArrayList getItems() { + return items; + } + + public Item getRandomItem(){ + int index = 0; + if(!items.isEmpty()) { + index = random.nextInt(items.size()); + return items.get(index); + + } else { + return null; + } + + } + + public void addItem(Item item, int finalBag) { + if (!items.contains(item)) { + items.add(item); + currentMemory = currentMemory + item.getMemory(); + currentCPU = currentCPU + item.getCPU(); + this.totalPower += item.getPower()[finalBag].getFirst(); + } + + + } + + public double availableMemory(){ + return (Memory-currentMemory); + } + + public double availableCPU() { + return (CPU - currentCPU); + } + + public Item removeItem(Item item, int finalBag) { + + + currentMemory = currentMemory - item.getMemory(); + currentCPU = currentCPU - item.getCPU(); + int index = items.indexOf(item); + this.totalPower -= item.getPower()[finalBag].getFirst(); + return items.remove(index); + } + + public Bag clone() { + Bag newBag = new Bag(Memory, CPU, params, index); + newBag.currentMemory = currentMemory; + newBag.currentCPU = currentCPU; + newBag.totalPower = totalPower; + newBag.CPU = CPU; + newBag.items = new ArrayList<>(items); + + return newBag; + } + + public String toString(){ + String s = "Bag(index: " + this.index + ", Memory: " + this.Memory + ", current memory: " +this.currentMemory + ", CPU: " + this.CPU +", currentCPU: " + this.currentCPU+", value: "+totalPower+")" + "\n"; + for (int i = 0; i < items.size(); i++) { + s += items.get(i).toStringByIdx(this.index); + s += "\n"; + } + return s; + } + public String toFullString(){ + return "Bag(Memory: " + this.Memory + ", current Memory: " +this.currentMemory + ", items: "+this.items+")"; + } + +} diff --git a/aggregator/src/main/java/com/vmware/flowgate/aggregator/tool/basic/Item.java b/aggregator/src/main/java/com/vmware/flowgate/aggregator/tool/basic/Item.java new file mode 100644 index 000000000..64edcb87d --- /dev/null +++ b/aggregator/src/main/java/com/vmware/flowgate/aggregator/tool/basic/Item.java @@ -0,0 +1,112 @@ +package com.vmware.flowgate.aggregator.tool.basic; +import org.apache.commons.math3.util.Pair; + +import java.util.*; +public class Item { + double memory;//Memory + double CPU;//CPUUsage + double CPU_capacity; + Pair[] power; + String id; + + public Item(String id, double memory, double cpu, double cpu_capacity) { + this.id = id; + this.memory = memory; + this.CPU = cpu; + this.CPU_capacity = cpu_capacity; + } + + public double getMemory() { + return memory; + } + + public String getId() { + return id; + } + + public Pair[] getPower() { + return this.power; + } + + public double getCPU_capacity () { + return this.CPU_capacity; + } + + public int getValueIdxThroughBagIdx(int BagIdx) { + for (int i = 0; i < this.getPower().length; i++) { + if (this.getPower()[i].getSecond() == BagIdx) + { + return i; + } + } + return -1; + } + + public void setValueAndBenefitInBag(Bag[] bags) { + this.power = new Pair[bags.length]; + for (int i = 0; i < bags.length; i++) { + Bag bag = bags[i]; + this.power[i] = new Pair(bag.getValueInBag(CPU), i); + } + Arrays.sort(this.power, new Comparator>() { + @Override + public int compare(Pair o1, Pair o2) { + if(o1.getFirst()==o2.getFirst()){ + return 0; + }else if (o1.getFirst() > o2.getFirst()){ + return -1; + } + else return 1; + } + }); + + } + + public double getCPU() { + return CPU; + } + + public double getBenefit() { + return getCPU()/memory; + } + + public int compareTo(Item o) { + return 0; + } + + + @Override + public int hashCode() { + return Objects.hash(memory,CPU); + } + + @Override + public boolean equals(Object o) + { + if (this == o) { + return true; + } + if (o == null) { + return false; + } + if (this.getClass() != o.getClass()) { + return false; + } + Item other = (Item)o; + if (!Objects.equals(this.memory, other.getMemory())) { + return false; + } + if (!Objects.equals(this.CPU, other.getCPU())) { + return false; + } + return true; + } + + public String toString() { + return "Item(Id: " + this.getId() + ", Memory: "+this.memory +", CPU used: "+this.CPU +", CPU capacity: " + this.CPU_capacity + ", hash: "+this.hashCode()+")"; + } + + public String toStringByIdx(int idx) { + return "Item(Id: " + this.getId() + ", Memory: "+this.memory +", CPU used: "+this.CPU +", CPU capacity: " + this.CPU_capacity + ", power: " + power[getValueIdxThroughBagIdx(idx)].getFirst() + ", hash: "+this.hashCode()+")"; + } +} diff --git a/aggregator/src/main/java/com/vmware/flowgate/aggregator/tool/basic/Neighborhood.java b/aggregator/src/main/java/com/vmware/flowgate/aggregator/tool/basic/Neighborhood.java new file mode 100644 index 000000000..4bb554716 --- /dev/null +++ b/aggregator/src/main/java/com/vmware/flowgate/aggregator/tool/basic/Neighborhood.java @@ -0,0 +1,51 @@ +package com.vmware.flowgate.aggregator.tool.basic; +import java.util.ArrayList; +public class Neighborhood { + ArrayList unusedItems; + Bag[] bags; + + public Neighborhood(ArrayList unusedItems, Bag[] bags) { + this.unusedItems = new ArrayList<>(unusedItems); + + this.bags = new Bag[bags.length]; + for(int i = 0; i getUnusedItems() { + return unusedItems; + } + + public Bag[] getBags() { + return bags; + } + + public int getBagsItemsNumber () { + int ret = 0; + for (int i = 0; i < bags.length; i++) { + ret += bags[i].getItems().size(); + } + return ret; + } + + public int getTotalPower(){ + int res = 0; + for(Bag b : bags){ + res+=b.getTotalPower(); + } + return res; + } + + public String toString(){ + String res = "Neighborhood with value: " + getTotalPower() + "\n"; + + for(int i = 0; i - /log/aggregator-info.log + aggregator-info.log /log/aggregator-info.%d{yyyy-MM-dd}.gz @@ -43,7 +43,7 @@ - - + + \ No newline at end of file diff --git a/aggregator/src/test/java/com/vmware/flowgate/aggregator/MessageProcessingTest.java b/aggregator/src/test/java/com/vmware/flowgate/aggregator/MessageProcessingTest.java index 9388415df..3c6f9dc59 100644 --- a/aggregator/src/test/java/com/vmware/flowgate/aggregator/MessageProcessingTest.java +++ b/aggregator/src/test/java/com/vmware/flowgate/aggregator/MessageProcessingTest.java @@ -10,6 +10,7 @@ import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.when; +import java.io.FileNotFoundException; import java.io.IOException; import java.util.ArrayList; import java.util.Date; @@ -37,6 +38,7 @@ import org.springframework.test.context.ActiveProfiles; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import com.csvreader.CsvReader; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; @@ -45,6 +47,7 @@ import com.vmware.flowgate.aggregator.scheduler.job.CustomerAdapterJobDispatcher; import com.vmware.flowgate.aggregator.scheduler.job.OpenmanageJobDispatcher; import com.vmware.flowgate.aggregator.scheduler.job.VCenterJobDispatcher; +import com.vmware.flowgate.aggregator.tool.SyncFittingTool; import com.vmware.flowgate.client.WormholeAPIClient; import com.vmware.flowgate.common.FlowgateConstant; import com.vmware.flowgate.common.MetricName; @@ -54,6 +57,7 @@ import com.vmware.flowgate.common.model.FacilitySoftwareConfig; import com.vmware.flowgate.common.model.FacilitySoftwareConfig.AdvanceSettingType; import com.vmware.flowgate.common.model.IntegrationStatus; +import com.vmware.flowgate.common.model.MetricData; import com.vmware.flowgate.common.model.IntegrationStatus.Status; import com.vmware.flowgate.common.model.SDDCSoftwareConfig; import com.vmware.flowgate.common.model.SDDCSoftwareConfig.SoftwareType; @@ -131,6 +135,8 @@ public void testVC() throws Exception{ System.out.println(mapper.writeValueAsString(message)); } + + @Test public void testGetPositionInfo() { Asset asset1 = new Asset(); @@ -513,7 +519,7 @@ public void testGeneratePduformulaForServer() { TestCase.assertEquals(pduIds.size(), pduFormula.size()); TestCase.assertEquals(8, pduFormula.get(pduIds.get(0)).size()); } - + FacilitySoftwareConfig createFacilitySoftware() { FacilitySoftwareConfig example = new FacilitySoftwareConfig(); example.setId(UUID.randomUUID().toString()); @@ -534,7 +540,8 @@ FacilitySoftwareConfig createFacilitySoftware() { example.setIntegrationStatus(integrationStatus); return example; } - + + public ResponseEntity getFacilitySoftwareByType(FacilitySoftwareConfig intergration) { FacilitySoftwareConfig[] configs = new FacilitySoftwareConfig[1]; configs[0] = intergration; diff --git a/aggregator/src/test/java/com/vmware/flowgate/aggregator/RecommendTest.java b/aggregator/src/test/java/com/vmware/flowgate/aggregator/RecommendTest.java new file mode 100644 index 000000000..a72a45ce5 --- /dev/null +++ b/aggregator/src/test/java/com/vmware/flowgate/aggregator/RecommendTest.java @@ -0,0 +1,132 @@ +package com.vmware.flowgate.aggregator; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.when; +import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document; +import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get; +import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath; +import static org.springframework.restdocs.payload.PayloadDocumentation.responseFields; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.junit.Assert; +import org.junit.Test; +import org.mockito.InjectMocks; +import org.mockito.Spy; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.boot.test.mock.mockito.SpyBean; + +import org.springframework.data.redis.core.StringRedisTemplate; +import org.springframework.restdocs.payload.FieldDescriptor; +import org.springframework.restdocs.payload.JsonFieldType; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.MvcResult; + + +import com.vmware.flowgate.aggregator.config.ServiceKeyConfig; +import com.vmware.flowgate.aggregator.scheduler.job.AggregatorService; +import com.vmware.flowgate.aggregator.tool.SyncFittingTool; +import com.vmware.flowgate.client.WormholeAPIClient; +import com.vmware.flowgate.common.AssetCategory; +import com.vmware.flowgate.common.model.Asset; +import com.vmware.flowgate.common.model.MetricData; +import com.vmware.flowgate.aggregator.tool.*; +import com.vmware.flowgate.aggregator.tool.basic.*; + + +import junit.framework.TestCase; + +public class RecommendTest { + @MockBean + private StringRedisTemplate template; + @Spy + @InjectMocks + private AggregatorService aggregatorService = new AggregatorService(); + + @MockBean + private WormholeAPIClient restClient; + + @MockBean + private ServiceKeyConfig serviceKeyConfig; + + + + @Test + public void testRecommend() throws Exception { + try { + int nbrOfItems = 5; + int nbrOfBags = 2; + Item[] items = new Item[nbrOfItems]; + Bag[] bags = new Bag[nbrOfBags]; + items[0] = new Item("1", 10, 2, 2.2); + items[1] = new Item("2", 20, 3, 3.1); + items[2] = new Item("3", 18, 4, 4.3); + items[3] = new Item("4", 15, 3, 3.4); + items[4] = new Item("5", 22, 5, 5.1); + double[] params0 = new double[5], params1 = new double[5]; + params0[0] = 50; + params0[1] = 2; + params0[2] = -2.4; + params0[3] = -0.8; + params0[4] = 0.2; + params1[0] = 99; + params1[1] = -4; + params1[2] = -1.2; + params1[3] = 0.5; + params1[4] = -0.1; + bags[0] = new Bag(70, 10, params0, 0); + bags[1] = new Bag(50, 10, params1, 1); + NeighborhoodSearch ns = new NeighborhoodSearch(bags, new ArrayList<>(Arrays.asList(items))); + ns.search(); + Bag[] bag_result = ns.getBags(); + double[] bag0_result = {bag_result[0].getCurrentMemory(), bag_result[0].getCurrentCPU(), bag_result[0].getTotalPower()}; + double[] bag0_answer = {38.0, 7.0, 48.6}; + double[] bag1_result = {bag_result[1].getCurrentMemory(), bag_result[1].getCurrentCPU(), bag_result[1].getTotalPower()}; + double[] bag1_answer = {47.0, 10.0, 219.2}; + ArrayList bag0_items = bag_result[0].getItems(); + ArrayList bag1_items = bag_result[1].getItems(); + HashSet bag0items_answer = new HashSet<>(); + HashSet bag0items_result = new HashSet<>(); + HashSet bag1items_answer = new HashSet<>(); + HashSet bag1items_result = new HashSet<>(); + + for (int i = 0; i < bag0_items.size(); i++) { + bag0items_result.add(bag0_items.get(i).getId()); + } + for (int i = 0; i < bag1_items.size(); i++) { + bag1items_result.add(bag1_items.get(i).getId()); + } + bag0items_answer.add("2"); + bag0items_answer.add("3"); + bag1items_answer.add("1"); + bag1items_answer.add("4"); + bag1items_answer.add("5"); + + Assert.assertArrayEquals(bag0_result, bag0_answer, 0.5); + Assert.assertArrayEquals(bag1_result, bag1_answer, 0.5); + + if (!bag0items_result.equals(bag0items_answer)) { + System.out.print(false); + Assert.fail(); + } + if (!bag1items_result.equals(bag1items_answer)) { + Assert.fail(); + } + + } catch(Exception e) { + Assert.fail(); + } + + } + + +} \ No newline at end of file diff --git a/aggregator/src/test/java/com/vmware/flowgate/aggregator/SyncFittingTest.java b/aggregator/src/test/java/com/vmware/flowgate/aggregator/SyncFittingTest.java new file mode 100644 index 000000000..ae5bc5c3c --- /dev/null +++ b/aggregator/src/test/java/com/vmware/flowgate/aggregator/SyncFittingTest.java @@ -0,0 +1,106 @@ +package com.vmware.flowgate.aggregator; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.when; +import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document; +import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get; +import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath; +import static org.springframework.restdocs.payload.PayloadDocumentation.responseFields; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + + +import org.junit.Assert; +import org.junit.Test; +import org.mockito.InjectMocks; +import org.mockito.Spy; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.boot.test.mock.mockito.SpyBean; + +import org.springframework.data.redis.core.StringRedisTemplate; +import org.springframework.restdocs.payload.FieldDescriptor; +import org.springframework.restdocs.payload.JsonFieldType; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.MvcResult; + +import com.csvreader.CsvReader; + +import com.vmware.flowgate.aggregator.config.ServiceKeyConfig; +import com.vmware.flowgate.aggregator.scheduler.job.AggregatorService; +import com.vmware.flowgate.aggregator.tool.SyncFittingTool; +import com.vmware.flowgate.client.WormholeAPIClient; +import com.vmware.flowgate.common.AssetCategory; +import com.vmware.flowgate.common.model.Asset; +import com.vmware.flowgate.common.model.MetricData; + + +import junit.framework.TestCase; + +public class SyncFittingTest { + @MockBean + private StringRedisTemplate template; + @Spy + @InjectMocks + private AggregatorService aggregatorService = new AggregatorService(); + + @MockBean + private WormholeAPIClient restClient; + + @MockBean + private ServiceKeyConfig serviceKeyConfig; + + + + @Test + public void testSyncFitting() throws Exception { + try { + List MetricDatas; + SyncFittingTool tool = new SyncFittingTool(); + MetricDatas = new ArrayList<>(); + + CsvReader csvReader = new CsvReader("testData.csv"); + boolean re = csvReader.readHeaders(); + int n = 0; + while (csvReader.readRecord()) { + String rawRecord = csvReader.getRawRecord(); + String[] line = rawRecord.split(","); + MetricData cpu = new MetricData(); + cpu.setMetricName("CpuUsage"); + cpu.setValueNum(Double.valueOf(line[0])); + cpu.setTimeStamp(n); + MetricDatas.add(cpu); + MetricData power = new MetricData(); + power.setMetricName("Power"); + power.setValueNum(Double.valueOf(line[1])); + power.setTimeStamp(n); + MetricDatas.add(power); + n+=1; + } + + List results = tool.doFitting(MetricDatas); + + double [] arr_result = new double[results.size()]; + for (int i = 0; i < results.size(); i++) { + arr_result[i] = results.get(i); + } + double[] testAnswer = {67.61123636351215, 2.0250676734875026, -0.04034063855153128, 3.8173496754197417E-4, -1.2569420548906328E-6}; + Assert.assertArrayEquals(arr_result, testAnswer, 0.5); + Asset asset = new Asset(); + asset.setFittingResults(results); + restClient.saveAssets(asset); + + } catch(Exception e) { + Assert.fail(); + } + + } + + +} diff --git a/aggregator/testData.csv b/aggregator/testData.csv new file mode 100644 index 000000000..601f6b9c4 --- /dev/null +++ b/aggregator/testData.csv @@ -0,0 +1,520 @@ +0.72,71.0 +0.73,71.0 +0.71,71.0 +0.71,71.0 +0.72,71.0 +0.7,71.0 +0.7,71.0 +0.71,71.0 +0.73,71.0 +0.71,71.0 +0.68,71.0 +0.68,71.0 +0.68,71.0 +3.51,73.0 +3.38,73.0 +3.43,73.0 +3.6,73.0 +3.42,73.0 +3.55,73.0 +3.41,73.0 +3.66,73.0 +3.94,73.0 +3.91,73.0 +3.96,73.0 +4.59,74.0 +4.33,74.0 +5.42,74.0 +3.9,74.0 +3.77,74.0 +3.6,74.0 +5.02,74.0 +3.68,74.0 +4.97,74.0 +5.53,74.0 +4.4,74.0 +4.67,74.0 +5.58,74.0 +5.46,74.0 +4.94,74.0 +4.92,74.0 +6.67,75.0 +6.18,75.0 +6.01,75.0 +4.88,75.0 +5.17,75.0 +6.13,75.0 +6.75,75.0 +7.21,75.0 +6.25,75.0 +8.72,76.0 +8.37,76.0 +7.07,76.0 +8.35,76.0 +8.04,76.0 +7.5,76.0 +3.49,77.0 +3.52,77.0 +4.19,77.0 +5.76,77.0 +9.17,78.0 +9.61,78.0 +7.08,79.0 +6.51,79.0 +4.4,79.0 +4.42,79.0 +4.41,79.0 +3.77,80.0 +5.91,80.0 +11.02,82.0 +10.99,82.0 +11.11,87.0 +11.28,87.0 +13.43,88.0 +13.81,88.0 +13.24,88.0 +15.1,89.0 +14.75,89.0 +15.21,89.0 +15.08,89.0 +15.97,90.0 +16.15,90.0 +18.22,91.0 +18.53,91.0 +17.42,91.0 +19.02,91.0 +17.49,91.0 +21.89,92.0 +23.86,92.0 +22.39,92.0 +19.05,92.0 +20.29,92.0 +23.74,92.0 +20.72,92.0 +12.01,93.0 +12.04,93.0 +11.9,93.0 +12.18,93.0 +11.91,93.0 +12.11,93.0 +12.02,93.0 +11.96,93.0 +11.98,93.0 +12.01,93.0 +12.04,93.0 +12.01,93.0 +11.93,93.0 +11.97,93.0 +12.23,93.0 +12.12,93.0 +11.98,93.0 +27.78,94.0 +29.52,94.0 +26.03,94.0 +28.76,94.0 +30.97,94.0 +31.63,95.0 +33.37,95.0 +32.98,95.0 +32.65,95.0 +33.72,96.0 +31.84,96.0 +31.35,96.0 +35.07,96.0 +36.82,96.0 +34.67,96.0 +36.45,97.0 +37.54,97.0 +39.9,97.0 +35.73,97.0 +38.68,97.0 +38.51,97.0 +26.91,98.0 +27.1,98.0 +26.95,98.0 +26.39,98.0 +25.6,98.0 +26.9,98.0 +27.97,98.0 +27.69,98.0 +27.3,98.0 +27.43,98.0 +22.77,98.0 +24.31,98.0 +22.82,98.0 +22.84,98.0 +22.9,98.0 +23.36,98.0 +22.87,98.0 +23.36,98.0 +27.36,99.0 +22.78,99.0 +33.54,99.0 +22.88,99.0 +23.02,99.0 +24.54,99.0 +22.75,99.0 +22.84,99.0 +22.92,99.0 +24.27,99.0 +22.74,99.0 +47.93,100.0 +50.07,100.0 +51.93,100.0 +52.48,100.0 +52.06,100.0 +55.01,101.0 +52.2,101.0 +50.0,101.0 +49.05,101.0 +54.56,101.0 +52.99,101.0 +48.67,101.0 +35.23,102.0 +33.56,102.0 +33.65,102.0 +33.54,102.0 +35.12,102.0 +33.64,102.0 +33.59,102.0 +33.49,102.0 +33.51,102.0 +35.21,102.0 +33.38,102.0 +31.75,102.0 +31.58,102.0 +33.55,103.0 +33.54,103.0 +33.56,103.0 +33.6,103.0 +33.52,103.0 +33.4,103.0 +33.57,103.0 +33.53,103.0 +33.53,103.0 +33.51,103.0 +33.54,103.0 +33.7,103.0 +33.48,103.0 +33.49,104.0 +33.55,104.0 +34.28,104.0 +34.64,104.0 +35.27,104.0 +33.64,104.0 +33.48,104.0 +35.06,104.0 +33.6,104.0 +33.59,104.0 +33.71,104.0 +33.7,104.0 +34.93,104.0 +33.65,104.0 +34.98,104.0 +66.26,105.0 +68.51,105.0 +66.88,105.0 +66.78,105.0 +67.82,105.0 +69.54,105.0 +70.17,105.0 +69.0,105.0 +66.61,105.0 +72.33,106.0 +70.58,106.0 +69.47,106.0 +73.82,106.0 +72.47,106.0 +74.77,107.0 +76.04,107.0 +77.66,107.0 +74.86,107.0 +72.98,107.0 +45.84,107.0 +44.25,107.0 +44.31,107.0 +44.06,107.0 +45.71,107.0 +44.09,107.0 +45.23,107.0 +44.51,107.0 +44.23,107.0 +42.63,107.0 +75.13,107.0 +76.42,107.0 +78.13,107.0 +75.88,107.0 +74.37,107.0 +79.33,108.0 +80.31,108.0 +79.12,108.0 +80.23,108.0 +79.43,108.0 +77.86,108.0 +83.85,109.0 +84.74,109.0 +86.31,109.0 +82.71,109.0 +82.86,109.0 +84.61,109.0 +86.04,109.0 +85.02,109.0 +83.09,109.0 +88.13,110.0 +88.64,110.0 +86.73,110.0 +87.94,110.0 +87.3,110.0 +91.67,111.0 +92.75,111.0 +94.13,111.0 +95.17,111.0 +90.66,111.0 +54.82,111.0 +54.75,111.0 +56.16,111.0 +54.79,111.0 +54.58,111.0 +55.18,111.0 +54.79,111.0 +55.96,111.0 +55.06,111.0 +54.57,111.0 +54.54,111.0 +90.49,111.0 +91.62,111.0 +92.89,111.0 +93.24,111.0 +91.59,111.0 +89.57,111.0 +96.67,112.0 +95.33,112.0 +94.5,112.0 +95.57,112.0 +96.71,112.0 +97.72,112.0 +97.96,112.0 +96.46,112.0 +94.72,112.0 +100.0,113.0 +100.0,113.0 +100.0,113.0 +100.0,113.0 +100.0,113.0 +100.0,113.0 +100.0,113.0 +100.0,113.0 +100.0,113.0 +100.0,113.0 +100.0,114.0 +100.0,114.0 +100.0,114.0 +100.0,114.0 +100.0,114.0 +55.52,114.0 +54.98,114.0 +54.93,114.0 +54.85,114.0 +56.45,114.0 +54.53,114.0 +54.87,114.0 +54.83,114.0 +55.06,114.0 +56.26,114.0 +54.84,114.0 +55.02,114.0 +54.93,114.0 +54.9,114.0 +56.27,114.0 +54.83,114.0 +54.9,114.0 +56.22,114.0 +100.0,114.0 +100.0,114.0 +100.0,114.0 +100.0,114.0 +100.0,114.0 +100.0,114.0 +100.0,114.0 +100.0,114.0 +100.0,114.0 +100.0,114.0 +100.0,114.0 +100.0,114.0 +100.0,114.0 +100.0,115.0 +100.0,115.0 +100.0,115.0 +100.0,115.0 +100.0,115.0 +100.0,115.0 +100.0,115.0 +100.0,115.0 +100.0,115.0 +100.0,115.0 +100.0,115.0 +100.0,115.0 +100.0,115.0 +100.0,115.0 +100.0,115.0 +100.0,115.0 +100.0,115.0 +100.0,115.0 +100.0,115.0 +100.0,115.0 +100.0,115.0 +100.0,115.0 +100.0,115.0 +100.0,115.0 +100.0,116.0 +100.0,116.0 +100.0,116.0 +100.0,116.0 +100.0,116.0 +100.0,116.0 +100.0,116.0 +100.0,116.0 +100.0,116.0 +100.0,116.0 +100.0,116.0 +100.0,116.0 +100.0,116.0 +100.0,116.0 +100.0,116.0 +100.0,116.0 +100.0,117.0 +100.0,117.0 +100.0,117.0 +100.0,117.0 +100.0,117.0 +100.0,117.0 +100.0,117.0 +100.0,117.0 +100.0,117.0 +100.0,117.0 +100.0,117.0 +100.0,117.0 +100.0,117.0 +100.0,117.0 +65.31,118.0 +64.5,118.0 +64.57,118.0 +64.84,118.0 +64.47,118.0 +64.99,118.0 +64.71,118.0 +65.07,118.0 +64.5,118.0 +64.51,118.0 +64.96,118.0 +64.67,118.0 +74.43,119.0 +73.97,119.0 +74.41,119.0 +74.11,119.0 +74.63,119.0 +74.27,119.0 +74.62,119.0 +74.1,119.0 +74.22,119.0 +73.83,119.0 +82.88,121.0 +82.87,121.0 +82.97,122.0 +83.12,122.0 +83.08,122.0 +83.35,122.0 +82.9,122.0 +83.34,122.0 +83.47,122.0 +92.54,125.0 +92.75,125.0 +92.45,125.0 +92.36,125.0 +92.58,125.0 +92.49,125.0 +92.74,125.0 +92.61,126.0 +92.45,126.0 +92.57,126.0 +94.16,126.0 +92.55,126.0 +93.5,126.0 +92.28,126.0 +92.44,126.0 +93.43,126.0 +100.0,127.0 +100.0,127.0 +92.49,128.0 +71.79,128.0 +92.66,129.0 +92.68,129.0 +92.58,129.0 +92.55,129.0 +92.07,129.0 +92.65,129.0 +92.58,129.0 +92.68,129.0 +92.41,129.0 +92.24,129.0 +92.33,129.0 +92.59,129.0 +100.0,130.0 +100.0,130.0 +100.0,130.0 +100.0,130.0 +100.0,130.0 +100.0,130.0 +100.0,130.0 +100.0,130.0 +100.0,130.0 +100.0,130.0 +100.0,130.0 +100.0,130.0 +100.0,130.0 +100.0,130.0 +100.0,130.0 +100.0,130.0 +100.0,130.0 +100.0,130.0 +100.0,130.0 +100.0,130.0 +100.0,130.0 +100.0,130.0 +100.0,130.0 +100.0,130.0 +100.0,130.0 +100.0,130.0 +100.0,130.0 +100.0,130.0 +100.0,130.0 +100.0,130.0 +100.0,130.0 +100.0,130.0 +100.0,135.0 +100.0,135.0 +100.0,135.0 +100.0,136.0 +100.0,136.0 +100.0,136.0 +100.0,136.0 +100.0,136.0 +100.0,136.0 +100.0,136.0 +100.0,136.0 +100.0,136.0 +100.0,136.0 +100.0,136.0 +100.0,136.0 +100.0,136.0 +100.0,136.0 +100.0,136.0 +100.0,137.0 +100.0,137.0 +100.0,137.0 +100.0,137.0 +100.0,137.0 +100.0,137.0 +100.0,137.0 +100.0,137.0 +100.0,137.0 diff --git a/common-restclient/src/main/java/com/vmware/flowgate/client/WormholeAPIClient.java b/common-restclient/src/main/java/com/vmware/flowgate/client/WormholeAPIClient.java index d4cd9bb0c..c556a1aba 100644 --- a/common-restclient/src/main/java/com/vmware/flowgate/client/WormholeAPIClient.java +++ b/common-restclient/src/main/java/com/vmware/flowgate/client/WormholeAPIClient.java @@ -40,6 +40,8 @@ public class WormholeAPIClient extends RestClientBase { private static final String fetchSensorDataURL = "/v1/assets/server/%s/realtimedata?starttime=%d&duration=%d"; + private static final String fetchServerDataURL = + "/v1/assets/%s/realtimedata?starttime=%d&duration=%d"; private static final String GetJobsURL = "/v1/jobs/type/%s"; private static final String GetSummaryDataURL = "/v1/summary/systemsummary?usecache=%s"; @@ -356,6 +358,14 @@ public ResponseEntity getServerRelatedSensorDataByServerID(String + String.format(fetchSensorDataURL, assetID, startTime, duration), HttpMethod.GET, getDefaultEntity(), MetricData[].class); } + + public ResponseEntity getServerRealtimeDataByServerID(String assetID, + long startTime, long duration) { + return this.restTemplate.exchange( + getAPIServiceEndpoint() + + String.format(fetchServerDataURL, assetID, startTime, duration), + HttpMethod.GET, getDefaultEntity(), MetricData[].class); + } public ResponseEntity mergMapping(String id1, String id2) { return this.restTemplate.exchange( diff --git a/flowgate-api/src/main/java/com/vmware/flowgate/service/AssetService.java b/flowgate-api/src/main/java/com/vmware/flowgate/service/AssetService.java index 5d78ea916..036f91848 100644 --- a/flowgate-api/src/main/java/com/vmware/flowgate/service/AssetService.java +++ b/flowgate-api/src/main/java/com/vmware/flowgate/service/AssetService.java @@ -1407,4 +1407,4 @@ private String getValueUnitName(Map formulaKeyAndValueUnitNameMa } return valueUnitName; } -} +} \ No newline at end of file diff --git a/flowgate-api/src/main/java/com/vmware/flowgate/service/CompareValueUnitByTime.java b/flowgate-api/src/main/java/com/vmware/flowgate/service/CompareValueUnitByTime.java index a5fcf1dbc..69a8d0523 100644 --- a/flowgate-api/src/main/java/com/vmware/flowgate/service/CompareValueUnitByTime.java +++ b/flowgate-api/src/main/java/com/vmware/flowgate/service/CompareValueUnitByTime.java @@ -18,4 +18,4 @@ public int compare(ValueUnit v1, ValueUnit v2) { } return -1; } -} +} \ No newline at end of file diff --git a/flowgate-api/src/main/resources/logback-spring.xml b/flowgate-api/src/main/resources/logback-spring.xml index 2896a1111..7932588f3 100644 --- a/flowgate-api/src/main/resources/logback-spring.xml +++ b/flowgate-api/src/main/resources/logback-spring.xml @@ -4,11 +4,10 @@ - /log/flowgate-api-info.log + flowgate-api-info.log - /log/flowgate-api-info.%d{yyyy-MM-dd}.gz - + flowgate-api-info.%d{yyyy-MM-dd}.gz 30 3GB @@ -29,8 +28,7 @@ - /log/flowgate-api-error.%d{yyyy-MM-dd}.gz - + /log/flowgate-api-error.%d{yyyy-MM-dd}.gz 30 3GB diff --git a/flowgate-api/src/test/java/com/vmware/flowgate/controller/AssetControllerTest.java b/flowgate-api/src/test/java/com/vmware/flowgate/controller/AssetControllerTest.java index 342c110fa..ab9bdee76 100644 --- a/flowgate-api/src/test/java/com/vmware/flowgate/controller/AssetControllerTest.java +++ b/flowgate-api/src/test/java/com/vmware/flowgate/controller/AssetControllerTest.java @@ -3871,4 +3871,4 @@ Asset fillingMetricsformula(Asset asset){ asset.setMetricsformulars(formulars); return asset; } -} +} \ No newline at end of file diff --git a/flowgate-api/src/test/resources/application.properties b/flowgate-api/src/test/resources/application.properties index 9b0f8e0ac..8f1fac5c8 100644 --- a/flowgate-api/src/test/resources/application.properties +++ b/flowgate-api/src/test/resources/application.properties @@ -19,4 +19,4 @@ spring.data.redis.repositories.enabled=false ##########guard store############# api.guardstore.path=classpath:guard.jceks api.guardstore.alias=flowgateEncrypt -api.guardstore.pass=c010d0ac205c46e6a0ff7144e05773ed \ No newline at end of file +api.guardstore.pass=c010d0ac205c46e6a0ff7144e05773ed diff --git a/flowgate-api/src/test/resources/application.properties-e b/flowgate-api/src/test/resources/application.properties-e new file mode 100644 index 000000000..07e03a910 --- /dev/null +++ b/flowgate-api/src/test/resources/application.properties-e @@ -0,0 +1,22 @@ +#Copyright 2019 VMware, Inc. +#SPDX-License-Identifier: BSD-2-Clause +#######service port########### +server.port=49610 + +########couchbase config###### +spring.couchbase.env.timeouts.query=30000 +spring.couchbase.bootstrap-hosts=database-build +spring.couchbase.bucket.name=flowgatetest +spring.couchbase.bucket.password=COUCHBASEPASSWD_CHANGE +spring.data.couchbase.auto-index=true +#######Default query limitation###### +#######By default only allow query realtime data for 30 minutes +asset.realtimedata.limit.duration=30 +api.cross.allowedOrigin = * +api.cross.allowedMethod = GET,POST,PUT,DELETE +api.cross.allowedHeader = Content-Type,Authorization +spring.data.redis.repositories.enabled=false +##########guard store############# +api.guardstore.path=classpath:guard.jceks +api.guardstore.alias=flowgateEncrypt +api.guardstore.pass=c010d0ac205c46e6a0ff7144e05773ed diff --git a/flowgate-common/src/main/java/com/vmware/flowgate/common/MetricKeyName.java b/flowgate-common/src/main/java/com/vmware/flowgate/common/MetricKeyName.java index 3cf7c2f5c..fd6a6c14f 100644 --- a/flowgate-common/src/main/java/com/vmware/flowgate/common/MetricKeyName.java +++ b/flowgate-common/src/main/java/com/vmware/flowgate/common/MetricKeyName.java @@ -20,4 +20,4 @@ public class MetricKeyName { public static final String SERVER_CONNECTED_PDUX_OUTLETX_CURRENT = "PDU:%s|%s|Current"; public static final String SERVER_CONNECTED_PDUX_OUTLETX_POWER = "PDU:%s|%s|Power"; public static final String SERVER_CONNECTED_PDUX_OUTLETX_VOLTAGE = "PDU:%s|%s|Voltage"; -} +} \ No newline at end of file diff --git a/flowgate-common/src/main/java/com/vmware/flowgate/common/MetricName.java b/flowgate-common/src/main/java/com/vmware/flowgate/common/MetricName.java index be65e7bce..7e3c6dd7d 100644 --- a/flowgate-common/src/main/java/com/vmware/flowgate/common/MetricName.java +++ b/flowgate-common/src/main/java/com/vmware/flowgate/common/MetricName.java @@ -15,8 +15,8 @@ public class MetricName { public static final String PDU_APPARENT_POWER = "ApparentPower"; public static final String PDU_CURRENT = "Current"; public static final String PDU_FREE_CAPACITY = "FreeCapacity"; - public static final String PDU_TOTAL_CURRENT = "Current"; - public static final String PDU_TOTAL_POWER = "Power"; + public static final String PDU_TOTAL_CURRENT = "TotalCurrent"; + public static final String PDU_TOTAL_POWER = "TotalPower"; public static final String PDU_CURRENT_LOAD = "CurrentLoad"; public static final String PDU_POWER_LOAD = "PowerLoad"; public static final String PDU_TEMPERATURE = "Temperature"; @@ -31,14 +31,14 @@ public class MetricName { public static final String PDU_INLET_XPOLE_CURRENT = "%s|%s|Current"; public static final String PDU_INLET_XPOLE_FREE_CAPACITY = "%s|%s|FreeCapacity"; public static final String PDU_INLET_XPOLE_VOLTAGE = "%s|%s|Voltage"; - + public static final String SERVER_FRONT_TEMPERATURE = "FrontTemperature"; public static final String SERVER_BACK_TEMPREATURE = "BackTemperature"; public static final String SERVER_FRONT_HUMIDITY = "FrontHumidity"; public static final String SERVER_BACK_HUMIDITY = "BackHumidity"; public static final String SERVER_TOTAL_CURRENT = "TotalCurrent"; public static final String SERVER_TOTAL_POWER = "TotalPower"; - public static final String SERVER_VOLTAGE = "Voltage"; + public static final String SERVER_VOLTAGE = "Voltage"; public static final String SERVER_CONNECTED_PDU_CURRENT = "Current"; public static final String SERVER_CONNECTED_PDU_POWER = "Power"; public static final String SERVER_CONNECTED_PDU_CURRENT_LOAD = "CurrentLoad"; diff --git a/flowgate-common/src/main/java/com/vmware/flowgate/common/model/Asset.java b/flowgate-common/src/main/java/com/vmware/flowgate/common/model/Asset.java index f9e4e3fb2..7f24768c7 100644 --- a/flowgate-common/src/main/java/com/vmware/flowgate/common/model/Asset.java +++ b/flowgate-common/src/main/java/com/vmware/flowgate/common/model/Asset.java @@ -93,7 +93,10 @@ public class Asset implements Serializable, BaseDocument { * The location city of the asset */ private String city; - + /** + * Fitting results + */ + private List fitting_results; /** * The location building of the asset */ @@ -252,6 +255,14 @@ public void setTag(String tag) { this.tag = tag; } + public List getFittingResults() { + return this.fitting_results; + } + + public void setFittingResults(List fitting_results) { + this.fitting_results = fitting_results; + } + public AssetAddress getAssetAddress() { return assetAddress; } diff --git a/flowgate-common/src/main/java/com/vmware/flowgate/common/model/MetricData.java b/flowgate-common/src/main/java/com/vmware/flowgate/common/model/MetricData.java index bfbc9a389..edb5fbfa1 100644 --- a/flowgate-common/src/main/java/com/vmware/flowgate/common/model/MetricData.java +++ b/flowgate-common/src/main/java/com/vmware/flowgate/common/model/MetricData.java @@ -8,8 +8,8 @@ public class MetricData { private String metricName; private double valueNum; private String value; - private String unit; private long timeStamp; + private String unit; public String getMetricName() { return metricName; @@ -39,16 +39,15 @@ public long getTimeStamp() { return timeStamp; } - public void setTimeStamp(long timeStamp) { - this.timeStamp = timeStamp; - } - public String getUnit() { - return unit; + return unit; } public void setUnit(String unit) { - this.unit = unit; + this.unit = unit; + } + + public void setTimeStamp(long timeStamp) { + this.timeStamp = timeStamp; } - } diff --git a/flowgate-common/src/main/java/com/vmware/flowgate/common/model/TranslateContext.java b/flowgate-common/src/main/java/com/vmware/flowgate/common/model/TranslateContext.java index b307c9122..69f8a910a 100644 --- a/flowgate-common/src/main/java/com/vmware/flowgate/common/model/TranslateContext.java +++ b/flowgate-common/src/main/java/com/vmware/flowgate/common/model/TranslateContext.java @@ -54,4 +54,4 @@ public String toString() { ", displayName='" + displayName + '\'' + '}'; } -} \ No newline at end of file +} diff --git a/flowgate-common/src/main/java/com/vmware/flowgate/common/model/ValueUnit.java b/flowgate-common/src/main/java/com/vmware/flowgate/common/model/ValueUnit.java index 78bfc74b1..76f7d5a15 100644 --- a/flowgate-common/src/main/java/com/vmware/flowgate/common/model/ValueUnit.java +++ b/flowgate-common/src/main/java/com/vmware/flowgate/common/model/ValueUnit.java @@ -62,12 +62,6 @@ public void setKey(String key) { this.key = key; } - /** - * According to the Metric Prefix in the International System of Units, - * M => 1000000; m => 0.001; k => 1000 - * Link: https://en.wikipedia.org/wiki/International_System_of_Units - * - */ public enum MetricUnit { //These units include KW,KA,KWH,KB,KBps,PERCENT will be deprecated in Flowgate-1.3 V("VOLTAGE",1), VOLTS("VOLTAGE",1), KV("VOLTAGE",1000), kV("VOLTAGE",1000), @@ -126,7 +120,7 @@ public String translateUnit(String val, MetricUnit sourceUnit, MetricUnit target } return String.valueOf(translateUnit(Double.parseDouble(val), sourceUnit, targetUnit)); } - + @Override public String toString() { return "ValueUnit{" + @@ -139,4 +133,6 @@ public String toString() { '}'; } + + } diff --git a/flowgate-common/src/main/java/com/vmware/flowgate/common/model/metadata/PredefinedSDDCJobs.java b/flowgate-common/src/main/java/com/vmware/flowgate/common/model/metadata/PredefinedSDDCJobs.java index 4b6b7fcf0..30ba695de 100644 --- a/flowgate-common/src/main/java/com/vmware/flowgate/common/model/metadata/PredefinedSDDCJobs.java +++ b/flowgate-common/src/main/java/com/vmware/flowgate/common/model/metadata/PredefinedSDDCJobs.java @@ -13,13 +13,17 @@ public class PredefinedSDDCJobs { public static final List ALLJobs = Arrays.asList( new JobConfig("AGGREGATOR-PREDEFINED-AGGREGATOR-JOB-DISPATCHER", "AggregateJobDispatcher", "AggregateJobs", - "Hourly", "AggregatorJob", "", "0 23 * * * ?", - "com.vmware.flowgate.aggregator.scheduler.job.AggregatorJobDispatcher", + "Hourly", "AggregatorJob", "", "0 23 * * * ?", + "com.vmware.flowgate.aggregator.scheduler.job.AggregatorJobDispatcher", JobType.AGGREGATOR), new JobConfig("AGGREGATOR-PREDEFINED-SYNC-VC-DATA", "SyncVCData", "AggregateJobs", "Hourly", "SyncVCAll", "", "0 0/5 * * * ? *", "com.vmware.flowgate.aggregator.scheduler.job.VCenterJobDispatcher", JobType.AGGREGATOR), + /*new JobConfig("AGGREGATOR-PREDEFINED-Fitting-VC-DATA", "FittingVCData", "AggregateJobs", + "FiveMinutes", "FittingVCAll", "", "0 0/5 * * * ? *", + "com.vmware.flowgate.aggregator.scheduler.job.AggregatorJobDispatcher", + JobType.AGGREGATOR),*/ new JobConfig("AGGREGATOR-PREDEFINED-SYNC-VRO-DATA", "SyncVROData", "AggregateJobs", "FiveMinutes", "SyncVROAll", "", "1 0/5 * * * ?", "com.vmware.flowgate.aggregator.scheduler.job.VROJobDispatcher", diff --git a/flowgate-common/src/main/java/com/vmware/flowgate/common/model/redis/message/impl/EventMessageUtil.java b/flowgate-common/src/main/java/com/vmware/flowgate/common/model/redis/message/impl/EventMessageUtil.java index 8ddd3b1ba..5ebdabd69 100644 --- a/flowgate-common/src/main/java/com/vmware/flowgate/common/model/redis/message/impl/EventMessageUtil.java +++ b/flowgate-common/src/main/java/com/vmware/flowgate/common/model/redis/message/impl/EventMessageUtil.java @@ -45,6 +45,7 @@ public class EventMessageUtil { public static final String OpenManageJobList = "openmanagejoblist"; public static final String HostNameIPMappingCommand = "hostnameipmapping"; public static final String FullMappingCommand = "fullservermapping"; + public static final String SYNC_FITTING = "syncfitting"; public static final String PDUServerMappingCommand = "pduservermapping"; public static final String SyncTemperatureAndHumiditySensors = "tempandhumiditymapping"; public static final String FullSyncTemperatureAndHumiditySensors = "fullsynctempandhumiditymapping"; @@ -58,6 +59,7 @@ public class EventMessageUtil { public static final String VCENTER_SyncCustomerAttrsData = "vcenter.synccustomerattrsdata"; public static final String VCENTER_SyncData = "vcenter.syncdata"; public static final String VCENTER_EXECOUNT = "vcenter.execount"; + public static final String VCENTER_SyncFitting = "vcenter.syncfitting"; public static final String VCENTER_QueryHostMetaData = "vcenter.queryhostmetadata"; public static final String VCENTER_QueryHostUsageData = "vcenter.queryhostusagedata";