eu.modaclouds.sla.service.rest.ModacloudsTranslator.java Source code

Java tutorial

Introduction

Here is the source code for eu.modaclouds.sla.service.rest.ModacloudsTranslator.java

Source

/**
 * Copyright 2015 Atos
 * Contact: Atos <roman.sosa@atos.net>
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */
package eu.modaclouds.sla.service.rest;

import java.io.StringReader;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.google.gson.stream.JsonReader;

import eu.atos.sla.datamodel.IAgreement;
import eu.atos.sla.datamodel.IGuaranteeTerm;
import eu.atos.sla.evaluation.constraint.IConstraintEvaluator;
import eu.atos.sla.monitoring.IMetricTranslator;
import eu.atos.sla.monitoring.IMonitoringMetric;

/**
 * Translates a serialized json of metrics (as sent by MC'Monitoring Platform) into 
 * a set of metrics suitable for sla enforcement.
 * 
 * This version is coupled to modaclouds-metrics-observer v1.0.1
 * 
 * @author rsosa
 */
public class ModacloudsTranslator implements IMetricTranslator<String> {
    private static final Logger logger = LoggerFactory.getLogger(ModacloudsTranslator.class);

    /**
     * Needed to get the guarantee term that evaluates a particular metric key.
     */
    private final IConstraintEvaluator constraintEvaluator;

    public ModacloudsTranslator(IConstraintEvaluator constraintEvaluator) {
        this.constraintEvaluator = constraintEvaluator;
    }

    @Override
    public Map<IGuaranteeTerm, List<IMonitoringMetric>> translate(IAgreement agreement, String data) {
        MultivaluedMapWrapper<IGuaranteeTerm, IMonitoringMetric> resultWrapper = new MultivaluedMapWrapper<IGuaranteeTerm, IMonitoringMetric>();

        Gson gson = new Gson();
        JsonReader reader = null;
        Type type = new TypeToken<Map<String, Map<String, List<Map<String, String>>>>>() {
        }.getType();
        reader = new JsonReader(new StringReader(data));
        final Map<String, Map<String, List<Map<String, String>>>> json = gson.fromJson(reader, type);

        final MultivaluedMapWrapper<String, IGuaranteeTerm> metric2terms = initTermsMap(agreement);

        for (Map<String, List<Map<String, String>>> item : json.values()) {
            BindingHelper var = new BindingHelper(item);
            List<IGuaranteeTerm> terms = metric2terms.get(var.key);

            if (terms == null) {
                logger.warn("List of terms handling " + var.key + " is empty");
            }

            resultWrapper.addToKeys(terms, newMetric(var));
        }
        logger.debug("Output metricsmap = " + resultWrapper.getMap());
        return resultWrapper.getMap();
    }

    private IMonitoringMetric newMetric(final BindingHelper binding) {
        return new IMonitoringMetric() {

            @Override
            public String getMetricValue() {
                return binding.value;
            }

            @Override
            public String getMetricKey() {
                return binding.key;
            }

            @Override
            public Date getDate() {
                return binding.date;
            }

            @Override
            public String toString() {
                return String.format("%s[key=%s, value=%s, date=%s]", this.getClass().getName(),
                        this.getMetricKey(), this.getMetricValue(), this.getDate().toString());
            }
        };
    }

    /**
     * Inits a MultivaluedMap with metrickey as key and the terms that evaluate the metrickey as values.
     * @param agreement
     * @return
     */
    private MultivaluedMapWrapper<String, IGuaranteeTerm> initTermsMap(IAgreement agreement) {
        MultivaluedMapWrapper<String, IGuaranteeTerm> result = new MultivaluedMapWrapper<String, IGuaranteeTerm>();

        for (IGuaranteeTerm term : agreement.getGuaranteeTerms()) {
            String variable = constraintEvaluator.getConstraintVariable(term.getServiceLevel());
            result.add(variable, term);
        }
        return result;
    }

    /**
     * Wrapper over a Map that implements a MultivaluedMap, i.e, a single key may have more than one value.
     * 
     * Internally, it is a Map<K, List<V>>. This wrapper simply facilitates the adding operations.
     * 
     * After adding all values, you can work with the result using {@link #getMap()}. Remember that 
     * any key that has no value may return <code>null</code> instead of an empty list.
     *  
     * @param <K> type of key
     * @param <V> type value
     * 
     * @author rsosa
     *
     */
    public static class MultivaluedMapWrapper<K, V> {

