2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017 AT&T Intellectual Property. All rights
7 * ================================================================================
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 * ============LICENSE_END=========================================================
22 package org.openecomp.appc.adapter.iaas.provider.operation.impl.base;
24 import org.openecomp.appc.Constants;
25 import org.openecomp.appc.adapter.iaas.impl.*;
26 import org.openecomp.appc.i18n.Msg;
27 import com.att.cdp.exceptions.ContextConnectionException;
28 import com.att.cdp.exceptions.NotLoggedInException;
29 import com.att.cdp.exceptions.TimeoutException;
30 import com.att.cdp.exceptions.ZoneException;
31 import com.att.cdp.pal.util.StringHelper;
32 import com.att.cdp.zones.ComputeService;
33 import com.att.cdp.zones.Context;
34 import com.att.cdp.zones.ImageService;
35 import com.att.cdp.zones.NetworkService;
36 import com.att.cdp.zones.Provider;
37 import com.att.cdp.zones.model.Hypervisor;
38 import com.att.cdp.zones.model.Image;
39 import com.att.cdp.zones.model.Network;
40 import com.att.cdp.zones.model.Port;
41 import com.att.cdp.zones.model.Server;
42 import com.att.eelf.configuration.EELFLogger;
43 import com.att.eelf.configuration.EELFManager;
44 import com.att.eelf.i18n.EELFResourceManager;
45 import org.glassfish.grizzly.http.util.HttpStatus;
46 import java.util.ArrayList;
47 import java.util.List;
50 * @since September 29, 2016
52 public abstract class ProviderServerOperation extends ProviderOperation{
54 private static final EELFLogger logger = EELFManager.getInstance().getLogger(ProviderServerOperation.class);
57 * Looks up the indicated server using the provided context and returns the server to the caller
62 * The provider context
64 * The id of the server
65 * @return The server, or null if there is a problem
66 * @throws ZoneException
67 * If the server cannot be found
68 * @throws RequestFailedException
69 * If the server cannot be found because we cant connect to the provider
71 @SuppressWarnings("nls")
72 protected Server lookupServer(RequestContext rc, Context context, String id)
73 throws ZoneException, RequestFailedException {
74 ComputeService service = context.getComputeService();
77 Provider provider = context.getProvider();
79 while (rc.attempt()) {
81 server = service.getServer(id);
83 } catch (ContextConnectionException e) {
84 msg = EELFResourceManager.format(Msg.CONNECTION_FAILED_RETRY, provider.getName(), service.getURL(),
85 context.getTenant().getName(), context.getTenant().getId(), e.getMessage(),
86 Long.toString(rc.getRetryDelay()), Integer.toString(rc.getAttempts()),
87 Integer.toString(rc.getRetryLimit()));
93 msg = EELFResourceManager.format(Msg.CONNECTION_FAILED, provider.getName(), service.getURL());
95 doFailure(rc, HttpStatus.BAD_GATEWAY_502, msg);
96 throw new RequestFailedException("Lookup Server", msg, HttpStatus.BAD_GATEWAY_502, server);
104 * Resume a suspended server and wait for it to enter a running state
107 * The request context that manages the state and recovery of the request for the life of its processing.
109 * The server to be resumed
110 * @throws ZoneException
111 * @throws RequestFailedException
113 @SuppressWarnings("nls")
114 protected void resumeServer(RequestContext rc, Server server) throws ZoneException, RequestFailedException {
115 logger.debug(Msg.RESUME_SERVER, server.getId());
117 Context context = server.getContext();
119 Provider provider = context.getProvider();
120 ComputeService service = context.getComputeService();
121 while (rc.attempt()) {
125 } catch (ContextConnectionException e) {
126 msg = EELFResourceManager.format(Msg.CONNECTION_FAILED_RETRY, provider.getName(), service.getURL(),
127 context.getTenant().getName(), context.getTenant().getId(), e.getMessage(),
128 Long.toString(rc.getRetryDelay()), Integer.toString(rc.getAttempts()),
129 Integer.toString(rc.getRetryLimit()));
130 logger.error(msg, e);
135 msg = EELFResourceManager.format(Msg.CONNECTION_FAILED, provider.getName(), service.getURL());
137 throw new RequestFailedException("Resume Server", msg, HttpStatus.BAD_GATEWAY_502, server);
140 waitForStateChange(rc, server, Server.Status.RUNNING);
144 protected boolean hasImageAccess(@SuppressWarnings("unused") RequestContext rc, Context context) {
145 logger.info("Checking permissions for image service.");
147 ImageService service = context.getImageService();
148 service.getImageByName("CHECK_IMAGE_ACCESS");
149 logger.info("Image service is accessible.");
151 } catch (ZoneException e) {
152 logger.warn("Image service could not be accessed. Some operations may fail.", e);
159 * Enter a pool-wait loop checking the server state to see if it has entered one of the desired states or not.
161 * This method checks the state of the server periodically for one of the desired states. When the server enters one
162 * of the desired states, the method returns a successful indication (true). If the server never enters one of the
163 * desired states within the allocated timeout period, then the method returns a failed response (false). No
164 * exceptions are thrown from this method.
168 * The request context that manages the state and recovery of the request for the life of its processing.
170 * The server to wait on
171 * @param desiredStates
172 * A variable list of desired states, any one of which is allowed.
173 * @throws RequestFailedException
174 * If the request times out or fails for some reason
175 * @throws NotLoggedInException
177 @SuppressWarnings("nls")
178 protected void waitForStateChange(RequestContext rc, Image image, Image.Status... desiredStates)
179 throws RequestFailedException, NotLoggedInException {
180 int pollInterval = configuration.getIntegerProperty(Constants.PROPERTY_OPENSTACK_POLL_INTERVAL);
181 int timeout = configuration.getIntegerProperty(Constants.PROPERTY_SERVER_STATE_CHANGE_TIMEOUT);
182 Context context = image.getContext();
183 Provider provider = context.getProvider();
184 ImageService service = context.getImageService();
187 long endTime = System.currentTimeMillis() + (timeout * 1000); //
189 while (rc.attempt()) {
192 image.waitForStateChange(pollInterval, timeout, desiredStates);
194 } catch (TimeoutException e) {
195 @SuppressWarnings("MismatchedQueryAndUpdateOfCollection")
196 List<String> list = new ArrayList<>();
197 for (Image.Status desiredState : desiredStates) {
198 list.add(desiredState.name());
200 msg = EELFResourceManager.format(Msg.CONNECTION_FAILED_RETRY, provider.getName(), service.getURL(),
201 context.getTenant().getName(), context.getTenant().getId(), e.getMessage(),
202 Long.toString(rc.getRetryDelay()), Integer.toString(rc.getAttempts()),
203 Integer.toString(rc.getRetryLimit()));
204 logger.error(msg, e);
207 } catch (ZoneException e) {
208 List<String> list = new ArrayList<>();
209 for (Image.Status desiredState : desiredStates) {
210 list.add(desiredState.name());
212 String reason = EELFResourceManager.format(Msg.STATE_CHANGE_EXCEPTION, e.getClass().getSimpleName(),
213 "server", image.getName(), image.getId(), StringHelper.asList(list), image.getStatus().name(),
215 logger.error(reason);
216 logger.error(EELFResourceManager.format(e));
218 // Instead of failing we are going to wait and try again.
219 // Timeout is reduced by delay time
220 logger.info(String.format("Retrying in %ds", rc.getRetryDelay()));
222 timeout = (int) (endTime - System.currentTimeMillis()) / 1000;
223 // throw new RequestFailedException(e, operation, reason,
224 // HttpStatus.BAD_GATEWAY_502, server);
229 msg = EELFResourceManager.format(Msg.CONNECTION_FAILED, provider.getName(), service.getURL());
231 throw new RequestFailedException("Waiting for State Change", msg, HttpStatus.BAD_GATEWAY_502, new Server());
238 * Enter a pool-wait loop checking the server state to see if it has entered one of the desired states or not.
240 * This method checks the state of the server periodically for one of the desired states. When the server enters one
241 * of the desired states, the method returns a successful indication (true). If the server never enters one of the
242 * desired states within the allocated timeout period, then the method returns a failed response (false). No
243 * exceptions are thrown from this method.
247 * The request context that manages the state and recovery of the request for the life of its processing.
249 * The server to wait on
250 * @param desiredStates
251 * A variable list of desired states, any one of which is allowed.
252 * @throws RequestFailedException
253 * If the request times out or fails for some reason
255 @SuppressWarnings("nls")
256 protected void waitForStateChange(RequestContext rc, Server server, Server.Status... desiredStates)
257 throws RequestFailedException {
258 int pollInterval = configuration.getIntegerProperty(Constants.PROPERTY_OPENSTACK_POLL_INTERVAL);
259 int timeout = configuration.getIntegerProperty(Constants.PROPERTY_SERVER_STATE_CHANGE_TIMEOUT);
260 Context context = server.getContext();
261 Provider provider = context.getProvider();
262 ComputeService service = context.getComputeService();
265 long endTime = System.currentTimeMillis() + (timeout * 1000); //
267 while (rc.attempt()) {
270 server.waitForStateChange(pollInterval, timeout, desiredStates);
272 } catch (TimeoutException e) {
273 @SuppressWarnings("MismatchedQueryAndUpdateOfCollection")
274 List<String> list = new ArrayList<>();
275 for (Server.Status desiredState : desiredStates) {
276 list.add(desiredState.name());
278 msg = EELFResourceManager.format(Msg.CONNECTION_FAILED_RETRY, provider.getName(), service.getURL(),
279 context.getTenant().getName(), context.getTenant().getId(), e.getMessage(),
280 Long.toString(rc.getRetryDelay()), Integer.toString(rc.getAttempts()),
281 Integer.toString(rc.getRetryLimit()));
282 logger.error(msg, e);
285 } catch (ZoneException e) {
286 List<String> list = new ArrayList<>();
287 for (Server.Status desiredState : desiredStates) {
288 list.add(desiredState.name());
290 String reason = EELFResourceManager.format(Msg.STATE_CHANGE_EXCEPTION, e.getClass().getSimpleName(),
291 "server", server.getName(), server.getId(), StringHelper.asList(list), server.getStatus().name(),
293 logger.error(reason);
294 logger.error(EELFResourceManager.format(e));
296 // Instead of failing we are going to wait and try again.
297 // Timeout is reduced by delay time
298 logger.info(String.format("Retrying in %ds", rc.getRetryDelay()));
300 timeout = (int) (endTime - System.currentTimeMillis()) / 1000;
301 // throw new RequestFailedException(e, operation, reason,
302 // HttpStatus.BAD_GATEWAY_502, server);
307 msg = EELFResourceManager.format(Msg.CONNECTION_FAILED, provider.getName(), service.getURL());
309 throw new RequestFailedException("Waiting for State Change", msg, HttpStatus.BAD_GATEWAY_502, server);
315 * Stop the specified server and wait for it to stop
318 * The request context that manages the state and recovery of the request for the life of its processing.
320 * The server to be stopped
321 * @throws ZoneException
322 * @throws RequestFailedException
324 @SuppressWarnings("nls")
325 protected void stopServer(RequestContext rc, Server server) throws ZoneException, RequestFailedException {
326 logger.debug(Msg.STOP_SERVER, server.getId());
329 Context context = server.getContext();
330 Provider provider = context.getProvider();
331 ComputeService service = context.getComputeService();
332 while (rc.attempt()) {
336 } catch (ContextConnectionException e) {
337 msg = EELFResourceManager.format(Msg.CONNECTION_FAILED_RETRY, provider.getName(), service.getURL(),
338 context.getTenant().getName(), context.getTenant().getId(), e.getMessage(),
339 Long.toString(rc.getRetryDelay()), Integer.toString(rc.getAttempts()),
340 Integer.toString(rc.getRetryLimit()));
341 logger.error(msg, e);
346 msg = EELFResourceManager.format(Msg.CONNECTION_FAILED, provider.getName(), service.getURL());
348 throw new RequestFailedException("Stop Server", msg, HttpStatus.BAD_GATEWAY_502, server);
351 waitForStateChange(rc, server, Server.Status.READY, Server.Status.ERROR);
355 * Start the server and wait for it to enter a running state
358 * The request context that manages the state and recovery of the request for the life of its processing.
360 * The server to be started
361 * @throws ZoneException
362 * @throws RequestFailedException
364 @SuppressWarnings("nls")
365 protected void startServer(RequestContext rc, Server server) throws ZoneException, RequestFailedException {
366 logger.debug(Msg.START_SERVER, server.getId());
368 Context context = server.getContext();
369 Provider provider = context.getProvider();
370 ComputeService service = context.getComputeService();
371 while (rc.attempt()) {
375 } catch (ContextConnectionException e) {
376 msg = EELFResourceManager.format(Msg.CONNECTION_FAILED_RETRY, provider.getName(), service.getURL(),
377 context.getTenant().getName(), context.getTenant().getId(), e.getMessage(),
378 Long.toString(rc.getRetryDelay()), Integer.toString(rc.getAttempts()),
379 Integer.toString(rc.getRetryLimit()));
380 logger.error(msg, e);
385 msg = EELFResourceManager.format(Msg.CONNECTION_FAILED, provider.getName(), service.getURL());
387 throw new RequestFailedException("Start Server", msg, HttpStatus.BAD_GATEWAY_502, server);
390 waitForStateChange(rc, server, Server.Status.RUNNING);
395 * Un-Pause a paused server and wait for it to enter a running state
398 * The request context that manages the state and recovery of the request for the life of its processing.
400 * The server to be un-paused
401 * @throws ZoneException
402 * @throws RequestFailedException
404 @SuppressWarnings("nls")
405 protected void unpauseServer(RequestContext rc, Server server) throws ZoneException, RequestFailedException {
406 logger.debug(Msg.UNPAUSE_SERVER, server.getId());
409 Context context = server.getContext();
410 Provider provider = context.getProvider();
411 ComputeService service = context.getComputeService();
412 while (rc.attempt()) {
416 } catch (ContextConnectionException e) {
417 msg = EELFResourceManager.format(Msg.CONNECTION_FAILED_RETRY, provider.getName(), service.getURL(),
418 context.getTenant().getName(), context.getTenant().getId(), e.getMessage(),
419 Long.toString(rc.getRetryDelay()), Integer.toString(rc.getAttempts()),
420 Integer.toString(rc.getRetryLimit()));
421 logger.error(msg, e);
426 msg = EELFResourceManager.format(Msg.CONNECTION_FAILED, provider.getName(), service.getURL());
428 throw new RequestFailedException("Unpause Server", msg, HttpStatus.BAD_GATEWAY_502, server);
431 waitForStateChange(rc, server, Server.Status.RUNNING, Server.Status.READY);
436 * Generates the event indicating what happened
439 * The request context that manages the state and recovery of the request for the life of its processing.
441 * True if the event represents a successful outcome
443 * The detailed message
445 protected void generateEvent(@SuppressWarnings("unused") RequestContext rc, @SuppressWarnings("unused") boolean success, @SuppressWarnings("unused") String msg) {
446 // indication to the DG to generate the event?
450 * Checks if the VM is connected to the Virtual Network and reachable
453 * The request context that manages the state and recovery of the request for the life of its processing.
455 * The server object representing the server we want to operate on
457 * The interface cloud service provider to access services or the object model, or both
460 protected void checkVirtualMachineNetworkStatus(RequestContext rc, Server server, Context context)
461 throws ZoneException, RequestFailedException {
463 logger.info("Performing the VM Server networking status checks...");
464 List<Port> ports = server.getPorts();
466 NetworkService netSvc = context.getNetworkService();
469 for (Port port : ports) {
471 switch (port.getPortState().toString().toUpperCase()) {
473 * The port is connected, configured, and usable for communication
476 Network network = netSvc.getNetworkById(port.getNetwork());
477 // Subnet subnet = netSvc.getSubnetById(port.getSubnetId());
478 if (!network.getStatus().equals(Network.Status.ACTIVE.toString())) {
479 msg = EELFResourceManager.format(Msg.SERVER_NETWORK_ERROR, server.getName(), port.getId());
481 doFailure(rc, HttpStatus.PRECONDITION_FAILED_412, msg);
482 throw new RequestFailedException("VM Server Network is DOWN", msg.toString(), HttpStatus.PRECONDITION_FAILED_412,
488 * The port is disconnected or powered-off and cannot be used for
492 msg = EELFResourceManager.format(Msg.SERVER_NETWORK_ERROR, server.getName(), port.getId());
494 doFailure(rc, HttpStatus.PRECONDITION_FAILED_412, msg);
495 throw new RequestFailedException("VM Server Port status is OFFLINE", msg.toString(), HttpStatus.PRECONDITION_FAILED_412,
499 * The port's status is changing because of some event or operation.
500 * The final state is yet to be determined.
503 msg = EELFResourceManager.format(Msg.SERVER_NETWORK_ERROR, server.getName(), port.getId());
505 doFailure(rc, HttpStatus.PRECONDITION_FAILED_412, msg);
506 throw new RequestFailedException("VM Server Port status is PENDING", msg.toString(), HttpStatus.PRECONDITION_FAILED_412,
510 * The port is in an unknown state and cannot be used.
513 msg = EELFResourceManager.format(Msg.SERVER_NETWORK_ERROR, server.getName(), port.getId());
515 doFailure(rc, HttpStatus.PRECONDITION_FAILED_412, msg);
516 throw new RequestFailedException("VM Server Port status is UNKNOWN", msg.toString(), HttpStatus.PRECONDITION_FAILED_412,
521 logger.info("Passed the VM Server the Hypervisor status checks..");
526 * Checks if the VM is connected to the Virtual Network and reachable
529 * The server object representing the server we want to operate on
531 protected void checkHypervisor(Server server)
532 throws ZoneException, RequestFailedException {
534 logger.info("Performing the Hypervisor status checks..");
535 String status = null, state = null, msg = null;
537 status = server.getHypervisor().getStatus().toString();
538 state = server.getHypervisor().getState().toString();
540 if (!status.equals(Hypervisor.Status.ENABLED.toString()) || !state.equals(Hypervisor.State.UP.toString())) {
541 msg = EELFResourceManager.format(Msg.HYPERVISOR_DOWN_ERROR, server.getHypervisor().getHostName(), server.getName());
542 logger.error(msg.toString());
544 //doFailure(rc, HttpStatus.PRECONDITION_FAILED_412, msg);
545 throw new RequestFailedException("Hypervisor status DOWN or NOT ENABLED", msg.toString(), HttpStatus.PRECONDITION_FAILED_412,
550 logger.info("Passed the Hypervisor status checks..");
555 * Checks if a Host machine is reachable
558 * IP Address of the Host Machine.
560 * The server object representing the Virtual Machine server
564 /*private boolean isHostReachable(String ipAddress) throws IOException {
566 InetAddress address = InetAddress.getByName(ipAddress);
568 return address.isReachable(15000);