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";