View Javadoc

1   /**
2    *
3    * Copyright (C) 2011 Cloud Conscious, LLC. <info@cloudconscious.com>
4    *
5    * ====================================================================
6    * Licensed under the Apache License, Version 2.0 (the "License");
7    * you may not use this file except in compliance with the License.
8    * You may obtain a copy of the License at
9    *
10   * http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   * ====================================================================
18   */
19  package org.jclouds.cloudsigma.compute.functions;
20  
21  import static com.google.common.base.Preconditions.checkNotNull;
22  import static org.jclouds.compute.util.ComputeServiceUtils.parseGroupFromName;
23  
24  import java.util.List;
25  import java.util.Map;
26  import java.util.Set;
27  
28  import javax.inject.Inject;
29  import javax.inject.Singleton;
30  
31  import org.jclouds.cloudsigma.domain.Device;
32  import org.jclouds.cloudsigma.domain.DriveInfo;
33  import org.jclouds.cloudsigma.domain.Server;
34  import org.jclouds.cloudsigma.domain.ServerInfo;
35  import org.jclouds.cloudsigma.domain.ServerStatus;
36  import org.jclouds.collect.FindResourceInSet;
37  import org.jclouds.collect.Memoized;
38  import org.jclouds.compute.domain.HardwareBuilder;
39  import org.jclouds.compute.domain.Image;
40  import org.jclouds.compute.domain.NodeMetadata;
41  import org.jclouds.compute.domain.NodeMetadataBuilder;
42  import org.jclouds.compute.domain.NodeState;
43  import org.jclouds.compute.domain.Processor;
44  import org.jclouds.compute.domain.Volume;
45  import org.jclouds.compute.domain.VolumeBuilder;
46  import org.jclouds.domain.Credentials;
47  import org.jclouds.domain.Location;
48  
49  import com.google.common.base.Function;
50  import com.google.common.base.Supplier;
51  import com.google.common.collect.ImmutableList;
52  import com.google.common.collect.ImmutableMap;
53  import com.google.common.collect.ImmutableSet;
54  import com.google.common.collect.Iterables;
55  
56  /**
57   * @author Adrian Cole
58   */
59  @Singleton
60  public class ServerInfoToNodeMetadata implements Function<ServerInfo, NodeMetadata> {
61     public static final Map<ServerStatus, NodeState> serverStatusToNodeState = ImmutableMap
62           .<ServerStatus, NodeState> builder().put(ServerStatus.ACTIVE, NodeState.RUNNING)//
63           .put(ServerStatus.STOPPED, NodeState.SUSPENDED)//
64           .put(ServerStatus.PAUSED, NodeState.SUSPENDED)//
65           .put(ServerStatus.DUMPED, NodeState.PENDING)//
66           .put(ServerStatus.DEAD, NodeState.TERMINATED)//
67           .put(ServerStatus.UNRECOGNIZED, NodeState.UNRECOGNIZED)//
68           .build();
69  
70     private final Function<Server, String> getImageIdFromServer;
71     private final Function<String, Image> findImageForId;
72     private final Map<String, Credentials> credentialStore;
73     private final Supplier<Location> locationSupplier;
74     private final Function<Device, Volume> deviceToVolume;
75  
76     @Inject
77     ServerInfoToNodeMetadata(Map<String, Credentials> credentialStore, Function<Server, String> getImageIdFromServer,
78           Function<String, Image> findImageForId, Function<Device, Volume> deviceToVolume,
79           Supplier<Location> locationSupplier) {
80        this.credentialStore = checkNotNull(credentialStore, "credentialStore");
81        this.locationSupplier = checkNotNull(locationSupplier, "locationSupplier");
82        this.deviceToVolume = checkNotNull(deviceToVolume, "deviceToVolume");
83        this.findImageForId = checkNotNull(findImageForId, "findImageForId");
84        this.getImageIdFromServer = checkNotNull(getImageIdFromServer, "getImageIdFromServer");
85     }
86  
87     @SuppressWarnings({ "unchecked", "rawtypes" })
88     @Override
89     public NodeMetadata apply(ServerInfo from) {
90        NodeMetadataBuilder builder = new NodeMetadataBuilder();
91        builder.ids(from.getUuid());
92        builder.name(from.getName());
93        builder.location(locationSupplier.get());
94        builder.group(parseGroupFromName(from.getName()));
95  
96        String imageId = getImageIdFromServer.apply(from);
97        if (imageId != null) {
98           Image image = findImageForId.apply(imageId);
99           if (image != null) {
100             builder.operatingSystem(image.getOperatingSystem());
101             builder.adminPassword(image.getAdminPassword());
102          }
103       }
104       builder.hardware(new HardwareBuilder().ids(from.getUuid())
105             .processors(ImmutableList.of(new Processor(1, from.getCpu()))).ram(from.getMem())
106             .volumes((List) ImmutableList.of(Iterables.transform(from.getDevices().values(), deviceToVolume))).build());
107       builder.state(serverStatusToNodeState.get(from.getStatus()));
108       builder.publicAddresses(ImmutableSet.<String> of(from.getVnc().getIp()));
109       builder.privateAddresses(ImmutableSet.<String> of());
110       builder.credentials(credentialStore.get(from.getUuid()));
111       return builder.build();
112    }
113 
114    @Singleton
115    public static final class DeviceToVolume implements Function<Device, Volume> {
116       private final Map<String, DriveInfo> cache;
117 
118       @Inject
119       public DeviceToVolume(Map<String, DriveInfo> cache) {
120          this.cache = checkNotNull(cache, "cache");
121       }
122 
123       @Override
124       public Volume apply(Device input) {
125          VolumeBuilder builder = new VolumeBuilder();
126          builder.id(input.getId());
127          DriveInfo drive = cache.get(input.getDriveUuid());
128          if (drive != null) {
129             builder.size(drive.getSize() / 1024 / 1024f);
130          }
131          return new VolumeBuilder().durable(true).type(Volume.Type.NAS).build();
132       }
133    }
134 
135    /**
136     * When we create the boot drive of the server, by convention we set the name to the image it
137     * came from.
138     * 
139     * @author Adrian Cole
140     * 
141     */
142    @Singleton
143    public static class GetImageIdFromServer implements Function<Server, String> {
144       private final Map<String, DriveInfo> cache;
145 
146       @Inject
147       public GetImageIdFromServer(Map<String, DriveInfo> cache) {
148          this.cache = cache;
149       }
150 
151       @Override
152       public String apply(Server from) {
153          String imageId = null;
154          String bootDeviceId = Iterables.get(from.getBootDeviceIds(), 0);
155          Device bootDevice = from.getDevices().get(bootDeviceId);
156          if (bootDevice != null) {
157             try {
158                imageId = cache.get(bootDevice.getDriveUuid()).getName();
159             } catch (NullPointerException e) {
160 
161             }
162          }
163          return imageId;
164       }
165    }
166 
167    @Singleton
168    public static class FindImageForId extends FindResourceInSet<String, Image> {
169 
170       @Inject
171       public FindImageForId(@Memoized Supplier<Set<? extends Image>> images) {
172          super(images);
173       }
174 
175       @Override
176       public boolean matches(String from, Image input) {
177          return input.getProviderId().equals(from);
178       }
179    }
180 
181 }