2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6 * ================================================================================
7 * Copyright (C) 2017 Amdocs
8 * =============================================================================
9 * Licensed under the Apache License, Version 2.0 (the "License");
10 * you may not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
13 * http://www.apache.org/licenses/LICENSE-2.0
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS,
17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the License for the specific language governing permissions and
19 * limitations under the License.
21 * ECOMP is a trademark and service mark of AT&T Intellectual Property.
22 * ============LICENSE_END=========================================================
25 package org.openecomp.appc.adapter.iaas.provider.operation.impl.base;
27 import org.openecomp.appc.Constants;
28 import org.openecomp.appc.adapter.iaas.impl.*;
29 import org.openecomp.appc.i18n.Msg;
30 import com.att.cdp.exceptions.ContextConnectionException;
31 import com.att.cdp.exceptions.NotLoggedInException;
32 import com.att.cdp.exceptions.TimeoutException;
33 import com.att.cdp.exceptions.ZoneException;
34 import com.att.cdp.pal.util.StringHelper;
35 import com.att.cdp.zones.ComputeService;
36 import com.att.cdp.zones.Context;
37 import com.att.cdp.zones.ImageService;
38 import com.att.cdp.zones.NetworkService;
39 import com.att.cdp.zones.Provider;
40 import com.att.cdp.zones.model.Hypervisor;
41 import com.att.cdp.zones.model.Image;
42 import com.att.cdp.zones.model.Network;
43 import com.att.cdp.zones.model.Port;
44 import com.att.cdp.zones.model.Server;
45 import com.att.eelf.configuration.EELFLogger;
46 import com.att.eelf.configuration.EELFManager;
47 import com.att.eelf.i18n.EELFResourceManager;
48 import org.glassfish.grizzly.http.util.HttpStatus;
49 import java.util.ArrayList;
50 import java.util.List;
53 * @since September 29, 2016
55 public abstract class ProviderServerOperation extends ProviderOperation{
57 private static final EELFLogger logger = EELFManager.getInstance().getLogger(ProviderServerOperation.class);
60 * Looks up the indicated server using the provided context and returns the server to the caller
65 * The provider context
67 * The id of the server
68 * @return The server, or null if there is a problem
69 * @throws ZoneException
70 * If the server cannot be found
71 * @throws RequestFailedException
72 * If the server cannot be found because we cant connect to the provider
74 @SuppressWarnings("nls")
75 protected Server lookupServer(RequestContext rc, Context context, String id)
76 throws ZoneException, RequestFailedException {
77 ComputeService service = context.getComputeService();
80 Provider provider = context.getProvider();
82 while (rc.attempt()) {
84 server = service.getServer(id);
86 } catch (ContextConnectionException e) {
87 msg = EELFResourceManager.format(Msg.CONNECTION_FAILED_RETRY, provider.getName(), service.getURL(),
88 context.getTenant().getName(), context.getTenant().getId(), e.getMessage(),
89 Long.toString(rc.getRetryDelay()), Integer.toString(rc.getAttempts()),
90 Integer.toString(rc.getRetryLimit()));
96 msg = EELFResourceManager.format(Msg.CONNECTION_FAILED, provider.getName(), service.getURL());
98 doFailure(rc, HttpStatus.BAD_GATEWAY_502, msg);
99 throw new RequestFailedException("Lookup Server", msg, HttpStatus.BAD_GATEWAY_502, server);
107 * Resume a suspended server and wait for it to enter a running state
110 * The request context that manages the state and recovery of the request for the life of its processing.
112 * The server to be resumed
113 * @throws ZoneException
114 * @throws RequestFailedException
116 @SuppressWarnings("nls")
117 protected void resumeServer(RequestContext rc, Server server) throws ZoneException, RequestFailedException {
118 logger.debug(Msg.RESUME_SERVER, server.getId());
120 Context context = server.getContext();
122 Provider provider = context.getProvider();
123 ComputeService service = context.getComputeService();
124 while (rc.attempt()) {
128 } catch (ContextConnectionException e) {
129 msg = EELFResourceManager.format(Msg.CONNECTION_FAILED_RETRY, provider.getName(), service.getURL(),
130 context.getTenant().getName(), context.getTenant().getId(), e.getMessage(),
131 Long.toString(rc.getRetryDelay()), Integer.toString(rc.getAttempts()),
132 Integer.toString(rc.getRetryLimit()));
133 logger.error(msg, e);
138 msg = EELFResourceManager.format(Msg.CONNECTION_FAILED, provider.getName(), service.getURL());
140 throw new RequestFailedException("Resume Server", msg, HttpStatus.BAD_GATEWAY_502, server);
143 waitForStateChange(rc, server, Server.Status.RUNNING);
147 protected boolean hasImageAccess(@SuppressWarnings("unused") RequestContext rc, Context context) {
148 logger.info("Checking permissions for image service.");
150 ImageService service = context.getImageService();
151 service.getImageByName("CHECK_IMAGE_ACCESS");
152 logger.info("Image service is accessible.");
154 } catch (ZoneException e) {
155 logger.warn("Image service could not be accessed. Some operations may fail.", e);
162 * Enter a pool-wait loop checking the server state to see if it has entered one of the desired states or not.
164 * This method checks the state of the server periodically for one of the desired states. When the server enters one
165 * of the desired states, the method returns a successful indication (true). If the server never enters one of the
166 * desired states within the allocated timeout period, then the method returns a failed response (false). No
167 * exceptions are thrown from this method.
171 * The request context that manages the state and recovery of the request for the life of its processing.
173 * The server to wait on
174 * @param desiredStates
175 * A variable list of desired states, any one of which is allowed.
176 * @throws RequestFailedException
177 * If the request times out or fails for some reason
178 * @throws NotLoggedInException
180 @SuppressWarnings("nls")
181 protected void waitForStateChange(RequestContext rc, Image image, Image.Status... desiredStates)
182 throws RequestFailedException, NotLoggedInException {
183 int pollInterval = configuration.getIntegerProperty(Constants.PROPERTY_OPENSTACK_POLL_INTERVAL);
184 int timeout = configuration.getIntegerProperty(Constants.PROPERTY_SERVER_STATE_CHANGE_TIMEOUT);
185 Context context = image.getContext();
186 Provider provider = context.getProvider();
187 ImageService service = context.getImageService();
190 long endTime = System.currentTimeMillis() + (timeout * 1000); //
192 while (rc.attempt()) {
195 image.waitForStateChange(pollInterval, timeout, desiredStates);
197 } catch (TimeoutException e) {
198 @SuppressWarnings("MismatchedQueryAndUpdateOfCollection")
199 List<String> list = new ArrayList<>();
200 for (Image.Status desiredState : desiredStates) {
201 list.add(desiredState.name());
203 msg = EELFResourceManager.format(Msg.CONNECTION_FAILED_RETRY, provider.getName(), service.getURL(),
204 context.getTenant().getName(), context.getTenant().getId(), e.getMessage(),
205 Long.toString(rc.getRetryDelay()), Integer.toString(rc.getAttempts()),
206 Integer.toString(rc.getRetryLimit()));
207 logger.error(msg, e);
210 } catch (ZoneException e) {
211 List<String> list = new ArrayList<>();
212 for (Image.Status desiredState : desiredStates) {
213 list.add(desiredState.name());
215 String reason = EELFResourceManager.format(Msg.STATE_CHANGE_EXCEPTION, e.getClass().getSimpleName(),
216 "server", image.getName(), image.getId(), StringHelper.asList(list), image.getStatus().name(),
218 logger.error(reason);
219 logger.error(EELFResourceManager.format(e));
221 // Instead of failing we are going to wait and try again.
222 // Timeout is reduced by delay time
223 logger.info(String.format("Retrying in %ds", rc.getRetryDelay()));
225 timeout = (int) (endTime - System.currentTimeMillis()) / 1000;
226 // throw new RequestFailedException(e, operation, reason,
227 // HttpStatus.BAD_GATEWAY_502, server);
232 msg = EELFResourceManager.format(Msg.CONNECTION_FAILED, provider.getName(), service.getURL());
234 throw new RequestFailedException("Waiting for State Change", msg, HttpStatus.BAD_GATEWAY_502, new Server());
241 * Enter a pool-wait loop checking the server state to see if it has entered one of the desired states or not.
243 * This method checks the state of the server periodically for one of the desired states. When the server enters one
244 * of the desired states, the method returns a successful indication (true). If the server never enters one of the
245 * desired states within the allocated timeout period, then the method returns a failed response (false). No
246 * exceptions are thrown from this method.
250 * The request context that manages the state and recovery of the request for the life of its processing.
252 * The server to wait on
253 * @param desiredStates
254 * A variable list of desired states, any one of which is allowed.
255 * @throws RequestFailedException
256 * If the request times out or fails for some reason
258 @SuppressWarnings("nls")
259 protected void waitForStateChange(RequestContext rc, Server server, Server.Status... desiredStates)
260 throws RequestFailedException {
261 int pollInterval = configuration.getIntegerProperty(Constants.PROPERTY_OPENSTACK_POLL_INTERVAL);
262 int timeout = configuration.getIntegerProperty(Constants.PROPERTY_SERVER_STATE_CHANGE_TIMEOUT);
263 Context context = server.getContext();
264 Provider provider = context.getProvider();
265 ComputeService service = context.getComputeService();
268 long endTime = System.currentTimeMillis() + (timeout * 1000); //
270 while (rc.attempt()) {
273 server.waitForStateChange(pollInterval, timeout, desiredStates);
275 } catch (TimeoutException e) {
276 @SuppressWarnings("MismatchedQueryAndUpdateOfCollection")
277 List<String> list = new ArrayList<>();
278 for (Server.Status desiredState : desiredStates) {
279 list.add(desiredState.name());
281 msg = EELFResourceManager.format(Msg.CONNECTION_FAILED_RETRY, provider.getName(), service.getURL(),
282 context.getTenant().getName(), context.getTenant().getId(), e.getMessage(),
283 Long.toString(rc.getRetryDelay()), Integer.toString(rc.getAttempts()),
284 Integer.toString(rc.getRetryLimit()));
285 logger.error(msg, e);
288 } catch (ZoneException e) {
289 List<String> list = new ArrayList<>();
290 for (Server.Status desiredState : desiredStates) {
291 list.add(desiredState.name());
293 String reason = EELFResourceManager.format(Msg.STATE_CHANGE_EXCEPTION, e.getClass().getSimpleName(),
294 "server", server.getName(), server.getId(), StringHelper.asList(list), server.getStatus().name(),
296 logger.error(reason);
297 logger.error(EELFResourceManager.format(e));
299 // Instead of failing we are going to wait and try again.
300 // Timeout is reduced by delay time
301 logger.info(String.format("Retrying in %ds", rc.getRetryDelay()));
303 timeout = (int) (endTime - System.currentTimeMillis()) / 1000;
304 // throw new RequestFailedException(e, operation, reason,
305 // HttpStatus.BAD_GATEWAY_502, server);
310 msg = EELFResourceManager.format(Msg.CONNECTION_FAILED, provider.getName(), service.getURL());
312 throw new RequestFailedException("Waiting for State Change", msg, HttpStatus.BAD_GATEWAY_502, server);
318 * Stop the specified server and wait for it to stop
321 * The request context that manages the state and recovery of the request for the life of its processing.
323 * The server to be stopped
324 * @throws ZoneException
325 * @throws RequestFailedException
327 @SuppressWarnings("nls")
328 protected void stopServer(RequestContext rc, Server server) throws ZoneException, RequestFailedException {
329 logger.debug(Msg.STOP_SERVER, server.getId());
332 Context context = server.getContext();
333 Provider provider = context.getProvider();
334 ComputeService service = context.getComputeService();
335 while (rc.attempt()) {
339 } catch (ContextConnectionException e) {
340 msg = EELFResourceManager.format(Msg.CONNECTION_FAILED_RETRY, provider.getName(), service.getURL(),
341 context.getTenant().getName(), context.getTenant().getId(), e.getMessage(),
342 Long.toString(rc.getRetryDelay()), Integer.toString(rc.getAttempts()),
343 Integer.toString(rc.getRetryLimit()));
344 logger.error(msg, e);
349 msg = EELFResourceManager.format(Msg.CONNECTION_FAILED, provider.getName(), service.getURL());
351 throw new RequestFailedException("Stop Server", msg, HttpStatus.BAD_GATEWAY_502, server);
354 waitForStateChange(rc, server, Server.Status.READY, Server.Status.ERROR);
358 * Start the server and wait for it to enter a running state
361 * The request context that manages the state and recovery of the request for the life of its processing.
363 * The server to be started
364 * @throws ZoneException
365 * @throws RequestFailedException
367 @SuppressWarnings("nls")
368 protected void startServer(RequestContext rc, Server server) throws ZoneException, RequestFailedException {
369 logger.debug(Msg.START_SERVER, server.getId());
371 Context context = server.getContext();
372 Provider provider = context.getProvider();
373 ComputeService service = context.getComputeService();
374 while (rc.attempt()) {
378 } catch (ContextConnectionException e) {
379 msg = EELFResourceManager.format(Msg.CONNECTION_FAILED_RETRY, provider.getName(), service.getURL(),
380 context.getTenant().getName(), context.getTenant().getId(), e.getMessage(),
381 Long.toString(rc.getRetryDelay()), Integer.toString(rc.getAttempts()),
382 Integer.toString(rc.getRetryLimit()));
383 logger.error(msg, e);
388 msg = EELFResourceManager.format(Msg.CONNECTION_FAILED, provider.getName(), service.getURL());
390 throw new RequestFailedException("Start Server", msg, HttpStatus.BAD_GATEWAY_502, server);
393 waitForStateChange(rc, server, Server.Status.RUNNING);
398 * Un-Pause a paused server and wait for it to enter a running state
401 * The request context that manages the state and recovery of the request for the life of its processing.
403 * The server to be un-paused
404 * @throws ZoneException
405 * @throws RequestFailedException
407 @SuppressWarnings("nls")
408 protected void unpauseServer(RequestContext rc, Server server) throws ZoneException, RequestFailedException {
409 logger.debug(Msg.UNPAUSE_SERVER, server.getId());
412 Context context = server.getContext();
413 Provider provider = context.getProvider();
414 ComputeService service = context.getComputeService();
415 while (rc.attempt()) {
419 } catch (ContextConnectionException e) {
420 msg = EELFResourceManager.format(Msg.CONNECTION_FAILED_RETRY, provider.getName(), service.getURL(),
421 context.getTenant().getName(), context.getTenant().getId(), e.getMessage(),
422 Long.toString(rc.getRetryDelay()), Integer.toString(rc.getAttempts()),
423 Integer.toString(rc.getRetryLimit()));
424 logger.error(msg, e);
429 msg = EELFResourceManager.format(Msg.CONNECTION_FAILED, provider.getName(), service.getURL());
431 throw new RequestFailedException("Unpause Server", msg, HttpStatus.BAD_GATEWAY_502, server);
434 waitForStateChange(rc, server, Server.Status.RUNNING, Server.Status.READY);
439 * Generates the event indicating what happened
442 * The request context that manages the state and recovery of the request for the life of its processing.
444 * True if the event represents a successful outcome
446 * The detailed message
448 protected void generateEvent(@SuppressWarnings("unused") RequestContext rc, @SuppressWarnings("unused") boolean success, @SuppressWarnings("unused") String msg) {
449 // indication to the DG to generate the event?
453 * Checks if the VM is connected to the Virtual Network and reachable
456 * The request context that manages the state and recovery of the request for the life of its processing.
458 * The server object representing the server we want to operate on
460 * The interface cloud service provider to access services or the object model, or both
463 protected void checkVirtualMachineNetworkStatus(RequestContext rc, Server server, Context context)
464 throws ZoneException, RequestFailedException {
466 logger.info("Performing the VM Server networking status checks...");
467 List<Port> ports = server.getPorts();
469 NetworkService netSvc = context.getNetworkService();
472 for (Port port : ports) {
474 switch (port.getPortState().toString().toUpperCase()) {
476 * The port is connected, configured, and usable for communication
479 Network network = netSvc.getNetworkById(port.getNetwork());
480 // Subnet subnet = netSvc.getSubnetById(port.getSubnetId());
481 if (!network.getStatus().equals(Network.Status.ACTIVE.toString())) {
482 msg = EELFResourceManager.format(Msg.SERVER_NETWORK_ERROR, server.getName(), port.getId());
484 doFailure(rc, HttpStatus.PRECONDITION_FAILED_412, msg);
485 throw new RequestFailedException("VM Server Network is DOWN", msg.toString(), HttpStatus.PRECONDITION_FAILED_412,
491 * The port is disconnected or powered-off and cannot be used for
495 msg = EELFResourceManager.format(Msg.SERVER_NETWORK_ERROR, server.getName(), port.getId());
497 doFailure(rc, HttpStatus.PRECONDITION_FAILED_412, msg);
498 throw new RequestFailedException("VM Server Port status is OFFLINE", msg.toString(), HttpStatus.PRECONDITION_FAILED_412,
502 * The port's status is changing because of some event or operation.
503 * The final state is yet to be determined.
506 msg = EELFResourceManager.format(Msg.SERVER_NETWORK_ERROR, server.getName(), port.getId());
508 doFailure(rc, HttpStatus.PRECONDITION_FAILED_412, msg);
509 throw new RequestFailedException("VM Server Port status is PENDING", msg.toString(), HttpStatus.PRECONDITION_FAILED_412,
513 * The port is in an unknown state and cannot be used.
516 msg = EELFResourceManager.format(Msg.SERVER_NETWORK_ERROR, server.getName(), port.getId());
518 doFailure(rc, HttpStatus.PRECONDITION_FAILED_412, msg);
519 throw new RequestFailedException("VM Server Port status is UNKNOWN", msg.toString(), HttpStatus.PRECONDITION_FAILED_412,
524 logger.info("Passed the VM Server the Hypervisor status checks..");
529 * Checks if the VM is connected to the Virtual Network and reachable
532 * The server object representing the server we want to operate on
534 protected void checkHypervisor(Server server)
535 throws ZoneException, RequestFailedException {
537 logger.info("Performing the Hypervisor status checks..");
538 String status = null, state = null, msg = null;
540 status = server.getHypervisor().getStatus().toString();
541 state = server.getHypervisor().getState().toString();
543 if (!status.equals(Hypervisor.Status.ENABLED.toString()) || !state.equals(Hypervisor.State.UP.toString())) {
544 msg = EELFResourceManager.format(Msg.HYPERVISOR_DOWN_ERROR, server.getHypervisor().getHostName(), server.getName());
545 logger.error(msg.toString());
547 //doFailure(rc, HttpStatus.PRECONDITION_FAILED_412, msg);
548 throw new RequestFailedException("Hypervisor status DOWN or NOT ENABLED", msg.toString(), HttpStatus.PRECONDITION_FAILED_412,
553 logger.info("Passed the Hypervisor status checks..");
558 * Checks if a Host machine is reachable
561 * IP Address of the Host Machine.
563 * The server object representing the Virtual Machine server
567 /*private boolean isHostReachable(String ipAddress) throws IOException {
569 InetAddress address = InetAddress.getByName(ipAddress);
571 return address.isReachable(15000);