        private final Map<K, List<V>> map;

        public MultivaluedMapWrapper() {
            this.map = new HashMap<K, List<V>>();
        }

        public MultivaluedMapWrapper(Map<K, List<V>> map) {
            if (map == null) {
                throw new IllegalArgumentException("map cannot be null");
            }
            this.map = map;
        }

        /**
         * Return the list of values associated to a key, or an empty list. 
         */
        public List<V> get(K key) {
            List<V> list = map.get(key);

            return list == null ? Collections.<V>emptyList() : list;
        }

        /**
         * Add a value to a key
         */
        public void add(K key, V value) {

            List<V> list;
            if (map.containsKey(key)) {
                list = map.get(key);
            } else {
                list = new ArrayList<V>();
                map.put(key, list);
            }
            list.add(value);
        }

        /**
         * Add a value to the given keys
         */
        public void addToKeys(List<K> keys, V value) {

            for (K key : keys) {
                this.add(key, value);
            }
        }

        /**
         * Returns an unmodifiable Map over the internal map.
         */
        public Map<K, List<V>> getMap() {
            return Collections.unmodifiableMap(map);
        }
    }

    private static class BindingHelper {
        private final String key;
        private final String value;
        private final Date date;
        //      private final String resourceId;

        public BindingHelper(Map<String, List<Map<String, String>>> binding) {
            key = getItem(binding, "http://www.modaclouds.eu/rdfs/1.0/monitoringdata#metric");
            value = getItem(binding, "http://www.modaclouds.eu/rdfs/1.0/monitoringdata#value");
            String dateStr = getItem(binding, "http://www.modaclouds.eu/rdfs/1.0/monitoringdata#timestamp");
            date = new Date(Long.parseLong(dateStr));
            //         resourceId = getItem(binding, "http://www.modaclouds.eu/rdfs/1.0/monitoringdata#resourceId");
        }

        private String getItem(Map<String, List<Map<String, String>>> binding, String ns) {
            String item = nullable(binding.get(ns)).get(0).get("value");

            return item;
        }

        private List<Map<String, String>> nullable(List<Map<String, String>> list) {
            if (list != null)
                return list;
            else {
                List<Map<String, String>> emptyValueList = new ArrayList<Map<String, String>>();
                Map<String, String> emptyValueMap = new HashMap<String, String>();
                emptyValueMap.put("value", "");
                emptyValueList.add(emptyValueMap);
                return emptyValueList;
            }
        }

    }

    //   public static class ModaCloudsMonitoringMetric {
    //      private ModaCloudsMonitoringMetric.Head head;
    //      private ModaCloudsMonitoringMetric.Result results;
    //      
    //      public ModaCloudsMonitoringMetric.Head getHead() {
    //         return head;
    //      }
    //      public void setHead(ModaCloudsMonitoringMetric.Head head) {
    //         this.head = head;
    //      }
    //      public ModaCloudsMonitoringMetric.Result getResults() {
    //         return results;
    //      }
    //      public void setResults(ModaCloudsMonitoringMetric.Result results) {
    //         this.results = results;
    //      }
    //
    //      public static class Head {
    //         
    //         private ArrayList<String> vars;
    //
    //         public ArrayList<String> getVars() {
    //            return vars;
    //         }
    //
    //         public void setVars(ArrayList<String> vars) {
    //            this.vars = vars;
    //         }
    //      }
    //      
    //      public static class Result {
    //         
    //         private ArrayList<Map<String, ModaCloudsMonitoringMetric.Variable>> bindings;
    //
    //         public ArrayList<Map<String, ModaCloudsMonitoringMetric.Variable>> getBindings() {
    //            return bindings;
    //         }
    //
    //         public void setBindings(ArrayList<Map<String, ModaCloudsMonitoringMetric.Variable>> bindings) {
    //            this.bindings = bindings;
    //         }
    //         
    //      }
    //      
    //      public static class Variable {
    //         
    //         private String datatype;
    //         private String type;
    //         private String value;
    //         
    //         public String getDatatype() {
    //            return datatype;
    //         }
    //         public void setDatatype(String datatype) {
    //            this.datatype = datatype;
    //         }
    //         public String getType() {
    //            return type;
    //         }
    //         public void setType(String type) {
    //            this.type = type;
    //         }
    //         public String getValue() {
    //            return value;
    //         }
    //         public void setValue(String value) {
    //            this.value = value;
    //         }
    //      }
    //   }

}