blob: ace98e9dabc953ec8e783f3f49c19f860da96d5a [file] [log] [blame]
/*
* 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 org.jclouds.aliyun.ecs.compute.config;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Function;
import com.google.common.base.Predicate;
import com.google.inject.Provides;
import com.google.inject.TypeLiteral;
import com.google.inject.name.Named;
import org.jclouds.aliyun.ecs.ECSComputeServiceApi;
import org.jclouds.aliyun.ecs.compute.ECSComputeService;
import org.jclouds.aliyun.ecs.compute.ECSComputeServiceAdapter;
import org.jclouds.aliyun.ecs.compute.functions.ImageInRegionToImage;
import org.jclouds.aliyun.ecs.compute.functions.InstanceStatusToStatus;
import org.jclouds.aliyun.ecs.compute.functions.InstanceToNodeMetadata;
import org.jclouds.aliyun.ecs.compute.functions.InstanceTypeToHardware;
import org.jclouds.aliyun.ecs.compute.functions.RegionToLocation;
import org.jclouds.aliyun.ecs.compute.strategy.CreateResourcesThenCreateNodes;
import org.jclouds.aliyun.ecs.domain.Instance;
import org.jclouds.aliyun.ecs.domain.InstanceStatus;
import org.jclouds.aliyun.ecs.domain.InstanceType;
import org.jclouds.aliyun.ecs.domain.Region;
import org.jclouds.aliyun.ecs.domain.regionscoped.ImageInRegion;
import org.jclouds.aliyun.ecs.domain.regionscoped.RegionAndId;
import org.jclouds.aliyun.ecs.compute.options.ECSServiceTemplateOptions;
import org.jclouds.aliyun.ecs.predicates.InstanceStatusPredicate;
import org.jclouds.compute.ComputeService;
import org.jclouds.compute.ComputeServiceAdapter;
import org.jclouds.compute.config.ComputeServiceAdapterContextModule;
import org.jclouds.compute.domain.Hardware;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.functions.NodeAndTemplateOptionsToStatement;
import org.jclouds.compute.functions.NodeAndTemplateOptionsToStatementWithoutPublicKey;
import org.jclouds.compute.options.TemplateOptions;
import org.jclouds.compute.reference.ComputeServiceConstants;
import org.jclouds.compute.strategy.CreateNodesInGroupThenAddToSet;
import org.jclouds.domain.Location;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_RUNNING;
import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_SUSPENDED;
import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_TERMINATED;
import static org.jclouds.util.Predicates2.retry;
public class ECSServiceContextModule extends ComputeServiceAdapterContextModule<Instance, InstanceType, ImageInRegion, Region> {
@Override
protected void configure() {
super.configure();
bind(new TypeLiteral<ComputeServiceAdapter<Instance, InstanceType, ImageInRegion, Region>>() {
}).to(ECSComputeServiceAdapter.class);
bind(ComputeService.class).to(ECSComputeService.class);
bind(new TypeLiteral<Function<Instance, NodeMetadata>>() {
}).to(InstanceToNodeMetadata.class);
bind(new TypeLiteral<Function<InstanceType, Hardware>>() {
}).to(InstanceTypeToHardware.class);
bind(new TypeLiteral<Function<ImageInRegion, org.jclouds.compute.domain.Image>>() {
}).to(ImageInRegionToImage.class);
bind(new TypeLiteral<Function<Region, Location>>() {
}).to(RegionToLocation.class);
bind(new TypeLiteral<Function<Instance.Status, NodeMetadata.Status>>() {
}).to(InstanceStatusToStatus.class);
install(new LocationsFromComputeServiceAdapterModule<Instance, InstanceType, ImageInRegion, Region>() {
});
bind(TemplateOptions.class).to(ECSServiceTemplateOptions.class);
bind(CreateNodesInGroupThenAddToSet.class).to(CreateResourcesThenCreateNodes.class);
bind(NodeAndTemplateOptionsToStatement.class).to(NodeAndTemplateOptionsToStatementWithoutPublicKey.class);
}
@Provides
@Named(TIMEOUT_NODE_RUNNING)
protected Predicate<String> provideInstanceRunningPredicate(final ECSComputeServiceApi api,
ComputeServiceConstants.Timeouts timeouts, ComputeServiceConstants.PollPeriod pollPeriod) {
return retry(new InstanceInStatusPredicate(api, InstanceStatus.Status.RUNNING), timeouts.nodeRunning,
pollPeriod.pollInitialPeriod, pollPeriod.pollMaxPeriod);
}
@Provides
@Named(TIMEOUT_NODE_SUSPENDED)
protected Predicate<String> provideInstanceSuspendedPredicate(final ECSComputeServiceApi api,
ComputeServiceConstants.Timeouts timeouts, ComputeServiceConstants.PollPeriod pollPeriod) {
return retry(new InstanceInStatusPredicate(api, InstanceStatus.Status.STOPPED), timeouts.nodeSuspended,
pollPeriod.pollInitialPeriod, pollPeriod.pollMaxPeriod);
}
@Provides
@Named(TIMEOUT_NODE_TERMINATED)
protected Predicate<String> provideInstanceTerminatedPredicate(final ECSComputeServiceApi api,
ComputeServiceConstants.Timeouts timeouts, ComputeServiceConstants.PollPeriod pollPeriod) {
return retry(new InstanceTerminatedPredicate(api), timeouts.nodeTerminated, pollPeriod.pollInitialPeriod,
pollPeriod.pollMaxPeriod);
}
@VisibleForTesting
static class InstanceInStatusPredicate implements Predicate<String> {
private final ECSComputeServiceApi api;
private final InstanceStatus.Status desiredStatus;
public InstanceInStatusPredicate(ECSComputeServiceApi api, InstanceStatus.Status desiredStatus) {
this.api = checkNotNull(api, "api must not be null");
this.desiredStatus = checkNotNull(desiredStatus, "instance status must not be null");
}
@Override
public boolean apply(String id) {
checkNotNull(id, "id");
RegionAndId regionAndId = RegionAndId.fromSlashEncoded(id);
String regionId = regionAndId.regionId();
String instanceId = regionAndId.id();
InstanceStatus instanceStatus = api.instanceApi().listInstanceStatus(regionId)
.concat()
.firstMatch(new InstanceStatusPredicate(instanceId))
.orNull();
return instanceStatus != null && desiredStatus == instanceStatus.status();
}
}
@VisibleForTesting
static class InstanceTerminatedPredicate implements Predicate<String> {
private final ECSComputeServiceApi api;
public InstanceTerminatedPredicate(ECSComputeServiceApi api) {
this.api = checkNotNull(api, "api must not be null");
}
@Override
public boolean apply(String id) {
checkNotNull(id, "id");
RegionAndId regionAndId = RegionAndId.fromSlashEncoded(id);
String regionId = regionAndId.regionId();
final String instanceId = regionAndId.id();
InstanceStatus instanceStatus = api.instanceApi().listInstanceStatus(regionId)
.concat()
.firstMatch(new InstanceStatusPredicate(instanceId))
.orNull();
return instanceStatus == null;
}
}
}