1bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon/*
2bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon * Copyright (C) 2017 The Android Open Source Project
3bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon *
4bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon * Licensed under the Apache License, Version 2.0 (the "License");
5bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon * you may not use this file except in compliance with the License.
6bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon * You may obtain a copy of the License at
7bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon *
8bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon *      http://www.apache.org/licenses/LICENSE-2.0
9bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon *
10bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon * Unless required by applicable law or agreed to in writing, software
11bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon * distributed under the License is distributed on an "AS IS" BASIS,
12bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon * See the License for the specific language governing permissions and
14bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon * limitations under the License.
15bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon */
16bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafonpackage com.android.statsd.loadtest;
17bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon
18bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafonimport android.content.Context;
19bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafonimport android.content.res.Resources;
20bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafonimport android.util.Log;
21bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon
2212d01fa7c165a1f79091d4d742a48bffd7552650Stefan Lafonimport com.android.internal.os.StatsdConfigProto.Predicate;
23bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafonimport com.android.internal.os.StatsdConfigProto.CountMetric;
24bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafonimport com.android.internal.os.StatsdConfigProto.DurationMetric;
25a5b5191351a85ea33641dc42ee4223189b3612f3Stefan Lafonimport com.android.internal.os.StatsdConfigProto.MetricConditionLink;
26bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafonimport com.android.internal.os.StatsdConfigProto.EventMetric;
27bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafonimport com.android.internal.os.StatsdConfigProto.GaugeMetric;
28bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafonimport com.android.internal.os.StatsdConfigProto.ValueMetric;
292087716f2bdca90c7c3034d556ac12911bd8018eYangster-macimport com.android.internal.os.StatsdConfigProto.FieldValueMatcher;
30b8c9aa8c9ccba4e64759c177381b742ca99a5487Stefan Lafonimport com.android.internal.os.StatsdConfigProto.AtomMatcher;
3112d01fa7c165a1f79091d4d742a48bffd7552650Stefan Lafonimport com.android.internal.os.StatsdConfigProto.SimplePredicate;
32bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafonimport com.android.internal.os.StatsdConfigProto.StatsdConfig;
33b814481ad1f8d0e429d799b1571a6272e1a7f6c5Yangster-macimport com.android.internal.os.StatsdConfigProto.TimeUnit;
34bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon
35bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafonimport java.io.InputStream;
36bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafonimport java.io.IOException;
37bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafonimport java.util.ArrayList;
38bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafonimport java.util.List;
39bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon
40bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon/**
41bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon * Creates StatsdConfig protos for loadtesting.
42bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon */
43bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafonpublic class ConfigFactory {
44c6f2fa2700c12b44ef7b28d42c513125bc9476aeStefan Lafon    public static class ConfigMetadata {
45c6f2fa2700c12b44ef7b28d42c513125bc9476aeStefan Lafon        public final byte[] bytes;
46c6f2fa2700c12b44ef7b28d42c513125bc9476aeStefan Lafon        public final int numMetrics;
47c6f2fa2700c12b44ef7b28d42c513125bc9476aeStefan Lafon
48c6f2fa2700c12b44ef7b28d42c513125bc9476aeStefan Lafon        public ConfigMetadata(byte[] bytes, int numMetrics) {
49c6f2fa2700c12b44ef7b28d42c513125bc9476aeStefan Lafon            this.bytes = bytes;
50c6f2fa2700c12b44ef7b28d42c513125bc9476aeStefan Lafon            this.numMetrics = numMetrics;
51c6f2fa2700c12b44ef7b28d42c513125bc9476aeStefan Lafon        }
52c6f2fa2700c12b44ef7b28d42c513125bc9476aeStefan Lafon    }
53c6f2fa2700c12b44ef7b28d42c513125bc9476aeStefan Lafon
5494e197cceb2ba7df13ff8de04f60bfeec64015d9Yangster-mac    public static final long CONFIG_ID = 123456789;
55bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon
569709fa26f1e3f713e0558c5cce71c28f208afbe9Stefan Lafon    private static final String TAG = "loadtest.ConfigFactory";
57bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon
58bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon    private final StatsdConfig mTemplate;
59bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon
60bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon    public ConfigFactory(Context context) {
61bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon        // Read the config template from the resoures.
62bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon        Resources res = context.getResources();
63bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon        byte[] template = null;
64bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon        StatsdConfig templateProto = null;
65bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon        try {
66bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon            InputStream inputStream = res.openRawResource(R.raw.loadtest_config);
67bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon            template = new byte[inputStream.available()];
68bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon            inputStream.read(template);
69bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon            templateProto = StatsdConfig.parseFrom(template);
70bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon        } catch (IOException e) {
71bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon            Log.e(TAG, "Unable to read or parse loadtest config template. Using an empty config.");
72bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon        }
73bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon        mTemplate = templateProto == null ? StatsdConfig.newBuilder().build() : templateProto;
74bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon
75bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon        Log.d(TAG, "Loadtest template config: " + mTemplate);
76bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon    }
77bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon
78bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon    /**
79bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon     * Generates a config.
80bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon     *
81bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon     * All configs are based on the same template.
82bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon     * That template is designed to make the most use of the set of atoms that {@code SequencePusher}
83bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon     * pushes, and to exercise as many of the metrics features as possible.
84bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon     * Furthermore, by passing a replication factor to this method, one can artificially inflate
85bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon     * the number of metrics in the config. One can also adjust the bucket size for aggregate
86bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon     * metrics.
87bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon     *
88bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon     * @param replication The number of times each metric is replicated in the config.
89bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon     *        If the config template has n metrics, the generated config will have n * replication
90bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon     *        ones
91bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon     * @param bucketMillis The bucket size, in milliseconds, for aggregate metrics
92bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon     * @param placebo If true, only return an empty config
93c6f2fa2700c12b44ef7b28d42c513125bc9476aeStefan Lafon     * @return The serialized config and the number of metrics.
94bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon     */
95c6f2fa2700c12b44ef7b28d42c513125bc9476aeStefan Lafon    public ConfigMetadata getConfig(int replication, TimeUnit bucket, boolean placebo,
96c6f2fa2700c12b44ef7b28d42c513125bc9476aeStefan Lafon            boolean includeCount, boolean includeDuration, boolean includeEvent,
97c6f2fa2700c12b44ef7b28d42c513125bc9476aeStefan Lafon            boolean includeValue, boolean includeGauge) {
98bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon        StatsdConfig.Builder config = StatsdConfig.newBuilder()
9994e197cceb2ba7df13ff8de04f60bfeec64015d9Yangster-mac            .setId(CONFIG_ID);
100bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon        if (placebo) {
101bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon          replication = 0;  // Config will be empty, aside from a name.
102bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon        }
103bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon        int numMetrics = 0;
104bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon        for (int i = 0; i < replication; i++) {
105bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon            // metrics
1060d7d4d4f306c5102c73fa5ee88069a64ecd2b70dYao Chen            if (includeEvent) {
1070d7d4d4f306c5102c73fa5ee88069a64ecd2b70dYao Chen                for (EventMetric metric : mTemplate.getEventMetricList()) {
1080d7d4d4f306c5102c73fa5ee88069a64ecd2b70dYao Chen                    addEventMetric(metric, i, config);
1090d7d4d4f306c5102c73fa5ee88069a64ecd2b70dYao Chen                    numMetrics++;
1100d7d4d4f306c5102c73fa5ee88069a64ecd2b70dYao Chen                }
111bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon            }
1120d7d4d4f306c5102c73fa5ee88069a64ecd2b70dYao Chen            if (includeCount) {
1130d7d4d4f306c5102c73fa5ee88069a64ecd2b70dYao Chen                for (CountMetric metric : mTemplate.getCountMetricList()) {
114b814481ad1f8d0e429d799b1571a6272e1a7f6c5Yangster-mac                    addCountMetric(metric, i, bucket, config);
1150d7d4d4f306c5102c73fa5ee88069a64ecd2b70dYao Chen                    numMetrics++;
1160d7d4d4f306c5102c73fa5ee88069a64ecd2b70dYao Chen                }
117bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon            }
1180d7d4d4f306c5102c73fa5ee88069a64ecd2b70dYao Chen            if (includeDuration) {
1190d7d4d4f306c5102c73fa5ee88069a64ecd2b70dYao Chen                for (DurationMetric metric : mTemplate.getDurationMetricList()) {
120b814481ad1f8d0e429d799b1571a6272e1a7f6c5Yangster-mac                    addDurationMetric(metric, i, bucket, config);
1210d7d4d4f306c5102c73fa5ee88069a64ecd2b70dYao Chen                    numMetrics++;
1220d7d4d4f306c5102c73fa5ee88069a64ecd2b70dYao Chen                }
123bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon            }
1240d7d4d4f306c5102c73fa5ee88069a64ecd2b70dYao Chen            if (includeGauge) {
1250d7d4d4f306c5102c73fa5ee88069a64ecd2b70dYao Chen                for (GaugeMetric metric : mTemplate.getGaugeMetricList()) {
126b814481ad1f8d0e429d799b1571a6272e1a7f6c5Yangster-mac                    addGaugeMetric(metric, i, bucket, config);
1270d7d4d4f306c5102c73fa5ee88069a64ecd2b70dYao Chen                    numMetrics++;
1280d7d4d4f306c5102c73fa5ee88069a64ecd2b70dYao Chen                }
129bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon            }
1300d7d4d4f306c5102c73fa5ee88069a64ecd2b70dYao Chen            if (includeValue) {
1310d7d4d4f306c5102c73fa5ee88069a64ecd2b70dYao Chen                for (ValueMetric metric : mTemplate.getValueMetricList()) {
132b814481ad1f8d0e429d799b1571a6272e1a7f6c5Yangster-mac                    addValueMetric(metric, i, bucket, config);
1330d7d4d4f306c5102c73fa5ee88069a64ecd2b70dYao Chen                    numMetrics++;
1340d7d4d4f306c5102c73fa5ee88069a64ecd2b70dYao Chen                }
135bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon            }
13612d01fa7c165a1f79091d4d742a48bffd7552650Stefan Lafon            // predicates
13712d01fa7c165a1f79091d4d742a48bffd7552650Stefan Lafon            for (Predicate predicate : mTemplate.getPredicateList()) {
13812d01fa7c165a1f79091d4d742a48bffd7552650Stefan Lafon              addPredicate(predicate, i, config);
139bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon            }
140bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon            // matchers
141b8c9aa8c9ccba4e64759c177381b742ca99a5487Stefan Lafon            for (AtomMatcher matcher : mTemplate.getAtomMatcherList()) {
142bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon              addMatcher(matcher, i, config);
143bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon            }
144bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon        }
145bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon
146bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon        Log.d(TAG, "Loadtest config is : " + config.build());
147bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon        Log.d(TAG, "Generated config has " + numMetrics + " metrics");
148bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon
149c6f2fa2700c12b44ef7b28d42c513125bc9476aeStefan Lafon        return new ConfigMetadata(config.build().toByteArray(), numMetrics);
150bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon    }
151bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon
152bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon    /**
153a5b5191351a85ea33641dc42ee4223189b3612f3Stefan Lafon     * Creates {@link MetricConditionLink}s that are identical to the one passed to this method,
154bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon     * except that the names are appended with the provided suffix.
155bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon     */
156a5b5191351a85ea33641dc42ee4223189b3612f3Stefan Lafon    private List<MetricConditionLink> getLinks(
157a5b5191351a85ea33641dc42ee4223189b3612f3Stefan Lafon        List<MetricConditionLink> links, int suffix) {
158a5b5191351a85ea33641dc42ee4223189b3612f3Stefan Lafon        List<MetricConditionLink> newLinks = new ArrayList();
159a5b5191351a85ea33641dc42ee4223189b3612f3Stefan Lafon        for (MetricConditionLink link : links) {
160bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon            newLinks.add(link.toBuilder()
161bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon                .setCondition(link.getCondition() + suffix)
162bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon                .build());
163bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon        }
164bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon        return newLinks;
165bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon    }
166bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon
167bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon    /**
168bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon     * Creates an {@link EventMetric} based on the template. Makes sure that all names are appended
169bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon     * with the provided suffix. Then adds that metric to the config.
170bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon     */
171bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon    private void addEventMetric(EventMetric template, int suffix, StatsdConfig.Builder config) {
172bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon        EventMetric.Builder metric = template.toBuilder()
17394e197cceb2ba7df13ff8de04f60bfeec64015d9Yangster-mac            .setId(template.getId() + suffix)
174bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon            .setWhat(template.getWhat() + suffix);
175bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon        if (template.hasCondition()) {
176bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon            metric.setCondition(template.getCondition() + suffix);
177bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon        }
178bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon        if (template.getLinksCount() > 0) {
179a5b5191351a85ea33641dc42ee4223189b3612f3Stefan Lafon            List<MetricConditionLink> links = getLinks(template.getLinksList(), suffix);
180bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon            metric.clearLinks();
181bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon            metric.addAllLinks(links);
182bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon        }
183bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon        config.addEventMetric(metric);
184bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon    }
185bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon
186bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon    /**
187bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon     * Creates a {@link CountMetric} based on the template. Makes sure that all names are appended
188bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon     * with the provided suffix, and overrides the bucket size. Then adds that metric to the config.
189bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon     */
190b814481ad1f8d0e429d799b1571a6272e1a7f6c5Yangster-mac    private void addCountMetric(CountMetric template, int suffix, TimeUnit bucket,
191bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon        StatsdConfig.Builder config) {
192bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon        CountMetric.Builder metric = template.toBuilder()
19394e197cceb2ba7df13ff8de04f60bfeec64015d9Yangster-mac            .setId(template.getId() + suffix)
194bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon            .setWhat(template.getWhat() + suffix);
195bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon        if (template.hasCondition()) {
196bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon            metric.setCondition(template.getCondition() + suffix);
197bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon        }
198bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon        if (template.getLinksCount() > 0) {
199a5b5191351a85ea33641dc42ee4223189b3612f3Stefan Lafon            List<MetricConditionLink> links = getLinks(template.getLinksList(), suffix);
200bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon            metric.clearLinks();
201bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon            metric.addAllLinks(links);
202bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon        }
203b814481ad1f8d0e429d799b1571a6272e1a7f6c5Yangster-mac        metric.setBucket(bucket);
204bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon        config.addCountMetric(metric);
205bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon    }
206bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon
207bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon    /**
208bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon     * Creates a {@link DurationMetric} based on the template. Makes sure that all names are appended
209bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon     * with the provided suffix, and overrides the bucket size. Then adds that metric to the config.
210bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon     */
211b814481ad1f8d0e429d799b1571a6272e1a7f6c5Yangster-mac    private void addDurationMetric(DurationMetric template, int suffix, TimeUnit bucket,
212bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon        StatsdConfig.Builder config) {
213bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon        DurationMetric.Builder metric = template.toBuilder()
21494e197cceb2ba7df13ff8de04f60bfeec64015d9Yangster-mac            .setId(template.getId() + suffix)
215bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon            .setWhat(template.getWhat() + suffix);
216bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon        if (template.hasCondition()) {
217bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon            metric.setCondition(template.getCondition() + suffix);
218bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon        }
219bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon        if (template.getLinksCount() > 0) {
220a5b5191351a85ea33641dc42ee4223189b3612f3Stefan Lafon            List<MetricConditionLink> links = getLinks(template.getLinksList(), suffix);
221bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon            metric.clearLinks();
222bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon            metric.addAllLinks(links);
223bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon        }
224b814481ad1f8d0e429d799b1571a6272e1a7f6c5Yangster-mac        metric.setBucket(bucket);
225bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon        config.addDurationMetric(metric);
226bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon    }
227bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon
228bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon    /**
229bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon     * Creates a {@link GaugeMetric} based on the template. Makes sure that all names are appended
230bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon     * with the provided suffix, and overrides the bucket size. Then adds that metric to the config.
231bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon     */
232b814481ad1f8d0e429d799b1571a6272e1a7f6c5Yangster-mac    private void addGaugeMetric(GaugeMetric template, int suffix, TimeUnit bucket,
233bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon        StatsdConfig.Builder config) {
234bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon        GaugeMetric.Builder metric = template.toBuilder()
23594e197cceb2ba7df13ff8de04f60bfeec64015d9Yangster-mac            .setId(template.getId() + suffix)
236bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon            .setWhat(template.getWhat() + suffix);
237bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon        if (template.hasCondition()) {
238bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon            metric.setCondition(template.getCondition() + suffix);
239bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon        }
240bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon        if (template.getLinksCount() > 0) {
241a5b5191351a85ea33641dc42ee4223189b3612f3Stefan Lafon            List<MetricConditionLink> links = getLinks(template.getLinksList(), suffix);
242bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon            metric.clearLinks();
243bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon            metric.addAllLinks(links);
244bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon        }
245b814481ad1f8d0e429d799b1571a6272e1a7f6c5Yangster-mac        metric.setBucket(bucket);
246bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon        config.addGaugeMetric(metric);
247bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon    }
248bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon
249bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon    /**
250bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon     * Creates a {@link ValueMetric} based on the template. Makes sure that all names are appended
251bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon     * with the provided suffix, and overrides the bucket size. Then adds that metric to the config.
252bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon     */
253b814481ad1f8d0e429d799b1571a6272e1a7f6c5Yangster-mac    private void addValueMetric(ValueMetric template, int suffix, TimeUnit bucket,
254bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon        StatsdConfig.Builder config) {
255bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon        ValueMetric.Builder metric = template.toBuilder()
25694e197cceb2ba7df13ff8de04f60bfeec64015d9Yangster-mac            .setId(template.getId() + suffix)
257bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon            .setWhat(template.getWhat() + suffix);
258bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon        if (template.hasCondition()) {
259bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon            metric.setCondition(template.getCondition() + suffix);
260bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon        }
261bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon        if (template.getLinksCount() > 0) {
262a5b5191351a85ea33641dc42ee4223189b3612f3Stefan Lafon            List<MetricConditionLink> links = getLinks(template.getLinksList(), suffix);
263bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon            metric.clearLinks();
264bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon            metric.addAllLinks(links);
265bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon        }
266b814481ad1f8d0e429d799b1571a6272e1a7f6c5Yangster-mac        metric.setBucket(bucket);
267bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon        config.addValueMetric(metric);
268bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon    }
269bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon
270bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon    /**
27112d01fa7c165a1f79091d4d742a48bffd7552650Stefan Lafon     * Creates a {@link Predicate} based on the template. Makes sure that all names
27212d01fa7c165a1f79091d4d742a48bffd7552650Stefan Lafon     * are appended with the provided suffix. Then adds that predicate to the config.
273bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon     */
27412d01fa7c165a1f79091d4d742a48bffd7552650Stefan Lafon    private void addPredicate(Predicate template, int suffix, StatsdConfig.Builder config) {
27512d01fa7c165a1f79091d4d742a48bffd7552650Stefan Lafon        Predicate.Builder predicate = template.toBuilder()
27694e197cceb2ba7df13ff8de04f60bfeec64015d9Yangster-mac            .setId(template.getId() + suffix);
277bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon        if (template.hasCombination()) {
27812d01fa7c165a1f79091d4d742a48bffd7552650Stefan Lafon            Predicate.Combination.Builder cb = template.getCombination().toBuilder()
27912d01fa7c165a1f79091d4d742a48bffd7552650Stefan Lafon                .clearPredicate();
28094e197cceb2ba7df13ff8de04f60bfeec64015d9Yangster-mac            for (long child : template.getCombination().getPredicateList()) {
28112d01fa7c165a1f79091d4d742a48bffd7552650Stefan Lafon                cb.addPredicate(child + suffix);
282bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon            }
28312d01fa7c165a1f79091d4d742a48bffd7552650Stefan Lafon            predicate.setCombination(cb.build());
284bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon        }
28512d01fa7c165a1f79091d4d742a48bffd7552650Stefan Lafon        if (template.hasSimplePredicate()) {
28612d01fa7c165a1f79091d4d742a48bffd7552650Stefan Lafon            SimplePredicate.Builder sc = template.getSimplePredicate().toBuilder()
28712d01fa7c165a1f79091d4d742a48bffd7552650Stefan Lafon                .setStart(template.getSimplePredicate().getStart() + suffix)
28812d01fa7c165a1f79091d4d742a48bffd7552650Stefan Lafon                .setStop(template.getSimplePredicate().getStop() + suffix);
28912d01fa7c165a1f79091d4d742a48bffd7552650Stefan Lafon            if (template.getSimplePredicate().hasStopAll()) {
29012d01fa7c165a1f79091d4d742a48bffd7552650Stefan Lafon                sc.setStopAll(template.getSimplePredicate().getStopAll() + suffix);
291bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon            }
29212d01fa7c165a1f79091d4d742a48bffd7552650Stefan Lafon            predicate.setSimplePredicate(sc.build());
293bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon        }
29412d01fa7c165a1f79091d4d742a48bffd7552650Stefan Lafon        config.addPredicate(predicate);
295bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon    }
296bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon
297bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon    /**
298b8c9aa8c9ccba4e64759c177381b742ca99a5487Stefan Lafon     * Creates a {@link AtomMatcher} based on the template. Makes sure that all names
299bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon     * are appended with the provided suffix. Then adds that matcher to the config.
300bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon     */
301b8c9aa8c9ccba4e64759c177381b742ca99a5487Stefan Lafon    private void addMatcher(AtomMatcher template, int suffix, StatsdConfig.Builder config) {
302b8c9aa8c9ccba4e64759c177381b742ca99a5487Stefan Lafon        AtomMatcher.Builder matcher = template.toBuilder()
30394e197cceb2ba7df13ff8de04f60bfeec64015d9Yangster-mac            .setId(template.getId() + suffix);
304bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon        if (template.hasCombination()) {
305b8c9aa8c9ccba4e64759c177381b742ca99a5487Stefan Lafon            AtomMatcher.Combination.Builder cb = template.getCombination().toBuilder()
306bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon                .clearMatcher();
30794e197cceb2ba7df13ff8de04f60bfeec64015d9Yangster-mac            for (long child : template.getCombination().getMatcherList()) {
308bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon                cb.addMatcher(child + suffix);
309bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon            }
310bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon            matcher.setCombination(cb);
311bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon        }
312b8c9aa8c9ccba4e64759c177381b742ca99a5487Stefan Lafon        config.addAtomMatcher(matcher);
313bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon    }
314bc7a04b88db83b6bb91c2c50a4cd8b6bafabac06Stefan Lafon}
315