001/******************************************************************************* 002 * Copyright (c) 2017 Red Hat Inc and others 003 * 004 * All rights reserved. This program and the accompanying materials 005 * are made available under the terms of the Eclipse Public License v1.0 006 * which accompanies this distribution, and is available at 007 * http://www.eclipse.org/legal/epl-v10.html 008 * 009 * Contributors: 010 * Red Hat Inc - initial API and implementation 011 *******************************************************************************/ 012package org.eclipse.kapua.gateway.client.kura.internal; 013 014import java.nio.ByteBuffer; 015import java.util.List; 016import java.util.Map; 017import java.util.Objects; 018import java.util.TreeMap; 019 020import org.eclipse.kapua.gateway.client.kura.payload.KuraPayloadProto.KuraPayload; 021import org.eclipse.kapua.gateway.client.kura.payload.KuraPayloadProto.KuraPayload.KuraMetric; 022import org.eclipse.kapua.gateway.client.kura.payload.KuraPayloadProto.KuraPayload.KuraMetric.ValueType; 023 024import com.google.protobuf.ByteString; 025 026public final class Metrics { 027 028 private Metrics() { 029 } 030 031 /** 032 * Convert plain key value map into a Kura metric structure <br> 033 * Only the supported Kura values types must be used (String, boolean, int, 034 * long, float, double, byte[]) 035 * 036 * @param builder 037 * the builder to append the metrics to 038 * @param metrics 039 * the metrics map 040 * @throws IllegalArgumentException 041 * in case of an unsupported value type 042 */ 043 public static void buildMetrics(final KuraPayload.Builder builder, final Map<String, ?> metrics) { 044 Objects.requireNonNull(metrics); 045 046 for (final Map.Entry<String, ?> metric : metrics.entrySet()) { 047 addMetric(builder, metric.getKey(), metric.getValue()); 048 } 049 } 050 051 public static void buildBody(final KuraPayload.Builder builder, final ByteBuffer body) { 052 if (body == null) { 053 return; 054 } 055 056 Objects.requireNonNull(builder); 057 058 builder.setBody(ByteString.copyFrom(body)); 059 } 060 061 public static void addMetric(final KuraPayload.Builder builder, final String key, final Object value) { 062 final KuraMetric.Builder b = KuraMetric.newBuilder(); 063 b.setName(key); 064 065 if (value == null) { 066 return; 067 } else if (value instanceof Boolean) { 068 b.setType(ValueType.BOOL); 069 b.setBoolValue((boolean) value); 070 } else if (value instanceof Integer) { 071 b.setType(ValueType.INT32); 072 b.setIntValue((int) value); 073 } else if (value instanceof String) { 074 b.setType(ValueType.STRING); 075 b.setStringValue((String) value); 076 } else if (value instanceof Long) { 077 b.setType(ValueType.INT64); 078 b.setLongValue((Long) value); 079 } else if (value instanceof Double) { 080 b.setType(ValueType.DOUBLE); 081 b.setDoubleValue((Double) value); 082 } else if (value instanceof Float) { 083 b.setType(ValueType.FLOAT); 084 b.setFloatValue((Float) value); 085 } else if (value instanceof byte[]) { 086 b.setType(ValueType.BYTES); 087 b.setBytesValue(ByteString.copyFrom((byte[]) value)); 088 } else { 089 throw new IllegalArgumentException(String.format("Illegal metric data type: %s", value.getClass())); 090 } 091 092 builder.addMetric(b); 093 } 094 095 public static Map<String, Object> extractMetrics(final KuraPayload payload) { 096 if (payload == null) { 097 return null; 098 } 099 return extractMetrics(payload.getMetricList()); 100 } 101 102 public static Map<String, Object> extractMetrics(final List<KuraMetric> metricList) { 103 if (metricList == null) { 104 return null; 105 } 106 107 /* 108 * We are using a TreeMap in order to have a stable order of properties 109 */ 110 final Map<String, Object> result = new TreeMap<>(); 111 112 for (final KuraMetric metric : metricList) { 113 final String name = metric.getName(); 114 switch (metric.getType()) { 115 case BOOL: 116 result.put(name, metric.getBoolValue()); 117 break; 118 case BYTES: 119 result.put(name, metric.getBytesValue().toByteArray()); 120 break; 121 case DOUBLE: 122 result.put(name, metric.getDoubleValue()); 123 break; 124 case FLOAT: 125 result.put(name, metric.getFloatValue()); 126 break; 127 case INT32: 128 result.put(name, metric.getIntValue()); 129 break; 130 case INT64: 131 result.put(name, metric.getLongValue()); 132 break; 133 case STRING: 134 result.put(name, metric.getStringValue()); 135 break; 136 } 137 } 138 139 return result; 140 } 141 142 public static String getAsString(final Map<String, Object> metrics, final String key) { 143 return getAsString(metrics, key, null); 144 } 145 146 public static String getAsString(final Map<String, Object> metrics, final String key, final String defaultValue) { 147 final Object value = metrics.get(key); 148 if (value == null) { 149 return defaultValue; 150 } 151 if (value instanceof String) { 152 return (String) value; 153 } 154 return defaultValue; 155 } 156}