aboutsummaryrefslogtreecommitdiffstats
path: root/src/main/java/org/onap/aai/migration/v12/MigrateServiceInstanceToConfiguration.java
blob: b4208af9d96db2977a579b760eb1089d123832a6 (plain)
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
/**
 * ============LICENSE_START=======================================================
 * org.onap.aai
 * ================================================================================
 * Copyright © 2017-2018 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.onap.aai.migration.v12;

import java.io.UnsupportedEncodingException;
import java.util.Iterator;
import java.util.Optional;
import java.util.UUID;

import org.apache.tinkerpop.gremlin.process.traversal.P;
import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal;
import org.apache.tinkerpop.gremlin.structure.Direction;
import org.apache.tinkerpop.gremlin.structure.Vertex;
import org.onap.aai.db.props.AAIProperties;
import org.onap.aai.edges.EdgeIngestor;
import org.onap.aai.exceptions.AAIException;
import org.onap.aai.introspection.Introspector;
import org.onap.aai.introspection.LoaderFactory;
import org.onap.aai.introspection.exceptions.AAIUnknownObjectException;
import org.onap.aai.migration.MigrationDangerRating;
import org.onap.aai.migration.MigrationPriority;
import org.onap.aai.migration.Migrator;
import org.onap.aai.migration.Status;
import org.onap.aai.edges.enums.EdgeType;
import org.onap.aai.serialization.db.EdgeSerializer;
import org.onap.aai.serialization.engines.TransactionalGraphEngine;
import org.onap.aai.setup.SchemaVersions;

//@Enabled
@MigrationPriority(10)
@MigrationDangerRating(10)
public class MigrateServiceInstanceToConfiguration extends Migrator {

	private boolean success = true;
	private final String CONFIGURATION_NODE_TYPE = "configuration";
	private final String SERVICE_INSTANCE_NODE_TYPE = "service-instance";
	private Introspector configObj;

	public MigrateServiceInstanceToConfiguration(TransactionalGraphEngine engine, LoaderFactory loaderFactory, EdgeIngestor edgeIngestor, EdgeSerializer edgeSerializer, SchemaVersions schemaVersions) {
		super(engine, loaderFactory, edgeIngestor, edgeSerializer, schemaVersions);
		try {
			this.configObj = this.loader.introspectorFromName(CONFIGURATION_NODE_TYPE);
		} catch (AAIUnknownObjectException e) {
			this.configObj = null;
		}
	}

	@Override
	public void run() {		
		Vertex serviceInstance = null;
		Vertex configuration = null;
		String serviceInstanceId = "", tunnelBandwidth = "";
		String bandwidthTotal, configType, nodeType;
		GraphTraversal<Vertex, Vertex> serviceInstanceItr;
		Iterator<Vertex> configurationItr;

		try {
			serviceInstanceItr = this.engine.asAdmin().getTraversalSource().V()
					.has(AAIProperties.NODE_TYPE, P.within(getAffectedNodeTypes().get()))
					.where(this.engine.getQueryBuilder()
							.createEdgeTraversal(EdgeType.TREE, "service-instance", "service-subscription")
							.getVerticesByProperty("service-type", "DHV")
							.<GraphTraversal<?, ?>>getQuery());

			if (serviceInstanceItr == null || !serviceInstanceItr.hasNext()) {
				logger.info("No servince-instance nodes found with service-type of DHV");
				return;
			}

			// iterate through all service instances of service-type DHV
			while (serviceInstanceItr.hasNext()) {
				serviceInstance = serviceInstanceItr.next();

				if (serviceInstance != null && serviceInstance.property("bandwidth-total").isPresent()) {
					serviceInstanceId = serviceInstance.value("service-instance-id");
					logger.info("Processing service instance with id=" + serviceInstanceId);
					bandwidthTotal = serviceInstance.value("bandwidth-total");

					if (bandwidthTotal != null && !bandwidthTotal.isEmpty()) {

						// check for existing edges to configuration nodes 
						configurationItr = serviceInstance.vertices(Direction.OUT, "has");

						// create new configuration node if service-instance does not have existing ones
						if (!configurationItr.hasNext()) {
							logger.info(serviceInstanceId + " has no existing configuration nodes, creating new node");
							createConfigurationNode(serviceInstance, bandwidthTotal);
							continue;
						}

						// in case if configuration nodes exist, but none are DHV
						boolean hasDHVConfig = false;

						// service-instance has existing configuration nodes
						while (configurationItr.hasNext()) {
							configuration = configurationItr.next();
							nodeType = configuration.value("aai-node-type").toString();

							if (configuration != null && "configuration".equalsIgnoreCase(nodeType)) {
								logger.info("Processing configuration node with id=" + configuration.property("configuration-id").value());
								configType = configuration.value("configuration-type");
								logger.info("Configuration type: " + configType);

								// if configuration-type is DHV, update tunnel-bandwidth to bandwidth-total value
								if ("DHV".equalsIgnoreCase(configType)) {
									if (configuration.property("tunnel-bandwidth").isPresent()) {
										tunnelBandwidth = configuration.value("tunnel-bandwidth");
									} else {
										tunnelBandwidth = "";
									}

									logger.info("Existing tunnel-bandwidth: " + tunnelBandwidth);
									configuration.property("tunnel-bandwidth", bandwidthTotal);
									touchVertexProperties(configuration, false);
									logger.info("Updated tunnel-bandwidth: " + configuration.value("tunnel-bandwidth"));
									hasDHVConfig = true;
								}
							}
						}

						// create new configuration node if none of existing config nodes are of type DHV 
						if (!hasDHVConfig) {
							logger.info(serviceInstanceId + " has existing configuration nodes, but none are DHV, create new node");
							createConfigurationNode(serviceInstance, bandwidthTotal);
						}
					}
				}
			}
		} catch (AAIException | UnsupportedEncodingException e) {
			logger.error("Caught exception while processing service instance with id=" + serviceInstanceId + " | " + e.toString());
			success = false;
		}
	}

	private void createConfigurationNode(Vertex serviceInstance, String bandwidthTotal) throws UnsupportedEncodingException, AAIException {
		// create new vertex
		Vertex configurationNode = serializer.createNewVertex(configObj);

		// configuration-id: UUID format
		String configurationUUID = UUID.randomUUID().toString();
		configObj.setValue("configuration-id", configurationUUID);

		// configuration-type: DHV
		configObj.setValue("configuration-type", "DHV");

		// migrate the bandwidth-total property from the service-instance to the 
		// tunnel-bandwidth property of the related configuration object
		configObj.setValue("tunnel-bandwidth", bandwidthTotal);

		// create edge between service instance and configuration: cousinEdge(out, in)
		createCousinEdge(serviceInstance, configurationNode);

		// serialize edge & vertex, takes care of everything
		serializer.serializeSingleVertex(configurationNode, configObj, "migrations");
		logger.info("Created configuration node with uuid=" + configurationUUID + ", tunnel-bandwidth=" + bandwidthTotal);
	}

	@Override
	public Status getStatus() {
		if (success) {
			return Status.SUCCESS;
		} else {
			return Status.FAILURE;
		}
	}

	@Override
	public Optional<String[]> getAffectedNodeTypes() {
		return Optional.of(new String[] {SERVICE_INSTANCE_NODE_TYPE});
	}

	@Override
	public String getMigrationName() {
		return "service-instance-to-configuration";
	}
}