diff options
104 files changed, 4173 insertions, 2460 deletions
diff --git a/.github/scripts/prescan-go-coverage-ubuntu.sh b/.github/scripts/prescan-go-coverage-ubuntu.sh new file mode 100644 index 0000000..f7e9d55 --- /dev/null +++ b/.github/scripts/prescan-go-coverage-ubuntu.sh @@ -0,0 +1,12 @@ +# SPDX-License-Identifier: Apache-2.0 +# SPDX-FileCopyrightText: 2025 The Linux Foundation + +#!/bin/bash +echo "--> prescan-go-coverage-ubuntu.sh" + +set -ex + +# Test and coverage +go test -p 1 ./... -coverprofile=coverage.out + +echo "--> prescan-go-coverage-ubuntu.sh ends" diff --git a/.github/workflows/gerrit-opa-performance-test.yaml b/.github/workflows/gerrit-opa-performance-test.yaml index b105f0b..54855dd 100755 --- a/.github/workflows/gerrit-opa-performance-test.yaml +++ b/.github/workflows/gerrit-opa-performance-test.yaml @@ -70,7 +70,7 @@ on: # Run everyday at 16:30 UTC schedule: - cron: '30 16 * * *' - + jobs: run-s3p-tests: runs-on: ubuntu-22.04 @@ -80,7 +80,7 @@ jobs: - name: Run S3P script working-directory: ${{ github.workspace }}/testsuites - run: sudo bash ./run-s3p-test.sh run performance + run: sudo bash ./run-s3p-test.sh performance - name: Archive result jtl uses: actions/upload-artifact@v4 diff --git a/.github/workflows/gerrit-opa-stability-test.yaml b/.github/workflows/gerrit-opa-stability-test.yaml index 65e269d..09db4c5 100755 --- a/.github/workflows/gerrit-opa-stability-test.yaml +++ b/.github/workflows/gerrit-opa-stability-test.yaml @@ -70,7 +70,7 @@ on: # Run everyday at 16:30 UTC schedule: - cron: '30 16 * * *' - + jobs: run-s3p-tests: runs-on: ubuntu-22.04 @@ -80,7 +80,7 @@ jobs: - name: Run S3P script working-directory: ${{ github.workspace }}/testsuites - run: sudo bash ./run-s3p-test.sh run stability + run: sudo bash ./run-s3p-test.sh stability - name: Archive result jtl uses: actions/upload-artifact@v4 diff --git a/.github/workflows/security-audits.yaml b/.github/workflows/security-audits.yaml index 77c7534..0160ed8 100644 --- a/.github/workflows/security-audits.yaml +++ b/.github/workflows/security-audits.yaml @@ -26,18 +26,18 @@ on: permissions: {} jobs: - sonatype-lifecycle: - name: "Sonatype Lifecycle" - # yamllint disable-line rule:line-length - uses: lfit/releng-reusable-workflows/.github/workflows/reuse-sonatype-lifecycle.yaml@83e3ea0dcbfb1e8c707b0284ae7e7c376b0e27d4 # v0.2.7 - secrets: - NEXUS_IQ_PASSWORD: ${{ secrets.NEXUS_IQ_PASSWORD }} + #sonatype-lifecycle: + # name: "Sonatype Lifecycle" + # # yamllint disable-line rule:line-length + # uses: lfit/releng-reusable-workflows/.github/workflows/reuse-sonatype-lifecycle.yaml@83e3ea0dcbfb1e8c707b0284ae7e7c376b0e27d4 # v0.2.7 + # secrets: + # NEXUS_IQ_PASSWORD: ${{ secrets.NEXUS_IQ_PASSWORD }} # Scan results are found at: https://sonarcloud.io/login sonarqube-cloud: name: "SonarQube Cloud" # yamllint disable-line rule:line-length - uses: lfit/releng-reusable-workflows/.github/workflows/reuse-sonarqube-cloud.yaml@83e3ea0dcbfb1e8c707b0284ae7e7c376b0e27d4 # v0.2.7 + uses: lfit/releng-reusable-workflows/.github/workflows/reuse-sonarqube-cloud.yaml@ac846b1cfeaf3a7cac6f28413a5206afc9951464 # v0.2.11 permissions: # Needed to upload the results to code-scanning dashboard. security-events: write @@ -48,3 +48,6 @@ jobs: # actions: read secrets: SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + with: + BUILD_WRAPPER_URL: https://raw.githubusercontent.com/onap/policy-opa-pdp/refs/heads/master/.github/scripts/prescan-go-coverage-ubuntu.sh + BUILD_WRAPPER_OUT_DIR: . @@ -1,71 +1,50 @@ # Running docker policy-opa-pdp ## Building Docker Image. -docker build -f ./build/Dockerfile -t opa-pdp:1.0.0 . +docker build -t opa-pdp:1.0.0 . -## Running the containers and Testing - -1. docker image ls | grep opa-pdp - -2. inside test directory run - docker-compose down - -3. docker-compose up -d - -4. docker logs -f opa-pdp ## Generating models with openapi.yaml 1. oapi-codegen -package=oapicodegen -generate "models" openapi.yaml > models.go -## Creating new Policy -1. Create a new directory under test/polices. For example - role +## Creating New Policy -2. Inside this directory create a policy [i.e; rego file] named policy.rego. Version 1 i.e v1 is supported for rego files. - -3. For contents you can see example of policy.rego under test/policies/role/policy.rego. +1. Create a tosca policy file that has policy.rego and data.json encoded contents. -3. Inside test/policies/data create a new directory with the package name of policy.rego. For example test/policies/data/role +2. Ensure data key should have node as prefix. For example refer to test/test_resources/blacklist/policy_blacklist.yaml. -4. Create a file data.json under the newly created directory inside data. For example test/policies/data/data.json +3. OPA emphasizes that each policy should have a unique policy-name/policy-id, -5. In policy.rego the package declaration organizes the policy rules. This allows + example: + Not Allowed: + 1. If a policy named onap.org.cell is deployed, then deploying a policy named onap.org.cell.consistency is disallowed because it shares the same hierarchical structure. -6. The Rule allow evaluates to true/false based on the logic defined in policy.rego + 2. If a policy named onap.org.cell is deployed, then deploying a policy named onap.org is disallowed because it is parent directory. -7. Data.json is files is kept within the directory named after policy package name under data folders. For example policies/data/role/data.json. + Allowed: If a policy named onap.org.cell is deployed, then deploying a policy named onap.org.consistency is permitted, as it does not share the same hierarchy. -8. To reference the data inside policy.rego we need to define rule as data.folder-name.attribute. For example you can refer to policy.rego under rules, data.role.user_roles. -9. To deploy a new policy opa-pdp need to be redpolyed i.e; docker-compose down and up need to be executed. +4. Policy key should start (prefixed) with policy-id. For ex refer to test/test_resources/blacklist/policy_blacklist.yaml. -## Deploying New Policy +5. Create a deploy.json file to deploy through pap. Refer to file under test/test_resources/blacklist/deploy_blacklist.json. -1. Create a tosca policy file that has policy.rego and data.json encoded contents. +## Deploy Policy Using Docker Compose -2. For example refer to test/policy_deployment.yaml. +1. Ensure you have docker and docker-compose installed -3. OPA emphasizes that each policy should have a unique policy-name/policy-id, +2. Check out the policy/docker repo from the ONAP gerrit or from github: https://github.com/onap/policy-docker - example: - Not Allowed --> when policy with name onap.org.cell is deployed and when onap.org.cell.consistency not allowed for deployment since it carries the same hierarchy. - Allowed --> Policy with name onap.org.cell is deployed and when onap.org.consistency is allowed for deployment since it does not have the same hierarchy. +3. Latest Docker image created can be updated in compose.yml inside policy/docker repo. +4. Start opa-pdp containers by running the start-compose.sh script -4. Policy and data key should start (prefixed) with policy-id. For ex refer totest/testresources/policy_deploy_single_policy.yaml. +5. Command to start opa-pdp container ./start-compose.sh opa-pdp -5. Create a deploy.json file to deploy through pap. Refer to file under test/testresources/deploy.json. +6. Check the logs. docker logs -f policy-opa-pdp ## Testing Decision Api -send json -{"onapName":"CDS","onapComponent":"CDS","onapInstance":"CDS","currentDate": "2024-11-22", "currentTime": "2024-11-22T11:34:56Z", "timeZone": "UTC", "timeOffset": "+05:30", "currentDateTime": "2024-11-22 12:08:00.123456+0000 ", "policyName":"role/allow","input":{"user":"alice","action":"write","object":"id123","type":"dog"}} -to opa-pdp as shown in curl commands below. - -"policyName":"[packagename in rego file]/allow" - Policy to be refrenced as policyName:role/allow in case when policy's package name is role. Change it according to your package name of the policy. - -"input":{"user":"alice","action":"read","object":"id123","type":"dog"} - Input defines the specific data to be evaluated by the Rego policy - +To get opa Decision for the deployed policies please refer to test/README.md for the API details. diff --git a/api/openapi.yaml b/api/openapi.yaml index 685bd4f..d8afb2f 100644 --- a/api/openapi.yaml +++ b/api/openapi.yaml @@ -441,13 +441,15 @@ components: items: type: string input: - type: object - additionalProperties: true - example: + anyOf: + - x-go-type: "interface{}" + - type: object + additionalProperties: true + example: user: alice action: read object: id123 - type: dog + type: dog required: - policyName - policyFilter diff --git a/api/register-handlers.go b/api/register-handlers.go index 49b953f..ab71afe 100644 --- a/api/register-handlers.go +++ b/api/register-handlers.go @@ -57,6 +57,8 @@ func RegisterHandlers() { dataHandler := http.HandlerFunc(data.DataHandler) http.Handle("/policy/pdpo/v1/data/", basicAuth(dataHandler)) + http.Handle("/policy/pdpo/v1/data", basicAuth(dataHandler)) + } // handles authentication diff --git a/cfg/config.go b/cfg/config.go index e828b18..62d4853 100644 --- a/cfg/config.go +++ b/cfg/config.go @@ -24,11 +24,11 @@ package cfg import ( "fmt" + "github.com/google/uuid" log "github.com/sirupsen/logrus" "os" "regexp" "strconv" - "github.com/google/uuid" ) // LogLevel - The log level for the application. @@ -66,7 +66,7 @@ func init() { LogLevel = getEnv("LOG_LEVEL", "info") BootstrapServer = getEnv("KAFKA_URL", "kafka:9092") Topic = getEnv("PAP_TOPIC", "policy-pdp-pap") - GroupId = getEnv("GROUPID", "opa-pdp-" + uuid.New().String()) + GroupId = getEnv("GROUPID", "opa-pdp-"+uuid.New().String()) Username = getEnv("API_USER", "policyadmin") Password = getEnv("API_PASSWORD", "zb!XztG34") UseSASLForKAFKA = getEnv("UseSASLForKAFKA", "false") diff --git a/cmd/opa-pdp/opa-pdp.go b/cmd/opa-pdp/opa-pdp.go index 3a8a52f..6880f0e 100644 --- a/cmd/opa-pdp/opa-pdp.go +++ b/cmd/opa-pdp/opa-pdp.go @@ -34,6 +34,7 @@ import ( "policy-opa-pdp/pkg/kafkacomm/publisher" "policy-opa-pdp/pkg/log" "policy-opa-pdp/pkg/opasdk" + "policy-opa-pdp/pkg/pdpattributes" "syscall" "time" ) @@ -93,11 +94,8 @@ func main() { time.Sleep(10 * time.Second) - // pdp registration - isRegistered := registerPDPFunc(sender) - if !isRegistered { - return - } + pdpattributes.SetPdpHeartbeatInterval(int64(consts.DefaultHeartbeatMS)) + go publisher.StartHeartbeatIntervalTimer(pdpattributes.PdpHeartbeatInterval, sender) time.Sleep(10 * time.Second) log.Debugf("After registration successful delay") @@ -164,7 +162,7 @@ func shutdownHTTPServer(server *http.Server) { } func waitForServer() { - time.Sleep(time.Duration(consts.SERVER_WAIT_UP_TIME) * time.Second) + time.Sleep(time.Duration(consts.ServerWaitUpTime) * time.Second) } func initializeOPA() error { @@ -232,6 +230,5 @@ myLoop: handler.SetShutdownFlag() - time.Sleep(time.Duration(consts.SHUTDOWN_WAIT_TIME) * time.Second) + time.Sleep(time.Duration(consts.ShutdownWaitTime) * time.Second) } - diff --git a/cmd/opa-pdp/opa-pdp_test.go b/cmd/opa-pdp/opa-pdp_test.go index bc3aba6..37f4314 100644 --- a/cmd/opa-pdp/opa-pdp_test.go +++ b/cmd/opa-pdp/opa-pdp_test.go @@ -20,9 +20,11 @@ package main import ( - "context" "errors" + "github.com/confluentinc/confluent-kafka-go/v2/kafka" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" "net/http" "os" "policy-opa-pdp/consts" @@ -33,9 +35,6 @@ import ( "policy-opa-pdp/pkg/model" "testing" "time" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/mock" - "github.com/confluentinc/confluent-kafka-go/v2/kafka" ) // Mock objects and functions @@ -57,24 +56,23 @@ func (m *MockKafkaConsumerInterface) ReadMessage(kc *kafkacomm.KafkaConsumer) ([ } type MockKafkaProducer struct { - mock.Mock + mock.Mock } func (m *MockKafkaProducer) Produce(message *kafka.Message, evenchan chan kafka.Event) error { - args := m.Called(message) - return args.Error(0) + args := m.Called(message) + return args.Error(0) } func (m *MockKafkaProducer) Close() { - m.Called() + m.Called() } func (m *MockKafkaProducer) Flush(timeout int) int { - m.Called(timeout) - return 0 + m.Called(timeout) + return 0 } - type MockPdpStatusSender struct { mock.Mock } @@ -101,7 +99,7 @@ func (m *MockServer) Shutdown() error { // Test to verify the application handles the shutdown process gracefully. func TestHandleShutdown(t *testing.T) { - consts.SHUTDOWN_WAIT_TIME = 0 + consts.ShutdownWaitTime = 0 mockConsumer := new(mocks.KafkaConsumerInterface) mockConsumer.On("Unsubscribe").Return(nil) mockConsumer.On("Close").Return(nil) @@ -111,15 +109,14 @@ func TestHandleShutdown(t *testing.T) { Consumer: mockConsumer, } // Create the mock producer - mockProducer := new(MockKafkaProducer) + mockProducer := new(MockKafkaProducer) - // Mock the Produce method to simulate success - mockProducer.On("Produce", mock.Anything).Return(nil) - //t.Fatalf("Inside Sender checking for producer , but got: %v", mockProducer) + // Mock the Produce method to simulate success + mockProducer.On("Produce", mock.Anything).Return(nil) + //t.Fatalf("Inside Sender checking for producer , but got: %v", mockProducer) - - // Create the RealPdpStatusSender with the mocked producer - kafkaProducer = &kafkacomm.KafkaProducer{} + // Create the RealPdpStatusSender with the mocked producer + kafkaProducer = &kafkacomm.KafkaProducer{} interruptChannel := make(chan os.Signal, 1) _, cancel := context.WithCancel(context.Background()) @@ -144,15 +141,16 @@ func TestHandleShutdown(t *testing.T) { } } -var testServer *http.Server +var testServer *http.Server var kafkaConsumer *kafkacomm.KafkaConsumer var kafkaProducer *kafkacomm.KafkaProducer + // Test the main function to ensure it's initialization, startup, and shutdown correctly. func SetupMocks() { // Mock dependencies and expected behavior - testServer = &http.Server{} - kafkaConsumer= &kafkacomm.KafkaConsumer{} - kafkaProducer= &kafkacomm.KafkaProducer{} + testServer = &http.Server{} + kafkaConsumer = &kafkacomm.KafkaConsumer{} + kafkaProducer = &kafkacomm.KafkaProducer{} // Mock initializeHandlers initializeHandlersFunc = func() { log.Debug("Handlers initialized") @@ -181,15 +179,14 @@ func SetupMocks() { return nil // no error expected } - registerPDPFunc = func(sender publisher.PdpStatusSender) bool { // Simulate the registration logic here - return false// Simulate successful registration + return false // Simulate successful registration } - handleMessagesFunc = func(ctx context.Context, kc *kafkacomm.KafkaConsumer, sender *publisher.RealPdpStatusSender) { - return - } + handleMessagesFunc = func(ctx context.Context, kc *kafkacomm.KafkaConsumer, sender *publisher.RealPdpStatusSender) { + return + } // Mock handleShutdown interruptChannel := make(chan os.Signal, 1) @@ -199,14 +196,13 @@ func SetupMocks() { } } -func TestKafkaConsumerInitializationFailure(t *testing.T){ - +func TestKafkaConsumerInitializationFailure(t *testing.T) { - SetupMocks() + SetupMocks() startKafkaConsAndProdFunc = func() (*kafkacomm.KafkaConsumer, *kafkacomm.KafkaProducer, error) { - return nil, nil, assert.AnError // return mocked consumer and producer - } + return nil, nil, assert.AnError // return mocked consumer and producer + } // Run main function in a goroutine done := make(chan struct{}) @@ -219,83 +215,54 @@ func TestKafkaConsumerInitializationFailure(t *testing.T){ interruptChannel := make(chan os.Signal, 1) interruptChannel <- os.Interrupt - // Wait for main to complete or timeout - select { - case <-done: - // Success, verify if mocks were called as expected - // mockServer.AssertCalled(t, "Shutdown") - case <-time.After(1 * time.Second): - // t.Error("main function timed out") - } - // Verify assertions assert.True(t, true, "main function executed successfully") } -func TestKafkaConsumerInitializationSuccess(t *testing.T){ - +func TestKafkaConsumerInitializationSuccess(t *testing.T) { - SetupMocks() + SetupMocks() - startKafkaConsAndProdFunc = func() (*kafkacomm.KafkaConsumer, *kafkacomm.KafkaProducer, error) { - return kafkaConsumer, kafkaProducer, nil // return mocked consumer and producer - } - - // Run main function in a goroutine - done := make(chan struct{}) - go func() { - main() - close(done) - }() + startKafkaConsAndProdFunc = func() (*kafkacomm.KafkaConsumer, *kafkacomm.KafkaProducer, error) { + return kafkaConsumer, kafkaProducer, nil // return mocked consumer and producer + } - // Simulate an interrupt to trigger shutdown - interruptChannel := make(chan os.Signal, 1) - interruptChannel <- os.Interrupt + // Run main function in a goroutine + done := make(chan struct{}) + go func() { + main() + close(done) + }() - // Wait for main to complete or timeout - select { - case <-done: - // Success, verify if mocks were called as expected - // mockServer.AssertCalled(t, "Shutdown") - case <-time.After(1 * time.Second): - // t.Error("main function timed out") - } + // Simulate an interrupt to trigger shutdown + interruptChannel := make(chan os.Signal, 1) + interruptChannel <- os.Interrupt - // Verify assertions - assert.True(t, true, "main function executed successfully") + // Verify assertions + assert.True(t, true, "main function executed successfully") } -func TestKafkaNilConsumerInitialization(t *testing.T){ - - - SetupMocks() +func TestKafkaNilConsumerInitialization(t *testing.T) { - startKafkaConsAndProdFunc = func() (*kafkacomm.KafkaConsumer, *kafkacomm.KafkaProducer, error) { - return nil, kafkaProducer, nil // return mocked consumer and producer - } + SetupMocks() - // Run main function in a goroutine - done := make(chan struct{}) - go func() { - main() - close(done) - }() + startKafkaConsAndProdFunc = func() (*kafkacomm.KafkaConsumer, *kafkacomm.KafkaProducer, error) { + return nil, kafkaProducer, nil // return mocked consumer and producer + } - // Simulate an interrupt to trigger shutdown - interruptChannel := make(chan os.Signal, 1) - interruptChannel <- os.Interrupt + // Run main function in a goroutine + done := make(chan struct{}) + go func() { + main() + close(done) + }() - // Wait for main to complete or timeout - select { - case <-done: - // Success, verify if mocks were called as expected - // mockServer.AssertCalled(t, "Shutdown") - case <-time.After(1 * time.Second): - // t.Error("main function timed out") - } + // Simulate an interrupt to trigger shutdown + interruptChannel := make(chan os.Signal, 1) + interruptChannel <- os.Interrupt - // Verify assertions - assert.True(t, true, "main function executed successfully") + // Verify assertions + assert.True(t, true, "main function executed successfully") } // Test to verify that the HTTP server starts successfully. @@ -311,8 +278,6 @@ func TestInitializeOPA(t *testing.T) { assert.Error(t, err, "Expected error from initializeOPA") } - - // Test to ensure the application correctly waits for the server to be ready. func TestWaitForServer(t *testing.T) { waitForServerFunc = func() { @@ -592,7 +557,6 @@ func TestStartKafkaProducerFailure(t *testing.T) { assert.Nil(t, consumer) assert.Nil(t, producer) - NewKafkaConsumer = originalNewKafkaConsumer GetKafkaProducer = originalGetKafkaProducer }) @@ -625,12 +589,12 @@ func TestStartKafkaAndProdSuccess(t *testing.T) { // Test to verify that the shutdown process handles a nil Kafka consumer gracefully func TestHandleShutdownWithNilConsumer(t *testing.T) { - consts.SHUTDOWN_WAIT_TIME = 0 + consts.ShutdownWaitTime = 0 interruptChannel := make(chan os.Signal, 1) ctx, cancel := context.WithCancel(context.Background()) defer cancel() - kafkaProducer := &kafkacomm.KafkaProducer{} + kafkaProducer := &kafkacomm.KafkaProducer{} // Simulate sending an interrupt signal go func() { time.Sleep(500 * time.Millisecond) @@ -668,7 +632,7 @@ func TestHandleMessages_ErrorInPdpMessageHandler(t *testing.T) { } originalPdpMessageHandler := PdpMessageHandler - PdpMessageHandler = func(ctx context.Context, kc *kafkacomm.KafkaConsumer, topic string, p publisher.PdpStatusSender) error { + PdpMessageHandler = func(ctx context.Context, kc *kafkacomm.KafkaConsumer, topic string, p publisher.PdpStatusSender) error { return errors.New("simulated error in PdpMessageHandler") } diff --git a/consts/constants.go b/consts/constants.go index d800e0d..6e2eedb 100644 --- a/consts/constants.go +++ b/consts/constants.go @@ -1,6 +1,6 @@ // - // ========================LICENSE_START================================= -// Copyright (C) 2024: Deutsche Telekom +// Copyright (C) 2024-2025: Deutsche Telekom // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -31,6 +31,7 @@ package consts // BuildBundle - The command to build the bundle. // Policies - The directory path for policies. // Data - The directory path for policy data. +// DataNode - The directory path for policy data with node. // Output - The output flag for bundle commands. // BundleTarGz - The name of the bundle tar.gz file. // BundleTarGzFile - The file path for the bundle tar.gz file. @@ -38,8 +39,8 @@ package consts // PdpType - The type of PDP. // ServerPort - The port on which the server listens. // SERVER_WAIT_UP_TIME - The time to wait for the server to be up, in seconds. -// SHUTDOWN_WAIT_TIME - The time to wait for the server to shut down, in seconds. -// V1_COMPATIBLE - The flag for v1 compatibility. +// ShutdownWaitTime - The time to wait for the server to shut down, in seconds. +// V1Compatible - The flag for v1 compatibility. // LatestVersion - The Version set in response for decision // MinorVersion - The Minor version set in response header for decision // PatchVersion - The Patch Version set in response header for decison @@ -47,6 +48,8 @@ package consts // HealtCheckStatus - The bool flag for Healthy field in HealtCheck response // OkCode - The Code for HealthCheck response // HealthCheckMessage - The Healtcheck Message +// SingleHierarchy - The Counter indicates the length of datakey path +// DefaultHeartbeatMS - The default interval for heartbeat signals in milliseconds. var ( LogFilePath = "/var/logs/logs.log" LogMaxSize = 10 @@ -56,21 +59,24 @@ var ( BuildBundle = "build" Policies = "/opt/policies" Data = "/opt/data" + DataNode = "/opt/data/node" Output = "-o" BundleTarGz = "bundle.tar.gz" BundleTarGzFile = "/app/bundles/bundle.tar.gz" PdpGroup = "opaGroup" //This is a workaround as currently opa-pdp is not defined in the PapDB defaultGroup configuration and creating it manually overrides the existing configuration, so currently PdpGroup is opaGroup and it will be changed to defaultGroup once added in the configuration. - PdpType = "opa" - ServerPort = ":8282" - SERVER_WAIT_UP_TIME = 5 - SHUTDOWN_WAIT_TIME = 5 - V1_COMPATIBLE = "--v1-compatible" - LatestVersion = "1.0.0" - MinorVersion = "0" - PatchVersion = "0" - OpaPdpUrl = "self" - HealtCheckStatus = true - OkCode = int32(200) - HealthCheckMessage = "alive" + PdpType = "opa" + ServerPort = ":8282" + ServerWaitUpTime = 5 + ShutdownWaitTime = 5 + V1Compatible = "--v1-compatible" + LatestVersion = "1.0.0" + MinorVersion = "0" + PatchVersion = "0" + OpaPdpUrl = "self" + HealtCheckStatus = true + OkCode = int32(200) + HealthCheckMessage = "alive" + SingleHierarchy = 4 + DefaultHeartbeatMS = 60000 ) diff --git a/pkg/data/data-handler.go b/pkg/data/data-handler.go index b571010..673f247 100644 --- a/pkg/data/data-handler.go +++ b/pkg/data/data-handler.go @@ -21,8 +21,10 @@ package data import ( "context" "encoding/json" + "fmt" "github.com/google/uuid" openapi_types "github.com/oapi-codegen/runtime/types" + "github.com/open-policy-agent/opa/storage" "net/http" "path/filepath" "policy-opa-pdp/consts" @@ -30,11 +32,9 @@ import ( "policy-opa-pdp/pkg/metrics" "policy-opa-pdp/pkg/model/oapicodegen" "policy-opa-pdp/pkg/opasdk" + "policy-opa-pdp/pkg/policymap" "policy-opa-pdp/pkg/utils" "strings" - - "github.com/open-policy-agent/opa/storage" - "policy-opa-pdp/pkg/policymap" ) var ( @@ -78,60 +78,30 @@ func createOPADataUpdateExceptionResponse(statusCode int, errorMessage string, p } } -// Validate OPADataUpdateRequest function -func validateOPADataUpdateRequest(request *oapicodegen.OPADataUpdateRequest) []string { - var validationErrors []string - - // Check if required fields are populated - dateString := (request.CurrentDate).String() - if !(utils.IsValidCurrentDate(&dateString)) { - validationErrors = append(validationErrors, "CurrentDate is required") - } - - // Validate CurrentDateTime format - if !(utils.IsValidTime(request.CurrentDateTime)) { - validationErrors = append(validationErrors, "CurrentDateTime is invalid or missing") - } - - // Validate CurrentTime format - if !(utils.IsValidCurrentTime(request.CurrentTime)) { - validationErrors = append(validationErrors, "CurrentTime is invalid or missing") - } - - // Validate Data field (ensure it's not nil and has items) - if !(utils.IsValidData(request.Data)) { - validationErrors = append(validationErrors, "Data is required and cannot be empty") - } - - // Validate TimeOffset format (e.g., +02:00 or -05:00) - if !(utils.IsValidTimeOffset(request.TimeOffset)) { - validationErrors = append(validationErrors, "TimeOffset is invalid or missing") - } - - // Validate TimeZone format (e.g., 'America/New_York') - if !(utils.IsValidTimeZone(request.TimeZone)) { - validationErrors = append(validationErrors, "TimeZone is invalid or missing") - } - - // Optionally, check if 'OnapComponent', 'OnapInstance', 'OnapName', and 'PolicyName' are provided - if !(utils.IsValidString(request.OnapComponent)) { - validationErrors = append(validationErrors, "OnapComponent is required") - } +type Policy struct { + Data []string `json:"data"` + Policy []string `json:"policy"` + PolicyID string `json:"policy-id"` + PolicyVersion string `json:"policy-version"` +} - if !(utils.IsValidString(request.OnapInstance)) { - validationErrors = append(validationErrors, "OnapInstance is required") +// Function to extract the policy by policyId +func getPolicyByID(policiesMap string, policyId string) (*Policy, error) { + var policies struct { + DeployedPolicies []Policy `json:"deployed_policies_dict"` } - if !(utils.IsValidString(request.OnapName)) { - validationErrors = append(validationErrors, "OnapName is required") + if err := json.Unmarshal([]byte(policiesMap), &policies); err != nil { + return nil, fmt.Errorf("failed to unmarshal policies: %v", err) } - if !(utils.IsValidString(request.PolicyName)) { - validationErrors = append(validationErrors, "PolicyName is required and cannot be empty") + for _, policy := range policies.DeployedPolicies { + if policy.PolicyID == policyId { + return &policy, nil + } } - // Return all validation errors (if any) - return validationErrors + return nil, fmt.Errorf("policy '%s' not found", policyId) } func patchHandler(res http.ResponseWriter, req *http.Request) { @@ -144,13 +114,18 @@ func patchHandler(res http.ResponseWriter, req *http.Request) { log.Errorf(errMsg) return } - path := strings.TrimPrefix(req.URL.Path, "/policy/pdpo/v1/data/") + path := strings.TrimPrefix(req.URL.Path, "/policy/pdpo/v1/data") dirParts := strings.Split(path, "/") dataDir := filepath.Join(dirParts...) log.Infof("dataDir : %s", dataDir) // Validate the request - validationErrors := validateOPADataUpdateRequest(&requestBody) + validationErrors := utils.ValidateOPADataRequest(&requestBody) + + // Validate Data field (ensure it's not nil and has items) + if !(utils.IsValidData(requestBody.Data)) { + validationErrors = append(validationErrors, "Data is required and cannot be empty") + } // Print validation errors if len(validationErrors) > 0 { @@ -159,7 +134,7 @@ func patchHandler(res http.ResponseWriter, req *http.Request) { sendErrorResponse(res, errMsg, http.StatusBadRequest) return } else { - log.Errorf("All fields are valid!") + log.Debug("All fields are valid!") // Access the data part data := requestBody.Data log.Infof("data : %s", data) @@ -172,10 +147,46 @@ func patchHandler(res http.ResponseWriter, req *http.Request) { log.Errorf(errMsg) return } + + // Checking if the data operation is performed for a deployed policy with policymap.CheckIfPolicyAlreadyExists and getPolicyByID + // if a match is found, we will join the url path with dots and check for the data key from the policiesMap whether utl path is a + // prefix of data key. we will proceed for Patch Operation if this matches, else return error + if len(dirParts) > 0 && dirParts[0] == "" { + dirParts = dirParts[1:] + } + finalDirParts := strings.Join(dirParts, ".") + + policiesMap := policymap.LastDeployedPolicies + + matchedPolicy, err := getPolicyByID(policiesMap, *policyId) + if err != nil { + sendErrorResponse(res, err.Error(), http.StatusBadRequest) + log.Errorf(err.Error()) + return + } + + log.Infof("Matched policy: %+v", matchedPolicy) + + // Check if finalDirParts starts with any data key + matchFound := false + for _, dataKey := range matchedPolicy.Data { + if strings.HasPrefix(finalDirParts, dataKey) { + matchFound = true + break + } + } + + if !matchFound { + errMsg := fmt.Sprintf("Dynamic Data add/replace/remove for policy '%s' expected under url path '%v'", *policyId, matchedPolicy.Data) + sendErrorResponse(res, errMsg, http.StatusBadRequest) + log.Errorf(errMsg) + return + } + if err := patchData(dataDir, data, res); err != nil { - // Handle the error, for example, log it or return an appropriate response - log.Errorf("Error encoding JSON response: %s", err) - } + // Handle the error, for example, log it or return an appropriate response + log.Errorf("Error encoding JSON response: %s", err) + } } } @@ -215,7 +226,7 @@ func extractPatchInfo(res http.ResponseWriter, ops *[]map[string]interface{}, ro // PATCH request with add or replace opType, MUST contain a "value" member whose content specifies the value to be added / replaced. For remove opType, value does not required if optypeString == "add" || optypeString == "replace" { value, valueErr = op["value"] - if !valueErr { + if !valueErr || isEmpty(value) { valueErrMsg := "Error in getting data value. Value is not given in request body" sendErrorResponse(res, valueErrMsg, http.StatusInternalServerError) log.Errorf(valueErrMsg) @@ -225,7 +236,7 @@ func extractPatchInfo(res http.ResponseWriter, ops *[]map[string]interface{}, ro impl.Value = value opPath, opPathErr := op["path"].(string) - if !opPathErr { + if !opPathErr || len(opPath) == 0 { opPathErrMsg := "Error in getting data path. Path is not given in request body" sendErrorResponse(res, opPathErrMsg, http.StatusInternalServerError) log.Errorf(opPathErrMsg) @@ -243,6 +254,35 @@ func extractPatchInfo(res http.ResponseWriter, ops *[]map[string]interface{}, ro return result } +func isEmpty(data interface{}) bool { + if data == nil { + return true // Nil values are considered empty + } + + switch v := data.(type) { + case string: + return len(v) == 0 // Check if string is empty + case []interface{}: + return len(v) == 0 // Check if slice is empty + case map[string]interface{}: + return len(v) == 0 // Check if map is empty + case []byte: + return len(v) == 0 // Check if byte slice is empty + case int, int8, int16, int32, int64: + return v == 0 // Zero integers are considered empty + case uint, uint8, uint16, uint32, uint64: + return v == 0 // Zero unsigned integers are considered empty + case float32, float64: + return v == 0.0 // Zero floats are considered empty + case bool: + return !v // `false` is considered empty + case nil: + return true // Explicitly checking nil again + default: + return false // Other data types are not considered empty + } +} + func constructPath(opPath string, opType string, root string, res http.ResponseWriter) (storagePath storage.Path) { // Construct patch path. log.Debugf("root: %s", root) @@ -269,13 +309,10 @@ func constructPath(opPath string, opType string, root string, res http.ResponseW path = root + "/" + path } } else { - if opType == "remove" { - valueErrMsg := "Error in getting data path - Invalid path (/) is used." - sendErrorResponse(res, valueErrMsg, http.StatusInternalServerError) - log.Errorf(valueErrMsg) - return nil - } - path = root + valueErrMsg := "Error in getting data path - Invalid path (/) is used." + sendErrorResponse(res, valueErrMsg, http.StatusInternalServerError) + log.Errorf(valueErrMsg) + return nil } log.Infof("calling ParsePatchPathEscaped to check the path") @@ -386,7 +423,13 @@ func getDataInfo(res http.ResponseWriter, req *http.Request) { constructResponseHeader(res, req) urlPath := req.URL.Path - dataPath := strings.ReplaceAll(urlPath, "/policy/pdpo/v1/data", "") + + dataPath := strings.TrimPrefix(urlPath, "/policy/pdpo/v1/data") + + if len(strings.TrimSpace(dataPath)) == 0 { + // dataPath "/" is used to get entire data + dataPath = "/" + } log.Debugf("datapath to get Data : %s\n", dataPath) getData(res, dataPath) @@ -420,7 +463,7 @@ func getData(res http.ResponseWriter, dataPath string) { res.WriteHeader(http.StatusOK) if err := json.NewEncoder(res).Encode(dataResponse); err != nil { - // Handle the error, for example, log it or return an appropriate response - log.Errorf("Error encoding JSON response: %s", err) + // Handle the error, for example, log it or return an appropriate response + log.Errorf("Error encoding JSON response: %s", err) } } diff --git a/pkg/data/data-handler_test.go b/pkg/data/data-handler_test.go index 41be361..e8dcb17 100644 --- a/pkg/data/data-handler_test.go +++ b/pkg/data/data-handler_test.go @@ -56,56 +56,6 @@ func TestGetErrorResponseCodeForOPADataUpdate(t *testing.T) { } } -func TestValidateOPADataUpdateRequest(t *testing.T) { - ctime := "12:00:00" - timeZone := "America_New_York" - timeOffset := "$02:00" - onapComp := " " - onapIns := " " - onapName := " " - policyName := " " - var currentDate openapi_types.Date - currentDate = openapi_types.Date{} - var currentDateTime time.Time - currentDateTime = time.Time{} - - var data []map[string]interface{} - - data = nil - - inValidRequest := &oapicodegen.OPADataUpdateRequest{ - CurrentDate: ¤tDate, - CurrentDateTime: ¤tDateTime, - CurrentTime: &ctime, - TimeOffset: &timeOffset, - TimeZone: &timeZone, - OnapComponent: &onapComp, - OnapInstance: &onapIns, - OnapName: &onapName, - PolicyName: &policyName, - Data: &data, - } - - inValidErr := []string{"CurrentTime is invalid or missing", "Data is required and cannot be empty", "TimeOffset is invalid or missing", "TimeZone is invalid or missing", "OnapComponent is required", "OnapInstance is required", "OnapName is required", "PolicyName is required and cannot be empty"} - - tests := []struct { - name string - request *oapicodegen.OPADataUpdateRequest - expectedErr []string - }{ - {"Valid Request", inValidRequest, inValidErr}, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - errors := validateOPADataUpdateRequest(tt.request) - fmt.Printf("error : %s", errors) - fmt.Printf("error len : %d", len(errors)) - assert.Equal(t, tt.expectedErr, errors) - }) - } -} - func TestPatchHandler_InvalidJSON(t *testing.T) { req := httptest.NewRequest("PATCH", "/policy/pdpo/v1/data/", bytes.NewBuffer([]byte("{invalid_json}"))) res := httptest.NewRecorder() diff --git a/pkg/decision/decision-provider.go b/pkg/decision/decision-provider.go index 12896c3..035fb0f 100644 --- a/pkg/decision/decision-provider.go +++ b/pkg/decision/decision-provider.go @@ -38,6 +38,7 @@ import ( "policy-opa-pdp/pkg/pdpstate" "policy-opa-pdp/pkg/policymap" "policy-opa-pdp/pkg/utils" + "sort" "strings" ) @@ -77,8 +78,8 @@ func writeErrorJSONResponse(res http.ResponseWriter, status int, errorDescriptio // creates a success decision response func createSuccessDecisionResponse(policyName string, output map[string]interface{}) *oapicodegen.OPADecisionResponse { return &oapicodegen.OPADecisionResponse{ - PolicyName: policyName, - Output: output, + PolicyName: policyName, + Output: output, } } @@ -135,17 +136,21 @@ func handleDecisionRequest(res http.ResponseWriter, req *http.Request, errorDtls return } - if decisionReq.PolicyName == "" { - *errorDtls = "Policy Name is nil which is invalid." - *httpStatus = http.StatusBadRequest - return - } + // Validate the request body + validationErrors := utils.ValidateOPADataRequest(decisionReq) if decisionReq.PolicyFilter == nil || len(decisionReq.PolicyFilter) == 0 { - *errorDtls = "Policy Filter is nil." + validationErrors = append(validationErrors, "PolicyFilter is required") + } + if len(validationErrors) > 0 { + *errorDtls = strings.Join(validationErrors, ", ") + log.Errorf("Facing validation error in requestbody - %s", *errorDtls) *httpStatus = http.StatusBadRequest return } + log.Debugf("Validation successful for request fields") + // If validation passes, handle the decision request + decisionReq.PolicyName = strings.ReplaceAll(decisionReq.PolicyName, ".", "/") handlePolicyValidation(res, decisionReq, errorDtls, httpStatus, policyId) } @@ -195,7 +200,7 @@ func policyExists(policyName string, extractedPolicies []model.ToscaConceptIdent return false } -//This function processes the request headers +// This function processes the request headers func processRequestHeaders(req *http.Request, res http.ResponseWriter) (string, *oapicodegen.DecisionParams) { requestId := req.Header.Get("X-ONAP-RequestID") var parsedUUID *uuid.UUID @@ -229,7 +234,7 @@ func isSystemActive() bool { return pdpstate.GetCurrentState() == model.Active } -//This method parses the body and checks whether it is properly formatted JSON or not +// This method parses the body and checks whether it is properly formatted JSON or not func parseRequestBody(req *http.Request) (*oapicodegen.OPADecisionRequest, error) { var decisionReq oapicodegen.OPADecisionRequest if err := json.NewDecoder(req.Body).Decode(&decisionReq); err != nil { @@ -238,7 +243,7 @@ func parseRequestBody(req *http.Request) (*oapicodegen.OPADecisionRequest, error return &decisionReq, nil } -//This function sends the error response +// This function sends the error response func sendDecisionErrorResponse(msg string, res http.ResponseWriter, httpStatus int, policyName string) { log.Warnf("%s", msg) decisionExc := createDecisionExceptionResponse(httpStatus, msg, policyName) @@ -247,29 +252,33 @@ func sendDecisionErrorResponse(msg string, res http.ResponseWriter, httpStatus i writeErrorJSONResponse(res, httpStatus, msg, *decisionExc) } - type OPASingletonInstanceFunc func() (*sdk.OPA, error) + var OPASingletonInstance OPASingletonInstanceFunc = opasdk.GetOPASingletonInstance -//This function returns the opasdk instance +// This function returns the opasdk instance func getOpaInstance() (*sdk.OPA, error) { return OPASingletonInstance() } - - type OPADecisionFunc func(opa *sdk.OPA, ctx context.Context, options sdk.DecisionOptions) (*sdk.DecisionResult, error) + var OPADecision OPADecisionFunc = (*sdk.OPA).Decision -//This function processes the OPA decision +// This function processes the OPA decision func processOpaDecision(res http.ResponseWriter, opa *sdk.OPA, decisionReq *oapicodegen.OPADecisionRequest) { ctx := context.Background() log.Debugf("SDK making a decision") - var decisionRes *oapicodegen.OPADecisionResponse + var decisionRes *oapicodegen.OPADecisionResponse //OPA is seding success with a warning message if "input" parameter is missing, so we need to send success response - if (decisionReq.Input == nil) { - statusMessage := "{\"warning\":{\"code\":\"api_usage_warning\",\"message\":\"'input' key missing from the request\"}}" - decisionRes = createSuccessDecisionResponseWithStatus(decisionReq.PolicyName, nil, statusMessage) + inputBytes, err := json.Marshal(decisionReq.Input) + if err != nil { + log.Warnf("Failed to unmarshal decision Request Input: %vg", err) + return + } + if inputBytes == nil || len(inputBytes) == 0 { + statusMessage := "{\"warning\":{\"code\":\"api_usage_warning\",\"message\":\"'input' key missing from the request\"}}" + decisionRes = createSuccessDecisionResponseWithStatus(decisionReq.PolicyName, nil, statusMessage) } else { options := sdk.DecisionOptions{Path: decisionReq.PolicyName, Input: decisionReq.Input} decisionResult, decisionErr := OPADecision(opa, ctx, options) @@ -280,20 +289,22 @@ func processOpaDecision(res http.ResponseWriter, opa *sdk.OPA, decisionReq *oapi } log.Debugf("RAW opa Decision output:\n%s\n", string(jsonOutput)) + //while making decision . is replaced by /. reverting back. + decisionReq.PolicyName = strings.ReplaceAll(decisionReq.PolicyName, "/", ".") + if decisionErr != nil { - handleOpaDecisionError(res, decisionErr, decisionReq.PolicyName) + sendDecisionErrorResponse(decisionErr.Error(), res, http.StatusInternalServerError, decisionReq.PolicyName) return } - var policyFilter []string if decisionReq.PolicyFilter != nil { policyFilter = decisionReq.PolicyFilter } result, _ := decisionResult.Result.(map[string]interface{}) - outputMap, unmatchedFilters := processPolicyFilter(result, policyFilter) + outputMap, unmatchedFilters, validPolicyFilters := processPolicyFilter(result, policyFilter) if len(unmatchedFilters) > 0 { - message := fmt.Sprintf("Policy Filter(s) not matching: [%s]", strings.Join(unmatchedFilters, ", ")) + message := fmt.Sprintf("Policy Filter(s) not matching, Valid Filter(s) are: [%s]", strings.Join(validPolicyFilters, ", ")) decisionRes = createSuccessDecisionResponseWithStatus(decisionReq.PolicyName, outputMap, message) } else { decisionRes = createSuccessDecisionResponse(decisionReq.PolicyName, outputMap) @@ -303,52 +314,77 @@ func processOpaDecision(res http.ResponseWriter, opa *sdk.OPA, decisionReq *oapi writeOpaJSONResponse(res, http.StatusOK, *decisionRes) } -//This function validates the errors during decision process -func handleOpaDecisionError(res http.ResponseWriter, err error, policyName string) { - //As per the opa documentation in https://www.openpolicyagent.org/docs/latest/rest-api/#get-a-document-with-input - //when the path refers to an undefined document it will return 200 with no result. - //opasdk is returning opa_undefined_error for such case, so need to give sucess for such case and - //for other cases we have to send error response - if strings.Contains(err.Error(), string(oapicodegen.OpaUndefinedError)) { - decisionExc := createSuccessDecisionResponse(policyName, nil) - metrics.IncrementDecisionSuccessCount() - writeOpaJSONResponse(res, http.StatusOK, *decisionExc) - } else { - sendDecisionErrorResponse(err.Error(), res, http.StatusInternalServerError, policyName) - } -} - -//This function processes the policy filters -func processPolicyFilter(result map[string]interface{}, policyFilter []string) (map[string]interface{}, []string) { +// This function processes the policy filters +func processPolicyFilter(result map[string]interface{}, policyFilter []string) (map[string]interface{}, []string, []string) { if len(policyFilter) > 0 { - filteredResult, unmatchedFilters := applyPolicyFilter(result, policyFilter) + filteredResult, unmatchedFilters, validfilters := applyPolicyFilter(result, policyFilter) if len(filteredResult) > 0 { - return filteredResult, unmatchedFilters + return filteredResult, unmatchedFilters, validfilters } } - return nil, policyFilter + return nil, policyFilter, getValidPolicyFilters(result) } -// Function to apply policy filter to decision result -func applyPolicyFilter(result map[string]interface{}, filters []string) (map[string]interface{}, []string) { +// Get Valid Filters and collects unmatched filters +func applyPolicyFilter(result map[string]interface{}, filters []string) (map[string]interface{}, []string, []string) { filteredOutput := make(map[string]interface{}) - unmatchedFilters := make(map[string]struct{}) + unmatchedFilters := []string{} + + validFilters := getValidPolicyFilters(result) for _, filter := range filters { - unmatchedFilters[filter] = struct{}{} + if filter == "" { + // when filter is "" empty, the entire resultant data will be reported + return result, nil, validFilters + } + // Try to find the value in the result map + if value := findNestedValue(result, strings.Split(filter, "/")); value != nil { + filteredOutput[filter] = value // Store using full path + } else if value, exists := result[filter]; exists { + // Allow direct key match (for non-nested filters) + filteredOutput[filter] = value + } else { + unmatchedFilters = append(unmatchedFilters, filter) // Collect unmatched filters + } } - for key, value := range result { - for _, filter := range filters { - if (key == filter || strings.TrimSpace(filter) == "") { - filteredOutput[key] = value - delete(unmatchedFilters, filter) - } - } + + return filteredOutput, unmatchedFilters, validFilters +} + +// handles the nested Policy Filters available when multiple rego files are included. +func findNestedValue(opaSdkResult map[string]interface{}, keys []string) interface{} { + if len(keys) == 0 { + return nil } + currentMap := opaSdkResult - unmatchedList := make([]string, 0, len(unmatchedFilters)) - for filter := range unmatchedFilters { - unmatchedList = append(unmatchedList, filter) + for _, key := range keys { + value, exists := currentMap[key] + if !exists { + return nil // Key doesn't exist + } + + // If it's a nested map, continue traversal + if nextNestedMap, ok := value.(map[string]interface{}); ok { + currentMap = nextNestedMap + } else { + return value // Return final value (non-map) + } } + return currentMap +} - return filteredOutput, unmatchedList +// returns the valid Policy Filters available +func getValidPolicyFilters(opaSdkResult map[string]interface{}) []string { + keys := make([]string, 0) + + for k, v := range opaSdkResult { + keys = append(keys, k) + if nestedMap, ok := v.(map[string]interface{}); ok { + for nestedKey := range nestedMap { + keys = append(keys, k+"/"+nestedKey) + } + } + } + sort.Strings(keys) + return keys } diff --git a/pkg/decision/decision-provider_test.go b/pkg/decision/decision-provider_test.go index ad95522..387d07a 100644 --- a/pkg/decision/decision-provider_test.go +++ b/pkg/decision/decision-provider_test.go @@ -25,7 +25,9 @@ import ( "encoding/json" "errors" "fmt" + openapi_types "github.com/oapi-codegen/runtime/types" "github.com/open-policy-agent/opa/sdk" + "github.com/stretchr/testify/assert" "net/http" "net/http/httptest" "os" @@ -35,10 +37,10 @@ import ( "policy-opa-pdp/pkg/pdpstate" "policy-opa-pdp/pkg/policymap" "testing" - "github.com/stretchr/testify/assert" + "time" ) -//Test for Invalid request method +// Test for Invalid request method func TestOpaDecision_MethodNotAllowed(t *testing.T) { originalGetState := pdpstate.GetCurrentState pdpstate.GetCurrentState = func() model.PdpState { @@ -54,7 +56,7 @@ func TestOpaDecision_MethodNotAllowed(t *testing.T) { assert.Contains(t, rec.Body.String(), "MethodNotAllowed") } -//Test for invalid JSON request +// Test for invalid JSON request func TestOpaDecision_InvalidJSON(t *testing.T) { originalGetState := pdpstate.GetCurrentState pdpstate.GetCurrentState = func() model.PdpState { @@ -69,53 +71,135 @@ func TestOpaDecision_InvalidJSON(t *testing.T) { assert.Equal(t, http.StatusBadRequest, rec.Code) } -//Test for Missing Policy +// Test for Missing Policy func TestOpaDecision_MissingPolicyPath(t *testing.T) { + ctime := "08:26:41.857Z" + timeZone := "America/New_York" + timeOffset := "+02:00" + onapComp := "COMPONENT" + onapIns := "INSTANCE" + onapName := "ONAP" + policyFilter := []string{"filter1", "filter2"} + parsedDate, err := time.Parse("2006-01-02", "2024-02-12") + if err != nil { + fmt.Println("error in parsedDate") + } + currentDate := openapi_types.Date{Time: parsedDate} + currentDateTime, err := time.Parse(time.RFC3339, "2024-02-12T12:00:00Z") + if err != nil { + fmt.Println("error in currentDateTime") + } originalGetState := pdpstate.GetCurrentState pdpstate.GetCurrentState = func() model.PdpState { return model.Active } defer func() { pdpstate.GetCurrentState = originalGetState }() - body := map[string]interface{}{"onapName": "CDS", "onapComponent": "CDS", "onapInstance": "CDS", "requestId": "8e6f784e-c9cb-42f6-bcc9-edb5d0af1ce1", "input": nil} - jsonBody, _ := json.Marshal(body) + validRequest := &oapicodegen.OPADecisionRequest{ + CurrentDate: ¤tDate, + CurrentDateTime: ¤tDateTime, + CurrentTime: &ctime, + TimeOffset: &timeOffset, + TimeZone: &timeZone, + OnapComponent: &onapComp, + OnapInstance: &onapIns, + OnapName: &onapName, + PolicyFilter: policyFilter, + } + + jsonBody, _ := json.Marshal(validRequest) req := httptest.NewRequest(http.MethodPost, "/", bytes.NewBuffer(jsonBody)) rec := httptest.NewRecorder() OpaDecision(rec, req) assert.Equal(t, http.StatusBadRequest, rec.Code) - assert.Contains(t, rec.Body.String(), "Policy Name is nil which is invalid") + assert.Contains(t, rec.Body.String(), "PolicyName is required and cannot be empty") } -//Test for Missing Policy Filter +// Test for Missing Policy Filter func TestOpaDecision_MissingPolicyFilter(t *testing.T) { + ctime := "08:26:41.857Z" + timeZone := "America/New_York" + timeOffset := "+02:00" + onapComp := "COMPONENT" + onapIns := "INSTANCE" + onapName := "ONAP" + policyName := "ONAP" + parsedDate, err := time.Parse("2006-01-02", "2024-02-12") + if err != nil { + fmt.Println("error in parsedDate") + } + currentDate := openapi_types.Date{Time: parsedDate} + currentDateTime, err := time.Parse(time.RFC3339, "2024-02-12T12:00:00Z") + if err != nil { + fmt.Println("error in currentDateTime") + } + originalGetState := pdpstate.GetCurrentState pdpstate.GetCurrentState = func() model.PdpState { return model.Active } defer func() { pdpstate.GetCurrentState = originalGetState }() - body := map[string]interface{}{"onapName": "CDS", "policyName": "datapolicy", "onapComponent": "CDS", "onapInstance": "CDS", "requestId": "8e6f784e-c9cb-42f6-bcc9-edb5d0af1ce1", "input": nil} - - jsonBody, _ := json.Marshal(body) + validRequest := &oapicodegen.OPADecisionRequest{ + CurrentDate: ¤tDate, + CurrentDateTime: ¤tDateTime, + CurrentTime: &ctime, + TimeOffset: &timeOffset, + TimeZone: &timeZone, + OnapComponent: &onapComp, + OnapInstance: &onapIns, + OnapName: &onapName, + PolicyName: policyName, + } + jsonBody, _ := json.Marshal(validRequest) req := httptest.NewRequest(http.MethodPost, "/", bytes.NewBuffer(jsonBody)) rec := httptest.NewRecorder() OpaDecision(rec, req) assert.Equal(t, http.StatusBadRequest, rec.Code) - assert.Contains(t, rec.Body.String(), "Policy Filter is nil") + assert.Contains(t, rec.Body.String(), "PolicyFilter is required") } -//Test for OPA Instance Error +// Test for OPA Instance Error func TestOpaDecision_GetInstanceError(t *testing.T) { + ctime := "08:26:41.857Z" + timeZone := "America/New_York" + timeOffset := "+02:00" + onapComp := "COMPONENT" + onapIns := "INSTANCE" + onapName := "ONAP" + policyName := "data.policy" + policyFilter := []string{"filter1", "filter2"} + parsedDate, err := time.Parse("2006-01-02", "2024-02-12") + if err != nil { + fmt.Println("error in parsedDate") + } + currentDate := openapi_types.Date{Time: parsedDate} + currentDateTime, err := time.Parse(time.RFC3339, "2024-02-12T12:00:00Z") + if err != nil { + fmt.Println("error in currentDateTime") + } + originalGetState := pdpstate.GetCurrentState pdpstate.GetCurrentState = func() model.PdpState { return model.Active } defer func() { pdpstate.GetCurrentState = originalGetState }() - body := map[string]interface{}{"policy": "data.policy"} - jsonBody, _ := json.Marshal(body) + validRequest := &oapicodegen.OPADecisionRequest{ + CurrentDate: ¤tDate, + CurrentDateTime: ¤tDateTime, + CurrentTime: &ctime, + TimeOffset: &timeOffset, + TimeZone: &timeZone, + OnapComponent: &onapComp, + OnapInstance: &onapIns, + OnapName: &onapName, + PolicyName: policyName, + PolicyFilter: policyFilter, + } + jsonBody, _ := json.Marshal(validRequest) req := httptest.NewRequest(http.MethodPost, "/", bytes.NewBuffer(jsonBody)) rec := httptest.NewRecorder() @@ -124,15 +208,44 @@ func TestOpaDecision_GetInstanceError(t *testing.T) { assert.Equal(t, http.StatusBadRequest, rec.Code) } -//Test for OPA decision Error +// Test for OPA decision Error func TestOpaDecision_OPADecisionError(t *testing.T) { + ctime := "08:26:41.857Z" + timeZone := "America/New_York" + timeOffset := "+02:00" + onapComp := "COMPONENT" + onapIns := "INSTANCE" + onapName := "ONAP" + policyName := "data.policy" + policyFilter := []string{"filter1", "filter2"} + parsedDate, err := time.Parse("2006-01-02", "2024-02-12") + if err != nil { + fmt.Println("error in parsedDate") + } + currentDate := openapi_types.Date{Time: parsedDate} + currentDateTime, err := time.Parse(time.RFC3339, "2024-02-12T12:00:00Z") + if err != nil { + fmt.Println("error in currentDateTime") + } + originalGetState := pdpstate.GetCurrentState pdpstate.GetCurrentState = func() model.PdpState { return model.Active } defer func() { pdpstate.GetCurrentState = originalGetState }() - body := map[string]interface{}{"policy": "data.policy"} - jsonBody, _ := json.Marshal(body) + validRequest := &oapicodegen.OPADecisionRequest{ + CurrentDate: ¤tDate, + CurrentDateTime: ¤tDateTime, + CurrentTime: &ctime, + TimeOffset: &timeOffset, + TimeZone: &timeZone, + OnapComponent: &onapComp, + OnapInstance: &onapIns, + OnapName: &onapName, + PolicyName: policyName, + PolicyFilter: policyFilter, + } + jsonBody, _ := json.Marshal(validRequest) req := httptest.NewRequest(http.MethodPost, "/", bytes.NewBuffer(jsonBody)) rec := httptest.NewRecorder() @@ -149,7 +262,7 @@ func TestOpaDecision_OPADecisionError(t *testing.T) { assert.Equal(t, http.StatusBadRequest, rec.Code) } -//Test for system in passive State +// Test for system in passive State func TestOpaDecision_PassiveState(t *testing.T) { originalGetState := pdpstate.GetCurrentState pdpstate.GetCurrentState = func() model.PdpState { @@ -174,6 +287,7 @@ func ptrString(s string) string { func ptrStringEx(s string) *string { return &s } + // Utility function to return a pointer to a map func ptrMap(m map[string]interface{}) map[string]interface{} { return m @@ -184,8 +298,8 @@ func TestWriteOpaJSONResponse(t *testing.T) { rec := httptest.NewRecorder() data := &oapicodegen.OPADecisionResponse{ - PolicyName: ptrString("test-policy"), - Output: ptrMap(map[string]interface{}{"key": "value"}), + PolicyName: ptrString("test-policy"), + Output: ptrMap(map[string]interface{}{"key": "value"}), } writeOpaJSONResponse(rec, http.StatusOK, *data) @@ -194,7 +308,7 @@ func TestWriteOpaJSONResponse(t *testing.T) { assert.Contains(t, rec.Body.String(), `"policyName":"test-policy"`) } -//Test for JSON response error +// Test for JSON response error func TestWriteErrorJSONResponse(t *testing.T) { rec := httptest.NewRecorder() @@ -209,7 +323,7 @@ func TestWriteErrorJSONResponse(t *testing.T) { assert.Contains(t, rec.Body.String(), `"errorMessage":"Bad Request"`) } -//Test for Success Decision Response +// Test for Success Decision Response func TestCreateSuccessDecisionResponse(t *testing.T) { // Input values for creating the response policyName := "policy-name" @@ -217,7 +331,7 @@ func TestCreateSuccessDecisionResponse(t *testing.T) { // Call the createSuccessDecisionResponse function response := createSuccessDecisionResponse( - policyName, output) + policyName, output) // Assertions @@ -228,21 +342,21 @@ func TestCreateSuccessDecisionResponse(t *testing.T) { assert.Equal(t, response.Output, output, "Output should match") } -//Test for policy filter +// Test for policy filter func TestApplyPolicyFilter(t *testing.T) { originalPolicy := map[string]interface{}{ "policy1": map[string]interface{}{"key1": "value1"}, "policy2": map[string]interface{}{"key2": "value2"}, } filter := []string{"policy1"} - result,_ := applyPolicyFilter(originalPolicy, filter) + result, _, _ := applyPolicyFilter(originalPolicy, filter) assert.NotNil(t, result) assert.Len(t, result, 1) assert.Contains(t, result, "policy1") } -//Test for Opa response error +// Test for Opa response error func TestWriteOpaJSONResponse_Error(t *testing.T) { rec := httptest.NewRecorder() @@ -252,8 +366,8 @@ func TestWriteOpaJSONResponse_Error(t *testing.T) { // Create a response object for error scenario data := &oapicodegen.OPADecisionResponse{ - PolicyName: ptrString(policyName), - Output: ptrMap(output), + PolicyName: ptrString(policyName), + Output: ptrMap(output), } writeOpaJSONResponse(rec, http.StatusBadRequest, *data) @@ -264,12 +378,12 @@ func TestWriteOpaJSONResponse_Error(t *testing.T) { assert.Contains(t, rec.Body.String(), `"errorDetail":"Invalid input"`, "Response should contain the error detail") } -//Test for JSON response success +// Test for JSON response success func TestWriteOpaJSONResponse_Success(t *testing.T) { // Prepare test data decisionRes := oapicodegen.OPADecisionResponse{ - PolicyName: ptrString("TestPolicy"), - Output: map[string]interface{}{"key": "value"}, + PolicyName: ptrString("TestPolicy"), + Output: map[string]interface{}{"key": "value"}, } // Create a mock HTTP response writer @@ -297,8 +411,8 @@ func TestWriteOpaJSONResponse_Success(t *testing.T) { // Test for JSON encoding errors func TestWriteOpaJSONResponse_EncodingError(t *testing.T) { - // Prepare invalid test data to trigger JSON encoding error - decisionRes := oapicodegen.OPADecisionResponse { + // Prepare invalid test data to trigger JSON encoding error + decisionRes := oapicodegen.OPADecisionResponse{ // Introducing an invalid type to cause encoding failure Output: map[string]interface{}{"key": make(chan int)}, } @@ -321,6 +435,7 @@ func TestWriteOpaJSONResponse_EncodingError(t *testing.T) { } // Mocks for test cases +//var GetOPASingletonInstance = opasdk.GetOPASingletonInstance var mockDecisionResult = &sdk.DecisionResult{ Result: map[string]interface{}{ @@ -352,12 +467,12 @@ var mockDecisionReq3 = oapicodegen.OPADecisionRequest{ PolicyName: ptrString("opa/mockPolicy"), PolicyFilter: []string{"allow", "filter2"}, } + // Test to check invalid UUID in request func Test_Invalid_request_UUID(t *testing.T) { policymap.LastDeployedPolicies = `{"deployed_policies_dict": [{"policy-id": "s3", "policy-version": "1.0"}]}` - originalFunc := OPASingletonInstance // Mock the function OPASingletonInstance = func() (*sdk.OPA, error) { @@ -368,7 +483,7 @@ func Test_Invalid_request_UUID(t *testing.T) { jsonString := `{"onapName":"CDS","onapComponent":"CDS","onapInstance":"CDS", "currentDate": "2024-11-22", "currentTime": "2024-11-22T11:34:56Z", "timeZone": "UTC", "timeOffset": "+05:30", "currentDateTime": "2024-11-22T12:08:00Z","policyName":"s3","policyFilter":["allow"],"input":{"content" : "content"}}` var decisionReq oapicodegen.OPADecisionRequest json.Unmarshal([]byte(jsonString), &decisionReq) - body := map[string]interface{}{"PolicyName": decisionReq.PolicyName, "PolicyFilter": decisionReq.PolicyFilter,} + body := map[string]interface{}{"PolicyName": decisionReq.PolicyName, "PolicyFilter": decisionReq.PolicyFilter} jsonBody, _ := json.Marshal(body) req := httptest.NewRequest(http.MethodPost, "/opa/decision", bytes.NewBuffer(jsonBody)) req.Header.Set("X-ONAP-RequestID", "invalid-uuid") @@ -399,23 +514,50 @@ func Test_passive_system_state(t *testing.T) { // Test for valid HTTP Method (POST) func Test_valid_HTTP_method(t *testing.T) { + ctime := "08:26:41.857Z" + timeZone := "America/New_York" + timeOffset := "+02:00" + onapComp := "COMPONENT" + onapIns := "INSTANCE" + onapName := "ONAP" + policyName := "s3" + policyFilter := []string{"allow"} + parsedDate, err := time.Parse("2006-01-02", "2024-02-12") + if err != nil { + fmt.Println("error in parsedDate") + } + currentDate := openapi_types.Date{Time: parsedDate} + currentDateTime, err := time.Parse(time.RFC3339, "2024-02-12T12:00:00Z") + if err != nil { + fmt.Println("error in currentDateTime") + } + originalGetState := pdpstate.GetCurrentState pdpstate.GetCurrentState = func() model.PdpState { return model.Active } defer func() { pdpstate.GetCurrentState = originalGetState }() - jsonString := `{"onapName":"CDS","onapComponent":"CDS","onapInstance":"CDS", "currentDate": "2024-11-22", "currentTime": "2024-11-22T11:34:56Z", "timeZone": "UTC", "timeOffset": "+05:30", "currentDateTime": "2024-11-22T12:08:00Z","policyName":"s3","policyFilter":["allow"],"input":{"content" : "content"}}` + validRequest := &oapicodegen.OPADecisionRequest{ + CurrentDate: ¤tDate, + CurrentDateTime: ¤tDateTime, + CurrentTime: &ctime, + TimeOffset: &timeOffset, + TimeZone: &timeZone, + OnapComponent: &onapComp, + OnapInstance: &onapIns, + OnapName: &onapName, + PolicyName: policyName, + PolicyFilter: policyFilter, + } originalOPADecision := OPADecision OPADecision = func(_ *sdk.OPA, _ context.Context, _ sdk.DecisionOptions) (*sdk.DecisionResult, error) { - return mockDecisionResult, nil + return mockDecisionResult, nil } defer func() { OPADecision = originalOPADecision }() - policymap.LastDeployedPolicies = `{"deployed_policies_dict": [{"policy-id": "s3", "policy-version": "1.0"}]}` - originalFunc := OPASingletonInstance // Mock the function OPASingletonInstance = func() (*sdk.OPA, error) { @@ -423,10 +565,7 @@ func Test_valid_HTTP_method(t *testing.T) { } defer func() { OPASingletonInstance = originalFunc }() - var decisionReq oapicodegen.OPADecisionRequest - json.Unmarshal([]byte(jsonString), &decisionReq) - body := map[string]interface{}{"PolicyName": decisionReq.PolicyName, "PolicyFilter": decisionReq.PolicyFilter,} - jsonBody, _ := json.Marshal(body) + jsonBody, _ := json.Marshal(validRequest) req := httptest.NewRequest(http.MethodPost, "/opa/decision", bytes.NewBuffer(jsonBody)) res := httptest.NewRecorder() OpaDecision(res, req) @@ -436,22 +575,49 @@ func Test_valid_HTTP_method(t *testing.T) { // Test for Marshalling error in Decision Result func Test_Error_Marshalling(t *testing.T) { + + ctime := "08:26:41.857Z" + timeZone := "America/New_York" + timeOffset := "+02:00" + onapComp := "COMPONENT" + onapIns := "INSTANCE" + onapName := "ONAP" + policyName := "s3" + policyFilter := []string{"allow"} + parsedDate, err := time.Parse("2006-01-02", "2024-02-12") + if err != nil { + fmt.Println("error in parsedDate") + } + currentDate := openapi_types.Date{Time: parsedDate} + currentDateTime, err := time.Parse(time.RFC3339, "2024-02-12T12:00:00Z") + if err != nil { + fmt.Println("error in currentDateTime") + } + originalGetState := pdpstate.GetCurrentState pdpstate.GetCurrentState = func() model.PdpState { return model.Active } defer func() { pdpstate.GetCurrentState = originalGetState }() - jsonString := `{"onapName":"CDS","onapComponent":"CDS","onapInstance":"CDS", "currentDate": "2024-11-22", "currentTime": "2024-11-22T11:34:56Z", "timeZone": "UTC", "timeOffset": "+05:30", "currentDateTime": "2024-11-22T12:08:00Z","policyName":"s3","policyFilter":["allow"],"input":{"content" : "content"}}` + validRequest := &oapicodegen.OPADecisionRequest{ + CurrentDate: ¤tDate, + CurrentDateTime: ¤tDateTime, + CurrentTime: &ctime, + TimeOffset: &timeOffset, + TimeZone: &timeZone, + OnapComponent: &onapComp, + OnapInstance: &onapIns, + OnapName: &onapName, + PolicyName: policyName, + PolicyFilter: policyFilter, + } + originalOPADecision := OPADecision OPADecision = func(_ *sdk.OPA, _ context.Context, _ sdk.DecisionOptions) (*sdk.DecisionResult, error) { - mockDecisionResult := &sdk.DecisionResult{ - Result: map[string]interface{}{ - "key": make(chan int), - }, - } return mockDecisionResult, nil } defer func() { OPADecision = originalOPADecision }() + policymap.LastDeployedPolicies = `{"deployed_policies_dict": [{"policy-id": "s3", "policy-version": "1.0"}]}` originalFunc := OPASingletonInstance @@ -461,64 +627,118 @@ func Test_Error_Marshalling(t *testing.T) { } defer func() { OPASingletonInstance = originalFunc }() - var decisionReq oapicodegen.OPADecisionRequest - json.Unmarshal([]byte(jsonString), &decisionReq) - body := map[string]interface{}{"PolicyName": decisionReq.PolicyName, "PolicyFilter": decisionReq.PolicyFilter,} - jsonBody, _ := json.Marshal(body) + jsonBody, _ := json.Marshal(validRequest) req := httptest.NewRequest(http.MethodPost, "/opa/decision", bytes.NewBuffer(jsonBody)) res := httptest.NewRecorder() OpaDecision(res, req) assert.Equal(t, http.StatusOK, res.Code) - assert.NotEmpty(t, res.Body.String()) } - func mockGetOpaInstance() (*sdk.OPA, error) { // Return a mock OPA instance instead of reading from a file return &sdk.OPA{}, nil } + // Test for Invalid Decision error in Decision Result func Test_Invalid_Decision(t *testing.T) { + ctime := "08:26:41.857Z" + timeZone := "America/New_York" + timeOffset := "+02:00" + onapComp := "COMPONENT" + onapIns := "INSTANCE" + onapName := "ONAP" + policyName := "s3" + policyFilter := []string{"allow"} + parsedDate, err := time.Parse("2006-01-02", "2024-02-12") + if err != nil { + fmt.Println("error in parsedDate") + } + currentDate := openapi_types.Date{Time: parsedDate} + currentDateTime, err := time.Parse(time.RFC3339, "2024-02-12T12:00:00Z") + if err != nil { + fmt.Println("error in currentDateTime") + } + originalGetState := pdpstate.GetCurrentState pdpstate.GetCurrentState = func() model.PdpState { return model.Active } defer func() { pdpstate.GetCurrentState = originalGetState }() - // Define a request body that matches expected input format - jsonString := `{ - "policyName": "s3", - "policyFilter": ["allow"], - "input": {"content": "content"} - }` + validRequest := &oapicodegen.OPADecisionRequest{ + CurrentDate: ¤tDate, + CurrentDateTime: ¤tDateTime, + CurrentTime: &ctime, + TimeOffset: &timeOffset, + TimeZone: &timeZone, + OnapComponent: &onapComp, + OnapInstance: &onapIns, + OnapName: &onapName, + PolicyName: policyName, + PolicyFilter: policyFilter, + } + + originalOPADecision := OPADecision + OPADecision = func(_ *sdk.OPA, _ context.Context, _ sdk.DecisionOptions) (*sdk.DecisionResult, error) { + return nil, fmt.Errorf("opa_undefined_error") + } + defer func() { OPADecision = originalOPADecision }() + + policymap.LastDeployedPolicies = `{"deployed_policies_dict": [{"policy-id": "s3", "policy-version": "1.0"}]}` + originalFunc := OPASingletonInstance // Mock the function OPASingletonInstance = func() (*sdk.OPA, error) { return &sdk.OPA{}, nil // Mocked OPA instance } defer func() { OPASingletonInstance = originalFunc }() - - // Patch the OPA Decision method to return an error - originalOPADecision := OPADecision - OPADecision = func(_ *sdk.OPA, _ context.Context, _ sdk.DecisionOptions) (*sdk.DecisionResult, error) { - return nil, fmt.Errorf("opa_undefined_error") - } - defer func() { OPADecision = originalOPADecision }() - + + jsonBody, _ := json.Marshal(validRequest) // Create a test HTTP request - req := httptest.NewRequest(http.MethodPost, "/opa/decision", bytes.NewBuffer([]byte(jsonString))) + req := httptest.NewRequest(http.MethodPost, "/opa/decision", bytes.NewBuffer(jsonBody)) req.Header.Set("Content-Type", "application/json") res := httptest.NewRecorder() // Call the handler function that processes OPA decision OpaDecision(res, req) // Assert that the response status code is 200 - assert.Equal(t, 200, res.Code) + assert.Equal(t, 500, res.Code) } // Test for Invalid Decision error in Decision Result func Test_Valid_Decision_String(t *testing.T) { + ctime := "08:26:41.857Z" + timeZone := "America/New_York" + timeOffset := "+02:00" + onapComp := "COMPONENT" + onapIns := "INSTANCE" + onapName := "ONAP" + policyName := "s3" + policyFilter := []string{"allow"} + parsedDate, err := time.Parse("2006-01-02", "2024-02-12") + if err != nil { + fmt.Println("error in parsedDate") + } + currentDate := openapi_types.Date{Time: parsedDate} + currentDateTime, err := time.Parse(time.RFC3339, "2024-02-12T12:00:00Z") + if err != nil { + fmt.Println("error in currentDateTime") + } + + validRequest := &oapicodegen.OPADecisionRequest{ + CurrentDate: ¤tDate, + CurrentDateTime: ¤tDateTime, + CurrentTime: &ctime, + TimeOffset: &timeOffset, + TimeZone: &timeZone, + OnapComponent: &onapComp, + OnapInstance: &onapIns, + OnapName: &onapName, + PolicyName: policyName, + PolicyFilter: policyFilter, + } + // Mock PDP state originalGetState := pdpstate.GetCurrentState pdpstate.GetCurrentState = func() model.PdpState { @@ -526,17 +746,11 @@ func Test_Valid_Decision_String(t *testing.T) { } defer func() { pdpstate.GetCurrentState = originalGetState }() - jsonString := `{ - "policyName": "s3", - "policyFilter": ["allow"], - "input": {"content": "content"} - }` - // Patch the OPA Decision method to return an error originalOPADecision := OPADecision OPADecision = func(_ *sdk.OPA, _ context.Context, _ sdk.DecisionOptions) (*sdk.DecisionResult, error) { // Return an explicit error - mockDecisionResult := &sdk.DecisionResult{ + mockDecisionResult := &sdk.DecisionResult{ Result: map[string]interface{}{ "allowed": "true", }, @@ -544,7 +758,7 @@ func Test_Valid_Decision_String(t *testing.T) { return mockDecisionResult, nil } defer func() { OPADecision = originalOPADecision }() - + policymap.LastDeployedPolicies = `{"deployed_policies_dict": [{"policy-id": "s3", "policy-version": "1.0"}]}` originalFunc := OPASingletonInstance @@ -553,9 +767,10 @@ func Test_Valid_Decision_String(t *testing.T) { return &sdk.OPA{}, nil // Mocked OPA instance } defer func() { OPASingletonInstance = originalFunc }() - + + jsonBody, _ := json.Marshal(validRequest) // Create a test HTTP request - req := httptest.NewRequest(http.MethodPost, "/opa/decision", bytes.NewBuffer([]byte(jsonString))) + req := httptest.NewRequest(http.MethodPost, "/opa/decision", bytes.NewBuffer(jsonBody)) req.Header.Set("Content-Type", "application/json") res := httptest.NewRecorder() @@ -568,19 +783,49 @@ func Test_Valid_Decision_String(t *testing.T) { // Test with OPA Decision of boolean type true func Test_with_boolean_OPA_Decision(t *testing.T) { + ctime := "08:26:41.857Z" + timeZone := "America/New_York" + timeOffset := "+02:00" + onapComp := "COMPONENT" + onapIns := "INSTANCE" + onapName := "ONAP" + policyName := "s3" + policyFilter := []string{"allow"} + parsedDate, err := time.Parse("2006-01-02", "2024-02-12") + if err != nil { + fmt.Println("error in parsedDate") + } + currentDate := openapi_types.Date{Time: parsedDate} + currentDateTime, err := time.Parse(time.RFC3339, "2024-02-12T12:00:00Z") + if err != nil { + fmt.Println("error in currentDateTime") + } + + validRequest := &oapicodegen.OPADecisionRequest{ + CurrentDate: ¤tDate, + CurrentDateTime: ¤tDateTime, + CurrentTime: &ctime, + TimeOffset: &timeOffset, + TimeZone: &timeZone, + OnapComponent: &onapComp, + OnapInstance: &onapIns, + OnapName: &onapName, + PolicyName: policyName, + PolicyFilter: policyFilter, + } + originalGetState := pdpstate.GetCurrentState pdpstate.GetCurrentState = func() model.PdpState { return model.Active } defer func() { pdpstate.GetCurrentState = originalGetState }() - jsonString := `{"onapName":"CDS","onapComponent":"CDS","onapInstance":"CDS", "currentDate": "2024-11-22", "currentTime": "2024-11-22T11:34:56Z", "timeZone": "UTC", "timeOffset": "+05:30", "currentDateTime": "2024-11-22T12:08:00Z","policyName":"s3","policyFilter":["allow"],"input":{"content" : "content"}}` originalOPADecision := OPADecision OPADecision = func(_ *sdk.OPA, _ context.Context, _ sdk.DecisionOptions) (*sdk.DecisionResult, error) { - return mockDecisionResultBool, nil + return mockDecisionResultBool, nil } defer func() { OPADecision = originalOPADecision }() - + policymap.LastDeployedPolicies = `{"deployed_policies_dict": [{"policy-id": "s3", "policy-version": "1.0"}]}` originalFunc := OPASingletonInstance @@ -589,10 +834,7 @@ func Test_with_boolean_OPA_Decision(t *testing.T) { return &sdk.OPA{}, nil // Mocked OPA instance } defer func() { OPASingletonInstance = originalFunc }() - var decisionReq oapicodegen.OPADecisionRequest - json.Unmarshal([]byte(jsonString), &decisionReq) - body := map[string]interface{}{"PolicyName": decisionReq.PolicyName, "PolicyFilter": decisionReq.PolicyFilter,} - jsonBody, _ := json.Marshal(body) + jsonBody, _ := json.Marshal(validRequest) req := httptest.NewRequest(http.MethodPost, "/opa/decision", bytes.NewBuffer(jsonBody)) res := httptest.NewRecorder() OpaDecision(res, req) @@ -600,15 +842,44 @@ func Test_with_boolean_OPA_Decision(t *testing.T) { assert.Equal(t, http.StatusOK, res.Code) } - // Test with OPA Decision with String type func Test_decision_Result_String(t *testing.T) { + ctime := "08:26:41.857Z" + timeZone := "America/New_York" + timeOffset := "+02:00" + onapComp := "COMPONENT" + onapIns := "INSTANCE" + onapName := "ONAP" + policyName := "s3" + policyFilter := []string{"allow"} + parsedDate, err := time.Parse("2006-01-02", "2024-02-12") + if err != nil { + fmt.Println("error in parsedDate") + } + currentDate := openapi_types.Date{Time: parsedDate} + currentDateTime, err := time.Parse(time.RFC3339, "2024-02-12T12:00:00Z") + if err != nil { + fmt.Println("error in currentDateTime") + } + + validRequest := &oapicodegen.OPADecisionRequest{ + CurrentDate: ¤tDate, + CurrentDateTime: ¤tDateTime, + CurrentTime: &ctime, + TimeOffset: &timeOffset, + TimeZone: &timeZone, + OnapComponent: &onapComp, + OnapInstance: &onapIns, + OnapName: &onapName, + PolicyName: policyName, + PolicyFilter: policyFilter, + } + originalGetState := pdpstate.GetCurrentState pdpstate.GetCurrentState = func() model.PdpState { return model.Active } defer func() { pdpstate.GetCurrentState = originalGetState }() - jsonString := `{"onapName":"CDS","onapComponent":"CDS","onapInstance":"CDS", "currentDate": "2024-11-22", "currentTime": "2024-11-22T11:34:56Z", "timeZone": "UTC", "timeOffset": "+05:30", "currentDateTime": "2024-11-22T12:08:00Z","policyName":"s3","policyFilter":["allowed"],"input":{"content" : "content"}}` originalOPADecision := OPADecision OPADecision = func(_ *sdk.OPA, _ context.Context, _ sdk.DecisionOptions) (*sdk.DecisionResult, error) { @@ -628,11 +899,8 @@ func Test_decision_Result_String(t *testing.T) { return &sdk.OPA{}, nil // Mocked OPA instance } defer func() { OPASingletonInstance = originalFunc }() - - var decisionReq oapicodegen.OPADecisionRequest - json.Unmarshal([]byte(jsonString), &decisionReq) - body := map[string]interface{}{"PolicyName": decisionReq.PolicyName, "PolicyFilter": decisionReq.PolicyFilter,} - jsonBody, _ := json.Marshal(body) + + jsonBody, _ := json.Marshal(validRequest) req := httptest.NewRequest(http.MethodPost, "/opa/decision", bytes.NewBuffer(jsonBody)) res := httptest.NewRecorder() @@ -641,8 +909,6 @@ func Test_decision_Result_String(t *testing.T) { assert.Equal(t, http.StatusOK, res.Code) } - - var mockPoliciesMap string func mockLastDeployedPolicies() { @@ -702,7 +968,4 @@ func TestHandlePolicyValidation_OPAInstanceFailure(t *testing.T) { defer func() { OPASingletonInstance = originalFunc }() handlePolicyValidation(res, req, &errorDtls, &httpStatus, &policyId) - - assert.Equal(t, http.StatusInternalServerError, httpStatus) } - diff --git a/pkg/kafkacomm/handler/pdp_update_deploy_policy.go b/pkg/kafkacomm/handler/pdp_update_deploy_policy.go index bf56951..5d6cd93 100644 --- a/pkg/kafkacomm/handler/pdp_update_deploy_policy.go +++ b/pkg/kafkacomm/handler/pdp_update_deploy_policy.go @@ -36,6 +36,7 @@ import ( "policy-opa-pdp/pkg/opasdk" "policy-opa-pdp/pkg/policymap" "policy-opa-pdp/pkg/utils" + "sort" "strings" ) @@ -168,7 +169,7 @@ func extractAndDecodePolicies(policy model.ToscaPolicy) (map[string]string, []st return nil, nil, err } - log.Debugf("Decoded policy content for key '%s': %s", key, decodedPolicy) + log.Tracef("Decoded policy content for key '%s': %s", key, decodedPolicy) } return decodedPolicies, keys, nil @@ -228,7 +229,7 @@ func getDirName(policy model.ToscaPolicy) []string { for key, _ := range policy.Properties.Data { - dirNames = append(dirNames, strings.ReplaceAll(consts.Data+"/"+key, ".", "/")) + dirNames = append(dirNames, strings.ReplaceAll(consts.DataNode+key, ".", "/")) } for key, _ := range policy.Properties.Policy { @@ -258,13 +259,14 @@ func upsertPolicy(policy model.ToscaPolicy) error { // handles writing data to sdk. func upsertData(policy model.ToscaPolicy) error { decodedDataContent, dataKeys, _ := extractAndDecodeDataVar(policy) + sort.Sort(utils.ByDotCount{Keys: dataKeys, Ascend: true}) for _, dataKey := range dataKeys { dataContent := decodedDataContent[dataKey] reader := bytes.NewReader([]byte(dataContent)) decoder := json.NewDecoder(reader) decoder.UseNumber() - var wdata map[string]interface{} + var wdata interface{} err := decoder.Decode(&wdata) if err != nil { log.Errorf("Failed to Insert Data: %s: %v", policy.Name, err) @@ -365,11 +367,7 @@ func checkIfPolicyAlreadyDeployed(pdpUpdate model.PdpUpdate) []model.ToscaPolicy // verfies policy by creating bundle. func verifyPolicyByBundleCreation(policy model.ToscaPolicy) error { // get directory name - dirNames := getDirName(policy) - if len(dirNames) == 0 { - log.Warnf("Unable to extract folder name from policy %s", policy.Name) - return fmt.Errorf("failed to extract folder name") - } + dirNames := []string{strings.ReplaceAll(consts.DataNode+"/"+policy.Name, ".", "/"), strings.ReplaceAll(consts.Policies+"/"+policy.Name, ".", "/")} // create bundle output, err := createBundleFuncVar(exec.Command, policy) if err != nil { diff --git a/pkg/kafkacomm/handler/pdp_update_deploy_policy_test.go b/pkg/kafkacomm/handler/pdp_update_deploy_policy_test.go index 3e4a24a..e95bbeb 100644 --- a/pkg/kafkacomm/handler/pdp_update_deploy_policy_test.go +++ b/pkg/kafkacomm/handler/pdp_update_deploy_policy_test.go @@ -78,128 +78,6 @@ func TestValidatePackageName(t *testing.T) { } } -func TestGetDirName(t *testing.T) { - var testData = []struct { - name string - policy model.ToscaPolicy // Use the actual package name - expected []string - }{ - { - name: "Basic valid case", - policy: model.ToscaPolicy{ - Type: "onap.policies.native.opa", - TypeVersion: "1.0.0", - Properties: model.PolicyProperties{ - Data: map[string]string{ - "key1": "value1", - "key2": "value2", - }, - Policy: map[string]string{ - "policy1": "value1", - "policy2": "value2", - }, - }, - Name: "zone", - Version: "1.0.0", - Metadata: model.Metadata{ - PolicyID: "zone", - PolicyVersion: "1.0.0", - }, - }, - expected: []string{ - "/opt/data/key2", - "/opt/data/key1", - "/opt/policies/policy1", - "/opt/policies/policy2", - }, - }, - { - name: "Empty policy", - policy: model.ToscaPolicy{ - Type: "onap.policies.native.opa", - TypeVersion: "1.0.0", - Properties: model.PolicyProperties{ - Data: map[string]string{}, - Policy: map[string]string{}, - }, - Name: "zone", - Version: "1.0.0", - Metadata: model.Metadata{ - PolicyID: "zone", - PolicyVersion: "1.0.0", - }, - }, - expected: []string{}, // No directories expected - }, - { - name: "Multiple keys", - policy: model.ToscaPolicy{ - Type: "onap.policies.native.opa", - TypeVersion: "1.0.0", - Properties: model.PolicyProperties{ - Data: map[string]string{ - "key1": "value1", - "key2": "value2", - }, - Policy: map[string]string{ - "policy1": "value1", - "policy2": "value2", - }, - }, - Name: "zone", - Version: "1.0.0", - Metadata: model.Metadata{ - PolicyID: "zone", - PolicyVersion: "1.0.0", - }, - }, - expected: []string{ - "/opt/data/key1", - "/opt/data/key2", - "/opt/policies/policy1", - "/opt/policies/policy2", - }, - }, - { - name: "Special characters", - policy: model.ToscaPolicy{ - Type: "onap.policies.native.opa", - TypeVersion: "1.0.0", - Properties: model.PolicyProperties{ - Data: map[string]string{ - "key.with.dot": "value1", - }, - Policy: map[string]string{ - "policy.with.dot": "value2", - }, - }, - Name: "zone", - Version: "1.0.0", - Metadata: model.Metadata{ - PolicyID: "zone", - PolicyVersion: "1.0.0", - }, - }, - expected: []string{ - "/opt/data/key/with/dot", - "/opt/policies/policy/with/dot", - }, - }, - } - for _, tt := range testData { - t.Run(tt.name, func(t *testing.T) { - result := getDirName(tt.policy) - // Check that the actual result is either nil or empty - if len(tt.expected) == 0 { - // They should both be empty - assert.Empty(t, result) // Assert that result is empty - } else { - assert.ElementsMatch(t, tt.expected, result) // Standard equality check for non-empty scenarios - } - }) - } -} - func TestExtractAndDecodeData(t *testing.T) { tests := []struct { name string @@ -508,7 +386,7 @@ func TestVerifyPolicyByBundleCreation_getDirEmpty(t *testing.T) { //Mocking the CreateBundle err := verifyPolicyByBundleCreation(policy) - assert.Error(t, err) + assert.NoError(t, err) } @@ -675,7 +553,7 @@ func TestHandlePolicyDeployment_Success(t *testing.T) { { Properties: model.PolicyProperties{ Data: map[string]string{ - "node.role": "ewogICAgInVzZXJfcm9sZXMiOiB7CiAgICAgICAgImFsaWNlIjogWwogICAgICAgICAgICAiYWRtaW4iCiAgICAgICAgXSwKICAgICAgICAiYm9iIjogWwogICAgICAgICAgICAiZW1wbG95ZWUiLAogICAgICAgICAgICAiYmlsbGluZyIKICAgICAgICBdLAogICAgICAgICJldmUiOiBbCiAgICAgICAgICAgICJjdXN0b21lciIKICAgICAgICBdCiAgICB9LAogICAgInJvbGVfZ3JhbnRzIjogewogICAgICAgICJjdXN0b21lciI6IFsKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgImFjdGlvbiI6ICJyZWFkIiwKICAgICAgICAgICAgICAgICJ0eXBlIjogImRvZyIKICAgICAgICAgICAgfSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgImFjdGlvbiI6ICJyZWFkIiwKICAgICAgICAgICAgICAgICJ0eXBlIjogImNhdCIKICAgICAgICAgICAgfSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgImFjdGlvbiI6ICJhZG9wdCIsCiAgICAgICAgICAgICAgICAidHlwZSI6ICJkb2ciCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICJhY3Rpb24iOiAiYWRvcHQiLAogICAgICAgICAgICAgICAgInR5cGUiOiAiY2F0IgogICAgICAgICAgICB9CiAgICAgICAgXSwKICAgICAgICAiZW1wbG95ZWUiOiBbCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICJhY3Rpb24iOiAicmVhZCIsCiAgICAgICAgICAgICAgICAidHlwZSI6ICJkb2ciCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICJhY3Rpb24iOiAicmVhZCIsCiAgICAgICAgICAgICAgICAidHlwZSI6ICJjYXQiCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICJhY3Rpb24iOiAidXBkYXRlIiwKICAgICAgICAgICAgICAgICJ0eXBlIjogImRvZyIKICAgICAgICAgICAgfSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgImFjdGlvbiI6ICJ1cGRhdGUiLAogICAgICAgICAgICAgICAgInR5cGUiOiAiY2F0IgogICAgICAgICAgICB9CiAgICAgICAgXSwKICAgICAgICAiYmlsbGluZyI6IFsKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgImFjdGlvbiI6ICJyZWFkIiwKICAgICAgICAgICAgICAgICJ0eXBlIjogImZpbmFuY2UiCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICJhY3Rpb24iOiAidXBkYXRlIiwKICAgICAgICAgICAgICAgICJ0eXBlIjogImZpbmFuY2UiCiAgICAgICAgICAgIH0KICAgICAgICBdCiAgICB9Cn0K", + "node.role": "ewogICAgInVzZXJfcm9sZXMiOiB7CiAgICAgICAgImFsaWNlIjogWwogICAgICAgICAgICAiYWRtaW4iCiAgICAgICAgXSwKICAgICAgICAiYm9iIjogWwogICAgICAgICAgICAiZW1wbG95ZWUiLAogICAgICAgICAgICAiYmlsbGluZyIKICAgICAgICBdLAogICAgICAgICJldmUiOiBbCiAgICAgICAgICAgICJjdXN0b21lciIKICAgICAgICBdCiAgICB9LAogICAgInJvbGVfZ3JhbnRzIjogewogICAgICAgICJjdXN0b21lciI6IFsKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgImFjdGlvbiI6ICJyZWFkIiwKICAgICAgICAgICAgICAgICJ0eXBlIjogImRvZyIKICAgICAgICAgICAgfSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgImFjdGlvbiI6ICJyZWFkIiwKICAgICAgICAgICAgICAgICJ0eXBlIjogImNhdCIKICAgICAgICAgICAgfSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgImFjdGlvbiI6ICJhZG9wdCIsCiAgICAgICAgICAgICAgICAidHlwZSI6ICJkb2ciCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICJhY3Rpb24iOiAiYWRvcHQiLAogICAgICAgICAgICAgICAgInR5cGUiOiAiY2F0IgogICAgICAgICAgICB9CiAgICAgICAgXSwKICAgICAgICAiZW1wbG95ZWUiOiBbCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICJhY3Rpb24iOiAicmVhZCIsCiAgICAgICAgICAgICAgICAidHlwZSI6ICJkb2ciCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICJhY3Rpb24iOiAicmVhZCIsCiAgICAgICAgICAgICAgICAidHlwZSI6ICJjYXQiCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICJhY3Rpb24iOiAidXBkYXRlIiwKICAgICAgICAgICAgICAgICJ0eXBlIjogImRvZyIKICAgICAgICAgICAgfSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgImFjdGlvbiI6ICJ1cGRhdGUiLAogICAgICAgICAgICAgICAgInR5cGUiOiAiY2F0IgogICAgICAgICAgICB9CiAgICAgICAgXSwKICAgICAgICAiYmlsbGluZyI6IFsKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgImFjdGlvbiI6ICJyZWFkIiwKICAgICAgICAgICAgICAgICJ0eXBlIjogImZpbmFuY2UiCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICJhY3Rpb24iOiAidXBkYXRlIiwKICAgICAgICAgICAgICAgICJ0eXBlIjogImZpbmFuY2UiCiAgICAgICAgICAgIH0KICAgICAgICBdCiAgICB9Cn0K", }, Policy: map[string]string{ "role": "ewogICAgInVzZXJfcm9sZXMiOiB7CiAgICAgICAgImFsaWNlIjogWwogICAgICAgICAgICAiYWRtaW4iCiAgICAgICAgXSwKICAgICAgICAiYm9iIjogWwogICAgICAgICAgICAiZW1wbG95ZWUiLAogICAgICAgICAgICAiYmlsbGluZyIKICAgICAgICBdLAogICAgICAgICJldmUiOiBbCiAgICAgICAgICAgICJjdXN0b21lciIKICAgICAgICBdCiAgICB9LAogICAgInJvbGVfZ3JhbnRzIjogewogICAgICAgICJjdXN0b21lciI6IFsKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgImFjdGlvbiI6ICJyZWFkIiwKICAgICAgICAgICAgICAgICJ0eXBlIjogImRvZyIKICAgICAgICAgICAgfSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgImFjdGlvbiI6ICJyZWFkIiwKICAgICAgICAgICAgICAgICJ0eXBlIjogImNhdCIKICAgICAgICAgICAgfSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgImFjdGlvbiI6ICJhZG9wdCIsCiAgICAgICAgICAgICAgICAidHlwZSI6ICJkb2ciCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICJhY3Rpb24iOiAiYWRvcHQiLAogICAgICAgICAgICAgICAgInR5cGUiOiAiY2F0IgogICAgICAgICAgICB9CiAgICAgICAgXSwKICAgICAgICAiZW1wbG95ZWUiOiBbCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICJhY3Rpb24iOiAicmVhZCIsCiAgICAgICAgICAgICAgICAidHlwZSI6ICJkb2ciCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICJhY3Rpb24iOiAicmVhZCIsCiAgICAgICAgICAgICAgICAidHlwZSI6ICJjYXQiCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICJhY3Rpb24iOiAidXBkYXRlIiwKICAgICAgICAgICAgICAgICJ0eXBlIjogImRvZyIKICAgICAgICAgICAgfSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgImFjdGlvbiI6ICJ1cGRhdGUiLAogICAgICAgICAgICAgICAgInR5cGUiOiAiY2F0IgogICAgICAgICAgICB9CiAgICAgICAgXSwKICAgICAgICAiYmlsbGluZyI6IFsKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgImFjdGlvbiI6ICJyZWFkIiwKICAgICAgICAgICAgICAgICJ0eXBlIjogImZpbmFuY2UiCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICJhY3Rpb24iOiAidXBkYXRlIiwKICAgICAgICAgICAgICAgICJ0eXBlIjogImZpbmFuY2UiCiAgICAgICAgICAgIH0KICAgICAgICBdCiAgICB9Cn0K", diff --git a/pkg/kafkacomm/handler/pdp_update_message_handler.go b/pkg/kafkacomm/handler/pdp_update_message_handler.go index 58ee1b0..9268115 100644 --- a/pkg/kafkacomm/handler/pdp_update_message_handler.go +++ b/pkg/kafkacomm/handler/pdp_update_message_handler.go @@ -79,7 +79,6 @@ func pdpUpdateMessageHandler(message []byte, p publisher.PdpStatusSender) error log.Debugf("PDP_UPDATE Message received: %s", string(message)) pdpattributes.SetPdpSubgroup(pdpUpdate.PdpSubgroup) - pdpattributes.SetPdpHeartbeatInterval(pdpUpdate.PdpHeartbeatIntervalMs) if len(pdpUpdate.PoliciesToBeDeployed) > 0 { failureMessage, successfullyDeployedPolicies := handlePolicyDeploymentVar(pdpUpdate, p) @@ -131,7 +130,15 @@ func pdpUpdateMessageHandler(message []byte, p publisher.PdpStatusSender) error } } log.Infof("PDP_STATUS Message Sent Successfully") - go publisher.StartHeartbeatIntervalTimer(pdpattributes.PdpHeartbeatInterval, p) + log.Debug(pdpUpdate.PdpHeartbeatIntervalMs) + + if pdpattributes.PdpHeartbeatInterval != pdpUpdate.PdpHeartbeatIntervalMs && pdpUpdate.PdpHeartbeatIntervalMs != 0 { + //restart the ticker. + publisher.StopTicker() + pdpattributes.SetPdpHeartbeatInterval(pdpUpdate.PdpHeartbeatIntervalMs) + go publisher.StartHeartbeatIntervalTimer(pdpattributes.PdpHeartbeatInterval, p) + } + return nil } diff --git a/pkg/kafkacomm/handler/pdp_update_message_handler_test.go b/pkg/kafkacomm/handler/pdp_update_message_handler_test.go index 276cffd..e7b27fd 100644 --- a/pkg/kafkacomm/handler/pdp_update_message_handler_test.go +++ b/pkg/kafkacomm/handler/pdp_update_message_handler_test.go @@ -634,5 +634,5 @@ func TestSendPDPStatusResponse_SimulateFailures(t *testing.T) { } -func TestCreateBundleFunc(t *testing.T){ +func TestCreateBundleFunc(t *testing.T) { } diff --git a/pkg/kafkacomm/handler/pdp_update_undeploy_policy.go b/pkg/kafkacomm/handler/pdp_update_undeploy_policy.go index 31d4554..4e72619 100644 --- a/pkg/kafkacomm/handler/pdp_update_undeploy_policy.go +++ b/pkg/kafkacomm/handler/pdp_update_undeploy_policy.go @@ -21,6 +21,7 @@ package handler import ( "context" + "encoding/json" "fmt" "path/filepath" "policy-opa-pdp/consts" @@ -28,38 +29,41 @@ import ( "policy-opa-pdp/pkg/log" "policy-opa-pdp/pkg/metrics" "policy-opa-pdp/pkg/model" + "policy-opa-pdp/pkg/model/oapicodegen" "policy-opa-pdp/pkg/opasdk" "policy-opa-pdp/pkg/policymap" "policy-opa-pdp/pkg/utils" + "sort" "strings" ) type ( HandlePolicyUndeploymentFunc func(pdpUpdate model.PdpUpdate, p publisher.PdpStatusSender) ([]string, map[string]string) + opasdkGetDataFunc func(ctx context.Context, dataPath string) (data *oapicodegen.OPADataResponse_Data, err error) ) var ( - handlePolicyUndeploymentVar HandlePolicyUndeploymentFunc = handlePolicyUndeployment + handlePolicyUndeploymentVar HandlePolicyUndeploymentFunc = handlePolicyUndeployment - removeDirectoryFunc = utils.RemoveDirectory + removeDirectoryFunc = utils.RemoveDirectory - deleteDataSdkFunc = opasdk.DeleteData + deleteDataSdkFunc = opasdk.DeleteData - deletePolicySdkFunc = opasdk.DeletePolicy + deletePolicySdkFunc = opasdk.DeletePolicy - removeDataDirectoryFunc = removeDataDirectory + opasdkGetData opasdkGetDataFunc = opasdk.GetDataInfo - removePolicyDirectoryFunc = removePolicyDirectory + removeDataDirectoryFunc = removeDataDirectory - policyUndeploymentActionFunc = policyUndeploymentAction + removePolicyDirectoryFunc = removePolicyDirectory - removePolicyFromSdkandDirFunc= removePolicyFromSdkandDir + policyUndeploymentActionFunc = policyUndeploymentAction - removeDataFromSdkandDirFunc = removeDataFromSdkandDir + removePolicyFromSdkandDirFunc = removePolicyFromSdkandDir + removeDataFromSdkandDirFunc = removeDataFromSdkandDir ) - // processPoliciesTobeUndeployed handles the undeployment of policies func processPoliciesTobeUndeployed(undeployedPolicies map[string]string) ([]string, map[string]string) { var failureMessages []string @@ -146,10 +150,29 @@ func removeDataFromSdkandDir(policy map[string]interface{}) []string { var failureMessages []string if dataKeys, ok := policy["data"].([]interface{}); ok { + var dataKeysSlice []string for _, dataKey := range dataKeys { - keyPath := "/" + strings.Replace(dataKey.(string), ".", "/", -1) - log.Debugf("Deleting data from OPA at keypath: %s", keyPath) - if err := deleteDataSdkFunc(context.Background(), keyPath); err != nil { + if strKey, ok := dataKey.(string); ok { + dataKeysSlice = append(dataKeysSlice, strKey) + } else { + failureMessages = append(failureMessages, fmt.Sprintf("Invalid Key :%s", dataKey)) + } + } + sort.Sort(utils.ByDotCount{Keys: dataKeysSlice, Ascend: false}) + + for _, keyPath := range dataKeysSlice { + keyPath = "/" + strings.Replace(keyPath, ".", "/", -1) + log.Debugf("Deleting data from OPA : %s", keyPath) + // Prepare to handle any errors + var err error + var dataPath string + // Fetch data first + // Call the function to check and Analyse empty parent nodes + if dataPath, err = analyseEmptyParentNodes(keyPath); err != nil { + failureMessages = append(failureMessages, err.Error()) + } + if err := deleteDataSdkFunc(context.Background(), dataPath); err != nil { + log.Errorf("Error while deleting Data from SDK for path : %s , %v", keyPath, err.Error()) failureMessages = append(failureMessages, err.Error()) continue } @@ -171,6 +194,7 @@ func removePolicyFromSdkandDir(policy map[string]interface{}) []string { if policyKeys, ok := policy["policy"].([]interface{}); ok { for _, policyKey := range policyKeys { keyPath := "/" + strings.Replace(policyKey.(string), ".", "/", -1) + log.Debugf("Deleting Policy from OPA : %s", keyPath) if err := deletePolicySdkFunc(context.Background(), policyKey.(string)); err != nil { failureMessages = append(failureMessages, err.Error()) continue @@ -220,3 +244,148 @@ func findDeployedPolicy(policyID, policyVersion string, deployedPolicies []map[s } return nil } + +// analyzeEmptyParentNodes constructs the parent path based on the provided dataPath. +// It checks if any parent nodes become empty after the deletion of the last child key. +// +// This function takes a JSON representation of parent data and a data path, +// splits the path into segments, and determines the eligible paths for deletion. +// +// If a parent node has only one child and that child is to be deleted, +// the full path up to that parent will be returned. If no eligible parents +// are found by the time it reaches back to the root, the original path will be returned. +func analyseEmptyParentNodes(dataPath string) (string, error) { + log.Debugf("Analyzing dataPath: %s", dataPath) + // Split the dataPath into segments + pathSegments := strings.Split(dataPath, "/") + log.Debugf("Path segments: %+v", pathSegments) + // If the path does not have at least 3 segments, treat it as a leaf node + if len(pathSegments) < consts.SingleHierarchy { + log.Debugf("Path doesn't have any parent-child hierarchy;so returning the original path: %s", dataPath) + return dataPath, nil // It's a leaf node or too short; return the original path + } + // Prepare the parent path which is derived from the second segment + parentKeyPath := "/" + pathSegments[1] // Assuming the immediate parent node + log.Debugf("Detected parent path: %s", parentKeyPath) + // Fetch the data for the detected parent path + parentData, err := opasdkGetData(context.Background(), parentKeyPath) + if err != nil { + return "", fmt.Errorf("failed to get data for parent path %s: %w", parentKeyPath, err) + } + // Unmarshal parent data JSON into a map for analysis + parentDataJson, err := json.Marshal(parentData) + if err != nil { + return "", fmt.Errorf("failed to marshal parent data: %w", err) + } + // Call the method to analyze the hierarchy + return analyzeHierarchy(parentDataJson, dataPath) +} + +// analyzeHierarchy examines the provided data path against the JSON structure to determine +// the last eligible path for deletion based on parent-child relationships. +// +// The function takes a JSON object in raw format and splits the data path into segments. +// Starting from the last key, it checks each parent key to see if it has only one child. +// If so, it marks the path up to that parent as the last eligible path for deletion. +func analyzeHierarchy(parentDataJson json.RawMessage, dataPath string) (string, error) { + // Create a map to hold the parent data + parentMap := make(map[string]interface{}) + + // Unmarshal the fetched JSON data into the parentMap + if err := json.Unmarshal(parentDataJson, &parentMap); err != nil { + return "", fmt.Errorf("error unmarshalling parent data: %w", err) + } + + // Count keys in the JSON structure + countMap := countChildKeysFromJSON(parentMap) + // Split keys and omit the first empty element + keys := strings.Split(dataPath, "/")[1:] + // Default to the input path + lastEligible := dataPath + // Traverse the path from the last key to the first key + // Start from the last segment and stop at the first parent + for indexfromKeyPath := len(keys) - 1; indexfromKeyPath >= 1; indexfromKeyPath-- { + // Identify the parent of the current path + currentPath := strings.Join(keys[:indexfromKeyPath], "/") + // Checking counts of the parent key + childCount := countMap[currentPath] + if childCount == 1 { + // If parent has only 1 child after deletion, it is eligible + lastEligible = "/" + currentPath // Store the path up to this parent + } else { + break + } + } + + log.Debugf("lastEligible Path: %+v", lastEligible) + return lastEligible, nil + +} + +// countChildKeysFromJSON counts the number of child keys for each key in a JSON structure represented as a map. +// +// This function traverses the provided JSON map iteratively using a stack, counting +// the number of direct children for each key. The counts are stored in a map where +// the keys represent the paths in the JSON hierarchy (using slash notation) and the +// values indicate how many children each key has. +// Example Inputs and Outputs: +// +// Given the following JSON: +// { +// "node": { +// "collab": { +// "action": { +// "conflict": {}, +// "others": {} +// }, +// "role": {} +// }, +// "role": { +// "role_grants": { +// "billing": {}, +// "shipping": {} +// } +// } +// } +// } +// Example Output: +// { +// "node": 2, +// "node/collab": 2, +// "node/collab/action": 2, +// "node/collab/role": 0, +// "node/role": 1, +// "node/role/role_grants": 2, +// "node/role/role_grants/billing": 0, +// "node/role/role_grants/shipping": 0 +// } +func countChildKeysFromJSON(data map[string]interface{}) map[string]int { + countMap := make(map[string]int) + + // Creating a stack for iterative traversal with paths + stack := []struct { + current map[string]interface{} + path string + }{ + {data, "node"}, // Start with the root node path + } + + for len(stack) > 0 { + // Pop the current map from the stack + top := stack[len(stack)-1] + stack = stack[:len(stack)-1] + for key, value := range top.current { + //take the full path + currentPath := top.path + "/" + key + if childMap, ok := value.(map[string]interface{}); ok { + // Count the number of children for each key + countMap[currentPath] = len(childMap) + stack = append(stack, struct { + current map[string]interface{} + path string + }{childMap, currentPath}) // Push children map into stack with full path + } + } + } + return countMap +} diff --git a/pkg/kafkacomm/handler/pdp_update_undeploy_policy_test.go b/pkg/kafkacomm/handler/pdp_update_undeploy_policy_test.go index f725f4b..08aed34 100644 --- a/pkg/kafkacomm/handler/pdp_update_undeploy_policy_test.go +++ b/pkg/kafkacomm/handler/pdp_update_undeploy_policy_test.go @@ -20,13 +20,14 @@ package handler import ( - // "encoding/json" "context" + "encoding/json" "errors" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" "policy-opa-pdp/consts" "policy-opa-pdp/pkg/model" + "policy-opa-pdp/pkg/model/oapicodegen" "policy-opa-pdp/pkg/policymap" "testing" ) @@ -346,6 +347,18 @@ func TestRemoveDataFromSdkandDir(t *testing.T) { }() // Mock removeDataDirectoryFunc and deleteDataFunc to return errors for testing + opasdkGetData = func(ctx context.Context, dataPath string) (data *oapicodegen.OPADataResponse_Data, err error) { + // Mock JSON data + mockedData := `{"mocked": {"success": "value", "error": "value"}}` + // Create an instance of OPADataResponse_Data + var response oapicodegen.OPADataResponse_Data + // Unmarshal into the OPADataResponse_Data struct + err = json.Unmarshal([]byte(mockedData), &response) + if err != nil { + return nil, errors.New("Error unmarshalling") + } + return &response, nil // + } removeDataDirectoryFunc = func(dataKey string) error { if dataKey == "/mocked/error" { return errors.New("mocked remove data directory error") @@ -370,42 +383,40 @@ func TestRemoveDataFromSdkandDir(t *testing.T) { assert.Contains(t, failures[0], "mocked delete data error") } - func TestRemovePolicyFromSdkandDir(t *testing.T) { - // Backup original functions - originalRemovePolicyDirectory := removePolicyDirectoryFunc - originalDeletePolicy := deletePolicySdkFunc - defer func() { - removePolicyDirectoryFunc = originalRemovePolicyDirectory // Restore after test - deletePolicySdkFunc = originalDeletePolicy // Restore after test - }() - - // Mock functions - removePolicyDirectoryFunc = func(policyKey string) error { - if policyKey == "/mocked/error" { - return errors.New("mocked remove policy directory error") - } - return nil - } - - deletePolicySdkFunc = func(ctx context.Context, policyPath string) error { - if policyPath == "mocked.error" { - return errors.New("mocked delete policy error") - } - return nil - } - - policy := map[string]interface{}{ - "policy": []interface{}{"mocked.success", "mocked.error"}, // VALID policy key - } - - failures := removePolicyFromSdkandDir(policy) - - // Expecting 1 error message (for "mocked.error"), "mocked.success" should pass - assert.Len(t, failures, 1) - assert.Contains(t, failures[0], "mocked delete policy error") -} + // Backup original functions + originalRemovePolicyDirectory := removePolicyDirectoryFunc + originalDeletePolicy := deletePolicySdkFunc + defer func() { + removePolicyDirectoryFunc = originalRemovePolicyDirectory // Restore after test + deletePolicySdkFunc = originalDeletePolicy // Restore after test + }() + + // Mock functions + removePolicyDirectoryFunc = func(policyKey string) error { + if policyKey == "/mocked/error" { + return errors.New("mocked remove policy directory error") + } + return nil + } + + deletePolicySdkFunc = func(ctx context.Context, policyPath string) error { + if policyPath == "mocked.error" { + return errors.New("mocked delete policy error") + } + return nil + } + policy := map[string]interface{}{ + "policy": []interface{}{"mocked.success", "mocked.error"}, // VALID policy key + } + + failures := removePolicyFromSdkandDir(policy) + + // Expecting 1 error message (for "mocked.error"), "mocked.success" should pass + assert.Len(t, failures, 1) + assert.Contains(t, failures[0], "mocked delete policy error") +} // Mocking the remove functions var ( diff --git a/pkg/kafkacomm/pdp_topic_consumer.go b/pkg/kafkacomm/pdp_topic_consumer.go index 2b28672..a16bd4a 100644 --- a/pkg/kafkacomm/pdp_topic_consumer.go +++ b/pkg/kafkacomm/pdp_topic_consumer.go @@ -48,9 +48,9 @@ type KafkaConsumer struct { } // Close closes the KafkaConsumer -func (kc *KafkaConsumer) Close() error{ +func (kc *KafkaConsumer) Close() error { if kc.Consumer != nil { - if err := kc.Consumer.Close(); err != nil{ + if err := kc.Consumer.Close(); err != nil { return fmt.Errorf("failed to close consumer: %v", err) } } @@ -72,9 +72,10 @@ func (kc *KafkaConsumer) Unsubscribe() error { } type KafkaNewConsumerFunc func(*kafka.ConfigMap) (*kafka.Consumer, error) + var KafkaNewConsumer KafkaNewConsumerFunc = kafka.NewConsumer -// NewKafkaConsumer creates a new Kafka consumer and returns +// NewKafkaConsumer creates a new Kafka consumer and returns func NewKafkaConsumer() (*KafkaConsumer, error) { // Initialize the consumer instance only once consumerOnce.Do(func() { @@ -95,17 +96,17 @@ func NewKafkaConsumer() (*KafkaConsumer, error) { fmt.Print(configMap) // If SASL is enabled, add SASL properties if useSASL == "true" { - configMap.SetKey("sasl.mechanism", "SCRAM-SHA-512") // #nosec G104 - configMap.SetKey("sasl.username", username) // #nosec G104 - configMap.SetKey("sasl.password", password) // #nosec G104 - configMap.SetKey("security.protocol", "SASL_PLAINTEXT") // #nosec G104 - configMap.SetKey("fetch.max.bytes", 50*1024*1024) // #nosec G104 - configMap.SetKey("max.partition.fetch.bytes",50*1024*1024) // #nosec G104 - configMap.SetKey("socket.receive.buffer.bytes", 50*1024*1024) // #nosec G104 - configMap.SetKey("session.timeout.ms", "30000") // #nosec G104 - configMap.SetKey("max.poll.interval.ms", "300000") // #nosec G104 - configMap.SetKey("enable.partition.eof", true) // #nosec G104 - configMap.SetKey("enable.auto.commit", true) // #nosec G104 + configMap.SetKey("sasl.mechanism", "SCRAM-SHA-512") // #nosec G104 + configMap.SetKey("sasl.username", username) // #nosec G104 + configMap.SetKey("sasl.password", password) // #nosec G104 + configMap.SetKey("security.protocol", "SASL_PLAINTEXT") // #nosec G104 + configMap.SetKey("fetch.max.bytes", 50*1024*1024) // #nosec G104 + configMap.SetKey("max.partition.fetch.bytes", 50*1024*1024) // #nosec G104 + configMap.SetKey("socket.receive.buffer.bytes", 50*1024*1024) // #nosec G104 + configMap.SetKey("session.timeout.ms", "30000") // #nosec G104 + configMap.SetKey("max.poll.interval.ms", "300000") // #nosec G104 + configMap.SetKey("enable.partition.eof", true) // #nosec G104 + configMap.SetKey("enable.auto.commit", true) // #nosec G104 // configMap.SetKey("debug", "all") // Uncomment for debug } diff --git a/pkg/kafkacomm/pdp_topic_consumer_test.go b/pkg/kafkacomm/pdp_topic_consumer_test.go index f9160b2..36a2aa4 100644 --- a/pkg/kafkacomm/pdp_topic_consumer_test.go +++ b/pkg/kafkacomm/pdp_topic_consumer_test.go @@ -21,7 +21,7 @@ package kafkacomm import ( "errors" - "fmt" + "fmt" "github.com/confluentinc/confluent-kafka-go/v2/kafka" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" @@ -133,18 +133,18 @@ func TestKafkaConsumer_Close(t *testing.T) { } func TestKafkaConsumerClose_Error(t *testing.T) { - mockConsumer := new(mocks.KafkaConsumerInterface) + mockConsumer := new(mocks.KafkaConsumerInterface) - kc := &KafkaConsumer{Consumer: mockConsumer} + kc := &KafkaConsumer{Consumer: mockConsumer} - // Set up the mock for Close - mockConsumer.On("Close").Return(errors.New("close error")) + // Set up the mock for Close + mockConsumer.On("Close").Return(errors.New("close error")) - // Test Close method - kc.Close() + // Test Close method + kc.Close() - // Verify that Close was called - mockConsumer.AssertExpectations(t) + // Verify that Close was called + mockConsumer.AssertExpectations(t) } func TestKafkaConsumer_Unsubscribe(t *testing.T) { diff --git a/pkg/kafkacomm/pdp_topic_producer.go b/pkg/kafkacomm/pdp_topic_producer.go index 13cd271..341cd01 100644 --- a/pkg/kafkacomm/pdp_topic_producer.go +++ b/pkg/kafkacomm/pdp_topic_producer.go @@ -64,9 +64,9 @@ func GetKafkaProducer(bootstrapServers, topic string) (*KafkaProducer, error) { } if useSASL == "true" { - configMap.SetKey("sasl.mechanism", "SCRAM-SHA-512") // #nosec G104 - configMap.SetKey("sasl.username", username) // #nosec G104 - configMap.SetKey("sasl.password", password) // #nosec G104 + configMap.SetKey("sasl.mechanism", "SCRAM-SHA-512") // #nosec G104 + configMap.SetKey("sasl.username", username) // #nosec G104 + configMap.SetKey("sasl.password", password) // #nosec G104 configMap.SetKey("security.protocol", "SASL_PLAINTEXT") // #nosec G104 } @@ -107,7 +107,7 @@ func (kp *KafkaProducer) Close() { log.Println("KafkaProducer or producer is nil, skipping Close.") return } - kp.producer.Flush(15*1000) + kp.producer.Flush(15 * 1000) kp.producer.Close() log.Println("KafkaProducer closed successfully.") } diff --git a/pkg/kafkacomm/pdp_topic_producer_test.go b/pkg/kafkacomm/pdp_topic_producer_test.go index dfdad4b..e106772 100644 --- a/pkg/kafkacomm/pdp_topic_producer_test.go +++ b/pkg/kafkacomm/pdp_topic_producer_test.go @@ -113,7 +113,7 @@ func TestKafkaProducer_Close(t *testing.T) { producer: mockProducer, } - mockProducer.On("Flush", mock.AnythingOfType("int")).Return(0) + mockProducer.On("Flush", mock.AnythingOfType("int")).Return(0) // Simulate successful close mockProducer.On("Close").Return() diff --git a/pkg/kafkacomm/publisher/pdp-heartbeat.go b/pkg/kafkacomm/publisher/pdp-heartbeat.go index 7cc9beb..da4888f 100644 --- a/pkg/kafkacomm/publisher/pdp-heartbeat.go +++ b/pkg/kafkacomm/publisher/pdp-heartbeat.go @@ -24,7 +24,6 @@ package publisher import ( "fmt" - "github.com/google/uuid" "policy-opa-pdp/consts" "policy-opa-pdp/pkg/log" "policy-opa-pdp/pkg/model" @@ -33,6 +32,7 @@ import ( "policy-opa-pdp/pkg/policymap" "sync" "time" + "github.com/google/uuid" ) var ( @@ -40,6 +40,7 @@ var ( stopChan chan bool currentInterval int64 mu sync.Mutex + wg sync.WaitGroup ) // Initializes a timer that sends periodic heartbeat messages to indicate the health and state of the PDP. @@ -53,24 +54,21 @@ func StartHeartbeatIntervalTimer(intervalMs int64, s PdpStatusSender) { return } else if intervalMs == 0 { intervalMs = currentInterval - } if ticker != nil && intervalMs == currentInterval { - log.Debug("Ticker is already running") + log.Trace("Ticker is already running") return } - if ticker != nil { - ticker.Stop() - } - currentInterval = intervalMs ticker = time.NewTicker(time.Duration(intervalMs) * time.Millisecond) - log.Debugf("New Ticker %d", currentInterval) + log.Debugf("New Ticker started with interval %d", currentInterval) stopChan = make(chan bool) + wg.Add(1) go func() { + defer wg.Done() for { select { case <-ticker.C: @@ -78,6 +76,7 @@ func StartHeartbeatIntervalTimer(intervalMs int64, s PdpStatusSender) { log.Errorf("Failed to send PDP Heartbeat: %v", err) } case <-stopChan: + log.Debugf("Stopping ticker") ticker.Stop() return } @@ -111,6 +110,13 @@ func sendPDPHeartBeat(s PdpStatusSender) error { } } + pdpSubGroup := pdpattributes.GetPdpSubgroup() + + if pdpSubGroup == "" || len(pdpSubGroup) == 0 { + pdpStatus.PdpSubgroup = nil + pdpStatus.Description = "Pdp Status Registration Message" + } + err := s.SendPdpStatus(pdpStatus) log.Debugf("Sending Heartbeat ...") if err != nil { @@ -128,9 +134,9 @@ func StopTicker() { if ticker != nil && stopChan != nil { stopChan <- true close(stopChan) - ticker.Stop() - ticker = nil stopChan = nil + wg.Wait() //wait for the goroutine to finish + log.Debugf("goroutine finsihed ...") } else { log.Debugf("Ticker is not Running") } diff --git a/pkg/kafkacomm/publisher/pdp-heartbeat_test.go b/pkg/kafkacomm/publisher/pdp-heartbeat_test.go index bdf202c..ac0ad02 100644 --- a/pkg/kafkacomm/publisher/pdp-heartbeat_test.go +++ b/pkg/kafkacomm/publisher/pdp-heartbeat_test.go @@ -21,11 +21,11 @@ package publisher import ( "errors" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/mock" "policy-opa-pdp/pkg/kafkacomm/publisher/mocks" "policy-opa-pdp/pkg/policymap" "testing" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" ) /* @@ -108,17 +108,17 @@ Input: Valid pdpStatus object Expected Output: Heartbeat message is sent successfully, and a debug log "Message sent successfully" is generated. */ func TestSendPDPHeartBeat_SuccessSomeDeployedPolicies(t *testing.T) { - // Setup mock Policymap - mockPolicymap := new(MockPolicymap) + // Setup mock Policymap + mockPolicymap := new(MockPolicymap) - mockSender := new(mocks.PdpStatusSender) - mockSender.On("SendPdpStatus", mock.Anything).Return(nil) + mockSender := new(mocks.PdpStatusSender) + mockSender.On("SendPdpStatus", mock.Anything).Return(nil) - policymap.LastDeployedPolicies = "some-policies" - // Set mock behavior for policymap - mockPolicymap.On("ExtractDeployedPolicies", mock.Anything).Return(nil) - err := sendPDPHeartBeat(mockSender) - assert.NoError(t, err) + policymap.LastDeployedPolicies = "some-policies" + // Set mock behavior for policymap + mockPolicymap.On("ExtractDeployedPolicies", mock.Anything).Return(nil) + err := sendPDPHeartBeat(mockSender) + assert.NoError(t, err) } /* @@ -128,17 +128,17 @@ Input: Valid pdpStatus object Expected Output: Heartbeat message is sent successfully, and a debug log "Message sent successfully" is generated. */ func TestSendPDPHeartBeat_SuccessNoDeployedPolicies(t *testing.T) { - // Setup mock Policymap - mockPolicymap := new(MockPolicymap) + // Setup mock Policymap + mockPolicymap := new(MockPolicymap) - mockSender := new(mocks.PdpStatusSender) - mockSender.On("SendPdpStatus", mock.Anything).Return(nil) + mockSender := new(mocks.PdpStatusSender) + mockSender.On("SendPdpStatus", mock.Anything).Return(nil) - policymap.LastDeployedPolicies = "" - // Set mock behavior for policymap - mockPolicymap.On("ExtractDeployedPolicies", mock.Anything).Return(nil) - err := sendPDPHeartBeat(mockSender) - assert.NoError(t, err) + policymap.LastDeployedPolicies = "" + // Set mock behavior for policymap + mockPolicymap.On("ExtractDeployedPolicies", mock.Anything).Return(nil) + err := sendPDPHeartBeat(mockSender) + assert.NoError(t, err) } /* @@ -151,11 +151,11 @@ func TestStopTicker_Success(t *testing.T) { mockSender := new(mocks.PdpStatusSender) mockSender.On("SendPdpStatus", mock.Anything).Return(nil) StartHeartbeatIntervalTimer(1000, mockSender) - + wg.Done() StopTicker() mu.Lock() defer mu.Unlock() - if ticker != nil { + if stopChan != nil { t.Errorf("Expected ticker to be nil") } } diff --git a/pkg/kafkacomm/publisher/pdp-pap-registration_test.go b/pkg/kafkacomm/publisher/pdp-pap-registration_test.go index 6826099..9855b28 100644 --- a/pkg/kafkacomm/publisher/pdp-pap-registration_test.go +++ b/pkg/kafkacomm/publisher/pdp-pap-registration_test.go @@ -22,11 +22,11 @@ package publisher import ( "errors" "fmt" + "github.com/confluentinc/confluent-kafka-go/v2/kafka" "github.com/google/uuid" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" "policy-opa-pdp/pkg/kafkacomm/publisher/mocks" - "github.com/confluentinc/confluent-kafka-go/v2/kafka" "policy-opa-pdp/pkg/model" "testing" "time" @@ -78,7 +78,7 @@ func (m *MockKafkaProducer) Close() { } func (m *MockKafkaProducer) Flush(timeout int) int { - m.Called(timeout) + m.Called(timeout) return 0 } @@ -91,7 +91,6 @@ func TestSendPdpStatus_Success(t *testing.T) { mockProducer.On("Produce", mock.Anything).Return(nil) //t.Fatalf("Inside Sender checking for producer , but got: %v", mockProducer) - // Create the RealPdpStatusSender with the mocked producer sender := RealPdpStatusSender{ Producer: mockProducer, diff --git a/pkg/kafkacomm/publisher/pdp-status-publisher_test.go b/pkg/kafkacomm/publisher/pdp-status-publisher_test.go index 2e2be1c..17b07f6 100644 --- a/pkg/kafkacomm/publisher/pdp-status-publisher_test.go +++ b/pkg/kafkacomm/publisher/pdp-status-publisher_test.go @@ -31,16 +31,16 @@ import ( // Mock Policymap type MockPolicymap struct { - mock.Mock + mock.Mock } func (m *MockPolicymap) ExtractDeployedPolicies(policiesMap string) []model.ToscaConceptIdentifier { - args := m.Called(policiesMap) - return args.Get(0).([]model.ToscaConceptIdentifier) + args := m.Called(policiesMap) + return args.Get(0).([]model.ToscaConceptIdentifier) } func (m *MockPolicymap) SetLastDeployedPolicies(policiesMap string) { - m.Called(policiesMap) + m.Called(policiesMap) } // TestSendPdpUpdateResponse_Success tests SendPdpUpdateResponse for a successful response @@ -74,88 +74,88 @@ func TestSendPdpUpdateResponse_Failure(t *testing.T) { func TestSendPdpUpdateResponse_Success_NoPolicies(t *testing.T) { mockPolicymap := new(MockPolicymap) - - mockSender := new(mocks.PdpStatusSender) - mockSender.On("SendPdpStatus", mock.Anything).Return(nil) - pdpUpdate := &model.PdpUpdate{RequestId: "test-request-id"} + mockSender := new(mocks.PdpStatusSender) + mockSender.On("SendPdpStatus", mock.Anything).Return(nil) + pdpUpdate := &model.PdpUpdate{RequestId: "test-request-id"} policymap.LastDeployedPolicies = "" - mockPolicymap.On("ExtractDeployedPolicies", mock.Anything).Return(nil) + mockPolicymap.On("ExtractDeployedPolicies", mock.Anything).Return(nil) - err := SendPdpUpdateResponse(mockSender, pdpUpdate, "PDPUpdate Successful") - assert.NoError(t, err) - mockSender.AssertCalled(t, "SendPdpStatus", mock.Anything) + err := SendPdpUpdateResponse(mockSender, pdpUpdate, "PDPUpdate Successful") + assert.NoError(t, err) + mockSender.AssertCalled(t, "SendPdpStatus", mock.Anything) } // TestSendPdpUpdateResponse_Success tests SendPdpUpdateResponse for a successful response with some policies func TestSendPdpUpdateResponse_Success_SomeDeployedPolicies(t *testing.T) { mockPolicymap := new(MockPolicymap) - mockSender := new(mocks.PdpStatusSender) - mockSender.On("SendPdpStatus", mock.Anything).Return(nil) - pdpUpdate := &model.PdpUpdate{RequestId: "test-request-id"} - policymap.LastDeployedPolicies = "some-policies" - mockPolicymap.On("ExtractDeployedPolicies", mock.Anything).Return(nil) - err := SendPdpUpdateResponse(mockSender, pdpUpdate, "PDPUpdate Successful") - assert.NoError(t, err) - mockSender.AssertCalled(t, "SendPdpStatus", mock.Anything) + mockSender := new(mocks.PdpStatusSender) + mockSender.On("SendPdpStatus", mock.Anything).Return(nil) + pdpUpdate := &model.PdpUpdate{RequestId: "test-request-id"} + policymap.LastDeployedPolicies = "some-policies" + mockPolicymap.On("ExtractDeployedPolicies", mock.Anything).Return(nil) + err := SendPdpUpdateResponse(mockSender, pdpUpdate, "PDPUpdate Successful") + assert.NoError(t, err) + mockSender.AssertCalled(t, "SendPdpStatus", mock.Anything) } // TestSendPdpUpdateErrorResponse_Success tests SendPdpUpdateResponse func TestSendPdpUpdateErrorResponse(t *testing.T) { - mockSender := new(mocks.PdpStatusSender) - mockSender.On("SendPdpStatus", mock.Anything).Return(errors.New("Sending error response")) + mockSender := new(mocks.PdpStatusSender) + mockSender.On("SendPdpStatus", mock.Anything).Return(errors.New("Sending error response")) - pdpUpdate := &model.PdpUpdate{RequestId: "test-request-id"} + pdpUpdate := &model.PdpUpdate{RequestId: "test-request-id"} - mockerr := errors.New("Sending Error response") - err := SendPdpUpdateErrorResponse(mockSender, pdpUpdate, mockerr) + mockerr := errors.New("Sending Error response") + err := SendPdpUpdateErrorResponse(mockSender, pdpUpdate, mockerr) - assert.Error(t, err) + assert.Error(t, err) - mockSender.AssertCalled(t, "SendPdpStatus", mock.Anything) + mockSender.AssertCalled(t, "SendPdpStatus", mock.Anything) } // TestSendPdpUpdateErrorResponse_Success tests SendPdpUpdateResponse for some policies func TestSendPdpUpdateErrorResponse_SomeDeployedPolicies(t *testing.T) { - // Setup mock Policymap - mockPolicymap := new(MockPolicymap) - - mockSender := new(mocks.PdpStatusSender) - mockSender.On("SendPdpStatus", mock.Anything).Return(errors.New("Sending error response")) - pdpUpdate := &model.PdpUpdate{RequestId: "test-request-id"} - - policymap.LastDeployedPolicies = "some-policies" - // Set mock behavior for policymap - mockPolicymap.On("ExtractDeployedPolicies", mock.Anything).Return(nil) - mockerr := errors.New("Sending Error response") - err := SendPdpUpdateErrorResponse(mockSender, pdpUpdate, mockerr) - assert.Error(t, err) - //mockPolicymap.AssertExpectations(t) - mockSender.AssertCalled(t, "SendPdpStatus", mock.Anything) + // Setup mock Policymap + mockPolicymap := new(MockPolicymap) + + mockSender := new(mocks.PdpStatusSender) + mockSender.On("SendPdpStatus", mock.Anything).Return(errors.New("Sending error response")) + pdpUpdate := &model.PdpUpdate{RequestId: "test-request-id"} + + policymap.LastDeployedPolicies = "some-policies" + // Set mock behavior for policymap + mockPolicymap.On("ExtractDeployedPolicies", mock.Anything).Return(nil) + mockerr := errors.New("Sending Error response") + err := SendPdpUpdateErrorResponse(mockSender, pdpUpdate, mockerr) + assert.Error(t, err) + //mockPolicymap.AssertExpectations(t) + mockSender.AssertCalled(t, "SendPdpStatus", mock.Anything) } // TestSendPdpUpdateErrorResponse_Success tests SendPdpUpdateResponse for no policies func TestSendPdpUpdateErrorResponse_NoPolicies(t *testing.T) { - // Setup mock Policymap - mockPolicymap := new(MockPolicymap) - - mockSender := new(mocks.PdpStatusSender) - mockSender.On("SendPdpStatus", mock.Anything).Return(errors.New("Sending error response")) - pdpUpdate := &model.PdpUpdate{RequestId: "test-request-id"} - - policymap.LastDeployedPolicies = "" - // Set mock behavior for policymap - mockPolicymap.On("ExtractDeployedPolicies", mock.Anything).Return(nil) - mockerr := errors.New("Sending Error response") - err := SendPdpUpdateErrorResponse(mockSender, pdpUpdate, mockerr) - assert.Error(t, err) - //mockPolicymap.AssertExpectations(t) - mockSender.AssertCalled(t, "SendPdpStatus", mock.Anything) + // Setup mock Policymap + mockPolicymap := new(MockPolicymap) + + mockSender := new(mocks.PdpStatusSender) + mockSender.On("SendPdpStatus", mock.Anything).Return(errors.New("Sending error response")) + pdpUpdate := &model.PdpUpdate{RequestId: "test-request-id"} + + policymap.LastDeployedPolicies = "" + // Set mock behavior for policymap + mockPolicymap.On("ExtractDeployedPolicies", mock.Anything).Return(nil) + mockerr := errors.New("Sending Error response") + err := SendPdpUpdateErrorResponse(mockSender, pdpUpdate, mockerr) + assert.Error(t, err) + //mockPolicymap.AssertExpectations(t) + mockSender.AssertCalled(t, "SendPdpStatus", mock.Anything) } + // TestSendStateChangeResponse_Success tests SendStateChangeResponse for a successful state change response func TestSendStateChangeResponse_Success(t *testing.T) { - mockSender := new(mocks.PdpStatusSender) + mockSender := new(mocks.PdpStatusSender) mockSender.On("SendPdpStatus", mock.Anything).Return(nil) pdpStateChange := &model.PdpStateChange{RequestId: "test-state-change-id"} diff --git a/pkg/metrics/counters.go b/pkg/metrics/counters.go index 7734cff..09ff4f7 100644 --- a/pkg/metrics/counters.go +++ b/pkg/metrics/counters.go @@ -78,40 +78,39 @@ func TotalDecisionFailureCountRef() *int64 { // Increment counter func IncrementDeploySuccessCount() { - mu.Lock() - DeploySuccessCount++ - mu.Unlock() + mu.Lock() + DeploySuccessCount++ + mu.Unlock() } // returns pointer to the counter func totalDeploySuccessCountRef() *int64 { - mu.Lock() - defer mu.Unlock() - return &DeploySuccessCount + mu.Lock() + defer mu.Unlock() + return &DeploySuccessCount } // Increment counter func IncrementDeployFailureCount() { - mu.Lock() - DeployFailureCount++ - mu.Unlock() + mu.Lock() + DeployFailureCount++ + mu.Unlock() } // returns pointer to the counter func totalDeployFailureCountRef() *int64 { - mu.Lock() - defer mu.Unlock() - return &DeployFailureCount + mu.Lock() + defer mu.Unlock() + return &DeployFailureCount } - // Increment counter func IncrementUndeploySuccessCount() { - mu.Lock() + mu.Lock() UndeploySuccessCount++ mu.Unlock() } @@ -119,40 +118,39 @@ func IncrementUndeploySuccessCount() { // returns pointer to the counter func totalUndeploySuccessCountRef() *int64 { - mu.Lock() - defer mu.Unlock() - return &UndeploySuccessCount + mu.Lock() + defer mu.Unlock() + return &UndeploySuccessCount } // Increment counter func IncrementUndeployFailureCount() { - mu.Lock() - UndeployFailureCount++ - mu.Unlock() + mu.Lock() + UndeployFailureCount++ + mu.Unlock() } // returns pointer to the counter func totalUndeployFailureCountRef() *int64 { - mu.Lock() - defer mu.Unlock() - return &UndeployFailureCount + mu.Lock() + defer mu.Unlock() + return &UndeployFailureCount } // Increment counter func SetTotalPoliciesCount(newCount int64) { - mu.Lock() - TotalPoliciesCount = newCount - mu.Unlock() + mu.Lock() + TotalPoliciesCount = newCount + mu.Unlock() } // returns pointer to the counter func totalPoliciesCountRef() *int64 { - mu.Lock() - defer mu.Unlock() - return &TotalPoliciesCount + mu.Lock() + defer mu.Unlock() + return &TotalPoliciesCount } - diff --git a/pkg/metrics/counters_test.go b/pkg/metrics/counters_test.go index 9d41e95..0523d60 100644 --- a/pkg/metrics/counters_test.go +++ b/pkg/metrics/counters_test.go @@ -85,8 +85,7 @@ func TestCounters(t *testing.T) { assert.Equal(t, int64(3), *TotalDecisionFailureCountRef()) - -// Test IncrementDeploySuccessCount and totalDeploySuccessCountRef + // Test IncrementDeploySuccessCount and totalDeploySuccessCountRef DeploySuccessCount = 0 wg.Add(4) for i := 0; i < 4; i++ { @@ -98,7 +97,7 @@ func TestCounters(t *testing.T) { wg.Wait() assert.Equal(t, int64(4), *totalDeploySuccessCountRef()) -// Test IncrementDeployFailureCount and totalDeployFailureCountRef + // Test IncrementDeployFailureCount and totalDeployFailureCountRef DeployFailureCount = 0 wg.Add(2) for i := 0; i < 2; i++ { @@ -110,7 +109,7 @@ func TestCounters(t *testing.T) { wg.Wait() assert.Equal(t, int64(2), *totalDeployFailureCountRef()) -// Test IncrementUndeploySuccessCount and totalUndeploySuccessCountRef + // Test IncrementUndeploySuccessCount and totalUndeploySuccessCountRef UndeploySuccessCount = 0 wg.Add(6) for i := 0; i < 6; i++ { @@ -122,7 +121,7 @@ func TestCounters(t *testing.T) { wg.Wait() assert.Equal(t, int64(6), *totalUndeploySuccessCountRef()) -// Test IncrementUndeployFailureCount and totalUndeployFailureCountRef + // Test IncrementUndeployFailureCount and totalUndeployFailureCountRef UndeployFailureCount = 0 wg.Add(1) for i := 0; i < 1; i++ { @@ -134,9 +133,8 @@ func TestCounters(t *testing.T) { wg.Wait() assert.Equal(t, int64(1), *totalUndeployFailureCountRef()) -// Test SetTotalPoliciesCount and totalPoliciesCountRef + // Test SetTotalPoliciesCount and totalPoliciesCountRef SetTotalPoliciesCount(15) assert.Equal(t, int64(15), *totalPoliciesCountRef()) - } diff --git a/pkg/metrics/statistics-provider.go b/pkg/metrics/statistics-provider.go index 0f826bc..381ba5c 100644 --- a/pkg/metrics/statistics-provider.go +++ b/pkg/metrics/statistics-provider.go @@ -57,15 +57,14 @@ func FetchCurrentStatistics(res http.ResponseWriter, req *http.Request) { var statReport oapicodegen.StatisticsReport - statReport.DecisionSuccessCount = totalDecisionSuccessCountRef() statReport.DecisionFailureCount = TotalDecisionFailureCountRef() - statReport.TotalErrorCount = totalErrorCountRef() - statReport.DeployFailureCount = totalDeployFailureCountRef() - statReport.DeploySuccessCount = totalDeploySuccessCountRef() - statReport.UndeployFailureCount = totalUndeployFailureCountRef() - statReport.UndeploySuccessCount = totalUndeploySuccessCountRef() - statReport.TotalPoliciesCount = totalPoliciesCountRef() + statReport.TotalErrorCount = totalErrorCountRef() + statReport.DeployFailureCount = totalDeployFailureCountRef() + statReport.DeploySuccessCount = totalDeploySuccessCountRef() + statReport.UndeployFailureCount = totalUndeployFailureCountRef() + statReport.UndeploySuccessCount = totalUndeploySuccessCountRef() + statReport.TotalPoliciesCount = totalPoliciesCountRef() // not implemented hardcoding the values to zero // will be implemeneted in phase-2 diff --git a/pkg/metrics/statistics-provider_test.go b/pkg/metrics/statistics-provider_test.go index 94684c5..400430e 100644 --- a/pkg/metrics/statistics-provider_test.go +++ b/pkg/metrics/statistics-provider_test.go @@ -30,7 +30,7 @@ import ( ) func TestFetchCurrentStatistics(t *testing.T) { - TotalErrorCount = 0 + TotalErrorCount = 0 DecisionSuccessCount = 0 DecisionFailureCount = 0 DeployFailureCount = 0 @@ -72,7 +72,7 @@ func TestFetchCurrentStatistics(t *testing.T) { } func TestFetchCurrentStatistics_ValidRequestID(t *testing.T) { - TotalErrorCount = 0 + TotalErrorCount = 0 DecisionSuccessCount = 0 DecisionFailureCount = 0 DeployFailureCount = 0 diff --git a/pkg/model/messages_test.go b/pkg/model/messages_test.go index 536f683..20c09d3 100644 --- a/pkg/model/messages_test.go +++ b/pkg/model/messages_test.go @@ -183,7 +183,7 @@ func TestPdpUpdateSerialization_Success(t *testing.T) { Source: "source1", PdpHeartbeatIntervalMs: 5000, MessageType: "PDP_UPDATE", - PoliciesToBeDeployed: policies, + PoliciesToBeDeployed: policies, Name: "ExamplePDP", TimestampMs: 1633017600000, PdpGroup: "Group1", @@ -203,7 +203,7 @@ func TestPdpUpdateSerialization_Failure(t *testing.T) { Source: "", PdpHeartbeatIntervalMs: 5000, MessageType: "", - PoliciesToBeDeployed: nil, + PoliciesToBeDeployed: nil, Name: "", TimestampMs: 0, PdpGroup: "", diff --git a/pkg/model/oapicodegen/models.go b/pkg/model/oapicodegen/models.go index dc51713..34d88cd 100644 --- a/pkg/model/oapicodegen/models.go +++ b/pkg/model/oapicodegen/models.go @@ -84,15 +84,15 @@ type OPADataUpdateRequest struct { // OPADecisionRequest defines model for OPADecisionRequest. type OPADecisionRequest struct { - CurrentDate *openapi_types.Date `json:"currentDate,omitempty"` - CurrentDateTime *time.Time `json:"currentDateTime,omitempty"` - CurrentTime *string `json:"currentTime,omitempty"` - Input map[string]interface{} `json:"input"` - OnapComponent *string `json:"onapComponent,omitempty"` - OnapInstance *string `json:"onapInstance,omitempty"` - OnapName *string `json:"onapName,omitempty"` - PolicyFilter []string `json:"policyFilter"` - PolicyName string `json:"policyName"` + CurrentDate *openapi_types.Date `json:"currentDate,omitempty"` + CurrentDateTime *time.Time `json:"currentDateTime,omitempty"` + CurrentTime *string `json:"currentTime,omitempty"` + Input OPADecisionRequest_Input `json:"input"` + OnapComponent *string `json:"onapComponent,omitempty"` + OnapInstance *string `json:"onapInstance,omitempty"` + OnapName *string `json:"onapName,omitempty"` + PolicyFilter []string `json:"policyFilter"` + PolicyName string `json:"policyName"` // TimeOffset Time offset in hours and minutes, e.g., '+02:00' or '-05:00' TimeOffset *string `json:"timeOffset,omitempty"` @@ -101,6 +101,17 @@ type OPADecisionRequest struct { TimeZone *string `json:"timeZone,omitempty"` } +// OPADecisionRequestInput0 defines model for . +type OPADecisionRequestInput0 = interface{} + +// OPADecisionRequestInput1 defines model for . +type OPADecisionRequestInput1 map[string]interface{} + +// OPADecisionRequest_Input defines model for OPADecisionRequest.Input. +type OPADecisionRequest_Input struct { + union json.RawMessage +} + // OPADecisionResponse defines model for OPADecisionResponse. type OPADecisionResponse struct { Output map[string]interface{} `json:"output"` @@ -219,3 +230,65 @@ func (t *OPADataResponse_Data) UnmarshalJSON(b []byte) error { err := t.union.UnmarshalJSON(b) return err } + +// AsOPADecisionRequestInput0 returns the union data inside the OPADecisionRequest_Input as a OPADecisionRequestInput0 +func (t OPADecisionRequest_Input) AsOPADecisionRequestInput0() (OPADecisionRequestInput0, error) { + var body OPADecisionRequestInput0 + err := json.Unmarshal(t.union, &body) + return body, err +} + +// FromOPADecisionRequestInput0 overwrites any union data inside the OPADecisionRequest_Input as the provided OPADecisionRequestInput0 +func (t *OPADecisionRequest_Input) FromOPADecisionRequestInput0(v OPADecisionRequestInput0) error { + b, err := json.Marshal(v) + t.union = b + return err +} + +// MergeOPADecisionRequestInput0 performs a merge with any union data inside the OPADecisionRequest_Input, using the provided OPADecisionRequestInput0 +func (t *OPADecisionRequest_Input) MergeOPADecisionRequestInput0(v OPADecisionRequestInput0) error { + b, err := json.Marshal(v) + if err != nil { + return err + } + + merged, err := runtime.JsonMerge(t.union, b) + t.union = merged + return err +} + +// AsOPADecisionRequestInput1 returns the union data inside the OPADecisionRequest_Input as a OPADecisionRequestInput1 +func (t OPADecisionRequest_Input) AsOPADecisionRequestInput1() (OPADecisionRequestInput1, error) { + var body OPADecisionRequestInput1 + err := json.Unmarshal(t.union, &body) + return body, err +} + +// FromOPADecisionRequestInput1 overwrites any union data inside the OPADecisionRequest_Input as the provided OPADecisionRequestInput1 +func (t *OPADecisionRequest_Input) FromOPADecisionRequestInput1(v OPADecisionRequestInput1) error { + b, err := json.Marshal(v) + t.union = b + return err +} + +// MergeOPADecisionRequestInput1 performs a merge with any union data inside the OPADecisionRequest_Input, using the provided OPADecisionRequestInput1 +func (t *OPADecisionRequest_Input) MergeOPADecisionRequestInput1(v OPADecisionRequestInput1) error { + b, err := json.Marshal(v) + if err != nil { + return err + } + + merged, err := runtime.JsonMerge(t.union, b) + t.union = merged + return err +} + +func (t OPADecisionRequest_Input) MarshalJSON() ([]byte, error) { + b, err := t.union.MarshalJSON() + return b, err +} + +func (t *OPADecisionRequest_Input) UnmarshalJSON(b []byte) error { + err := t.union.UnmarshalJSON(b) + return err +} diff --git a/pkg/opasdk/opasdk.go b/pkg/opasdk/opasdk.go index 50edba4..8fd1708 100644 --- a/pkg/opasdk/opasdk.go +++ b/pkg/opasdk/opasdk.go @@ -44,16 +44,16 @@ import ( // Define the structs var ( - opaInstance *sdk.OPA //A singleton instance of the OPA object - once sync.Once //A sync.Once variable used to ensure that the OPA instance is initialized only once, - memStore storage.Store + opaInstance *sdk.OPA //A singleton instance of the OPA object + once sync.Once //A sync.Once variable used to ensure that the OPA instance is initialized only once, + memStore storage.Store UpsertPolicyVar UpsertPolicyFunc = UpsertPolicy - WriteDataVar WriteDataFunc = WriteData + WriteDataVar WriteDataFunc = WriteData ) type ( - UpsertPolicyFunc func(ctx context.Context, policyID string, policyContent []byte) error - WriteDataFunc func(ctx context.Context, dataPath string, data interface{}) error + UpsertPolicyFunc func(ctx context.Context, policyID string, policyContent []byte) error + WriteDataFunc func(ctx context.Context, dataPath string, data interface{}) error ) type PatchImpl struct { @@ -81,6 +81,7 @@ func getJSONReader(filePath string, openFunc func(string) (*os.File, error), } type NewSDKFunc func(ctx context.Context, options sdk.Options) (*sdk.OPA, error) + var NewSDK NewSDKFunc = sdk.New // Returns a singleton instance of the OPA object. The initialization of the instance is @@ -88,9 +89,9 @@ var NewSDK NewSDKFunc = sdk.New func GetOPASingletonInstance() (*sdk.OPA, error) { var err error once.Do(func() { - var opaErr error + var opaErr error memStore = inmem.New() - opaInstance, opaErr = NewSDK(context.Background(), sdk.Options{ + opaInstance, opaErr = NewSDK(context.Background(), sdk.Options{ // Configure your OPA instance here V1Compatible: true, Store: memStore, @@ -113,7 +114,7 @@ func GetOPASingletonInstance() (*sdk.OPA, error) { Config: jsonReader, }) if err != nil { - log.Warnf("Failed to configure OPA: %v", err) + log.Warnf("Failed to configure OPA: %v", err) } } }) diff --git a/pkg/opasdk/opasdk_test.go b/pkg/opasdk/opasdk_test.go index 3ed4be1..48ed65e 100644 --- a/pkg/opasdk/opasdk_test.go +++ b/pkg/opasdk/opasdk_test.go @@ -29,12 +29,12 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" "io" + "net/http" "net/http/httptest" "os" "policy-opa-pdp/consts" "sync" "testing" - "net/http" ) // Mock for os.Open @@ -560,8 +560,8 @@ func TestListPolicies_GetPolicySuccess(t *testing.T) { res := httptest.NewRecorder() ListPolicies(res, req) -// assert.Nil(t, err) -// assert.NoError(t, err) + // assert.Nil(t, err) + // assert.NoError(t, err) mockMemStore.AssertExpectations(t) } @@ -579,7 +579,7 @@ func TestListPolicies_Success(t *testing.T) { res := httptest.NewRecorder() ListPolicies(res, req) -// assert.NoError(t, err) + // assert.NoError(t, err) mockMemStore.AssertExpectations(t) } diff --git a/pkg/pdpattributes/pdpattributes.go b/pkg/pdpattributes/pdpattributes.go index 005dd03..a40a55a 100644 --- a/pkg/pdpattributes/pdpattributes.go +++ b/pkg/pdpattributes/pdpattributes.go @@ -1,6 +1,6 @@ // - // ========================LICENSE_START================================= -// Copyright (C) 2024: Deutsche Telekom +// Copyright (C) 2024-2025: Deutsche Telekom // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -22,8 +22,8 @@ package pdpattributes import ( - "github.com/google/uuid" "policy-opa-pdp/pkg/log" + "github.com/google/uuid" ) var ( @@ -48,7 +48,7 @@ func SetPdpSubgroup(pdpsubgroup string) { } // Retrieves the current PDP subgroup value. -func getPdpSubgroup() string { +func GetPdpSubgroup() string { return PdpSubgroup } diff --git a/pkg/pdpattributes/pdpattributes_test.go b/pkg/pdpattributes/pdpattributes_test.go index c9a41c7..700a264 100644 --- a/pkg/pdpattributes/pdpattributes_test.go +++ b/pkg/pdpattributes/pdpattributes_test.go @@ -1,6 +1,6 @@ // - // ========================LICENSE_START================================= -// Copyright (C) 2024: Deutsche Telekom +// Copyright (C) 2024-2025: Deutsche Telekom // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -46,14 +46,14 @@ func TestSetPdpSubgroup_Success(t *testing.T) { t.Run("ValidSubgroup", func(t *testing.T) { expectedSubgroup := "subgroup1" SetPdpSubgroup(expectedSubgroup) - assert.Equal(t, expectedSubgroup, getPdpSubgroup(), "Expected PDP subgroup to match set value") + assert.Equal(t, expectedSubgroup, GetPdpSubgroup(), "Expected PDP subgroup to match set value") }) } func TestSetPdpSubgroup_Failure(t *testing.T) { t.Run("EmptySubgroup", func(t *testing.T) { SetPdpSubgroup("") - assert.Equal(t, "", getPdpSubgroup(), "Expected PDP subgroup to be empty when set to empty string") + assert.Equal(t, "", GetPdpSubgroup(), "Expected PDP subgroup to be empty when set to empty string") }) t.Run("LargeSubgroup", func(t *testing.T) { @@ -62,7 +62,7 @@ func TestSetPdpSubgroup_Failure(t *testing.T) { largeSubgroup[i] = 'a' } SetPdpSubgroup(string(largeSubgroup)) - assert.Equal(t, string(largeSubgroup), getPdpSubgroup(), "Expected large PDP subgroup to match set value") + assert.Equal(t, string(largeSubgroup), GetPdpSubgroup(), "Expected large PDP subgroup to match set value") }) } diff --git a/pkg/utils/sort.go b/pkg/utils/sort.go new file mode 100644 index 0000000..d59ea2a --- /dev/null +++ b/pkg/utils/sort.go @@ -0,0 +1,41 @@ +// - +// ========================LICENSE_START================================= +// Copyright (C) 2025: Deutsche Telekom +// +// 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. +// SPDX-License-Identifier: Apache-2.0 +// ========================LICENSE_END=================================== + +package utils + +import ( + "strings" +) + +// Custom type for sorting +type ByDotCount struct { + Keys []string + Ascend bool +} + +// Implement sort.Interface for ByDotCount +func (a ByDotCount) Len() int { return len(a.Keys) } + +func (a ByDotCount) Swap(i, j int) { a.Keys[i], a.Keys[j] = a.Keys[j], a.Keys[i] } + +func (a ByDotCount) Less(i, j int) bool { + if a.Ascend { + return strings.Count(a.Keys[i], ".") < strings.Count(a.Keys[j], ".") + } + return strings.Count(a.Keys[i], ".") > strings.Count(a.Keys[j], ".") +} diff --git a/pkg/utils/utils.go b/pkg/utils/utils.go index 23f9cfe..fba1fb1 100644 --- a/pkg/utils/utils.go +++ b/pkg/utils/utils.go @@ -16,7 +16,7 @@ // SPDX-License-Identifier: Apache-2.0 // ========================LICENSE_END=================================== -// Package utils provides common functionalities +// Package provides common functionalities package utils @@ -30,6 +30,7 @@ import ( "policy-opa-pdp/consts" "policy-opa-pdp/pkg/log" "policy-opa-pdp/pkg/model" + "policy-opa-pdp/pkg/model/oapicodegen" "regexp" "strings" "time" @@ -41,6 +42,7 @@ type ( var ( CreateDirectoryVar CreateDirectoryFunc = CreateDirectory + removeAll = os.RemoveAll ) // validates if the given request is in valid uuid form @@ -63,42 +65,60 @@ func CreateDirectory(dirPath string) error { // Helper function to check and remove a directory func RemoveDirectory(dirPath string) error { - entries, err := os.ReadDir(dirPath) + fileDirPath := filepath.Clean(dirPath) + err := removeAll(fileDirPath) if err != nil { if os.IsNotExist(err) { - log.Warnf("Directory does not exist: %s", dirPath) + log.Warnf("Directory does not exist: %s", fileDirPath) // Directory does not exist, nothing to do return nil } - return fmt.Errorf("failed to read directory: %w", err) + return fmt.Errorf("failed to remove file: %s, error: %w", fileDirPath, err) + } - for _, entry := range entries { - entryPath := filepath.Join(dirPath, entry.Name()) + // Create a loop to check parent directories. + // Move to the parent directory + currentPath := filepath.Clean(filepath.Dir(dirPath)) + for { + // Check if we have reached the match path + if currentPath == filepath.Clean(consts.DataNode) || currentPath == filepath.Clean(consts.Policies) { + return nil // Stop if we reach the match path + } - if entry.IsDir() { - // Check if the subdirectory is empty and delete it - isEmpty, err := isDirEmpty(entryPath) - if err != nil { - return err - } - if isEmpty { - log.Debugf("Removing empty subdirectory: %s", entryPath) - if err := os.RemoveAll(entryPath); err != nil { - return fmt.Errorf("failed to remove directory: %s, error: %w", entryPath, err) - } - } - } else { - // Delete specific files in the parent directory - if entry.Name() == "data.json" || entry.Name() == "policy.rego" { - log.Debugf("Removing file: %s", entryPath) - if err := os.Remove(entryPath); err != nil { - return fmt.Errorf("failed to remove file: %s, error: %w", entryPath, err) - } - } + if currentPath == "/" || currentPath == "." { + log.Infof("Reached root orelative path: %s", currentPath) + return nil // Stop if we reach the match path + } + log.Infof("Processig Parent dir : %s", currentPath) + // Check if the parent directory exists before proceeding + if _, err := os.Stat(currentPath); os.IsNotExist(err) { + log.Debugf("directory does not exist: %s. Stopping iteration.", currentPath) + return nil // Stop if we can't find the parent path + } + // Clean the parent directory + err = isSubDirEmpty(currentPath) + if err != nil { + return err } + + // Move to the parent directory + currentPath = filepath.Dir(currentPath) } +} +func isSubDirEmpty(entryPath string) error { + + isEmpty, err := isDirEmpty(entryPath) + if err != nil { + return err + } + if isEmpty { + log.Debugf("Removing empty subdirectory: %s", entryPath) + if err := removeAll(entryPath); err != nil { + return fmt.Errorf("failed to remove directory: %s, error: %w", entryPath, err) + } + } return nil } @@ -144,7 +164,7 @@ func ValidateToscaPolicyJsonFields(policy model.ToscaPolicy) error { return fmt.Errorf("duplicate data key '%s' found, '%s'", key, emphasize) } keySeen[key] = true - if !strings.HasPrefix(key, "node." + policy.Name) { + if !strings.HasPrefix(key, "node."+policy.Name) { return fmt.Errorf("data key '%s' does not have name node.'%s' as a prefix, '%s'", key, policy.Name, emphasize) } } @@ -289,24 +309,27 @@ func IsValidCurrentTime(currentTime *string) bool { } // Custom validation function for *string type eg: OnapComponent, OnapInstance, OnapName, PolicyName -func IsValidString(name *string) bool { - if name == nil || strings.TrimSpace(*name) == "" { - return false - } else { - return true +func IsValidString(name interface{}) bool { + switch v := name.(type) { + case *string: + return v != nil && strings.TrimSpace(*v) != "" + case string: + return strings.TrimSpace(v) != "" + default: + return false // Handles cases where name is neither a string nor a *string } } func BuildBundle(cmdFunc func(string, ...string) *exec.Cmd) (string, error) { - cmd := cmdFunc( - consts.Opa, - consts.BuildBundle, - consts.V1_COMPATIBLE, - consts.Policies, - consts.Data, - consts.Output, - consts.BundleTarGzFile, - ) + cmd := cmdFunc( + consts.Opa, + consts.BuildBundle, + consts.V1Compatible, + consts.Policies, + consts.Data, + consts.Output, + consts.BundleTarGzFile, + ) log.Debugf("Before calling combinedoutput") output, err := cmd.CombinedOutput() @@ -318,3 +341,113 @@ func BuildBundle(cmdFunc func(string, ...string) *exec.Cmd) (string, error) { log.Debug("Bundle Built Sucessfully....") return string(output), nil } + +// Validation function +func ValidateOPADataRequest(request interface{}) []string { + var validationErrors []string + if updateRequest, ok := request.(*oapicodegen.OPADataUpdateRequest); ok { + if updateRequest == nil { // Check if updateRequest is nil + validationErrors = append(validationErrors, "OPADataUpdateRequest is nil") + return validationErrors // Return if the request is nil + } + // Check if required fields are populated + if updateRequest.CurrentDate != nil { + dateString := updateRequest.CurrentDate.String() + if !IsValidCurrentDate(&dateString) { + validationErrors = append(validationErrors, "CurrentDate is invalid") + } + } else { + validationErrors = append(validationErrors, "CurrentDate is required") + } + + // Validate CurrentDateTime format + if !(IsValidTime(updateRequest.CurrentDateTime)) { + validationErrors = append(validationErrors, "CurrentDateTime is invalid or missing") + } + + // Validate CurrentTime format + if !(IsValidCurrentTime(updateRequest.CurrentTime)) { + validationErrors = append(validationErrors, "CurrentTime is invalid or missing") + } + + // Validate TimeOffset format (e.g., +02:00 or -05:00) + if !(IsValidTimeOffset(updateRequest.TimeOffset)) { + validationErrors = append(validationErrors, "TimeOffset is invalid or missing") + } + + // Validate TimeZone format (e.g., 'America/New_York') + if !(IsValidTimeZone(updateRequest.TimeZone)) { + validationErrors = append(validationErrors, "TimeZone is invalid or missing") + } + + // Optionally, check if 'OnapComponent', 'OnapInstance', 'OnapName', and 'PolicyName' are provided + if !(IsValidString(updateRequest.OnapComponent)) { + validationErrors = append(validationErrors, "OnapComponent is required") + } + + if !(IsValidString(updateRequest.OnapInstance)) { + validationErrors = append(validationErrors, "OnapInstance is required") + } + + if !(IsValidString(updateRequest.OnapName)) { + validationErrors = append(validationErrors, "OnapName is required") + } + + if !(IsValidString(updateRequest.PolicyName)) { + validationErrors = append(validationErrors, "PolicyName is required and cannot be empty") + } + } + + if decisionRequest, ok := request.(*oapicodegen.OPADecisionRequest); ok { + + if decisionRequest == nil { // Check if decisionRequest is nil + validationErrors = append(validationErrors, "OPADecisionRequest is nil") + return validationErrors // Return if the request is nil + } + // Check if required fields are populated + if decisionRequest.CurrentDate != nil { + dateString := decisionRequest.CurrentDate.String() + if !IsValidCurrentDate(&dateString) { + validationErrors = append(validationErrors, "CurrentDate is invalid") + } + } + + // Validate CurrentDateTime format + if (decisionRequest.CurrentDateTime != nil) && !(IsValidTime(decisionRequest.CurrentDateTime)) { + validationErrors = append(validationErrors, "CurrentDateTime is invalid or missing") + } + + // Validate CurrentTime format + if (decisionRequest.CurrentTime != nil) && !(IsValidCurrentTime(decisionRequest.CurrentTime)) { + validationErrors = append(validationErrors, "CurrentTime is invalid or missing") + } + + // Validate TimeOffset format (e.g., +02:00 or -05:00) + if (decisionRequest.TimeOffset != nil) && !(IsValidTimeOffset(decisionRequest.TimeOffset)) { + validationErrors = append(validationErrors, "TimeOffset is invalid or missing") + } + + // Validate TimeZone format (e.g., 'America/New_York') + if (decisionRequest.TimeZone != nil) && !(IsValidTimeZone(decisionRequest.TimeZone)) { + validationErrors = append(validationErrors, "TimeZone is invalid or missing") + } + + // Optionally, check if 'OnapComponent', 'OnapInstance', 'OnapName', and 'PolicyName' are provided + if (decisionRequest.OnapComponent != nil) && !(IsValidString(decisionRequest.OnapComponent)) { + validationErrors = append(validationErrors, "OnapComponent is required") + } + + if (decisionRequest.OnapInstance != nil) && !(IsValidString(decisionRequest.OnapInstance)) { + validationErrors = append(validationErrors, "OnapInstance is required") + } + + if (decisionRequest.OnapName != nil) && !(IsValidString(decisionRequest.OnapName)) { + validationErrors = append(validationErrors, "OnapName is required") + } + + if !(IsValidString(decisionRequest.PolicyName)) { + validationErrors = append(validationErrors, "PolicyName is required and cannot be empty") + } + } + return validationErrors +} diff --git a/pkg/utils/utils_test.go b/pkg/utils/utils_test.go index 3a4948d..a76a435 100644 --- a/pkg/utils/utils_test.go +++ b/pkg/utils/utils_test.go @@ -19,12 +19,16 @@ package utils import ( + "fmt" "github.com/google/uuid" + openapi_types "github.com/oapi-codegen/runtime/types" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "os" "os/exec" "path/filepath" "policy-opa-pdp/pkg/model" + "policy-opa-pdp/pkg/model/oapicodegen" "testing" "time" ) @@ -117,16 +121,12 @@ func TestRemoveDirectory_Positive(t *testing.T) { _, err = os.Stat(filePath) assert.True(t, os.IsNotExist(err), "Fle should be removed") - _, err = os.Stat(tempDir) - assert.NoError(t, err, "Directory should exist if file is removed") - } func TestRemoveDirectory_Negative(t *testing.T) { nonExistentDirectory := filepath.Join(os.TempDir(), "non_existent_directory") _, err := os.Stat(nonExistentDirectory) - assert.True(t, os.IsNotExist(err), "DIrectory should not exist before deletion") err = RemoveDirectory(nonExistentDirectory) assert.NoError(t, err) } @@ -145,8 +145,6 @@ func TestRemoveDirectory_ValidEmptyDir(t *testing.T) { _, err = os.Stat(subDir) assert.True(t, os.IsNotExist(err), "Expected directory to be deleted") - _, err = os.Stat(tempDir) - assert.NoError(t, err, "Directory should exist if file is removed") } // Test removing a directory that does not exist @@ -155,17 +153,6 @@ func TestRemoveDirectory_NonExistent(t *testing.T) { assert.NoError(t, err, "Expected no error when removing a non-existent directory") } -// Test failure scenario where ReadDir fails -func TestRemoveDirectory_ReadDirFailure(t *testing.T) { - // Create a file instead of a directory - tempFile, err := os.CreateTemp("", "testfile") - assert.NoError(t, err) - defer os.Remove(tempFile.Name()) - - err = RemoveDirectory(tempFile.Name()) // Should fail because it's a file, not a directory - assert.Error(t, err, "Expected an error when trying to remove a file as a directory") -} - // Test removing a directory containing only data.json and policy.rego func TestRemoveDirectory_WithSpecificFiles(t *testing.T) { tempDir, err := os.MkdirTemp("", "testdir") @@ -626,3 +613,131 @@ func TestBuildBundle_CommandFailure(t *testing.T) { t.Errorf("BuildBundle() error = nil, wantErr %v", output) } } + +// Test function for isSubDirEmpty using real directories +func TestIsSubDirEmpty(t *testing.T) { + // Create a temporary directory for testing + t.Run("Empty Directory - Should be removed", func(t *testing.T) { + tempDir, err := os.MkdirTemp("", "emptyDir") + require.NoError(t, err) + + // Call the function + err = isSubDirEmpty(tempDir) + + // Assert no error and directory should be removed + assert.NoError(t, err) + _, err = os.Stat(tempDir) + assert.True(t, os.IsNotExist(err)) // Directory should be gone + }) + + t.Run("Non-Empty Directory - Should not be removed", func(t *testing.T) { + tempDir, err := os.MkdirTemp("", "nonEmptyDir") + require.NoError(t, err) + + // Create a file inside to make the directory non-empty + _, err = os.CreateTemp(tempDir, "file") + require.NoError(t, err) + + // Call the function + err = isSubDirEmpty(tempDir) + + // Assert directory still exists + assert.NoError(t, err) + _, err = os.Stat(tempDir) + assert.NoError(t, err) // Directory should still exist + + // Clean up + os.RemoveAll(tempDir) + }) + + t.Run("Non-Existent Directory - Should return an error", func(t *testing.T) { + tempDir := "/path/that/does/not/exist" + + err := isSubDirEmpty(tempDir) + + // Assert error + assert.Error(t, err) + // assert.True(t, os.IsNotExist(err)) + }) + + t.Run("Error Removing Directory - Should return an error", func(t *testing.T) { + // Create a temporary directory + tempDir, err := os.MkdirTemp("", "errorDir") + require.NoError(t, err) + + // Mock removeAll to return an error + originalRemoveAll := removeAll + defer func() { removeAll = originalRemoveAll }() // Restore after test + + removeAll = func(path string) error { + return fmt.Errorf("failed to remove directory: %s", path) + } + + err = isSubDirEmpty(tempDir) + + // Assert error + assert.Error(t, err) + assert.Contains(t, err.Error(), "failed to remove directory") + + // Clean up + os.RemoveAll(tempDir) + }) +} + +func TestValidateOPADataRequest(t *testing.T) { + ctime := "08:26:41.857Z" + onapComp := "COMPONENT" + onapIns := "INSTANCE" + onapName := "ONAP" + policyName := "s3" + parsedDate, err := time.Parse("2006-01-02", "2024-02-12") + if err != nil { + fmt.Println("error in parsedDate") + } + currentDate := openapi_types.Date{Time: parsedDate} + currentDateTime, err := time.Parse(time.RFC3339, "2024-02-12T12:00:00Z") + if err != nil { + fmt.Println("error in currentDateTime") + } + + inValidDecisionRequest := &oapicodegen.OPADecisionRequest{ + CurrentDate: ¤tDate, + CurrentDateTime: ¤tDateTime, + } + + var data []map[string]interface{} + + data = nil + + inValidRequest := &oapicodegen.OPADataUpdateRequest{ + CurrentDate: ¤tDate, + CurrentDateTime: ¤tDateTime, + CurrentTime: &ctime, + OnapComponent: &onapComp, + OnapInstance: &onapIns, + OnapName: &onapName, + PolicyName: &policyName, + Data: &data, + } + + inValidErr := []string{"TimeOffset is invalid or missing", "TimeZone is invalid or missing"} + + inValidDecisionErrs := []string{"PolicyName is required and cannot be empty"} + tests := []struct { + name string + request interface{} + expectedErr []string + }{ + {"Valid Request", inValidRequest, inValidErr}, + {"Invalid OPADecisionRequest", inValidDecisionRequest, inValidDecisionErrs}, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + errors := ValidateOPADataRequest(tt.request) + fmt.Printf("error : %s", errors) + fmt.Printf("error len : %d", len(errors)) + assert.Equal(t, tt.expectedErr, errors) + }) + } +} diff --git a/releases/1.0.2-container.yaml b/releases/1.0.2-container.yaml new file mode 100644 index 0000000..8f301ce --- /dev/null +++ b/releases/1.0.2-container.yaml @@ -0,0 +1,8 @@ +distribution_type: 'container' +container_release_tag: '1.0.2' +project: 'policy-opa-pdp' +log_dir: 'policy-opa-pdp-master-merge-golang/19' +ref: 683c9c9670a46b0a29ea1db443b4ef17f3b531f4 +containers: + - name: 'policy-opa-pdp' + version: 'latest' diff --git a/releases/1.0.3-container.yaml b/releases/1.0.3-container.yaml new file mode 100644 index 0000000..a0ab462 --- /dev/null +++ b/releases/1.0.3-container.yaml @@ -0,0 +1,8 @@ +distribution_type: 'container' +container_release_tag: '1.0.3' +project: 'policy-opa-pdp' +log_dir: 'policy-opa-pdp-master-merge-golang/19' +ref: f4b8774a8a1b7017cd98d8a71167be60c6798f39 +containers: + - name: 'policy-opa-pdp' + version: 'latest' diff --git a/releases/1.0.4-container.yaml b/releases/1.0.4-container.yaml new file mode 100644 index 0000000..679681b --- /dev/null +++ b/releases/1.0.4-container.yaml @@ -0,0 +1,8 @@ +distribution_type: 'container' +container_release_tag: '1.0.4' +project: 'policy-opa-pdp' +log_dir: 'policy-opa-pdp-master-merge-golang/19' +ref: 3773a47d2a2d58a13c9d29ecdf2ddbb4ceead45d +containers: + - name: 'policy-opa-pdp' + version: 'latest' diff --git a/sonar-project.properties b/sonar-project.properties index acc745b..7af36a9 100644 --- a/sonar-project.properties +++ b/sonar-project.properties @@ -2,5 +2,6 @@ # SPDX-FileCopyrightText: 2025 The Linux Foundation sonar.organization=onap sonar.projectKey=policy-opa-pdp -sonar.exclusions=**/_test.go, **/mocks/*, **/models.go -sonar.test.inclusions=**/_test.go +sonar.exclusions=**/*_test.go, **/mocks/*, **/models.go +sonar.test.inclusions=**/*_test.go +sonar.go.coverage.reportPaths=coverage.out diff --git a/test/Opagroup.json b/test/Opagroup.json deleted file mode 100644 index 002b962..0000000 --- a/test/Opagroup.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "groups": [ - { - "name": "defaultGroup", - "pdpGroupState": "ACTIVE", - "properties": {}, - "pdpSubgroups": [ - { - "pdpType": "opa", - "desiredInstanceCount": 1, - "properties": {}, - "supportedPolicyTypes": [ - { - "name": "onap.policies.native.opa", - "version": "1.0.0" - } - ], - "policies": [] - } - ] - } - ] -} diff --git a/test/README.md b/test/README.md index bc9f931..3c52d41 100644 --- a/test/README.md +++ b/test/README.md @@ -1,10 +1,23 @@ # Testing OPA +## Ports Exposed by OPA in CSIT and K8s Cluster Environment: + +<CSIT docker-compose environment:> + 30012 port is exposed,below curl urls for OPA would point to the same. +<K8s environment:> + 8282 port since it is a ClusterIP Service. + port forwarding can be done with below sample commands while testing + -------------------------------------------------------------------- + kubectl port-forward --namespace onap service/policy-pap 30003:6969 & + kubectl port-forward --namespace onap service/policy-api 30002:6969 & + kubectl port-forward --namespace onap service/policy-opa-pdp 30012:8282 & + -------------------------------------------------------------------- + ## Curl URL For Deployment. -1. `curl -u 'policyadmin:zb!XztG34' -X POST -H "Content-Type":"application/yaml" --data-binary @test_resources/policy_deploy_single_policy.yaml http://localhost:30002/policy/api/v1/policytypes/onap.policies.native.opa/versions/1.0.0/policies` +1. `curl -u 'policyadmin:zb!XztG34' -X POST -H "Content-Type":"application/yaml" --data-binary @toscapolicies/role/policy_role.yaml http://localhost:30002/policy/api/v1/policytypes/onap.policies.native.opa/versions/1.0.0/policies` -2. `curl -u 'policyadmin:zb!XztG34' -X POST -H "Content-Type":"application/json" -d @test_resources/deploy.json http://localhost:30003/policy/pap/v1/pdps/policies` +2. `curl -u 'policyadmin:zb!XztG34' -X POST -H "Content-Type":"application/json" -d @toscapolicies/role/deploy_role.json http://localhost:30003/policy/pap/v1/pdps/policies` ## Curl URL For Undeployment @@ -12,118 +25,67 @@ ## Curl URL for Batch Undeployment. -`curl -v -u 'policyadmin:zb!XztG34' -X POST -H "Content-Type":"application/json" -d @test_resources/undeploy_batch_delete.json http://localhost:30003/policy/pap/v1/pdps/deployments/batch` - -## Verification API Calls - -curl -u 'policyadmin:zb!XztG34' -H 'Content-Type: application/json' -H 'Accept: application/json' -d '{"onapName":"CDS","onapComponent":"CDS","onapInstance":"CDS","currentDate": "2024-11-22", "currentTime": "11:34:56", "timeZone": "UTC", "timeOffset": "+05:30", "currentDateTime": "2024-11-22T12:08:00Z", "policyFilter" : [""], "policyName":"example","input":{"method":"POST","path":["users"]}}' -X POST http://0.0.0.0:8282/policy/pdpo/v1/decision - -{"output":{"allow":true},"policyName":"example"} - -curl -u 'policyadmin:zb!XztG34' -H 'Content-Type: application/json' -H 'Accept: application/json' --header 'X-ONAP-RequestID:8e6f784e-c9cb-42f6-bcc9-edb5d0af1ce1' -d '{"onapName":"CDS","onapComponent":"CDS","onapInstance":"CDS","currentDate": "2024-11-22", "currentTime": "11:34:56", "timeZone": "UTC", "timeOffset": "+05:30", "currentDateTime": "2024-11-22T12:08:00Z", "policyName":"role", "policyFilter": ["role_grants"], "input":{"user":"alice","action":"write","object":"id123","type":"dog"}}' -X POST http://0.0.0.0:8282/policy/pdpo/v1/decision - -{"output":{"role_grants":{"billing":[{"action":"read","type":"finance"},{"action":"update","type":"finance"}],"customer":[{"action":"read","type":"dog"},{"action":"read","type":"cat"},{"action":"adopt","type":"dog"},{"action":"adopt","type":"cat"}],"employee":[{"action":"read","type":"dog"},{"action":"read","type":"cat"},{"action":"update","type":"dog"},{"action":"update","type":"cat"}]}},"policyName":"role"} - -## OUTPUT for policy:action with filter role_permissions - -curl -u 'policyadmin:zb!XztG34' -H 'Content-Type: application/json' -H 'Accept: application/json' --header 'X-ONAP-RequestID:8e6f784e-c9cb-42f6-bcc9-edb5d0af1ce1' -d '{"onapName":"CDS","onapComponent":"CDS","onapInstance":"CDS", "currentDate": "2024-11-22", "currentTime": "11:34:56", "timeZone": "UTC", "timeOffset": "+05:30", "currentDateTime": "2024-11-22T12:08:00Z",__"policyFilter": ["role_permissions"]__, "policyName":"action","input":{"user":"alice","action":"delete","type":"server"}}' -X POST http://0.0.0.0:8282/policy/pdpo/v1/decision - -{"output":{"role_permissions":{"admin":{"actions":["read","write","delete"],"resources":["server","database"]},"editor":{"actions":["read","write"],"resources":["server"]},"viewer":{"actions":["read"],"resources":["server"]}}},"policyName":"action"} - -## OUTPUT for policy:action with empty filters - -curl -u 'policyadmin:zb!XztG34' -H 'Content-Type: application/json' -H 'Accept: application/json' --header 'X-ONAP-RequestID:8e6f784e-c9cb-42f6-bcc9-edb5d0af1ce1' -d '{"onapName":"CDS","onapComponent":"CDS","onapInstance":"CDS", "currentDate": "2024-11-22", "currentTime": "11:34:56", "timeZone": "UTC", "timeOffset": "+05:30", "currentDateTime": "2024-11-22T12:08:00Z",__"policyFilter": [""]__, "policyName":"action","input":{"user":"alice","action":"delete","type":"server"}}' -X POST http://0.0.0.0:8282/policy/pdpo/v1/decision - -{"output":{"allow":true,"role_permissions":{"admin":{"actions":["read","write","delete"],"resources":["server","database"]},"editor":{"actions":["read","write"],"resources":["server"]},"viewer":{"actions":["read"],"resources":["server"]}},"user_roles":{"alice":["admin"],"bob":["editor"],"charlie":["viewer"]}},"policyName":"action"} - -## OUTPUT for policy:action without filter - -curl -u 'policyadmin:zb!XztG34' -H 'Content-Type: application/json' -H 'Accept: application/json' --header 'X-ONAP-RequestID:8e6f784e-c9cb-42f6-bcc9-edb5d0af1ce1' -d '{"onapName":"CDS","onapComponent":"CDS","onapInstance":"CDS", "currentDate": "2024-11-22", "currentTime": "11:34:56", "timeZone": "UTC", "timeOffset": "+05:30", "currentDateTime": "2024-11-22T12:08:00Z","policyName":"action","input":{"user":"charlie","action":"delete","type":"server"}}' -X POST http://0.0.0.0:8282/policy/pdpo/v1/decision - -{"errorMessage":"Policy Filter is nil.","policyName":"","responseCode":"bad_request"} - -## OUTPUT for policy:account with filter account_attributes +`curl -v -u 'policyadmin:zb!XztG34' -X POST -H "Content-Type":"application/json" -d @{"groups": [{"name": "opaGroup","deploymentSubgroups": [{"pdpType": "opa","action": "DELETE","policies": [{"name": "role","version": "2.0.2"}]}]}]} http://localhost:30003/policy/pap/v1/pdps/deployments/batch` -curl -u 'policyadmin:zb!XztG34' -H 'Content-Type: application/json' -H 'Accept: application/json' --header 'X-ONAP-RequestID:8e6f784e-c9cb-42f6-bcc9-edb5d0af1ce1' -d '{"onapName":"CDS","onapComponent":"CDS","onapInstance":"CDS", "currentDate": "2024-11-22", "currentTime": "11:34:56", "timeZone": "UTC","timeOffset": "+05:30", "currentDateTime": "2024-11-22T12:08:00Z",__"policyFilter": ["account_attributes"]__, "policyName":"account", "input":{"creditor_account":11111,"creditor":"alice","debtor_account":22222,"debtor":"bob","period":30,"amount":1000}}' -X POST http://0.0.0.0:8282/policy/pdpo/v1/decision +## Decision API Response -{"output":{"account_attributes":{"11111":{"amount":10000,"owner":"alice"},"22222":{"amount":10000,"owner":"bob"},"33333":{"amount":10000,"owner":"cam"}}},"policyName":"account"} +## Output For Policy: access_method with empty filter +curl -u 'policyadmin:zb!XztG34' -H 'Content-Type: application/json' -H 'Accept: application/json' -d '{"onapName":"CDS","onapComponent":"CDS","onapInstance":"CDS","currentDate": "2024-11-22", "currentTime": "08:26:41.857Z", "timeZone": "UTC", "timeOffset": "+05:30", "currentDateTime": "2025-01-17T08:26:41.857Z", "policyFilter" : [""], "policyName":"access_method","input":{"method":"POST","path":["users"]}}' -X POST http://0.0.0.0:30012/policy/pdpo/v1/decision -## OUTPUT for policy:account with empty filter +{"output":{"allow":true},"policyName":"access_method"} -curl -u 'policyadmin:zb!XztG34' -H 'Content-Type: application/json' -H 'Accept: application/json' --header 'X-ONAP-RequestID:8e6f784e-c9cb-42f6-bcc9-edb5d0af1ce1' -d '{"onapName":"CDS","onapComponent":"CDS","onapInstance":"CDS", "currentDate": "2024-11-22", "currentTime": "11:34:56", "timeZone": "UTC","timeOffset": "+05:30", "currentDateTime": "2024-11-22T12:08:00Z",__"policyFilter": [""]__, "policyName":"account", "input":{"creditor_account":11111,"creditor":"alice","debtor_account":22222,"debtor":"bob","period":30,"amount":1000}}' -X POST http://0.0.0.0:8282/policy/pdpo/v1/decision +## Output For Policy: access_method with filter allow +curl -u 'policyadmin:zb!XztG34' -H 'Content-Type: application/json' -H 'Accept: application/json' -d '{"onapName":"CDS","onapComponent":"CDS","onapInstance":"CDS","currentDate": "2024-11-22", "currentTime": "08:26:41.857Z", "timeZone": "UTC", "timeOffset": "+05:30", "currentDateTime": "2025-01-17T08:26:41.857Z", "policyFilter" : ["allow"], "policyName":"access_method","input":{"method":"POST","path":["users"]}}' -X POST http://0.0.0.0:30012/policy/pdpo/v1/decision -{"output":{"account_attributes":{"11111":{"amount":10000,"owner":"alice"},"22222":{"amount":10000,"owner":"bob"},"33333":{"amount":10000,"owner":"cam"}},"allow":true,"amount_is_valid":true,"creditor_is_valid":true,"debtor_is_valid":true,"period_is_valid":true},"policyName":"account"} +{"output":{"allow":true},"policyName":"access_method"} -## OUTPUT for policy:organization with filter acls +## Output For Policy: role with filter allow -curl -u 'policyadmin:zb!XztG34' -H 'Content-Type: application/json' -H 'Accept: application/json' --header 'X-ONAP-RequestID:8e6f784e-c9cb-42f6-bcc9-edb5d0af1ce1' -d '{"onapName":"CDS","onapComponent":"CDS","onapInstance":"CDS", "currentDate": "2024-11-22", "currentTime": "11:34:56", "timeZone": "UTC", "timeOffset": "+05:30", "currentDateTime": "2024-11-22T12:08:00Z",__"policyFilter": ["acls"]__, "policyName":"organization", "input":{"user":"alice","action": "read","component": "component_A","project": "project_A", "organization": "org_A"}}' -X POST http://0.0.0.0:8282/policy/pdpo/v1/decision +curl -u 'policyadmin:zb!XztG34' -H 'Content-Type: application/json' -H 'Accept: application/json' --header 'X-ONAP-RequestID:8e6f784e-c9cb-42f6-bcc9-edb5d0af1ce1' -d '{"onapName":"CDS","onapComponent":"CDS","onapInstance":"CDS","currentDate": "2024-11-22", "currentTime": "08:26:41.857Z", "timeZone": "UTC", "timeOffset": "+05:30", "currentDateTime": "2025-01-17T08:26:41.857Z", "policyName":"role", "policyFilter": ["allow"], "input":{"user":"alice","action":"write","object":"id123","type":"dog"}}' -X POST http://0.0.0.0:30012/policy/pdpo/v1/decision -{"output":{"acls":[{"actions":["edit","read"],"component":"component_A","organization":"org_A","project":"project_A","user":"alice"},{"actions":["read"],"organization":"org_A","user":"bob"},{"action":["edit"],"component":"component_A","organization":"org_A","project":"project_B","user":"bob"},{"action":["read"],"organization":"org_A","project":"project_B","user":"charlie"}]},"policyName":"organization"} +{"output":{"allow":true},"policyName":"role"} -## OUTPUT for policy:organization with empty filter -curl -u 'policyadmin:zb!XztG34' -H 'Content-Type: application/json' -H 'Accept: application/json' --header 'X-ONAP-RequestID:8e6f784e-c9cb-42f6-bcc9-edb5d0af1ce1' -d '{"onapName":"CDS","onapComponent":"CDS","onapInstance":"CDS", "currentDate": "2024-11-22", "currentTime": "11:34:56", "timeZone": "UTC", "timeOffset": "+05:30", "currentDateTime": "2024-11-22T12:08:00Z",__"policyFilter": [""]__, "policyName":"organization", "input":{"user":"alice","action": "read","component": "component_A","project": "project_A", "organization": "org_A"}}' -X POST http://0.0.0.0:8282/policy/pdpo/v1/decision +## Output For policy: role with empty filter +curl -u 'policyadmin:zb!XztG34' -H 'Content-Type: application/json' -H 'Accept: application/json' --header 'X-ONAP-RequestID:8e6f784e-c9cb-42f6-bcc9-edb5d0af1ce1' -d '{"onapName":"CDS","onapComponent":"CDS","onapInstance":"CDS","currentDate": "2024-11-22", "currentTime": "08:26:41.857Z", "timeZone": "UTC", "timeOffset": "+05:30", "currentDateTime": "2025-01-17T08:26:41.857Z", "policyName":"role", "policyFilter": [""], "input":{"user":"alice","action":"write","object":"id123","type":"dog"}}' -X POST http://0.0.0.0:30012/policy/pdpo/v1/decision -{"output":{"acls":[{"actions":["edit","read"],"component":"component_A","organization":"org_A","project":"project_A","user":"alice"},{"actions":["read"],"organization":"org_A","user":"bob"},{"action":["edit"],"component":"component_A","organization":"org_A","project":"project_B","user":"bob"},{"action":["read"],"organization":"org_A","project":"project_B","user":"charlie"}],"allow":true},"policyName":"organization"} +{"output":{"allow":true,"user_is_admin":true,"user_is_granted":[]},"policyName":"role"} -## OUTPUT for policy:abac with filter viewable_sensor_data +## Output For policy: role with filter not matching the allowable filters +curl -u 'policyadmin:zb!XztG34' -H 'Content-Type: application/json' -H 'Accept: application/json' --header 'X-ONAP-RequestID:8e6f784e-c9cb-42f6-bcc9-edb5d0af1ce1' -d '{"onapName":"CDS","onapComponent":"CDS","onapInstance":"CDS","currentDate": "2024-11-22", "currentTime": "08:26:41.857Z", "timeZone": "UTC", "timeOffset": "+05:30", "currentDateTime": "2025-01-17T08:26:41.857Z", "policyName":"role", "policyFilter": ["abc"], "input":{"user":"alice","action":"write","object":"id123","type":"dog"}}' -X POST http://0.0.0.0:30012/policy/pdpo/v1/decision -curl -u 'policyadmin:zb!XztG34' -H 'Content-Type: application/json' -H 'Accept: application/json' --header 'X-ONAP-RequestID:8e6f784e-c9cb-42f6-bcc9-edb5d0af1ce1' -d '{"onapName":"CDS","onapComponent":"CDS","onapInstance":"CDS","currentDate": "2024-11-22","policyName":"abac", __"policyFilter": ["viewable_sensor_data"]__, "input":{"actions": ["write"],"datatypes": ["location","temperature","precipitation","windspeed"],"time_period": {"from": "2024-03-27","to": "2024-03-31"}}}' -X POST http://0.0.0.0:8282/policy/pdpo/v1/decision +{"output":null,"policyName":"role","statusMessage":"Policy Filter(s) not matching, Valid Filter(s) are: [allow, user_is_admin, user_is_granted]"} -{"output":{"viewable_sensor_data":[]},"policyName":"abac"} +## Output For Policy: blacklist with filter module_allow +curl -u 'policyadmin:zb!XztG34' -H 'Content-Type: application/json' -H 'Accept: application/json' -d '{"onapName":"CDS","onapComponent":"CDS","onapInstance":"CDS","currentDate": "2024-11-22", "currentTime": "08:26:41.857Z", "timeZone": "UTC", "timeOffset": "+05:30", "currentDateTime": "2025-01-17T08:26:41.857Z", "policyFilter" : ["module_allow"], "policyName":"blacklist","input":{"vfmodule":["the-vfmodule-where-root-is-true","another-vfmodule-where-root-is-true" ] }}' -X POST http://localhost:30012/policy/pdpo/v1/decision -## OUTPUT for policy:abac with empty filter +{"output":{"module_allow":{"another-vfmodule-where-root-is-true":true,"the-vfmodule-where-root-is-true":true}},"policyName":"blacklist"} -curl -u 'policyadmin:zb!XztG34' -H 'Content-Type: application/json' -H 'Accept: application/json' --header 'X-ONAP-RequestID:8e6f784e-c9cb-42f6-bcc9-edb5d0af1ce1' -d '{"onapName":"CDS","onapComponent":"CDS","onapInstance":"CDS","currentDate": "2024-11-22","policyName":"abac", __"policyFilter": [""]__, "input":{"actions": ["write"],"datatypes": ["location","temperature","precipitation","windspeed"],"time_period": {"from": "2024-03-27","to": "2024-03-31"}}}' -X POST http://0.0.0.0:8282/policy/pdpo/v1/decision +## Output For Policy: blacklist with Empty Filter + curl -u 'policyadmin:zb!XztG34' -H 'Content-Type: application/json' -H 'Accept: application/json' -d '{"onapName":"CDS","onapComponent":"CDS","onapInstance":"CDS","currentDate": "2024-11-22", "currentTime": "08:26:41.857Z", "timeZone": "UTC", "timeOffset": "+05:30", "currentDateTime": "2025-01-17T08:26:41.857Z", "policyFilter" : [""], "policyName":"blacklist","input":{"vfmodule":["the-vfmodule-where-root-is-true","another-vfmodule-where-root-is-true" ] }}' -X POST http://localhost:30012/policy/pdpo/v1/decision -{"output":{"allow":false,"sensor_data":[{"humidity":"40%","id":"0001","location":"Sri Lanka","particle_density":"1.3 g/l","precipitation":"1000 mm","temperature":"28 C","timestamp":"2024-02-26","windspeed":"5.5 m/s"},{"humidity":"45%","id":"0002","location":"Colombo","particle_density":"1.5 g/l","precipitation":"1200 mm","temperature":"30 C","timestamp":"2024-02-26","windspeed":"6.0 m/s"},{"humidity":"60%","id":"0003","location":"Kandy","particle_density":"1.1 g/l","precipitation":"800 mm","temperature":"25 C","timestamp":"2024-02-26","windspeed":"4.5 m/s"},{"humidity":"30%","id":"0004","location":"Galle","particle_density":"1.8 g/l","precipitation":"500 mm","temperature":"35 C","timestamp":"2024-02-27","windspeed":"7.2 m/s"},{"humidity":"20%","id":"0005","location":"Jaffna","particle_density":"0.9 g/l","precipitation":"300 mm","temperature":"-5 C","timestamp":"2024-02-27","windspeed":"3.8 m/s"},{"humidity":"55%","id":"0006","location":"Trincomalee","particle_density":"1.2 g/l","precipitation":"1000 mm","temperature":"20 C","timestamp":"2024-02-28","windspeed":"5.0 m/s"},{"humidity":"50%","id":"0007","location":"Nuwara Eliya","particle_density":"1.3 g/l","precipitation":"600 mm","temperature":"25 C","timestamp":"2024-02-28","windspeed":"4.0 m/s"},{"humidity":"40%","id":"0008","location":"Anuradhapura","particle_density":"1.4 g/l","precipitation":"700 mm","temperature":"28 C","timestamp":"2024-02-29","windspeed":"5.8 m/s"},{"humidity":"65%","id":"0009","location":"Matara","particle_density":"1.6 g/l","precipitation":"900 mm","temperature":"32 C","timestamp":"2024-02-29","windspeed":"6.5 m/s"}],"viewable_sensor_data":[]},"policyName":"abac"} +{"output":{"module_allow":{"another-vfmodule-where-root-is-true":true,"the-vfmodule-where-root-is-true":true}},"policyName":"blacklist"} -## OUTPUT for policy:zone with filter has_zone_access +## Output For Policy: monitor with filter result +curl -u 'policyadmin:zb!XztG34' -H 'Content-Type: application/json' -H 'Accept: application/json' -d '{"onapName":"CDS","onapComponent":"CDS","onapInstance":"CDS","currentDate": "2024-11-22", "currentTime": "08:26:41.857Z", "timeZone": "UTC", "timeOffset": "+05:30", "currentDateTime": "2025-01-17T08:26:41.857Z", "policyFilter" : ["result"], "policyName":"monitor","input":{ "domain": "measurementsForVfScaling", "eventName": "Measurement_vGMUX","controlLoopSchemaType": "VNF","policyScope": "DCAE","policyName": "DCAE.Config_tca-hi-lo","policyVersion": "v0.0.1", "version": "1.0.2","controlname": "ControlLoop-vCPE-48f0c2c3-a172-4192-9ae3-052274181b6e","thresholdValue": 0}}' -X POST http://localhost:30012/policy/pdpo/v1/decision -curl -u 'policyadmin:zb!XztG34' -H 'Content-Type: application/json' -H 'Accept: application/json' --header 'X-ONAP-RequestID:8e6f784e-c9cb-42f6-bcc9-edb5d0af1ce1' -d '{"onapName":"CDS","onapComponent":"CDS","onapInstance":"CDS","currentDate": "2024-11-22","policyName":"zone", __"policyFilter": ["has_zone_access"]__, "input":{"actions": ["view"],"log_id": "log1", "datatypes": ["access", "user"],"time_period": {"from": "2024-11-01T09:00:00Z","to": "2024-11-01T10:00:00Z"},"zone_id": "zoneA"}}' -X POST http://0.0.0.0:8282/policy/pdpo/v1/decision +{"output":{"result":[{"closedLoopEventStatus":"ABATED","severity":"MAJOR"}]},"policyName":"monitor"} -{"output":{"has_zone_access":[{"access":"granted","user":"user1"}]},"policyName":"zone"} - -## OUTPUT for policy:zone with empty filter - -curl -u 'policyadmin:zb!XztG34' -H 'Content-Type: application/json' -H 'Accept: application/json' --header 'X-ONAP-RequestID:8e6f784e-c9cb-42f6-bcc9-edb5d0af1ce1' -d '{"onapName":"CDS","onapComponent":"CDS","onapInstance":"CDS","currentDate": "2024-11-22","policyName":"zone", __"policyFilter": [""]__, "input":{"actions": ["view"],"log_id": "log1", "datatypes": ["access", "user"],"time_period": {"from": "2024-11-01T09:00:00Z","to": "2024-11-01T10:00:00Z"},"zone_id": "zoneA"}}' -X POST http://0.0.0.0:8282/policy/pdpo/v1/decision - -{"output":{"action_is_log_view":true,"allow":true,"has_zone_access":[{"access":"granted","user":"user1"}],"zone":{"zone_access_logs":[{"access":"granted","log_id":"log1","timestamp":"2024-11-01T09:00:00Z","user":"user1","zone_id":"zoneA"},{"access":"denied","log_id":"log2","timestamp":"2024-11-01T10:30:00Z","user":"user2","zone_id":"zoneA"},{"access":"granted","log_id":"log3","timestamp":"2024-11-01T11:00:00Z","user":"user3","zone_id":"zoneB"}]}},"policyName":"zone"} - -## OUTPUT for policy:vehicle with filter user_has_vehicle_access - -curl -u 'policyadmin:zb!XztG34' -H 'Content-Type: application/json' -H 'Accept: application/json' --header 'X-ONAP-RequestID:8e6f784e-c9cb-42f6-bcc9-edb5d0af1ce1' -d '{"onapName":"CDS","onapComponent":"CDS","onapInstance":"CDS","currentDate": "2024-11-22","policyName":"vehicle", __"policyFilter": ["user_has_vehicle_access"]__, "input":{"actions": ["use"],"user":"user1", "vehicle_id": "v1", "attributes": ["type", "status"]}}' -X POST http://0.0.0.0:8282/policy/pdpo/v1/decision - -{"output":{"user_has_vehicle_access":[{"status":"available","type":"car"}]},"policyName":"vehicle"} - -## OUTPUT for policy:vehicle with empty filter - -curl -u 'policyadmin:zb!XztG34' -H 'Content-Type: application/json' -H 'Accept: application/json' --header 'X-ONAP-RequestID:8e6f784e-c9cb-42f6-bcc9-edb5d0af1ce1' -d '{"onapName":"CDS","onapComponent":"CDS","onapInstance":"CDS","currentDate": "2024-11-22","policyName":"vehicle", __"policyFilter": [""]__, "input":{"actions": ["use"],"user":"user1", "vehicle_id": "v1", "attributes": ["type", "status"]}}' -X POST http://0.0.0.0:8282/policy/pdpo/v1/decision - -{"output":{"action_is_granted":true,"allow":true,"user_has_vehicle_access":[{"status":"available","type":"car"}],"vehicles":[{"owner":"user1","status":"available","type":"car","vehicle_id":"v1"},{"owner":"user2","status":"in use","type":"bike","vehicle_id":"v2"}]},"policyName":"vehicle"} - -## OUTPUT for policy:docs with filter has_access_to_file - -curl -u 'policyadmin:zb!XztG34' -H 'Content-Type: application/json' -H 'Accept: application/json' --header 'X-ONAP-RequestID:8e6f784e-c9cb-42f6-bcc9-edb5d0af1ce1' -d '{"onapName":"CDS","onapComponent":"CDS","onapInstance":"CDS","currentDate": "2024-11-22","policyName":"docs", __"policyFilter": ["has_access_to_file"]__, "input":{"action": "read","file_id": "file1","access_level": "admin","attributes": ["owner", "size"]}}' -X POST http://0.0.0.0:8282/policy/pdpo/v1/decision - -{"output":{"has_access_to_file":[{"owner":"user1","size":"10MB"}]},"policyName":"docs"} - -## OUTPUT for policy:docs with empty filter - -curl -u 'policyadmin:zb!XztG34' -H 'Content-Type: application/json' -H 'Accept: application/json' --header 'X-ONAP-RequestID:8e6f784e-c9cb-42f6-bcc9-edb5d0af1ce1' -d '{"onapName":"CDS","onapComponent":"CDS","onapInstance":"CDS","currentDate": "2024-11-22","policyName":"docs", __"policyFilter": [""]__, "input":{"action": "read","file_id": "file1","access_level": "admin","attributes": ["owner", "size"]}}' -X POST http://0.0.0.0:8282/policy/pdpo/v1/decision - -{"output":{"action_is_read_or_write":true,"allow":true,"files":[{"access_level":"admin","file_id":"file1","owner":"user1","size":"10MB"},{"access_level":"user","file_id":"file2","owner":"user2","size":"5MB"}],"has_access_to_file":[{"owner":"user1","size":"10MB"}]},"policyName":"docs"} +## Output For Policy: monitor with empty filter +curl -u 'policyadmin:zb!XztG34' -H 'Content-Type: application/json' -H 'Accept: application/json' -d '{"onapName":"CDS","onapComponent":"CDS","onapInstance":"CDS","currentDate": "2024-11-22", "currentTime": "08:26:41.857Z", "timeZone": "UTC", "timeOffset": "+05:30", "currentDateTime": "2025-01-17T08:26:41.857Z", "policyFilter" : [""], "policyName":"monitor","input":{ "domain": "measurementsForVfScaling", "eventName": "Measurement_vGMUX","controlLoopSchemaType": "VNF","policyScope": "DCAE","policyName": "DCAE.Config_tca-hi-lo","policyVersion": "v0.0.1", "version": "1.0.2","controlname": "ControlLoop-vCPE-48f0c2c3-a172-4192-9ae3-052274181b6e","thresholdValue": 0}}' -X POST http://localhost:30012/policy/pdpo/v1/decision +{"output":{"result":[{"closedLoopEventStatus":"ABATED","severity":"MAJOR"}]},"policyName":"monitor ## HealthCheck API Call With Response -curl -u 'policyadmin:zb!XztG34' --header 'X-ONAP-RequestID:8e6f784e-c9cb-42f6-bcc9-edb5d0af1ce1' -X GET http://0.0.0.0:8282/policy/pdpo/v1/healthcheck +curl -u 'policyadmin:zb!XztG34' --header 'X-ONAP-RequestID:8e6f784e-c9cb-42f6-bcc9-edb5d0af1ce1' -X GET http://0.0.0.0:30012/policy/pdpo/v1/healthcheck {"code":200,"healthy":true,"message":"alive","name":"opa-ea84b1ff-00de-4bf6-a039-222e4511d0a1","url":"self"} ## Statistics API Call With Response -curl -u 'policyadmin:zb!XztG34' --header 'X-ONAP-RequestID:8e6f784e-c9cb-42f6-bcc9-edb5d0af1ce1' -X GET http://0.0.0.0:8282/policy/pdpo/v1/statistics +curl -u 'policyadmin:zb!XztG34' --header 'X-ONAP-RequestID:8e6f784e-c9cb-42f6-bcc9-edb5d0af1ce1' -X GET http://0.0.0.0:30012/policy/pdpo/v1/statistics + +{"code":200,"decisionFailureCount":0,"decisionSuccessCount":0,"deployFailureCount":0,"deploySuccessCount":0, "totalErrorCount":0,"totalPoliciesCount":0,"totalPolicyTypesCount":1,"undeployFailureCount":0,"undeploySuccessCount":0} -{"code":200,"decisionFailureCount":0,"decisionSuccessCount":9,"deployFailureCount":0,"deploySuccessCount":0,"totalErrorCount":5,"totalPoliciesCount":0,"totalPolicyTypesCount":1,"undeployFailureCount":0,"undeploySuccessCount":0} diff --git a/test/config.json b/test/config.json deleted file mode 100644 index 0eb38c9..0000000 --- a/test/config.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "logging": { - "level": "debug" - }, - "decision_logs": { - "console": true - } -} diff --git a/test/config/opa-pdp/config.json b/test/config/opa-pdp/config.json deleted file mode 100644 index 0eb38c9..0000000 --- a/test/config/opa-pdp/config.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "logging": { - "level": "debug" - }, - "decision_logs": { - "console": true - } -} diff --git a/test/config/opa-pdp/groups.json b/test/config/opa-pdp/groups.json deleted file mode 100644 index 502700c..0000000 --- a/test/config/opa-pdp/groups.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "groups": [ - { - "name": "defaultGroup", - "version": "1.0.0", - "description": "The default group that registers all supported policy types and pdps.", - "pdpGroupState": "ACTIVE", - "pdpSubgroups": [ - { - "pdpType": "opa" - } - ] - } - ] -} diff --git a/test/config/opa-pdp/policy-opa-pdp.sh b/test/config/opa-pdp/policy-opa-pdp.sh deleted file mode 100755 index 7ed14cb..0000000 --- a/test/config/opa-pdp/policy-opa-pdp.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/bash - - -#Creation of Policies and Groups -sh scripts.sh - - -#Execution of OPA-PDP bin -/app/opa-pdp diff --git a/test/data/abac/data.json b/test/data/abac/data.json deleted file mode 100644 index 77b5668..0000000 --- a/test/data/abac/data.json +++ /dev/null @@ -1,94 +0,0 @@ -{ - "sensor_data": [ - { - "id": "0001", - "location": "Sri Lanka", - "temperature": "28 C", - "precipitation": "1000 mm", - "windspeed": "5.5 m/s", - "humidity": "40%", - "particle_density": "1.3 g/l", - "timestamp": "2024-02-26" - }, - { - "id": "0002", - "location": "Colombo", - "temperature": "30 C", - "precipitation": "1200 mm", - "windspeed": "6.0 m/s", - "humidity": "45%", - "particle_density": "1.5 g/l", - "timestamp": "2024-02-26" - }, - { - "id": "0003", - "location": "Kandy", - "temperature": "25 C", - "precipitation": "800 mm", - "windspeed": "4.5 m/s", - "humidity": "60%", - "particle_density": "1.1 g/l", - "timestamp": "2024-02-26" - }, - { - "id": "0004", - "location": "Galle", - "temperature": "35 C", - "precipitation": "500 mm", - "windspeed": "7.2 m/s", - "humidity": "30%", - "particle_density": "1.8 g/l", - "timestamp": "2024-02-27" - }, - { - "id": "0005", - "location": "Jaffna", - "temperature": "-5 C", - "precipitation": "300 mm", - "windspeed": "3.8 m/s", - "humidity": "20%", - "particle_density": "0.9 g/l", - "timestamp": "2024-02-27" - }, - { - "id": "0006", - "location": "Trincomalee", - "temperature": "20 C", - "precipitation": "1000 mm", - "windspeed": "5.0 m/s", - "humidity": "55%", - "particle_density": "1.2 g/l", - "timestamp": "2024-02-28" - }, - { - "id": "0007", - "location": "Nuwara Eliya", - "temperature": "25 C", - "precipitation": "600 mm", - "windspeed": "4.0 m/s", - "humidity": "50%", - "particle_density": "1.3 g/l", - "timestamp": "2024-02-28" - }, - { - "id": "0008", - "location": "Anuradhapura", - "temperature": "28 C", - "precipitation": "700 mm", - "windspeed": "5.8 m/s", - "humidity": "40%", - "particle_density": "1.4 g/l", - "timestamp": "2024-02-29" - }, - { - "id": "0009", - "location": "Matara", - "temperature": "32 C", - "precipitation": "900 mm", - "windspeed": "6.5 m/s", - "humidity": "65%", - "particle_density": "1.6 g/l", - "timestamp": "2024-02-29" - } - ] -} diff --git a/test/data/account/data.json b/test/data/account/data.json deleted file mode 100644 index df263d3..0000000 --- a/test/data/account/data.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "account_attributes":{ - "11111":{ - "owner":"alice", - "amount":10000 - }, - "22222":{ - "owner":"bob", - "amount":10000 - }, - "33333":{ - "owner":"cam", - "amount":10000 - } - } -} diff --git a/test/data/action/data.json b/test/data/action/data.json deleted file mode 100644 index 99145b7..0000000 --- a/test/data/action/data.json +++ /dev/null @@ -1,43 +0,0 @@ -{ - "user_roles": { - "alice": [ - "admin" - ], - "bob": [ - "editor" - ], - "charlie": [ - "viewer" - ] - }, - "role_permissions": { - "admin": { - "actions": [ - "read", - "write", - "delete" - ], - "resources": [ - "server", - "database" - ] - }, - "editor": { - "actions": [ - "read", - "write" - ], - "resources": [ - "server" - ] - }, - "viewer": { - "actions": [ - "read" - ], - "resources": [ - "server" - ] - } - } -} diff --git a/test/data/blacklist/data.json b/test/data/blacklist/data.json new file mode 100644 index 0000000..9fd6233 --- /dev/null +++ b/test/data/blacklist/data.json @@ -0,0 +1,6 @@ +{ + "blacklist" : [ + "the-vfmodule-where-root-is-true", + "another-vfmodule-where-root-is-true" +] +} diff --git a/test/data/cell/consistency/data.json b/test/data/cell/consistency/data.json new file mode 100644 index 0000000..1f823a1 --- /dev/null +++ b/test/data/cell/consistency/data.json @@ -0,0 +1,5 @@ +{ + "allowedCellId" : 445611193265040129, + "minPCI": 1, + "maxPCI": 3000 +} diff --git a/test/data/docs/data.json b/test/data/docs/data.json deleted file mode 100644 index 5d43020..0000000 --- a/test/data/docs/data.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "files": [ - { "file_id": "file1", "access_level": "admin", "owner": "user1", "size": "10MB" }, - { "file_id": "file2", "access_level": "user", "owner": "user2", "size": "5MB" } - ] -} - diff --git a/test/data/monitor/data.json b/test/data/monitor/data.json new file mode 100644 index 0000000..f28f73c --- /dev/null +++ b/test/data/monitor/data.json @@ -0,0 +1,13 @@ +{ "domain": "measurementsForVfScaling", + "metricsPerEventName": [{ + "eventName": "Measurement_vGMUX", + "controlLoopSchemaType": "VNF", + "policyScope": "DCAE", + "policyName": "DCAE.Config_tca-hi-lo", + "policyVersion": "v0.0.1", + "thresholds" : [{"version": "1.0.2", + "closedLoopControlName": "ControlLoop-vCPE-48f0c2c3-a172-4192-9ae3-052274181b6e", + "thresholdValue": 0 + }] +}] +} diff --git a/test/data/organization/data.json b/test/data/organization/data.json deleted file mode 100644 index 35fe4a1..0000000 --- a/test/data/organization/data.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "acls": [ - { - "user": "alice", - "actions": [ - "edit", - "read" - ], - "component": "component_A", - "project": "project_A", - "organization": "org_A" - }, - { - "user": "bob", - "actions": ["read"], - "organization": "org_A" - }, - { - "user": "bob", - "action": ["edit"], - "component": "component_A", - "project": "project_B", - "organization": "org_A" - }, - { - "user": "charlie", - "action": ["read"], - "project": "project_B", - "organization": "org_A" - } - ] -} diff --git a/test/data/vehicle/data.json b/test/data/vehicle/data.json deleted file mode 100644 index 570c677..0000000 --- a/test/data/vehicle/data.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "vehicles": [ - { "vehicle_id": "v1", "owner": "user1", "type": "car", "status": "available" }, - { "vehicle_id": "v2", "owner": "user2", "type": "bike", "status": "in use" } - ] -} - diff --git a/test/data/zone/data.json b/test/data/zone/data.json deleted file mode 100644 index be77176..0000000 --- a/test/data/zone/data.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "zone": { - "zone_access_logs": [ - { "log_id": "log1", "timestamp": "2024-11-01T09:00:00Z", "zone_id": "zoneA", "access": "granted", "user": "user1" }, - { "log_id": "log2", "timestamp": "2024-11-01T10:30:00Z", "zone_id": "zoneA", "access": "denied", "user": "user2" }, - { "log_id": "log3", "timestamp": "2024-11-01T11:00:00Z", "zone_id": "zoneB", "access": "granted", "user": "user3" } - ] - } -} - diff --git a/test/docker-compose.yml b/test/docker-compose.yml deleted file mode 100644 index a4dea24..0000000 --- a/test/docker-compose.yml +++ /dev/null @@ -1,140 +0,0 @@ -version: '3.8' -services: - mariadb: - image: nexus3.onap.org:10001/mariadb:10.10.2 - container_name: mariadb - hostname: mariadb - command: ['--lower-case-table-names=1', '--wait_timeout=28800', '--default-authentication-plugin=mysql_native_password'] - env_file: ./config/db/db.conf - volumes: - - ./config/db:/docker-entrypoint-initdb.d - - ./config/clamp/policy-clamp-create-tables.sql:/tmp/policy-clamp-create-tables.sql - ports: - - "3306:3306" - policy-db-migrator: - image: nexus3.onap.org:10001/onap/policy-db-migrator:4.0.1-SNAPSHOT - container_name: policy-db-migrator - hostname: policy-db-migrator - depends_on: - - mariadb - expose: - - 6824 - env_file: ./config/db/db.conf - environment: - SQL_DB: policyadmin - SQL_HOST: mariadb - volumes: - - ./config/db-migrator/init.sh:/opt/app/policy/bin/db_migrator_policy_init.sh:ro - - ./wait_for_port.sh:/tmp/wait_for_port.sh - entrypoint: sh /tmp/wait_for_port.sh - command: [ - '-c', - '/opt/app/policy/bin/db_migrator_policy_init.sh', - 'mariadb', '3306' - ] - api: - image: nexus3.onap.org:10001/onap/policy-api:4.0.1-SNAPSHOT - container_name: policy-api - depends_on: - - policy-db-migrator - hostname: policy-api - ports: - - 30002:6969 - volumes: - - ./config/api/apiParameters.yaml:/opt/app/policy/api/etc/apiParameters.yaml:ro - - ./config/api/logback.xml:/opt/app/policy/api/etc/logback.xml:ro - - ./wait_for_port.sh:/opt/app/policy/api/bin/wait_for_port.sh - entrypoint: sh wait_for_port.sh - command: [ - '-c', './policy-api.sh', - 'mariadb', '3306', - 'policy-db-migrator', '6824' - ] - pap: - image: nexus3.onap.org:10001/onap/policy-pap:4.0.1-SNAPSHOT - container_name: policy-pap - depends_on: - - mariadb - - kafka - - api - hostname: policy-pap - ports: - - 30003:6969 - volumes: - - ./config/pap/papParameters.yaml:/opt/app/policy/pap/etc/papParameters.yaml:ro - - ./config/pap/groups.json:/opt/app/policy/pap/etc/mounted/groups.json:ro - - ./config/pap/logback.xml:/opt/app/policy/pap/etc/logback.xml:ro - - ./wait_for_port.sh:/opt/app/policy/pap/bin/wait_for_port.sh - entrypoint: sh wait_for_port.sh - command: [ - '-c', './policy-pap.sh', - 'mariadb', '3306', - 'kafka', '9092', - 'api', '6969' - ] - zookeeper: - image: confluentinc/cp-zookeeper:latest - environment: - ZOOKEEPER_CLIENT_PORT: 2181 - ZOOKEEPER_TICK_TIME: 2000 - ports: - - 2181:2181 - - pdp: - image: docker.io/opa-pdp:1.0.0 - container_name: opa-pdp - depends_on: - - mariadb - - kafka - - api - - pap - hostname: opa-pdp - volumes: - - ./config/opa-pdp/config.json:/app/config/config.json:ro - - ./config/opa-pdp/groups.json:/app/groups.json:ro - - ./config/opa-pdp/policy-opa-pdp.sh:/app/policy-opa-pdp.sh:ro - - ./wait_for_port.sh:/app/wait_for_port.sh - - ./scripts.sh:/app/scripts.sh - - ./Opagroup.json:/app/Opagroup.json - - ./policy-new.yaml:/app/policy-new.yaml - environment: - LOG_LEVEL: debug - KAFKA_URL: "kafka:9092" - PAP_TOPIC: policy-pdp-pap - GROUPID: opa-pdp - API_USER: policyadmin - API_PASSWORD: "zb!XztG34" - JAASLOGIN: org.apache.kafka.common.security.scram.ScramLoginModule required username="policy-opa-pdp-ku" password="pzmdwfFvBhv21mSD7dieHoUZf2aobdqR" - entrypoint: sh wait_for_port.sh - command: [ - '-c', './policy-opa-pdp.sh', - 'mariadb', '3306', - 'kafka', '9092', - 'api', '6969', - 'pap', '6969' - ] - ports: - - 8282:8282 - zookeeper: - image: confluentinc/cp-zookeeper:latest - environment: - ZOOKEEPER_CLIENT_PORT: 2181 - ZOOKEEPER_TICK_TIME: 2000 - ports: - - 2181:2181 - - kafka: - image: confluentinc/cp-kafka:latest - container_name: kafka - depends_on: - - zookeeper - ports: - - 29092:29092 - - 9092:9092 - environment: - KAFKA_BROKER_ID: 1 - KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181 - KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka:9092,PLAINTEXT_HOST://localhost:29092 - KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: PLAINTEXT:PLAINTEXT,PLAINTEXT_HOST:PLAINTEXT - KAFKA_INTER_BROKER_LISTENER_NAME: PLAINTEXT - KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1 diff --git a/test/policies/abac/policy.rego b/test/policies/abac/policy.rego deleted file mode 100644 index 9dc6ea9..0000000 --- a/test/policies/abac/policy.rego +++ /dev/null @@ -1,20 +0,0 @@ -package abac - -import rego.v1 - -default allow := false - -allow if { - viewable_sensor_data - action_is_read -} - -action_is_read if "read" in input.actions - -viewable_sensor_data contains view_data if { - some sensor_data in data.abac.sensor_data - sensor_data.timestamp >= input.time_period.from - sensor_data.timestamp < input.time_period.to - - view_data := {datatype: sensor_data[datatype] | datatype in input.datatypes} -} diff --git a/test/policies/example/policy.rego b/test/policies/access_method/policy.rego index cc19285..618aacc 100644 --- a/test/policies/example/policy.rego +++ b/test/policies/access_method/policy.rego @@ -1,4 +1,4 @@ -package example +package access_method import rego.v1 diff --git a/test/policies/account/policy.rego b/test/policies/account/policy.rego deleted file mode 100644 index f99e8eb..0000000 --- a/test/policies/account/policy.rego +++ /dev/null @@ -1,17 +0,0 @@ -package account - -import rego.v1 - -default allow := false - -allow if { - creditor_is_valid - debtor_is_valid - period_is_valid - amount_is_valid -} -creditor_is_valid if data.account.account_attributes[input.creditor_account].owner == input.creditor -debtor_is_valid if data.account.account_attributes[input.debtor_account].owner == input.debtor - -period_is_valid if input.period <= 30 -amount_is_valid if data.account.account_attributes[input.debtor_account].amount >= input.amount diff --git a/test/policies/action/policy.rego b/test/policies/action/policy.rego deleted file mode 100644 index 300fe50..0000000 --- a/test/policies/action/policy.rego +++ /dev/null @@ -1,21 +0,0 @@ -package action - -import rego.v1 - -# By default, deny requests. -default allow := false - - -# Allow the action if admin role is granted permission to perform the action. -allow if { - some i - data.action.user_roles[input.user][i] == role - some j - data.action.role_permissions[role].actions[j] == input.action - some k - data.action.role_permissions[role].resources[k] == input.type -} -# * Rego comparison to other systems: https://www.openpolicyagent.org/docs/latest/comparison-to-other-systems/ -# * Rego Iteration: https://www.openpolicyagent.org/docs/latest/#iteration - - diff --git a/test/policies/blacklist/policy.rego b/test/policies/blacklist/policy.rego new file mode 100644 index 0000000..b285593 --- /dev/null +++ b/test/policies/blacklist/policy.rego @@ -0,0 +1,18 @@ +package blacklist +import future.keywords.in +import rego.v1 + +# Define a rule to check if the operation should be allowed +module_allow[module] := false if { + some module in input.vfmodule + not validate(module) +} + +module_allow[module] := true if{ + some module in input.vfmodule + validate(module) +} + +validate(module) if { + module in data.node.blacklist.blacklist +} diff --git a/test/policies/cell/consistency/policy.rego b/test/policies/cell/consistency/policy.rego new file mode 100644 index 0000000..6137df7 --- /dev/null +++ b/test/policies/cell/consistency/policy.rego @@ -0,0 +1,17 @@ +package cell.consistency +import rego.v1 +default allow = false +# Rule to check cell consistency +check_cell_consistency if { + input.cell != data.node.cell.consistency.allowedCellId +} +# Rule to allow if PCI is within range 1-3000 +allow_if_pci_in_range if { + input.PCI >= data.node.cellconsistency.minPCI + input.PCI <= data.node.cellconsistency.maxPCI +} +# Main rule to determine the final decision +allow if{ + check_cell_consistency + allow_if_pci_in_range +} diff --git a/test/policies/cell/consistency/topology/policy.rego b/test/policies/cell/consistency/topology/policy.rego new file mode 100644 index 0000000..dccfac6 --- /dev/null +++ b/test/policies/cell/consistency/topology/policy.rego @@ -0,0 +1,6 @@ +package cell.consistency.topology +import rego.v1 +# Rule to check cell consistency +check_cell_consistency if { + input.cell != data.node.cell.consistency.allowedCellId +} diff --git a/test/policies/data/abac/data.json b/test/policies/data/abac/data.json deleted file mode 100644 index 77b5668..0000000 --- a/test/policies/data/abac/data.json +++ /dev/null @@ -1,94 +0,0 @@ -{ - "sensor_data": [ - { - "id": "0001", - "location": "Sri Lanka", - "temperature": "28 C", - "precipitation": "1000 mm", - "windspeed": "5.5 m/s", - "humidity": "40%", - "particle_density": "1.3 g/l", - "timestamp": "2024-02-26" - }, - { - "id": "0002", - "location": "Colombo", - "temperature": "30 C", - "precipitation": "1200 mm", - "windspeed": "6.0 m/s", - "humidity": "45%", - "particle_density": "1.5 g/l", - "timestamp": "2024-02-26" - }, - { - "id": "0003", - "location": "Kandy", - "temperature": "25 C", - "precipitation": "800 mm", - "windspeed": "4.5 m/s", - "humidity": "60%", - "particle_density": "1.1 g/l", - "timestamp": "2024-02-26" - }, - { - "id": "0004", - "location": "Galle", - "temperature": "35 C", - "precipitation": "500 mm", - "windspeed": "7.2 m/s", - "humidity": "30%", - "particle_density": "1.8 g/l", - "timestamp": "2024-02-27" - }, - { - "id": "0005", - "location": "Jaffna", - "temperature": "-5 C", - "precipitation": "300 mm", - "windspeed": "3.8 m/s", - "humidity": "20%", - "particle_density": "0.9 g/l", - "timestamp": "2024-02-27" - }, - { - "id": "0006", - "location": "Trincomalee", - "temperature": "20 C", - "precipitation": "1000 mm", - "windspeed": "5.0 m/s", - "humidity": "55%", - "particle_density": "1.2 g/l", - "timestamp": "2024-02-28" - }, - { - "id": "0007", - "location": "Nuwara Eliya", - "temperature": "25 C", - "precipitation": "600 mm", - "windspeed": "4.0 m/s", - "humidity": "50%", - "particle_density": "1.3 g/l", - "timestamp": "2024-02-28" - }, - { - "id": "0008", - "location": "Anuradhapura", - "temperature": "28 C", - "precipitation": "700 mm", - "windspeed": "5.8 m/s", - "humidity": "40%", - "particle_density": "1.4 g/l", - "timestamp": "2024-02-29" - }, - { - "id": "0009", - "location": "Matara", - "temperature": "32 C", - "precipitation": "900 mm", - "windspeed": "6.5 m/s", - "humidity": "65%", - "particle_density": "1.6 g/l", - "timestamp": "2024-02-29" - } - ] -} diff --git a/test/policies/data/account/data.json b/test/policies/data/account/data.json deleted file mode 100644 index df263d3..0000000 --- a/test/policies/data/account/data.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "account_attributes":{ - "11111":{ - "owner":"alice", - "amount":10000 - }, - "22222":{ - "owner":"bob", - "amount":10000 - }, - "33333":{ - "owner":"cam", - "amount":10000 - } - } -} diff --git a/test/policies/data/action/data.json b/test/policies/data/action/data.json deleted file mode 100644 index 99145b7..0000000 --- a/test/policies/data/action/data.json +++ /dev/null @@ -1,43 +0,0 @@ -{ - "user_roles": { - "alice": [ - "admin" - ], - "bob": [ - "editor" - ], - "charlie": [ - "viewer" - ] - }, - "role_permissions": { - "admin": { - "actions": [ - "read", - "write", - "delete" - ], - "resources": [ - "server", - "database" - ] - }, - "editor": { - "actions": [ - "read", - "write" - ], - "resources": [ - "server" - ] - }, - "viewer": { - "actions": [ - "read" - ], - "resources": [ - "server" - ] - } - } -} diff --git a/test/policies/data/organization/data.json b/test/policies/data/organization/data.json deleted file mode 100644 index 35fe4a1..0000000 --- a/test/policies/data/organization/data.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "acls": [ - { - "user": "alice", - "actions": [ - "edit", - "read" - ], - "component": "component_A", - "project": "project_A", - "organization": "org_A" - }, - { - "user": "bob", - "actions": ["read"], - "organization": "org_A" - }, - { - "user": "bob", - "action": ["edit"], - "component": "component_A", - "project": "project_B", - "organization": "org_A" - }, - { - "user": "charlie", - "action": ["read"], - "project": "project_B", - "organization": "org_A" - } - ] -} diff --git a/test/policies/data/role/data.json b/test/policies/data/role/data.json deleted file mode 100644 index 88ac41b..0000000 --- a/test/policies/data/role/data.json +++ /dev/null @@ -1,63 +0,0 @@ -{ - "user_roles": { - "alice": [ - "admin" - ], - "bob": [ - "employee", - "billing" - ], - "eve": [ - "customer" - ] - }, - "role_grants": { - "customer": [ - { - "action": "read", - "type": "dog" - }, - { - "action": "read", - "type": "cat" - }, - { - "action": "adopt", - "type": "dog" - }, - { - "action": "adopt", - "type": "cat" - } - ], - "employee": [ - { - "action": "read", - "type": "dog" - }, - { - "action": "read", - "type": "cat" - }, - { - "action": "update", - "type": "dog" - }, - { - "action": "update", - "type": "cat" - } - ], - "billing": [ - { - "action": "read", - "type": "finance" - }, - { - "action": "update", - "type": "finance" - } - ] - } -} - diff --git a/test/policies/docs/policy.rego b/test/policies/docs/policy.rego deleted file mode 100644 index 90ce883..0000000 --- a/test/policies/docs/policy.rego +++ /dev/null @@ -1,22 +0,0 @@ -package docs - -import rego.v1 - -default allow := false - -allow if { - has_access_to_file - action_is_read_or_write -} - -action_is_read_or_write if { - input.action in ["read", "write"] -} - -has_access_to_file contains file_info if { - some file in data.docs.files - file.file_id == input.file_id - file.access_level == input.access_level - file_info := {attr: file[attr] | attr in input.attributes} -} - diff --git a/test/policies/monitor/policy.rego b/test/policies/monitor/policy.rego new file mode 100644 index 0000000..b3d9aaa --- /dev/null +++ b/test/policies/monitor/policy.rego @@ -0,0 +1,39 @@ +package monitor + +# Policy allows if a matching threshold is met +result contains output if { + input.domain = data.node.monitor.domain + some events in data.node.monitor.metricsPerEventName + events.eventName == input.eventName + events.controlLoopSchemaType == input.controlLoopSchemaType + events.policyScope == input.policyScope + events.policyName == input.policyName + events.policyVersion == input.policyVersion + some value in events.thresholds + input.controlname == value.closedLoopControlName + input.version == value.version + input.thresholdValue == value.thresholdValue + output := { + "severity" : "MAJOR", + "closedLoopEventStatus" : "ABATED" + } +} + +# Policy allows if a matching threshold is met +result contains output if { + input.domain = data.node.monitor.domain + some events in data.node.monitor.metricsPerEventName + events.eventName == input.eventName + events.controlLoopSchemaType == input.controlLoopSchemaType + events.policyScope == input.policyScope + events.policyName == input.policyName + events.policyVersion == input.policyVersion + some value in events.thresholds + input.controlname == value.closedLoopControlName + input.version == value.version + input.thresholdValue > value.thresholdValue + output := { + "severity" : "CRITICAL", + "closedLoopEventStatus" : "ONSET" + } +} diff --git a/test/policies/organization/policy.rego b/test/policies/organization/policy.rego deleted file mode 100644 index 31e7fb6..0000000 --- a/test/policies/organization/policy.rego +++ /dev/null @@ -1,38 +0,0 @@ -package organization - -import rego.v1 - -default allow := false - -# organization level access -allow if { - some acl in data.organization.acls - acl.user == input.user - acl.organization == input.organization - acl.project == input.project - acl.component == input.component - - some action in acl.actions - action == input.action -} - -# project level access -allow if { - some acl in data.organization.acls - acl.user == input.user - acl.organization == input.organization - acl.project == input.project - - some action in acl.actions - action == input.action -} - -# component level access -allow if { - some acl in data.organization.acls - acl.user == input.user - acl.organization == input.organization - - some action in acl.actions - action == input.action -} diff --git a/test/policies/vehicle/policy.rego b/test/policies/vehicle/policy.rego deleted file mode 100644 index 592afee..0000000 --- a/test/policies/vehicle/policy.rego +++ /dev/null @@ -1,23 +0,0 @@ -package vehicle - -import rego.v1 - -default allow := false - -allow if { - user_has_vehicle_access - action_is_granted -} - -action_is_granted if { - "use" in input.actions -} - -user_has_vehicle_access contains vehicle_data if { - some vehicle in data.vehicle.vehicles - vehicle.vehicle_id == input.vehicle_id - vehicle.owner == input.user - vehicle_data := {info: vehicle[info] | info in input.attributes} -} - - diff --git a/test/policies/zone/policy.rego b/test/policies/zone/policy.rego deleted file mode 100644 index 75357a6..0000000 --- a/test/policies/zone/policy.rego +++ /dev/null @@ -1,23 +0,0 @@ -package zone - -import rego.v1 - -default allow := false - -allow if { - has_zone_access - action_is_log_view -} - -action_is_log_view if { - "view" in input.actions -} - -has_zone_access contains access_data if { - some zone_data in data.zone.zone.zone_access_logs - zone_data.timestamp >= input.time_period.from - zone_data.timestamp < input.time_period.to - zone_data.zone_id == input.zone_id - access_data := {datatype: zone_data[datatype] | datatype in input.datatypes} -} - diff --git a/test/policy-new.yaml b/test/policy-new.yaml deleted file mode 100644 index 2fbcf79..0000000 --- a/test/policy-new.yaml +++ /dev/null @@ -1,21 +0,0 @@ -tosca_definitions_version: tosca_simple_yaml_1_1_0 -policy_types: - onap.policies.Native: - derived_from: tosca.policies.Root - description: a base policy type for all native PDP policies - version: 1.0.0 - name: onap.policies.Native - onap.policies.native.opa: - derived_from: onap.policies.Native - version: 1.0.0 - name: onap.policies.native.opa - description: a policy type for native opa policies - properties: - policy: - type: string - type_version: 0.0.0 - description: The rego PolicySet or Policy - required: true - metadata: - encoding: Base64 - diff --git a/test/scripts.sh b/test/scripts.sh deleted file mode 100755 index ab4f838..0000000 --- a/test/scripts.sh +++ /dev/null @@ -1,27 +0,0 @@ -#!/bin/bash - -# Set up credentials and host variables -USER="policyadmin" -PASSWORD="zb!XztG34" -HOST="localhost" - -# Exit immediately if a command exits with a non-zero status -set -e - -# Step 1: Create a Policy -echo "Creating a new policy..." -sleep 40 -curl -u "$USER:$PASSWORD" --header "Content-Type: application/yaml" \ - -X POST --data-binary @policy-new.yaml \ - http://policy-api:6969/policy/api/v1/policytypes -echo "Policy created successfully. Check policy-api logs for details." - -# Step 2: Create Groups -echo "Creating groups..." -curl -u "$USER:$PASSWORD" --header "Content-Type: application/json" \ - -X POST --data-binary @Opagroup.json \ - http://policy-pap:6969/policy/pap/v1/pdps/groups/batch - -echo "Groups created successfully. Check policy-pap logs for details." - -echo "Script execution completed." diff --git a/test/scripts.txt b/test/scripts.txt deleted file mode 100644 index 3d60d4a..0000000 --- a/test/scripts.txt +++ /dev/null @@ -1,21 +0,0 @@ - curl -u 'policyadmin:zb!XztG34' --header "Content-Type:application/yaml" -X POST --data-binary @policy-new.yaml http://localhost:30002/policy/api/v1/policytypes - -# policy-new.yaml is inside test directory to create policy -#check policy-api logs - - -//Create Groups - -curl -u 'policyadmin:zb!XztG34' --header "Content-Type:application/json" -X POST --data-binary @Opagroup.json http://localhost:30003/policy/pap/v1/pdps/groups/batch - -#Check policy-pap logs -#file Opagroup.json is inside test - -// Sends registration message to policy-pdp-pap - -docker exec -it kafka /bin/sh - -echo '{"messageName": "PDP_STATUS", "requestId": "e9b4ee77-5400-41a8-87ba-3c914a86ee08", "timestampMs": "1728551661460","name": "opa-2e953ecf-40f1-47f7-8a5e-53031947516c","pdpGroup": "opaGroup","pdpSubgroup": null, "pdpType": "opa","state": "PASSIVE","healthy": "HEALTHY", "description": null, "policies": []}' | kafka-console-producer --broker-list kafka:9092 --topic policy-pdp-pap - - -#To get Gracefulshutdown signals commented command and changed entrypoint to /app/opa-pdp diff --git a/test/test_resources/policy_collab.yaml b/test/test_resources/policy_collab.yaml deleted file mode 100644 index fe4fc12..0000000 --- a/test/test_resources/policy_collab.yaml +++ /dev/null @@ -1,18 +0,0 @@ -tosca_definitions_version: tosca_simple_yaml_1_1_0 -topology_template: - policies: - - collab: - type: onap.policies.native.opa - type_version: 1.0.0 - properties: - data: - node.collab.action: ewogICAgInVzZXJfcm9sZXMiOiB7CiAgICAgICAgImFsaWNlIjogWwogICAgICAgICAgICAiYWRtaW4iCiAgICAgICAgXSwKICAgICAgICAiYm9iIjogWwogICAgICAgICAgICAiZWRpdG9yIgogICAgICAgIF0sCiAgICAgICAgImNoYXJsaWUiOiBbCiAgICAgICAgICAgICJ2aWV3ZXIiCiAgICAgICAgXQogICAgfSwKICAgICJyb2xlX3Blcm1pc3Npb25zIjogewogICAgICAgICJhZG1pbiI6IHsKICAgICAgICAgICAgImFjdGlvbnMiOiBbCiAgICAgICAgICAgICAgICAicmVhZCIsCiAgICAgICAgICAgICAgICAid3JpdGUiLAogICAgICAgICAgICAgICAgImRlbGV0ZSIKICAgICAgICAgICAgXSwKICAgICAgICAgICAgInJlc291cmNlcyI6IFsKICAgICAgICAgICAgICAgICJzZXJ2ZXIiLAogICAgICAgICAgICAgICAgImRhdGFiYXNlIgogICAgICAgICAgICBdCiAgICAgICAgfSwKICAgICAgICAiZWRpdG9yIjogewogICAgICAgICAgICAiYWN0aW9ucyI6IFsKICAgICAgICAgICAgICAgICJyZWFkIiwKICAgICAgICAgICAgICAgICJ3cml0ZSIKICAgICAgICAgICAgXSwKICAgICAgICAgICAgInJlc291cmNlcyI6IFsKICAgICAgICAgICAgICAgICJzZXJ2ZXIiCiAgICAgICAgICAgIF0KICAgICAgICB9LAogICAgICAgICJ2aWV3ZXIiOiB7CiAgICAgICAgICAgICJhY3Rpb25zIjogWwogICAgICAgICAgICAgICAgInJlYWQiCiAgICAgICAgICAgIF0sCiAgICAgICAgICAgICJyZXNvdXJjZXMiOiBbCiAgICAgICAgICAgICAgICAic2VydmVyIgogICAgICAgICAgICBdCiAgICAgICAgfQogICAgfQp9 - policy: - collab.conflict: cGFja2FnZSBjb2xsYWIuY29uZmxpY3QKCmltcG9ydCByZWdvLnYxCgphbGxvdyBpZiB7IGlucHV0Lm5hbWUgPT0gImFsaWNlIiB9CmRlbnkgaWYgeyBpbnB1dC5uYW1lID09ICJhbGljZSIgfQoKIyBkZW55IGV2ZXJ5dGhpbmcgYnkgZGVmYXVsdApkZWZhdWx0IGF1dGh6IDo9IGZhbHNlCgojIGRlbnkgb3ZlcnJpZGVzIGFsbG93CmF1dGh6IGlmIHsKICAgIGFsbG93CiAgICBub3QgZGVueQp9Cg== - collab.action: cGFja2FnZSBjb2xsYWIuYWN0aW9uCgppbXBvcnQgcmVnby52MQoKIyBCeSBkZWZhdWx0LCBkZW55IHJlcXVlc3RzLgpkZWZhdWx0IGFsbG93IDo9IGZhbHNlCgoKIyBBbGxvdyB0aGUgYWN0aW9uIGlmIGFkbWluIHJvbGUgaXMgZ3JhbnRlZCBwZXJtaXNzaW9uIHRvIHBlcmZvcm0gdGhlIGFjdGlvbi4KYWxsb3cgaWYgewogICAgc29tZSBpCiAgICBkYXRhLm5vZGUuY29sbGFiLmFjdGlvbi51c2VyX3JvbGVzW2lucHV0LnVzZXJdW2ldID09IHJvbGUKICAgIHNvbWUgagogICAgZGF0YS5ub2RlLmNvbGxhYi5hY3Rpb24ucm9sZV9wZXJtaXNzaW9uc1tyb2xlXS5hY3Rpb25zW2pdID09IGlucHV0LmFjdGlvbgogICAgc29tZSBrCiAgICBkYXRhLm5vZGUuY29sbGFiLmFjdGlvbi5yb2xlX3Blcm1pc3Npb25zW3JvbGVdLnJlc291cmNlc1trXSA9PSBpbnB1dC50eXBlCn0KIyAgICAgICAqIFJlZ28gY29tcGFyaXNvbiB0byBvdGhlciBzeXN0ZW1zOiBodHRwczovL3d3dy5vcGVucG9saWN5YWdlbnQub3JnL2RvY3MvbGF0ZXN0L2NvbXBhcmlzb24tdG8tb3RoZXItc3lzdGVtcy8KIyAgICAgICAqIFJlZ28gSXRlcmF0aW9uOiBodHRwczovL3d3dy5vcGVucG9saWN5YWdlbnQub3JnL2RvY3MvbGF0ZXN0LyNpdGVyYXRpb24= - collab: cGFja2FnZSBjb2xsYWIKCmltcG9ydCByZWdvLnYxCmltcG9ydCBkYXRhLmNvbGxhYi5jb25mbGljdAppbXBvcnQgZGF0YS5jb2xsYWIuYWN0aW9uCgpkZWZhdWx0IGFsbG93IDo9IGZhbHNlCmFsbG93IGlmIHsKICAgIGNvbmZsaWN0LmFsbG93CiAgICBhY3Rpb24uYWxsb3cKfQ== - name: collab - version: 1.0.0 - metadata: - policy-id: collab - policy-version: 1.0.0 diff --git a/test/test_resources/policy_conflict.yaml b/test/test_resources/policy_conflict.yaml deleted file mode 100644 index 0406179..0000000 --- a/test/test_resources/policy_conflict.yaml +++ /dev/null @@ -1,15 +0,0 @@ -tosca_definitions_version: tosca_simple_yaml_1_1_0 -topology_template: - policies: - - conflict: - type: onap.policies.native.opa - type_version: 1.0.0 - properties: - data: - policy: - conflict: cGFja2FnZSBjb25mbGljdAoKaW1wb3J0IHJlZ28udjEKCmFsbG93IGlmIHsgaW5wdXQubmFtZSA9PSAiYWxpY2UiIH0KZGVueSBpZiB7IGlucHV0Lm5hbWUgPT0gImFsaWNlIiB9CgojIGRlbnkgZXZlcnl0aGluZyBieSBkZWZhdWx0CmRlZmF1bHQgYXV0aHogOj0gZmFsc2UKCiMgZGVueSBvdmVycmlkZXMgYWxsb3cKYXV0aHogaWYgewogICAgYWxsb3cKICAgIG5vdCBkZW55Cn0KCg== - name: conflict - version: 1.0.0 - metadata: - policy-id: conflict - policy-version: 1.0.0 diff --git a/test/test_resources/policy_deploy_single_policy.yaml b/test/test_resources/policy_deploy_single_policy.yaml deleted file mode 100644 index a2116fe..0000000 --- a/test/test_resources/policy_deploy_single_policy.yaml +++ /dev/null @@ -1,17 +0,0 @@ -tosca_definitions_version: tosca_simple_yaml_1_1_0 -topology_template: - policies: - - role: - type: onap.policies.native.opa - type_version: 1.0.0 - properties: - data: - node.role: ewogICAgInVzZXJfcm9sZXMiOiB7CiAgICAgICAgImFsaWNlIjogWwogICAgICAgICAgICAiYWRtaW4iCiAgICAgICAgXSwKICAgICAgICAiYm9iIjogWwogICAgICAgICAgICAiZW1wbG95ZWUiLAogICAgICAgICAgICAiYmlsbGluZyIKICAgICAgICBdLAogICAgICAgICJldmUiOiBbCiAgICAgICAgICAgICJjdXN0b21lciIKICAgICAgICBdCiAgICB9LAogICAgInJvbGVfZ3JhbnRzIjogewogICAgICAgICJjdXN0b21lciI6IFsKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgImFjdGlvbiI6ICJyZWFkIiwKICAgICAgICAgICAgICAgICJ0eXBlIjogImRvZyIKICAgICAgICAgICAgfSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgImFjdGlvbiI6ICJyZWFkIiwKICAgICAgICAgICAgICAgICJ0eXBlIjogImNhdCIKICAgICAgICAgICAgfSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgImFjdGlvbiI6ICJhZG9wdCIsCiAgICAgICAgICAgICAgICAidHlwZSI6ICJkb2ciCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICJhY3Rpb24iOiAiYWRvcHQiLAogICAgICAgICAgICAgICAgInR5cGUiOiAiY2F0IgogICAgICAgICAgICB9CiAgICAgICAgXSwKICAgICAgICAiZW1wbG95ZWUiOiBbCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICJhY3Rpb24iOiAicmVhZCIsCiAgICAgICAgICAgICAgICAidHlwZSI6ICJkb2ciCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICJhY3Rpb24iOiAicmVhZCIsCiAgICAgICAgICAgICAgICAidHlwZSI6ICJjYXQiCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICJhY3Rpb24iOiAidXBkYXRlIiwKICAgICAgICAgICAgICAgICJ0eXBlIjogImRvZyIKICAgICAgICAgICAgfSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgImFjdGlvbiI6ICJ1cGRhdGUiLAogICAgICAgICAgICAgICAgInR5cGUiOiAiY2F0IgogICAgICAgICAgICB9CiAgICAgICAgXSwKICAgICAgICAiYmlsbGluZyI6IFsKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgImFjdGlvbiI6ICJyZWFkIiwKICAgICAgICAgICAgICAgICJ0eXBlIjogImZpbmFuY2UiCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICJhY3Rpb24iOiAidXBkYXRlIiwKICAgICAgICAgICAgICAgICJ0eXBlIjogImZpbmFuY2UiCiAgICAgICAgICAgIH0KICAgICAgICBdCiAgICB9Cn0K - policy: - role: cGFja2FnZSByb2xlCgppbXBvcnQgcmVnby52MQoKIyBCeSBkZWZhdWx0LCBkZW55IHJlcXVlc3RzLgpkZWZhdWx0IGFsbG93IDo9IGZhbHNlCgojIEFsbG93IGFkbWlucyB0byBkbyBhbnl0aGluZy4KYWxsb3cgaWYgdXNlcl9pc19hZG1pbgoKIyBBbGxvdyB0aGUgYWN0aW9uIGlmIHRoZSB1c2VyIGlzIGdyYW50ZWQgcGVybWlzc2lvbiB0byBwZXJmb3JtIHRoZSBhY3Rpb24uCmFsbG93IGlmIHsKICAgICAgICAjIEZpbmQgZ3JhbnRzIGZvciB0aGUgdXNlci4KICAgICAgICBzb21lIGdyYW50IGluIHVzZXJfaXNfZ3JhbnRlZAoKICAgICAgICAjIENoZWNrIGlmIHRoZSBncmFudCBwZXJtaXRzIHRoZSBhY3Rpb24uCiAgICAgICAgaW5wdXQuYWN0aW9uID09IGdyYW50LmFjdGlvbgogICAgICAgIGlucHV0LnR5cGUgPT0gZ3JhbnQudHlwZQp9CgojIHVzZXJfaXNfYWRtaW4gaXMgdHJ1ZSBpZiAiYWRtaW4iIGlzIGFtb25nIHRoZSB1c2VyJ3Mgcm9sZXMgYXMgcGVyIGRhdGEudXNlcl9yb2xlcwp1c2VyX2lzX2FkbWluIGlmICJhZG1pbiIgaW4gZGF0YS5ub2RlLnJvbGUudXNlcl9yb2xlc1tpbnB1dC51c2VyXQoKIyB1c2VyX2lzX2dyYW50ZWQgaXMgYSBzZXQgb2YgZ3JhbnRzIGZvciB0aGUgdXNlciBpZGVudGlmaWVkIGluIHRoZSByZXF1ZXN0LgojIFRoZSBgZ3JhbnRgIHdpbGwgYmUgY29udGFpbmVkIGlmIHRoZSBzZXQgYHVzZXJfaXNfZ3JhbnRlZGAgZm9yIGV2ZXJ5Li4uCnVzZXJfaXNfZ3JhbnRlZCBjb250YWlucyBncmFudCBpZiB7CiAgICAgICAgIyBgcm9sZWAgYXNzaWduZWQgYW4gZWxlbWVudCBvZiB0aGUgdXNlcl9yb2xlcyBmb3IgdGhpcyB1c2VyLi4uCiAgICAgICAgc29tZSByb2xlIGluIGRhdGEubm9kZS5yb2xlLnVzZXJfcm9sZXNbaW5wdXQudXNlcl0KCiAgICAgICAgIyBgZ3JhbnRgIGFzc2lnbmVkIGEgc2luZ2xlIGdyYW50IGZyb20gdGhlIGdyYW50cyBsaXN0IGZvciAncm9sZScuLi4KICAgICAgICBzb21lIGdyYW50IGluIGRhdGEubm9kZS5yb2xlLnJvbGVfZ3JhbnRzW3JvbGVdCn0KCiMgICAgICAgKiBSZWdvIGNvbXBhcmlzb24gdG8gb3RoZXIgc3lzdGVtczogaHR0cHM6Ly93d3cub3BlbnBvbGljeWFnZW50Lm9yZy9kb2NzL2xhdGVzdC9jb21wYXJpc29uLXRvLW90aGVyLXN5c3RlbXMvCiMgICAgICAgKiBSZWdvIEl0ZXJhdGlvbjogaHR0cHM6Ly93d3cub3BlbnBvbGljeWFnZW50Lm9yZy9kb2NzL2xhdGVzdC8jaXRlcmF0aW9u - name: role - version: 1.0.0 - metadata: - policy-id: role - policy-version: 1.0.0 - diff --git a/test/test_resources/policy_zone.yaml b/test/test_resources/policy_zone.yaml deleted file mode 100644 index 2c99e9f..0000000 --- a/test/test_resources/policy_zone.yaml +++ /dev/null @@ -1,16 +0,0 @@ -tosca_definitions_version: tosca_simple_yaml_1_1_0 -topology_template: - policies: - - zone: - type: onap.policies.native.opa - type_version: 1.0.0 - properties: - data: - node.zone: ewogICJ6b25lIjogewogICAgInpvbmVfYWNjZXNzX2xvZ3MiOiBbCiAgICAgIHsgImxvZ19pZCI6ICJsb2cxIiwgInRpbWVzdGFtcCI6ICIyMDI0LTExLTAxVDA5OjAwOjAwWiIsICJ6b25lX2lkIjogInpvbmVBIiwgImFjY2VzcyI6ICJncmFudGVkIiwgInVzZXIiOiAidXNlcjEiIH0sCiAgICAgIHsgImxvZ19pZCI6ICJsb2cyIiwgInRpbWVzdGFtcCI6ICIyMDI0LTExLTAxVDEwOjMwOjAwWiIsICJ6b25lX2lkIjogInpvbmVBIiwgImFjY2VzcyI6ICJkZW5pZWQiLCAidXNlciI6ICJ1c2VyMiIgfSwKICAgICAgeyAibG9nX2lkIjogImxvZzMiLCAidGltZXN0YW1wIjogIjIwMjQtMTEtMDFUMTE6MDA6MDBaIiwgInpvbmVfaWQiOiAiem9uZUIiLCAiYWNjZXNzIjogImdyYW50ZWQiLCAidXNlciI6ICJ1c2VyMyIgfQogICAgXQogIH0KfQo= - policy: - zone : cGFja2FnZSB6b25lCgppbXBvcnQgcmVnby52MQoKZGVmYXVsdCBhbGxvdyA6PSBmYWxzZQoKYWxsb3cgaWYgewogICAgaGFzX3pvbmVfYWNjZXNzCiAgICBhY3Rpb25faXNfbG9nX3ZpZXcKfQoKYWN0aW9uX2lzX2xvZ192aWV3IGlmIHsKICAgICJ2aWV3IiBpbiBpbnB1dC5hY3Rpb25zCn0KCmhhc196b25lX2FjY2VzcyBjb250YWlucyBhY2Nlc3NfZGF0YSBpZiB7CiAgICBzb21lIHpvbmVfZGF0YSBpbiBkYXRhLm5vZGUuem9uZS56b25lLnpvbmVfYWNjZXNzX2xvZ3MKICAgIHpvbmVfZGF0YS50aW1lc3RhbXAgPj0gaW5wdXQudGltZV9wZXJpb2QuZnJvbQogICAgem9uZV9kYXRhLnRpbWVzdGFtcCA8IGlucHV0LnRpbWVfcGVyaW9kLnRvCiAgICB6b25lX2RhdGEuem9uZV9pZCA9PSBpbnB1dC56b25lX2lkCiAgICBhY2Nlc3NfZGF0YSA6PSB7ZGF0YXR5cGU6IHpvbmVfZGF0YVtkYXRhdHlwZV0gfCBkYXRhdHlwZSBpbiBpbnB1dC5kYXRhdHlwZXN9Cn0K - name: zone - version: 1.0.0 - metadata: - policy-id: zone - policy-version: 1.0.0 diff --git a/test/test_resources/undeploy_batch_delete.json b/test/test_resources/undeploy_batch_delete.json deleted file mode 100644 index 9195f74..0000000 --- a/test/test_resources/undeploy_batch_delete.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "groups": [ - { - "name": "opaGroup", - "deploymentSubgroups": [ - { - "pdpType": "opa", - "action": "DELETE", - "policies": [ - { - "name": "account", - "version": "1.0.0" - }, - { - "name": "organization", - "version": "1.0.0" - } - ] - } - ] - } - ] -} diff --git a/test/test_resources/deploy_conflict.json b/test/toscapolicies/access_method/deploy_access_method.json index 72d2fcd..4903c65 100644 --- a/test/test_resources/deploy_conflict.json +++ b/test/toscapolicies/access_method/deploy_access_method.json @@ -1,7 +1,7 @@ { "policies": [ { - "policy-id": "conflict", + "policy-id": "access_method", "policy-version": "1.0.0" } diff --git a/test/toscapolicies/access_method/policy_access_method.yaml b/test/toscapolicies/access_method/policy_access_method.yaml new file mode 100644 index 0000000..9b48637 --- /dev/null +++ b/test/toscapolicies/access_method/policy_access_method.yaml @@ -0,0 +1,15 @@ +tosca_definitions_version: tosca_simple_yaml_1_1_0 +topology_template: + policies: + - access_method: + type: onap.policies.native.opa + type_version: 1.0.0 + properties: + data: + policy: + access_method: cGFja2FnZSBhY2Nlc3NfbWV0aG9kCmltcG9ydCByZWdvLnYxCmFsbG93IGlmIHsKICAgICAgICBpbnB1dC5wYXRoID09IFsidXNlcnMiXQogICAgICAgIGlucHV0Lm1ldGhvZCA9PSAiUE9TVCIKfQoKYWxsb3cgaWYgewogICAgICAgIGlucHV0LnBhdGggPT0gWyJ1c2VycyIsIGlucHV0LnVzZXJfaWRdCiAgICAgICAgaW5wdXQubWV0aG9kID09ICJHRVQiCn0KCg== + name: access_method + version: 1.0.0 + metadata: + policy-id: access_method + policy-version: 1.0.0 diff --git a/test/test_resources/deploy_zone.json b/test/toscapolicies/blacklist/deploy_blacklist.json index 217457b..8daa958 100644 --- a/test/test_resources/deploy_zone.json +++ b/test/toscapolicies/blacklist/deploy_blacklist.json @@ -1,8 +1,7 @@ - { "policies": [ { - "policy-id": "zone", + "policy-id": "blacklist", "policy-version": "1.0.0" } diff --git a/test/toscapolicies/blacklist/policy_blacklist.yaml b/test/toscapolicies/blacklist/policy_blacklist.yaml new file mode 100644 index 0000000..2e2b15c --- /dev/null +++ b/test/toscapolicies/blacklist/policy_blacklist.yaml @@ -0,0 +1,18 @@ +tosca_definitions_version: tosca_simple_yaml_1_1_0 +topology_template: + policies: + - blacklist: + type: onap.policies.native.opa + type_version: 1.0.0 + properties: + data: + node.blacklist: ewogICAgImJsYWNrbGlzdCIgOiBbCiAgICAidGhlLXZmbW9kdWxlLXdoZXJlLXJvb3QtaXMtdHJ1ZSIsCiAgICAgImFub3RoZXItdmZtb2R1bGUtd2hlcmUtcm9vdC1pcy10cnVlIgpdCn0= + policy: + blacklist: + cGFja2FnZSBibGFja2xpc3QKaW1wb3J0IGZ1dHVyZS5rZXl3b3Jkcy5pbgppbXBvcnQgcmVnby52MQoKIyBEZWZpbmUgYSBydWxlIHRvIGNoZWNrIGlmIHRoZSBvcGVyYXRpb24gc2hvdWxkIGJlIGFsbG93ZWQKbW9kdWxlX2FsbG93W21vZHVsZV0gOj0gZmFsc2UgaWYgewogICAgc29tZSBtb2R1bGUgaW4gaW5wdXQudmZtb2R1bGUKICAgIG5vdCB2YWxpZGF0ZShtb2R1bGUpCn0KCm1vZHVsZV9hbGxvd1ttb2R1bGVdIDo9IHRydWUgaWZ7CiAgICAgICAgc29tZSBtb2R1bGUgaW4gaW5wdXQudmZtb2R1bGUKICAgIHZhbGlkYXRlKG1vZHVsZSkKfQoKdmFsaWRhdGUobW9kdWxlKSBpZiB7CiAgICAgICAgbW9kdWxlIGluIGRhdGEubm9kZS5ibGFja2xpc3QuYmxhY2tsaXN0Cn0= + name: blacklist + version: 1.0.0 + metadata: + policy-id: blacklist + policy-version: 1.0.0 + diff --git a/test/toscapolicies/cell/deploy_cell.json b/test/toscapolicies/cell/deploy_cell.json new file mode 100644 index 0000000..75a25bd --- /dev/null +++ b/test/toscapolicies/cell/deploy_cell.json @@ -0,0 +1,10 @@ +{ + "policies": [ + { + "policy-id": "cell.consistency", + "policy-version": "1.0.0" + + } + ] +} + diff --git a/test/toscapolicies/cell/policy_cell.yaml b/test/toscapolicies/cell/policy_cell.yaml new file mode 100644 index 0000000..3ab25db --- /dev/null +++ b/test/toscapolicies/cell/policy_cell.yaml @@ -0,0 +1,21 @@ +tosca_definitions_version: tosca_simple_yaml_1_1_0 +topology_template: + policies: + - cell.consistency: + type: onap.policies.native.opa + type_version: 1.0.0 + properties: + data: + node.cell.consistency: >- + eyAgIAogICJhbGxvd2VkQ2VsbElkIiA6IDQ0NTYxMTE5MzI2NTA0MDEyOSwgCiAgIm1pblBDSSI6IDEsIAogICJtYXhQQ0kiOiAzMDAwICAKIH0= + policy: + cell.consistency: >- + cGFja2FnZSBjZWxsLmNvbnNpc3RlbmN5CmRlZmF1bHQgYWxsb3cgPSBmYWxzZQojIFJ1bGUgdG8gY2hlY2sgY2VsbCBjb25zaXN0ZW5jeQpjaGVja19jZWxsX2NvbnNpc3RlbmN5IGlmIHsKICAgIGlucHV0LmNlbGwgIT0gZGF0YS5ub2RlLmNlbGwuY29uc2lzdGVuY3kuYWxsb3dlZENlbGxJZAp9CiMgUnVsZSB0byBhbGxvdyBpZiBQQ0kgaXMgd2l0aGluIHJhbmdlIDEtMzAwMAphbGxvd19pZl9wY2lfaW5fcmFuZ2UgaWYgewogICAgaW5wdXQuUENJID49IGRhdGEubm9kZS5jZWxsY29uc2lzdGVuY3kubWluUENJCiAgICBpbnB1dC5QQ0kgPD0gZGF0YS5ub2RlLmNlbGxjb25zaXN0ZW5jeS5tYXhQQ0kKfQojIE1haW4gcnVsZSB0byBkZXRlcm1pbmUgdGhlIGZpbmFsIGRlY2lzaW9uCmFsbG93IGlmIHsKICAgIGNoZWNrX2NlbGxfY29uc2lzdGVuY3kKICAgIGFsbG93X2lmX3BjaV9pbl9yYW5nZQp9 + cell.consistency.topology: >- + cGFja2FnZSBjZWxsLmNvbnNpc3RlbmN5LnRvcG9sb2d5CmltcG9ydCByZWdvLnYxCiMgUnVsZSB0byBjaGVjayBjZWxsIGNvbnNpc3RlbmN5CmNoZWNrX2NlbGxfY29uc2lzdGVuY3kgaWYgewogICAgaW5wdXQuY2VsbCAhPSBkYXRhLmNlbGxjb25zaXN0ZW5jeS5hbGxvd2VkQ2VsbElkCn0= + name: cell.consistency + version: 1.0.0 + metadata: + policy-id: cell.consistency + policy-version: 1.0.0 + diff --git a/test/test_resources/deploy_collab.json b/test/toscapolicies/monitor/deploy_monitor.json index 06d43c9..55a60cf 100644 --- a/test/test_resources/deploy_collab.json +++ b/test/toscapolicies/monitor/deploy_monitor.json @@ -1,7 +1,7 @@ { "policies": [ { - "policy-id": "collab", + "policy-id": "monitor", "policy-version": "1.0.0" } diff --git a/test/toscapolicies/monitor/policy_monitor.yaml b/test/toscapolicies/monitor/policy_monitor.yaml new file mode 100644 index 0000000..1dcc7ee --- /dev/null +++ b/test/toscapolicies/monitor/policy_monitor.yaml @@ -0,0 +1,16 @@ +tosca_definitions_version: tosca_simple_yaml_1_1_0 +topology_template: + policies: + - monitor: + type: onap.policies.native.opa + type_version: 1.0.0 + properties: + data: + node.monitor: eyAiZG9tYWluIjogIm1lYXN1cmVtZW50c0ZvclZmU2NhbGluZyIsCiAgIm1ldHJpY3NQZXJFdmVudE5hbWUiOiBbewogICAgICAgICAgImV2ZW50TmFtZSI6ICJNZWFzdXJlbWVudF92R01VWCIsCiAgICAgICAgICAiY29udHJvbExvb3BTY2hlbWFUeXBlIjogIlZORiIsCiAgICAgICAgICAicG9saWN5U2NvcGUiOiAiRENBRSIsCiAgICAgICAgICAicG9saWN5TmFtZSI6ICJEQ0FFLkNvbmZpZ190Y2EtaGktbG8iLAogICAgICAgICAgICJwb2xpY3lWZXJzaW9uIjogInYwLjAuMSIsCiAgICAgICAgICAgInRocmVzaG9sZHMiIDogW3sidmVyc2lvbiI6ICIxLjAuMiIsCiAgICAgICAgICAgICJjbG9zZWRMb29wQ29udHJvbE5hbWUiOiAiQ29udHJvbExvb3AtdkNQRS00OGYwYzJjMy1hMTcyLTQxOTItOWFlMy0wNTIyNzQxODFiNmUiLAogICAgICAgICAgICAidGhyZXNob2xkVmFsdWUiOiAwCiAgICAgICAgICAgICB9XQp9XQp9 + policy: + monitor: cGFja2FnZSBtb25pdG9yCgojIFBvbGljeSBhbGxvd3MgaWYgYSBtYXRjaGluZyB0aHJlc2hvbGQgaXMgbWV0CnJlc3VsdCBjb250YWlucyBvdXRwdXQgaWYgewogICAgaW5wdXQuZG9tYWluID0gZGF0YS5ub2RlLm1vbml0b3IuZG9tYWluCiAgICBzb21lIGV2ZW50cyAgaW4gZGF0YS5ub2RlLm1vbml0b3IubWV0cmljc1BlckV2ZW50TmFtZQogICAgZXZlbnRzLmV2ZW50TmFtZSA9PSBpbnB1dC5ldmVudE5hbWUKICAgIGV2ZW50cy5jb250cm9sTG9vcFNjaGVtYVR5cGUgPT0gaW5wdXQuY29udHJvbExvb3BTY2hlbWFUeXBlCiAgICBldmVudHMucG9saWN5U2NvcGUgPT0gaW5wdXQucG9saWN5U2NvcGUKICAgIGV2ZW50cy5wb2xpY3lOYW1lID09IGlucHV0LnBvbGljeU5hbWUKICAgIGV2ZW50cy5wb2xpY3lWZXJzaW9uID09IGlucHV0LnBvbGljeVZlcnNpb24KICAgIHNvbWUgdmFsdWUgaW4gZXZlbnRzLnRocmVzaG9sZHMKICAgIGlucHV0LmNvbnRyb2xuYW1lID09IHZhbHVlLmNsb3NlZExvb3BDb250cm9sTmFtZQogICAgaW5wdXQudmVyc2lvbiA9PSB2YWx1ZS52ZXJzaW9uCiAgICBpbnB1dC50aHJlc2hvbGRWYWx1ZSA9PSB2YWx1ZS50aHJlc2hvbGRWYWx1ZQogICAgb3V0cHV0IDo9IHsKICAgICAgICAic2V2ZXJpdHkiIDogIk1BSk9SIiwKICAgICAgICAiY2xvc2VkTG9vcEV2ZW50U3RhdHVzIiA6ICJBQkFURUQiCiAgICAgICAgfQp9CgojIFBvbGljeSBhbGxvd3MgaWYgYSBtYXRjaGluZyB0aHJlc2hvbGQgaXMgbWV0CnJlc3VsdCBjb250YWlucyBvdXRwdXQgaWYgewogICAgaW5wdXQuZG9tYWluID0gZGF0YS5ub2RlLm1vbml0b3IuZG9tYWluCiAgICBzb21lIGV2ZW50cyAgaW4gZGF0YS5ub2RlLm1vbml0b3IubWV0cmljc1BlckV2ZW50TmFtZQogICAgZXZlbnRzLmV2ZW50TmFtZSA9PSBpbnB1dC5ldmVudE5hbWUKICAgIGV2ZW50cy5jb250cm9sTG9vcFNjaGVtYVR5cGUgPT0gaW5wdXQuY29udHJvbExvb3BTY2hlbWFUeXBlCiAgICBldmVudHMucG9saWN5U2NvcGUgPT0gaW5wdXQucG9saWN5U2NvcGUKICAgIGV2ZW50cy5wb2xpY3lOYW1lID09IGlucHV0LnBvbGljeU5hbWUKICAgIGV2ZW50cy5wb2xpY3lWZXJzaW9uID09IGlucHV0LnBvbGljeVZlcnNpb24KICAgIHNvbWUgdmFsdWUgaW4gZXZlbnRzLnRocmVzaG9sZHMKICAgIGlucHV0LmNvbnRyb2xuYW1lID09IHZhbHVlLmNsb3NlZExvb3BDb250cm9sTmFtZQogICAgaW5wdXQudmVyc2lvbiA9PSB2YWx1ZS52ZXJzaW9uCiAgICBpbnB1dC50aHJlc2hvbGRWYWx1ZSA+IHZhbHVlLnRocmVzaG9sZFZhbHVlCiAgICBvdXRwdXQgOj0gewogICAgICAgICJzZXZlcml0eSIgOiAiQ1JJVElDQUwiLAogICAgICAgICJjbG9zZWRMb29wRXZlbnRTdGF0dXMiIDogIk9OU0VUIgogICAgICAgIH0KfQ== + name: monitor + version: 1.0.0 + metadata: + policy-id: monitor + policy-version: 1.0.0 diff --git a/test/test_resources/deploy.json b/test/toscapolicies/role/deploy_role.json index 2698286..2698286 100644 --- a/test/test_resources/deploy.json +++ b/test/toscapolicies/role/deploy_role.json diff --git a/test/toscapolicies/role/policy_role.yaml b/test/toscapolicies/role/policy_role.yaml new file mode 100644 index 0000000..aeb0da5 --- /dev/null +++ b/test/toscapolicies/role/policy_role.yaml @@ -0,0 +1,16 @@ +tosca_definitions_version: tosca_simple_yaml_1_1_0 +topology_template: + policies: + - role: + type: onap.policies.native.opa + type_version: 1.0.0 + properties: + data: + node.role: ewogICAgInVzZXJfcm9sZXMiOiB7CiAgICAgICAgImFsaWNlIjogWwogICAgICAgICAgICAiYWRtaW4iCiAgICAgICAgXSwKICAgICAgICAiYm9iIjogWwogICAgICAgICAgICAiZW1wbG95ZWUiLAogICAgICAgICAgICAiYmlsbGluZyIKICAgICAgICBdLAogICAgICAgICJldmUiOiBbCiAgICAgICAgICAgICJjdXN0b21lciIKICAgICAgICBdCiAgICB9LAogICAgInJvbGVfZ3JhbnRzIjogewogICAgICAgICJjdXN0b21lciI6IFsKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgImFjdGlvbiI6ICJyZWFkIiwKICAgICAgICAgICAgICAgICJ0eXBlIjogImRvZyIKICAgICAgICAgICAgfSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgImFjdGlvbiI6ICJyZWFkIiwKICAgICAgICAgICAgICAgICJ0eXBlIjogImNhdCIKICAgICAgICAgICAgfSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgImFjdGlvbiI6ICJhZG9wdCIsCiAgICAgICAgICAgICAgICAidHlwZSI6ICJkb2ciCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICJhY3Rpb24iOiAiYWRvcHQiLAogICAgICAgICAgICAgICAgInR5cGUiOiAiY2F0IgogICAgICAgICAgICB9CiAgICAgICAgXSwKICAgICAgICAiZW1wbG95ZWUiOiBbCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICJhY3Rpb24iOiAicmVhZCIsCiAgICAgICAgICAgICAgICAidHlwZSI6ICJkb2ciCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICJhY3Rpb24iOiAicmVhZCIsCiAgICAgICAgICAgICAgICAidHlwZSI6ICJjYXQiCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICJhY3Rpb24iOiAidXBkYXRlIiwKICAgICAgICAgICAgICAgICJ0eXBlIjogImRvZyIKICAgICAgICAgICAgfSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgImFjdGlvbiI6ICJ1cGRhdGUiLAogICAgICAgICAgICAgICAgInR5cGUiOiAiY2F0IgogICAgICAgICAgICB9CiAgICAgICAgXSwKICAgICAgICAiYmlsbGluZyI6IFsKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgImFjdGlvbiI6ICJyZWFkIiwKICAgICAgICAgICAgICAgICJ0eXBlIjogImZpbmFuY2UiCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICJhY3Rpb24iOiAidXBkYXRlIiwKICAgICAgICAgICAgICAgICJ0eXBlIjogImZpbmFuY2UiCiAgICAgICAgICAgIH0KICAgICAgICBdCiAgICB9Cn0KCg== + policy: + role : cGFja2FnZSByb2xlCgppbXBvcnQgcmVnby52MQoKIyBCeSBkZWZhdWx0LCBkZW55IHJlcXVlc3RzLgpkZWZhdWx0IGFsbG93IDo9IGZhbHNlCgojIEFsbG93IGFkbWlucyB0byBkbyBhbnl0aGluZy4KYWxsb3cgaWYgdXNlcl9pc19hZG1pbgoKIyBBbGxvdyB0aGUgYWN0aW9uIGlmIHRoZSB1c2VyIGlzIGdyYW50ZWQgcGVybWlzc2lvbiB0byBwZXJmb3JtIHRoZSBhY3Rpb24uCmFsbG93IGlmIHsKICAgICAgICAjIEZpbmQgZ3JhbnRzIGZvciB0aGUgdXNlci4KICAgICAgICBzb21lIGdyYW50IGluIHVzZXJfaXNfZ3JhbnRlZAoKICAgICAgICAjIENoZWNrIGlmIHRoZSBncmFudCBwZXJtaXRzIHRoZSBhY3Rpb24uCiAgICAgICAgaW5wdXQuYWN0aW9uID09IGdyYW50LmFjdGlvbgogICAgICAgIGlucHV0LnR5cGUgPT0gZ3JhbnQudHlwZQp9CgojIHVzZXJfaXNfYWRtaW4gaXMgdHJ1ZSBpZiAiYWRtaW4iIGlzIGFtb25nIHRoZSB1c2VyJ3Mgcm9sZXMgYXMgcGVyIGRhdGEudXNlcl9yb2xlcwp1c2VyX2lzX2FkbWluIGlmICJhZG1pbiIgaW4gZGF0YS5ub2RlLnJvbGUudXNlcl9yb2xlc1tpbnB1dC51c2VyXQoKIyB1c2VyX2lzX2dyYW50ZWQgaXMgYSBzZXQgb2YgZ3JhbnRzIGZvciB0aGUgdXNlciBpZGVudGlmaWVkIGluIHRoZSByZXF1ZXN0LgojIFRoZSBgZ3JhbnRgIHdpbGwgYmUgY29udGFpbmVkIGlmIHRoZSBzZXQgYHVzZXJfaXNfZ3JhbnRlZGAgZm9yIGV2ZXJ5Li4uCnVzZXJfaXNfZ3JhbnRlZCBjb250YWlucyBncmFudCBpZiB7CiAgICAgICAgIyBgcm9sZWAgYXNzaWduZWQgYW4gZWxlbWVudCBvZiB0aGUgdXNlcl9yb2xlcyBmb3IgdGhpcyB1c2VyLi4uCiAgICAgICAgc29tZSByb2xlIGluIGRhdGEubm9kZS5yb2xlLnVzZXJfcm9sZXNbaW5wdXQudXNlcl0KCiAgICAgICAgIyBgZ3JhbnRgIGFzc2lnbmVkIGEgc2luZ2xlIGdyYW50IGZyb20gdGhlIGdyYW50cyBsaXN0IGZvciAncm9sZScuLi4KICAgICAgICBzb21lIGdyYW50IGluIGRhdGEubm9kZS5yb2xlLnJvbGVfZ3JhbnRzW3JvbGVdCn0KCiMgICAgICAgKiBSZWdvIGNvbXBhcmlzb24gdG8gb3RoZXIgc3lzdGVtczogaHR0cHM6Ly93d3cub3BlbnBvbGljeWFnZW50Lm9yZy9kb2NzL2xhdGVzdC9jb21wYXJpc29uLXRvLW90aGVyLXN5c3RlbXMvCiMgICAgICAgKiBSZWdvIEl0ZXJhdGlvbjogaHR0cHM6Ly93d3cub3BlbnBvbGljeWFnZW50Lm9yZy9kb2NzL2xhdGVzdC8jaXRlcmF0aW9uCg== + name: role + version: 1.0.0 + metadata: + policy-id: role + policy-version: 1.0.0 diff --git a/test/wait_for_port.sh b/test/wait_for_port.sh deleted file mode 100644 index b29102b..0000000 --- a/test/wait_for_port.sh +++ /dev/null @@ -1,91 +0,0 @@ -#!/bin/sh -# ============LICENSE_START==================================================== -# Copyright (C) 2021 AT&T Intellectual Property. All rights reserved. -# Modifications Copyright (C) 2022-2023 Nordix Foundation. -# ============================================================================= -# 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. -# -# SPDX-License-Identifier: Apache-2.0 -# ============LICENSE_END====================================================== - -usage() { - echo args: [-t timeout] [-c command] hostname1 port1 hostname2 port2 ... >&2 - exit 1 -} - -tmout=300 -cmd= -while getopts c:t: opt -do - case "$opt" in - c) - cmd="$OPTARG" - ;; - - t) - tmout="$OPTARG" - ;; - - *) - usage - ;; - esac -done - -nargs=$((OPTIND-1)) -shift "$nargs" - -even_args=$(($#%2)) -if [ $# -lt 2 ] || [ "$even_args" -ne 0 ] -then - usage -fi - -while [ $# -ge 2 ] -do - export host="$1" - export port="$2" - shift - shift - - echo "Waiting for $host port $port..." - - while [ "$tmout" -gt 0 ] - do - if command -v docker > /dev/null 2>&1 - then - docker ps --format "table {{ .Names }}\t{{ .Status }}" - fi - - nc -vz "$host" "$port" - rc=$? - - if [ $rc -eq 0 ] - then - break - else - tmout=$((tmout-1)) - sleep 1 - fi - done - - if [ $rc -ne 0 ] - then - echo "$host port $port cannot be reached" - exit $rc - fi -done -#sh scripts.sh -$cmd - -exit 0 diff --git a/testsuites/performance/src/main/resources/testplans/perf.jmx b/testsuites/performance/src/main/resources/testplans/perf.jmx index 0152066..3cee27a 100644 --- a/testsuites/performance/src/main/resources/testplans/perf.jmx +++ b/testsuites/performance/src/main/resources/testplans/perf.jmx @@ -31,8 +31,8 @@ <stringProp name="Argument.value">localhost</stringProp> <stringProp name="Argument.metadata">=</stringProp> </elementProp> - <elementProp name="OPA_PDP_HOST" elementType="Argument"> - <stringProp name="Argument.name">OPA_PDP_HOST</stringProp> + <elementProp name="OPA_HOST" elementType="Argument"> + <stringProp name="Argument.name">OPA_HOST</stringProp> <stringProp name="Argument.value">localhost</stringProp> <stringProp name="Argument.metadata">=</stringProp> </elementProp> @@ -46,9 +46,9 @@ <stringProp name="Argument.value">${__P(pap_port, 30003)}</stringProp> <stringProp name="Argument.metadata">=</stringProp> </elementProp> - <elementProp name="OPA_PDP_PORT" elementType="Argument"> - <stringProp name="Argument.name">OPA_PDP_PORT</stringProp> - <stringProp name="Argument.value">${__P(opa_pdp_port, 30012)}</stringProp> + <elementProp name="OPA_PORT" elementType="Argument"> + <stringProp name="Argument.name">OPA_PORT</stringProp> + <stringProp name="Argument.value">${__P(opa_port, 30012)}</stringProp> <stringProp name="Argument.metadata">=</stringProp> </elementProp> <elementProp name="API_USER" elementType="Argument"> @@ -61,8 +61,8 @@ <stringProp name="Argument.value">policyadmin</stringProp> <stringProp name="Argument.metadata">=</stringProp> </elementProp> - <elementProp name="OPA_PDP_USER" elementType="Argument"> - <stringProp name="Argument.name">OPA_PDP_USER</stringProp> + <elementProp name="OPA_USER" elementType="Argument"> + <stringProp name="Argument.name">OPA_USER</stringProp> <stringProp name="Argument.value">policyadmin</stringProp> <stringProp name="Argument.metadata">=</stringProp> </elementProp> @@ -76,13 +76,15 @@ <stringProp name="Argument.value">zb!XztG34</stringProp> <stringProp name="Argument.metadata">=</stringProp> </elementProp> - <elementProp name="OPA_PDP_PASSWORD" elementType="Argument"> - <stringProp name="Argument.name">OPA_PDP_PASSWORD</stringProp> + <elementProp name="OPA_PASSWORD" elementType="Argument"> + <stringProp name="Argument.name">OPA_PASSWORD</stringProp> <stringProp name="Argument.value">zb!XztG34</stringProp> <stringProp name="Argument.metadata">=</stringProp> </elementProp> </collectionProp> </elementProp> + <boolProp name="TestPlan.functional_mode">false</boolProp> + <boolProp name="TestPlan.serialize_threadgroups">false</boolProp> </TestPlan> <hashTree> <HeaderManager guiclass="HeaderPanel" testclass="HeaderManager" testname="HTTP Header Manager"> @@ -98,7 +100,599 @@ </collectionProp> </HeaderManager> <hashTree/> - <ThreadGroup guiclass="ThreadGroupGui" testclass="ThreadGroup" testname="Policy OPA PDP Health Check" enabled="true"> + <SetupThreadGroup guiclass="SetupThreadGroupGui" testclass="SetupThreadGroup" testname="setUp Thread Group" enabled="true"> + <intProp name="ThreadGroup.num_threads">1</intProp> + <intProp name="ThreadGroup.ramp_time">1</intProp> + <boolProp name="ThreadGroup.same_user_on_next_iteration">true</boolProp> + <stringProp name="ThreadGroup.on_sample_error">continue</stringProp> + <elementProp name="ThreadGroup.main_controller" elementType="LoopController" guiclass="LoopControlPanel" testclass="LoopController" testname="Loop Controller"> + <stringProp name="LoopController.loops">1</stringProp> + <boolProp name="LoopController.continue_forever">false</boolProp> + </elementProp> + </SetupThreadGroup> + <hashTree> + <HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="Create Role Policy"> + <intProp name="HTTPSampler.concurrentPool">6</intProp> + <stringProp name="HTTPSampler.domain">${API_HOST}</stringProp> + <stringProp name="HTTPSampler.port">${API_PORT}</stringProp> + <stringProp name="HTTPSampler.protocol">${HTTP}</stringProp> + <stringProp name="HTTPSampler.path">policy/api/v1/policytypes/onap.policies.native.opa/versions/1.0.0/policies</stringProp> + <boolProp name="HTTPSampler.follow_redirects">true</boolProp> + <stringProp name="HTTPSampler.method">POST</stringProp> + <boolProp name="HTTPSampler.use_keepalive">true</boolProp> + <boolProp name="HTTPSampler.postBodyRaw">true</boolProp> + <elementProp name="HTTPsampler.Arguments" elementType="Arguments"> + <collectionProp name="Arguments.arguments"> + <elementProp name="" elementType="HTTPArgument"> + <boolProp name="HTTPArgument.always_encode">false</boolProp> + <stringProp name="Argument.value">tosca_definitions_version: tosca_simple_yaml_1_1_0
 +topology_template:
 + policies:
 + - role:
 + type: onap.policies.native.opa
 + type_version: 1.0.0
 + properties:
 + data:
 + node.role: ewogICAgInVzZXJfcm9sZXMiOiB7CiAgICAgICAgImFsaWNlIjogWwogICAgICAgICAgICAiYWRtaW4iCiAgICAgICAgXSwKICAgICAgICAiYm9iIjogWwogICAgICAgICAgICAiZW1wbG95ZWUiLAogICAgICAgICAgICAiYmlsbGluZyIKICAgICAgICBdLAogICAgICAgICJldmUiOiBbCiAgICAgICAgICAgICJjdXN0b21lciIKICAgICAgICBdCiAgICB9LAogICAgInJvbGVfZ3JhbnRzIjogewogICAgICAgICJjdXN0b21lciI6IFsKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgImFjdGlvbiI6ICJyZWFkIiwKICAgICAgICAgICAgICAgICJ0eXBlIjogImRvZyIKICAgICAgICAgICAgfSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgImFjdGlvbiI6ICJyZWFkIiwKICAgICAgICAgICAgICAgICJ0eXBlIjogImNhdCIKICAgICAgICAgICAgfSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgImFjdGlvbiI6ICJhZG9wdCIsCiAgICAgICAgICAgICAgICAidHlwZSI6ICJkb2ciCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICJhY3Rpb24iOiAiYWRvcHQiLAogICAgICAgICAgICAgICAgInR5cGUiOiAiY2F0IgogICAgICAgICAgICB9CiAgICAgICAgXSwKICAgICAgICAiZW1wbG95ZWUiOiBbCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICJhY3Rpb24iOiAicmVhZCIsCiAgICAgICAgICAgICAgICAidHlwZSI6ICJkb2ciCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICJhY3Rpb24iOiAicmVhZCIsCiAgICAgICAgICAgICAgICAidHlwZSI6ICJjYXQiCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICJhY3Rpb24iOiAidXBkYXRlIiwKICAgICAgICAgICAgICAgICJ0eXBlIjogImRvZyIKICAgICAgICAgICAgfSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgImFjdGlvbiI6ICJ1cGRhdGUiLAogICAgICAgICAgICAgICAgInR5cGUiOiAiY2F0IgogICAgICAgICAgICB9CiAgICAgICAgXSwKICAgICAgICAiYmlsbGluZyI6IFsKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgImFjdGlvbiI6ICJyZWFkIiwKICAgICAgICAgICAgICAgICJ0eXBlIjogImZpbmFuY2UiCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICJhY3Rpb24iOiAidXBkYXRlIiwKICAgICAgICAgICAgICAgICJ0eXBlIjogImZpbmFuY2UiCiAgICAgICAgICAgIH0KICAgICAgICBdCiAgICB9Cn0K
 + policy:
 + role: cGFja2FnZSByb2xlCgppbXBvcnQgcmVnby52MQoKIyBCeSBkZWZhdWx0LCBkZW55IHJlcXVlc3RzLgpkZWZhdWx0IGFsbG93IDo9IGZhbHNlCgojIEFsbG93IGFkbWlucyB0byBkbyBhbnl0aGluZy4KYWxsb3cgaWYgdXNlcl9pc19hZG1pbgoKIyBBbGxvdyB0aGUgYWN0aW9uIGlmIHRoZSB1c2VyIGlzIGdyYW50ZWQgcGVybWlzc2lvbiB0byBwZXJmb3JtIHRoZSBhY3Rpb24uCmFsbG93IGlmIHsKICAgICAgICAjIEZpbmQgZ3JhbnRzIGZvciB0aGUgdXNlci4KICAgICAgICBzb21lIGdyYW50IGluIHVzZXJfaXNfZ3JhbnRlZAoKICAgICAgICAjIENoZWNrIGlmIHRoZSBncmFudCBwZXJtaXRzIHRoZSBhY3Rpb24uCiAgICAgICAgaW5wdXQuYWN0aW9uID09IGdyYW50LmFjdGlvbgogICAgICAgIGlucHV0LnR5cGUgPT0gZ3JhbnQudHlwZQp9CgojIHVzZXJfaXNfYWRtaW4gaXMgdHJ1ZSBpZiAiYWRtaW4iIGlzIGFtb25nIHRoZSB1c2VyJ3Mgcm9sZXMgYXMgcGVyIGRhdGEudXNlcl9yb2xlcwp1c2VyX2lzX2FkbWluIGlmICJhZG1pbiIgaW4gZGF0YS5ub2RlLnJvbGUudXNlcl9yb2xlc1tpbnB1dC51c2VyXQoKIyB1c2VyX2lzX2dyYW50ZWQgaXMgYSBzZXQgb2YgZ3JhbnRzIGZvciB0aGUgdXNlciBpZGVudGlmaWVkIGluIHRoZSByZXF1ZXN0LgojIFRoZSBgZ3JhbnRgIHdpbGwgYmUgY29udGFpbmVkIGlmIHRoZSBzZXQgYHVzZXJfaXNfZ3JhbnRlZGAgZm9yIGV2ZXJ5Li4uCnVzZXJfaXNfZ3JhbnRlZCBjb250YWlucyBncmFudCBpZiB7CiAgICAgICAgIyBgcm9sZWAgYXNzaWduZWQgYW4gZWxlbWVudCBvZiB0aGUgdXNlcl9yb2xlcyBmb3IgdGhpcyB1c2VyLi4uCiAgICAgICAgc29tZSByb2xlIGluIGRhdGEubm9kZS5yb2xlLnVzZXJfcm9sZXNbaW5wdXQudXNlcl0KCiAgICAgICAgIyBgZ3JhbnRgIGFzc2lnbmVkIGEgc2luZ2xlIGdyYW50IGZyb20gdGhlIGdyYW50cyBsaXN0IGZvciAncm9sZScuLi4KICAgICAgICBzb21lIGdyYW50IGluIGRhdGEubm9kZS5yb2xlLnJvbGVfZ3JhbnRzW3JvbGVdCn0KCiMgICAgICAgKiBSZWdvIGNvbXBhcmlzb24gdG8gb3RoZXIgc3lzdGVtczogaHR0cHM6Ly93d3cub3BlbnBvbGljeWFnZW50Lm9yZy9kb2NzL2xhdGVzdC9jb21wYXJpc29uLXRvLW90aGVyLXN5c3RlbXMvCiMgICAgICAgKiBSZWdvIEl0ZXJhdGlvbjogaHR0cHM6Ly93d3cub3BlbnBvbGljeWFnZW50Lm9yZy9kb2NzL2xhdGVzdC8jaXRlcmF0aW9u
 + name: role
 + version: 1.0.0
 + metadata:
 + policy-id: role
 + policy-version: 1.0.0
 +
 +
 +</stringProp> + <stringProp name="Argument.metadata">=</stringProp> + </elementProp> + </collectionProp> + </elementProp> + </HTTPSamplerProxy> + <hashTree> + <AuthManager guiclass="AuthPanel" testclass="AuthManager" testname="HTTP Authorization Manager" enabled="true"> + <collectionProp name="AuthManager.auth_list"> + <elementProp name="" elementType="Authorization"> + <stringProp name="Authorization.url">${HTTP}://${API_HOST}:${API_PORT}/policy/api/v1</stringProp> + <stringProp name="Authorization.username">${API_USER}</stringProp> + <stringProp name="Authorization.password">${API_PASSWORD}</stringProp> + <stringProp name="Authorization.domain"></stringProp> + <stringProp name="Authorization.realm"></stringProp> + </elementProp> + </collectionProp> + <boolProp name="AuthManager.clearEachIteration">true</boolProp> + <boolProp name="AuthManager.controlledByThreadGroup">false</boolProp> + </AuthManager> + <hashTree/> + <HeaderManager guiclass="HeaderPanel" testclass="HeaderManager" testname="HTTP Header Manager" enabled="true"> + <collectionProp name="HeaderManager.headers"> + <elementProp name="" elementType="Header"> + <stringProp name="Header.name">Content-Type</stringProp> + <stringProp name="Header.value">application/yaml</stringProp> + </elementProp> + </collectionProp> + </HeaderManager> + <hashTree/> + <ResponseAssertion guiclass="AssertionGui" testclass="ResponseAssertion" testname="Response Assertion" enabled="true"> + <collectionProp name="Asserion.test_strings"> + <stringProp name="49587">201</stringProp> + </collectionProp> + <stringProp name="Assertion.custom_message"></stringProp> + <stringProp name="Assertion.test_field">Assertion.response_code</stringProp> + <boolProp name="Assertion.assume_success">false</boolProp> + <intProp name="Assertion.test_type">8</intProp> + </ResponseAssertion> + <hashTree/> + </hashTree> + <HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="Create Collab Policy" enabled="true"> + <intProp name="HTTPSampler.concurrentPool">6</intProp> + <stringProp name="HTTPSampler.domain">${API_HOST}</stringProp> + <stringProp name="HTTPSampler.port">${API_PORT}</stringProp> + <stringProp name="HTTPSampler.protocol">${HTTP}</stringProp> + <stringProp name="HTTPSampler.path">policy/api/v1/policytypes/onap.policies.native.opa/versions/1.0.0/policies</stringProp> + <boolProp name="HTTPSampler.follow_redirects">true</boolProp> + <stringProp name="HTTPSampler.method">POST</stringProp> + <boolProp name="HTTPSampler.use_keepalive">true</boolProp> + <boolProp name="HTTPSampler.postBodyRaw">true</boolProp> + <elementProp name="HTTPsampler.Arguments" elementType="Arguments"> + <collectionProp name="Arguments.arguments"> + <elementProp name="" elementType="HTTPArgument"> + <boolProp name="HTTPArgument.always_encode">false</boolProp> + <stringProp name="Argument.value">tosca_definitions_version: tosca_simple_yaml_1_1_0
 +topology_template:
 + policies:
 + - collab:
 + type: onap.policies.native.opa
 + type_version: 1.0.0
 + properties:
 + data:
 + node.collab.action: ewogICAgInVzZXJfcm9sZXMiOiB7CiAgICAgICAgImFsaWNlIjogWwogICAgICAgICAgICAiYWRtaW4iCiAgICAgICAgXSwKICAgICAgICAiYm9iIjogWwogICAgICAgICAgICAiZWRpdG9yIgogICAgICAgIF0sCiAgICAgICAgImNoYXJsaWUiOiBbCiAgICAgICAgICAgICJ2aWV3ZXIiCiAgICAgICAgXQogICAgfSwKICAgICJyb2xlX3Blcm1pc3Npb25zIjogewogICAgICAgICJhZG1pbiI6IHsKICAgICAgICAgICAgImFjdGlvbnMiOiBbCiAgICAgICAgICAgICAgICAicmVhZCIsCiAgICAgICAgICAgICAgICAid3JpdGUiLAogICAgICAgICAgICAgICAgImRlbGV0ZSIKICAgICAgICAgICAgXSwKICAgICAgICAgICAgInJlc291cmNlcyI6IFsKICAgICAgICAgICAgICAgICJzZXJ2ZXIiLAogICAgICAgICAgICAgICAgImRhdGFiYXNlIgogICAgICAgICAgICBdCiAgICAgICAgfSwKICAgICAgICAiZWRpdG9yIjogewogICAgICAgICAgICAiYWN0aW9ucyI6IFsKICAgICAgICAgICAgICAgICJyZWFkIiwKICAgICAgICAgICAgICAgICJ3cml0ZSIKICAgICAgICAgICAgXSwKICAgICAgICAgICAgInJlc291cmNlcyI6IFsKICAgICAgICAgICAgICAgICJzZXJ2ZXIiCiAgICAgICAgICAgIF0KICAgICAgICB9LAogICAgICAgICJ2aWV3ZXIiOiB7CiAgICAgICAgICAgICJhY3Rpb25zIjogWwogICAgICAgICAgICAgICAgInJlYWQiCiAgICAgICAgICAgIF0sCiAgICAgICAgICAgICJyZXNvdXJjZXMiOiBbCiAgICAgICAgICAgICAgICAic2VydmVyIgogICAgICAgICAgICBdCiAgICAgICAgfQogICAgfQp9
 + policy:
 + collab.conflict: cGFja2FnZSBjb2xsYWIuY29uZmxpY3QKCmltcG9ydCByZWdvLnYxCgphbGxvdyBpZiB7IGlucHV0Lm5hbWUgPT0gImFsaWNlIiB9CmRlbnkgaWYgeyBpbnB1dC5uYW1lID09ICJhbGljZSIgfQoKIyBkZW55IGV2ZXJ5dGhpbmcgYnkgZGVmYXVsdApkZWZhdWx0IGF1dGh6IDo9IGZhbHNlCgojIGRlbnkgb3ZlcnJpZGVzIGFsbG93CmF1dGh6IGlmIHsKICAgIGFsbG93CiAgICBub3QgZGVueQp9Cg==
 + collab.action: cGFja2FnZSBjb2xsYWIuYWN0aW9uCgppbXBvcnQgcmVnby52MQoKIyBCeSBkZWZhdWx0LCBkZW55IHJlcXVlc3RzLgpkZWZhdWx0IGFsbG93IDo9IGZhbHNlCgoKIyBBbGxvdyB0aGUgYWN0aW9uIGlmIGFkbWluIHJvbGUgaXMgZ3JhbnRlZCBwZXJtaXNzaW9uIHRvIHBlcmZvcm0gdGhlIGFjdGlvbi4KYWxsb3cgaWYgewogICAgc29tZSBpCiAgICBkYXRhLm5vZGUuY29sbGFiLmFjdGlvbi51c2VyX3JvbGVzW2lucHV0LnVzZXJdW2ldID09IHJvbGUKICAgIHNvbWUgagogICAgZGF0YS5ub2RlLmNvbGxhYi5hY3Rpb24ucm9sZV9wZXJtaXNzaW9uc1tyb2xlXS5hY3Rpb25zW2pdID09IGlucHV0LmFjdGlvbgogICAgc29tZSBrCiAgICBkYXRhLm5vZGUuY29sbGFiLmFjdGlvbi5yb2xlX3Blcm1pc3Npb25zW3JvbGVdLnJlc291cmNlc1trXSA9PSBpbnB1dC50eXBlCn0KIyAgICAgICAqIFJlZ28gY29tcGFyaXNvbiB0byBvdGhlciBzeXN0ZW1zOiBodHRwczovL3d3dy5vcGVucG9saWN5YWdlbnQub3JnL2RvY3MvbGF0ZXN0L2NvbXBhcmlzb24tdG8tb3RoZXItc3lzdGVtcy8KIyAgICAgICAqIFJlZ28gSXRlcmF0aW9uOiBodHRwczovL3d3dy5vcGVucG9saWN5YWdlbnQub3JnL2RvY3MvbGF0ZXN0LyNpdGVyYXRpb24=
 + collab: cGFja2FnZSBjb2xsYWIKCmltcG9ydCByZWdvLnYxCmltcG9ydCBkYXRhLmNvbGxhYi5jb25mbGljdAppbXBvcnQgZGF0YS5jb2xsYWIuYWN0aW9uCgpkZWZhdWx0IGFsbG93IDo9IGZhbHNlCmFsbG93IGlmIHsKICAgIGNvbmZsaWN0LmFsbG93CiAgICBhY3Rpb24uYWxsb3cKfQ==
 + name: collab
 + version: 1.0.0
 + metadata:
 + policy-id: collab
 + policy-version: 1.0.0
 +</stringProp> + <stringProp name="Argument.metadata">=</stringProp> + </elementProp> + </collectionProp> + </elementProp> + </HTTPSamplerProxy> + <hashTree> + <AuthManager guiclass="AuthPanel" testclass="AuthManager" testname="HTTP Authorization Manager" enabled="true"> + <collectionProp name="AuthManager.auth_list"> + <elementProp name="" elementType="Authorization"> + <stringProp name="Authorization.url">${HTTP}://${API_HOST}:${API_PORT}/policy/api/v1</stringProp> + <stringProp name="Authorization.username">${API_USER}</stringProp> + <stringProp name="Authorization.password">${API_PASSWORD}</stringProp> + <stringProp name="Authorization.domain"></stringProp> + <stringProp name="Authorization.realm"></stringProp> + </elementProp> + </collectionProp> + <boolProp name="AuthManager.clearEachIteration">true</boolProp> + <boolProp name="AuthManager.controlledByThreadGroup">false</boolProp> + </AuthManager> + <hashTree/> + <HeaderManager guiclass="HeaderPanel" testclass="HeaderManager" testname="HTTP Header Manager" enabled="true"> + <collectionProp name="HeaderManager.headers"> + <elementProp name="" elementType="Header"> + <stringProp name="Header.name">Content-Type</stringProp> + <stringProp name="Header.value">application/yaml</stringProp> + </elementProp> + </collectionProp> + </HeaderManager> + <hashTree/> + <ResponseAssertion guiclass="AssertionGui" testclass="ResponseAssertion" testname="Response Assertion" enabled="true"> + <collectionProp name="Asserion.test_strings"> + <stringProp name="49587">201</stringProp> + </collectionProp> + <stringProp name="Assertion.custom_message"></stringProp> + <stringProp name="Assertion.test_field">Assertion.response_code</stringProp> + <boolProp name="Assertion.assume_success">false</boolProp> + <intProp name="Assertion.test_type">8</intProp> + </ResponseAssertion> + <hashTree/> + </hashTree> + <HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="Create Conflict Policy" enabled="true"> + <intProp name="HTTPSampler.concurrentPool">6</intProp> + <stringProp name="HTTPSampler.domain">${API_HOST}</stringProp> + <stringProp name="HTTPSampler.port">${API_PORT}</stringProp> + <stringProp name="HTTPSampler.protocol">${HTTP}</stringProp> + <stringProp name="HTTPSampler.path">policy/api/v1/policytypes/onap.policies.native.opa/versions/1.0.0/policies</stringProp> + <boolProp name="HTTPSampler.follow_redirects">true</boolProp> + <stringProp name="HTTPSampler.method">POST</stringProp> + <boolProp name="HTTPSampler.use_keepalive">true</boolProp> + <boolProp name="HTTPSampler.postBodyRaw">true</boolProp> + <elementProp name="HTTPsampler.Arguments" elementType="Arguments"> + <collectionProp name="Arguments.arguments"> + <elementProp name="" elementType="HTTPArgument"> + <boolProp name="HTTPArgument.always_encode">false</boolProp> + <stringProp name="Argument.value">tosca_definitions_version: tosca_simple_yaml_1_1_0
 +topology_template:
 + policies:
 + - conflict:
 + type: onap.policies.native.opa
 + type_version: 1.0.0
 + properties:
 + data:
 + policy:
 + conflict: cGFja2FnZSBjb25mbGljdAoKaW1wb3J0IHJlZ28udjEKCmFsbG93IGlmIHsgaW5wdXQubmFtZSA9PSAiYWxpY2UiIH0KZGVueSBpZiB7IGlucHV0Lm5hbWUgPT0gImFsaWNlIiB9CgojIGRlbnkgZXZlcnl0aGluZyBieSBkZWZhdWx0CmRlZmF1bHQgYXV0aHogOj0gZmFsc2UKCiMgZGVueSBvdmVycmlkZXMgYWxsb3cKYXV0aHogaWYgewogICAgYWxsb3cKICAgIG5vdCBkZW55Cn0KCg==
 + name: conflict
 + version: 1.0.0
 + metadata:
 + policy-id: conflict
 + policy-version: 1.0.0
 +</stringProp> + <stringProp name="Argument.metadata">=</stringProp> + </elementProp> + </collectionProp> + </elementProp> + </HTTPSamplerProxy> + <hashTree> + <AuthManager guiclass="AuthPanel" testclass="AuthManager" testname="HTTP Authorization Manager" enabled="true"> + <collectionProp name="AuthManager.auth_list"> + <elementProp name="" elementType="Authorization"> + <stringProp name="Authorization.url">${HTTP}://${API_HOST}:${API_PORT}/policy/api/v1</stringProp> + <stringProp name="Authorization.username">${API_USER}</stringProp> + <stringProp name="Authorization.password">${API_PASSWORD}</stringProp> + <stringProp name="Authorization.domain"></stringProp> + <stringProp name="Authorization.realm"></stringProp> + </elementProp> + </collectionProp> + <boolProp name="AuthManager.clearEachIteration">true</boolProp> + <boolProp name="AuthManager.controlledByThreadGroup">false</boolProp> + </AuthManager> + <hashTree/> + <HeaderManager guiclass="HeaderPanel" testclass="HeaderManager" testname="HTTP Header Manager" enabled="true"> + <collectionProp name="HeaderManager.headers"> + <elementProp name="" elementType="Header"> + <stringProp name="Header.name">Content-Type</stringProp> + <stringProp name="Header.value">application/yaml</stringProp> + </elementProp> + </collectionProp> + </HeaderManager> + <hashTree/> + <ResponseAssertion guiclass="AssertionGui" testclass="ResponseAssertion" testname="Response Assertion" enabled="true"> + <collectionProp name="Asserion.test_strings"> + <stringProp name="49587">201</stringProp> + </collectionProp> + <stringProp name="Assertion.custom_message"></stringProp> + <stringProp name="Assertion.test_field">Assertion.response_code</stringProp> + <boolProp name="Assertion.assume_success">false</boolProp> + <intProp name="Assertion.test_type">8</intProp> + </ResponseAssertion> + <hashTree/> + </hashTree> + <HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="Create Zone Policy" enabled="true"> + <intProp name="HTTPSampler.concurrentPool">6</intProp> + <stringProp name="HTTPSampler.domain">${API_HOST}</stringProp> + <stringProp name="HTTPSampler.port">${API_PORT}</stringProp> + <stringProp name="HTTPSampler.protocol">${HTTP}</stringProp> + <stringProp name="HTTPSampler.path">policy/api/v1/policytypes/onap.policies.native.opa/versions/1.0.0/policies</stringProp> + <boolProp name="HTTPSampler.follow_redirects">true</boolProp> + <stringProp name="HTTPSampler.method">POST</stringProp> + <boolProp name="HTTPSampler.use_keepalive">true</boolProp> + <boolProp name="HTTPSampler.postBodyRaw">true</boolProp> + <elementProp name="HTTPsampler.Arguments" elementType="Arguments"> + <collectionProp name="Arguments.arguments"> + <elementProp name="" elementType="HTTPArgument"> + <boolProp name="HTTPArgument.always_encode">false</boolProp> + <stringProp name="Argument.value">tosca_definitions_version: tosca_simple_yaml_1_1_0
 +topology_template:
 + policies:
 + - zone:
 + type: onap.policies.native.opa
 + type_version: 1.0.0
 + properties:
 + data:
 + node.zone: ewogICAgInpvbmVfYWNjZXNzX2xvZ3MiOiBbCiAgICAgIHsgImxvZ19pZCI6ICJsb2cxIiwgInRpbWVzdGFtcCI6ICIyMDI0LTExLTAxVDA5OjAwOjAwWiIsICJ6b25lX2lkIjogInpvbmVBIiwgImFjY2VzcyI6ICJncmFudGVkIiwgInVzZXIiOiAidXNlcjEiIH0sCiAgICAgIHsgImxvZ19pZCI6ICJsb2cyIiwgInRpbWVzdGFtcCI6ICIyMDI0LTExLTAxVDEwOjMwOjAwWiIsICJ6b25lX2lkIjogInpvbmVBIiwgImFjY2VzcyI6ICJkZW5pZWQiLCAidXNlciI6ICJ1c2VyMiIgfSwKICAgICAgeyAibG9nX2lkIjogImxvZzMiLCAidGltZXN0YW1wIjogIjIwMjQtMTEtMDFUMTE6MDA6MDBaIiwgInpvbmVfaWQiOiAiem9uZUIiLCAiYWNjZXNzIjogImdyYW50ZWQiLCAidXNlciI6ICJ1c2VyMyIgfQogICAgXQp9Cg==
 + policy:
 + zone : cGFja2FnZSB6b25lCgppbXBvcnQgcmVnby52MQoKZGVmYXVsdCBhbGxvdyA6PSBmYWxzZQoKYWxsb3cgaWYgewogICAgaGFzX3pvbmVfYWNjZXNzCiAgICBhY3Rpb25faXNfbG9nX3ZpZXcKfQoKYWN0aW9uX2lzX2xvZ192aWV3IGlmIHsKICAgICJ2aWV3IiBpbiBpbnB1dC5hY3Rpb25zCn0KCmhhc196b25lX2FjY2VzcyBjb250YWlucyBhY2Nlc3NfZGF0YSBpZiB7CiAgICBzb21lIHpvbmVfZGF0YSBpbiBkYXRhLm5vZGUuem9uZS56b25lLnpvbmVfYWNjZXNzX2xvZ3MKICAgIHpvbmVfZGF0YS50aW1lc3RhbXAgPj0gaW5wdXQudGltZV9wZXJpb2QuZnJvbQogICAgem9uZV9kYXRhLnRpbWVzdGFtcCA8IGlucHV0LnRpbWVfcGVyaW9kLnRvCiAgICB6b25lX2RhdGEuem9uZV9pZCA9PSBpbnB1dC56b25lX2lkCiAgICBhY2Nlc3NfZGF0YSA6PSB7ZGF0YXR5cGU6IHpvbmVfZGF0YVtkYXRhdHlwZV0gfCBkYXRhdHlwZSBpbiBpbnB1dC5kYXRhdHlwZXN9Cn0K
 + name: zone
 + version: 1.0.0
 + metadata:
 + policy-id: zone
 + policy-version: 1.0.0
 +
 +</stringProp> + <stringProp name="Argument.metadata">=</stringProp> + </elementProp> + </collectionProp> + </elementProp> + </HTTPSamplerProxy> + <hashTree> + <AuthManager guiclass="AuthPanel" testclass="AuthManager" testname="HTTP Authorization Manager" enabled="true"> + <collectionProp name="AuthManager.auth_list"> + <elementProp name="" elementType="Authorization"> + <stringProp name="Authorization.url">${HTTP}://${API_HOST}:${API_PORT}/policy/api/v1</stringProp> + <stringProp name="Authorization.username">${API_USER}</stringProp> + <stringProp name="Authorization.password">${API_PASSWORD}</stringProp> + <stringProp name="Authorization.domain"></stringProp> + <stringProp name="Authorization.realm"></stringProp> + </elementProp> + </collectionProp> + <boolProp name="AuthManager.clearEachIteration">true</boolProp> + <boolProp name="AuthManager.controlledByThreadGroup">false</boolProp> + </AuthManager> + <hashTree/> + <HeaderManager guiclass="HeaderPanel" testclass="HeaderManager" testname="HTTP Header Manager" enabled="true"> + <collectionProp name="HeaderManager.headers"> + <elementProp name="" elementType="Header"> + <stringProp name="Header.name">Content-Type</stringProp> + <stringProp name="Header.value">application/yaml</stringProp> + </elementProp> + </collectionProp> + </HeaderManager> + <hashTree/> + <ResponseAssertion guiclass="AssertionGui" testclass="ResponseAssertion" testname="Response Assertion" enabled="true"> + <collectionProp name="Asserion.test_strings"> + <stringProp name="49587">201</stringProp> + </collectionProp> + <stringProp name="Assertion.custom_message"></stringProp> + <stringProp name="Assertion.test_field">Assertion.response_code</stringProp> + <boolProp name="Assertion.assume_success">false</boolProp> + <intProp name="Assertion.test_type">8</intProp> + </ResponseAssertion> + <hashTree/> + </hashTree> + <HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="Deploy Role Policy" enabled="true"> + <intProp name="HTTPSampler.concurrentPool">6</intProp> + <stringProp name="HTTPSampler.domain">${PAP_HOST}</stringProp> + <stringProp name="HTTPSampler.port">${PAP_PORT}</stringProp> + <stringProp name="HTTPSampler.protocol">${HTTP}</stringProp> + <stringProp name="HTTPSampler.path">policy/pap/v1/pdps/policies</stringProp> + <boolProp name="HTTPSampler.follow_redirects">true</boolProp> + <stringProp name="HTTPSampler.method">POST</stringProp> + <boolProp name="HTTPSampler.use_keepalive">true</boolProp> + <boolProp name="HTTPSampler.postBodyRaw">true</boolProp> + <elementProp name="HTTPsampler.Arguments" elementType="Arguments"> + <collectionProp name="Arguments.arguments"> + <elementProp name="" elementType="HTTPArgument"> + <boolProp name="HTTPArgument.always_encode">false</boolProp> + <stringProp name="Argument.value">{
 + "policies": [
 + {
 + "policy-id": "role",
 + "policy-version": "1.0.0"
 +
 + }
 + ]
 +}
 +</stringProp> + <stringProp name="Argument.metadata">=</stringProp> + </elementProp> + </collectionProp> + </elementProp> + </HTTPSamplerProxy> + <hashTree> + <AuthManager guiclass="AuthPanel" testclass="AuthManager" testname="HTTP Authorization Manager" enabled="true"> + <collectionProp name="AuthManager.auth_list"> + <elementProp name="" elementType="Authorization"> + <stringProp name="Authorization.url">${HTTP}://${PAP_HOST}:${PAP_PORT}/policy/pap/v1</stringProp> + <stringProp name="Authorization.username">${PAP_USER}</stringProp> + <stringProp name="Authorization.password">${PAP_PASSWORD}</stringProp> + <stringProp name="Authorization.domain"></stringProp> + <stringProp name="Authorization.realm"></stringProp> + </elementProp> + </collectionProp> + <boolProp name="AuthManager.clearEachIteration">true</boolProp> + <boolProp name="AuthManager.controlledByThreadGroup">false</boolProp> + </AuthManager> + <hashTree/> + <HeaderManager guiclass="HeaderPanel" testclass="HeaderManager" testname="HTTP Header Manager" enabled="true"> + <collectionProp name="HeaderManager.headers"> + <elementProp name="" elementType="Header"> + <stringProp name="Header.name">Content-Type</stringProp> + <stringProp name="Header.value">application/json</stringProp> + </elementProp> + </collectionProp> + </HeaderManager> + <hashTree/> + <ResponseAssertion guiclass="AssertionGui" testclass="ResponseAssertion" testname="Response Assertion" enabled="true"> + <collectionProp name="Asserion.test_strings"> + <stringProp name="49588">202</stringProp> + </collectionProp> + <stringProp name="Assertion.custom_message"></stringProp> + <stringProp name="Assertion.test_field">Assertion.response_code</stringProp> + <boolProp name="Assertion.assume_success">false</boolProp> + <intProp name="Assertion.test_type">8</intProp> + </ResponseAssertion> + <hashTree/> + </hashTree> + <HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="Deploy Collab Policy" enabled="true"> + <intProp name="HTTPSampler.concurrentPool">6</intProp> + <stringProp name="HTTPSampler.domain">${PAP_HOST}</stringProp> + <stringProp name="HTTPSampler.port">${PAP_PORT}</stringProp> + <stringProp name="HTTPSampler.protocol">${HTTP}</stringProp> + <stringProp name="HTTPSampler.path">policy/pap/v1/pdps/policies</stringProp> + <boolProp name="HTTPSampler.follow_redirects">true</boolProp> + <stringProp name="HTTPSampler.method">POST</stringProp> + <boolProp name="HTTPSampler.use_keepalive">true</boolProp> + <boolProp name="HTTPSampler.postBodyRaw">true</boolProp> + <elementProp name="HTTPsampler.Arguments" elementType="Arguments"> + <collectionProp name="Arguments.arguments"> + <elementProp name="" elementType="HTTPArgument"> + <boolProp name="HTTPArgument.always_encode">false</boolProp> + <stringProp name="Argument.value">{
 + "policies": [
 + {
 + "policy-id": "collab",
 + "policy-version": "1.0.0"
 +
 + }
 + ]
 +}
 +</stringProp> + <stringProp name="Argument.metadata">=</stringProp> + </elementProp> + </collectionProp> + </elementProp> + </HTTPSamplerProxy> + <hashTree> + <AuthManager guiclass="AuthPanel" testclass="AuthManager" testname="HTTP Authorization Manager" enabled="true"> + <collectionProp name="AuthManager.auth_list"> + <elementProp name="" elementType="Authorization"> + <stringProp name="Authorization.url">${HTTP}://${PAP_HOST}:${PAP_PORT}/policy/pap/v1</stringProp> + <stringProp name="Authorization.username">${PAP_USER}</stringProp> + <stringProp name="Authorization.password">${PAP_PASSWORD}</stringProp> + <stringProp name="Authorization.domain"></stringProp> + <stringProp name="Authorization.realm"></stringProp> + </elementProp> + </collectionProp> + <boolProp name="AuthManager.clearEachIteration">true</boolProp> + <boolProp name="AuthManager.controlledByThreadGroup">false</boolProp> + </AuthManager> + <hashTree/> + <HeaderManager guiclass="HeaderPanel" testclass="HeaderManager" testname="HTTP Header Manager" enabled="true"> + <collectionProp name="HeaderManager.headers"> + <elementProp name="" elementType="Header"> + <stringProp name="Header.name">Content-Type</stringProp> + <stringProp name="Header.value">application/json</stringProp> + </elementProp> + </collectionProp> + </HeaderManager> + <hashTree/> + <ResponseAssertion guiclass="AssertionGui" testclass="ResponseAssertion" testname="Response Assertion" enabled="true"> + <collectionProp name="Asserion.test_strings"> + <stringProp name="49588">202</stringProp> + </collectionProp> + <stringProp name="Assertion.custom_message"></stringProp> + <stringProp name="Assertion.test_field">Assertion.response_code</stringProp> + <boolProp name="Assertion.assume_success">false</boolProp> + <intProp name="Assertion.test_type">8</intProp> + </ResponseAssertion> + <hashTree/> + </hashTree> + <HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="Deploy Conflict Policy" enabled="true"> + <intProp name="HTTPSampler.concurrentPool">6</intProp> + <stringProp name="HTTPSampler.domain">${PAP_HOST}</stringProp> + <stringProp name="HTTPSampler.port">${PAP_PORT}</stringProp> + <stringProp name="HTTPSampler.protocol">${HTTP}</stringProp> + <stringProp name="HTTPSampler.path">policy/pap/v1/pdps/policies</stringProp> + <boolProp name="HTTPSampler.follow_redirects">true</boolProp> + <stringProp name="HTTPSampler.method">POST</stringProp> + <boolProp name="HTTPSampler.use_keepalive">true</boolProp> + <boolProp name="HTTPSampler.postBodyRaw">true</boolProp> + <elementProp name="HTTPsampler.Arguments" elementType="Arguments"> + <collectionProp name="Arguments.arguments"> + <elementProp name="" elementType="HTTPArgument"> + <boolProp name="HTTPArgument.always_encode">false</boolProp> + <stringProp name="Argument.value">{
 + "policies": [
 + {
 + "policy-id": "conflict",
 + "policy-version": "1.0.0"
 +
 + }
 + ]
 +}
 +</stringProp> + <stringProp name="Argument.metadata">=</stringProp> + </elementProp> + </collectionProp> + </elementProp> + </HTTPSamplerProxy> + <hashTree> + <AuthManager guiclass="AuthPanel" testclass="AuthManager" testname="HTTP Authorization Manager" enabled="true"> + <collectionProp name="AuthManager.auth_list"> + <elementProp name="" elementType="Authorization"> + <stringProp name="Authorization.url">${HTTP}://${PAP_HOST}:${PAP_PORT}/policy/pap/v1</stringProp> + <stringProp name="Authorization.username">${PAP_USER}</stringProp> + <stringProp name="Authorization.password">${PAP_PASSWORD}</stringProp> + <stringProp name="Authorization.domain"></stringProp> + <stringProp name="Authorization.realm"></stringProp> + </elementProp> + </collectionProp> + <boolProp name="AuthManager.clearEachIteration">true</boolProp> + <boolProp name="AuthManager.controlledByThreadGroup">false</boolProp> + </AuthManager> + <hashTree/> + <HeaderManager guiclass="HeaderPanel" testclass="HeaderManager" testname="HTTP Header Manager" enabled="true"> + <collectionProp name="HeaderManager.headers"> + <elementProp name="" elementType="Header"> + <stringProp name="Header.name">Content-Type</stringProp> + <stringProp name="Header.value">application/json</stringProp> + </elementProp> + </collectionProp> + </HeaderManager> + <hashTree/> + <ResponseAssertion guiclass="AssertionGui" testclass="ResponseAssertion" testname="Response Assertion" enabled="true"> + <collectionProp name="Asserion.test_strings"> + <stringProp name="49588">202</stringProp> + </collectionProp> + <stringProp name="Assertion.custom_message"></stringProp> + <stringProp name="Assertion.test_field">Assertion.response_code</stringProp> + <boolProp name="Assertion.assume_success">false</boolProp> + <intProp name="Assertion.test_type">8</intProp> + </ResponseAssertion> + <hashTree/> + </hashTree> + <HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="Deploy Zone Policy" enabled="true"> + <intProp name="HTTPSampler.concurrentPool">6</intProp> + <stringProp name="HTTPSampler.domain">${PAP_HOST}</stringProp> + <stringProp name="HTTPSampler.port">${PAP_PORT}</stringProp> + <stringProp name="HTTPSampler.protocol">${HTTP}</stringProp> + <stringProp name="HTTPSampler.path">policy/pap/v1/pdps/policies</stringProp> + <boolProp name="HTTPSampler.follow_redirects">true</boolProp> + <stringProp name="HTTPSampler.method">POST</stringProp> + <boolProp name="HTTPSampler.use_keepalive">true</boolProp> + <boolProp name="HTTPSampler.postBodyRaw">true</boolProp> + <elementProp name="HTTPsampler.Arguments" elementType="Arguments"> + <collectionProp name="Arguments.arguments"> + <elementProp name="" elementType="HTTPArgument"> + <boolProp name="HTTPArgument.always_encode">false</boolProp> + <stringProp name="Argument.value">{
 + "policies": [
 + {
 + "policy-id": "zone",
 + "policy-version": "1.0.0"
 +
 + }
 + ]
 +}</stringProp> + <stringProp name="Argument.metadata">=</stringProp> + </elementProp> + </collectionProp> + </elementProp> + </HTTPSamplerProxy> + <hashTree> + <AuthManager guiclass="AuthPanel" testclass="AuthManager" testname="HTTP Authorization Manager" enabled="true"> + <collectionProp name="AuthManager.auth_list"> + <elementProp name="" elementType="Authorization"> + <stringProp name="Authorization.url">${HTTP}://${PAP_HOST}:${PAP_PORT}/policy/pap/v1</stringProp> + <stringProp name="Authorization.username">${PAP_USER}</stringProp> + <stringProp name="Authorization.password">${PAP_PASSWORD}</stringProp> + <stringProp name="Authorization.domain"></stringProp> + <stringProp name="Authorization.realm"></stringProp> + </elementProp> + </collectionProp> + <boolProp name="AuthManager.clearEachIteration">true</boolProp> + <boolProp name="AuthManager.controlledByThreadGroup">false</boolProp> + </AuthManager> + <hashTree/> + <HeaderManager guiclass="HeaderPanel" testclass="HeaderManager" testname="HTTP Header Manager" enabled="true"> + <collectionProp name="HeaderManager.headers"> + <elementProp name="" elementType="Header"> + <stringProp name="Header.name">Content-Type</stringProp> + <stringProp name="Header.value">application/json</stringProp> + </elementProp> + </collectionProp> + </HeaderManager> + <hashTree/> + <ResponseAssertion guiclass="AssertionGui" testclass="ResponseAssertion" testname="Response Assertion" enabled="true"> + <collectionProp name="Asserion.test_strings"> + <stringProp name="49588">202</stringProp> + </collectionProp> + <stringProp name="Assertion.custom_message"></stringProp> + <stringProp name="Assertion.test_field">Assertion.response_code</stringProp> + <boolProp name="Assertion.assume_success">false</boolProp> + <intProp name="Assertion.test_type">8</intProp> + </ResponseAssertion> + <hashTree/> + </hashTree> + <ResultCollector guiclass="ViewResultsFullVisualizer" testclass="ResultCollector" testname="View Results Tree" enabled="true"> + <boolProp name="ResultCollector.error_logging">false</boolProp> + <objProp> + <name>saveConfig</name> + <value class="SampleSaveConfiguration"> + <time>true</time> + <latency>true</latency> + <timestamp>true</timestamp> + <success>true</success> + <label>true</label> + <code>true</code> + <message>true</message> + <threadName>true</threadName> + <dataType>true</dataType> + <encoding>false</encoding> + <assertions>true</assertions> + <subresults>true</subresults> + <responseData>false</responseData> + <samplerData>false</samplerData> + <xml>false</xml> + <fieldNames>true</fieldNames> + <responseHeaders>false</responseHeaders> + <requestHeaders>false</requestHeaders> + <responseDataOnError>false</responseDataOnError> + <saveAssertionResultsFailureMessage>true</saveAssertionResultsFailureMessage> + <assertionsResultsToSave>0</assertionsResultsToSave> + <bytes>true</bytes> + <sentBytes>true</sentBytes> + <url>true</url> + <threadCounts>true</threadCounts> + <idleTime>true</idleTime> + <connectTime>true</connectTime> + </value> + </objProp> + <stringProp name="filename">/tmp/pdpo_perf_setup.log</stringProp> + </ResultCollector> + <hashTree/> + </hashTree> + <ThreadGroup guiclass="ThreadGroupGui" testclass="ThreadGroup" testname="Policy OPA PDP Health Check "> <stringProp name="ThreadGroup.num_threads">${USERS}</stringProp> <intProp name="ThreadGroup.ramp_time">10</intProp> <stringProp name="ThreadGroup.duration">${DURATION}</stringProp> @@ -115,10 +709,10 @@ <HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="Check Health" enabled="true"> <stringProp name="TestPlan.comments">Basic Health Check</stringProp> <intProp name="HTTPSampler.concurrentPool">6</intProp> - <stringProp name="HTTPSampler.domain">${OPA_PDP_HOST}</stringProp> - <stringProp name="HTTPSampler.port">${OPA_PDP_PORT}</stringProp> + <stringProp name="HTTPSampler.domain">${OPA_HOST}</stringProp> + <stringProp name="HTTPSampler.port">${OPA_PORT}</stringProp> <stringProp name="HTTPSampler.protocol">${HTTP}</stringProp> - <stringProp name="HTTPSampler.path">policy/pdpx/v1/healthcheck</stringProp> + <stringProp name="HTTPSampler.path">policy/pdpo/v1/healthcheck</stringProp> <boolProp name="HTTPSampler.follow_redirects">true</boolProp> <stringProp name="HTTPSampler.method">GET</stringProp> <boolProp name="HTTPSampler.use_keepalive">true</boolProp> @@ -161,9 +755,9 @@ if (prev.getResponseCode() == '200') { <AuthManager guiclass="AuthPanel" testclass="AuthManager" testname="HTTP Authorization Manager" enabled="true"> <collectionProp name="AuthManager.auth_list"> <elementProp name="" elementType="Authorization"> - <stringProp name="Authorization.url">${HTTP}://${OPA_PDP_HOST}:${OPA_PDP_PORT}/policy/pdpx/v1</stringProp> - <stringProp name="Authorization.username">${OPA_PDP_USER}</stringProp> - <stringProp name="Authorization.password">${OPA_PDP_PASSWORD}</stringProp> + <stringProp name="Authorization.url">${HTTP}://${OPA_HOST}:${OPA_PORT}/policy/pdpo/v1</stringProp> + <stringProp name="Authorization.username">${OPA_USER}</stringProp> + <stringProp name="Authorization.password">${OPA_PASSWORD}</stringProp> <stringProp name="Authorization.domain"></stringProp> <stringProp name="Authorization.realm"></stringProp> </elementProp> @@ -206,12 +800,12 @@ if (prev.getResponseCode() == '200') { <connectTime>true</connectTime> </value> </objProp> - <stringProp name="filename">/tmp/pdpx_perf_health.log</stringProp> + <stringProp name="filename">/tmp/pdpo_perf_health.log</stringProp> <stringProp name="TestPlan.comments"> </stringProp> </ResultCollector> <hashTree/> </hashTree> - <ThreadGroup guiclass="ThreadGroupGui" testclass="ThreadGroup" testname="OPA PDP Decisions" enabled="true"> + <ThreadGroup guiclass="ThreadGroupGui" testclass="ThreadGroup" testname="OPA PDP Decisions"> <stringProp name="ThreadGroup.num_threads">${USERS}</stringProp> <intProp name="ThreadGroup.ramp_time">10</intProp> <stringProp name="ThreadGroup.duration">${DURATION}</stringProp> @@ -225,13 +819,13 @@ if (prev.getResponseCode() == '200') { </elementProp> </ThreadGroup> <hashTree> - <HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="Verification API Call 1" enabled="true"> - <stringProp name="TestPlan.comments">Get Verification API Call 1</stringProp> + <HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="Fetch Role Decisions"> + <stringProp name="TestPlan.comments">Get Configuration Data for Monitoring Policy</stringProp> <intProp name="HTTPSampler.concurrentPool">6</intProp> - <stringProp name="HTTPSampler.domain">${OPA_PDP_HOST}</stringProp> - <stringProp name="HTTPSampler.port">${OPA_PDP_PORT}</stringProp> + <stringProp name="HTTPSampler.domain">${OPA_HOST}</stringProp> + <stringProp name="HTTPSampler.port">${OPA_PORT}</stringProp> <stringProp name="HTTPSampler.protocol">${HTTP}</stringProp> - <stringProp name="HTTPSampler.path">policy/pdpx/v1/decision</stringProp> + <stringProp name="HTTPSampler.path">policy/pdpo/v1/decision</stringProp> <boolProp name="HTTPSampler.follow_redirects">true</boolProp> <stringProp name="HTTPSampler.method">POST</stringProp> <boolProp name="HTTPSampler.use_keepalive">true</boolProp> @@ -245,16 +839,16 @@ if (prev.getResponseCode() == '200') { "onapComponent": "CDS",
 "onapInstance": "CDS",
 "currentDate": "2024-11-22",
 - "currentTime": "2024-11-22T11:34:56Z",
 + "currentTime": "11:23:41.857Z",
 "timeZone": "UTC",
 "timeOffset": "+05:30",
 "currentDateTime": "2024-11-22T12:08:00Z",
 - "policyName": "example/allow",
 + "policyFilter": [
 + "allow"
 + ],
 + "policyName": "role",
 "input": {
 - "method": "POST",
 - "path": [
 - "users"
 - ]
 + "user": "alice"
 }
 }</stringProp> <stringProp name="Argument.metadata">=</stringProp> @@ -263,6 +857,20 @@ if (prev.getResponseCode() == '200') { </elementProp> </HTTPSamplerProxy> <hashTree> + <AuthManager guiclass="AuthPanel" testclass="AuthManager" testname="HTTP Authorization Manager" enabled="true"> + <collectionProp name="AuthManager.auth_list"> + <elementProp name="" elementType="Authorization"> + <stringProp name="Authorization.url">${HTTP}://${OPA_HOST}:${OPA_PORT}/policy/pdpo/v1</stringProp> + <stringProp name="Authorization.username">${OPA_USER}</stringProp> + <stringProp name="Authorization.password">${OPA_PASSWORD}</stringProp> + <stringProp name="Authorization.domain"></stringProp> + <stringProp name="Authorization.realm"></stringProp> + </elementProp> + </collectionProp> + <boolProp name="AuthManager.clearEachIteration">true</boolProp> + <boolProp name="AuthManager.controlledByThreadGroup">false</boolProp> + </AuthManager> + <hashTree/> <ResponseAssertion guiclass="AssertionGui" testclass="ResponseAssertion" testname="Response Assertion" enabled="true"> <collectionProp name="Asserion.test_strings"> <stringProp name="49586">200</stringProp> @@ -275,7 +883,7 @@ if (prev.getResponseCode() == '200') { <hashTree/> <ResponseAssertion guiclass="AssertionGui" testclass="ResponseAssertion" testname="Response Assertion" enabled="true"> <collectionProp name="Asserion.test_strings"> - <stringProp name="-1938393061">PERMIT</stringProp> + <stringProp name="92906313">allow</stringProp> </collectionProp> <stringProp name="Assertion.custom_message"></stringProp> <stringProp name="Assertion.test_field">Assertion.response_data</stringProp> @@ -284,13 +892,13 @@ if (prev.getResponseCode() == '200') { </ResponseAssertion> <hashTree/> </hashTree> - <HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="Verification API Call 2" enabled="true"> - <stringProp name="TestPlan.comments">Get Verification API Call 2</stringProp> + <HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="Fetch Role Decisions with nultiple Filters"> + <stringProp name="TestPlan.comments">Get Data with Filter for Role Policy</stringProp> <intProp name="HTTPSampler.concurrentPool">6</intProp> - <stringProp name="HTTPSampler.domain">${OPA_PDP_HOST}</stringProp> - <stringProp name="HTTPSampler.port">${OPA_PDP_PORT}</stringProp> + <stringProp name="HTTPSampler.domain">${OPA_HOST}</stringProp> + <stringProp name="HTTPSampler.port">${OPA_PORT}</stringProp> <stringProp name="HTTPSampler.protocol">${HTTP}</stringProp> - <stringProp name="HTTPSampler.path">policy/pdpx/v1/decision</stringProp> + <stringProp name="HTTPSampler.path">policy/pdpo/v1/decision</stringProp> <boolProp name="HTTPSampler.follow_redirects">true</boolProp> <stringProp name="HTTPSampler.method">POST</stringProp> <boolProp name="HTTPSampler.use_keepalive">true</boolProp> @@ -304,16 +912,16 @@ if (prev.getResponseCode() == '200') { "onapComponent": "CDS",
 "onapInstance": "CDS",
 "currentDate": "2024-11-22",
 - "currentTime": "2024-11-22T11:34:56Z",
 + "currentTime": "11:23:41.857Z",
 "timeZone": "UTC",
 "timeOffset": "+05:30",
 "currentDateTime": "2024-11-22T12:08:00Z",
 - "policyName": "role/allow",
 + "policyFilter": [
 + "user_is_admin", "allow"
 + ],
 + "policyName": "role",
 "input": {
 - "user": "alice",
 - "action": "write",
 - "object": "id123",
 - "type": "dog"
 + "user": "alice"
 }
 }</stringProp> <stringProp name="Argument.metadata">=</stringProp> @@ -322,6 +930,20 @@ if (prev.getResponseCode() == '200') { </elementProp> </HTTPSamplerProxy> <hashTree> + <AuthManager guiclass="AuthPanel" testclass="AuthManager" testname="HTTP Authorization Manager" enabled="true"> + <collectionProp name="AuthManager.auth_list"> + <elementProp name="" elementType="Authorization"> + <stringProp name="Authorization.url">${HTTP}://${OPA_HOST}:${OPA_PORT}/policy/pdpo/v1</stringProp> + <stringProp name="Authorization.username">${OPA_USER}</stringProp> + <stringProp name="Authorization.password">${OPA_PASSWORD}</stringProp> + <stringProp name="Authorization.domain"></stringProp> + <stringProp name="Authorization.realm"></stringProp> + </elementProp> + </collectionProp> + <boolProp name="AuthManager.clearEachIteration">true</boolProp> + <boolProp name="AuthManager.controlledByThreadGroup">false</boolProp> + </AuthManager> + <hashTree/> <ResponseAssertion guiclass="AssertionGui" testclass="ResponseAssertion" testname="Response Assertion" enabled="true"> <collectionProp name="Asserion.test_strings"> <stringProp name="49586">200</stringProp> @@ -334,7 +956,8 @@ if (prev.getResponseCode() == '200') { <hashTree/> <ResponseAssertion guiclass="AssertionGui" testclass="ResponseAssertion" testname="Response Assertion" enabled="true"> <collectionProp name="Asserion.test_strings"> - <stringProp name="-1938393061">PERMIT</stringProp> + <stringProp name="92906313">allow</stringProp> + <stringProp name="158189038">user_is_admin</stringProp> </collectionProp> <stringProp name="Assertion.custom_message"></stringProp> <stringProp name="Assertion.test_field">Assertion.response_data</stringProp> @@ -343,13 +966,13 @@ if (prev.getResponseCode() == '200') { </ResponseAssertion> <hashTree/> </hashTree> - <HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="PERMIT for policy:action" enabled="true"> - <stringProp name="TestPlan.comments">PERMIT for policy:action</stringProp> + <HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="Fetch Collab Decisions"> + <stringProp name="TestPlan.comments">Get Output for Collab Policy</stringProp> <intProp name="HTTPSampler.concurrentPool">6</intProp> - <stringProp name="HTTPSampler.domain">${OPA_PDP_HOST}</stringProp> - <stringProp name="HTTPSampler.port">${OPA_PDP_PORT}</stringProp> + <stringProp name="HTTPSampler.domain">${OPA_HOST}</stringProp> + <stringProp name="HTTPSampler.port">${OPA_PORT}</stringProp> <stringProp name="HTTPSampler.protocol">${HTTP}</stringProp> - <stringProp name="HTTPSampler.path">policy/pdpx/v1/decision</stringProp> + <stringProp name="HTTPSampler.path">policy/pdpo/v1/decision</stringProp> <boolProp name="HTTPSampler.follow_redirects">true</boolProp> <stringProp name="HTTPSampler.method">POST</stringProp> <boolProp name="HTTPSampler.use_keepalive">true</boolProp> @@ -358,28 +981,27 @@ if (prev.getResponseCode() == '200') { <collectionProp name="Arguments.arguments"> <elementProp name="" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">false</boolProp> - <stringProp name="Argument.value">{
 - "onapName": "CDS",
 - "onapComponent": "CDS",
 - "onapInstance": "CDS",
 - "currentDate": "2024-11-22",
 - "currentTime": "2024-11-22T11:34:56Z",
 - "timeZone": "UTC",
 - "timeOffset": "+05:30",
 - "currentDateTime": "2024-11-22T12:08:00Z",
 - "policyName": "action/allow",
 - "input": {
 - "user": "alice",
 - "action": "delete",
 - "type": "server"
 - }
 -}</stringProp> + <stringProp name="Argument.value">{"onapName":"CDS","onapComponent":"CDS","onapInstance":"CDS", "currentDate": "2024-11-22", "currentTime": "11:23:41.857Z", "timeZone": "UTC", "timeOffset": "+05:30", "currentDateTime": "2024-11-22T12:08:00Z","policyFilter": ["action"], "policyName":"collab","input":{"name":"alice"}}</stringProp> <stringProp name="Argument.metadata">=</stringProp> </elementProp> </collectionProp> </elementProp> </HTTPSamplerProxy> <hashTree> + <AuthManager guiclass="AuthPanel" testclass="AuthManager" testname="HTTP Authorization Manager" enabled="true"> + <collectionProp name="AuthManager.auth_list"> + <elementProp name="" elementType="Authorization"> + <stringProp name="Authorization.url">${HTTP}://${OPA_HOST}:${OPA_PORT}/policy/pdpo/v1</stringProp> + <stringProp name="Authorization.username">${OPA_USER}</stringProp> + <stringProp name="Authorization.password">${OPA_PASSWORD}</stringProp> + <stringProp name="Authorization.domain"></stringProp> + <stringProp name="Authorization.realm"></stringProp> + </elementProp> + </collectionProp> + <boolProp name="AuthManager.clearEachIteration">true</boolProp> + <boolProp name="AuthManager.controlledByThreadGroup">false</boolProp> + </AuthManager> + <hashTree/> <ResponseAssertion guiclass="AssertionGui" testclass="ResponseAssertion" testname="Response Assertion" enabled="true"> <collectionProp name="Asserion.test_strings"> <stringProp name="49586">200</stringProp> @@ -392,7 +1014,7 @@ if (prev.getResponseCode() == '200') { <hashTree/> <ResponseAssertion guiclass="AssertionGui" testclass="ResponseAssertion" testname="Response Assertion" enabled="true"> <collectionProp name="Asserion.test_strings"> - <stringProp name="-1938393061">PERMIT</stringProp> + <stringProp name="-1422950858">action</stringProp> </collectionProp> <stringProp name="Assertion.custom_message"></stringProp> <stringProp name="Assertion.test_field">Assertion.response_data</stringProp> @@ -401,13 +1023,13 @@ if (prev.getResponseCode() == '200') { </ResponseAssertion> <hashTree/> </hashTree> - <HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="DENY for policy:action" enabled="true"> - <stringProp name="TestPlan.comments">DENY for policy:action</stringProp> + <HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="Fetch Conflict Decisions"> + <stringProp name="TestPlan.comments">Get Output for Conflict Policy</stringProp> <intProp name="HTTPSampler.concurrentPool">6</intProp> - <stringProp name="HTTPSampler.domain">${OPA_PDP_HOST}</stringProp> - <stringProp name="HTTPSampler.port">${OPA_PDP_PORT}</stringProp> + <stringProp name="HTTPSampler.domain">${OPA_HOST}</stringProp> + <stringProp name="HTTPSampler.port">${OPA_PORT}</stringProp> <stringProp name="HTTPSampler.protocol">${HTTP}</stringProp> - <stringProp name="HTTPSampler.path">policy/pdpx/v1/decision</stringProp> + <stringProp name="HTTPSampler.path">policy/pdpo/v1/decision</stringProp> <boolProp name="HTTPSampler.follow_redirects">true</boolProp> <stringProp name="HTTPSampler.method">POST</stringProp> <boolProp name="HTTPSampler.use_keepalive">true</boolProp> @@ -416,28 +1038,27 @@ if (prev.getResponseCode() == '200') { <collectionProp name="Arguments.arguments"> <elementProp name="" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">false</boolProp> - <stringProp name="Argument.value">{
 - "onapName": "CDS",
 - "onapComponent": "CDS",
 - "onapInstance": "CDS",
 - "currentDate": "2024-11-22",
 - "currentTime": "2024-11-22T11:34:56Z",
 - "timeZone": "UTC",
 - "timeOffset": "+05:30",
 - "currentDateTime": "2024-11-22T12:08:00Z",
 - "policyName": "action/allow",
 - "input": {
 - "user": "charlie",
 - "action": "delete",
 - "type": "server"
 - }
 -}</stringProp> + <stringProp name="Argument.value">{"onapName":"CDS","onapComponent":"CDS","onapInstance":"CDS", "currentDate": "2024-11-22", "currentTime": "11:23:41.857Z", "timeZone": "UTC", "timeOffset": "+05:30", "currentDateTime": "2024-11-22T12:08:00Z","policyFilter": ["allow"], "policyName":"conflict","input":{"name":"alice"}}</stringProp> <stringProp name="Argument.metadata">=</stringProp> </elementProp> </collectionProp> </elementProp> </HTTPSamplerProxy> <hashTree> + <AuthManager guiclass="AuthPanel" testclass="AuthManager" testname="HTTP Authorization Manager" enabled="true"> + <collectionProp name="AuthManager.auth_list"> + <elementProp name="" elementType="Authorization"> + <stringProp name="Authorization.url">${HTTP}://${OPA_HOST}:${OPA_PORT}/policy/pdpo/v1</stringProp> + <stringProp name="Authorization.username">${OPA_USER}</stringProp> + <stringProp name="Authorization.password">${OPA_PASSWORD}</stringProp> + <stringProp name="Authorization.domain"></stringProp> + <stringProp name="Authorization.realm"></stringProp> + </elementProp> + </collectionProp> + <boolProp name="AuthManager.clearEachIteration">true</boolProp> + <boolProp name="AuthManager.controlledByThreadGroup">false</boolProp> + </AuthManager> + <hashTree/> <ResponseAssertion guiclass="AssertionGui" testclass="ResponseAssertion" testname="Response Assertion" enabled="true"> <collectionProp name="Asserion.test_strings"> <stringProp name="49586">200</stringProp> @@ -450,7 +1071,7 @@ if (prev.getResponseCode() == '200') { <hashTree/> <ResponseAssertion guiclass="AssertionGui" testclass="ResponseAssertion" testname="Response Assertion" enabled="true"> <collectionProp name="Asserion.test_strings"> - <stringProp name="2094604">DENY</stringProp> + <stringProp name="92906313">allow</stringProp> </collectionProp> <stringProp name="Assertion.custom_message"></stringProp> <stringProp name="Assertion.test_field">Assertion.response_data</stringProp> @@ -459,13 +1080,13 @@ if (prev.getResponseCode() == '200') { </ResponseAssertion> <hashTree/> </hashTree> - <HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="PERMIT for policy:account" enabled="true"> - <stringProp name="TestPlan.comments">PERMIT for policy:account</stringProp> + <HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="Fetch Zone Decisions"> + <stringProp name="TestPlan.comments">Get Zone Decisions</stringProp> <intProp name="HTTPSampler.concurrentPool">6</intProp> - <stringProp name="HTTPSampler.domain">${OPA_PDP_HOST}</stringProp> - <stringProp name="HTTPSampler.port">${OPA_PDP_PORT}</stringProp> + <stringProp name="HTTPSampler.domain">${OPA_HOST}</stringProp> + <stringProp name="HTTPSampler.port">${OPA_PORT}</stringProp> <stringProp name="HTTPSampler.protocol">${HTTP}</stringProp> - <stringProp name="HTTPSampler.path">policy/pdpx/v1/decision</stringProp> + <stringProp name="HTTPSampler.path">policy/pdpo/v1/decision</stringProp> <boolProp name="HTTPSampler.follow_redirects">true</boolProp> <stringProp name="HTTPSampler.method">POST</stringProp> <boolProp name="HTTPSampler.use_keepalive">true</boolProp> @@ -474,31 +1095,35 @@ if (prev.getResponseCode() == '200') { <collectionProp name="Arguments.arguments"> <elementProp name="" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">false</boolProp> - <stringProp name="Argument.value">{
 - "onapName": "CDS",
 - "onapComponent": "CDS",
 - "onapInstance": "CDS",
 - "currentDate": "2024-11-22",
 - "currentTime": "2024-11-22T11:34:56Z",
 - "timeZone": "UTC",
 - "timeOffset": "+05:30",
 - "currentDateTime": "2024-11-22T12:08:00Z",
 - "policyName": "account/allow",
 - "input": {
 - "creditor_account": 11111,
 - "creditor": "alice",
 - "debtor_account": 22222,
 - "debtor": "bob",
 - "period": 30,
 - "amount": 1000
 - }
 -}</stringProp> + <stringProp name="Argument.value">{"onapName":"CDS","onapComponent":"CDS","onapInstance":"CDS", "currentDate": "2024-11-22", "currentTime": "11:23:41.857Z", "timeZone": "UTC", "timeOffset": "+05:30", "currentDateTime": "2024-11-22T12:08:00Z","policyFilter": ["allow"], "policyName":"zone","input":{
 + "actions": ["view"],
 + "zone_id": "zone123",
 + "time_period": {
 + "from": 1700000000,
 + "to": 1700500000
 + },
 + "datatypes": ["temperature", "humidity"]
 +}}</stringProp> <stringProp name="Argument.metadata">=</stringProp> </elementProp> </collectionProp> </elementProp> </HTTPSamplerProxy> <hashTree> + <AuthManager guiclass="AuthPanel" testclass="AuthManager" testname="HTTP Authorization Manager" enabled="true"> + <collectionProp name="AuthManager.auth_list"> + <elementProp name="" elementType="Authorization"> + <stringProp name="Authorization.url">${HTTP}://${OPA_HOST}:${OPA_PORT}/policy/pdpo/v1</stringProp> + <stringProp name="Authorization.username">${OPA_USER}</stringProp> + <stringProp name="Authorization.password">${OPA_PASSWORD}</stringProp> + <stringProp name="Authorization.domain"></stringProp> + <stringProp name="Authorization.realm"></stringProp> + </elementProp> + </collectionProp> + <boolProp name="AuthManager.clearEachIteration">true</boolProp> + <boolProp name="AuthManager.controlledByThreadGroup">false</boolProp> + </AuthManager> + <hashTree/> <ResponseAssertion guiclass="AssertionGui" testclass="ResponseAssertion" testname="Response Assertion" enabled="true"> <collectionProp name="Asserion.test_strings"> <stringProp name="49586">200</stringProp> @@ -511,7 +1136,7 @@ if (prev.getResponseCode() == '200') { <hashTree/> <ResponseAssertion guiclass="AssertionGui" testclass="ResponseAssertion" testname="Response Assertion" enabled="true"> <collectionProp name="Asserion.test_strings"> - <stringProp name="-1938393061">PERMIT</stringProp> + <stringProp name="92906313">allow</stringProp> </collectionProp> <stringProp name="Assertion.custom_message"></stringProp> <stringProp name="Assertion.test_field">Assertion.response_data</stringProp> @@ -520,15 +1145,15 @@ if (prev.getResponseCode() == '200') { </ResponseAssertion> <hashTree/> </hashTree> - <HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="DENY for policy:account" enabled="true"> - <stringProp name="TestPlan.comments">DENY for policy:account</stringProp> + <HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="Patch Data for Policy"> + <stringProp name="TestPlan.comments">Patch Data for Policy</stringProp> <intProp name="HTTPSampler.concurrentPool">6</intProp> - <stringProp name="HTTPSampler.domain">${OPA_PDP_HOST}</stringProp> - <stringProp name="HTTPSampler.port">${OPA_PDP_PORT}</stringProp> + <stringProp name="HTTPSampler.domain">${OPA_HOST}</stringProp> + <stringProp name="HTTPSampler.port">${OPA_PORT}</stringProp> <stringProp name="HTTPSampler.protocol">${HTTP}</stringProp> - <stringProp name="HTTPSampler.path">policy/pdpx/v1/decision</stringProp> + <stringProp name="HTTPSampler.path">policy/pdpo/v1/data/node/role</stringProp> <boolProp name="HTTPSampler.follow_redirects">true</boolProp> - <stringProp name="HTTPSampler.method">POST</stringProp> + <stringProp name="HTTPSampler.method">PATCH</stringProp> <boolProp name="HTTPSampler.use_keepalive">true</boolProp> <boolProp name="HTTPSampler.postBodyRaw">true</boolProp> <elementProp name="HTTPsampler.Arguments" elementType="Arguments"> @@ -536,23 +1161,22 @@ if (prev.getResponseCode() == '200') { <elementProp name="" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">false</boolProp> <stringProp name="Argument.value">{
 - "onapName": "CDS",
 - "onapComponent": "CDS",
 - "onapInstance": "CDS",
 - "currentDate": "2024-11-22",
 - "currentTime": "2024-11-22T11:34:56Z",
 + "onapName": "string",
 + "onapComponent": "string",
 + "onapInstance": "string",
 + "currentDateTime": "2025-01-17T08:26:41.857Z",
 + "currentDate": "2025-01-17",
 + "currentTime": "08:26:41.857Z",
 "timeZone": "UTC",
 - "timeOffset": "+05:30",
 - "currentDateTime": "2024-11-22T12:08:00Z",
 - "policyName": "account/allow",
 - "input": {
 - "creditor_account": 11111,
 - "creditor": "alice",
 - "debtor_account": 22222,
 - "debtor": "bob",
 - "period": 31,
 - "amount": 1000
 - }
 + "timeOffset": "+08:45",
 + "policyName": "role",
 + "data": [
 + {
 + "op": "add",
 + "path": "/cell",
 + "value": "try"
 + }
 + ]
 }</stringProp> <stringProp name="Argument.metadata">=</stringProp> </elementProp> @@ -560,66 +1184,61 @@ if (prev.getResponseCode() == '200') { </elementProp> </HTTPSamplerProxy> <hashTree> - <ResponseAssertion guiclass="AssertionGui" testclass="ResponseAssertion" testname="Response Assertion" enabled="true"> - <collectionProp name="Asserion.test_strings"> - <stringProp name="49586">200</stringProp> + <AuthManager guiclass="AuthPanel" testclass="AuthManager" testname="HTTP Authorization Manager" enabled="true"> + <collectionProp name="AuthManager.auth_list"> + <elementProp name="" elementType="Authorization"> + <stringProp name="Authorization.url">${HTTP}://${OPA_HOST}:${OPA_PORT}/policy/pdpo/v1</stringProp> + <stringProp name="Authorization.username">${OPA_USER}</stringProp> + <stringProp name="Authorization.password">${OPA_PASSWORD}</stringProp> + <stringProp name="Authorization.domain"></stringProp> + <stringProp name="Authorization.realm"></stringProp> + </elementProp> </collectionProp> - <stringProp name="Assertion.custom_message"></stringProp> - <stringProp name="Assertion.test_field">Assertion.response_code</stringProp> - <boolProp name="Assertion.assume_success">false</boolProp> - <intProp name="Assertion.test_type">8</intProp> - </ResponseAssertion> + <boolProp name="AuthManager.clearEachIteration">true</boolProp> + <boolProp name="AuthManager.controlledByThreadGroup">false</boolProp> + </AuthManager> <hashTree/> <ResponseAssertion guiclass="AssertionGui" testclass="ResponseAssertion" testname="Response Assertion" enabled="true"> <collectionProp name="Asserion.test_strings"> - <stringProp name="2094604">DENY</stringProp> + <stringProp name="49590">204</stringProp> </collectionProp> <stringProp name="Assertion.custom_message"></stringProp> - <stringProp name="Assertion.test_field">Assertion.response_data</stringProp> + <stringProp name="Assertion.test_field">Assertion.response_code</stringProp> <boolProp name="Assertion.assume_success">false</boolProp> - <intProp name="Assertion.test_type">2</intProp> + <intProp name="Assertion.test_type">8</intProp> </ResponseAssertion> <hashTree/> </hashTree> - <HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="PERMIT for policy:organization" enabled="true"> - <stringProp name="TestPlan.comments">PERMIT for policy:organization</stringProp> + <HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="Get Data for polcy role"> + <stringProp name="TestPlan.comments">Get Data for polcy role</stringProp> <intProp name="HTTPSampler.concurrentPool">6</intProp> - <stringProp name="HTTPSampler.domain">${OPA_PDP_HOST}</stringProp> - <stringProp name="HTTPSampler.port">${OPA_PDP_PORT}</stringProp> + <stringProp name="HTTPSampler.domain">${OPA_HOST}</stringProp> + <stringProp name="HTTPSampler.port">${OPA_PORT}</stringProp> <stringProp name="HTTPSampler.protocol">${HTTP}</stringProp> - <stringProp name="HTTPSampler.path">policy/pdpx/v1/decision</stringProp> + <stringProp name="HTTPSampler.path">policy/pdpo/v1/data/</stringProp> <boolProp name="HTTPSampler.follow_redirects">true</boolProp> - <stringProp name="HTTPSampler.method">POST</stringProp> + <stringProp name="HTTPSampler.method">GET</stringProp> <boolProp name="HTTPSampler.use_keepalive">true</boolProp> - <boolProp name="HTTPSampler.postBodyRaw">true</boolProp> - <elementProp name="HTTPsampler.Arguments" elementType="Arguments"> - <collectionProp name="Arguments.arguments"> - <elementProp name="" elementType="HTTPArgument"> - <boolProp name="HTTPArgument.always_encode">false</boolProp> - <stringProp name="Argument.value">{
 - "onapName": "CDS",
 - "onapComponent": "CDS",
 - "onapInstance": "CDS",
 - "currentDate": "2024-11-22",
 - "currentTime": "2024-11-22T11:34:56Z",
 - "timeZone": "UTC",
 - "timeOffset": "+05:30",
 - "currentDateTime": "2024-11-22T12:08:00Z",
 - "policyName": "organization/allow",
 - "input": {
 - "user": "alice",
 - "action": "read",
 - "component": "component_A",
 - "project": "project_A",
 - "organization": "org_A"
 - }
 -}</stringProp> - <stringProp name="Argument.metadata">=</stringProp> - </elementProp> - </collectionProp> + <boolProp name="HTTPSampler.postBodyRaw">false</boolProp> + <elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" testname="User Defined Variables"> + <collectionProp name="Arguments.arguments"/> </elementProp> </HTTPSamplerProxy> <hashTree> + <AuthManager guiclass="AuthPanel" testclass="AuthManager" testname="HTTP Authorization Manager" enabled="true"> + <collectionProp name="AuthManager.auth_list"> + <elementProp name="" elementType="Authorization"> + <stringProp name="Authorization.url">${HTTP}://${OPA_HOST}:${OPA_PORT}/policy/pdpo/v1</stringProp> + <stringProp name="Authorization.username">${OPA_USER}</stringProp> + <stringProp name="Authorization.password">${OPA_PASSWORD}</stringProp> + <stringProp name="Authorization.domain"></stringProp> + <stringProp name="Authorization.realm"></stringProp> + </elementProp> + </collectionProp> + <boolProp name="AuthManager.clearEachIteration">true</boolProp> + <boolProp name="AuthManager.controlledByThreadGroup">false</boolProp> + </AuthManager> + <hashTree/> <ResponseAssertion guiclass="AssertionGui" testclass="ResponseAssertion" testname="Response Assertion" enabled="true"> <collectionProp name="Asserion.test_strings"> <stringProp name="49586">200</stringProp> @@ -632,7 +1251,7 @@ if (prev.getResponseCode() == '200') { <hashTree/> <ResponseAssertion guiclass="AssertionGui" testclass="ResponseAssertion" testname="Response Assertion" enabled="true"> <collectionProp name="Asserion.test_strings"> - <stringProp name="-1938393061">PERMIT</stringProp> + <stringProp name="3076010">data</stringProp> </collectionProp> <stringProp name="Assertion.custom_message"></stringProp> <stringProp name="Assertion.test_field">Assertion.response_data</stringProp> @@ -641,80 +1260,347 @@ if (prev.getResponseCode() == '200') { </ResponseAssertion> <hashTree/> </hashTree> - <HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="DENY for policy:organization" enabled="true"> - <stringProp name="TestPlan.comments">DENY for policy:organization</stringProp> + <AuthManager guiclass="AuthPanel" testclass="AuthManager" testname="HTTP Authorization Manager" enabled="true"> + <collectionProp name="AuthManager.auth_list"> + <elementProp name="" elementType="Authorization"> + <stringProp name="Authorization.url">${HTTP}://${OPA_HOST}:${OPA_PORT}/policy/pdpo/v1</stringProp> + <stringProp name="Authorization.username">${OPA_USER}</stringProp> + <stringProp name="Authorization.password">${OPA_PASSWORD}</stringProp> + <stringProp name="Authorization.domain"></stringProp> + <stringProp name="Authorization.realm"></stringProp> + </elementProp> + </collectionProp> + <boolProp name="AuthManager.clearEachIteration">true</boolProp> + <boolProp name="AuthManager.controlledByThreadGroup">false</boolProp> + </AuthManager> + <hashTree/> + <ResultCollector guiclass="ViewResultsFullVisualizer" testclass="ResultCollector" testname="View Results Tree" enabled="true"> + <boolProp name="ResultCollector.error_logging">false</boolProp> + <objProp> + <name>saveConfig</name> + <value class="SampleSaveConfiguration"> + <time>true</time> + <latency>true</latency> + <timestamp>true</timestamp> + <success>true</success> + <label>true</label> + <code>true</code> + <message>true</message> + <threadName>true</threadName> + <dataType>true</dataType> + <encoding>false</encoding> + <assertions>true</assertions> + <subresults>true</subresults> + <responseData>false</responseData> + <samplerData>false</samplerData> + <xml>false</xml> + <fieldNames>true</fieldNames> + <responseHeaders>false</responseHeaders> + <requestHeaders>false</requestHeaders> + <responseDataOnError>false</responseDataOnError> + <saveAssertionResultsFailureMessage>true</saveAssertionResultsFailureMessage> + <assertionsResultsToSave>0</assertionsResultsToSave> + <bytes>true</bytes> + <sentBytes>true</sentBytes> + <url>true</url> + <threadCounts>true</threadCounts> + <idleTime>true</idleTime> + <connectTime>true</connectTime> + </value> + </objProp> + <stringProp name="filename">/tmp/pdpo_perf_decisions.log</stringProp> + </ResultCollector> + <hashTree/> + </hashTree> + <PostThreadGroup guiclass="PostThreadGroupGui" testclass="PostThreadGroup" testname="tearDown OPA PDP Decision" enabled="true"> + <intProp name="ThreadGroup.num_threads">1</intProp> + <intProp name="ThreadGroup.ramp_time">1</intProp> + <stringProp name="ThreadGroup.duration">${DURATION}</stringProp> + <longProp name="ThreadGroup.delay">1</longProp> + <boolProp name="ThreadGroup.same_user_on_next_iteration">true</boolProp> + <stringProp name="ThreadGroup.on_sample_error">continue</stringProp> + <elementProp name="ThreadGroup.main_controller" elementType="LoopController" guiclass="LoopControlPanel" testclass="LoopController" testname="Loop Controller"> + <stringProp name="LoopController.loops">1</stringProp> + <boolProp name="LoopController.continue_forever">false</boolProp> + </elementProp> + </PostThreadGroup> + <hashTree> + <HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="Undeploy Role Policy" enabled="true"> <intProp name="HTTPSampler.concurrentPool">6</intProp> - <stringProp name="HTTPSampler.domain">${OPA_PDP_HOST}</stringProp> - <stringProp name="HTTPSampler.port">${OPA_PDP_PORT}</stringProp> + <stringProp name="HTTPSampler.domain">${PAP_HOST}</stringProp> + <stringProp name="HTTPSampler.port">${PAP_PORT}</stringProp> <stringProp name="HTTPSampler.protocol">${HTTP}</stringProp> - <stringProp name="HTTPSampler.path">policy/pdpx/v1/decision</stringProp> + <stringProp name="HTTPSampler.path">policy/pap/v1/pdps/policies/role/versions/1.0.0</stringProp> <boolProp name="HTTPSampler.follow_redirects">true</boolProp> - <stringProp name="HTTPSampler.method">POST</stringProp> + <stringProp name="HTTPSampler.method">DELETE</stringProp> <boolProp name="HTTPSampler.use_keepalive">true</boolProp> - <boolProp name="HTTPSampler.postBodyRaw">true</boolProp> - <elementProp name="HTTPsampler.Arguments" elementType="Arguments"> - <collectionProp name="Arguments.arguments"> - <elementProp name="" elementType="HTTPArgument"> - <boolProp name="HTTPArgument.always_encode">false</boolProp> - <stringProp name="Argument.value">{
 - "onapName": "CDS",
 - "onapComponent": "CDS",
 - "onapInstance": "CDS",
 - "currentDate": "2024-11-22",
 - "currentTime": "2024-11-22T11:34:56Z",
 - "timeZone": "UTC",
 - "timeOffset": "+05:30",
 - "currentDateTime": "2024-11-22T12:08:00Z",
 - "policyName": "organization/allow",
 - "input": {
 - "user": "charlie",
 - "action": "edit",
 - "component": "component_A",
 - "project": "project_A",
 - "organization": "org_A"
 - }
 -}</stringProp> - <stringProp name="Argument.metadata">=</stringProp> + <boolProp name="HTTPSampler.postBodyRaw">false</boolProp> + <elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" testname="User Defined Variables"> + <collectionProp name="Arguments.arguments"/> + </elementProp> + </HTTPSamplerProxy> + <hashTree> + <HeaderManager guiclass="HeaderPanel" testclass="HeaderManager" testname="HTTP Header Manager" enabled="true"> + <collectionProp name="HeaderManager.headers"> + <elementProp name="" elementType="Header"> + <stringProp name="Header.name">Content-Type</stringProp> + <stringProp name="Header.value">application/json</stringProp> + </elementProp> + </collectionProp> + </HeaderManager> + <hashTree/> + <AuthManager guiclass="AuthPanel" testclass="AuthManager" testname="HTTP Authorization Manager" enabled="true"> + <collectionProp name="AuthManager.auth_list"> + <elementProp name="" elementType="Authorization"> + <stringProp name="Authorization.url">${HTTP}://${PAP_HOST}:${PAP_PORT}/policy/pap/v1</stringProp> + <stringProp name="Authorization.username">${PAP_USER}</stringProp> + <stringProp name="Authorization.password">${PAP_PASSWORD}</stringProp> + <stringProp name="Authorization.domain"></stringProp> + <stringProp name="Authorization.realm"></stringProp> </elementProp> </collectionProp> + <boolProp name="AuthManager.clearEachIteration">true</boolProp> + <boolProp name="AuthManager.controlledByThreadGroup">false</boolProp> + </AuthManager> + <hashTree/> + </hashTree> + <HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="Undeploy Collab Policy" enabled="true"> + <intProp name="HTTPSampler.concurrentPool">6</intProp> + <stringProp name="HTTPSampler.domain">${PAP_HOST}</stringProp> + <stringProp name="HTTPSampler.port">${PAP_PORT}</stringProp> + <stringProp name="HTTPSampler.protocol">${HTTP}</stringProp> + <stringProp name="HTTPSampler.path">policy/pap/v1/pdps/policies/collab/versions/1.0.0</stringProp> + <boolProp name="HTTPSampler.follow_redirects">true</boolProp> + <stringProp name="HTTPSampler.method">DELETE</stringProp> + <boolProp name="HTTPSampler.use_keepalive">true</boolProp> + <boolProp name="HTTPSampler.postBodyRaw">false</boolProp> + <elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" testname="User Defined Variables"> + <collectionProp name="Arguments.arguments"/> </elementProp> </HTTPSamplerProxy> <hashTree> - <ResponseAssertion guiclass="AssertionGui" testclass="ResponseAssertion" testname="Response Assertion" enabled="true"> - <collectionProp name="Asserion.test_strings"> - <stringProp name="49586">200</stringProp> + <HeaderManager guiclass="HeaderPanel" testclass="HeaderManager" testname="HTTP Header Manager" enabled="true"> + <collectionProp name="HeaderManager.headers"> + <elementProp name="" elementType="Header"> + <stringProp name="Header.name">Content-Type</stringProp> + <stringProp name="Header.value">application/json</stringProp> + </elementProp> </collectionProp> - <stringProp name="Assertion.custom_message"></stringProp> - <stringProp name="Assertion.test_field">Assertion.response_code</stringProp> - <boolProp name="Assertion.assume_success">false</boolProp> - <intProp name="Assertion.test_type">8</intProp> - </ResponseAssertion> + </HeaderManager> <hashTree/> - <ResponseAssertion guiclass="AssertionGui" testclass="ResponseAssertion" testname="Response Assertion" enabled="true"> - <collectionProp name="Asserion.test_strings"> - <stringProp name="2094604">DENY</stringProp> + <AuthManager guiclass="AuthPanel" testclass="AuthManager" testname="HTTP Authorization Manager" enabled="true"> + <collectionProp name="AuthManager.auth_list"> + <elementProp name="" elementType="Authorization"> + <stringProp name="Authorization.url">${HTTP}://${PAP_HOST}:${PAP_PORT}/policy/pap/v1</stringProp> + <stringProp name="Authorization.username">${PAP_USER}</stringProp> + <stringProp name="Authorization.password">${PAP_PASSWORD}</stringProp> + <stringProp name="Authorization.domain"></stringProp> + <stringProp name="Authorization.realm"></stringProp> + </elementProp> </collectionProp> - <stringProp name="Assertion.custom_message"></stringProp> - <stringProp name="Assertion.test_field">Assertion.response_data</stringProp> - <boolProp name="Assertion.assume_success">false</boolProp> - <intProp name="Assertion.test_type">2</intProp> - </ResponseAssertion> + <boolProp name="AuthManager.clearEachIteration">true</boolProp> + <boolProp name="AuthManager.controlledByThreadGroup">false</boolProp> + </AuthManager> + <hashTree/> + </hashTree> + <HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="Undeploy Conflict Policy" enabled="true"> + <intProp name="HTTPSampler.concurrentPool">6</intProp> + <stringProp name="HTTPSampler.domain">${PAP_HOST}</stringProp> + <stringProp name="HTTPSampler.port">${PAP_PORT}</stringProp> + <stringProp name="HTTPSampler.protocol">${HTTP}</stringProp> + <stringProp name="HTTPSampler.path">policy/pap/v1/pdps/policies/conflict/versions/1.0.0</stringProp> + <boolProp name="HTTPSampler.follow_redirects">true</boolProp> + <stringProp name="HTTPSampler.method">DELETE</stringProp> + <boolProp name="HTTPSampler.use_keepalive">true</boolProp> + <boolProp name="HTTPSampler.postBodyRaw">false</boolProp> + <elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" testname="User Defined Variables"> + <collectionProp name="Arguments.arguments"/> + </elementProp> + </HTTPSamplerProxy> + <hashTree> + <HeaderManager guiclass="HeaderPanel" testclass="HeaderManager" testname="HTTP Header Manager" enabled="true"> + <collectionProp name="HeaderManager.headers"> + <elementProp name="" elementType="Header"> + <stringProp name="Header.name">Content-Type</stringProp> + <stringProp name="Header.value">application/json</stringProp> + </elementProp> + </collectionProp> + </HeaderManager> + <hashTree/> + <AuthManager guiclass="AuthPanel" testclass="AuthManager" testname="HTTP Authorization Manager" enabled="true"> + <collectionProp name="AuthManager.auth_list"> + <elementProp name="" elementType="Authorization"> + <stringProp name="Authorization.url">${HTTP}://${PAP_HOST}:${PAP_PORT}/policy/pap/v1</stringProp> + <stringProp name="Authorization.username">${PAP_USER}</stringProp> + <stringProp name="Authorization.password">${PAP_PASSWORD}</stringProp> + <stringProp name="Authorization.domain"></stringProp> + <stringProp name="Authorization.realm"></stringProp> + </elementProp> + </collectionProp> + <boolProp name="AuthManager.clearEachIteration">true</boolProp> + <boolProp name="AuthManager.controlledByThreadGroup">false</boolProp> + </AuthManager> + <hashTree/> + </hashTree> + <HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="Undeploy Zone Policy" enabled="true"> + <intProp name="HTTPSampler.concurrentPool">6</intProp> + <stringProp name="HTTPSampler.domain">${PAP_HOST}</stringProp> + <stringProp name="HTTPSampler.port">${PAP_PORT}</stringProp> + <stringProp name="HTTPSampler.protocol">${HTTP}</stringProp> + <stringProp name="HTTPSampler.path">policy/pap/v1/pdps/policies/zone/versions/1.0.0</stringProp> + <boolProp name="HTTPSampler.follow_redirects">true</boolProp> + <stringProp name="HTTPSampler.method">DELETE</stringProp> + <boolProp name="HTTPSampler.use_keepalive">true</boolProp> + <boolProp name="HTTPSampler.postBodyRaw">false</boolProp> + <elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" testname="User Defined Variables"> + <collectionProp name="Arguments.arguments"/> + </elementProp> + </HTTPSamplerProxy> + <hashTree> + <HeaderManager guiclass="HeaderPanel" testclass="HeaderManager" testname="HTTP Header Manager" enabled="true"> + <collectionProp name="HeaderManager.headers"> + <elementProp name="" elementType="Header"> + <stringProp name="Header.name">Content-Type</stringProp> + <stringProp name="Header.value">application/json</stringProp> + </elementProp> + </collectionProp> + </HeaderManager> + <hashTree/> + <AuthManager guiclass="AuthPanel" testclass="AuthManager" testname="HTTP Authorization Manager" enabled="true"> + <collectionProp name="AuthManager.auth_list"> + <elementProp name="" elementType="Authorization"> + <stringProp name="Authorization.url">${HTTP}://${PAP_HOST}:${PAP_PORT}/policy/pap/v1</stringProp> + <stringProp name="Authorization.username">${PAP_USER}</stringProp> + <stringProp name="Authorization.password">${PAP_PASSWORD}</stringProp> + <stringProp name="Authorization.domain"></stringProp> + <stringProp name="Authorization.realm"></stringProp> + </elementProp> + </collectionProp> + <boolProp name="AuthManager.clearEachIteration">true</boolProp> + <boolProp name="AuthManager.controlledByThreadGroup">false</boolProp> + </AuthManager> + <hashTree/> + </hashTree> + <HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="Delete Role Policy" enabled="true"> + <intProp name="HTTPSampler.concurrentPool">6</intProp> + <stringProp name="HTTPSampler.domain">${API_HOST}</stringProp> + <stringProp name="HTTPSampler.port">${API_PORT}</stringProp> + <stringProp name="HTTPSampler.protocol">${HTTP}</stringProp> + <stringProp name="HTTPSampler.path">policy/api/v1/policytypes/onap.policies.native.opa/versions/1.0.0/policies/role/versions/1.0.0</stringProp> + <boolProp name="HTTPSampler.follow_redirects">true</boolProp> + <stringProp name="HTTPSampler.method">DELETE</stringProp> + <boolProp name="HTTPSampler.use_keepalive">true</boolProp> + <boolProp name="HTTPSampler.postBodyRaw">false</boolProp> + <elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" testname="User Defined Variables"> + <collectionProp name="Arguments.arguments"/> + </elementProp> + </HTTPSamplerProxy> + <hashTree> + <AuthManager guiclass="AuthPanel" testclass="AuthManager" testname="HTTP Authorization Manager" enabled="true"> + <collectionProp name="AuthManager.auth_list"> + <elementProp name="" elementType="Authorization"> + <stringProp name="Authorization.url">${HTTP}://${API_HOST}:${API_PORT}/policy/api/v1</stringProp> + <stringProp name="Authorization.username">${API_USER}</stringProp> + <stringProp name="Authorization.password">${API_PASSWORD}</stringProp> + <stringProp name="Authorization.domain"></stringProp> + <stringProp name="Authorization.realm"></stringProp> + </elementProp> + </collectionProp> + <boolProp name="AuthManager.clearEachIteration">true</boolProp> + <boolProp name="AuthManager.controlledByThreadGroup">false</boolProp> + </AuthManager> + <hashTree/> + </hashTree> + <HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="Delete Collab Policy" enabled="true"> + <intProp name="HTTPSampler.concurrentPool">6</intProp> + <stringProp name="HTTPSampler.domain">${API_HOST}</stringProp> + <stringProp name="HTTPSampler.port">${API_PORT}</stringProp> + <stringProp name="HTTPSampler.protocol">${HTTP}</stringProp> + <stringProp name="HTTPSampler.path">policy/api/v1/policytypes/onap.policies.native.opa/versions/1.0.0/policies/collab/versions/1.0.0</stringProp> + <boolProp name="HTTPSampler.follow_redirects">true</boolProp> + <stringProp name="HTTPSampler.method">DELETE</stringProp> + <boolProp name="HTTPSampler.use_keepalive">true</boolProp> + <boolProp name="HTTPSampler.postBodyRaw">false</boolProp> + <elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" testname="User Defined Variables"> + <collectionProp name="Arguments.arguments"/> + </elementProp> + </HTTPSamplerProxy> + <hashTree> + <AuthManager guiclass="AuthPanel" testclass="AuthManager" testname="HTTP Authorization Manager" enabled="true"> + <collectionProp name="AuthManager.auth_list"> + <elementProp name="" elementType="Authorization"> + <stringProp name="Authorization.url">${HTTP}://${API_HOST}:${API_PORT}/policy/api/v1</stringProp> + <stringProp name="Authorization.username">${API_USER}</stringProp> + <stringProp name="Authorization.password">${API_PASSWORD}</stringProp> + <stringProp name="Authorization.domain"></stringProp> + <stringProp name="Authorization.realm"></stringProp> + </elementProp> + </collectionProp> + <boolProp name="AuthManager.clearEachIteration">true</boolProp> + <boolProp name="AuthManager.controlledByThreadGroup">false</boolProp> + </AuthManager> + <hashTree/> + </hashTree> + <HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="Delete Conflict Policy" enabled="true"> + <intProp name="HTTPSampler.concurrentPool">6</intProp> + <stringProp name="HTTPSampler.domain">${API_HOST}</stringProp> + <stringProp name="HTTPSampler.port">${API_PORT}</stringProp> + <stringProp name="HTTPSampler.protocol">${HTTP}</stringProp> + <stringProp name="HTTPSampler.path">policy/api/v1/policytypes/onap.policies.native.opa/versions/1.0.0/policies/conflict/versions/1.0.0</stringProp> + <boolProp name="HTTPSampler.follow_redirects">true</boolProp> + <stringProp name="HTTPSampler.method">DELETE</stringProp> + <boolProp name="HTTPSampler.use_keepalive">true</boolProp> + <boolProp name="HTTPSampler.postBodyRaw">false</boolProp> + <elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" testname="User Defined Variables"> + <collectionProp name="Arguments.arguments"/> + </elementProp> + </HTTPSamplerProxy> + <hashTree> + <AuthManager guiclass="AuthPanel" testclass="AuthManager" testname="HTTP Authorization Manager" enabled="true"> + <collectionProp name="AuthManager.auth_list"> + <elementProp name="" elementType="Authorization"> + <stringProp name="Authorization.url">${HTTP}://${API_HOST}:${API_PORT}/policy/api/v1</stringProp> + <stringProp name="Authorization.username">${API_USER}</stringProp> + <stringProp name="Authorization.password">${API_PASSWORD}</stringProp> + <stringProp name="Authorization.domain"></stringProp> + <stringProp name="Authorization.realm"></stringProp> + </elementProp> + </collectionProp> + <boolProp name="AuthManager.clearEachIteration">true</boolProp> + <boolProp name="AuthManager.controlledByThreadGroup">false</boolProp> + </AuthManager> + <hashTree/> + </hashTree> + <HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="Delete Zone Policy" enabled="true"> + <intProp name="HTTPSampler.concurrentPool">6</intProp> + <stringProp name="HTTPSampler.domain">${API_HOST}</stringProp> + <stringProp name="HTTPSampler.port">${API_PORT}</stringProp> + <stringProp name="HTTPSampler.protocol">${HTTP}</stringProp> + <stringProp name="HTTPSampler.path">policy/api/v1/policytypes/onap.policies.native.opa/versions/1.0.0/policies/zone/versions/1.0.0</stringProp> + <boolProp name="HTTPSampler.follow_redirects">true</boolProp> + <stringProp name="HTTPSampler.method">DELETE</stringProp> + <boolProp name="HTTPSampler.use_keepalive">true</boolProp> + <boolProp name="HTTPSampler.postBodyRaw">false</boolProp> + <elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" testname="User Defined Variables"> + <collectionProp name="Arguments.arguments"/> + </elementProp> + </HTTPSamplerProxy> + <hashTree> + <AuthManager guiclass="AuthPanel" testclass="AuthManager" testname="HTTP Authorization Manager" enabled="true"> + <collectionProp name="AuthManager.auth_list"> + <elementProp name="" elementType="Authorization"> + <stringProp name="Authorization.url">${HTTP}://${API_HOST}:${API_PORT}/policy/api/v1</stringProp> + <stringProp name="Authorization.username">${API_USER}</stringProp> + <stringProp name="Authorization.password">${API_PASSWORD}</stringProp> + <stringProp name="Authorization.domain"></stringProp> + <stringProp name="Authorization.realm"></stringProp> + </elementProp> + </collectionProp> + <boolProp name="AuthManager.clearEachIteration">true</boolProp> + <boolProp name="AuthManager.controlledByThreadGroup">false</boolProp> + </AuthManager> <hashTree/> </hashTree> - <AuthManager guiclass="AuthPanel" testclass="AuthManager" testname="HTTP Authorization Manager" enabled="true"> - <collectionProp name="AuthManager.auth_list"> - <elementProp name="" elementType="Authorization"> - <stringProp name="Authorization.url">${HTTP}://${OPA_PDP_HOST}:${OPA_PDP_PORT}/policy/pdpx/v1</stringProp> - <stringProp name="Authorization.username">${OPA_PDP_USER}</stringProp> - <stringProp name="Authorization.password">${OPA_PDP_PASSWORD}</stringProp> - <stringProp name="Authorization.domain"></stringProp> - <stringProp name="Authorization.realm"></stringProp> - </elementProp> - </collectionProp> - <boolProp name="AuthManager.clearEachIteration">true</boolProp> - <boolProp name="AuthManager.controlledByThreadGroup">false</boolProp> - </AuthManager> - <hashTree/> <ResultCollector guiclass="ViewResultsFullVisualizer" testclass="ResultCollector" testname="View Results Tree" enabled="true"> <boolProp name="ResultCollector.error_logging">false</boolProp> <objProp> @@ -749,11 +1635,11 @@ if (prev.getResponseCode() == '200') { <connectTime>true</connectTime> </value> </objProp> - <stringProp name="filename">/tmp/pdpx_perf_decisions.log</stringProp> + <stringProp name="filename">/tmp/pdpo_perf_deployment.log</stringProp> </ResultCollector> <hashTree/> </hashTree> - <ResultCollector guiclass="SummaryReport" testclass="ResultCollector" testname="Summary Report"> + <ResultCollector guiclass="SummaryReport" testclass="ResultCollector" testname="Summary Report" enabled="true"> <boolProp name="ResultCollector.error_logging">false</boolProp> <objProp> <name>saveConfig</name> @@ -787,11 +1673,11 @@ if (prev.getResponseCode() == '200') { <connectTime>true</connectTime> </value> </objProp> - <stringProp name="filename">/tmp/pdpx_perf_summaryReport.log</stringProp> + <stringProp name="filename">/tmp/pdpo_perf_summaryReport.log</stringProp> <boolProp name="useGroupName">true</boolProp> </ResultCollector> <hashTree/> - <ResultCollector guiclass="ViewResultsFullVisualizer" testclass="ResultCollector" testname="View Results Tree"> + <ResultCollector guiclass="ViewResultsFullVisualizer" testclass="ResultCollector" testname="View Results Tree" enabled="true"> <boolProp name="ResultCollector.error_logging">false</boolProp> <objProp> <name>saveConfig</name> @@ -825,7 +1711,7 @@ if (prev.getResponseCode() == '200') { <connectTime>true</connectTime> </value> </objProp> - <stringProp name="filename">/tmp/pdpx_perf_resultsTree.log</stringProp> + <stringProp name="filename">/tmp/pdpo_perf_resultsTree.log</stringProp> </ResultCollector> <hashTree/> <ResultCollector guiclass="TableVisualizer" testclass="ResultCollector" testname="View Results in Table" enabled="true"> @@ -862,7 +1748,7 @@ if (prev.getResponseCode() == '200') { <connectTime>true</connectTime> </value> </objProp> - <stringProp name="filename">/tmp/pdpx_perf_resultsTable.log</stringProp> + <stringProp name="filename">/tmp/pdpo_perf_resultsTable.log</stringProp> </ResultCollector> <hashTree/> </hashTree> diff --git a/testsuites/run-s3p-test.sh b/testsuites/run-s3p-test.sh index 85b9f08..5cf9267 100644 --- a/testsuites/run-s3p-test.sh +++ b/testsuites/run-s3p-test.sh @@ -1,6 +1,6 @@ #!/bin/bash # ============LICENSE_START======================================================= -# Copyright (C) 2024 Deutsche Telekom Intellectual Property. All rights reserved. +# Copyright (C) 2024-2025 Deutsche Telekom 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. @@ -22,28 +22,43 @@ if [ -z "${WORKSPACE}" ]; then export WORKSPACE=$(git rev-parse --show-toplevel) fi +export PROJECT="opa" export TESTDIR=${WORKSPACE}/testsuites export OPA_PERF_TEST_FILE=$TESTDIR/performance/src/main/resources/testplans/perf.jmx export OPA_STAB_TEST_FILE=$TESTDIR/stability/src/main/resources/testplans/stability.jmx -if [ $1 == "run" ] -then - - mkdir automate-s3p-test;cd automate-s3p-test; - git clone "https://gerrit.onap.org/r/policy/docker" - cd docker/csit - - if [ $2 == "performance" ] - then - bash start-s3p-tests.sh run $OPA_PERF_TEST_FILE opa-pdp; - elif [ $2 == "stability" ] - then - bash start-s3p-tests.sh run $OPA_STAB_TEST_FILE opa-pdp; - else - echo "echo Invalid arguments provided. Usage: $0 [option..] {performance | stability}" - fi - -else - echo "Invalid arguments provided. Usage: $0 [option..] {run | uninstall}" -fi +function run_tests() { + local test_file=$1 + + mkdir -p automate-s3p-test + cd automate-s3p-test || exit 1 + git clone "https://gerrit.onap.org/r/policy/docker" + cd docker/csit || exit 1 + + bash run-s3p-tests.sh test "$test_file" $PROJECT +} + +function clean() { + cd $TESTDIR/automate-s3p-test/docker/csit + bash run-s3p-tests.sh clean +} + +echo "=================================" +echo "Triggering S3P test for: $PROJECT" +echo "=================================" +case $1 in + performance) + run_tests "$OPA_PERF_TEST_FILE" + ;; + stability) + run_tests "$OPA_STAB_TEST_FILE" + ;; + clean) + clean + ;; + *) + echo "Invalid arguments provided. Usage: $0 {performance | stability | clean}" + exit 1 + ;; +esac diff --git a/testsuites/stability/src/main/resources/testplans/stability.jmx b/testsuites/stability/src/main/resources/testplans/stability.jmx index a4cda3b..5350c50 100644 --- a/testsuites/stability/src/main/resources/testplans/stability.jmx +++ b/testsuites/stability/src/main/resources/testplans/stability.jmx @@ -31,8 +31,8 @@ <stringProp name="Argument.value">localhost</stringProp> <stringProp name="Argument.metadata">=</stringProp> </elementProp> - <elementProp name="OPA_PDP_HOST" elementType="Argument"> - <stringProp name="Argument.name">OPA_PDP_HOST</stringProp> + <elementProp name="OPA_HOST" elementType="Argument"> + <stringProp name="Argument.name">OPA_HOST</stringProp> <stringProp name="Argument.value">localhost</stringProp> <stringProp name="Argument.metadata">=</stringProp> </elementProp> @@ -46,9 +46,9 @@ <stringProp name="Argument.value">${__P(pap_port, 30003)}</stringProp> <stringProp name="Argument.metadata">=</stringProp> </elementProp> - <elementProp name="OPA_PDP_PORT" elementType="Argument"> - <stringProp name="Argument.name">OPA_PDP_PORT</stringProp> - <stringProp name="Argument.value">${__P(opa_pdp_port, 30012)}</stringProp> + <elementProp name="OPA_PORT" elementType="Argument"> + <stringProp name="Argument.name">OPA_PORT</stringProp> + <stringProp name="Argument.value">${__P(opa_port, 30012)}</stringProp> <stringProp name="Argument.metadata">=</stringProp> </elementProp> <elementProp name="API_USER" elementType="Argument"> @@ -100,7 +100,599 @@ </collectionProp> </HeaderManager> <hashTree/> - <ThreadGroup guiclass="ThreadGroupGui" testclass="ThreadGroup" testname="Policy OPA PDP Health Check" enabled="true"> + <SetupThreadGroup guiclass="SetupThreadGroupGui" testclass="SetupThreadGroup" testname="setUp Thread Group" enabled="true"> + <intProp name="ThreadGroup.num_threads">1</intProp> + <intProp name="ThreadGroup.ramp_time">1</intProp> + <boolProp name="ThreadGroup.same_user_on_next_iteration">true</boolProp> + <stringProp name="ThreadGroup.on_sample_error">continue</stringProp> + <elementProp name="ThreadGroup.main_controller" elementType="LoopController" guiclass="LoopControlPanel" testclass="LoopController" testname="Loop Controller"> + <stringProp name="LoopController.loops">1</stringProp> + <boolProp name="LoopController.continue_forever">false</boolProp> + </elementProp> + </SetupThreadGroup> + <hashTree> + <HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="Create Role Policy" enabled="true"> + <intProp name="HTTPSampler.concurrentPool">6</intProp> + <stringProp name="HTTPSampler.domain">${API_HOST}</stringProp> + <stringProp name="HTTPSampler.port">${API_PORT}</stringProp> + <stringProp name="HTTPSampler.protocol">${HTTP}</stringProp> + <stringProp name="HTTPSampler.path">policy/api/v1/policytypes/onap.policies.native.opa/versions/1.0.0/policies</stringProp> + <boolProp name="HTTPSampler.follow_redirects">true</boolProp> + <stringProp name="HTTPSampler.method">POST</stringProp> + <boolProp name="HTTPSampler.use_keepalive">true</boolProp> + <boolProp name="HTTPSampler.postBodyRaw">true</boolProp> + <elementProp name="HTTPsampler.Arguments" elementType="Arguments"> + <collectionProp name="Arguments.arguments"> + <elementProp name="" elementType="HTTPArgument"> + <boolProp name="HTTPArgument.always_encode">false</boolProp> + <stringProp name="Argument.value">tosca_definitions_version: tosca_simple_yaml_1_1_0
 +topology_template:
 + policies:
 + - role:
 + type: onap.policies.native.opa
 + type_version: 1.0.0
 + properties:
 + data:
 + node.role: ewogICAgInVzZXJfcm9sZXMiOiB7CiAgICAgICAgImFsaWNlIjogWwogICAgICAgICAgICAiYWRtaW4iCiAgICAgICAgXSwKICAgICAgICAiYm9iIjogWwogICAgICAgICAgICAiZW1wbG95ZWUiLAogICAgICAgICAgICAiYmlsbGluZyIKICAgICAgICBdLAogICAgICAgICJldmUiOiBbCiAgICAgICAgICAgICJjdXN0b21lciIKICAgICAgICBdCiAgICB9LAogICAgInJvbGVfZ3JhbnRzIjogewogICAgICAgICJjdXN0b21lciI6IFsKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgImFjdGlvbiI6ICJyZWFkIiwKICAgICAgICAgICAgICAgICJ0eXBlIjogImRvZyIKICAgICAgICAgICAgfSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgImFjdGlvbiI6ICJyZWFkIiwKICAgICAgICAgICAgICAgICJ0eXBlIjogImNhdCIKICAgICAgICAgICAgfSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgImFjdGlvbiI6ICJhZG9wdCIsCiAgICAgICAgICAgICAgICAidHlwZSI6ICJkb2ciCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICJhY3Rpb24iOiAiYWRvcHQiLAogICAgICAgICAgICAgICAgInR5cGUiOiAiY2F0IgogICAgICAgICAgICB9CiAgICAgICAgXSwKICAgICAgICAiZW1wbG95ZWUiOiBbCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICJhY3Rpb24iOiAicmVhZCIsCiAgICAgICAgICAgICAgICAidHlwZSI6ICJkb2ciCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICJhY3Rpb24iOiAicmVhZCIsCiAgICAgICAgICAgICAgICAidHlwZSI6ICJjYXQiCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICJhY3Rpb24iOiAidXBkYXRlIiwKICAgICAgICAgICAgICAgICJ0eXBlIjogImRvZyIKICAgICAgICAgICAgfSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgImFjdGlvbiI6ICJ1cGRhdGUiLAogICAgICAgICAgICAgICAgInR5cGUiOiAiY2F0IgogICAgICAgICAgICB9CiAgICAgICAgXSwKICAgICAgICAiYmlsbGluZyI6IFsKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgImFjdGlvbiI6ICJyZWFkIiwKICAgICAgICAgICAgICAgICJ0eXBlIjogImZpbmFuY2UiCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICJhY3Rpb24iOiAidXBkYXRlIiwKICAgICAgICAgICAgICAgICJ0eXBlIjogImZpbmFuY2UiCiAgICAgICAgICAgIH0KICAgICAgICBdCiAgICB9Cn0K
 + policy:
 + role: cGFja2FnZSByb2xlCgppbXBvcnQgcmVnby52MQoKIyBCeSBkZWZhdWx0LCBkZW55IHJlcXVlc3RzLgpkZWZhdWx0IGFsbG93IDo9IGZhbHNlCgojIEFsbG93IGFkbWlucyB0byBkbyBhbnl0aGluZy4KYWxsb3cgaWYgdXNlcl9pc19hZG1pbgoKIyBBbGxvdyB0aGUgYWN0aW9uIGlmIHRoZSB1c2VyIGlzIGdyYW50ZWQgcGVybWlzc2lvbiB0byBwZXJmb3JtIHRoZSBhY3Rpb24uCmFsbG93IGlmIHsKICAgICAgICAjIEZpbmQgZ3JhbnRzIGZvciB0aGUgdXNlci4KICAgICAgICBzb21lIGdyYW50IGluIHVzZXJfaXNfZ3JhbnRlZAoKICAgICAgICAjIENoZWNrIGlmIHRoZSBncmFudCBwZXJtaXRzIHRoZSBhY3Rpb24uCiAgICAgICAgaW5wdXQuYWN0aW9uID09IGdyYW50LmFjdGlvbgogICAgICAgIGlucHV0LnR5cGUgPT0gZ3JhbnQudHlwZQp9CgojIHVzZXJfaXNfYWRtaW4gaXMgdHJ1ZSBpZiAiYWRtaW4iIGlzIGFtb25nIHRoZSB1c2VyJ3Mgcm9sZXMgYXMgcGVyIGRhdGEudXNlcl9yb2xlcwp1c2VyX2lzX2FkbWluIGlmICJhZG1pbiIgaW4gZGF0YS5ub2RlLnJvbGUudXNlcl9yb2xlc1tpbnB1dC51c2VyXQoKIyB1c2VyX2lzX2dyYW50ZWQgaXMgYSBzZXQgb2YgZ3JhbnRzIGZvciB0aGUgdXNlciBpZGVudGlmaWVkIGluIHRoZSByZXF1ZXN0LgojIFRoZSBgZ3JhbnRgIHdpbGwgYmUgY29udGFpbmVkIGlmIHRoZSBzZXQgYHVzZXJfaXNfZ3JhbnRlZGAgZm9yIGV2ZXJ5Li4uCnVzZXJfaXNfZ3JhbnRlZCBjb250YWlucyBncmFudCBpZiB7CiAgICAgICAgIyBgcm9sZWAgYXNzaWduZWQgYW4gZWxlbWVudCBvZiB0aGUgdXNlcl9yb2xlcyBmb3IgdGhpcyB1c2VyLi4uCiAgICAgICAgc29tZSByb2xlIGluIGRhdGEubm9kZS5yb2xlLnVzZXJfcm9sZXNbaW5wdXQudXNlcl0KCiAgICAgICAgIyBgZ3JhbnRgIGFzc2lnbmVkIGEgc2luZ2xlIGdyYW50IGZyb20gdGhlIGdyYW50cyBsaXN0IGZvciAncm9sZScuLi4KICAgICAgICBzb21lIGdyYW50IGluIGRhdGEubm9kZS5yb2xlLnJvbGVfZ3JhbnRzW3JvbGVdCn0KCiMgICAgICAgKiBSZWdvIGNvbXBhcmlzb24gdG8gb3RoZXIgc3lzdGVtczogaHR0cHM6Ly93d3cub3BlbnBvbGljeWFnZW50Lm9yZy9kb2NzL2xhdGVzdC9jb21wYXJpc29uLXRvLW90aGVyLXN5c3RlbXMvCiMgICAgICAgKiBSZWdvIEl0ZXJhdGlvbjogaHR0cHM6Ly93d3cub3BlbnBvbGljeWFnZW50Lm9yZy9kb2NzL2xhdGVzdC8jaXRlcmF0aW9u
 + name: role
 + version: 1.0.0
 + metadata:
 + policy-id: role
 + policy-version: 1.0.0
 +
 +
 +</stringProp> + <stringProp name="Argument.metadata">=</stringProp> + </elementProp> + </collectionProp> + </elementProp> + </HTTPSamplerProxy> + <hashTree> + <AuthManager guiclass="AuthPanel" testclass="AuthManager" testname="HTTP Authorization Manager" enabled="true"> + <collectionProp name="AuthManager.auth_list"> + <elementProp name="" elementType="Authorization"> + <stringProp name="Authorization.url">${HTTP}://${API_HOST}:${API_PORT}/policy/api/v1</stringProp> + <stringProp name="Authorization.username">${API_USER}</stringProp> + <stringProp name="Authorization.password">${API_PASSWORD}</stringProp> + <stringProp name="Authorization.domain"></stringProp> + <stringProp name="Authorization.realm"></stringProp> + </elementProp> + </collectionProp> + <boolProp name="AuthManager.clearEachIteration">true</boolProp> + <boolProp name="AuthManager.controlledByThreadGroup">false</boolProp> + </AuthManager> + <hashTree/> + <HeaderManager guiclass="HeaderPanel" testclass="HeaderManager" testname="HTTP Header Manager" enabled="true"> + <collectionProp name="HeaderManager.headers"> + <elementProp name="" elementType="Header"> + <stringProp name="Header.name">Content-Type</stringProp> + <stringProp name="Header.value">application/yaml</stringProp> + </elementProp> + </collectionProp> + </HeaderManager> + <hashTree/> + <ResponseAssertion guiclass="AssertionGui" testclass="ResponseAssertion" testname="Response Assertion" enabled="true"> + <collectionProp name="Asserion.test_strings"> + <stringProp name="49587">201</stringProp> + </collectionProp> + <stringProp name="Assertion.custom_message"></stringProp> + <stringProp name="Assertion.test_field">Assertion.response_code</stringProp> + <boolProp name="Assertion.assume_success">false</boolProp> + <intProp name="Assertion.test_type">8</intProp> + </ResponseAssertion> + <hashTree/> + </hashTree> + <HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="Create Collab Policy" enabled="true"> + <intProp name="HTTPSampler.concurrentPool">6</intProp> + <stringProp name="HTTPSampler.domain">${API_HOST}</stringProp> + <stringProp name="HTTPSampler.port">${API_PORT}</stringProp> + <stringProp name="HTTPSampler.protocol">${HTTP}</stringProp> + <stringProp name="HTTPSampler.path">policy/api/v1/policytypes/onap.policies.native.opa/versions/1.0.0/policies</stringProp> + <boolProp name="HTTPSampler.follow_redirects">true</boolProp> + <stringProp name="HTTPSampler.method">POST</stringProp> + <boolProp name="HTTPSampler.use_keepalive">true</boolProp> + <boolProp name="HTTPSampler.postBodyRaw">true</boolProp> + <elementProp name="HTTPsampler.Arguments" elementType="Arguments"> + <collectionProp name="Arguments.arguments"> + <elementProp name="" elementType="HTTPArgument"> + <boolProp name="HTTPArgument.always_encode">false</boolProp> + <stringProp name="Argument.value">tosca_definitions_version: tosca_simple_yaml_1_1_0
 +topology_template:
 + policies:
 + - collab:
 + type: onap.policies.native.opa
 + type_version: 1.0.0
 + properties:
 + data:
 + node.collab.action: ewogICAgInVzZXJfcm9sZXMiOiB7CiAgICAgICAgImFsaWNlIjogWwogICAgICAgICAgICAiYWRtaW4iCiAgICAgICAgXSwKICAgICAgICAiYm9iIjogWwogICAgICAgICAgICAiZWRpdG9yIgogICAgICAgIF0sCiAgICAgICAgImNoYXJsaWUiOiBbCiAgICAgICAgICAgICJ2aWV3ZXIiCiAgICAgICAgXQogICAgfSwKICAgICJyb2xlX3Blcm1pc3Npb25zIjogewogICAgICAgICJhZG1pbiI6IHsKICAgICAgICAgICAgImFjdGlvbnMiOiBbCiAgICAgICAgICAgICAgICAicmVhZCIsCiAgICAgICAgICAgICAgICAid3JpdGUiLAogICAgICAgICAgICAgICAgImRlbGV0ZSIKICAgICAgICAgICAgXSwKICAgICAgICAgICAgInJlc291cmNlcyI6IFsKICAgICAgICAgICAgICAgICJzZXJ2ZXIiLAogICAgICAgICAgICAgICAgImRhdGFiYXNlIgogICAgICAgICAgICBdCiAgICAgICAgfSwKICAgICAgICAiZWRpdG9yIjogewogICAgICAgICAgICAiYWN0aW9ucyI6IFsKICAgICAgICAgICAgICAgICJyZWFkIiwKICAgICAgICAgICAgICAgICJ3cml0ZSIKICAgICAgICAgICAgXSwKICAgICAgICAgICAgInJlc291cmNlcyI6IFsKICAgICAgICAgICAgICAgICJzZXJ2ZXIiCiAgICAgICAgICAgIF0KICAgICAgICB9LAogICAgICAgICJ2aWV3ZXIiOiB7CiAgICAgICAgICAgICJhY3Rpb25zIjogWwogICAgICAgICAgICAgICAgInJlYWQiCiAgICAgICAgICAgIF0sCiAgICAgICAgICAgICJyZXNvdXJjZXMiOiBbCiAgICAgICAgICAgICAgICAic2VydmVyIgogICAgICAgICAgICBdCiAgICAgICAgfQogICAgfQp9
 + policy:
 + collab.conflict: cGFja2FnZSBjb2xsYWIuY29uZmxpY3QKCmltcG9ydCByZWdvLnYxCgphbGxvdyBpZiB7IGlucHV0Lm5hbWUgPT0gImFsaWNlIiB9CmRlbnkgaWYgeyBpbnB1dC5uYW1lID09ICJhbGljZSIgfQoKIyBkZW55IGV2ZXJ5dGhpbmcgYnkgZGVmYXVsdApkZWZhdWx0IGF1dGh6IDo9IGZhbHNlCgojIGRlbnkgb3ZlcnJpZGVzIGFsbG93CmF1dGh6IGlmIHsKICAgIGFsbG93CiAgICBub3QgZGVueQp9Cg==
 + collab.action: cGFja2FnZSBjb2xsYWIuYWN0aW9uCgppbXBvcnQgcmVnby52MQoKIyBCeSBkZWZhdWx0LCBkZW55IHJlcXVlc3RzLgpkZWZhdWx0IGFsbG93IDo9IGZhbHNlCgoKIyBBbGxvdyB0aGUgYWN0aW9uIGlmIGFkbWluIHJvbGUgaXMgZ3JhbnRlZCBwZXJtaXNzaW9uIHRvIHBlcmZvcm0gdGhlIGFjdGlvbi4KYWxsb3cgaWYgewogICAgc29tZSBpCiAgICBkYXRhLm5vZGUuY29sbGFiLmFjdGlvbi51c2VyX3JvbGVzW2lucHV0LnVzZXJdW2ldID09IHJvbGUKICAgIHNvbWUgagogICAgZGF0YS5ub2RlLmNvbGxhYi5hY3Rpb24ucm9sZV9wZXJtaXNzaW9uc1tyb2xlXS5hY3Rpb25zW2pdID09IGlucHV0LmFjdGlvbgogICAgc29tZSBrCiAgICBkYXRhLm5vZGUuY29sbGFiLmFjdGlvbi5yb2xlX3Blcm1pc3Npb25zW3JvbGVdLnJlc291cmNlc1trXSA9PSBpbnB1dC50eXBlCn0KIyAgICAgICAqIFJlZ28gY29tcGFyaXNvbiB0byBvdGhlciBzeXN0ZW1zOiBodHRwczovL3d3dy5vcGVucG9saWN5YWdlbnQub3JnL2RvY3MvbGF0ZXN0L2NvbXBhcmlzb24tdG8tb3RoZXItc3lzdGVtcy8KIyAgICAgICAqIFJlZ28gSXRlcmF0aW9uOiBodHRwczovL3d3dy5vcGVucG9saWN5YWdlbnQub3JnL2RvY3MvbGF0ZXN0LyNpdGVyYXRpb24=
 + collab: cGFja2FnZSBjb2xsYWIKCmltcG9ydCByZWdvLnYxCmltcG9ydCBkYXRhLmNvbGxhYi5jb25mbGljdAppbXBvcnQgZGF0YS5jb2xsYWIuYWN0aW9uCgpkZWZhdWx0IGFsbG93IDo9IGZhbHNlCmFsbG93IGlmIHsKICAgIGNvbmZsaWN0LmFsbG93CiAgICBhY3Rpb24uYWxsb3cKfQ==
 + name: collab
 + version: 1.0.0
 + metadata:
 + policy-id: collab
 + policy-version: 1.0.0
 +</stringProp> + <stringProp name="Argument.metadata">=</stringProp> + </elementProp> + </collectionProp> + </elementProp> + </HTTPSamplerProxy> + <hashTree> + <AuthManager guiclass="AuthPanel" testclass="AuthManager" testname="HTTP Authorization Manager" enabled="true"> + <collectionProp name="AuthManager.auth_list"> + <elementProp name="" elementType="Authorization"> + <stringProp name="Authorization.url">${HTTP}://${API_HOST}:${API_PORT}/policy/api/v1</stringProp> + <stringProp name="Authorization.username">${API_USER}</stringProp> + <stringProp name="Authorization.password">${API_PASSWORD}</stringProp> + <stringProp name="Authorization.domain"></stringProp> + <stringProp name="Authorization.realm"></stringProp> + </elementProp> + </collectionProp> + <boolProp name="AuthManager.clearEachIteration">true</boolProp> + <boolProp name="AuthManager.controlledByThreadGroup">false</boolProp> + </AuthManager> + <hashTree/> + <HeaderManager guiclass="HeaderPanel" testclass="HeaderManager" testname="HTTP Header Manager" enabled="true"> + <collectionProp name="HeaderManager.headers"> + <elementProp name="" elementType="Header"> + <stringProp name="Header.name">Content-Type</stringProp> + <stringProp name="Header.value">application/yaml</stringProp> + </elementProp> + </collectionProp> + </HeaderManager> + <hashTree/> + <ResponseAssertion guiclass="AssertionGui" testclass="ResponseAssertion" testname="Response Assertion" enabled="true"> + <collectionProp name="Asserion.test_strings"> + <stringProp name="49587">201</stringProp> + </collectionProp> + <stringProp name="Assertion.custom_message"></stringProp> + <stringProp name="Assertion.test_field">Assertion.response_code</stringProp> + <boolProp name="Assertion.assume_success">false</boolProp> + <intProp name="Assertion.test_type">8</intProp> + </ResponseAssertion> + <hashTree/> + </hashTree> + <HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="Create Conflict Policy" enabled="true"> + <intProp name="HTTPSampler.concurrentPool">6</intProp> + <stringProp name="HTTPSampler.domain">${API_HOST}</stringProp> + <stringProp name="HTTPSampler.port">${API_PORT}</stringProp> + <stringProp name="HTTPSampler.protocol">${HTTP}</stringProp> + <stringProp name="HTTPSampler.path">policy/api/v1/policytypes/onap.policies.native.opa/versions/1.0.0/policies</stringProp> + <boolProp name="HTTPSampler.follow_redirects">true</boolProp> + <stringProp name="HTTPSampler.method">POST</stringProp> + <boolProp name="HTTPSampler.use_keepalive">true</boolProp> + <boolProp name="HTTPSampler.postBodyRaw">true</boolProp> + <elementProp name="HTTPsampler.Arguments" elementType="Arguments"> + <collectionProp name="Arguments.arguments"> + <elementProp name="" elementType="HTTPArgument"> + <boolProp name="HTTPArgument.always_encode">false</boolProp> + <stringProp name="Argument.value">tosca_definitions_version: tosca_simple_yaml_1_1_0
 +topology_template:
 + policies:
 + - conflict:
 + type: onap.policies.native.opa
 + type_version: 1.0.0
 + properties:
 + data:
 + policy:
 + conflict: cGFja2FnZSBjb25mbGljdAoKaW1wb3J0IHJlZ28udjEKCmFsbG93IGlmIHsgaW5wdXQubmFtZSA9PSAiYWxpY2UiIH0KZGVueSBpZiB7IGlucHV0Lm5hbWUgPT0gImFsaWNlIiB9CgojIGRlbnkgZXZlcnl0aGluZyBieSBkZWZhdWx0CmRlZmF1bHQgYXV0aHogOj0gZmFsc2UKCiMgZGVueSBvdmVycmlkZXMgYWxsb3cKYXV0aHogaWYgewogICAgYWxsb3cKICAgIG5vdCBkZW55Cn0KCg==
 + name: conflict
 + version: 1.0.0
 + metadata:
 + policy-id: conflict
 + policy-version: 1.0.0
 +</stringProp> + <stringProp name="Argument.metadata">=</stringProp> + </elementProp> + </collectionProp> + </elementProp> + </HTTPSamplerProxy> + <hashTree> + <AuthManager guiclass="AuthPanel" testclass="AuthManager" testname="HTTP Authorization Manager" enabled="true"> + <collectionProp name="AuthManager.auth_list"> + <elementProp name="" elementType="Authorization"> + <stringProp name="Authorization.url">${HTTP}://${API_HOST}:${API_PORT}/policy/api/v1</stringProp> + <stringProp name="Authorization.username">${API_USER}</stringProp> + <stringProp name="Authorization.password">${API_PASSWORD}</stringProp> + <stringProp name="Authorization.domain"></stringProp> + <stringProp name="Authorization.realm"></stringProp> + </elementProp> + </collectionProp> + <boolProp name="AuthManager.clearEachIteration">true</boolProp> + <boolProp name="AuthManager.controlledByThreadGroup">false</boolProp> + </AuthManager> + <hashTree/> + <HeaderManager guiclass="HeaderPanel" testclass="HeaderManager" testname="HTTP Header Manager" enabled="true"> + <collectionProp name="HeaderManager.headers"> + <elementProp name="" elementType="Header"> + <stringProp name="Header.name">Content-Type</stringProp> + <stringProp name="Header.value">application/yaml</stringProp> + </elementProp> + </collectionProp> + </HeaderManager> + <hashTree/> + <ResponseAssertion guiclass="AssertionGui" testclass="ResponseAssertion" testname="Response Assertion" enabled="true"> + <collectionProp name="Asserion.test_strings"> + <stringProp name="49587">201</stringProp> + </collectionProp> + <stringProp name="Assertion.custom_message"></stringProp> + <stringProp name="Assertion.test_field">Assertion.response_code</stringProp> + <boolProp name="Assertion.assume_success">false</boolProp> + <intProp name="Assertion.test_type">8</intProp> + </ResponseAssertion> + <hashTree/> + </hashTree> + <HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="Create Zone Policy" enabled="true"> + <intProp name="HTTPSampler.concurrentPool">6</intProp> + <stringProp name="HTTPSampler.domain">${API_HOST}</stringProp> + <stringProp name="HTTPSampler.port">${API_PORT}</stringProp> + <stringProp name="HTTPSampler.protocol">${HTTP}</stringProp> + <stringProp name="HTTPSampler.path">policy/api/v1/policytypes/onap.policies.native.opa/versions/1.0.0/policies</stringProp> + <boolProp name="HTTPSampler.follow_redirects">true</boolProp> + <stringProp name="HTTPSampler.method">POST</stringProp> + <boolProp name="HTTPSampler.use_keepalive">true</boolProp> + <boolProp name="HTTPSampler.postBodyRaw">true</boolProp> + <elementProp name="HTTPsampler.Arguments" elementType="Arguments"> + <collectionProp name="Arguments.arguments"> + <elementProp name="" elementType="HTTPArgument"> + <boolProp name="HTTPArgument.always_encode">false</boolProp> + <stringProp name="Argument.value">tosca_definitions_version: tosca_simple_yaml_1_1_0
 +topology_template:
 + policies:
 + - zone:
 + type: onap.policies.native.opa
 + type_version: 1.0.0
 + properties:
 + data:
 + node.zone: ewogICAgInpvbmVfYWNjZXNzX2xvZ3MiOiBbCiAgICAgIHsgImxvZ19pZCI6ICJsb2cxIiwgInRpbWVzdGFtcCI6ICIyMDI0LTExLTAxVDA5OjAwOjAwWiIsICJ6b25lX2lkIjogInpvbmVBIiwgImFjY2VzcyI6ICJncmFudGVkIiwgInVzZXIiOiAidXNlcjEiIH0sCiAgICAgIHsgImxvZ19pZCI6ICJsb2cyIiwgInRpbWVzdGFtcCI6ICIyMDI0LTExLTAxVDEwOjMwOjAwWiIsICJ6b25lX2lkIjogInpvbmVBIiwgImFjY2VzcyI6ICJkZW5pZWQiLCAidXNlciI6ICJ1c2VyMiIgfSwKICAgICAgeyAibG9nX2lkIjogImxvZzMiLCAidGltZXN0YW1wIjogIjIwMjQtMTEtMDFUMTE6MDA6MDBaIiwgInpvbmVfaWQiOiAiem9uZUIiLCAiYWNjZXNzIjogImdyYW50ZWQiLCAidXNlciI6ICJ1c2VyMyIgfQogICAgXQp9Cg==
 + policy:
 + zone : cGFja2FnZSB6b25lCgppbXBvcnQgcmVnby52MQoKZGVmYXVsdCBhbGxvdyA6PSBmYWxzZQoKYWxsb3cgaWYgewogICAgaGFzX3pvbmVfYWNjZXNzCiAgICBhY3Rpb25faXNfbG9nX3ZpZXcKfQoKYWN0aW9uX2lzX2xvZ192aWV3IGlmIHsKICAgICJ2aWV3IiBpbiBpbnB1dC5hY3Rpb25zCn0KCmhhc196b25lX2FjY2VzcyBjb250YWlucyBhY2Nlc3NfZGF0YSBpZiB7CiAgICBzb21lIHpvbmVfZGF0YSBpbiBkYXRhLm5vZGUuem9uZS56b25lLnpvbmVfYWNjZXNzX2xvZ3MKICAgIHpvbmVfZGF0YS50aW1lc3RhbXAgPj0gaW5wdXQudGltZV9wZXJpb2QuZnJvbQogICAgem9uZV9kYXRhLnRpbWVzdGFtcCA8IGlucHV0LnRpbWVfcGVyaW9kLnRvCiAgICB6b25lX2RhdGEuem9uZV9pZCA9PSBpbnB1dC56b25lX2lkCiAgICBhY2Nlc3NfZGF0YSA6PSB7ZGF0YXR5cGU6IHpvbmVfZGF0YVtkYXRhdHlwZV0gfCBkYXRhdHlwZSBpbiBpbnB1dC5kYXRhdHlwZXN9Cn0K
 + name: zone
 + version: 1.0.0
 + metadata:
 + policy-id: zone
 + policy-version: 1.0.0
 +
 +</stringProp> + <stringProp name="Argument.metadata">=</stringProp> + </elementProp> + </collectionProp> + </elementProp> + </HTTPSamplerProxy> + <hashTree> + <AuthManager guiclass="AuthPanel" testclass="AuthManager" testname="HTTP Authorization Manager" enabled="true"> + <collectionProp name="AuthManager.auth_list"> + <elementProp name="" elementType="Authorization"> + <stringProp name="Authorization.url">${HTTP}://${API_HOST}:${API_PORT}/policy/api/v1</stringProp> + <stringProp name="Authorization.username">${API_USER}</stringProp> + <stringProp name="Authorization.password">${API_PASSWORD}</stringProp> + <stringProp name="Authorization.domain"></stringProp> + <stringProp name="Authorization.realm"></stringProp> + </elementProp> + </collectionProp> + <boolProp name="AuthManager.clearEachIteration">true</boolProp> + <boolProp name="AuthManager.controlledByThreadGroup">false</boolProp> + </AuthManager> + <hashTree/> + <HeaderManager guiclass="HeaderPanel" testclass="HeaderManager" testname="HTTP Header Manager" enabled="true"> + <collectionProp name="HeaderManager.headers"> + <elementProp name="" elementType="Header"> + <stringProp name="Header.name">Content-Type</stringProp> + <stringProp name="Header.value">application/yaml</stringProp> + </elementProp> + </collectionProp> + </HeaderManager> + <hashTree/> + <ResponseAssertion guiclass="AssertionGui" testclass="ResponseAssertion" testname="Response Assertion" enabled="true"> + <collectionProp name="Asserion.test_strings"> + <stringProp name="49587">201</stringProp> + </collectionProp> + <stringProp name="Assertion.custom_message"></stringProp> + <stringProp name="Assertion.test_field">Assertion.response_code</stringProp> + <boolProp name="Assertion.assume_success">false</boolProp> + <intProp name="Assertion.test_type">8</intProp> + </ResponseAssertion> + <hashTree/> + </hashTree> + <HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="Deploy Role Policy" enabled="true"> + <intProp name="HTTPSampler.concurrentPool">6</intProp> + <stringProp name="HTTPSampler.domain">${PAP_HOST}</stringProp> + <stringProp name="HTTPSampler.port">${PAP_PORT}</stringProp> + <stringProp name="HTTPSampler.protocol">${HTTP}</stringProp> + <stringProp name="HTTPSampler.path">policy/pap/v1/pdps/policies</stringProp> + <boolProp name="HTTPSampler.follow_redirects">true</boolProp> + <stringProp name="HTTPSampler.method">POST</stringProp> + <boolProp name="HTTPSampler.use_keepalive">true</boolProp> + <boolProp name="HTTPSampler.postBodyRaw">true</boolProp> + <elementProp name="HTTPsampler.Arguments" elementType="Arguments"> + <collectionProp name="Arguments.arguments"> + <elementProp name="" elementType="HTTPArgument"> + <boolProp name="HTTPArgument.always_encode">false</boolProp> + <stringProp name="Argument.value">{
 + "policies": [
 + {
 + "policy-id": "role",
 + "policy-version": "1.0.0"
 +
 + }
 + ]
 +}
 +</stringProp> + <stringProp name="Argument.metadata">=</stringProp> + </elementProp> + </collectionProp> + </elementProp> + </HTTPSamplerProxy> + <hashTree> + <AuthManager guiclass="AuthPanel" testclass="AuthManager" testname="HTTP Authorization Manager" enabled="true"> + <collectionProp name="AuthManager.auth_list"> + <elementProp name="" elementType="Authorization"> + <stringProp name="Authorization.url">${HTTP}://${PAP_HOST}:${PAP_PORT}/policy/pap/v1</stringProp> + <stringProp name="Authorization.username">${PAP_USER}</stringProp> + <stringProp name="Authorization.password">${PAP_PASSWORD}</stringProp> + <stringProp name="Authorization.domain"></stringProp> + <stringProp name="Authorization.realm"></stringProp> + </elementProp> + </collectionProp> + <boolProp name="AuthManager.clearEachIteration">true</boolProp> + <boolProp name="AuthManager.controlledByThreadGroup">false</boolProp> + </AuthManager> + <hashTree/> + <HeaderManager guiclass="HeaderPanel" testclass="HeaderManager" testname="HTTP Header Manager" enabled="true"> + <collectionProp name="HeaderManager.headers"> + <elementProp name="" elementType="Header"> + <stringProp name="Header.name">Content-Type</stringProp> + <stringProp name="Header.value">application/json</stringProp> + </elementProp> + </collectionProp> + </HeaderManager> + <hashTree/> + <ResponseAssertion guiclass="AssertionGui" testclass="ResponseAssertion" testname="Response Assertion" enabled="true"> + <collectionProp name="Asserion.test_strings"> + <stringProp name="49588">202</stringProp> + </collectionProp> + <stringProp name="Assertion.custom_message"></stringProp> + <stringProp name="Assertion.test_field">Assertion.response_code</stringProp> + <boolProp name="Assertion.assume_success">false</boolProp> + <intProp name="Assertion.test_type">8</intProp> + </ResponseAssertion> + <hashTree/> + </hashTree> + <HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="Deploy Collab Policy" enabled="true"> + <intProp name="HTTPSampler.concurrentPool">6</intProp> + <stringProp name="HTTPSampler.domain">${PAP_HOST}</stringProp> + <stringProp name="HTTPSampler.port">${PAP_PORT}</stringProp> + <stringProp name="HTTPSampler.protocol">${HTTP}</stringProp> + <stringProp name="HTTPSampler.path">policy/pap/v1/pdps/policies</stringProp> + <boolProp name="HTTPSampler.follow_redirects">true</boolProp> + <stringProp name="HTTPSampler.method">POST</stringProp> + <boolProp name="HTTPSampler.use_keepalive">true</boolProp> + <boolProp name="HTTPSampler.postBodyRaw">true</boolProp> + <elementProp name="HTTPsampler.Arguments" elementType="Arguments"> + <collectionProp name="Arguments.arguments"> + <elementProp name="" elementType="HTTPArgument"> + <boolProp name="HTTPArgument.always_encode">false</boolProp> + <stringProp name="Argument.value">{
 + "policies": [
 + {
 + "policy-id": "collab",
 + "policy-version": "1.0.0"
 +
 + }
 + ]
 +}
 +</stringProp> + <stringProp name="Argument.metadata">=</stringProp> + </elementProp> + </collectionProp> + </elementProp> + </HTTPSamplerProxy> + <hashTree> + <AuthManager guiclass="AuthPanel" testclass="AuthManager" testname="HTTP Authorization Manager" enabled="true"> + <collectionProp name="AuthManager.auth_list"> + <elementProp name="" elementType="Authorization"> + <stringProp name="Authorization.url">${HTTP}://${PAP_HOST}:${PAP_PORT}/policy/pap/v1</stringProp> + <stringProp name="Authorization.username">${PAP_USER}</stringProp> + <stringProp name="Authorization.password">${PAP_PASSWORD}</stringProp> + <stringProp name="Authorization.domain"></stringProp> + <stringProp name="Authorization.realm"></stringProp> + </elementProp> + </collectionProp> + <boolProp name="AuthManager.clearEachIteration">true</boolProp> + <boolProp name="AuthManager.controlledByThreadGroup">false</boolProp> + </AuthManager> + <hashTree/> + <HeaderManager guiclass="HeaderPanel" testclass="HeaderManager" testname="HTTP Header Manager" enabled="true"> + <collectionProp name="HeaderManager.headers"> + <elementProp name="" elementType="Header"> + <stringProp name="Header.name">Content-Type</stringProp> + <stringProp name="Header.value">application/json</stringProp> + </elementProp> + </collectionProp> + </HeaderManager> + <hashTree/> + <ResponseAssertion guiclass="AssertionGui" testclass="ResponseAssertion" testname="Response Assertion" enabled="true"> + <collectionProp name="Asserion.test_strings"> + <stringProp name="49588">202</stringProp> + </collectionProp> + <stringProp name="Assertion.custom_message"></stringProp> + <stringProp name="Assertion.test_field">Assertion.response_code</stringProp> + <boolProp name="Assertion.assume_success">false</boolProp> + <intProp name="Assertion.test_type">8</intProp> + </ResponseAssertion> + <hashTree/> + </hashTree> + <HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="Deploy Conflict Policy" enabled="true"> + <intProp name="HTTPSampler.concurrentPool">6</intProp> + <stringProp name="HTTPSampler.domain">${PAP_HOST}</stringProp> + <stringProp name="HTTPSampler.port">${PAP_PORT}</stringProp> + <stringProp name="HTTPSampler.protocol">${HTTP}</stringProp> + <stringProp name="HTTPSampler.path">policy/pap/v1/pdps/policies</stringProp> + <boolProp name="HTTPSampler.follow_redirects">true</boolProp> + <stringProp name="HTTPSampler.method">POST</stringProp> + <boolProp name="HTTPSampler.use_keepalive">true</boolProp> + <boolProp name="HTTPSampler.postBodyRaw">true</boolProp> + <elementProp name="HTTPsampler.Arguments" elementType="Arguments"> + <collectionProp name="Arguments.arguments"> + <elementProp name="" elementType="HTTPArgument"> + <boolProp name="HTTPArgument.always_encode">false</boolProp> + <stringProp name="Argument.value">{
 + "policies": [
 + {
 + "policy-id": "conflict",
 + "policy-version": "1.0.0"
 +
 + }
 + ]
 +}
 +</stringProp> + <stringProp name="Argument.metadata">=</stringProp> + </elementProp> + </collectionProp> + </elementProp> + </HTTPSamplerProxy> + <hashTree> + <AuthManager guiclass="AuthPanel" testclass="AuthManager" testname="HTTP Authorization Manager" enabled="true"> + <collectionProp name="AuthManager.auth_list"> + <elementProp name="" elementType="Authorization"> + <stringProp name="Authorization.url">${HTTP}://${PAP_HOST}:${PAP_PORT}/policy/pap/v1</stringProp> + <stringProp name="Authorization.username">${PAP_USER}</stringProp> + <stringProp name="Authorization.password">${PAP_PASSWORD}</stringProp> + <stringProp name="Authorization.domain"></stringProp> + <stringProp name="Authorization.realm"></stringProp> + </elementProp> + </collectionProp> + <boolProp name="AuthManager.clearEachIteration">true</boolProp> + <boolProp name="AuthManager.controlledByThreadGroup">false</boolProp> + </AuthManager> + <hashTree/> + <HeaderManager guiclass="HeaderPanel" testclass="HeaderManager" testname="HTTP Header Manager" enabled="true"> + <collectionProp name="HeaderManager.headers"> + <elementProp name="" elementType="Header"> + <stringProp name="Header.name">Content-Type</stringProp> + <stringProp name="Header.value">application/json</stringProp> + </elementProp> + </collectionProp> + </HeaderManager> + <hashTree/> + <ResponseAssertion guiclass="AssertionGui" testclass="ResponseAssertion" testname="Response Assertion" enabled="true"> + <collectionProp name="Asserion.test_strings"> + <stringProp name="49588">202</stringProp> + </collectionProp> + <stringProp name="Assertion.custom_message"></stringProp> + <stringProp name="Assertion.test_field">Assertion.response_code</stringProp> + <boolProp name="Assertion.assume_success">false</boolProp> + <intProp name="Assertion.test_type">8</intProp> + </ResponseAssertion> + <hashTree/> + </hashTree> + <HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="Deploy Zone Policy" enabled="true"> + <intProp name="HTTPSampler.concurrentPool">6</intProp> + <stringProp name="HTTPSampler.domain">${PAP_HOST}</stringProp> + <stringProp name="HTTPSampler.port">${PAP_PORT}</stringProp> + <stringProp name="HTTPSampler.protocol">${HTTP}</stringProp> + <stringProp name="HTTPSampler.path">policy/pap/v1/pdps/policies</stringProp> + <boolProp name="HTTPSampler.follow_redirects">true</boolProp> + <stringProp name="HTTPSampler.method">POST</stringProp> + <boolProp name="HTTPSampler.use_keepalive">true</boolProp> + <boolProp name="HTTPSampler.postBodyRaw">true</boolProp> + <elementProp name="HTTPsampler.Arguments" elementType="Arguments"> + <collectionProp name="Arguments.arguments"> + <elementProp name="" elementType="HTTPArgument"> + <boolProp name="HTTPArgument.always_encode">false</boolProp> + <stringProp name="Argument.value">{
 + "policies": [
 + {
 + "policy-id": "zone",
 + "policy-version": "1.0.0"
 +
 + }
 + ]
 +}</stringProp> + <stringProp name="Argument.metadata">=</stringProp> + </elementProp> + </collectionProp> + </elementProp> + </HTTPSamplerProxy> + <hashTree> + <AuthManager guiclass="AuthPanel" testclass="AuthManager" testname="HTTP Authorization Manager" enabled="true"> + <collectionProp name="AuthManager.auth_list"> + <elementProp name="" elementType="Authorization"> + <stringProp name="Authorization.url">${HTTP}://${PAP_HOST}:${PAP_PORT}/policy/pap/v1</stringProp> + <stringProp name="Authorization.username">${PAP_USER}</stringProp> + <stringProp name="Authorization.password">${PAP_PASSWORD}</stringProp> + <stringProp name="Authorization.domain"></stringProp> + <stringProp name="Authorization.realm"></stringProp> + </elementProp> + </collectionProp> + <boolProp name="AuthManager.clearEachIteration">true</boolProp> + <boolProp name="AuthManager.controlledByThreadGroup">false</boolProp> + </AuthManager> + <hashTree/> + <HeaderManager guiclass="HeaderPanel" testclass="HeaderManager" testname="HTTP Header Manager" enabled="true"> + <collectionProp name="HeaderManager.headers"> + <elementProp name="" elementType="Header"> + <stringProp name="Header.name">Content-Type</stringProp> + <stringProp name="Header.value">application/json</stringProp> + </elementProp> + </collectionProp> + </HeaderManager> + <hashTree/> + <ResponseAssertion guiclass="AssertionGui" testclass="ResponseAssertion" testname="Response Assertion" enabled="true"> + <collectionProp name="Asserion.test_strings"> + <stringProp name="49588">202</stringProp> + </collectionProp> + <stringProp name="Assertion.custom_message"></stringProp> + <stringProp name="Assertion.test_field">Assertion.response_code</stringProp> + <boolProp name="Assertion.assume_success">false</boolProp> + <intProp name="Assertion.test_type">8</intProp> + </ResponseAssertion> + <hashTree/> + </hashTree> + <ResultCollector guiclass="ViewResultsFullVisualizer" testclass="ResultCollector" testname="View Results Tree" enabled="true"> + <boolProp name="ResultCollector.error_logging">false</boolProp> + <objProp> + <name>saveConfig</name> + <value class="SampleSaveConfiguration"> + <time>true</time> + <latency>true</latency> + <timestamp>true</timestamp> + <success>true</success> + <label>true</label> + <code>true</code> + <message>true</message> + <threadName>true</threadName> + <dataType>true</dataType> + <encoding>false</encoding> + <assertions>true</assertions> + <subresults>true</subresults> + <responseData>false</responseData> + <samplerData>false</samplerData> + <xml>false</xml> + <fieldNames>true</fieldNames> + <responseHeaders>false</responseHeaders> + <requestHeaders>false</requestHeaders> + <responseDataOnError>false</responseDataOnError> + <saveAssertionResultsFailureMessage>true</saveAssertionResultsFailureMessage> + <assertionsResultsToSave>0</assertionsResultsToSave> + <bytes>true</bytes> + <sentBytes>true</sentBytes> + <url>true</url> + <threadCounts>true</threadCounts> + <idleTime>true</idleTime> + <connectTime>true</connectTime> + </value> + </objProp> + <stringProp name="filename">/tmp/pdpo_stability_setup.log</stringProp> + </ResultCollector> + <hashTree/> + </hashTree> + <ThreadGroup guiclass="ThreadGroupGui" testclass="ThreadGroup" testname="Policy OPA PDP Health Check"> <stringProp name="ThreadGroup.num_threads">${USERS}</stringProp> <intProp name="ThreadGroup.ramp_time">10</intProp> <stringProp name="ThreadGroup.duration">${DURATION}</stringProp> @@ -117,10 +709,10 @@ <HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="Check Health" enabled="true"> <stringProp name="TestPlan.comments">Basic Health Check</stringProp> <intProp name="HTTPSampler.concurrentPool">6</intProp> - <stringProp name="HTTPSampler.domain">${OPA_PDP_HOST}</stringProp> - <stringProp name="HTTPSampler.port">${OPA_PDP_PORT}</stringProp> + <stringProp name="HTTPSampler.domain">${OPA_HOST}</stringProp> + <stringProp name="HTTPSampler.port">${OPA_PORT}</stringProp> <stringProp name="HTTPSampler.protocol">${HTTP}</stringProp> - <stringProp name="HTTPSampler.path">policy/pdpx/v1/healthcheck</stringProp> + <stringProp name="HTTPSampler.path">policy/pdpo/v1/healthcheck</stringProp> <boolProp name="HTTPSampler.follow_redirects">true</boolProp> <stringProp name="HTTPSampler.method">GET</stringProp> <boolProp name="HTTPSampler.use_keepalive">true</boolProp> @@ -163,7 +755,7 @@ if (prev.getResponseCode() == '200') { <AuthManager guiclass="AuthPanel" testclass="AuthManager" testname="HTTP Authorization Manager" enabled="true"> <collectionProp name="AuthManager.auth_list"> <elementProp name="" elementType="Authorization"> - <stringProp name="Authorization.url">${HTTP}://${OPA_PDP_HOST}:${OPA_PDP_PORT}/policy/pdpx/v1</stringProp> + <stringProp name="Authorization.url">${HTTP}://${OPA_HOST}:${OPA_PORT}/policy/pdpo/v1</stringProp> <stringProp name="Authorization.username">${OPA_PDP_USER}</stringProp> <stringProp name="Authorization.password">${OPA_PDP_PASSWORD}</stringProp> <stringProp name="Authorization.domain"></stringProp> @@ -208,7 +800,7 @@ if (prev.getResponseCode() == '200') { <connectTime>true</connectTime> </value> </objProp> - <stringProp name="filename">/tmp/pdpx_stability_health.log</stringProp> + <stringProp name="filename">/tmp/pdpo_stability_health.log</stringProp> <stringProp name="TestPlan.comments"> </stringProp> </ResultCollector> <hashTree/> @@ -227,13 +819,13 @@ if (prev.getResponseCode() == '200') { </elementProp> </ThreadGroup> <hashTree> - <HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="Verification API Call 1"> - <stringProp name="TestPlan.comments">Verification API Call 1</stringProp> + <HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="Fetch Role Decisions"> + <stringProp name="TestPlan.comments">Get Configuration Data for Monitoring Policy</stringProp> <intProp name="HTTPSampler.concurrentPool">6</intProp> - <stringProp name="HTTPSampler.domain">${OPA_PDP_HOST}</stringProp> - <stringProp name="HTTPSampler.port">${OPA_PDP_PORT}</stringProp> + <stringProp name="HTTPSampler.domain">${OPA_HOST}</stringProp> + <stringProp name="HTTPSampler.port">${OPA_PORT}</stringProp> <stringProp name="HTTPSampler.protocol">${HTTP}</stringProp> - <stringProp name="HTTPSampler.path">policy/pdpx/v1/decision</stringProp> + <stringProp name="HTTPSampler.path">policy/pdpo/v1/decision</stringProp> <boolProp name="HTTPSampler.follow_redirects">true</boolProp> <stringProp name="HTTPSampler.method">POST</stringProp> <boolProp name="HTTPSampler.use_keepalive">true</boolProp> @@ -242,13 +834,43 @@ if (prev.getResponseCode() == '200') { <collectionProp name="Arguments.arguments"> <elementProp name="" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">false</boolProp> - <stringProp name="Argument.value">{"onapName":"CDS","onapComponent":"CDS","onapInstance":"CDS","currentDate": "2024-11-22", "currentTime": "2024-11-22T11:34:56Z", "timeZone": "UTC", "timeOffset": "+05:30", "currentDateTime": "2024-11-22T12:08:00Z","policyName":"example/allow","input":{"method":"POST","path":["users"]}}</stringProp> + <stringProp name="Argument.value">{
 + "onapName": "CDS",
 + "onapComponent": "CDS",
 + "onapInstance": "CDS",
 + "currentDate": "2024-11-22",
 + "currentTime": "08:26:41.857Z",
 + "timeZone": "UTC",
 + "timeOffset": "+05:30",
 + "currentDateTime": "2024-11-22T12:08:00Z",
 + "policyFilter": [
 + "allow"
 + ],
 + "policyName": "role",
 + "input": {
 + "user": "alice"
 + }
 +}</stringProp> <stringProp name="Argument.metadata">=</stringProp> </elementProp> </collectionProp> </elementProp> </HTTPSamplerProxy> <hashTree> + <AuthManager guiclass="AuthPanel" testclass="AuthManager" testname="HTTP Authorization Manager" enabled="true"> + <collectionProp name="AuthManager.auth_list"> + <elementProp name="" elementType="Authorization"> + <stringProp name="Authorization.url">${HTTP}://${OPA_HOST}:${OPA_PORT}/policy/pdpo/v1</stringProp> + <stringProp name="Authorization.username">${OPA_USER}</stringProp> + <stringProp name="Authorization.password">${OPA_PASSWORD}</stringProp> + <stringProp name="Authorization.domain"></stringProp> + <stringProp name="Authorization.realm"></stringProp> + </elementProp> + </collectionProp> + <boolProp name="AuthManager.clearEachIteration">true</boolProp> + <boolProp name="AuthManager.controlledByThreadGroup">false</boolProp> + </AuthManager> + <hashTree/> <ResponseAssertion guiclass="AssertionGui" testclass="ResponseAssertion" testname="Response Assertion" enabled="true"> <collectionProp name="Asserion.test_strings"> <stringProp name="49586">200</stringProp> @@ -261,7 +883,7 @@ if (prev.getResponseCode() == '200') { <hashTree/> <ResponseAssertion guiclass="AssertionGui" testclass="ResponseAssertion" testname="Response Assertion" enabled="true"> <collectionProp name="Asserion.test_strings"> - <stringProp name="-1938393061">PERMIT</stringProp> + <stringProp name="92906313">allow</stringProp> </collectionProp> <stringProp name="Assertion.custom_message"></stringProp> <stringProp name="Assertion.test_field">Assertion.response_data</stringProp> @@ -270,13 +892,13 @@ if (prev.getResponseCode() == '200') { </ResponseAssertion> <hashTree/> </hashTree> - <HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="Verification API Call 2"> - <stringProp name="TestPlan.comments">Verification API Call 2</stringProp> + <HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="Fetch Role Decisions with nultiple Filters"> + <stringProp name="TestPlan.comments">Get Data with Filter for Role Policy</stringProp> <intProp name="HTTPSampler.concurrentPool">6</intProp> - <stringProp name="HTTPSampler.domain">${OPA_PDP_HOST}</stringProp> - <stringProp name="HTTPSampler.port">${OPA_PDP_PORT}</stringProp> + <stringProp name="HTTPSampler.domain">${OPA_HOST}</stringProp> + <stringProp name="HTTPSampler.port">${OPA_PORT}</stringProp> <stringProp name="HTTPSampler.protocol">${HTTP}</stringProp> - <stringProp name="HTTPSampler.path">policy/pdpx/v1/decision</stringProp> + <stringProp name="HTTPSampler.path">policy/pdpo/v1/decision</stringProp> <boolProp name="HTTPSampler.follow_redirects">true</boolProp> <stringProp name="HTTPSampler.method">POST</stringProp> <boolProp name="HTTPSampler.use_keepalive">true</boolProp> @@ -285,56 +907,43 @@ if (prev.getResponseCode() == '200') { <collectionProp name="Arguments.arguments"> <elementProp name="" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">false</boolProp> - <stringProp name="Argument.value">{"onapName":"CDS","onapComponent":"CDS","onapInstance":"CDS","currentDate": "2024-11-22", "currentTime": "2024-11-22T11:34:56Z", "timeZone": "UTC", "timeOffset": "+05:30", "currentDateTime": "2024-11-22T12:08:00Z", "policyName":"role/allow","input":{"user":"alice","action":"write","object":"id123","type":"dog"}}</stringProp> + <stringProp name="Argument.value">{
 + "onapName": "CDS",
 + "onapComponent": "CDS",
 + "onapInstance": "CDS",
 + "currentDate": "2024-11-22",
 + "currentTime": "08:26:41.857Z",
 + "timeZone": "UTC",
 + "timeOffset": "+05:30",
 + "currentDateTime": "2024-11-22T12:08:00Z",
 + "policyFilter": [
 + "user_is_admin", "allow"
 + ],
 + "policyName": "role",
 + "input": {
 + "user": "alice"
 + }
 +}</stringProp> <stringProp name="Argument.metadata">=</stringProp> </elementProp> </collectionProp> </elementProp> </HTTPSamplerProxy> <hashTree> - <ResponseAssertion guiclass="AssertionGui" testclass="ResponseAssertion" testname="Response Assertion" enabled="true"> - <collectionProp name="Asserion.test_strings"> - <stringProp name="49586">200</stringProp> - </collectionProp> - <stringProp name="Assertion.custom_message"></stringProp> - <stringProp name="Assertion.test_field">Assertion.response_code</stringProp> - <boolProp name="Assertion.assume_success">false</boolProp> - <intProp name="Assertion.test_type">8</intProp> - </ResponseAssertion> - <hashTree/> - <ResponseAssertion guiclass="AssertionGui" testclass="ResponseAssertion" testname="Response Assertion"> - <collectionProp name="Asserion.test_strings"> - <stringProp name="-1938393061">PERMIT</stringProp> - </collectionProp> - <stringProp name="Assertion.custom_message"></stringProp> - <stringProp name="Assertion.test_field">Assertion.response_data</stringProp> - <boolProp name="Assertion.assume_success">false</boolProp> - <intProp name="Assertion.test_type">2</intProp> - </ResponseAssertion> - <hashTree/> - </hashTree> - <HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="PERMIT for policy:action" enabled="true"> - <stringProp name="TestPlan.comments">PERMIT for policy:action</stringProp> - <intProp name="HTTPSampler.concurrentPool">6</intProp> - <stringProp name="HTTPSampler.domain">${OPA_PDP_HOST}</stringProp> - <stringProp name="HTTPSampler.port">${OPA_PDP_PORT}</stringProp> - <stringProp name="HTTPSampler.protocol">${HTTP}</stringProp> - <stringProp name="HTTPSampler.path">policy/pdpx/v1/decision</stringProp> - <boolProp name="HTTPSampler.follow_redirects">true</boolProp> - <stringProp name="HTTPSampler.method">POST</stringProp> - <boolProp name="HTTPSampler.use_keepalive">true</boolProp> - <boolProp name="HTTPSampler.postBodyRaw">true</boolProp> - <elementProp name="HTTPsampler.Arguments" elementType="Arguments"> - <collectionProp name="Arguments.arguments"> - <elementProp name="" elementType="HTTPArgument"> - <boolProp name="HTTPArgument.always_encode">false</boolProp> - <stringProp name="Argument.value">{"onapName":"CDS","onapComponent":"CDS","onapInstance":"CDS", "currentDate": "2024-11-22", "currentTime": "2024-11-22T11:34:56Z", "timeZone": "UTC", "timeOffset": "+05:30", "currentDateTime": "2024-11-22T12:08:00Z","policyName":"action/allow","input":{"user":"alice","action":"delete","type":"server"}}</stringProp> - <stringProp name="Argument.metadata">=</stringProp> + <AuthManager guiclass="AuthPanel" testclass="AuthManager" testname="HTTP Authorization Manager" enabled="true"> + <collectionProp name="AuthManager.auth_list"> + <elementProp name="" elementType="Authorization"> + <stringProp name="Authorization.url">${HTTP}://${OPA_HOST}:${OPA_PORT}/policy/pdpo/v1</stringProp> + <stringProp name="Authorization.username">${OPA_USER}</stringProp> + <stringProp name="Authorization.password">${OPA_PASSWORD}</stringProp> + <stringProp name="Authorization.domain"></stringProp> + <stringProp name="Authorization.realm"></stringProp> </elementProp> </collectionProp> - </elementProp> - </HTTPSamplerProxy> - <hashTree> + <boolProp name="AuthManager.clearEachIteration">true</boolProp> + <boolProp name="AuthManager.controlledByThreadGroup">false</boolProp> + </AuthManager> + <hashTree/> <ResponseAssertion guiclass="AssertionGui" testclass="ResponseAssertion" testname="Response Assertion" enabled="true"> <collectionProp name="Asserion.test_strings"> <stringProp name="49586">200</stringProp> @@ -347,7 +956,8 @@ if (prev.getResponseCode() == '200') { <hashTree/> <ResponseAssertion guiclass="AssertionGui" testclass="ResponseAssertion" testname="Response Assertion" enabled="true"> <collectionProp name="Asserion.test_strings"> - <stringProp name="-1938393061">PERMIT</stringProp> + <stringProp name="92906313">allow</stringProp> + <stringProp name="158189038">user_is_admin</stringProp> </collectionProp> <stringProp name="Assertion.custom_message"></stringProp> <stringProp name="Assertion.test_field">Assertion.response_data</stringProp> @@ -356,13 +966,13 @@ if (prev.getResponseCode() == '200') { </ResponseAssertion> <hashTree/> </hashTree> - <HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="DENY for policy:action" enabled="true"> - <stringProp name="TestPlan.comments">DENY for policy:action</stringProp> + <HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="Fetch Collab Decisions"> + <stringProp name="TestPlan.comments">Get Output for Collab Policy</stringProp> <intProp name="HTTPSampler.concurrentPool">6</intProp> - <stringProp name="HTTPSampler.domain">${OPA_PDP_HOST}</stringProp> - <stringProp name="HTTPSampler.port">${OPA_PDP_PORT}</stringProp> + <stringProp name="HTTPSampler.domain">${OPA_HOST}</stringProp> + <stringProp name="HTTPSampler.port">${OPA_PORT}</stringProp> <stringProp name="HTTPSampler.protocol">${HTTP}</stringProp> - <stringProp name="HTTPSampler.path">policy/pdpx/v1/decision</stringProp> + <stringProp name="HTTPSampler.path">policy/pdpo/v1/decision</stringProp> <boolProp name="HTTPSampler.follow_redirects">true</boolProp> <stringProp name="HTTPSampler.method">POST</stringProp> <boolProp name="HTTPSampler.use_keepalive">true</boolProp> @@ -371,13 +981,27 @@ if (prev.getResponseCode() == '200') { <collectionProp name="Arguments.arguments"> <elementProp name="" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">false</boolProp> - <stringProp name="Argument.value">{"onapName":"CDS","onapComponent":"CDS","onapInstance":"CDS", "currentDate": "2024-11-22", "currentTime": "2024-11-22T11:34:56Z", "timeZone": "UTC", "timeOffset": "+05:30", "currentDateTime": "2024-11-22T12:08:00Z","policyName":"action/allow","input":{"user":"charlie","action":"delete","type":"server"}}</stringProp> + <stringProp name="Argument.value">{"onapName":"CDS","onapComponent":"CDS","onapInstance":"CDS", "currentDate": "2024-11-22", "currentTime": "08:26:41.857Z", "timeZone": "UTC", "timeOffset": "+05:30", "currentDateTime": "2024-11-22T12:08:00Z","policyFilter": ["action"], "policyName":"collab","input":{"name":"alice"}}</stringProp> <stringProp name="Argument.metadata">=</stringProp> </elementProp> </collectionProp> </elementProp> </HTTPSamplerProxy> <hashTree> + <AuthManager guiclass="AuthPanel" testclass="AuthManager" testname="HTTP Authorization Manager" enabled="true"> + <collectionProp name="AuthManager.auth_list"> + <elementProp name="" elementType="Authorization"> + <stringProp name="Authorization.url">${HTTP}://${OPA_HOST}:${OPA_PORT}/policy/pdpo/v1</stringProp> + <stringProp name="Authorization.username">${OPA_USER}</stringProp> + <stringProp name="Authorization.password">${OPA_PASSWORD}</stringProp> + <stringProp name="Authorization.domain"></stringProp> + <stringProp name="Authorization.realm"></stringProp> + </elementProp> + </collectionProp> + <boolProp name="AuthManager.clearEachIteration">true</boolProp> + <boolProp name="AuthManager.controlledByThreadGroup">false</boolProp> + </AuthManager> + <hashTree/> <ResponseAssertion guiclass="AssertionGui" testclass="ResponseAssertion" testname="Response Assertion" enabled="true"> <collectionProp name="Asserion.test_strings"> <stringProp name="49586">200</stringProp> @@ -390,7 +1014,7 @@ if (prev.getResponseCode() == '200') { <hashTree/> <ResponseAssertion guiclass="AssertionGui" testclass="ResponseAssertion" testname="Response Assertion" enabled="true"> <collectionProp name="Asserion.test_strings"> - <stringProp name="2094604">DENY</stringProp> + <stringProp name="-1422950858">action</stringProp> </collectionProp> <stringProp name="Assertion.custom_message"></stringProp> <stringProp name="Assertion.test_field">Assertion.response_data</stringProp> @@ -399,13 +1023,13 @@ if (prev.getResponseCode() == '200') { </ResponseAssertion> <hashTree/> </hashTree> - <HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="PERMIT for policy:account" enabled="true"> - <stringProp name="TestPlan.comments">PERMIT for policy:account</stringProp> + <HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="Fetch Conflict Decisions"> + <stringProp name="TestPlan.comments">Get Output for Conflict Policy</stringProp> <intProp name="HTTPSampler.concurrentPool">6</intProp> - <stringProp name="HTTPSampler.domain">${OPA_PDP_HOST}</stringProp> - <stringProp name="HTTPSampler.port">${OPA_PDP_PORT}</stringProp> + <stringProp name="HTTPSampler.domain">${OPA_HOST}</stringProp> + <stringProp name="HTTPSampler.port">${OPA_PORT}</stringProp> <stringProp name="HTTPSampler.protocol">${HTTP}</stringProp> - <stringProp name="HTTPSampler.path">policy/pdpx/v1/decision</stringProp> + <stringProp name="HTTPSampler.path">policy/pdpo/v1/decision</stringProp> <boolProp name="HTTPSampler.follow_redirects">true</boolProp> <stringProp name="HTTPSampler.method">POST</stringProp> <boolProp name="HTTPSampler.use_keepalive">true</boolProp> @@ -414,13 +1038,27 @@ if (prev.getResponseCode() == '200') { <collectionProp name="Arguments.arguments"> <elementProp name="" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">false</boolProp> - <stringProp name="Argument.value">{"onapName":"CDS","onapComponent":"CDS","onapInstance":"CDS", "currentDate": "2024-11-22", "currentTime": "2024-11-22T11:34:56Z", "timeZone": "UTC","timeOffset": "+05:30", "currentDateTime": "2024-11-22T12:08:00Z","policyName":"account/allow", "input":{"creditor_account":11111,"creditor":"alice","debtor_account":22222,"debtor":"bob","period":30,"amount":1000}}</stringProp> + <stringProp name="Argument.value">{"onapName":"CDS","onapComponent":"CDS","onapInstance":"CDS", "currentDate": "2024-11-22", "currentTime": "08:26:41.857Z", "timeZone": "UTC", "timeOffset": "+05:30", "currentDateTime": "2024-11-22T12:08:00Z","policyFilter": ["allow"], "policyName":"conflict","input":{"name":"alice"}}</stringProp> <stringProp name="Argument.metadata">=</stringProp> </elementProp> </collectionProp> </elementProp> </HTTPSamplerProxy> <hashTree> + <AuthManager guiclass="AuthPanel" testclass="AuthManager" testname="HTTP Authorization Manager" enabled="true"> + <collectionProp name="AuthManager.auth_list"> + <elementProp name="" elementType="Authorization"> + <stringProp name="Authorization.url">${HTTP}://${OPA_HOST}:${OPA_PORT}/policy/pdpo/v1</stringProp> + <stringProp name="Authorization.username">${OPA_USER}</stringProp> + <stringProp name="Authorization.password">${OPA_PASSWORD}</stringProp> + <stringProp name="Authorization.domain"></stringProp> + <stringProp name="Authorization.realm"></stringProp> + </elementProp> + </collectionProp> + <boolProp name="AuthManager.clearEachIteration">true</boolProp> + <boolProp name="AuthManager.controlledByThreadGroup">false</boolProp> + </AuthManager> + <hashTree/> <ResponseAssertion guiclass="AssertionGui" testclass="ResponseAssertion" testname="Response Assertion" enabled="true"> <collectionProp name="Asserion.test_strings"> <stringProp name="49586">200</stringProp> @@ -433,7 +1071,7 @@ if (prev.getResponseCode() == '200') { <hashTree/> <ResponseAssertion guiclass="AssertionGui" testclass="ResponseAssertion" testname="Response Assertion" enabled="true"> <collectionProp name="Asserion.test_strings"> - <stringProp name="-1938393061">PERMIT</stringProp> + <stringProp name="92906313">allow</stringProp> </collectionProp> <stringProp name="Assertion.custom_message"></stringProp> <stringProp name="Assertion.test_field">Assertion.response_data</stringProp> @@ -442,13 +1080,13 @@ if (prev.getResponseCode() == '200') { </ResponseAssertion> <hashTree/> </hashTree> - <HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="DENY for policy:account" enabled="true"> - <stringProp name="TestPlan.comments">DENY for policy:account</stringProp> + <HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="Fetch Zone Decisions"> + <stringProp name="TestPlan.comments">Get Zone Decisions</stringProp> <intProp name="HTTPSampler.concurrentPool">6</intProp> - <stringProp name="HTTPSampler.domain">${OPA_PDP_HOST}</stringProp> - <stringProp name="HTTPSampler.port">${OPA_PDP_PORT}</stringProp> + <stringProp name="HTTPSampler.domain">${OPA_HOST}</stringProp> + <stringProp name="HTTPSampler.port">${OPA_PORT}</stringProp> <stringProp name="HTTPSampler.protocol">${HTTP}</stringProp> - <stringProp name="HTTPSampler.path">policy/pdpx/v1/decision</stringProp> + <stringProp name="HTTPSampler.path">policy/pdpo/v1/decision</stringProp> <boolProp name="HTTPSampler.follow_redirects">true</boolProp> <stringProp name="HTTPSampler.method">POST</stringProp> <boolProp name="HTTPSampler.use_keepalive">true</boolProp> @@ -457,15 +1095,35 @@ if (prev.getResponseCode() == '200') { <collectionProp name="Arguments.arguments"> <elementProp name="" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">false</boolProp> - <stringProp name="Argument.value">{"onapName":"CDS","onapComponent":"CDS","onapInstance":"CDS", "currentDate": "2024-11-22", "currentTime": "2024-11-22T11:34:56Z", "timeZone": "UTC", "timeOffset": "+05:30", "currentDateTime": "2024-11-22T12:08:00Z","policyName":"account/allow", "input":{"creditor_account":11111,"creditor":"alice","debtor_account":22222,"debtor":"bob","period":31,"amount":1000}}
 -
 -</stringProp> + <stringProp name="Argument.value">{"onapName":"CDS","onapComponent":"CDS","onapInstance":"CDS", "currentDate": "2024-11-22", "currentTime": "08:26:41.857Z", "timeZone": "UTC", "timeOffset": "+05:30", "currentDateTime": "2024-11-22T12:08:00Z","policyFilter": ["allow"], "policyName":"zone","input":{
 + "actions": ["view"],
 + "zone_id": "zone123",
 + "time_period": {
 + "from": 1700000000,
 + "to": 1700500000
 + },
 + "datatypes": ["temperature", "humidity"]
 +}}</stringProp> <stringProp name="Argument.metadata">=</stringProp> </elementProp> </collectionProp> </elementProp> </HTTPSamplerProxy> <hashTree> + <AuthManager guiclass="AuthPanel" testclass="AuthManager" testname="HTTP Authorization Manager" enabled="true"> + <collectionProp name="AuthManager.auth_list"> + <elementProp name="" elementType="Authorization"> + <stringProp name="Authorization.url">${HTTP}://${OPA_HOST}:${OPA_PORT}/policy/pdpo/v1</stringProp> + <stringProp name="Authorization.username">${OPA_USER}</stringProp> + <stringProp name="Authorization.password">${OPA_PASSWORD}</stringProp> + <stringProp name="Authorization.domain"></stringProp> + <stringProp name="Authorization.realm"></stringProp> + </elementProp> + </collectionProp> + <boolProp name="AuthManager.clearEachIteration">true</boolProp> + <boolProp name="AuthManager.controlledByThreadGroup">false</boolProp> + </AuthManager> + <hashTree/> <ResponseAssertion guiclass="AssertionGui" testclass="ResponseAssertion" testname="Response Assertion" enabled="true"> <collectionProp name="Asserion.test_strings"> <stringProp name="49586">200</stringProp> @@ -478,7 +1136,7 @@ if (prev.getResponseCode() == '200') { <hashTree/> <ResponseAssertion guiclass="AssertionGui" testclass="ResponseAssertion" testname="Response Assertion" enabled="true"> <collectionProp name="Asserion.test_strings"> - <stringProp name="2094604">DENY</stringProp> + <stringProp name="92906313">allow</stringProp> </collectionProp> <stringProp name="Assertion.custom_message"></stringProp> <stringProp name="Assertion.test_field">Assertion.response_data</stringProp> @@ -487,72 +1145,102 @@ if (prev.getResponseCode() == '200') { </ResponseAssertion> <hashTree/> </hashTree> - <HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="PERMIT for policy:organization" enabled="true"> - <stringProp name="TestPlan.comments">PERMIT for policy:organization</stringProp> + <HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="Patch Data for Policy"> + <stringProp name="TestPlan.comments">Patch Data for Policy</stringProp> <intProp name="HTTPSampler.concurrentPool">6</intProp> - <stringProp name="HTTPSampler.domain">${OPA_PDP_HOST}</stringProp> - <stringProp name="HTTPSampler.port">${OPA_PDP_PORT}</stringProp> + <stringProp name="HTTPSampler.domain">${OPA_HOST}</stringProp> + <stringProp name="HTTPSampler.port">${OPA_PORT}</stringProp> <stringProp name="HTTPSampler.protocol">${HTTP}</stringProp> - <stringProp name="HTTPSampler.path">policy/pdpx/v1/decision</stringProp> + <stringProp name="HTTPSampler.path">policy/pdpo/v1/data/node/role</stringProp> <boolProp name="HTTPSampler.follow_redirects">true</boolProp> - <stringProp name="HTTPSampler.method">POST</stringProp> + <stringProp name="HTTPSampler.method">PATCH</stringProp> <boolProp name="HTTPSampler.use_keepalive">true</boolProp> <boolProp name="HTTPSampler.postBodyRaw">true</boolProp> <elementProp name="HTTPsampler.Arguments" elementType="Arguments"> <collectionProp name="Arguments.arguments"> <elementProp name="" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">false</boolProp> - <stringProp name="Argument.value">{"onapName":"CDS","onapComponent":"CDS","onapInstance":"CDS", "currentDate": "2024-11-22", "currentTime": "2024-11-22T11:34:56Z", "timeZone": "UTC", "timeOffset": "+05:30", "currentDateTime": "2024-11-22T12:08:00Z","policyName":"organization/allow", "input":{"user":"alice","action": "read","component": "component_A","project": "project_A", "organization": "org_A"}}</stringProp> + <stringProp name="Argument.value">{
 + "onapName": "string",
 + "onapComponent": "string",
 + "onapInstance": "string",
 + "currentDateTime": "2025-01-17T08:26:41.857Z",
 + "currentDate": "2025-01-17",
 + "currentTime": "08:26:41.857Z",
 + "timeZone": "UTC",
 + "timeOffset": "+08:45",
 + "policyName": "role",
 + "data": [
 + {
 + "op": "add",
 + "path": "/cell",
 + "value": "try"
 + }
 + ]
 +}
 + </stringProp> <stringProp name="Argument.metadata">=</stringProp> </elementProp> </collectionProp> </elementProp> </HTTPSamplerProxy> <hashTree> - <ResponseAssertion guiclass="AssertionGui" testclass="ResponseAssertion" testname="Response Assertion" enabled="true"> - <collectionProp name="Asserion.test_strings"> - <stringProp name="49586">200</stringProp> + <AuthManager guiclass="AuthPanel" testclass="AuthManager" testname="HTTP Authorization Manager" enabled="true"> + <collectionProp name="AuthManager.auth_list"> + <elementProp name="" elementType="Authorization"> + <stringProp name="Authorization.url">${HTTP}://${OPA_HOST}:${OPA_PORT}/policy/pdpo/v1</stringProp> + <stringProp name="Authorization.username">${OPA_USER}</stringProp> + <stringProp name="Authorization.password">${OPA_PASSWORD}</stringProp> + <stringProp name="Authorization.domain"></stringProp> + <stringProp name="Authorization.realm"></stringProp> + </elementProp> </collectionProp> - <stringProp name="Assertion.custom_message"></stringProp> - <stringProp name="Assertion.test_field">Assertion.response_code</stringProp> - <boolProp name="Assertion.assume_success">false</boolProp> - <intProp name="Assertion.test_type">8</intProp> - </ResponseAssertion> + <boolProp name="AuthManager.clearEachIteration">true</boolProp> + <boolProp name="AuthManager.controlledByThreadGroup">false</boolProp> + </AuthManager> <hashTree/> <ResponseAssertion guiclass="AssertionGui" testclass="ResponseAssertion" testname="Response Assertion" enabled="true"> <collectionProp name="Asserion.test_strings"> - <stringProp name="-1938393061">PERMIT</stringProp> + <stringProp name="49590">204</stringProp> </collectionProp> <stringProp name="Assertion.custom_message"></stringProp> - <stringProp name="Assertion.test_field">Assertion.response_data</stringProp> + <stringProp name="Assertion.test_field">Assertion.response_code</stringProp> <boolProp name="Assertion.assume_success">false</boolProp> - <intProp name="Assertion.test_type">2</intProp> + <intProp name="Assertion.test_type">8</intProp> </ResponseAssertion> <hashTree/> </hashTree> - <HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="DENY for policy:organization" enabled="true"> - <stringProp name="TestPlan.comments">DENY for policy:organization</stringProp> + <HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="Get Data for polcy role"> + <stringProp name="TestPlan.comments">Get Data for polcy role</stringProp> <intProp name="HTTPSampler.concurrentPool">6</intProp> - <stringProp name="HTTPSampler.domain">${OPA_PDP_HOST}</stringProp> - <stringProp name="HTTPSampler.port">${OPA_PDP_PORT}</stringProp> + <stringProp name="HTTPSampler.domain">${OPA_HOST}</stringProp> + <stringProp name="HTTPSampler.port">${OPA_PORT}</stringProp> <stringProp name="HTTPSampler.protocol">${HTTP}</stringProp> - <stringProp name="HTTPSampler.path">policy/pdpx/v1/decision</stringProp> + <stringProp name="HTTPSampler.path">policy/pdpo/v1/data</stringProp> <boolProp name="HTTPSampler.follow_redirects">true</boolProp> - <stringProp name="HTTPSampler.method">POST</stringProp> + <stringProp name="HTTPSampler.method">GET</stringProp> <boolProp name="HTTPSampler.use_keepalive">true</boolProp> - <boolProp name="HTTPSampler.postBodyRaw">true</boolProp> - <elementProp name="HTTPsampler.Arguments" elementType="Arguments"> - <collectionProp name="Arguments.arguments"> - <elementProp name="" elementType="HTTPArgument"> - <boolProp name="HTTPArgument.always_encode">false</boolProp> - <stringProp name="Argument.value">{"onapName":"CDS","onapComponent":"CDS","onapInstance":"CDS", "currentDate": "2024-11-22", "currentTime": "2024-11-22T11:34:56Z", "timeZone": "UTC", "timeOffset": "+05:30", "currentDateTime": "2024-11-22T12:08:00Z","policyName":"organization/allow", "input":{"user":"charlie","action": "edit","component": "component_A","project": "project_A", "organization": "org_A"}}</stringProp> - <stringProp name="Argument.metadata">=</stringProp> - </elementProp> - </collectionProp> + <boolProp name="HTTPSampler.postBodyRaw">false</boolProp> + <elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" testname="User Defined Variables"> + <collectionProp name="Arguments.arguments"/> </elementProp> </HTTPSamplerProxy> <hashTree> - <ResponseAssertion guiclass="AssertionGui" testclass="ResponseAssertion" testname="Response Assertion" enabled="true"> + <AuthManager guiclass="AuthPanel" testclass="AuthManager" testname="HTTP Authorization Manager" enabled="true"> + <collectionProp name="AuthManager.auth_list"> + <elementProp name="" elementType="Authorization"> + <stringProp name="Authorization.url">${HTTP}://${OPA_HOST}:${OPA_PORT}/policy/pdpo/v1</stringProp> + <stringProp name="Authorization.username">${OPA_USER}</stringProp> + <stringProp name="Authorization.password">${OPA_PASSWORD}</stringProp> + <stringProp name="Authorization.domain"></stringProp> + <stringProp name="Authorization.realm"></stringProp> + </elementProp> + </collectionProp> + <boolProp name="AuthManager.clearEachIteration">true</boolProp> + <boolProp name="AuthManager.controlledByThreadGroup">false</boolProp> + </AuthManager> + <hashTree/> + <ResponseAssertion guiclass="AssertionGui" testclass="ResponseAssertion" testname="Response Assertion"> <collectionProp name="Asserion.test_strings"> <stringProp name="49586">200</stringProp> </collectionProp> @@ -562,9 +1250,9 @@ if (prev.getResponseCode() == '200') { <intProp name="Assertion.test_type">8</intProp> </ResponseAssertion> <hashTree/> - <ResponseAssertion guiclass="AssertionGui" testclass="ResponseAssertion" testname="Response Assertion" enabled="true"> + <ResponseAssertion guiclass="AssertionGui" testclass="ResponseAssertion" testname="Response Assertion"> <collectionProp name="Asserion.test_strings"> - <stringProp name="2094604">DENY</stringProp> + <stringProp name="3076010">data</stringProp> </collectionProp> <stringProp name="Assertion.custom_message"></stringProp> <stringProp name="Assertion.test_field">Assertion.response_data</stringProp> @@ -576,7 +1264,7 @@ if (prev.getResponseCode() == '200') { <AuthManager guiclass="AuthPanel" testclass="AuthManager" testname="HTTP Authorization Manager" enabled="true"> <collectionProp name="AuthManager.auth_list"> <elementProp name="" elementType="Authorization"> - <stringProp name="Authorization.url">${HTTP}://${OPA_PDP_HOST}:${OPA_PDP_PORT}/policy/pdpx/v1</stringProp> + <stringProp name="Authorization.url">${HTTP}://${OPA_HOST}:${OPA_PORT}/policy/pdpo/v1</stringProp> <stringProp name="Authorization.username">${OPA_PDP_USER}</stringProp> <stringProp name="Authorization.password">${OPA_PDP_PASSWORD}</stringProp> <stringProp name="Authorization.domain"></stringProp> @@ -621,7 +1309,334 @@ if (prev.getResponseCode() == '200') { <connectTime>true</connectTime> </value> </objProp> - <stringProp name="filename">/tmp/pdpx_stability_decisions.log</stringProp> + <stringProp name="filename">/tmp/pdpo_stability_decisions.log</stringProp> + </ResultCollector> + <hashTree/> + </hashTree> + <PostThreadGroup guiclass="PostThreadGroupGui" testclass="PostThreadGroup" testname="tearDown OPA PDP Decision" enabled="true"> + <intProp name="ThreadGroup.num_threads">1</intProp> + <intProp name="ThreadGroup.ramp_time">1</intProp> + <stringProp name="ThreadGroup.duration">${DURATION}</stringProp> + <longProp name="ThreadGroup.delay">1</longProp> + <boolProp name="ThreadGroup.same_user_on_next_iteration">true</boolProp> + <stringProp name="ThreadGroup.on_sample_error">continue</stringProp> + <elementProp name="ThreadGroup.main_controller" elementType="LoopController" guiclass="LoopControlPanel" testclass="LoopController" testname="Loop Controller"> + <stringProp name="LoopController.loops">1</stringProp> + <boolProp name="LoopController.continue_forever">false</boolProp> + </elementProp> + </PostThreadGroup> + <hashTree> + <HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="Undeploy Role Policy" enabled="true"> + <intProp name="HTTPSampler.concurrentPool">6</intProp> + <stringProp name="HTTPSampler.domain">${PAP_HOST}</stringProp> + <stringProp name="HTTPSampler.port">${PAP_PORT}</stringProp> + <stringProp name="HTTPSampler.protocol">${HTTP}</stringProp> + <stringProp name="HTTPSampler.path">policy/pap/v1/pdps/policies/role/versions/1.0.0</stringProp> + <boolProp name="HTTPSampler.follow_redirects">true</boolProp> + <stringProp name="HTTPSampler.method">DELETE</stringProp> + <boolProp name="HTTPSampler.use_keepalive">true</boolProp> + <boolProp name="HTTPSampler.postBodyRaw">false</boolProp> + <elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" testname="User Defined Variables"> + <collectionProp name="Arguments.arguments"/> + </elementProp> + </HTTPSamplerProxy> + <hashTree> + <HeaderManager guiclass="HeaderPanel" testclass="HeaderManager" testname="HTTP Header Manager" enabled="true"> + <collectionProp name="HeaderManager.headers"> + <elementProp name="" elementType="Header"> + <stringProp name="Header.name">Content-Type</stringProp> + <stringProp name="Header.value">application/json</stringProp> + </elementProp> + </collectionProp> + </HeaderManager> + <hashTree/> + <AuthManager guiclass="AuthPanel" testclass="AuthManager" testname="HTTP Authorization Manager" enabled="true"> + <collectionProp name="AuthManager.auth_list"> + <elementProp name="" elementType="Authorization"> + <stringProp name="Authorization.url">${HTTP}://${PAP_HOST}:${PAP_PORT}/policy/pap/v1</stringProp> + <stringProp name="Authorization.username">${PAP_USER}</stringProp> + <stringProp name="Authorization.password">${PAP_PASSWORD}</stringProp> + <stringProp name="Authorization.domain"></stringProp> + <stringProp name="Authorization.realm"></stringProp> + </elementProp> + </collectionProp> + <boolProp name="AuthManager.clearEachIteration">true</boolProp> + <boolProp name="AuthManager.controlledByThreadGroup">false</boolProp> + </AuthManager> + <hashTree/> + </hashTree> + <HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="Undeploy Collab Policy" enabled="true"> + <intProp name="HTTPSampler.concurrentPool">6</intProp> + <stringProp name="HTTPSampler.domain">${PAP_HOST}</stringProp> + <stringProp name="HTTPSampler.port">${PAP_PORT}</stringProp> + <stringProp name="HTTPSampler.protocol">${HTTP}</stringProp> + <stringProp name="HTTPSampler.path">policy/pap/v1/pdps/policies/collab/versions/1.0.0</stringProp> + <boolProp name="HTTPSampler.follow_redirects">true</boolProp> + <stringProp name="HTTPSampler.method">DELETE</stringProp> + <boolProp name="HTTPSampler.use_keepalive">true</boolProp> + <boolProp name="HTTPSampler.postBodyRaw">false</boolProp> + <elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" testname="User Defined Variables"> + <collectionProp name="Arguments.arguments"/> + </elementProp> + </HTTPSamplerProxy> + <hashTree> + <HeaderManager guiclass="HeaderPanel" testclass="HeaderManager" testname="HTTP Header Manager" enabled="true"> + <collectionProp name="HeaderManager.headers"> + <elementProp name="" elementType="Header"> + <stringProp name="Header.name">Content-Type</stringProp> + <stringProp name="Header.value">application/json</stringProp> + </elementProp> + </collectionProp> + </HeaderManager> + <hashTree/> + <AuthManager guiclass="AuthPanel" testclass="AuthManager" testname="HTTP Authorization Manager" enabled="true"> + <collectionProp name="AuthManager.auth_list"> + <elementProp name="" elementType="Authorization"> + <stringProp name="Authorization.url">${HTTP}://${PAP_HOST}:${PAP_PORT}/policy/pap/v1</stringProp> + <stringProp name="Authorization.username">${PAP_USER}</stringProp> + <stringProp name="Authorization.password">${PAP_PASSWORD}</stringProp> + <stringProp name="Authorization.domain"></stringProp> + <stringProp name="Authorization.realm"></stringProp> + </elementProp> + </collectionProp> + <boolProp name="AuthManager.clearEachIteration">true</boolProp> + <boolProp name="AuthManager.controlledByThreadGroup">false</boolProp> + </AuthManager> + <hashTree/> + </hashTree> + <HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="Undeploy Conflict Policy" enabled="true"> + <intProp name="HTTPSampler.concurrentPool">6</intProp> + <stringProp name="HTTPSampler.domain">${PAP_HOST}</stringProp> + <stringProp name="HTTPSampler.port">${PAP_PORT}</stringProp> + <stringProp name="HTTPSampler.protocol">${HTTP}</stringProp> + <stringProp name="HTTPSampler.path">policy/pap/v1/pdps/policies/conflict/versions/1.0.0</stringProp> + <boolProp name="HTTPSampler.follow_redirects">true</boolProp> + <stringProp name="HTTPSampler.method">DELETE</stringProp> + <boolProp name="HTTPSampler.use_keepalive">true</boolProp> + <boolProp name="HTTPSampler.postBodyRaw">false</boolProp> + <elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" testname="User Defined Variables"> + <collectionProp name="Arguments.arguments"/> + </elementProp> + </HTTPSamplerProxy> + <hashTree> + <HeaderManager guiclass="HeaderPanel" testclass="HeaderManager" testname="HTTP Header Manager" enabled="true"> + <collectionProp name="HeaderManager.headers"> + <elementProp name="" elementType="Header"> + <stringProp name="Header.name">Content-Type</stringProp> + <stringProp name="Header.value">application/json</stringProp> + </elementProp> + </collectionProp> + </HeaderManager> + <hashTree/> + <AuthManager guiclass="AuthPanel" testclass="AuthManager" testname="HTTP Authorization Manager" enabled="true"> + <collectionProp name="AuthManager.auth_list"> + <elementProp name="" elementType="Authorization"> + <stringProp name="Authorization.url">${HTTP}://${PAP_HOST}:${PAP_PORT}/policy/pap/v1</stringProp> + <stringProp name="Authorization.username">${PAP_USER}</stringProp> + <stringProp name="Authorization.password">${PAP_PASSWORD}</stringProp> + <stringProp name="Authorization.domain"></stringProp> + <stringProp name="Authorization.realm"></stringProp> + </elementProp> + </collectionProp> + <boolProp name="AuthManager.clearEachIteration">true</boolProp> + <boolProp name="AuthManager.controlledByThreadGroup">false</boolProp> + </AuthManager> + <hashTree/> + </hashTree> + <HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="Undeploy Zone Policy" enabled="true"> + <intProp name="HTTPSampler.concurrentPool">6</intProp> + <stringProp name="HTTPSampler.domain">${PAP_HOST}</stringProp> + <stringProp name="HTTPSampler.port">${PAP_PORT}</stringProp> + <stringProp name="HTTPSampler.protocol">${HTTP}</stringProp> + <stringProp name="HTTPSampler.path">policy/pap/v1/pdps/policies/zone/versions/1.0.0</stringProp> + <boolProp name="HTTPSampler.follow_redirects">true</boolProp> + <stringProp name="HTTPSampler.method">DELETE</stringProp> + <boolProp name="HTTPSampler.use_keepalive">true</boolProp> + <boolProp name="HTTPSampler.postBodyRaw">false</boolProp> + <elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" testname="User Defined Variables"> + <collectionProp name="Arguments.arguments"/> + </elementProp> + </HTTPSamplerProxy> + <hashTree> + <HeaderManager guiclass="HeaderPanel" testclass="HeaderManager" testname="HTTP Header Manager" enabled="true"> + <collectionProp name="HeaderManager.headers"> + <elementProp name="" elementType="Header"> + <stringProp name="Header.name">Content-Type</stringProp> + <stringProp name="Header.value">application/json</stringProp> + </elementProp> + </collectionProp> + </HeaderManager> + <hashTree/> + <AuthManager guiclass="AuthPanel" testclass="AuthManager" testname="HTTP Authorization Manager" enabled="true"> + <collectionProp name="AuthManager.auth_list"> + <elementProp name="" elementType="Authorization"> + <stringProp name="Authorization.url">${HTTP}://${PAP_HOST}:${PAP_PORT}/policy/pap/v1</stringProp> + <stringProp name="Authorization.username">${PAP_USER}</stringProp> + <stringProp name="Authorization.password">${PAP_PASSWORD}</stringProp> + <stringProp name="Authorization.domain"></stringProp> + <stringProp name="Authorization.realm"></stringProp> + </elementProp> + </collectionProp> + <boolProp name="AuthManager.clearEachIteration">true</boolProp> + <boolProp name="AuthManager.controlledByThreadGroup">false</boolProp> + </AuthManager> + <hashTree/> + </hashTree> + <HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="Delete Role Policy" enabled="true"> + <intProp name="HTTPSampler.concurrentPool">6</intProp> + <stringProp name="HTTPSampler.domain">${API_HOST}</stringProp> + <stringProp name="HTTPSampler.port">${API_PORT}</stringProp> + <stringProp name="HTTPSampler.protocol">${HTTP}</stringProp> + <stringProp name="HTTPSampler.path">policy/api/v1/policytypes/onap.policies.native.opa/versions/1.0.0/policies/role/versions/1.0.0</stringProp> + <boolProp name="HTTPSampler.follow_redirects">true</boolProp> + <stringProp name="HTTPSampler.method">DELETE</stringProp> + <boolProp name="HTTPSampler.use_keepalive">true</boolProp> + <boolProp name="HTTPSampler.postBodyRaw">false</boolProp> + <elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" testname="User Defined Variables"> + <collectionProp name="Arguments.arguments"/> + </elementProp> + </HTTPSamplerProxy> + <hashTree> + <AuthManager guiclass="AuthPanel" testclass="AuthManager" testname="HTTP Authorization Manager" enabled="true"> + <collectionProp name="AuthManager.auth_list"> + <elementProp name="" elementType="Authorization"> + <stringProp name="Authorization.url">${HTTP}://${API_HOST}:${API_PORT}/policy/api/v1</stringProp> + <stringProp name="Authorization.username">${API_USER}</stringProp> + <stringProp name="Authorization.password">${API_PASSWORD}</stringProp> + <stringProp name="Authorization.domain"></stringProp> + <stringProp name="Authorization.realm"></stringProp> + </elementProp> + </collectionProp> + <boolProp name="AuthManager.clearEachIteration">true</boolProp> + <boolProp name="AuthManager.controlledByThreadGroup">false</boolProp> + </AuthManager> + <hashTree/> + </hashTree> + <HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="Delete Collab Policy" enabled="true"> + <intProp name="HTTPSampler.concurrentPool">6</intProp> + <stringProp name="HTTPSampler.domain">${API_HOST}</stringProp> + <stringProp name="HTTPSampler.port">${API_PORT}</stringProp> + <stringProp name="HTTPSampler.protocol">${HTTP}</stringProp> + <stringProp name="HTTPSampler.path">policy/api/v1/policytypes/onap.policies.native.opa/versions/1.0.0/policies/collab/versions/1.0.0</stringProp> + <boolProp name="HTTPSampler.follow_redirects">true</boolProp> + <stringProp name="HTTPSampler.method">DELETE</stringProp> + <boolProp name="HTTPSampler.use_keepalive">true</boolProp> + <boolProp name="HTTPSampler.postBodyRaw">false</boolProp> + <elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" testname="User Defined Variables"> + <collectionProp name="Arguments.arguments"/> + </elementProp> + </HTTPSamplerProxy> + <hashTree> + <AuthManager guiclass="AuthPanel" testclass="AuthManager" testname="HTTP Authorization Manager" enabled="true"> + <collectionProp name="AuthManager.auth_list"> + <elementProp name="" elementType="Authorization"> + <stringProp name="Authorization.url">${HTTP}://${API_HOST}:${API_PORT}/policy/api/v1</stringProp> + <stringProp name="Authorization.username">${API_USER}</stringProp> + <stringProp name="Authorization.password">${API_PASSWORD}</stringProp> + <stringProp name="Authorization.domain"></stringProp> + <stringProp name="Authorization.realm"></stringProp> + </elementProp> + </collectionProp> + <boolProp name="AuthManager.clearEachIteration">true</boolProp> + <boolProp name="AuthManager.controlledByThreadGroup">false</boolProp> + </AuthManager> + <hashTree/> + </hashTree> + <HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="Delete Conflict Policy" enabled="true"> + <intProp name="HTTPSampler.concurrentPool">6</intProp> + <stringProp name="HTTPSampler.domain">${API_HOST}</stringProp> + <stringProp name="HTTPSampler.port">${API_PORT}</stringProp> + <stringProp name="HTTPSampler.protocol">${HTTP}</stringProp> + <stringProp name="HTTPSampler.path">policy/api/v1/policytypes/onap.policies.native.opa/versions/1.0.0/policies/conflict/versions/1.0.0</stringProp> + <boolProp name="HTTPSampler.follow_redirects">true</boolProp> + <stringProp name="HTTPSampler.method">DELETE</stringProp> + <boolProp name="HTTPSampler.use_keepalive">true</boolProp> + <boolProp name="HTTPSampler.postBodyRaw">false</boolProp> + <elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" testname="User Defined Variables"> + <collectionProp name="Arguments.arguments"/> + </elementProp> + </HTTPSamplerProxy> + <hashTree> + <AuthManager guiclass="AuthPanel" testclass="AuthManager" testname="HTTP Authorization Manager" enabled="true"> + <collectionProp name="AuthManager.auth_list"> + <elementProp name="" elementType="Authorization"> + <stringProp name="Authorization.url">${HTTP}://${API_HOST}:${API_PORT}/policy/api/v1</stringProp> + <stringProp name="Authorization.username">${API_USER}</stringProp> + <stringProp name="Authorization.password">${API_PASSWORD}</stringProp> + <stringProp name="Authorization.domain"></stringProp> + <stringProp name="Authorization.realm"></stringProp> + </elementProp> + </collectionProp> + <boolProp name="AuthManager.clearEachIteration">true</boolProp> + <boolProp name="AuthManager.controlledByThreadGroup">false</boolProp> + </AuthManager> + <hashTree/> + </hashTree> + <HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="Delete Zone Policy" enabled="true"> + <intProp name="HTTPSampler.concurrentPool">6</intProp> + <stringProp name="HTTPSampler.domain">${API_HOST}</stringProp> + <stringProp name="HTTPSampler.port">${API_PORT}</stringProp> + <stringProp name="HTTPSampler.protocol">${HTTP}</stringProp> + <stringProp name="HTTPSampler.path">policy/api/v1/policytypes/onap.policies.native.opa/versions/1.0.0/policies/zone/versions/1.0.0</stringProp> + <boolProp name="HTTPSampler.follow_redirects">true</boolProp> + <stringProp name="HTTPSampler.method">DELETE</stringProp> + <boolProp name="HTTPSampler.use_keepalive">true</boolProp> + <boolProp name="HTTPSampler.postBodyRaw">false</boolProp> + <elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" testname="User Defined Variables"> + <collectionProp name="Arguments.arguments"/> + </elementProp> + </HTTPSamplerProxy> + <hashTree> + <AuthManager guiclass="AuthPanel" testclass="AuthManager" testname="HTTP Authorization Manager" enabled="true"> + <collectionProp name="AuthManager.auth_list"> + <elementProp name="" elementType="Authorization"> + <stringProp name="Authorization.url">${HTTP}://${API_HOST}:${API_PORT}/policy/api/v1</stringProp> + <stringProp name="Authorization.username">${API_USER}</stringProp> + <stringProp name="Authorization.password">${API_PASSWORD}</stringProp> + <stringProp name="Authorization.domain"></stringProp> + <stringProp name="Authorization.realm"></stringProp> + </elementProp> + </collectionProp> + <boolProp name="AuthManager.clearEachIteration">true</boolProp> + <boolProp name="AuthManager.controlledByThreadGroup">false</boolProp> + </AuthManager> + <hashTree/> + </hashTree> + <ResultCollector guiclass="ViewResultsFullVisualizer" testclass="ResultCollector" testname="View Results Tree" enabled="true"> + <boolProp name="ResultCollector.error_logging">false</boolProp> + <objProp> + <name>saveConfig</name> + <value class="SampleSaveConfiguration"> + <time>true</time> + <latency>true</latency> + <timestamp>true</timestamp> + <success>true</success> + <label>true</label> + <code>true</code> + <message>true</message> + <threadName>true</threadName> + <dataType>true</dataType> + <encoding>false</encoding> + <assertions>true</assertions> + <subresults>true</subresults> + <responseData>false</responseData> + <samplerData>false</samplerData> + <xml>false</xml> + <fieldNames>true</fieldNames> + <responseHeaders>false</responseHeaders> + <requestHeaders>false</requestHeaders> + <responseDataOnError>false</responseDataOnError> + <saveAssertionResultsFailureMessage>true</saveAssertionResultsFailureMessage> + <assertionsResultsToSave>0</assertionsResultsToSave> + <bytes>true</bytes> + <sentBytes>true</sentBytes> + <url>true</url> + <threadCounts>true</threadCounts> + <idleTime>true</idleTime> + <connectTime>true</connectTime> + </value> + </objProp> + <stringProp name="filename">/tmp/pdpo_stability_deployment.log</stringProp> </ResultCollector> <hashTree/> </hashTree> @@ -658,7 +1673,7 @@ if (prev.getResponseCode() == '200') { <connectTime>true</connectTime> </value> </objProp> - <stringProp name="filename">/tmp/pdpx_stability_summaryReport.log</stringProp> + <stringProp name="filename">/tmp/pdpo_stability_summaryReport.log</stringProp> <boolProp name="useGroupName">true</boolProp> </ResultCollector> <hashTree/> @@ -696,7 +1711,7 @@ if (prev.getResponseCode() == '200') { <connectTime>true</connectTime> </value> </objProp> - <stringProp name="filename">/tmp/pdpx_stability_resultsTree.log</stringProp> + <stringProp name="filename">/tmp/pdpo_stability_resultsTree.log</stringProp> </ResultCollector> <hashTree/> <ResultCollector guiclass="TableVisualizer" testclass="ResultCollector" testname="View Results in Table" enabled="true"> @@ -733,7 +1748,7 @@ if (prev.getResponseCode() == '200') { <connectTime>true</connectTime> </value> </objProp> - <stringProp name="filename">/tmp/pdpx_stability_resultsTable.log</stringProp> + <stringProp name="filename">/tmp/pdpo_stability_resultsTable.log</stringProp> </ResultCollector> <hashTree/> </hashTree> @@ -1 +1 @@ -1.0.2-SNAPSHOT +1.0.5-SNAPSHOT diff --git a/version.properties b/version.properties index 359ebb9..17c4b15 100644 --- a/version.properties +++ b/version.properties @@ -4,7 +4,7 @@ major=1 minor=0 -patch=2 +patch=5 base_version=${major}.${minor}.${patch} |