software.amazon.awssdk.services.costexplorer.model.Expression Maven / Gradle / Ivy
Show all versions of costexplorer Show documentation
/*
* Copyright 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.io.Serializable;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import software.amazon.awssdk.annotations.Generated;
import software.amazon.awssdk.core.SdkField;
import software.amazon.awssdk.core.SdkPojo;
import software.amazon.awssdk.core.protocol.MarshallLocation;
import software.amazon.awssdk.core.protocol.MarshallingType;
import software.amazon.awssdk.core.traits.ListTrait;
import software.amazon.awssdk.core.traits.LocationTrait;
import software.amazon.awssdk.core.util.DefaultSdkAutoConstructList;
import software.amazon.awssdk.core.util.SdkAutoConstructList;
import software.amazon.awssdk.utils.ToString;
import software.amazon.awssdk.utils.builder.CopyableBuilder;
import software.amazon.awssdk.utils.builder.ToCopyableBuilder;
/**
*
* Use Expression
to filter in various Cost Explorer APIs.
*
*
* Not all Expression
types are supported in each API. Refer to the documentation for each specific API to
* see what is supported.
*
*
* There are two patterns:
*
*
* -
*
* Simple dimension values.
*
*
* -
*
* There are three types of simple dimension values: CostCategories
, Tags
, and
* Dimensions
.
*
*
* -
*
* Specify the CostCategories
field to define a filter that acts on Cost Categories.
*
*
* -
*
* Specify the Tags
field to define a filter that acts on Cost Allocation Tags.
*
*
* -
*
* Specify the Dimensions
field to define a filter that acts on the
* DimensionValues
.
*
*
*
*
* -
*
* For each filter type, you can set the dimension name and values for the filters that you plan to use.
*
*
* -
*
* For example, you can filter for REGION==us-east-1 OR REGION==us-west-1
. For
* GetRightsizingRecommendation
, the Region is a full name (for example,
* REGION==US East (N. Virginia)
.
*
*
* -
*
* The corresponding Expression
for this example is as follows:
* { "Dimensions": { "Key": "REGION", "Values": [ "us-east-1", "us-west-1" ] } }
*
*
* -
*
* As shown in the previous example, lists of dimension values are combined with OR
when applying the
* filter.
*
*
*
*
* -
*
* You can also set different match options to further control how the filter behaves. Not all APIs support match
* options. Refer to the documentation for each specific API to see what is supported.
*
*
* -
*
* For example, you can filter for linked account names that start with "a".
*
*
* -
*
* The corresponding Expression
for this example is as follows:
* { "Dimensions": { "Key": "LINKED_ACCOUNT_NAME", "MatchOptions": [ "STARTS_WITH" ], "Values": [ "a" ] } }
*
*
*
*
*
*
* -
*
* Compound Expression
types 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. By doing this, you can filter by more advanced options.
*
*
* -
*
* For example, you can filter by
* ((REGION == us-east-1 OR REGION == us-west-1) OR (TAG.Type == Type1)) AND (USAGE_TYPE != DataTransfer)
.
*
*
* -
*
* The corresponding Expression
for this example is as follows:
* { "And": [ {"Or": [ {"Dimensions": { "Key": "REGION", "Values": [ "us-east-1", "us-west-1" ] }}, {"Tags": { "Key": "TagName", "Values": ["Value1"] } } ]}, {"Not": {"Dimensions": { "Key": "USAGE_TYPE", "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 creates an error:
* { "And": [ ... ], "Dimensions": { "Key": "USAGE_TYPE", "Values": [ "DataTransfer" ] } }
*
*
* The following is an example of the corresponding error message:
* "Expression has more than one roots. Only one root operator is allowed for each expression: And, Or, Not, Dimensions, Tags, CostCategories"
*
*
*
*
*
* For the GetRightsizingRecommendation
action, a combination of OR and NOT isn't supported. OR isn't
* supported between different dimensions, or dimensions and tags. NOT operators aren't supported. Dimensions are also
* limited to LINKED_ACCOUNT
, REGION
, or RIGHTSIZING_TYPE
.
*
*
* For the GetReservationPurchaseRecommendation
action, only NOT is supported. AND and OR aren't supported.
* Dimensions are limited to LINKED_ACCOUNT
.
*
*
*/
@Generated("software.amazon.awssdk:codegen")
public final class Expression implements SdkPojo, Serializable, ToCopyableBuilder {
private static final SdkField> OR_FIELD = SdkField
.> builder(MarshallingType.LIST)
.memberName("Or")
.getter(getter(Expression::or))
.setter(setter(Builder::or))
.traits(LocationTrait.builder().location(MarshallLocation.PAYLOAD).locationName("Or").build(),
ListTrait
.builder()
.memberLocationName(null)
.memberFieldInfo(
SdkField. builder(MarshallingType.SDK_POJO)
.constructor(Expression::builder)
.traits(LocationTrait.builder().location(MarshallLocation.PAYLOAD)
.locationName("member").build()).build()).build()).build();
private static final SdkField> AND_FIELD = SdkField
.> builder(MarshallingType.LIST)
.memberName("And")
.getter(getter(Expression::and))
.setter(setter(Builder::and))
.traits(LocationTrait.builder().location(MarshallLocation.PAYLOAD).locationName("And").build(),
ListTrait
.builder()
.memberLocationName(null)
.memberFieldInfo(
SdkField. builder(MarshallingType.SDK_POJO)
.constructor(Expression::builder)
.traits(LocationTrait.builder().location(MarshallLocation.PAYLOAD)
.locationName("member").build()).build()).build()).build();
private static final SdkField NOT_FIELD = SdkField. builder(MarshallingType.SDK_POJO)
.memberName("Not").getter(getter(Expression::not)).setter(setter(Builder::not)).constructor(Expression::builder)
.traits(LocationTrait.builder().location(MarshallLocation.PAYLOAD).locationName("Not").build()).build();
private static final SdkField DIMENSIONS_FIELD = SdkField
. builder(MarshallingType.SDK_POJO).memberName("Dimensions").getter(getter(Expression::dimensions))
.setter(setter(Builder::dimensions)).constructor(DimensionValues::builder)
.traits(LocationTrait.builder().location(MarshallLocation.PAYLOAD).locationName("Dimensions").build()).build();
private static final SdkField TAGS_FIELD = SdkField. builder(MarshallingType.SDK_POJO)
.memberName("Tags").getter(getter(Expression::tags)).setter(setter(Builder::tags)).constructor(TagValues::builder)
.traits(LocationTrait.builder().location(MarshallLocation.PAYLOAD).locationName("Tags").build()).build();
private static final SdkField COST_CATEGORIES_FIELD = SdkField
. builder(MarshallingType.SDK_POJO).memberName("CostCategories")
.getter(getter(Expression::costCategories)).setter(setter(Builder::costCategories))
.constructor(CostCategoryValues::builder)
.traits(LocationTrait.builder().location(MarshallLocation.PAYLOAD).locationName("CostCategories").build()).build();
private static final List> SDK_FIELDS = Collections.unmodifiableList(Arrays.asList(OR_FIELD, AND_FIELD,
NOT_FIELD, DIMENSIONS_FIELD, TAGS_FIELD, COST_CATEGORIES_FIELD));
private static final long serialVersionUID = 1L;
private final List or;
private final List and;
private final Expression not;
private final DimensionValues dimensions;
private final TagValues tags;
private final CostCategoryValues costCategories;
private Expression(BuilderImpl builder) {
this.or = builder.or;
this.and = builder.and;
this.not = builder.not;
this.dimensions = builder.dimensions;
this.tags = builder.tags;
this.costCategories = builder.costCategories;
}
/**
* For responses, this returns true if the service returned a value for the Or property. This DOES NOT check that
* the value is non-empty (for which, you should check the {@code isEmpty()} method on the property). This is useful
* because the SDK will never return a null collection or map, but you may need to differentiate between the service
* returning nothing (or null) and the service returning an empty collection or map. For requests, this returns true
* if a value for the property was specified in the request builder, and false if a value was not specified.
*/
public final boolean hasOr() {
return or != null && !(or instanceof SdkAutoConstructList);
}
/**
*
* Return results that match either Dimension
object.
*
*
* Attempts to modify the collection returned by this method will result in an UnsupportedOperationException.
*
*
* This method will never return null. If you would like to know whether the service returned this field (so that
* you can differentiate between null and empty), you can use the {@link #hasOr} method.
*
*
* @return Return results that match either Dimension
object.
*/
public final List or() {
return or;
}
/**
* For responses, this returns true if the service returned a value for the And property. This DOES NOT check that
* the value is non-empty (for which, you should check the {@code isEmpty()} method on the property). This is useful
* because the SDK will never return a null collection or map, but you may need to differentiate between the service
* returning nothing (or null) and the service returning an empty collection or map. For requests, this returns true
* if a value for the property was specified in the request builder, and false if a value was not specified.
*/
public final boolean hasAnd() {
return and != null && !(and instanceof SdkAutoConstructList);
}
/**
*
* Return results that match both Dimension
objects.
*
*
* Attempts to modify the collection returned by this method will result in an UnsupportedOperationException.
*
*
* This method will never return null. If you would like to know whether the service returned this field (so that
* you can differentiate between null and empty), you can use the {@link #hasAnd} method.
*
*
* @return Return results that match both Dimension
objects.
*/
public final List and() {
return and;
}
/**
*
* Return results that don't match a Dimension
object.
*
*
* @return Return results that don't match a Dimension
object.
*/
public final Expression not() {
return not;
}
/**
*
* The specific Dimension
to use for Expression
.
*
*
* @return The specific Dimension
to use for Expression
.
*/
public final DimensionValues dimensions() {
return dimensions;
}
/**
*
* The specific Tag
to use for Expression
.
*
*
* @return The specific Tag
to use for Expression
.
*/
public final TagValues tags() {
return tags;
}
/**
*
* The filter that's based on CostCategory
values.
*
*
* @return The filter that's based on CostCategory
values.
*/
public final CostCategoryValues costCategories() {
return costCategories;
}
@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 final int hashCode() {
int hashCode = 1;
hashCode = 31 * hashCode + Objects.hashCode(hasOr() ? or() : null);
hashCode = 31 * hashCode + Objects.hashCode(hasAnd() ? and() : null);
hashCode = 31 * hashCode + Objects.hashCode(not());
hashCode = 31 * hashCode + Objects.hashCode(dimensions());
hashCode = 31 * hashCode + Objects.hashCode(tags());
hashCode = 31 * hashCode + Objects.hashCode(costCategories());
return hashCode;
}
@Override
public final boolean equals(Object obj) {
return equalsBySdkFields(obj);
}
@Override
public final boolean equalsBySdkFields(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (!(obj instanceof Expression)) {
return false;
}
Expression other = (Expression) obj;
return hasOr() == other.hasOr() && Objects.equals(or(), other.or()) && hasAnd() == other.hasAnd()
&& Objects.equals(and(), other.and()) && Objects.equals(not(), other.not())
&& Objects.equals(dimensions(), other.dimensions()) && Objects.equals(tags(), other.tags())
&& Objects.equals(costCategories(), other.costCategories());
}
/**
* Returns a string representation of this object. This is useful for testing and debugging. Sensitive data will be
* redacted from this string using a placeholder value.
*/
@Override
public final String toString() {
return ToString.builder("Expression").add("Or", hasOr() ? or() : null).add("And", hasAnd() ? and() : null)
.add("Not", not()).add("Dimensions", dimensions()).add("Tags", tags()).add("CostCategories", costCategories())
.build();
}
public final 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()));
case "CostCategories":
return Optional.ofNullable(clazz.cast(costCategories()));
default:
return Optional.empty();
}
}
@Override
public final List> sdkFields() {
return SDK_FIELDS;
}
private static Function