Merge "Reorder modifiers"
[so.git] / adapters / mso-tenant-adapter / src / main / java / org / openecomp / mso / adapters / tenant / MsoTenantAdapterImpl.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP - SO
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  * 
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  * 
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END=========================================================
19  */
20
21 package org.openecomp.mso.adapters.tenant;
22
23
24 import java.util.Map;
25
26 import javax.annotation.Resource;
27 import javax.jws.WebService;
28 import javax.xml.ws.Holder;
29 import javax.xml.ws.WebServiceContext;
30
31 import org.openecomp.mso.openstack.exceptions.MsoCloudSiteNotFound;
32 import org.openecomp.mso.properties.MsoPropertiesFactory;
33 import org.openecomp.mso.adapters.tenant.exceptions.TenantAlreadyExists;
34 import org.openecomp.mso.adapters.tenant.exceptions.TenantException;
35 import org.openecomp.mso.adapters.tenantrest.TenantRollback;
36 import org.openecomp.mso.entity.MsoRequest;
37 import org.openecomp.mso.logger.MessageEnum;
38 import org.openecomp.mso.logger.MsoLogger;
39 import org.openecomp.mso.openstack.beans.MsoTenant;
40 import org.openecomp.mso.openstack.exceptions.MsoException;
41 import org.openecomp.mso.openstack.utils.MsoTenantUtils;
42 import org.openecomp.mso.openstack.utils.MsoTenantUtilsFactory;
43
44 @WebService(serviceName = "TenantAdapter", endpointInterface = "org.openecomp.mso.adapters.tenant.MsoTenantAdapter", targetNamespace = "http://org.openecomp.mso/tenant")
45 public class MsoTenantAdapterImpl implements MsoTenantAdapter {
46
47         MsoPropertiesFactory msoPropertiesFactory = new MsoPropertiesFactory();
48         MsoTenantUtilsFactory tFactory = new MsoTenantUtilsFactory(MSO_PROP_TENANT_ADAPTER);
49         
50         public static final String MSO_PROP_TENANT_ADAPTER="MSO_PROP_TENANT_ADAPTER";
51         public static final String CREATE_TENANT = "CreateTenant";
52     public static final String OPENSTACK = "OpenStack";
53     public static final String QUERY_TENANT = "QueryTenant";
54     public static final String DELETE_TENANT = "DeleteTenant";
55     public static final String ROLLBACK_TENANT = "RollbackTenant";
56         
57     @Resource
58     WebServiceContext wsContext;
59
60     private static MsoLogger logger = MsoLogger.getMsoLogger (MsoLogger.Catalog.RA);
61
62     protected MsoTenantUtilsFactory getTenantUtilsFactory() {
63         return tFactory;
64     }
65
66     /**
67      * Health Check web method. Does nothing but return to show the adapter is deployed.
68      */
69     @Override
70     public void healthCheck () {
71         logger.debug ("Health check call in Tenant Adapter");
72     }
73
74     /**
75      * This is the "Create Tenant" web service implementation. It will create
76      * a new Tenant in the specified cloud. If the tenant already exists, this
77      * can be considered a success or failure, depending on the value of the
78      * 'failIfExists' parameter.
79      *
80      * The method returns the tenantId (the Openstack ID), and a TenantRollback
81      * object. This last object can be passed as-is to the rollbackTenant method
82      * to undo what (if anything) was created. This is useful if a Tenant is
83      * successfully created but the orchestrator fails on a subsequent operation.
84      */
85     @Override
86     public void createTenant (String cloudSiteId,
87                               String tenantName,
88                               Map <String, String> metadata,
89                               Boolean failIfExists,
90                               Boolean backout,
91                               MsoRequest msoRequest,
92                               Holder <String> tenantId,
93                               Holder <TenantRollback> rollback) throws TenantException {
94         MsoLogger.setLogContext (msoRequest);
95         MsoLogger.setServiceName (CREATE_TENANT);
96
97         logger.debug ("Call to MSO createTenant adapter. Creating Tenant: " + tenantName
98                                       + "in "
99                                       + cloudSiteId);
100
101         // Will capture total time for metrics
102         long startTime = System.currentTimeMillis ();
103
104         // Start building up rollback object
105         TenantRollback tenantRollback = new TenantRollback ();
106         tenantRollback.setCloudId (cloudSiteId);
107         tenantRollback.setMsoRequest (msoRequest);
108
109         MsoTenantUtils tUtils;
110         MsoTenant newTenant = null;
111         String newTenantId;
112         long queryTenantStartTime = System.currentTimeMillis ();
113         try {
114             tUtils = tFactory.getTenantUtils (cloudSiteId);
115             newTenant = tUtils.queryTenantByName (tenantName, cloudSiteId);
116             logger.recordMetricEvent (queryTenantStartTime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc, "Successfully received response from Open Stack", OPENSTACK, QUERY_TENANT, null);
117
118         } catch (MsoException me) {
119             logger.recordMetricEvent (queryTenantStartTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.CommunicationError, "Exception while communicate with Open Stack", OPENSTACK, QUERY_TENANT, null);
120             String error = "Create Tenant " + tenantName + ": " + me;
121             logger.error (MessageEnum.RA_CREATE_TENANT_ERR, me.getMessage(), OPENSTACK, "createTenant", MsoLogger.ErrorCode.DataError, "Exception while communicate with Open Stack", me);
122             logger.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.CommunicationError, error);
123             throw new TenantException (me);
124         }
125         if (newTenant == null) {
126             if (backout == null)
127                 backout = true;
128             long createTenantStartTime = System.currentTimeMillis ();
129             try {
130                 newTenantId = tUtils.createTenant (tenantName, cloudSiteId, metadata, backout.booleanValue ());
131                 logger.recordMetricEvent (createTenantStartTime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc, "Successfully received response from Open Stack", OPENSTACK, CREATE_TENANT, null);
132             } catch (MsoException me) {
133                 logger.recordMetricEvent (createTenantStartTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.CommunicationError, "Exception while communicate with Open Stack", OPENSTACK, CREATE_TENANT, null);
134                 String error = "Create Tenant " + tenantName + ": " + me;
135                 logger.error (MessageEnum.RA_CREATE_TENANT_ERR, me.getMessage(), OPENSTACK, "createTenant", MsoLogger.ErrorCode.DataError, "Exception while communicate with Open Stack", me);
136                 logger.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.CommunicationError, error);
137                 throw new TenantException (me);
138             }
139             tenantRollback.setTenantId (newTenantId);
140             tenantRollback.setTenantCreated (true);
141             logger.debug ("Tenant " + tenantName + " successfully created with ID " + newTenantId);
142         } else {
143             if (failIfExists != null && failIfExists) {
144                 String error = CREATE_TENANT + ": Tenant " + tenantName + " already exists in " + cloudSiteId;
145                 logger.error (MessageEnum.RA_TENANT_ALREADY_EXIST, tenantName, cloudSiteId, OPENSTACK, "", MsoLogger.ErrorCode.DataError, CREATE_TENANT + ", Tenant already exists");
146                 logger.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.DataError, error);
147                 throw new TenantAlreadyExists (tenantName, cloudSiteId, newTenant.getTenantId ());
148             }
149
150             newTenantId = newTenant.getTenantId ();
151             tenantRollback.setTenantCreated (false);
152             logger.debug ("Tenant " + tenantName + " already exists with ID " + newTenantId);
153         }
154
155
156         tenantId.value = newTenantId;
157         rollback.value = tenantRollback;
158         logger.recordAuditEvent (startTime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc, "Successfully create tenant");
159         return;
160     }
161
162     @Override
163     public void queryTenant (String cloudSiteId,
164                              String tenantNameOrId,
165                              MsoRequest msoRequest,
166                              Holder <String> tenantId,
167                              Holder <String> tenantName,
168                              Holder <Map <String, String>> metadata) throws TenantException {
169         MsoLogger.setLogContext (msoRequest);
170         MsoLogger.setServiceName (QUERY_TENANT);
171         logger.debug ("Querying Tenant " + tenantNameOrId + " in " + cloudSiteId);
172
173         // Will capture execution time for metrics
174         long startTime = System.currentTimeMillis ();
175
176         MsoTenantUtils tUtils = null;
177         MsoTenant qTenant = null;
178         long subStartTime = System.currentTimeMillis ();
179         try {
180             tUtils = tFactory.getTenantUtils (cloudSiteId);
181             qTenant = tUtils.queryTenant (tenantNameOrId, cloudSiteId);
182             logger.recordMetricEvent (subStartTime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc, "Successfully received response from Open Stack", OPENSTACK, QUERY_TENANT, null);
183             if (qTenant == null) {
184                 // Not found by ID, Try by name.
185                 qTenant = tUtils.queryTenantByName (tenantNameOrId, cloudSiteId);
186             }
187
188             if (qTenant == null) {
189                 logger.debug ("QueryTenant: Tenant " + tenantNameOrId + " not found");
190                 tenantId.value = null;
191                 tenantName.value = null;
192                 metadata.value = null;
193             } else {
194                 logger.debug ("QueryTenant: Tenant " + tenantNameOrId + " found with ID " + qTenant.getTenantId ());
195                 tenantId.value = qTenant.getTenantId ();
196                 tenantName.value = qTenant.getTenantName ();
197                 metadata.value = qTenant.getMetadata ();
198             }
199         } catch (MsoException me) {
200             String error = "Query Tenant " + tenantNameOrId + ": " + me;
201             logger.recordMetricEvent (subStartTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.CommunicationError, error, OPENSTACK, QUERY_TENANT, null);
202             logger.error (MessageEnum.RA_GENERAL_EXCEPTION, me.getMessage(), OPENSTACK, "", MsoLogger.ErrorCode.DataError, "Exception in queryTenant", me);
203             logger.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.CommunicationError, error);
204             throw new TenantException (me);
205         }
206         logger.recordAuditEvent (startTime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc, "Successfully query tenant");
207         return;
208     }
209
210     @Override
211     public void deleteTenant (String cloudSiteId,
212                               String tenantId,
213                               MsoRequest msoRequest,
214                               Holder <Boolean> tenantDeleted) throws TenantException {
215         MsoLogger.setLogContext (msoRequest);
216         MsoLogger.setServiceName (DELETE_TENANT);
217
218         logger.debug ("Deleting Tenant " + tenantId + " in " + cloudSiteId);
219
220         // Will capture execution time for metrics
221         long startTime = System.currentTimeMillis ();
222
223         // Delete the Tenant.
224         long subStartTime = System.currentTimeMillis ();
225         try {
226                 
227                 MsoTenantUtils tUtils = tFactory.getTenantUtils (cloudSiteId);
228             boolean deleted = tUtils.deleteTenant (tenantId, cloudSiteId);
229             tenantDeleted.value = deleted;
230             logger.recordMetricEvent (subStartTime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc, "Successfully communicate with Open Stack", OPENSTACK, DELETE_TENANT, null);
231         } catch (MsoException me) {
232             String error = "Delete Tenant " + tenantId + ": " + me;
233             logger.recordMetricEvent (subStartTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.CommunicationError, error, OPENSTACK, DELETE_TENANT, null);
234             logger.error (MessageEnum.RA_DELETE_TEMAMT_ERR, me.getMessage(), OPENSTACK, "", MsoLogger.ErrorCode.DataError, "Exception - DeleteTenant", me);
235             logger.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.CommunicationError, error);
236             throw new TenantException (me);
237         }
238
239         // On success, nothing is returned.
240         logger.recordAuditEvent (startTime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc, "Successfully delete tenant");
241         return;
242     }
243
244     /**
245      * This web service endpoint will rollback a previous Create VNF operation.
246      * A rollback object is returned to the client in a successful creation
247      * response. The client can pass that object as-is back to the rollbackVnf
248      * operation to undo the creation.
249      *
250      * The rollback includes removing the VNF and deleting the tenant if the
251      * tenant did not exist prior to the VNF creation.
252      */
253     @Override
254     public void rollbackTenant (TenantRollback rollback) throws TenantException {
255         long startTime = System.currentTimeMillis ();
256         MsoLogger.setServiceName (ROLLBACK_TENANT);
257         // rollback may be null (e.g. if stack already existed when Create was called)
258         if (rollback == null) {
259             logger.warn (MessageEnum.RA_ROLLBACK_NULL, OPENSTACK, "rollbackTenant", MsoLogger.ErrorCode.DataError, "rollbackTenant, rollback is null");
260             return;
261         }
262
263         // Get the elements of the VnfRollback object for easier access
264         String cloudSiteId = rollback.getCloudId ();
265         String tenantId = rollback.getTenantId ();
266
267         MsoLogger.setLogContext (rollback.getMsoRequest ());
268         logger.debug ("Rolling Back Tenant " + rollback.getTenantId () + " in " + cloudSiteId);
269
270         long subStartTime = System.currentTimeMillis ();
271         if (rollback.getTenantCreated ()) {
272             try {
273                  
274                 MsoTenantUtils tUtils = tFactory.getTenantUtils (cloudSiteId);
275                 tUtils.deleteTenant (tenantId, cloudSiteId);
276                 logger.recordMetricEvent (subStartTime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc, "Successfully communicate with Open Stack", OPENSTACK, ROLLBACK_TENANT, null);
277             } catch (MsoException me) {
278                 me.addContext (ROLLBACK_TENANT);
279                 // Failed to delete the tenant.
280                 String error = "Rollback Tenant " + tenantId + ": " + me;
281                 logger.recordMetricEvent (subStartTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.CommunicationError, error, OPENSTACK, ROLLBACK_TENANT, null);
282                 logger.error (MessageEnum.RA_ROLLBACK_TENANT_ERR, me.getMessage(), OPENSTACK, "rollbackTenant", MsoLogger.ErrorCode.DataError, "Exception - rollbackTenant", me);
283                 logger.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.CommunicationError, error);
284                 throw new TenantException (me);
285             }
286         }
287         logger.recordAuditEvent (startTime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc, "Successfully roll back tenant");
288         return;
289     }
290 }