Merge "remove unneeded code"
diff --git a/bpmn/MSOCommonBPMN/src/test/java/org/onap/so/client/dmaapproperties/DmaapPropertiesClientTest.java b/bpmn/MSOCommonBPMN/src/test/java/org/onap/so/client/dmaapproperties/DmaapPropertiesClientTest.java
index c50a6db..886025c 100644
--- a/bpmn/MSOCommonBPMN/src/test/java/org/onap/so/client/dmaapproperties/DmaapPropertiesClientTest.java
+++ b/bpmn/MSOCommonBPMN/src/test/java/org/onap/so/client/dmaapproperties/DmaapPropertiesClientTest.java
@@ -20,27 +20,30 @@
 
 package org.onap.so.client.dmaapproperties;
 
-import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
-import static com.github.tomakehurst.wiremock.client.WireMock.post;
-import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo;
 import static com.shazam.shazamcrest.matcher.Matchers.sameBeanAs;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertThat;
-import static org.junit.Assert.assertTrue;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
 
 import java.io.File;
 import java.io.IOException;
 
-import org.apache.http.HttpStatus;
+import org.junit.Before;
 import org.junit.Test;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+import org.onap.so.BaseTest;
 import org.onap.so.client.avpn.dmaap.beans.AVPNDmaapBean;
 import org.onap.so.client.exception.MapperException;
-import org.onap.so.BaseTest;
+import org.onap.so.client.dmaapproperties.GlobalDmaapPublisher;
 import org.springframework.beans.factory.annotation.Autowired;
 
 import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fasterxml.jackson.databind.ObjectMapper;
-import static com.github.tomakehurst.wiremock.client.WireMock.*;
 
 public class DmaapPropertiesClientTest extends BaseTest{
 	
@@ -75,10 +78,24 @@
 
 	@Test
 	public void testDmaapPublishRequest() throws JsonProcessingException, MapperException {
-		stubFor(post(urlEqualTo("/events/com.att.mso.asyncStatusUpdate?timeout=60000"))
-				.willReturn(aResponse().withHeader("Content-Type", "application/json").withStatus(HttpStatus.SC_ACCEPTED)));
-
-		dmaapPropertiesClient.dmaapPublishRequest(requestId, clientSource, correlator, serviceInstanceId, startTime, finishTime, requestScope,
-													requestType, timestamp, requestState, statusMessage, percentProgress, false);
+		DmaapPropertiesClient client = Mockito.spy(DmaapPropertiesClient.class);
+		GlobalDmaapPublisher mockedClientDmaapPublisher = Mockito.mock(GlobalDmaapPublisher.class);
+		AVPNDmaapBean mockedDmaapBean = Mockito.mock(AVPNDmaapBean.class);
+		String request = "test";
+		
+		doReturn(mockedDmaapBean).when(client).buildRequestJson(requestId, clientSource, correlator, serviceInstanceId, startTime, finishTime, requestScope,
+				requestType, timestamp, requestState, statusMessage, percentProgress, false); 
+		
+		AVPNDmaapBean actualDmaapBean = client.buildRequestJson(requestId, clientSource, correlator, serviceInstanceId, startTime, finishTime, requestScope,
+				requestType, timestamp, requestState, statusMessage, percentProgress, false);
+		mockedClientDmaapPublisher.send(request);
+		
+		doNothing().when(mockedClientDmaapPublisher).send(anyString());
+		
+		verify(client, times(1)).buildRequestJson(requestId, clientSource, correlator, serviceInstanceId, startTime, 
+				finishTime, requestScope, requestType, timestamp, requestState, statusMessage, percentProgress, false);
+		verify(mockedClientDmaapPublisher, times(1)).send(request);
+		   
+		assertNotNull(actualDmaapBean);
 	}
 }
