All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.eclipse.ditto.connectivity.model.ImmutableAddressMetric Maven / Gradle / Ivy

There is a newer version: 3.6.2
Show newest version
/*
 * Copyright (c) 2017 Contributors to the Eclipse Foundation
 *
 * See the NOTICE file(s) distributed with this work for additional
 * information regarding copyright ownership.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0
 *
 * SPDX-License-Identifier: EPL-2.0
 */
package org.eclipse.ditto.connectivity.model;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.function.Predicate;
import java.util.stream.Stream;

import javax.annotation.concurrent.Immutable;

import org.eclipse.ditto.base.model.common.ConditionChecker;
import org.eclipse.ditto.base.model.json.JsonSchemaVersion;
import org.eclipse.ditto.json.JsonFactory;
import org.eclipse.ditto.json.JsonField;
import org.eclipse.ditto.json.JsonKey;
import org.eclipse.ditto.json.JsonObject;
import org.eclipse.ditto.json.JsonObjectBuilder;
import org.eclipse.ditto.json.JsonPointer;
import org.eclipse.ditto.json.JsonValue;

/**
 * Immutable implementation of {@link AddressMetric}.
 */
@Immutable
final class ImmutableAddressMetric implements AddressMetric {

    private static final JsonKey SUCCESS_KEY = JsonFactory.newKey("success");
    private static final JsonKey FAILURE_KEY = JsonFactory.newKey("failure");

    private final Set measurements;

    private ImmutableAddressMetric(final Set measurements) {
        this.measurements = Collections.unmodifiableSet(new LinkedHashSet<>(measurements));
    }

    /**
     * Creates a new {@code ImmutableAddressMetric} instance.
     *
     * @param measurements set of measurements for this address
     * @return a new instance of ImmutableAddressMetric
     */
    public static ImmutableAddressMetric of(final Set measurements) {
        return new ImmutableAddressMetric(ConditionChecker.checkNotNull(measurements, "measurements"));
    }

    @Override
    public Set getMeasurements() {
        return measurements;
    }

    @Override
    public JsonObject toJson(final JsonSchemaVersion schemaVersion, final Predicate thePredicate) {
        if (measurements.isEmpty()) {
            return JsonFactory.nullObject();
        } else {
            final Predicate predicate = schemaVersion.and(thePredicate);
            final JsonObjectBuilder jsonObjectBuilder = JsonFactory.newObjectBuilder();
            final List sortedMeasurements = new ArrayList<>(measurements);
            sortedMeasurements.sort(getMeasurementComparator());
            for (final Measurement measurement : sortedMeasurements) {
                final JsonPointer pointer = JsonFactory.newPointer(
                        JsonFactory.newKey(measurement.getMetricType().getName()),
                        measurement.isSuccess() ? SUCCESS_KEY : FAILURE_KEY);
                jsonObjectBuilder.set(pointer,
                        measurement.toJson(predicate).getValue(pointer).orElse(JsonFactory.newObject()));
            }
            return jsonObjectBuilder.build();
        }
    }

    private static Comparator getMeasurementComparator() {
        final List sortedTypes = Arrays.asList(MetricType.values());
        Collections.sort(sortedTypes);

        return (m1, m2) -> {
            if (m1.equals(m2)) {
                return 0;
            } else {
                return calculateComparatorScore(sortedTypes, m1, m2);
            }
        };
    }

    private static int calculateComparatorScore(final List sortedTypes, final Measurement m1,
            final Measurement m2) {
        final int idx1 = sortedTypes.indexOf(m1.getMetricType());
        final int idx2 = sortedTypes.indexOf(m2.getMetricType());

        final int score;
        if (m1.isSuccess() && m2.isSuccess()) {
            score = 1;
        } else if (m1.isSuccess()) {
            score = 2;
        } else {
            score = 3;
        }

        if (idx1 < idx2) {
            return -score;
        } else if (idx1 == idx2) {
            return m1.isSuccess() ? -1 : 1;
        } else {
            return score;
        }
    }

    /**
     * Creates a new {@code AddressMetric} object from the specified JSON object.
     *
     * @param jsonObject a JSON object which provides the data for the AddressMetric to be created.
     * @return a new AddressMetric which is initialised with the extracted data from {@code jsonObject}.
     * @throws NullPointerException if {@code jsonObject} is {@code null}.
     * @throws org.eclipse.ditto.json.JsonParseException if {@code jsonObject} is not an appropriate JSON object.
     */
    public static AddressMetric fromJson(final JsonObject jsonObject) {
        final Set readMeasurements = new LinkedHashSet<>();
        jsonObject.stream()
                .filter(field -> field.getValue().isObject())
                .forEach(f -> Stream.of(SUCCESS_KEY, FAILURE_KEY)
                        .map(key -> JsonFactory.newPointer(JsonFactory.newKey(f.getKeyName()), key))
                        .map(jsonObject::get)
                        .filter(JsonValue::isObject)
                        .filter(o -> !o.isEmpty())
                        .map(JsonValue::asObject)
                        .map(ImmutableMeasurement::fromJson)
                        .forEach(readMeasurements::add));
        return ImmutableAddressMetric.of(readMeasurements);
    }


    @Override
    public boolean equals(final Object o) {
        if (this == o) {
            return true;
        }
        if (!(o instanceof ImmutableAddressMetric)) {
            return false;
        }
        final ImmutableAddressMetric that = (ImmutableAddressMetric) o;
        return Objects.equals(measurements, that.measurements);
    }

    @Override
    public int hashCode() {
        return Objects.hash(measurements);
    }

    @Override
    public String toString() {
        return getClass().getSimpleName() + " [" +
                "measurements=" + measurements +
                "]";
    }

    /**
     * Convert an indexed address metric into a JSON field.
     *
     * @param key Key of the address metric; may be empty.
     * @param metric the address metric to convert.
     * @return a valid JSON field for the address metric.
     */
    static JsonField toJsonField(final String key, final AddressMetric metric) {
        final String nonemptyKey = key.isEmpty() ? "" : key;
        return JsonFactory.newField(JsonKey.of(nonemptyKey), metric.toJson());
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy