software.amazon.awssdk.services.costexplorer.model.Expression Maven / Gradle / Ivy
/*
* Copyright 2013-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with
* the License. A copy of the License is located at
*
* http://aws.amazon.com/apache2.0
*
* or in the "license" file accompanying this file. This file 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 software.amazon.awssdk.services.costexplorer.model;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Consumer;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import software.amazon.awssdk.annotations.Generated;
import software.amazon.awssdk.annotations.SdkInternalApi;
import software.amazon.awssdk.core.protocol.ProtocolMarshaller;
import software.amazon.awssdk.core.protocol.StructuredPojo;
import software.amazon.awssdk.core.util.DefaultSdkAutoConstructList;
import software.amazon.awssdk.services.costexplorer.transform.ExpressionMarshaller;
import software.amazon.awssdk.utils.ToString;
import software.amazon.awssdk.utils.builder.CopyableBuilder;
import software.amazon.awssdk.utils.builder.ToCopyableBuilder;
/**
*
* Use Expression
to filter by cost or by usage. There are two patterns:
*
*
* -
*
* Simple dimension values - You can set the dimension name and values for the filters that you plan to use. For
* example, you can filter for InstanceType==m4.xlarge OR InstanceType==c4.large
. The
* Expression
for that looks like this.
*
*
* { "Dimensions": { "Key": "InstanceType", "Values": [ "m4.xlarge", “c4.large” ] } }
*
*
* The list of dimension values are OR'd together to retrieve cost or usage data. You can create Expression
* and DimensionValues
objects using either with*
methods or set*
methods in
* multiple lines.
*
*
* -
*
* Compound dimension values with logical operations - You can use multiple Expression
types and the
* logical operators AND/OR/NOT
to create a list of one or more Expression
objects. This
* allows you to filter on more advanced options. For example, you can filter on
* ((InstanceType == m4.large OR InstanceType == m3.large) OR (Tag.Type == Type1)) AND (UsageType != DataTransfer)
* . The Expression
for that looks like this.
*
*
* { "And": [ {"Or": [ {"Dimensions": { "Key": "InstanceType", "Values": [ "m4.x.large", "c4.large" ] }}, {"Tag": { "Key": "TagName", "Values": ["Value1"] } } ]}, {"Not": {"dimensions": { "Key": "UsageType", "Values": ["DataTransfer"] }}} ] }
*
*
*
* Because each Expression
can have only one operator, the service returns an error if more than one is
* specified. The following example shows an Expression object that will create an error.
*
*
*
* { "And": [ ... ], "DimensionValues": { "Dimension": "UsageType", "Values": [ "DataTransfer" ] } }
*
*
*
*/
@Generated("software.amazon.awssdk:codegen")
public final class Expression implements StructuredPojo, ToCopyableBuilder {
private final List or;
private final List and;
private final Expression not;
private final DimensionValues dimensions;
private final TagValues tags;
private Expression(BuilderImpl builder) {
this.or = builder.or;
this.and = builder.and;
this.not = builder.not;
this.dimensions = builder.dimensions;
this.tags = builder.tags;
}
/**
*
* Return results that match either Dimension
.
*
*
* Attempts to modify the collection returned by this method will result in an UnsupportedOperationException.
*
*
* @return Return results that match either Dimension
.
*/
public List or() {
return or;
}
/**
*
* Return results that match both Dimension
objects.
*
*
* Attempts to modify the collection returned by this method will result in an UnsupportedOperationException.
*
*
* @return Return results that match both Dimension
objects.
*/
public List and() {
return and;
}
/**
*
* Return results that don't match Dimension
.
*
*
* @return Return results that don't match Dimension
.
*/
public Expression not() {
return not;
}
/**
*
* The specific Dimension
to use for Expression
.
*
*
* @return The specific Dimension
to use for Expression
.
*/
public DimensionValues dimensions() {
return dimensions;
}
/**
*
* The specific Tag
to use for Expression
.
*
*
* @return The specific Tag
to use for Expression
.
*/
public TagValues tags() {
return tags;
}
@Override
public Builder toBuilder() {
return new BuilderImpl(this);
}
public static Builder builder() {
return new BuilderImpl();
}
public static Class extends Builder> serializableBuilderClass() {
return BuilderImpl.class;
}
@Override
public int hashCode() {
int hashCode = 1;
hashCode = 31 * hashCode + Objects.hashCode(or());
hashCode = 31 * hashCode + Objects.hashCode(and());
hashCode = 31 * hashCode + Objects.hashCode(not());
hashCode = 31 * hashCode + Objects.hashCode(dimensions());
hashCode = 31 * hashCode + Objects.hashCode(tags());
return hashCode;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (!(obj instanceof Expression)) {
return false;
}
Expression other = (Expression) obj;
return Objects.equals(or(), other.or()) && Objects.equals(and(), other.and()) && Objects.equals(not(), other.not())
&& Objects.equals(dimensions(), other.dimensions()) && Objects.equals(tags(), other.tags());
}
@Override
public String toString() {
return ToString.builder("Expression").add("Or", or()).add("And", and()).add("Not", not()).add("Dimensions", dimensions())
.add("Tags", tags()).build();
}
public Optional getValueForField(String fieldName, Class clazz) {
switch (fieldName) {
case "Or":
return Optional.ofNullable(clazz.cast(or()));
case "And":
return Optional.ofNullable(clazz.cast(and()));
case "Not":
return Optional.ofNullable(clazz.cast(not()));
case "Dimensions":
return Optional.ofNullable(clazz.cast(dimensions()));
case "Tags":
return Optional.ofNullable(clazz.cast(tags()));
default:
return Optional.empty();
}
}
@SdkInternalApi
@Override
public void marshall(ProtocolMarshaller protocolMarshaller) {
ExpressionMarshaller.getInstance().marshall(this, protocolMarshaller);
}
public interface Builder extends CopyableBuilder {
/**
*
* Return results that match either Dimension
.
*
*
* @param or
* Return results that match either Dimension
.
* @return Returns a reference to this object so that method calls can be chained together.
*/
Builder or(Collection or);
/**
*
* Return results that match either Dimension
.
*
*
* @param or
* Return results that match either Dimension
.
* @return Returns a reference to this object so that method calls can be chained together.
*/
Builder or(Expression... or);
/**
*
* Return results that match either Dimension
.
*
* This is a convenience that creates an instance of the {@link List.Builder} avoiding the need to
* create one manually via {@link List#builder()}.
*
* When the {@link Consumer} completes, {@link List.Builder#build()} is called immediately and its
* result is passed to {@link #or(List)}.
*
* @param or
* a consumer that will call methods on {@link List.Builder}
* @return Returns a reference to this object so that method calls can be chained together.
* @see #or(List)
*/
Builder or(Consumer... or);
/**
*
* Return results that match both Dimension
objects.
*
*
* @param and
* Return results that match both Dimension
objects.
* @return Returns a reference to this object so that method calls can be chained together.
*/
Builder and(Collection and);
/**
*
* Return results that match both Dimension
objects.
*
*
* @param and
* Return results that match both Dimension
objects.
* @return Returns a reference to this object so that method calls can be chained together.
*/
Builder and(Expression... and);
/**
*
* Return results that match both Dimension
objects.
*
* This is a convenience that creates an instance of the {@link List.Builder} avoiding the need to
* create one manually via {@link List#builder()}.
*
* When the {@link Consumer} completes, {@link List.Builder#build()} is called immediately and its
* result is passed to {@link #and(List)}.
*
* @param and
* a consumer that will call methods on {@link List.Builder}
* @return Returns a reference to this object so that method calls can be chained together.
* @see #and(List)
*/
Builder and(Consumer... and);
/**
*
* Return results that don't match Dimension
.
*
*
* @param not
* Return results that don't match Dimension
.
* @return Returns a reference to this object so that method calls can be chained together.
*/
Builder not(Expression not);
/**
*
* Return results that don't match Dimension
.
*
* This is a convenience that creates an instance of the {@link Expression.Builder} avoiding the need to create
* one manually via {@link Expression#builder()}.
*
* When the {@link Consumer} completes, {@link Expression.Builder#build()} is called immediately and its result
* is passed to {@link #not(Expression)}.
*
* @param not
* a consumer that will call methods on {@link Expression.Builder}
* @return Returns a reference to this object so that method calls can be chained together.
* @see #not(Expression)
*/
default Builder not(Consumer not) {
return not(Expression.builder().applyMutation(not).build());
}
/**
*
* The specific Dimension
to use for Expression
.
*
*
* @param dimensions
* The specific Dimension
to use for Expression
.
* @return Returns a reference to this object so that method calls can be chained together.
*/
Builder dimensions(DimensionValues dimensions);
/**
*
* The specific Dimension
to use for Expression
.
*
* This is a convenience that creates an instance of the {@link DimensionValues.Builder} avoiding the need to
* create one manually via {@link DimensionValues#builder()}.
*
* When the {@link Consumer} completes, {@link DimensionValues.Builder#build()} is called immediately and its
* result is passed to {@link #dimensions(DimensionValues)}.
*
* @param dimensions
* a consumer that will call methods on {@link DimensionValues.Builder}
* @return Returns a reference to this object so that method calls can be chained together.
* @see #dimensions(DimensionValues)
*/
default Builder dimensions(Consumer dimensions) {
return dimensions(DimensionValues.builder().applyMutation(dimensions).build());
}
/**
*
* The specific Tag
to use for Expression
.
*
*
* @param tags
* The specific Tag
to use for Expression
.
* @return Returns a reference to this object so that method calls can be chained together.
*/
Builder tags(TagValues tags);
/**
*
* The specific Tag
to use for Expression
.
*
* This is a convenience that creates an instance of the {@link TagValues.Builder} avoiding the need to create
* one manually via {@link TagValues#builder()}.
*
* When the {@link Consumer} completes, {@link TagValues.Builder#build()} is called immediately and its result
* is passed to {@link #tags(TagValues)}.
*
* @param tags
* a consumer that will call methods on {@link TagValues.Builder}
* @return Returns a reference to this object so that method calls can be chained together.
* @see #tags(TagValues)
*/
default Builder tags(Consumer tags) {
return tags(TagValues.builder().applyMutation(tags).build());
}
}
static final class BuilderImpl implements Builder {
private List or = DefaultSdkAutoConstructList.getInstance();
private List and = DefaultSdkAutoConstructList.getInstance();
private Expression not;
private DimensionValues dimensions;
private TagValues tags;
private BuilderImpl() {
}
private BuilderImpl(Expression model) {
or(model.or);
and(model.and);
not(model.not);
dimensions(model.dimensions);
tags(model.tags);
}
public final Collection getOr() {
return or != null ? or.stream().map(Expression::toBuilder).collect(Collectors.toList()) : null;
}
@Override
public final Builder or(Collection or) {
this.or = ExpressionsCopier.copy(or);
return this;
}
@Override
@SafeVarargs
public final Builder or(Expression... or) {
or(Arrays.asList(or));
return this;
}
@Override
@SafeVarargs
public final Builder or(Consumer... or) {
or(Stream.of(or).map(c -> Expression.builder().applyMutation(c).build()).collect(Collectors.toList()));
return this;
}
public final void setOr(Collection or) {
this.or = ExpressionsCopier.copyFromBuilder(or);
}
public final Collection getAnd() {
return and != null ? and.stream().map(Expression::toBuilder).collect(Collectors.toList()) : null;
}
@Override
public final Builder and(Collection and) {
this.and = ExpressionsCopier.copy(and);
return this;
}
@Override
@SafeVarargs
public final Builder and(Expression... and) {
and(Arrays.asList(and));
return this;
}
@Override
@SafeVarargs
public final Builder and(Consumer... and) {
and(Stream.of(and).map(c -> Expression.builder().applyMutation(c).build()).collect(Collectors.toList()));
return this;
}
public final void setAnd(Collection and) {
this.and = ExpressionsCopier.copyFromBuilder(and);
}
public final Builder getNot() {
return not != null ? not.toBuilder() : null;
}
@Override
public final Builder not(Expression not) {
this.not = not;
return this;
}
public final void setNot(BuilderImpl not) {
this.not = not != null ? not.build() : null;
}
public final DimensionValues.Builder getDimensions() {
return dimensions != null ? dimensions.toBuilder() : null;
}
@Override
public final Builder dimensions(DimensionValues dimensions) {
this.dimensions = dimensions;
return this;
}
public final void setDimensions(DimensionValues.BuilderImpl dimensions) {
this.dimensions = dimensions != null ? dimensions.build() : null;
}
public final TagValues.Builder getTags() {
return tags != null ? tags.toBuilder() : null;
}
@Override
public final Builder tags(TagValues tags) {
this.tags = tags;
return this;
}
public final void setTags(TagValues.BuilderImpl tags) {
this.tags = tags != null ? tags.build() : null;
}
@Override
public Expression build() {
return new Expression(this);
}
}
}