diff --git a/bpmn/MSOCommonBPMN/src/test/java/org/onap/so/client/dmaapproperties/GlobalDmaapPublisherTest.java b/bpmn/MSOCommonBPMN/src/test/java/org/onap/so/client/dmaapproperties/GlobalDmaapPublisherTest.java
index fc69f81..088b018 100644
--- a/bpmn/MSOCommonBPMN/src/test/java/org/onap/so/client/dmaapproperties/GlobalDmaapPublisherTest.java
+++ b/bpmn/MSOCommonBPMN/src/test/java/org/onap/so/client/dmaapproperties/GlobalDmaapPublisherTest.java
@@ -21,23 +21,27 @@
 package org.onap.so.client.dmaapproperties;
 
 import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
 
+import org.junit.BeforeClass;
 import org.junit.Test;
 import org.onap.so.BaseTest;
 import org.springframework.beans.factory.annotation.Autowired;
 
 public class GlobalDmaapPublisherTest extends BaseTest{
 
+	@BeforeClass
+	public static void setUp() throws Exception {
+		System.setProperty("mso.global.dmaap.host", "http://test:1234");
+	}
+    
 	@Autowired
 	private GlobalDmaapPublisher globalDmaapPublisher;
-
-
+	
 	@Test
 	public void testGetters() {
 		assertEquals("81B7E3533B91A6706830611FB9A8ECE529BBCCE754B1F1520FA7C8698B42F97235BEFA993A387E664D6352C63A6185D68DA7F0B1D360637CBA102CB166E3E62C11EB1F75386D3506BCECE51E54", globalDmaapPublisher.getAuth());
 		assertEquals("07a7159d3bf51a0e53be7a8f89699be7", globalDmaapPublisher.getKey());
 		assertEquals("com.att.mso.asyncStatusUpdate", globalDmaapPublisher.getTopic());
-		assertEquals("http://localhost:" + wireMockPort, globalDmaapPublisher.getHost().get());
+		assertEquals("http://test:1234", globalDmaapPublisher.getHost().get());
 	}
 }
diff --git a/bpmn/so-bpmn-infrastructure-common/src/main/java/org/onap/so/bpmn/infrastructure/workflow/service/ServicePluginFactory.java b/bpmn/so-bpmn-infrastructure-common/src/main/java/org/onap/so/bpmn/infrastructure/workflow/service/ServicePluginFactory.java
index 48c7863..477dc34 100644
--- a/bpmn/so-bpmn-infrastructure-common/src/main/java/org/onap/so/bpmn/infrastructure/workflow/service/ServicePluginFactory.java
+++ b/bpmn/so-bpmn-infrastructure-common/src/main/java/org/onap/so/bpmn/infrastructure/workflow/service/ServicePluginFactory.java
@@ -4,6 +4,8 @@
  * ================================================================================
  * Copyright (C) 2018 Huawei Intellectual Property. All rights reserved.
  * ================================================================================
+ * Modifications Copyright (c) 2019 Samsung
+ * ================================================================================
  * 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
@@ -127,7 +129,7 @@
 			return newRequest;
 		}
 
-		List<Resource> addResourceList = new ArrayList<Resource>();
+		List<Resource> addResourceList = new ArrayList<>();
 		addResourceList.addAll(serviceDecomposition.getServiceResources());
 		
 		serviceDecomposition.setVnfResources(null);
@@ -237,7 +239,7 @@
 		String url = getInventoryOSSEndPoint();
 		url += "/oss/inventory?location=" +  UriUtils.encode(locationAddress,"UTF-8");
 		String responseContent = sendRequest(url, "GET", "");
-		List<Object> accessTPs = new ArrayList<Object>();
+		List<Object> accessTPs = new ArrayList<>();
 		if (null != responseContent) {
 			accessTPs = getJsonObject(responseContent, List.class);
 		}
