Java tutorial
/************************************************************************* * Copyright 2009-2015 Eucalyptus Systems, Inc. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; version 3 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see http://www.gnu.org/licenses/. * * Please contact Eucalyptus Systems, Inc., 6755 Hollister Ave., Goleta * CA 93117, USA or visit http://www.eucalyptus.com/licenses/ if you need * additional information or have any questions. ************************************************************************/ package com.eucalyptus.autoscaling.service; import com.eucalyptus.auth.AuthContextSupplier; import static com.eucalyptus.util.RestrictedTypes.getIamActionByMessageType; import java.util.Collection; import java.util.Collections; import java.util.EnumSet; import java.util.List; import java.util.Map; import java.util.NoSuchElementException; import javax.inject.Inject; import org.apache.log4j.Logger; import org.hibernate.criterion.Restrictions; import com.eucalyptus.auth.Permissions; import com.eucalyptus.auth.policy.PolicySpec; import com.eucalyptus.auth.principal.OwnerFullName; import com.eucalyptus.autoscaling.common.AutoScalingBackend; import com.eucalyptus.autoscaling.common.AutoScalingMetadata; import com.eucalyptus.autoscaling.common.AutoScalingMetadatas; import com.eucalyptus.autoscaling.common.AutoScalingResourceName; import com.eucalyptus.autoscaling.common.internal.activities.ScalingActivities; import com.eucalyptus.autoscaling.common.internal.activities.ScalingActivity; import com.eucalyptus.autoscaling.common.internal.configurations.LaunchConfiguration; import com.eucalyptus.autoscaling.common.internal.configurations.LaunchConfigurations; import com.eucalyptus.autoscaling.common.internal.groups.AutoScalingGroup; import com.eucalyptus.autoscaling.common.internal.groups.AutoScalingGroupMinimumView; import com.eucalyptus.autoscaling.common.internal.groups.AutoScalingGroups; import com.eucalyptus.autoscaling.common.internal.groups.MetricCollectionType; import com.eucalyptus.autoscaling.common.internal.groups.ScalingProcessType; import com.eucalyptus.autoscaling.common.internal.groups.TerminationPolicyType; import com.eucalyptus.autoscaling.common.internal.instances.AutoScalingInstance; import com.eucalyptus.autoscaling.common.internal.instances.AutoScalingInstances; import com.eucalyptus.autoscaling.common.internal.metadata.AutoScalingMetadataException; import com.eucalyptus.autoscaling.common.internal.metadata.AutoScalingMetadataNotFoundException; import com.eucalyptus.autoscaling.common.internal.policies.AdjustmentType; import com.eucalyptus.autoscaling.common.internal.policies.ScalingPolicies; import com.eucalyptus.autoscaling.common.internal.tags.Tag; import com.eucalyptus.autoscaling.common.internal.tags.TagSupport; import com.eucalyptus.autoscaling.common.internal.tags.Tags; import com.eucalyptus.autoscaling.common.msgs.Activity; import com.eucalyptus.autoscaling.common.msgs.AdjustmentTypes; import com.eucalyptus.autoscaling.common.msgs.AutoScalingGroupType; import com.eucalyptus.autoscaling.common.msgs.AutoScalingInstanceDetails; import com.eucalyptus.autoscaling.common.msgs.AutoScalingMessage; import com.eucalyptus.autoscaling.common.msgs.DeleteNotificationConfigurationResponseType; import com.eucalyptus.autoscaling.common.msgs.DeleteNotificationConfigurationType; import com.eucalyptus.autoscaling.common.msgs.DeleteScheduledActionResponseType; import com.eucalyptus.autoscaling.common.msgs.DeleteScheduledActionType; import com.eucalyptus.autoscaling.common.msgs.DescribeAccountLimitsResponseType; import com.eucalyptus.autoscaling.common.msgs.DescribeAccountLimitsType; import com.eucalyptus.autoscaling.common.msgs.DescribeAdjustmentTypesResponseType; import com.eucalyptus.autoscaling.common.msgs.DescribeAdjustmentTypesType; import com.eucalyptus.autoscaling.common.msgs.DescribeAutoScalingGroupsResponseType; import com.eucalyptus.autoscaling.common.msgs.DescribeAutoScalingGroupsType; import com.eucalyptus.autoscaling.common.msgs.DescribeAutoScalingInstancesResponseType; import com.eucalyptus.autoscaling.common.msgs.DescribeAutoScalingInstancesType; import com.eucalyptus.autoscaling.common.msgs.DescribeAutoScalingNotificationTypesResponseType; import com.eucalyptus.autoscaling.common.msgs.DescribeAutoScalingNotificationTypesType; import com.eucalyptus.autoscaling.common.msgs.DescribeLaunchConfigurationsResponseType; import com.eucalyptus.autoscaling.common.msgs.DescribeLaunchConfigurationsType; import com.eucalyptus.autoscaling.common.msgs.DescribeMetricCollectionTypesResponseType; import com.eucalyptus.autoscaling.common.msgs.DescribeMetricCollectionTypesType; import com.eucalyptus.autoscaling.common.msgs.DescribeNotificationConfigurationsResponseType; import com.eucalyptus.autoscaling.common.msgs.DescribeNotificationConfigurationsType; import com.eucalyptus.autoscaling.common.msgs.DescribeScalingActivitiesResponseType; import com.eucalyptus.autoscaling.common.msgs.DescribeScalingActivitiesType; import com.eucalyptus.autoscaling.common.msgs.DescribeScalingProcessTypesResponseType; import com.eucalyptus.autoscaling.common.msgs.DescribeScalingProcessTypesType; import com.eucalyptus.autoscaling.common.msgs.DescribeScheduledActionsResponseType; import com.eucalyptus.autoscaling.common.msgs.DescribeScheduledActionsType; import com.eucalyptus.autoscaling.common.msgs.DescribeTagsResponseType; import com.eucalyptus.autoscaling.common.msgs.DescribeTagsType; import com.eucalyptus.autoscaling.common.msgs.DescribeTerminationPolicyTypesResponseType; import com.eucalyptus.autoscaling.common.msgs.DescribeTerminationPolicyTypesType; import com.eucalyptus.autoscaling.common.msgs.Filter; import com.eucalyptus.autoscaling.common.msgs.LaunchConfigurationType; import com.eucalyptus.autoscaling.common.msgs.MetricCollectionTypes; import com.eucalyptus.autoscaling.common.msgs.MetricGranularityType; import com.eucalyptus.autoscaling.common.msgs.MetricGranularityTypes; import com.eucalyptus.autoscaling.common.msgs.ProcessType; import com.eucalyptus.autoscaling.common.msgs.PutNotificationConfigurationResponseType; import com.eucalyptus.autoscaling.common.msgs.PutNotificationConfigurationType; import com.eucalyptus.autoscaling.common.msgs.PutScheduledUpdateGroupActionResponseType; import com.eucalyptus.autoscaling.common.msgs.PutScheduledUpdateGroupActionType; import com.eucalyptus.autoscaling.common.msgs.ResponseMetadata; import com.eucalyptus.autoscaling.common.msgs.TagDescription; import com.eucalyptus.autoscaling.common.msgs.TagDescriptionList; import com.eucalyptus.autoscaling.common.policy.AutoScalingPolicySpec; import com.eucalyptus.component.Topology; import com.eucalyptus.component.annotation.ComponentNamed; import com.eucalyptus.context.Context; import com.eucalyptus.context.Contexts; import com.eucalyptus.util.EucalyptusCloudException; import com.eucalyptus.util.Exceptions; import com.eucalyptus.util.RestrictedTypes; import com.eucalyptus.util.Strings; import com.eucalyptus.util.TypeMappers; import com.eucalyptus.util.async.AsyncExceptions; import com.eucalyptus.util.async.AsyncRequests; import com.eucalyptus.util.async.FailedRequestException; import com.eucalyptus.ws.EucalyptusWebServiceException; import com.eucalyptus.ws.Role; import com.google.common.base.Function; import com.google.common.base.Functions; import com.google.common.base.MoreObjects; import com.google.common.base.Optional; import com.google.common.base.Predicate; import com.google.common.base.Predicates; import com.google.common.collect.Collections2; import com.google.common.collect.ImmutableMap; import com.google.common.collect.Iterables; import com.google.common.collect.Lists; import com.google.common.collect.Ordering; import edu.ucsb.eucalyptus.msgs.BaseMessage; import edu.ucsb.eucalyptus.msgs.BaseMessages; /** * */ @ComponentNamed public class AutoScalingService { private static final Logger logger = Logger.getLogger(AutoScalingService.class); private static final Map<String, Function<Tag, String>> tagFilterExtractors = ImmutableMap .<String, Function<Tag, String>>builder().put("auto-scaling-group", Tags.resourceId()) .put("key", Tags.key()).put("value", Tags.value()).put("propagate-at-launch", Tags.propagateAtLaunch()) .build(); private static final Map<String, Function<String, String>> tagValuePreProcessors = ImmutableMap .<String, Function<String, String>>builder().put("propagate-at-launch", Strings.lower()).build(); private final LaunchConfigurations launchConfigurations; private final AutoScalingGroups autoScalingGroups; private final AutoScalingInstances autoScalingInstances; private final ScalingPolicies scalingPolicies; private final ScalingActivities scalingActivities; @Inject public AutoScalingService(final LaunchConfigurations launchConfigurations, final AutoScalingGroups autoScalingGroups, final AutoScalingInstances autoScalingInstances, final ScalingPolicies scalingPolicies, final ScalingActivities scalingActivities) { this.launchConfigurations = launchConfigurations; this.autoScalingGroups = autoScalingGroups; this.autoScalingInstances = autoScalingInstances; this.scalingPolicies = scalingPolicies; this.scalingActivities = scalingActivities; } public DeleteNotificationConfigurationResponseType deleteNotificationConfiguration( final DeleteNotificationConfigurationType request) throws EucalyptusCloudException { DeleteNotificationConfigurationResponseType reply = request.getReply(); return reply; } public DeleteScheduledActionResponseType deleteScheduledAction(final DeleteScheduledActionType request) throws EucalyptusCloudException { DeleteScheduledActionResponseType reply = request.getReply(); return reply; } public DescribeAccountLimitsResponseType describeAccountLimits(final DescribeAccountLimitsType request) throws EucalyptusCloudException { DescribeAccountLimitsResponseType reply = request.getReply(); return reply; } public DescribeAdjustmentTypesResponseType describeAdjustmentTypes(final DescribeAdjustmentTypesType request) throws EucalyptusCloudException { final DescribeAdjustmentTypesResponseType reply = request.getReply(); reply.getDescribeAdjustmentTypesResult() .setAdjustmentTypes( new AdjustmentTypes(Collections2.transform( Collections2.filter(EnumSet.allOf(AdjustmentType.class), RestrictedTypes.filterPrivilegedWithoutOwner()), Strings.toStringFunction()))); return reply; } public DescribeAutoScalingGroupsResponseType describeAutoScalingGroups( final DescribeAutoScalingGroupsType request) throws EucalyptusCloudException { final DescribeAutoScalingGroupsResponseType reply = request.getReply(); //TODO: MaxRecords / NextToken support for DescribeAutoScalingGroups final Context ctx = Contexts.lookup(); final boolean showAll = request.autoScalingGroupNames().remove("verbose") || !request.autoScalingGroupNames().isEmpty(); final OwnerFullName ownerFullName = ctx.isAdministrator() && showAll ? null : ctx.getUserFullName().asAccountFullName(); final Predicate<AutoScalingMetadata.AutoScalingGroupMetadata> requestedAndAccessible = AutoScalingMetadatas .filterPrivilegesByIdOrArn(AutoScalingMetadata.AutoScalingGroupMetadata.class, request.autoScalingGroupNames()); try { final List<AutoScalingGroupType> results = reply.getDescribeAutoScalingGroupsResult() .getAutoScalingGroups().getMember(); results.addAll(autoScalingGroups.list(ownerFullName, requestedAndAccessible, TypeMappers.lookup(AutoScalingGroup.class, AutoScalingGroupType.class))); final Map<String, List<Tag>> tagsMap = TagSupport.forResourceClass(AutoScalingGroup.class) .getResourceTagMap(ctx.getUserFullName().asAccountFullName(), Iterables.transform(results, AutoScalingGroupType.groupName()), Predicates.alwaysTrue()); for (final AutoScalingGroupType type : results) { final TagDescriptionList tags = new TagDescriptionList(); Tags.addFromTags(tags.getMember(), TagDescription.class, tagsMap.get(type.getAutoScalingGroupName())); if (!tags.getMember().isEmpty()) { type.setTags(tags); } } } catch (Exception e) { handleException(e); } return reply; } public DescribeAutoScalingInstancesResponseType describeAutoScalingInstances( final DescribeAutoScalingInstancesType request) throws EucalyptusCloudException { final DescribeAutoScalingInstancesResponseType reply = request.getReply(); //TODO: MaxRecords / NextToken support for DescribeAutoScalingInstances final Context ctx = Contexts.lookup(); final boolean showAll = request.instanceIds().remove("verbose") || !request.instanceIds().isEmpty(); final OwnerFullName ownerFullName = ctx.isAdministrator() && showAll ? null : ctx.getUserFullName().asAccountFullName(); final Predicate<? super AutoScalingInstance> requestedAndAccessible = AutoScalingMetadatas .filteringFor(AutoScalingInstance.class).byId(request.instanceIds()).byPrivileges() .buildPredicate(); try { final List<AutoScalingInstanceDetails> results = reply.getDescribeAutoScalingInstancesResult() .getAutoScalingInstances().getMember(); results.addAll(autoScalingInstances.list(ownerFullName, requestedAndAccessible, TypeMappers.lookup(AutoScalingInstance.class, AutoScalingInstanceDetails.class))); } catch (Exception e) { handleException(e); } return reply; } public DescribeAutoScalingNotificationTypesResponseType describeAutoScalingNotificationTypes( final DescribeAutoScalingNotificationTypesType request) throws EucalyptusCloudException { DescribeAutoScalingNotificationTypesResponseType reply = request.getReply(); return reply; } public DescribeLaunchConfigurationsResponseType describeLaunchConfigurations( DescribeLaunchConfigurationsType request) throws EucalyptusCloudException { final DescribeLaunchConfigurationsResponseType reply = request.getReply(); //TODO: MaxRecords / NextToken support for DescribeLaunchConfigurations final Context ctx = Contexts.lookup(); final boolean showAll = request.launchConfigurationNames().remove("verbose") || (!request.launchConfigurationNames().isEmpty() && Iterables .all(request.launchConfigurationNames(), AutoScalingResourceName.isResourceName())); final OwnerFullName ownerFullName = ctx.isAdministrator() && showAll ? null : ctx.getUserFullName().asAccountFullName(); final Predicate<AutoScalingMetadata.LaunchConfigurationMetadata> requestedAndAccessible = AutoScalingMetadatas .filterPrivilegesByIdOrArn(AutoScalingMetadata.LaunchConfigurationMetadata.class, request.launchConfigurationNames()); try { final List<LaunchConfigurationType> results = reply.getDescribeLaunchConfigurationsResult() .getLaunchConfigurations().getMember(); results.addAll(launchConfigurations.list(ownerFullName, requestedAndAccessible, TypeMappers.lookup(LaunchConfiguration.class, LaunchConfigurationType.class))); } catch (Exception e) { handleException(e); } return reply; } public DescribeMetricCollectionTypesResponseType describeMetricCollectionTypes( final DescribeMetricCollectionTypesType request) throws EucalyptusCloudException { final DescribeMetricCollectionTypesResponseType reply = request.getReply(); reply.getDescribeMetricCollectionTypesResult() .setMetrics( new MetricCollectionTypes(Collections2.transform( Collections2.filter(EnumSet.allOf(MetricCollectionType.class), RestrictedTypes.filterPrivilegedWithoutOwner()), Strings.toStringFunction()))); reply.getDescribeMetricCollectionTypesResult().setGranularities( new MetricGranularityTypes(Collections.singletonList(new MetricGranularityType("1Minute")))); return reply; } public DescribeNotificationConfigurationsResponseType describeNotificationConfigurations( final DescribeNotificationConfigurationsType request) throws EucalyptusCloudException { DescribeNotificationConfigurationsResponseType reply = request.getReply(); return reply; } public DescribeScalingActivitiesResponseType describeScalingActivities( final DescribeScalingActivitiesType request) throws EucalyptusCloudException { final DescribeScalingActivitiesResponseType reply = request.getReply(); final int maxRecords = Math.max(1, MoreObjects.firstNonNull(request.getMaxRecords(), Integer.MAX_VALUE)); final Context ctx = Contexts.lookup(); final boolean showAll = request.activityIds().remove("verbose") || AutoScalingResourceName.isResourceName().apply(request.getAutoScalingGroupName()); final OwnerFullName ownerFullName = ctx.isAdministrator() && showAll ? null : ctx.getUserFullName().asAccountFullName(); try { final AutoScalingGroupMinimumView group = com.google.common.base.Strings .isNullOrEmpty(request.getAutoScalingGroupName()) ? null : autoScalingGroups.lookup(ownerFullName, request.getAutoScalingGroupName(), TypeMappers.lookup(AutoScalingGroup.class, AutoScalingGroupMinimumView.class)); final List<Activity> scalingActivities = this.scalingActivities.list(ownerFullName, group, request.activityIds(), AutoScalingMetadatas.filteringFor(ScalingActivity.class).byPrivileges().buildPredicate(), TypeMappers.lookup(ScalingActivity.class, Activity.class)); Collections.sort(scalingActivities, Ordering.natural().reverse().onResultOf(Activity.startTime())); reply.getDescribeScalingActivitiesResult().getActivities().getMember() .addAll(scalingActivities.size() > maxRecords ? scalingActivities.subList(0, maxRecords) : scalingActivities); } catch (AutoScalingMetadataNotFoundException e) { throw new AutoScalingClientException("ValidationError", "Auto scaling group not found: " + request.getAutoScalingGroupName()); } catch (AutoScalingMetadataException e) { handleException(e); } return reply; } public DescribeScalingProcessTypesResponseType describeScalingProcessTypes( final DescribeScalingProcessTypesType request) throws EucalyptusCloudException { final DescribeScalingProcessTypesResponseType reply = request.getReply(); final List<ProcessType> policies = reply.getDescribeScalingProcessTypesResult().getProcesses().getMember(); policies.addAll(Collections2.transform( Collections2.filter(EnumSet.allOf(ScalingProcessType.class), RestrictedTypes.filterPrivilegedWithoutOwner()), TypeMappers.lookup(ScalingProcessType.class, ProcessType.class))); return reply; } public DescribeScheduledActionsResponseType describeScheduledActions(final DescribeScheduledActionsType request) throws EucalyptusCloudException { DescribeScheduledActionsResponseType reply = request.getReply(); return reply; } public DescribeTagsResponseType describeTags(final DescribeTagsType request) throws EucalyptusCloudException { final DescribeTagsResponseType reply = request.getReply(); //TODO: MaxRecords / NextToken support for DescribeTags final Collection<Predicate<Tag>> tagFilters = Lists.newArrayList(); for (final Filter filter : request.filters()) { final Function<Tag, String> extractor = tagFilterExtractors.get(filter.getName()); if (extractor == null) { throw new AutoScalingClientException("ValidationError", "Filter type " + filter.getName() + " is not correct. Allowed Filter types are: auto-scaling-group key value propagate-at-launch"); } final Function<String, String> tagValueConverter = MoreObjects .firstNonNull(tagValuePreProcessors.get(filter.getName()), Functions.identity()); tagFilters.add(Predicates .compose(Predicates.in(Collections2.transform(filter.values(), tagValueConverter)), extractor)); } final Context context = Contexts.lookup(); final Ordering<Tag> ordering = Ordering.natural().onResultOf(Tags.resourceId()) .compound(Ordering.natural().onResultOf(Tags.key())) .compound(Ordering.natural().onResultOf(Tags.value())); try { final TagDescriptionList tagDescriptions = new TagDescriptionList(); for (final Tag tag : ordering.sortedCopy(Tags.list(context.getUserFullName().asAccountFullName(), Predicates.and(tagFilters), Restrictions.conjunction(), Collections.emptyMap()))) { if (Permissions.isAuthorized(AutoScalingPolicySpec.VENDOR_AUTOSCALING, tag.getResourceType(), tag.getKey(), context.getAccount(), PolicySpec.describeAction(AutoScalingPolicySpec.VENDOR_AUTOSCALING, tag.getResourceType()), context.getAuthContext())) { tagDescriptions.getMember().add(TypeMappers.transform(tag, TagDescription.class)); } } if (!tagDescriptions.getMember().isEmpty()) { reply.getDescribeTagsResult().setTags(tagDescriptions); } } catch (AutoScalingMetadataNotFoundException e) { handleException(e); } return reply; } public DescribeTerminationPolicyTypesResponseType describeTerminationPolicyTypes( final DescribeTerminationPolicyTypesType request) throws EucalyptusCloudException { final DescribeTerminationPolicyTypesResponseType reply = request.getReply(); final List<String> policies = reply.getDescribeTerminationPolicyTypesResult().getTerminationPolicyTypes() .getMember(); policies.addAll(Collections2.transform(Collections2.filter(EnumSet.allOf(TerminationPolicyType.class), RestrictedTypes.filterPrivilegedWithoutOwner()), Strings.toStringFunction())); return reply; } public PutNotificationConfigurationResponseType putNotificationConfiguration( final PutNotificationConfigurationType request) throws EucalyptusCloudException { PutNotificationConfigurationResponseType reply = request.getReply(); return reply; } public PutScheduledUpdateGroupActionResponseType putScheduledUpdateGroupAction( final PutScheduledUpdateGroupActionType request) throws EucalyptusCloudException { PutScheduledUpdateGroupActionResponseType reply = request.getReply(); return reply; } public AutoScalingMessage dispatchAction(final AutoScalingMessage request) throws EucalyptusCloudException { final AuthContextSupplier user = Contexts.lookup().getAuthContext(); // Dispatch try { final AutoScalingMessage backendRequest = (AutoScalingMessage) BaseMessages.deepCopy(request, getBackendMessageClass(request)); final BaseMessage backendResponse = send(backendRequest); final AutoScalingMessage response = (AutoScalingMessage) BaseMessages.deepCopy(backendResponse, request.getReply().getClass()); final ResponseMetadata metadata = AutoScalingMessage.getResponseMetadata(response); if (metadata != null) { metadata.setRequestId(request.getCorrelationId()); } response.setCorrelationId(request.getCorrelationId()); return response; } catch (Exception e) { handleRemoteException(e); Exceptions.findAndRethrow(e, EucalyptusWebServiceException.class, EucalyptusCloudException.class); throw new EucalyptusCloudException(e); } } private static Class getBackendMessageClass(final BaseMessage request) throws ClassNotFoundException { return Class.forName(request.getClass().getName().replace(".common.msgs.", ".common.backend.msgs.")); } private static BaseMessage send(final BaseMessage request) throws Exception { try { return AsyncRequests.sendSyncWithCurrentIdentity(Topology.lookup(AutoScalingBackend.class), request); } catch (NoSuchElementException e) { throw new AutoScalingUnavailableException("Service Unavailable"); } catch (final FailedRequestException e) { if (request.getReply().getClass().isInstance(e.getRequest())) { return e.getRequest(); } throw e.getRequest() == null ? e : new AutoScalingException("InternalError", Role.Receiver, "Internal error " + e.getRequest().getClass().getSimpleName() + ":false"); } } @SuppressWarnings("ThrowableResultOfMethodCallIgnored") private void handleRemoteException(final Exception e) throws EucalyptusCloudException { final Optional<AsyncExceptions.AsyncWebServiceError> serviceErrorOption = AsyncExceptions .asWebServiceError(e); if (serviceErrorOption.isPresent()) { final AsyncExceptions.AsyncWebServiceError serviceError = serviceErrorOption.get(); final String code = serviceError.getCode(); final String message = serviceError.getMessage(); switch (serviceError.getHttpErrorCode()) { case 400: throw new AutoScalingClientException(code, message); case 403: throw new AutoScalingAuthorizationException(code, message); case 503: throw new AutoScalingUnavailableException(message); default: throw new AutoScalingException(code, Role.Receiver, message); } } } private static void handleException(final Exception e) throws AutoScalingException { handleException(e, false); } private static void handleException(final Exception e, final boolean isCreate) throws AutoScalingException { final AutoScalingException cause = Exceptions.findCause(e, AutoScalingException.class); if (cause != null) { throw cause; } logger.error(e, e); final AutoScalingServiceException exception = new AutoScalingServiceException("InternalFailure", String.valueOf(e.getMessage())); if (Contexts.lookup().hasAdministrativePrivileges()) { exception.initCause(e); } throw exception; } }