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