Repository: redhat-developer/service-binding-operator
Pull request #583 (2020-07-23 15:40:19)

Reconcile should log error if a resource is not found in detect Bindable resource
Fix for #584 
Do not error out when resource not found in the binding resources, Instead log it as stated below
```
2020-07-23T21:04:33.309+0530	DEBUG	reconciler.buildServiceContexts	Resource not found in Bindable Resources	{"Request.Namespace": "try", "Request.Name": "binding-request-etcd", "ServiceBindingRequest.Name": "binding-request-etcd", "Error": "the server could not find the requested resource"}
```


openshift-ci-robot: [APPROVALNOTIFIER] This PR is **NOT APPROVED**

This pull-request has been approved by:
To complete the [pull request process](https://git.k8s.io/community/contributors/guide/owners.md#the-code-review-process), please assign **avni-sharma**
You can assign the PR to them by writing `/assign @avni-sharma` in a comment when ready.

The full list of commands accepted by this bot can be found [here](https://go.k8s.io/bot-commands?repo=redhat-developer%2Fservice-binding-operator).

<details open>
Needs approval from an approver in each of these files:

- **[OWNERS](https://github.com/redhat-developer/service-binding-operator/blob/master/OWNERS)**

Approvers can indicate their approval by writing `/approve` in a comment
Approvers can cancel approval by writing `/approve cancel` in a comment
</details>
<!-- META={"approvers":["avni-sharma"]} -->
openshift-ci-robot: @Avni-Sharma: The following test **failed**, say `/retest` to rerun all failed tests:

Test name | Commit | Details | Rerun command
--- | --- | --- | ---
ci/prow/lint | 4a790485337e6548aa13a4cac03a60332d22c945 | [link](https://prow.ci.openshift.org/view/gs/origin-ci-test/pr-logs/pull/redhat-developer_service-binding-operator/583/pull-ci-redhat-developer-service-binding-operator-master-lint/1286325284282306560) | `/test lint`

[Full PR test history](https://prow.ci.openshift.org/pr-history?org=redhat-developer&repo=service-binding-operator&pr=583). [Your PR dashboard](https://prow.ci.openshift.org/pr?query=is:pr+state:open+author:Avni-Sharma).

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository. I understand the commands that are listed [here](https://go.k8s.io/bot-commands).
</details>
<!-- test report -->
openshift-ci-robot: @Avni-Sharma: The following tests **failed**, say `/retest` to rerun all failed tests:

Test name | Commit | Details | Rerun command
--- | --- | --- | ---
ci/prow/lint | 4a790485337e6548aa13a4cac03a60332d22c945 | [link](https://prow.ci.openshift.org/view/gs/origin-ci-test/pr-logs/pull/redhat-developer_service-binding-operator/583/pull-ci-redhat-developer-service-binding-operator-master-lint/1286325284282306560) | `/test lint`
ci/prow/4.5-lint | 4a790485337e6548aa13a4cac03a60332d22c945 | [link](https://prow.ci.openshift.org/view/gs/origin-ci-test/pr-logs/pull/redhat-developer_service-binding-operator/583/pull-ci-redhat-developer-service-binding-operator-master-4.5-lint/1286325283963539456) | `/test 4.5-lint`

[Full PR test history](https://prow.ci.openshift.org/pr-history?org=redhat-developer&repo=service-binding-operator&pr=583). [Your PR dashboard](https://prow.ci.openshift.org/pr?query=is:pr+state:open+author:Avni-Sharma).

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository. I understand the commands that are listed [here](https://go.k8s.io/bot-commands).
</details>
<!-- test report -->
openshift-ci-robot: @Avni-Sharma: The following tests **failed**, say `/retest` to rerun all failed tests:

Test name | Commit | Details | Rerun command
--- | --- | --- | ---
ci/prow/lint | 4a790485337e6548aa13a4cac03a60332d22c945 | [link](https://prow.ci.openshift.org/view/gs/origin-ci-test/pr-logs/pull/redhat-developer_service-binding-operator/583/pull-ci-redhat-developer-service-binding-operator-master-lint/1286325284282306560) | `/test lint`
ci/prow/4.5-lint | 4a790485337e6548aa13a4cac03a60332d22c945 | [link](https://prow.ci.openshift.org/view/gs/origin-ci-test/pr-logs/pull/redhat-developer_service-binding-operator/583/pull-ci-redhat-developer-service-binding-operator-master-4.5-lint/1286325283963539456) | `/test 4.5-lint`
ci/prow/4.5-unit | 4a790485337e6548aa13a4cac03a60332d22c945 | [link](https://prow.ci.openshift.org/view/gs/origin-ci-test/pr-logs/pull/redhat-developer_service-binding-operator/583/pull-ci-redhat-developer-service-binding-operator-master-4.5-unit/1286325364716474368) | `/test 4.5-unit`

[Full PR test history](https://prow.ci.openshift.org/pr-history?org=redhat-developer&repo=service-binding-operator&pr=583). [Your PR dashboard](https://prow.ci.openshift.org/pr?query=is:pr+state:open+author:Avni-Sharma).

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository. I understand the commands that are listed [here](https://go.k8s.io/bot-commands).
</details>
<!-- test report -->

Patch:
diff --git a/Makefile b/Makefile
index 606b2bd6..6cc6edaa 100644
--- a/Makefile
+++ b/Makefile
@@ -159,6 +159,8 @@ PULL_NUMBER := $(shell echo $$CLONEREFS_OPTIONS | jq '.refs[0].pulls[0].number')
 
 # -- Variables for acceptance tests
 TEST_ACCEPTANCE_START_SBO ?= local
+TEST_ACCEPTANCE_OUTPUT_DIR ?= $(OUTPUT_DIR)/acceptance-tests
+TEST_ACCEPTANCE_ARTIFACTS ?= /tmp/artifacts
 
 ## -- Static code analysis (lint) targets --
 
@@ -278,11 +280,11 @@ test-unit-with-coverage:
 
 .PHONY: test-acceptance-setup
 ## Setup the environment for the acceptance tests
-test-acceptance-setup: setup-venv
+test-acceptance-setup: setup-venv e2e-setup set-test-namespace deploy-rbac deploy-crds
 ifeq ($(TEST_ACCEPTANCE_START_SBO), local)
 test-acceptance-setup:
 	$(Q)echo "Starting local SBO instance"
-	$(eval TEST_ACCEPTANCE_SBO_STARTED := $(shell OPERATOR_NAMESPACE="$(TEST_NAMESPACE)" ZAP_FLAGS="$(ZAP_FLAGS)" ./hack/deploy-sbo-local.sh))
+	$(eval TEST_ACCEPTANCE_SBO_STARTED := $(shell OPERATOR_NAMESPACE="$(TEST_NAMESPACE)" ZAP_FLAGS="$(ZAP_FLAGS)" OUTPUT="$(TEST_ACCEPTANCE_OUTPUT_DIR)" ./hack/deploy-sbo-local.sh))
 else ifeq ($(TEST_ACCEPTANCE_START_SBO), operator-hub)
 test-acceptance-setup:
 	$(eval TEST_ACCEPTANCE_SBO_STARTED := $(shell ./hack/deploy-sbo-operator-hub.sh))
@@ -295,14 +297,21 @@ set-test-namespace: get-test-namespace
 
 .PHONY: test-acceptance
 ## Runs acceptance tests
-test-acceptance: e2e-setup set-test-namespace deploy-clean deploy-rbac deploy-crds test-acceptance-setup
+test-acceptance: test-acceptance-setup
 	$(Q)echo "Running acceptance tests"
 	$(Q)TEST_ACCEPTANCE_START_SBO=$(TEST_ACCEPTANCE_START_SBO) \
 		TEST_ACCEPTANCE_SBO_STARTED=$(TEST_ACCEPTANCE_SBO_STARTED) \
 		TEST_NAMESPACE=$(TEST_NAMESPACE) \
-		$(PYTHON_VENV_DIR)/bin/behave --junit --junit-directory $(OUTPUT_DIR)/acceptance-tests $(V_FLAG) --no-capture --no-capture-stderr --tags="~@disabled" test/acceptance/features
+		$(PYTHON_VENV_DIR)/bin/behave --junit --junit-directory $(TEST_ACCEPTANCE_OUTPUT_DIR) $(V_FLAG) --no-capture --no-capture-stderr --tags="~@disabled" test/acceptance/features
 	$(Q)kill $(TEST_ACCEPTANCE_SBO_STARTED)
 
+.PHONY: test-acceptance-artifacts
+## Collect artifacts from acceptance tests to be archived in CI
+test-acceptance-artifacts:
+	$(Q)echo "Gathering acceptance tests artifacts"
+	$(Q)mkdir -p $(TEST_ACCEPTANCE_ARTIFACTS) \
+	    && cp -rvf $(TEST_ACCEPTANCE_OUTPUT_DIR) $(TEST_ACCEPTANCE_ARTIFACTS)/
+
 .PHONY: test
 ## Test: Runs unit and integration (e2e) tests
 test: test-unit test-e2e
@@ -450,15 +459,9 @@ else
 		-Z > codecov-upload.log
 endif
 
-## -- Target for maintaining consistent crd copies --
 
-.PHONY: consistent-crds-manifests-upstream
-## Copy crd from deploy/crds to manifests-upstream/
-consistent-crds-manifests-upstream:
-	$(Q)cd ./manifests-upstream/${OPERATOR_VERSION}/ && ln -srf ../../deploy/crds/apps_v1alpha1_servicebindingrequest_crd.yaml \
-	servicebindingrequests.apps.openshift.io.crd.yaml
+## -- Bundle validation, push and release targets
 
-## -- Target for merge to master dev release --
 .PHONY: merge-to-master-release
 ## Make a dev release on every merge to master
 merge-to-master-release:
@@ -468,7 +471,6 @@ merge-to-master-release:
 	docker push "$(OPERATOR_IMAGE_REF)"
 
 
-## -- Target for pushing manifest bundle to service-binding-operator-manifest repo --
 .PHONY: push-to-manifest-repo
 ## Push manifest bundle to service-binding-operator-manifest repo
 push-to-manifest-repo:
@@ -486,7 +488,6 @@ push-to-manifest-repo:
 	sed -i -e 's,ICON_BASE64_DATA,$(shell base64 --wrap=0 ./assets/icon/red-hat-logo.svg),g' $(MANIFESTS_TMP)/${BUNDLE_VERSION}/*.clusterserviceversion.yaml
 	sed -i -e 's,ICON_MEDIA_TYPE,image/svg+xml,g' $(MANIFESTS_TMP)/${BUNDLE_VERSION}/*.clusterserviceversion.yaml
 
-## -- Target for preparing manifest bundle to quay application --
 .PHONY: prepare-bundle-to-quay
 ## Prepare manifest bundle to quay application
 prepare-bundle-to-quay:
@@ -498,23 +499,21 @@ prepare-bundle-to-quay:
 	$(Q)$(PYTHON_VENV_DIR)/bin/operator-courier verify $(MANIFESTS_TMP)
 	rm -rf deploy/olm-catalog/$(GO_PACKAGE_REPO_NAME)/$(BUNDLE_VERSION)
 
-## -- Target to push bundle to quay
+
 .PHONY: push-bundle-to-quay
 ## Push manifest bundle to quay application
 push-bundle-to-quay:
 	$(Q)$(PYTHON_VENV_DIR)/bin/operator-courier verify $(SBR_MANIFESTS)
 	$(Q)$(PYTHON_VENV_DIR)/bin/operator-courier push $(SBR_MANIFESTS) redhat-developer service-binding-operator $(BUNDLE_VERSION) "$(QUAY_BUNDLE_TOKEN)"
 
-## -- Target for validating the operator --
+
 .PHONY: dev-release
 ## validating the operator by installing new quay releases
 dev-release:
 	BUNDLE_VERSION=$(BUNDLE_VERSION) ./hack/dev-release.sh
 
-## -- Target to validate release --
 .PHONY: validate-release
 ## validate the operator by installing the releases
 validate-release: setup-venv
 	$(Q)$(PYTHON_VENV_DIR)/bin/pip install yq==2.10.0
 	BUNDLE_VERSION=$(BASE_BUNDLE_VERSION) CHANNEL="alpha" ./hack/validate-release.sh
-
diff --git a/examples/java_postgresql_customvar/README.md b/examples/java_postgresql_customvar/README.md
index 2284c5cd..aadb27cc 100644
--- a/examples/java_postgresql_customvar/README.md
+++ b/examples/java_postgresql_customvar/README.md
@@ -199,13 +199,14 @@ spec:
     version: v1alpha1
     kind: Database
     resourceRef: db-demo
+    id: postgresDB
   customEnvVar:
     - name: JDBC_URL
-      value: 'jdbc:postgresql://{{ .status.dbConnectionIP }}:{{ .status.dbConnectionPort }}/{{ .status.dbName }}'
+      value: 'jdbc:postgresql://{{ .postgresDB.status.dbConnectionIP }}:{{ .postgresDB.status.dbConnectionPort }}/{{ .postgresDB.status.dbName }}'
     - name: DB_USER
-      value: '{{ index .status.dbConfigMap "db.username" }}'
+      value: '{{ .postgresDB.status.dbCredentials.user }}'
     - name: DB_PASSWORD
-      value: '{{ index .status.dbConfigMap "db.password" }}'
+      value: '{{ .postgresDB.status.dbCredentials.password }}'
 EOS
 ```
 
diff --git a/examples/java_postgresql_customvar/service-binding-request.yaml b/examples/java_postgresql_customvar/service-binding-request.yaml
index 0a434e5b..8344dfaf 100644
--- a/examples/java_postgresql_customvar/service-binding-request.yaml
+++ b/examples/java_postgresql_customvar/service-binding-request.yaml
@@ -15,10 +15,11 @@ spec:
     version: v1alpha1
     kind: Database
     resourceRef: db-demo
+    id: postgresDB
   customEnvVar:
     - name: JDBC_URL
-      value: 'jdbc:postgresql://{{ .status.dbConnectionIP }}:{{ .status.dbConnectionPort }}/{{ .status.dbName }}'   # yamllint disable-line rule:line-length
+      value: 'jdbc:postgresql://{{ .postgresDB.status.dbConnectionIP }}:{{ .postgresDB.status.dbConnectionPort }}/{{ .postgresDB.status.dbName }}'
     - name: DB_USER
-      value: '{{ index .status.dbConfigMap "db.username" }}'
+      value: '{{ .postgresDB.status.dbCredentials.user }}'
     - name: DB_PASSWORD
-      value: '{{ index .status.dbConfigMap "db.password" }}'
+      value: '{{ .postgresDB.status.dbCredentials.password }}'
diff --git a/examples/knative_postgresql_customvar/README.md b/examples/knative_postgresql_customvar/README.md
index d88e4d02..cbf2e1a6 100644
--- a/examples/knative_postgresql_customvar/README.md
+++ b/examples/knative_postgresql_customvar/README.md
@@ -205,11 +205,12 @@ spec:
     resourceRef: db-demo
   customEnvVar:
     - name: JDBC_URL
-      value: 'jdbc:postgresql://{{ .status.dbConnectionIP }}:{{ .status.dbConnectionPort }}/{{ .status.dbName }}'
+      value: 'jdbc:postgresql://{{ .postgresDB.status.dbConnectionIP }}:{{ .postgresDB.status.dbConnectionPort }}/{{ .postgresDB.status.dbName }}'
     - name: DB_USER
-      value: '{{ index .status.dbConfigMap "db.username" }}'
+      value: '{{ .postgresDB.status.dbCredentials.user }}'
     - name: DB_PASSWORD
-      value: '{{ index .status.dbConfigMap "db.password" }}'
+      value: '{{ .postgresDB.status.dbCredentials.password }}'
+
 EOS
 ```
 
diff --git a/examples/knative_postgresql_customvar/service-binding-request.yaml b/examples/knative_postgresql_customvar/service-binding-request.yaml
index d2806931..17c7f38e 100644
--- a/examples/knative_postgresql_customvar/service-binding-request.yaml
+++ b/examples/knative_postgresql_customvar/service-binding-request.yaml
@@ -15,10 +15,11 @@ spec:
     version: v1alpha1
     kind: Database
     resourceRef: db-demo
+    id: postgresDB
   customEnvVar:
     - name: JDBC_URL
-      value: 'jdbc:postgresql://{{ .status.dbConnectionIP }}:{{ .status.dbConnectionPort }}/{{ .status.dbName }}'   # yamllint disable-line rule:line-length
+      value: 'jdbc:postgresql://{{ .postgresDB.status.dbConnectionIP }}:{{ .postgresDB.status.dbConnectionPort }}/{{ .postgresDB.status.dbName }}'
     - name: DB_USER
-      value: '{{ index .status.dbConfigMap "db.username" }}'
+      value: '{{ .postgresDB.status.dbCredentials.user }}'
     - name: DB_PASSWORD
-      value: '{{ index .status.dbConfigMap "db.password" }}'
+      value: '{{ .postgresDB.status.dbCredentials.password }}'
diff --git a/hack/check-python/detect-dead-code.sh b/hack/check-python/detect-dead-code.sh
index 2e409a7c..a9fe9d9f 100755
--- a/hack/check-python/detect-dead-code.sh
+++ b/hack/check-python/detect-dead-code.sh
@@ -36,7 +36,7 @@ echo
 # checks for the whole directories
 for directory in $directories
 do
-    files=$(find "$directory" -prune -o -name '*.py' -print)
+    files=$(find "$directory" -path "$PYTHON_VENV_DIR" -prune -o -name '*.py' -print)
 
     check_files "$files"
 done
diff --git a/hack/deploy-sbo-local.sh b/hack/deploy-sbo-local.sh
index 61facec4..a4fa54bc 100755
--- a/hack/deploy-sbo-local.sh
+++ b/hack/deploy-sbo-local.sh
@@ -3,7 +3,22 @@
 OPERATOR_NAMESPACE=${OPERATOR_NAMESPACE:-}
 ZAP_FLAGS=${ZAP_FLAGS:-}
 
-SBO_LOCAL_LOG=out/sbo-local.log
+OUTPUT="${OUTPUT:-out/acceptance-tests}"
+mkdir -p "$OUTPUT"
+
+SBO_LOCAL_LOG="$OUTPUT/sbo-local.log"
+
+_killall(){
+    which killall &> /dev/null
+    if [ $? -eq 0 ]; then
+        killall $1
+    else
+        for i in "$(ps -l | grep $1)"; do if [ -n "$i" ]; then kill $(echo "$i" | sed -e 's,\s\+,#,g' | cut -d "#" -f4); fi; done
+    fi
+}
+
+_killall operator-sdk
+_killall service-binding-operator-local
 
 operator-sdk --verbose run --local --namespace="$OPERATOR_NAMESPACE" --operator-flags "$ZAP_FLAGS" > $SBO_LOCAL_LOG 2>&1 &
 
diff --git a/pkg/controller/servicebindingrequest/annotations/attribute.go b/pkg/controller/servicebindingrequest/annotations/attribute.go
index 2d1a27ee..40a63612 100644
--- a/pkg/controller/servicebindingrequest/annotations/attribute.go
+++ b/pkg/controller/servicebindingrequest/annotations/attribute.go
@@ -47,6 +47,10 @@ func newAttributeHandler(
 	if len(bi.ResourceReferencePath) > 0 {
 		outputPath = bi.ResourceReferencePath
 	}
+	inputPath := bi.SourcePath
+	if inputPath == "" {
+		inputPath = bi.ResourceReferencePath
+	}
 
 	// the current implementation removes "status." and "spec." from fields exported through
 	// annotations.
@@ -57,7 +61,7 @@ func newAttributeHandler(
 	}
 
 	return &attributeHandler{
-		inputPath:  bi.SourcePath,
+		inputPath:  inputPath,
 		outputPath: outputPath,
 		resource:   resource,
 	}
diff --git a/pkg/controller/servicebindingrequest/annotations/bindinginfo.go b/pkg/controller/servicebindingrequest/annotations/bindinginfo.go
index 0617dfc8..970db4e2 100644
--- a/pkg/controller/servicebindingrequest/annotations/bindinginfo.go
+++ b/pkg/controller/servicebindingrequest/annotations/bindinginfo.go
@@ -38,21 +38,24 @@ func NewBindingInfo(name string, value string) (*bindingInfo, error) {
 	if len(cleanName) == 0 {
 		return nil, ErrEmptyAnnotationName
 	}
-
 	parts := strings.SplitN(cleanName, "-", 2)
 
 	resourceReferencePath := parts[0]
-	sourcePath := parts[0]
-
+	// sourcePath := parts[0]
+	sourcePath := ""
+	descriptor := ""
 	// the annotation is a reference to another manifest
 	if len(parts) == 2 {
 		sourcePath = parts[1]
+		descriptor = strings.Join([]string{value, sourcePath}, ":")
+	} else {
+		descriptor = strings.Join([]string{value, resourceReferencePath}, ":")
 	}
 
 	return &bindingInfo{
 		ResourceReferencePath: resourceReferencePath,
 		SourcePath:            sourcePath,
-		Descriptor:            strings.Join([]string{value, sourcePath}, ":"),
+		Descriptor:            descriptor,
 		Value:                 value,
 	}, nil
 }
diff --git a/pkg/controller/servicebindingrequest/annotations/resource.go b/pkg/controller/servicebindingrequest/annotations/resource.go
index ec309570..3438a6c6 100644
--- a/pkg/controller/servicebindingrequest/annotations/resource.go
+++ b/pkg/controller/servicebindingrequest/annotations/resource.go
@@ -85,7 +85,7 @@ func discoverBindingType(val string) (bindingType, error) {
 // the resulting slice.
 func getInputPathFields(bi *bindingInfo, inputPathPrefix *string) []string {
 	inputPathFields := []string{}
-	if bi.ResourceReferencePath != bi.SourcePath {
+	if bi.SourcePath != "" {
 		inputPathFields = append(inputPathFields, bi.SourcePath)
 	}
 	if inputPathPrefix != nil && len(*inputPathPrefix) > 0 {
@@ -105,7 +105,6 @@ func (h *resourceHandler) Handle() (result, error) {
 	if err != nil {
 		return result{}, err
 	}
-
 	inputPathFields := getInputPathFields(h.bindingInfo, h.inputPathRoot)
 	val, ok, err := unstructured.NestedFieldCopy(resource.Object, inputPathFields...)
 	if !ok {
@@ -121,8 +120,6 @@ func (h *resourceHandler) Handle() (result, error) {
 		return result{}, err
 	}
 
-	outputPathParts := []string{strings.ToLower(gvk.Kind)}
-
 	if mapVal, ok := val.(map[string]interface{}); ok {
 		tmpVal := make(map[string]interface{})
 		for k, v := range mapVal {
@@ -138,7 +135,6 @@ func (h *resourceHandler) Handle() (result, error) {
 		if err != nil {
 			return result{}, err
 		}
-		outputPathParts = append(outputPathParts, nested.NewPath(h.bindingInfo.SourcePath).GetParts()...)
 	}
 
 	typ, err := discoverBindingType(h.bindingInfo.Value)
@@ -147,18 +143,27 @@ func (h *resourceHandler) Handle() (result, error) {
 	}
 
 	// prefix the output path with the kind of the resource.
-	outputPath := strings.Join(outputPathParts, ".")
+	outputPath := ""
+	rawDataPath := ""
 
-	rawDataPath := strings.Join([]string{
-		h.bindingInfo.ResourceReferencePath,
-		h.bindingInfo.SourcePath,
-	}, ".")
+	if h.bindingInfo.SourcePath == "" {
+		outputPath = strings.ToLower(gvk.Kind)
+		rawDataPath = h.bindingInfo.ResourceReferencePath
+	} else {
+		outputPath = strings.Join([]string{
+			strings.ToLower(gvk.Kind),
+			h.bindingInfo.SourcePath,
+		}, ".")
+		rawDataPath = strings.Join([]string{
+			h.bindingInfo.ResourceReferencePath,
+			h.bindingInfo.SourcePath,
+		}, ".")
+	}
 
 	return result{
-		Data: nested.ComposeValue(val, nested.NewPath(outputPath)),
-		Type: typ,
-		Path: outputPath,
-
+		Data:    nested.ComposeValue(val, nested.NewPath(outputPath)),
+		Type:    typ,
+		Path:    outputPath,
 		RawData: nested.ComposeValue(val, nested.NewPath(rawDataPath)),
 	}, nil
 }
@@ -189,10 +194,6 @@ func NewResourceHandler(
 		return nil, invalidArgumentErr("bi")
 	}
 
-	if len(bi.SourcePath) == 0 {
-		return nil, invalidArgumentErr("bi.Path")
-	}
-
 	if len(bi.ResourceReferencePath) == 0 {
 		return nil, invalidArgumentErr("bi.ResourceReferencePath")
 	}
diff --git a/pkg/controller/servicebindingrequest/nested/path.go b/pkg/controller/servicebindingrequest/nested/path.go
index ba9d2501..3bdb7ca2 100644
--- a/pkg/controller/servicebindingrequest/nested/path.go
+++ b/pkg/controller/servicebindingrequest/nested/path.go
@@ -129,6 +129,9 @@ func (p path) clean() path {
 
 // NewPath creates a new path with the given string in the format 'a.b.c'.
 func NewPath(s string) path {
+	if s == "" {
+		return path{}
+	}
 	parts := strings.Split(s, ".")
 	return newPathWithParts(parts)
 }
diff --git a/pkg/controller/servicebindingrequest/service.go b/pkg/controller/servicebindingrequest/service.go
index bc7b2c18..609784d2 100644
--- a/pkg/controller/servicebindingrequest/service.go
+++ b/pkg/controller/servicebindingrequest/service.go
@@ -4,6 +4,7 @@ import (
 	"errors"
 	"strings"
 
+	k8serrors "k8s.io/apimachinery/pkg/api/errors"
 	"k8s.io/apimachinery/pkg/api/meta"
 	"k8s.io/apimachinery/pkg/types"
 
@@ -15,6 +16,7 @@ import (
 	olmv1alpha1 "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1"
 	"github.com/redhat-developer/service-binding-operator/pkg/controller/servicebindingrequest/annotations"
 	"github.com/redhat-developer/service-binding-operator/pkg/controller/servicebindingrequest/nested"
+	"github.com/redhat-developer/service-binding-operator/pkg/log"
 )
 
 var (
@@ -160,6 +162,7 @@ var bindableResources = []bindableResource{
 }
 
 func getOwnedResources(
+	logger *log.Log,
 	client dynamic.Interface,
 	ns string,
 	gvk schema.GroupVersionKind,
@@ -173,6 +176,10 @@ func getOwnedResources(
 	for _, br := range bindableResources {
 		lst, err := client.Resource(br.gvr).Namespace(ns).List(metav1.ListOptions{})
 		if err != nil {
+			if k8serrors.IsNotFound(err) {
+				logger.Debug("Resource not found in Bindable Resources", "Error", err)
+				continue
+			}
 			return resources, err
 		}
 		for idx, item := range lst.Items {
diff --git a/pkg/controller/servicebindingrequest/servicecontext.go b/pkg/controller/servicebindingrequest/servicecontext.go
index df4fa81e..23870e92 100644
--- a/pkg/controller/servicebindingrequest/servicecontext.go
+++ b/pkg/controller/servicebindingrequest/servicecontext.go
@@ -85,6 +85,7 @@ SELECTORS:
 				svcEnvVarPrefix = &s.Kind
 			}
 			ownedResourcesCtxs, err := findOwnedResourcesCtxs(
+				logger,
 				client,
 				ns,
 				svcCtx.service.GetName(),
@@ -104,6 +105,7 @@ SELECTORS:
 }
 
 func findOwnedResourcesCtxs(
+	logger *log.Log,
 	client dynamic.Interface,
 	ns string,
 	name string,
@@ -113,6 +115,7 @@ func findOwnedResourcesCtxs(
 	restMapper meta.RESTMapper,
 ) (serviceContextList, error) {
 	ownedResources, err := getOwnedResources(
+		logger,
 		client,
 		ns,
 		gvk,


Test patch:
diff --git a/pkg/controller/servicebindingrequest/annotations/bindinginfo_test.go b/pkg/controller/servicebindingrequest/annotations/bindinginfo_test.go
index 98dbe1ee..05f88213 100644
--- a/pkg/controller/servicebindingrequest/annotations/bindinginfo_test.go
+++ b/pkg/controller/servicebindingrequest/annotations/bindinginfo_test.go
@@ -39,7 +39,7 @@ func TestNewBindingInfo(t *testing.T) {
 			want: &bindingInfo{
 				Descriptor:            "binding:status.connectionString",
 				ResourceReferencePath: "status.connectionString",
-				SourcePath:            "status.connectionString",
+				SourcePath:            "",
 				Value:                 "binding",
 			},
 			name:    "{path} annotation",
diff --git a/pkg/controller/servicebindingrequest/annotations/configmap_test.go b/pkg/controller/servicebindingrequest/annotations/configmap_test.go
index d717f805..34b82f33 100644
--- a/pkg/controller/servicebindingrequest/annotations/configmap_test.go
+++ b/pkg/controller/servicebindingrequest/annotations/configmap_test.go
@@ -16,11 +16,12 @@ import (
 
 func TestConfigMapHandler(t *testing.T) {
 	type args struct {
-		name      string
-		value     string
-		service   map[string]interface{}
-		resources []runtime.Object
-		expected  map[string]interface{}
+		name            string
+		value           string
+		service         map[string]interface{}
+		resources       []runtime.Object
+		expectedData    map[string]interface{}
+		expectedRawData map[string]interface{}
 	}
 
 	assertHandler := func(args args) func(*testing.T) {
@@ -45,7 +46,8 @@ func TestConfigMapHandler(t *testing.T) {
 			got, err := handler.Handle()
 			require.NoError(t, err)
 			require.NotNil(t, got)
-			require.Equal(t, args.expected, got.Data)
+			require.Equal(t, args.expectedData, got.Data)
+			require.Equal(t, args.expectedRawData, got.RawData)
 		}
 	}
 
@@ -75,11 +77,18 @@ func TestConfigMapHandler(t *testing.T) {
 				},
 			},
 		},
-		expected: map[string]interface{}{
+		expectedData: map[string]interface{}{
 			"configmap": map[string]interface{}{
 				"password": "hunter2",
 			},
 		},
+		expectedRawData: map[string]interface{}{
+			"status": map[string]interface{}{
+				"dbCredentials": map[string]interface{}{
+					"password": "hunter2",
+				},
+			},
+		},
 	}))
 
 	t.Run("configmap/map", assertHandler(args{
@@ -108,11 +117,19 @@ func TestConfigMapHandler(t *testing.T) {
 				},
 			},
 		},
-		expected: map[string]interface{}{
+		expectedData: map[string]interface{}{
 			"configmap": map[string]interface{}{
 				"username": "AzureDiamond",
 				"password": "hunter2",
 			},
 		},
+		expectedRawData: map[string]interface{}{
+			"status": map[string]interface{}{
+				"dbCredentials": map[string]interface{}{
+					"username": "AzureDiamond",
+					"password": "hunter2",
+				},
+			},
+		},
 	}))
 }
diff --git a/pkg/controller/servicebindingrequest/annotations/secret_test.go b/pkg/controller/servicebindingrequest/annotations/secret_test.go
index f8b5d596..e6b0d2bd 100644
--- a/pkg/controller/servicebindingrequest/annotations/secret_test.go
+++ b/pkg/controller/servicebindingrequest/annotations/secret_test.go
@@ -16,11 +16,12 @@ import (
 
 func TestSecretHandler(t *testing.T) {
 	type args struct {
-		name      string
-		value     string
-		service   map[string]interface{}
-		resources []runtime.Object
-		expected  map[string]interface{}
+		name            string
+		value           string
+		service         map[string]interface{}
+		resources       []runtime.Object
+		expectedData    map[string]interface{}
+		expectedRawData map[string]interface{}
 	}
 
 	assertHandler := func(args args) func(*testing.T) {
@@ -45,7 +46,8 @@ func TestSecretHandler(t *testing.T) {
 			got, err := handler.Handle()
 			require.NoError(t, err)
 			require.NotNil(t, got)
-			require.Equal(t, args.expected, got.Data)
+			require.Equal(t, args.expectedData, got.Data)
+			require.Equal(t, args.expectedRawData, got.RawData)
 		}
 	}
 
@@ -74,11 +76,18 @@ func TestSecretHandler(t *testing.T) {
 				},
 			},
 		},
-		expected: map[string]interface{}{
+		expectedData: map[string]interface{}{
 			"secret": map[string]interface{}{
 				"password": "hunter2",
 			},
 		},
+		expectedRawData: map[string]interface{}{
+			"status": map[string]interface{}{
+				"dbCredentials": map[string]interface{}{
+					"password": "hunter2",
+				},
+			},
+		},
 	}))
 
 	t.Run("secret/map", assertHandler(args{
@@ -107,11 +116,19 @@ func TestSecretHandler(t *testing.T) {
 				},
 			},
 		},
-		expected: map[string]interface{}{
+		expectedData: map[string]interface{}{
 			"secret": map[string]interface{}{
 				"username": "AzureDiamond",
 				"password": "hunter2",
 			},
 		},
+		expectedRawData: map[string]interface{}{
+			"status": map[string]interface{}{
+				"dbCredentials": map[string]interface{}{
+					"username": "AzureDiamond",
+					"password": "hunter2",
+				},
+			},
+		},
 	}))
 }
diff --git a/pkg/controller/servicebindingrequest/servicecontext_test.go b/pkg/controller/servicebindingrequest/servicecontext_test.go
index cb9324ac..d6609b47 100644
--- a/pkg/controller/servicebindingrequest/servicecontext_test.go
+++ b/pkg/controller/servicebindingrequest/servicecontext_test.go
@@ -189,11 +189,13 @@ func TestFindOwnedResourcesCtxs_ConfigMap(t *testing.T) {
 	f.AddMockResource(cr)
 	f.AddMockResource(us)
 	f.AddMockResource(&unstructured.Unstructured{Object: route})
+	logger := log.NewLog("testFindOwnedResourcesCtxs_cm")
 
 	restMapper := testutils.BuildTestRESTMapper()
 
 	t.Run("existing selectors", func(t *testing.T) {
 		got, err := findOwnedResourcesCtxs(
+			logger,
 			f.FakeDynClient(),
 			cr.GetNamespace(),
 			cr.GetName(),
@@ -251,6 +253,7 @@ func TestFindOwnedResourcesCtxs_Secrets(t *testing.T) {
 			f.S.AddKnownTypes(routev1.SchemeGroupVersion, &routev1.Route{})
 			f.AddMockResource(cr)
 			f.AddMockResource(&unstructured.Unstructured{Object: route})
+			logger := log.NewLog("testFindOwnedResourcesCtxs_secret")
 
 			restMapper := testutils.BuildTestRESTMapper()
 
@@ -265,6 +268,7 @@ func TestFindOwnedResourcesCtxs_Secrets(t *testing.T) {
 			}
 
 			ownedResourcesCtxs, err := findOwnedResourcesCtxs(
+				logger,
 				f.FakeDynClient(),
 				cr.GetNamespace(),
 				cr.GetName(),
diff --git a/test/acceptance/features/steps/dboperator.py b/test/acceptance/features/steps/dboperator.py
index 01187d3e..05910b97 100644
--- a/test/acceptance/features/steps/dboperator.py
+++ b/test/acceptance/features/steps/dboperator.py
@@ -14,9 +14,9 @@ class DbOperator():
 
     name = ""
     namespace = ""
-    operator_source_name = "db-operators"
-    operator_registry_namespace = "pmacik"
-    operator_registry_channel = "stable"
+    operator_catalog_source_name = "sample-db-operators"
+    operator_catalog_image = "quay.io/redhat-developer/sample-db-operators-olm:v1"
+    operator_catalog_channel = "stable"
     package_name = "db-operators"
 
     def __init__(self, name="postgresql-operator", namespace="openshift-operators"):
@@ -35,16 +35,19 @@ class DbOperator():
         else:
             return False
 
-    def install_operator_source(self):
-        install_src_output = self.openshift.create_operator_source(self.operator_source_name, self.operator_registry_namespace)
-        if not re.search(r'.*operatorsource.operators.coreos.com/%s\s(unchanged|created)' % self.operator_source_name, install_src_output):
-            print("Failed to create {} operator source".format(self.operator_source_name))
+    def install_catalog_source(self):
+        install_src_output = self.openshift.create_catalog_source(self.operator_catalog_source_name, self.operator_catalog_image)
+        if re.search(r'.*catalogsource.operators.coreos.com/%s\s(unchanged|created)' % self.operator_catalog_source_name, install_src_output) is None:
+            print("Failed to create {} catalog source".format(self.operator_catalog_source_name))
             return False
-        return self.openshift.wait_for_package_manifest(self.package_name, self.operator_source_name, self.operator_registry_channel)
+        return self.openshift.wait_for_package_manifest(self.package_name, self.operator_catalog_source_name, self.operator_catalog_channel)
 
     def install_operator_subscription(self):
-        install_sub_output = self.openshift.create_operator_subscription(self.package_name, self.operator_source_name, self.operator_registry_channel)
-        return re.search(r'.*subscription.operators.coreos.com/%s\s(unchanged|created)' % self.operator_source_name, install_sub_output)
+        install_sub_output = self.openshift.create_operator_subscription(self.package_name, self.operator_catalog_source_name, self.operator_catalog_channel)
+        if re.search(r'.*subscription.operators.coreos.com/%s\s(unchanged|created)' % self.package_name, install_sub_output) is None:
+            print("Failed to create {} operator subscription".format(self.package_name))
+            return False
+        return True
 
     def get_package_manifest(self):
         cmd = 'oc get packagemanifest %s -o "jsonpath={.metadata.name}"' % self.pkgManifest
diff --git a/test/acceptance/features/steps/openshift.py b/test/acceptance/features/steps/openshift.py
index 10bafe93..13322b68 100644
--- a/test/acceptance/features/steps/openshift.py
+++ b/test/acceptance/features/steps/openshift.py
@@ -9,17 +9,19 @@ nodejs_app = "https://github.com/pmacik/nodejs-rest-http-crud"
 class Openshift(object):
     def __init__(self):
         self.cmd = Command()
-        self.operator_source_yaml_template = '''
----
-apiVersion: operators.coreos.com/v1
-kind: OperatorSource
+        self.catalog_source_yaml_template = '''
+apiVersion: operators.coreos.com/v1alpha1
+kind: CatalogSource
 metadata:
     name: {name}
     namespace: openshift-marketplace
 spec:
-    type: appregistry
-    endpoint: https://quay.io/cnr
-    registryNamespace: {registry_namespace}
+    sourceType: grpc
+    image: {catalog_image}
+    displayName: {name} OLM registry
+    updateStrategy:
+        registryPoll:
+            interval: 30m
 '''
         self.operator_subscription_yaml_template = '''
 ---
@@ -102,9 +104,9 @@ spec:
         (output, exit_code) = self.cmd.run("oc apply -f -", yaml)
         return output
 
-    def create_operator_source(self, name, registry_namespace):
-        operator_source = self.operator_source_yaml_template.format(name=name, registry_namespace=registry_namespace)
-        return self.oc_apply(operator_source)
+    def create_catalog_source(self, name, catalog_image):
+        catalog_source = self.catalog_source_yaml_template.format(name=name, catalog_image=catalog_image)
+        return self.oc_apply(catalog_source)
 
     def get_current_csv(self, package_name, catalog, channel):
         cmd = f'oc get packagemanifests -o json | jq -r \'.items[] \
diff --git a/test/acceptance/features/steps/steps.py b/test/acceptance/features/steps/steps.py
index ec881eb2..ed29f87c 100644
--- a/test/acceptance/features/steps/steps.py
+++ b/test/acceptance/features/steps/steps.py
@@ -82,7 +82,7 @@ def given_db_operator_is_installed(context):
     db_operator = DbOperator()
     if not db_operator.is_running():
         print("DB operator is not installed, installing...")
-        db_operator.install_operator_source() | should.be_truthy.desc("DB operator source installed")
+        db_operator.install_catalog_source() | should.be_truthy.desc("DB catalog source installed")
         db_operator.install_operator_subscription() | should.be_truthy.desc("DB operator subscription installed")
         db_operator.is_running(wait=True) | should.be_truthy.desc("DB operator installed")
     print("PostgresSQL DB operator is running!!!")