2  * ============LICENSE_START=======================================================
 
   3  * Copyright (C) 2019 Bell Canada.
 
   4  * Modifications Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
 
   5  * ================================================================================
 
   6  * Licensed under the Apache License, Version 2.0 (the "License");
 
   7  * you may not use this file except in compliance with the License.
 
   8  * You may obtain a copy of the License at
 
  10  *      http://www.apache.org/licenses/LICENSE-2.0
 
  12  * Unless required by applicable law or agreed to in writing, software
 
  13  * distributed under the License is distributed on an "AS IS" BASIS,
 
  14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 
  15  * See the License for the specific language governing permissions and
 
  16  * limitations under the License.
 
  17  * ============LICENSE_END=========================================================
 
  20 package org.onap.policy.cds.client;
 
  22 import static org.junit.Assert.assertEquals;
 
  23 import static org.mockito.AdditionalAnswers.delegatesTo;
 
  24 import static org.mockito.Mockito.mock;
 
  25 import static org.mockito.Mockito.verify;
 
  27 import io.grpc.ClientInterceptors;
 
  28 import io.grpc.ManagedChannel;
 
  29 import io.grpc.Metadata;
 
  30 import io.grpc.Metadata.Key;
 
  31 import io.grpc.ServerCall;
 
  32 import io.grpc.ServerCall.Listener;
 
  33 import io.grpc.ServerCallHandler;
 
  34 import io.grpc.ServerInterceptor;
 
  35 import io.grpc.ServerInterceptors;
 
  36 import io.grpc.inprocess.InProcessChannelBuilder;
 
  37 import io.grpc.inprocess.InProcessServerBuilder;
 
  38 import io.grpc.stub.StreamObserver;
 
  39 import io.grpc.testing.GrpcCleanupRule;
 
  40 import java.io.IOException;
 
  41 import java.nio.charset.StandardCharsets;
 
  42 import java.util.Base64;
 
  43 import org.junit.Before;
 
  44 import org.junit.Rule;
 
  45 import org.junit.Test;
 
  46 import org.mockito.ArgumentCaptor;
 
  47 import org.mockito.ArgumentMatchers;
 
  48 import org.onap.ccsdk.cds.controllerblueprints.processing.api.BlueprintProcessingServiceGrpc;
 
  49 import org.onap.ccsdk.cds.controllerblueprints.processing.api.BlueprintProcessingServiceGrpc.BlueprintProcessingServiceImplBase;
 
  50 import org.onap.ccsdk.cds.controllerblueprints.processing.api.BlueprintProcessingServiceGrpc.BlueprintProcessingServiceStub;
 
  51 import org.onap.ccsdk.cds.controllerblueprints.processing.api.ExecutionServiceOutput;
 
  52 import org.onap.policy.cds.properties.CdsServerProperties;
 
  54 public class BasicAuthClientHeaderInterceptorTest {
 
  56     // Generate a unique in-process server name.
 
  57     private static final String SERVER_NAME = InProcessServerBuilder.generateName();
 
  58     private static final String CREDS = "test";
 
  60     // Manages automatic graceful shutdown for the registered server and client channels at the end of test.
 
  62     public final GrpcCleanupRule grpcCleanup = new GrpcCleanupRule();
 
  64     private final ServerInterceptor mockCdsGrpcServerInterceptor = mock(ServerInterceptor.class,
 
  65         delegatesTo(new TestServerInterceptor()));
 
  67     private final CdsServerProperties props = new CdsServerProperties();
 
  69     private ManagedChannel channel;
 
  74      * @throws IOException on failure to register the test grpc server for graceful shutdown
 
  77     public void setUp() throws IOException {
 
  78         // Setup the CDS properties
 
  79         props.setHost(SERVER_NAME);
 
  81         props.setUsername(CREDS);
 
  82         props.setPassword(CREDS);
 
  85         // Implement the test gRPC server
 
  86         BlueprintProcessingServiceImplBase testCdsBlueprintServerImpl = new BlueprintProcessingServiceImplBase() {};
 
  88         // Create a server, add service, start, and register for automatic graceful shutdown.
 
  89         grpcCleanup.register(InProcessServerBuilder.forName(SERVER_NAME).directExecutor()
 
  90             .addService(ServerInterceptors.intercept(testCdsBlueprintServerImpl, mockCdsGrpcServerInterceptor)).build()
 
  93         // Create a client channel and register for automatic graceful shutdown
 
  94         channel = grpcCleanup.register(InProcessChannelBuilder.forName(SERVER_NAME).directExecutor().build());
 
  98     public void testIfBasicAuthHeaderIsDeliveredToCdsServer() {
 
  99         BlueprintProcessingServiceStub bpProcessingSvcStub = BlueprintProcessingServiceGrpc
 
 100             .newStub(ClientInterceptors.intercept(channel, new BasicAuthClientHeaderInterceptor(props)));
 
 101         ArgumentCaptor<Metadata> metadataCaptor = ArgumentCaptor.forClass(Metadata.class);
 
 102         bpProcessingSvcStub.process(new StreamObserver<ExecutionServiceOutput>() {
 
 104             public void onNext(final ExecutionServiceOutput executionServiceOutput) {
 
 109             public void onError(final Throwable throwable) {
 
 114             public void onCompleted() {
 
 118         verify(mockCdsGrpcServerInterceptor).interceptCall(ArgumentMatchers.any(), metadataCaptor.capture(),
 
 119             ArgumentMatchers.any());
 
 121         Key<String> authHeader = Key
 
 122             .of(BasicAuthClientHeaderInterceptor.BASIC_AUTH_HEADER_KEY, Metadata.ASCII_STRING_MARSHALLER);
 
 123         String expectedBaseAuth = "Basic " + Base64.getEncoder().encodeToString(String.format("%s:%s", CREDS, CREDS)
 
 124             .getBytes(StandardCharsets.UTF_8));
 
 125         assertEquals(expectedBaseAuth, metadataCaptor.getValue().get(authHeader));
 
 128     private static class TestServerInterceptor implements ServerInterceptor {
 
 131         public <Q, P> Listener<Q> interceptCall(final ServerCall<Q, P> serverCall,
 
 132                         final Metadata metadata, final ServerCallHandler<Q, P> serverCallHandler) {
 
 133             return serverCallHandler.startCall(serverCall, metadata);