/* * Copyright 2015-2016 Red Hat, Inc. and/or its affiliates * and other contributors as indicated by the @author tags. * * 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 org.hawkular.inventory.base; import static java.util.Collections.emptyList; import static org.hawkular.inventory.api.Relationships.WellKnown.contains; import static org.hawkular.inventory.api.filters.Related.by; import static org.hawkular.inventory.api.filters.With.id; import static org.hawkular.inventory.api.filters.With.type; import org.hawkular.inventory.api.EntityAlreadyExistsException; import org.hawkular.inventory.api.EntityNotFoundException; import org.hawkular.inventory.api.Environments; import org.hawkular.inventory.api.Feeds; import org.hawkular.inventory.api.MetadataPacks; import org.hawkular.inventory.api.MetricTypes; import org.hawkular.inventory.api.ResourceTypes; import org.hawkular.inventory.api.Tenants; import org.hawkular.inventory.api.filters.Filter; import org.hawkular.inventory.api.model.Environment; import org.hawkular.inventory.api.model.Feed; import org.hawkular.inventory.api.model.MetadataPack; import org.hawkular.inventory.api.model.MetricType; import org.hawkular.inventory.api.model.ResourceType; import org.hawkular.inventory.api.model.Tenant; import org.hawkular.inventory.base.spi.Discriminator; import org.hawkular.inventory.paths.CanonicalPath; import org.hawkular.inventory.paths.Path; /** * @author Lukas Krejci * @since 0.1.0 */ public final class BaseTenants { private BaseTenants() { } public static class ReadWrite<BE> extends Mutator<BE, Tenant, Tenant.Blueprint, Tenant.Update, String> implements Tenants.ReadWrite { public ReadWrite(TraversalContext<BE, Tenant> context) { super(context); } @Override protected String getProposedId(Transaction<BE> tx, Tenant.Blueprint blueprint) { return blueprint.getId(); } @Override protected EntityAndPendingNotifications<BE, Tenant> wireUpNewEntity(Discriminator discriminator, BE entity, Tenant.Blueprint blueprint, CanonicalPath parentPath, BE parent, Transaction<BE> tx) { return new EntityAndPendingNotifications<>(entity, new Tenant(blueprint.getName(), CanonicalPath.of() .tenant(tx.extractId(entity)).get(), null, blueprint.getProperties()), emptyList()); } @Override public Tenants.Multiple getAll(Filter[][] filters) { return new Multiple<>(context.proceed().whereAll(filters).get()); } @Override public Tenants.Single get(String id) throws EntityNotFoundException { return new Single<>(context.proceed().where(id(id)).get()); } @Override public Tenants.Single create(Tenant.Blueprint blueprint, boolean cache) throws EntityAlreadyExistsException { return new Single<>(context.toCreatedEntity(doCreate(blueprint), cache)); } } public static class ReadContained<BE> extends Traversal<BE, Tenant> implements Tenants.ReadContained { public ReadContained(TraversalContext<BE, Tenant> context) { super(context); } @Override public Tenants.Multiple getAll(Filter[][] filters) { return new Multiple<>(context.proceed().whereAll(filters).get()); } @Override public Tenants.Single get(String id) throws EntityNotFoundException { return new Single<>(context.proceed().where(id(id)).get()); } } public static class Read<BE> extends Traversal<BE, Tenant> implements Tenants.Read { public Read(TraversalContext<BE, Tenant> context) { super(context); } @Override public Tenants.Multiple getAll(Filter[][] filters) { return new Multiple<>(context.proceed().whereAll(filters).get()); } @Override public Tenants.Single get(Path id) throws EntityNotFoundException { return new Single<>(context.proceedTo(id)); } } public static class Multiple<BE> extends MultipleEntityFetcher<BE, Tenant, Tenant.Update> implements Tenants.Multiple { public Multiple(TraversalContext<BE, Tenant> context) { super(context); } @Override public Feeds.ReadContained feeds() { return new BaseFeeds.ReadContained<>(context.proceedTo(contains, Feed.class).get()); } @Override public ResourceTypes.ReadContained resourceTypes() { return new BaseResourceTypes.ReadContained<>(context.proceedTo(contains, ResourceType.class).get()); } @Override public MetricTypes.ReadContained metricTypes() { return new BaseMetricTypes.ReadContained<>(context.proceedTo(contains, MetricType.class).get()); } @Override public Environments.ReadContained environments() { return new BaseEnvironments.ReadContained<>(context.proceedTo(contains, Environment.class).get()); } @Override public MetricTypes.Read metricTypesUnder(Tenants.MetricTypeParents... parents) { return proceedToMetricTypes(context, parents); } @Override public ResourceTypes.Read resourceTypesUnder(Tenants.ResourceTypeParents... parents) { return proceedToResourceTypes(context, parents); } @Override public MetadataPacks.ReadContained metadataPacks() { return new BaseMetadataPacks.ReadContained<>(context.proceedTo(contains, MetadataPack.class).get()); } } public static class Single<BE> extends SingleEntityFetcher<BE, Tenant, Tenant.Update> implements Tenants.Single { public Single(TraversalContext<BE, Tenant> context) { super(context); } @Override public Feeds.ReadWrite feeds() { return new BaseFeeds.ReadWrite<>(context.proceedTo(contains, Feed.class).get()); } @Override public ResourceTypes.ReadWrite resourceTypes() { return new BaseResourceTypes.ReadWrite<>(context.proceedTo(contains, ResourceType.class).get()); } @Override public MetricTypes.ReadWrite metricTypes() { return new BaseMetricTypes.ReadWrite<>(context.proceedTo(contains, MetricType.class).get()); } @Override public Environments.ReadWrite environments() { return new BaseEnvironments.ReadWrite<>(context.proceedTo(contains, Environment.class).get()); } @Override public ResourceTypes.Read resourceTypesUnder(Tenants.ResourceTypeParents... parents) { return proceedToResourceTypes(context, parents); } @Override public MetricTypes.Read metricTypesUnder(Tenants.MetricTypeParents... parents) { return proceedToMetricTypes(context, parents); } @Override public MetadataPacks.ReadWrite metadataPacks() { return new BaseMetadataPacks.ReadWrite<>(context.proceedTo(contains, MetadataPack.class).get()); } } private static <BE> BaseResourceTypes.Read<BE> proceedToResourceTypes(TraversalContext<BE, Tenant> context, Tenants.ResourceTypeParents... parents) { return new BaseResourceTypes.Read<>(context.proceedWithParents(ResourceType.class, Tenants.ResourceTypeParents.class, Tenants.ResourceTypeParents.TENANT, parents, (p, extender) -> { switch (p) { case FEED: extender.path() .with(by(contains), type(Feed.class), by(contains), type(ResourceType.class)); break; case TENANT: extender.path().with(by(contains), type(ResourceType.class)); break; default: throw new AssertionError("Unhandled parent type " + p); } })); } private static <BE> BaseMetricTypes.Read<BE> proceedToMetricTypes(TraversalContext<BE, Tenant> context, Tenants.MetricTypeParents... parents) { return new BaseMetricTypes.Read<>(context.proceedWithParents(MetricType.class, Tenants.MetricTypeParents.class, Tenants.MetricTypeParents.TENANT, parents, (p, extender) -> { switch (p) { case FEED: extender.path().with(by(contains), type(Feed.class), by(contains), type(MetricType.class)); break; case TENANT: extender.path().with(by(contains), type(MetricType.class)); break; default: throw new AssertionError("Unhandled parent type " + p); } })); } }