@@ -246,8 +248,8 @@
 	
 	@SuppressWarnings("unchecked")
 	private void putResourceRequestInputs(Map<String, Object> resource, Map<String, Object> resourceInputs) {
-		Map<String, Object> resourceParametersObject = new HashMap<String, Object>();
-		Map<String, Object> resourceRequestInputs = new HashMap<String, Object>();
+		Map<String, Object> resourceParametersObject = new HashMap<>();
+		Map<String, Object> resourceRequestInputs = new HashMap<>();
 		resourceRequestInputs.put("requestInputs", resourceInputs);
 		resourceParametersObject.put("parameters", resourceRequestInputs);
 
@@ -428,7 +430,6 @@
 	// this method check if pInterface is remote
 	private boolean isRemotePInterface(AAIResourcesClient client, AAIResourceUri uri) {
 		
-		Map<String, String> keys = uri.getURIKeys();
 		String uriString = uri.build().toString();
 
 		if (uriString != null) {
@@ -555,14 +556,14 @@
 	}
 
 	private List<Object> queryTerminalPointsFromServiceProviderSystem(String srcLocation, String dstLocation) {
-		Map<String, String> locationSrc = new HashMap<String, String>();
+		Map<String, String> locationSrc = new HashMap<>();
 		locationSrc.put("location", srcLocation);
-		Map<String, String> locationDst = new HashMap<String, String>();
+		Map<String, String> locationDst = new HashMap<>();
 		locationDst.put("location", dstLocation);
-		List<Map<String, String>> locations = new ArrayList<Map<String, String>>();
+		List<Map<String, String>> locations = new ArrayList<>();
 		locations.add(locationSrc);
 		locations.add(locationDst);
-		List<Object> returnList = new ArrayList<Object>();
+		List<Object> returnList = new ArrayList<>();
 		String reqContent = getJsonString(locations);
 		String url = getThirdSPEndPoint();
 		String responseContent = sendRequest(url, "POST", reqContent);
@@ -604,7 +605,7 @@
 		Map<String, Object> serviceObject = (Map<String, Object>) uuiObject.get("service");
 		Map<String, Object> serviceParametersObject = (Map<String, Object>) serviceObject.get("parameters");
 		Map<String, Object> serviceRequestInputs = (Map<String, Object>) serviceParametersObject.get("requestInputs");
-		Map<String, Object> oofQueryObject = new HashMap<String, Object>();
+		Map<String, Object> oofQueryObject = new HashMap<>();
 		List<Object> resources = (List<Object>) serviceParametersObject.get("resources");
 		oofQueryObject.put("src-access-provider-id", serviceRequestInputs.get("inner-src-access-provider-id"));
 		oofQueryObject.put("src-access-client-id", serviceRequestInputs.get("inner-src-access-client-id"));
@@ -620,7 +621,7 @@
 		String url = getOOFCalcEndPoint();
 		String responseContent = sendRequest(url, "POST", oofRequestReq);
 
-		List<Object> returnList = new ArrayList<Object>();
+		List<Object> returnList = new ArrayList<>();
 		if (null != responseContent) {
 			returnList = getJsonObject(responseContent, List.class);
 		}
@@ -635,7 +636,7 @@
 	}
 	
 	private Map<String, Object> getReturnRoute(List<Object> returnList){
-		Map<String, Object> returnRoute = new HashMap<String,Object>();
+		Map<String, Object> returnRoute = new HashMap<>();
 		for(Object returnVpn :returnList){
 			Map<String, Object> returnVpnInfo = (Map<String, Object>) returnVpn;
 		    String accessTopoId = (String)returnVpnInfo.get("access-topology-id");
@@ -664,11 +665,11 @@
 	private Map<String, Object> getResourceParams(Execution execution, String resourceCustomizationUuid,
 			String serviceParameters) {
 		List<String> resourceList = jsonUtil.StringArrayToList(execution,
-				(String) JsonUtils.getJsonValue(serviceParameters, "resources"));
+				JsonUtils.getJsonValue(serviceParameters, "resources"));
 		// Get the right location str for resource. default is an empty array.
 		String resourceInputsFromUui = "";
 		for (String resource : resourceList) {
-			String resCusUuid = (String) JsonUtils.getJsonValue(resource, "resourceCustomizationUuid");
+			String resCusUuid = JsonUtils.getJsonValue(resource, "resourceCustomizationUuid");
 			if (resourceCustomizationUuid.equals(resCusUuid)) {
 				String resourceParameters = JsonUtils.getJsonValue(resource, "parameters");
 				resourceInputsFromUui = JsonUtils.getJsonValue(resourceParameters, "requestInputs");
@@ -738,14 +739,6 @@
 				method = httpDelete;
 			}
 
-			// now have no auth
-			// String userCredentials =
-			// SDNCAdapterProperties.getEncryptedProperty(Constants.SDNC_AUTH_PROP,
-			// Constants.DEFAULT_SDNC_AUTH, Constants.ENCRYPTION_KEY);
-			// String authorization = "Basic " +
-			// DatatypeConverter.printBase64Binary(userCredentials.getBytes());
-			// method.setHeader("Authorization", authorization);
-
 			httpResponse = client.execute(method);
 			String responseContent = null;
 			if (null != httpResponse && httpResponse.getEntity() != null) {
diff --git a/common/src/main/java/org/onap/so/client/aai/AAIRestClient.java b/common/src/main/java/org/onap/so/client/aai/AAIRestClient.java
index a265119..30d1b04 100644
--- a/common/src/main/java/org/onap/so/client/aai/AAIRestClient.java
+++ b/common/src/main/java/org/onap/so/client/aai/AAIRestClient.java
@@ -27,20 +27,17 @@
 import javax.ws.rs.core.Response;
 
 import org.onap.so.client.ResponseExceptionMapper;
-import org.onap.so.client.RestClientSSL;
 import org.onap.so.client.graphinventory.GraphInventoryPatchConverter;
+import org.onap.so.client.graphinventory.GraphInventoryRestClient;
 import org.onap.so.client.policy.CommonObjectMapperProvider;
 import org.onap.so.utils.TargetEntity;
 
-public class AAIRestClient extends RestClientSSL {
+public class AAIRestClient extends GraphInventoryRestClient {
 
 	private final AAIProperties aaiProperties;
-	private static final AAICommonObjectMapperProvider standardProvider = new AAICommonObjectMapperProvider();
 
-	private final GraphInventoryPatchConverter patchConverter = new GraphInventoryPatchConverter();
-	
 	protected AAIRestClient(AAIProperties props, URI uri) {
-		super(props, Optional.of(uri));
+		super(props, uri);
 		this.aaiProperties = props;
 	}
 
@@ -67,27 +64,8 @@
 		return Optional.of(new AAIClientResponseExceptionMapper());
 	}
 	
-	@Override
-	protected CommonObjectMapperProvider getCommonObjectMapperProvider() {
-		return standardProvider;
-	}
-
-	@Override
-	public Response patch(Object obj) {
-		return super.patch(convertToPatchFormat(obj));
-	}
-
-	@Override
-	public <T> T patch(Object obj, Class<T> resultClass) {
-		return super.patch(convertToPatchFormat(obj), resultClass);
-	}
-	
 	protected GraphInventoryPatchConverter getPatchConverter() {
 		return this.patchConverter;
 	}
-	
-	protected String convertToPatchFormat(Object obj) {
-		return getPatchConverter().convertPatchFormat(obj);
-	}
 
 }
diff --git a/common/src/main/java/org/onap/so/client/aai/entities/AAIResultWrapper.java b/common/src/main/java/org/onap/so/client/aai/entities/AAIResultWrapper.java
index 9b3f98b..5ce81ce 100644
--- a/common/src/main/java/org/onap/so/client/aai/entities/AAIResultWrapper.java
+++ b/common/src/main/java/org/onap/so/client/aai/entities/AAIResultWrapper.java
@@ -26,7 +26,7 @@
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-public class AAIResultWrapper extends GraphInventoryResultWrapper implements Serializable {
+public class AAIResultWrapper extends GraphInventoryResultWrapper<Relationships> implements Serializable {
 
 	private static final long serialVersionUID = 5895841925807816737L;
 	private final static transient Logger logger = LoggerFactory.getLogger(AAIResultWrapper.class);
@@ -38,4 +38,9 @@
 	public AAIResultWrapper(Object aaiObject) {
 		super(aaiObject, logger);
 	}
+
+	@Override
+	protected Relationships createRelationships(String json) {
+		return new Relationships(json);
+	}
 }
diff --git a/common/src/main/java/org/onap/so/client/aai/entities/Relationships.java b/common/src/main/java/org/onap/so/client/aai/entities/Relationships.java
index e907bc9..61a2f4b 100644
--- a/common/src/main/java/org/onap/so/client/aai/entities/Relationships.java
+++ b/common/src/main/java/org/onap/so/client/aai/entities/Relationships.java
@@ -20,117 +20,55 @@
 
 package org.onap.so.client.aai.entities;
 
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.HashMap;
 import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-import java.util.function.Predicate;
 
 import javax.ws.rs.core.UriBuilder;
 
-import org.onap.so.client.aai.AAICommonObjectMapperProvider;
 import org.onap.so.client.aai.AAIObjectType;
 import org.onap.so.client.aai.AAIResourcesClient;
 import org.onap.so.client.aai.entities.uri.AAIResourceUri;
 import org.onap.so.client.aai.entities.uri.AAIUriFactory;
 import org.onap.so.client.graphinventory.GraphInventoryObjectName;
-import org.onap.so.jsonpath.JsonPathUtil;
+import org.onap.so.client.graphinventory.entities.GraphInventoryRelationships;
 
-import com.fasterxml.jackson.core.type.TypeReference;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.google.common.base.CaseFormat;
+public class Relationships extends GraphInventoryRelationships<AAIResultWrapper, AAIResourceUri, AAIObjectType>{
 
-public class Relationships {
-
-	private final ObjectMapper mapper;
-	private Map<String, Object> map;
-	private final String jsonBody;
 	public Relationships(String json) {
-		this.jsonBody = json;
-		this.mapper = new AAICommonObjectMapperProvider().getMapper();
-		try {
-			this.map = mapper.readValue(json, new TypeReference<Map<String, Object>>() {});
-		} catch (IOException e) {
-			this.map = new HashMap<>();
-		}
+		super(json);
 	}
 	
-	public List<AAIResultWrapper> getByType(GraphInventoryObjectName type) {
-		
-		return this.getAll(Optional.of(type));
-	}
-	
-	public List<AAIResultWrapper> getAll() {
-		
-		return this.getAll(Optional.empty());
-	}
-	
-	
-	public List<String> getRelatedLinks() {
-		return this.getRelatedLinks(Optional.empty());
-	}
-	
-	public List<String> getRelatedLinks(GraphInventoryObjectName type) {
-		return this.getRelatedLinks(Optional.of(type));
-	}
-	
+	@Deprecated
+	/**
+	 * Use getRelatedUris instead
+	 * @return
+	 */
 	public List<AAIResourceUri> getRelatedAAIUris() {
-		return this.getRelatedAAIUris(x -> true);
+		return this.getRelatedUris();
 	}
 	
+	@Deprecated
+	/**
+	 * Use getRelatedUris instead
+	 * @return
+	 */
 	public List<AAIResourceUri> getRelatedAAIUris(GraphInventoryObjectName type) {
-		return this.getRelatedAAIUris(x -> type.typeName().equals(x));
-	}
-	protected List<AAIResourceUri> getRelatedAAIUris(Predicate<String> p) {
-		List<AAIResourceUri> result = new ArrayList<>();
-		if (map.containsKey("relationship")) {
-			List<Map<String, Object>> relationships = (List<Map<String, Object>>)map.get("relationship");
-			for (Map<String, Object> relationship : relationships) {
-				final String relatedTo = (String)relationship.get("related-to");
-				if (p.test(relatedTo)) {
-					AAIObjectType type;
-					type = AAIObjectType.fromTypeName(relatedTo);
-					final String relatedLink = (String)relationship.get("related-link");
-					
-					result.add(AAIUriFactory.createResourceFromExistingURI(type, UriBuilder.fromPath(relatedLink).build()));
-				}
-			}
-		}
-		return result;
+		return this.getRelatedUris(type);
 	}
 	
 	
-	
-	protected List<AAIResultWrapper> getAll(final Optional<GraphInventoryObjectName> type) {
-		List<AAIResourceUri> relatedLinks;
-		if (type.isPresent()) {
-			relatedLinks = this.getRelatedAAIUris(type.get());
-		} else {
-			relatedLinks = this.getRelatedAAIUris();
-		}
-		ArrayList<AAIResultWrapper> result = new ArrayList<>();
-		for (AAIResourceUri link : relatedLinks) {
-			result.add(this.get(link));
-		}
-		return result;
-	}
-	
 	protected AAIResultWrapper get(AAIResourceUri uri) {
 		return new AAIResourcesClient().get(uri);
 		
 	}
-	
-	protected List<String> getRelatedLinks(Optional<GraphInventoryObjectName> type) {
-		String matcher = "";
-		if (type.isPresent()) {
-			matcher = "[?(@.related-to=='" + type.get() + "')]";
-		}
-		return JsonPathUtil.getInstance().locateResultList(this.jsonBody, String.format("$.relationship%s.related-link", matcher));
+
+	@Override
+	protected AAIResourceUri createUri(AAIObjectType type, String relatedLink) {
+		
+		return AAIUriFactory.createResourceFromExistingURI(type, UriBuilder.fromPath(relatedLink).build());
 	}
-	
-	public String getJson() {
-		return this.jsonBody;
+
+	@Override
+	protected AAIObjectType fromTypeName(String name) {
+		return AAIObjectType.fromTypeName(name);
 	}
 }
diff --git a/common/src/main/java/org/onap/so/client/graphinventory/GraphInventoryRestClient.java b/common/src/main/java/org/onap/so/client/graphinventory/GraphInventoryRestClient.java
new file mode 100644
index 0000000..10c0663
--- /dev/null
+++ b/common/src/main/java/org/onap/so/client/graphinventory/GraphInventoryRestClient.java
@@ -0,0 +1,77 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - SO
+ * ================================================================================
+ * 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.onap.so.client.graphinventory;
+
+import java.net.URI;
+import java.util.Map;
+import java.util.Optional;
+
+import javax.ws.rs.core.Response;
+
+import org.onap.so.client.ResponseExceptionMapper;
+import org.onap.so.client.RestClientSSL;
+import org.onap.so.client.RestProperties;
+import org.onap.so.client.policy.CommonObjectMapperProvider;
+import org.onap.so.utils.TargetEntity;
+
+public abstract class GraphInventoryRestClient extends RestClientSSL {
+
+	protected static final GraphInventoryCommonObjectMapperProvider standardProvider = new GraphInventoryCommonObjectMapperProvider();
+
+	protected final GraphInventoryPatchConverter patchConverter = new GraphInventoryPatchConverter();
+	
+	protected GraphInventoryRestClient(RestProperties props, URI uri) {
+		super(props, Optional.of(uri));
+	}
+
+	@Override
+    public abstract TargetEntity getTargetEntity();
+
+	@Override
+	protected abstract void initializeHeaderMap(Map<String, String> headerMap);
+
+	@Override
+	protected abstract Optional<ResponseExceptionMapper> addResponseExceptionMapper();
+	
+	@Override
+	protected CommonObjectMapperProvider getCommonObjectMapperProvider() {
+		return standardProvider;
+	}
+
+	@Override
+	public Response patch(Object obj) {
+		return super.patch(convertToPatchFormat(obj));
+	}
+
+	@Override
+	public <T> T patch(Object obj, Class<T> resultClass) {
+		return super.patch(convertToPatchFormat(obj), resultClass);
+	}
+	
+	protected GraphInventoryPatchConverter getPatchConverter() {
+		return this.patchConverter;
+	}
+	
+	protected String convertToPatchFormat(Object obj) {
+		return getPatchConverter().convertPatchFormat(obj);
+	}
+
+}
diff --git a/common/src/main/java/org/onap/so/client/graphinventory/entities/GraphInventoryRelationships.java b/common/src/main/java/org/onap/so/client/graphinventory/entities/GraphInventoryRelationships.java
new file mode 100644
index 0000000..759fad7
--- /dev/null
+++ b/common/src/main/java/org/onap/so/client/graphinventory/entities/GraphInventoryRelationships.java
@@ -0,0 +1,137 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - SO
+ * ================================================================================
+ * 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.onap.so.client.graphinventory.entities;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.function.Predicate;
+
+import org.onap.so.client.aai.AAICommonObjectMapperProvider;
+import org.onap.so.client.aai.AAIObjectType;
+import org.onap.so.client.aai.entities.AAIResultWrapper;
+import org.onap.so.client.aai.entities.uri.AAIResourceUri;
+import org.onap.so.client.graphinventory.GraphInventoryCommonObjectMapperProvider;
+import org.onap.so.client.graphinventory.GraphInventoryObjectName;
+import org.onap.so.client.graphinventory.GraphInventoryObjectType;
+import org.onap.so.client.graphinventory.entities.uri.GraphInventoryResourceUri;
+import org.onap.so.jsonpath.JsonPathUtil;
+
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+public abstract class GraphInventoryRelationships<Wrapper extends GraphInventoryResultWrapper, Uri extends GraphInventoryResourceUri, Type extends GraphInventoryObjectType> {
+
+	protected final ObjectMapper mapper;
+	protected Map<String, Object> map;
+	protected final String jsonBody;
+	
+	public GraphInventoryRelationships(String json) {
+		this.jsonBody = json;
+		this.mapper = new GraphInventoryCommonObjectMapperProvider().getMapper();
+		try {
+			this.map = mapper.readValue(json, new TypeReference<Map<String, Object>>() {});
+		} catch (IOException e) {
+			this.map = new HashMap<>();
+		}
+	}
+	
+	public List<Wrapper> getByType(GraphInventoryObjectName type) {
+		
+		return this.getAll(Optional.of(type));
+	}
+	
+	public List<Wrapper> getAll() {
+		
+		return this.getAll(Optional.empty());
+	}
+	
+	
+	public List<String> getRelatedLinks() {
+		return this.getRelatedLinks(Optional.empty());
+	}
+	
+	public List<String> getRelatedLinks(GraphInventoryObjectName type) {
+		return this.getRelatedLinks(Optional.of(type));
+	}
+	
+	public List<Uri> getRelatedUris() {
+		return this.getRelatedUris(x -> true);
+	}
+	
+	public List<Uri> getRelatedUris(GraphInventoryObjectName type) {
+		return this.getRelatedUris(x -> type.typeName().equals(x));
+	}
+	protected List<Uri> getRelatedUris(Predicate<String> p) {
+		List<Uri> result = new ArrayList<>();
+		if (map.containsKey("relationship")) {
+			List<Map<String, Object>> relationships = (List<Map<String, Object>>)map.get("relationship");
+			for (Map<String, Object> relationship : relationships) {
+				final String relatedTo = (String)relationship.get("related-to");
+				if (p.test(relatedTo)) {
+					Type type;
+					type = fromTypeName(relatedTo);
+					final String relatedLink = (String)relationship.get("related-link");
+					
+					result.add(createUri(type, relatedLink));
+				}
+			}
+		}
+		return result;
+	}
+	
+	
+	
+	protected List<Wrapper> getAll(final Optional<GraphInventoryObjectName> type) {
+		List<Uri> relatedLinks;
+		if (type.isPresent()) {
+			relatedLinks = this.getRelatedUris(type.get());
+		} else {
+			relatedLinks = this.getRelatedUris();
+		}
+		ArrayList<Wrapper> result = new ArrayList<>();
+		for (Uri link : relatedLinks) {
+			result.add(this.get(link));
+		}
+		return result;
+	}
+	
+	protected abstract Wrapper get(Uri uri);
+	
+	protected abstract Uri createUri(Type type, String relatedLink);
+	
+	protected abstract Type fromTypeName(String name);
+	
+	protected List<String> getRelatedLinks(Optional<GraphInventoryObjectName> type) {
+		String matcher = "";
+		if (type.isPresent()) {
+			matcher = "[?(@.related-to=='" + type.get() + "')]";
+		}
+		return JsonPathUtil.getInstance().locateResultList(this.jsonBody, String.format("$.relationship%s.related-link", matcher));
+	}
+	
+	public String getJson() {
+		return this.jsonBody;
+	}
+}
diff --git a/common/src/main/java/org/onap/so/client/graphinventory/entities/GraphInventoryResultWrapper.java b/common/src/main/java/org/onap/so/client/graphinventory/entities/GraphInventoryResultWrapper.java
index 2f71358..c5651c0 100644
--- a/common/src/main/java/org/onap/so/client/graphinventory/entities/GraphInventoryResultWrapper.java
+++ b/common/src/main/java/org/onap/so/client/graphinventory/entities/GraphInventoryResultWrapper.java
@@ -28,17 +28,15 @@
 import java.util.Map;
 import java.util.Optional;
 
-import org.onap.so.client.aai.AAICommonObjectMapperProvider;
-import org.onap.so.client.aai.entities.Relationships;
+import org.onap.so.client.graphinventory.GraphInventoryCommonObjectMapperProvider;
 import org.onap.so.jsonpath.JsonPathUtil;
 import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fasterxml.jackson.core.type.TypeReference;
 import com.fasterxml.jackson.databind.ObjectMapper;
 
-public class GraphInventoryResultWrapper implements Serializable {
+public abstract class GraphInventoryResultWrapper<R extends GraphInventoryRelationships<?, ?, ?>> implements Serializable {
 
 	private static final long serialVersionUID = 5895841925807816727L;
 	protected final String jsonBody;
@@ -47,12 +45,12 @@
 	
 	protected GraphInventoryResultWrapper(String json, Logger logger) {
 		this.jsonBody = json;
-		this.mapper = new AAICommonObjectMapperProvider().getMapper();
+		this.mapper = new GraphInventoryCommonObjectMapperProvider().getMapper();
 		this.logger = logger;
 	}
 	
 	protected GraphInventoryResultWrapper(Object aaiObject, Logger logger) {
-		this.mapper = new AAICommonObjectMapperProvider().getMapper();
+		this.mapper = new GraphInventoryCommonObjectMapperProvider().getMapper();
 		this.jsonBody = mapObjectToString(aaiObject);
 		this.logger = logger;
 	}
@@ -65,18 +63,19 @@
 			return "{}";
 		}
 	}
-	public Optional<Relationships> getRelationships() {
+	public Optional<R> getRelationships() {
 		final String path = "$.relationship-list";
 		if (isEmpty()) {
 			return Optional.empty();
 		}
 		Optional<String> result = JsonPathUtil.getInstance().locateResult(jsonBody, path);
 		if (result.isPresent()) {
-			return Optional.of(new Relationships(result.get()));
+			return Optional.of(createRelationships(result.get()));
 		} else {
 			return Optional.empty();
 		}
 	}
+	protected abstract R createRelationships(String json);
 	
 	public String getJson() {
 		if(jsonBody == null) {
diff --git a/common/src/main/java/org/onap/so/client/graphinventory/entities/uri/SimpleUri.java b/common/src/main/java/org/onap/so/client/graphinventory/entities/uri/SimpleUri.java
index dc4179a..1b88441 100644
--- a/common/src/main/java/org/onap/so/client/graphinventory/entities/uri/SimpleUri.java
+++ b/common/src/main/java/org/onap/so/client/graphinventory/entities/uri/SimpleUri.java
@@ -33,7 +33,6 @@
 import javax.ws.rs.core.UriBuilder;
 
 import org.apache.commons.lang3.builder.HashCodeBuilder;
-import org.onap.so.client.aai.entities.uri.AAIUri;
 import org.onap.so.client.graphinventory.Format;
 import org.onap.so.client.graphinventory.GraphInventoryObjectPlurals;
 import org.onap.so.client.graphinventory.GraphInventoryObjectType;
@@ -212,8 +211,8 @@
 	
 	@Override
 	public boolean equals(Object o) {
-		if (o instanceof AAIUri) {
-			return this.build().equals(((AAIUri)o).build());
+		if (o instanceof GraphInventoryUri) {
+			return this.build().equals(((GraphInventoryUri)o).build());
 		}
 		return false;
 	}