/* * Copyright (c) 2015 Spotify AB. * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you 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 com.spotify.heroic.metadata; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; import com.spotify.heroic.common.GroupSet; import com.spotify.heroic.common.ModuleIdBuilder; import com.spotify.heroic.dagger.PrimaryComponent; import com.spotify.heroic.lifecycle.LifeCycle; import com.spotify.heroic.metadata.MetadataModule.Exposed; import com.spotify.heroic.statistics.HeroicReporter; import com.spotify.heroic.statistics.MetadataBackendReporter; import dagger.Module; import dagger.Provides; import lombok.AccessLevel; import lombok.AllArgsConstructor; import lombok.NoArgsConstructor; import lombok.RequiredArgsConstructor; import javax.inject.Named; import java.util.ArrayList; import java.util.List; import java.util.Optional; import java.util.Set; import static com.spotify.heroic.common.Optionals.mergeOptionalList; import static java.util.Optional.empty; import static java.util.Optional.of; @RequiredArgsConstructor @Module public class MetadataManagerModule { private final List<MetadataModule> backends; private final Optional<List<String>> defaultBackends; @Provides @MetadataScope public MetadataBackendReporter localReporter(HeroicReporter reporter) { return reporter.newMetadataBackend(); } @Provides @MetadataScope public List<Exposed> components( final PrimaryComponent primary, final MetadataBackendReporter reporter ) { final List<Exposed> results = new ArrayList<>(); final ModuleIdBuilder idBuilder = new ModuleIdBuilder(); for (final MetadataModule m : backends) { final String id = idBuilder.buildId(m); final MetadataModule.Depends depends = new MetadataModule.Depends(reporter); results.add(m.module(primary, depends, id)); } return results; } @Provides @MetadataScope public Set<MetadataBackend> backends( List<Exposed> components, MetadataBackendReporter reporter ) { return ImmutableSet.copyOf( components.stream().map(Exposed::backend).map(reporter::decorate).iterator()); } @Provides @Named("groupSet") @MetadataScope public GroupSet<MetadataBackend> groupSet(Set<MetadataBackend> configured) { return GroupSet.build(configured, defaultBackends); } @Provides @Named("metadata") @MetadataScope LifeCycle metadataLife(List<Exposed> components) { return LifeCycle.combined(components.stream().map(c -> c.life())); } public static Builder builder() { return new Builder(); } @NoArgsConstructor(access = AccessLevel.PRIVATE) @AllArgsConstructor public static class Builder { private Optional<List<MetadataModule>> backends = empty(); private Optional<List<String>> defaultBackends = empty(); public Builder backends(List<MetadataModule> backends) { this.backends = of(backends); return this; } public Builder defaultBackends(List<String> defaultBackends) { this.defaultBackends = of(defaultBackends); return this; } public Builder merge(final Builder o) { // @formatter:off return new Builder( mergeOptionalList(o.backends, backends), mergeOptionalList(o.defaultBackends, defaultBackends) ); // @formatter:on } public MetadataManagerModule build() { // @formatter:off return new MetadataManagerModule( backends.orElseGet(ImmutableList::of), defaultBackends ); // @formatter:on } } }