summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordfarrelly <david.farrelly@est.tech>2019-04-03 14:40:31 +0000
committerdfarrelly <david.farrelly@est.tech>2019-04-03 14:40:31 +0000
commit49d2deae8aa7b57ecf6fb692803594c1bae8e8bf (patch)
tree6e8b70981cdc3e677ab8e8d483ab8542ac482bd5
parent7be6327ec6df91622c0a5feaa07e39fae8efb018 (diff)
Add support for HTTPS
*Add AAF certificates *Switch PM Mapper endpoints to HTTPS *Make external API calls secure if applicable Issue-ID: DCAEGEN2-1296 Change-Id: I63aef8a93cfe6d6a37dcd32496b35ed0841cec4b Signed-off-by: dfarrelly <david.farrelly@est.tech>
-rw-r--r--dpo/blueprints/k8s-pm-mapper.yaml64
-rw-r--r--src/main/java/org/onap/dcaegen2/services/pmmapper/App.java20
-rw-r--r--src/main/java/org/onap/dcaegen2/services/pmmapper/datarouter/DataRouterSubscriber.java2
-rw-r--r--src/main/java/org/onap/dcaegen2/services/pmmapper/exceptions/CreateContextException.java27
-rw-r--r--src/main/java/org/onap/dcaegen2/services/pmmapper/exceptions/KeyManagerException.java27
-rw-r--r--src/main/java/org/onap/dcaegen2/services/pmmapper/exceptions/LoadKeyStoreException.java27
-rw-r--r--src/main/java/org/onap/dcaegen2/services/pmmapper/exceptions/ServerResponseException.java27
-rw-r--r--src/main/java/org/onap/dcaegen2/services/pmmapper/exceptions/TrustManagerException.java27
-rw-r--r--src/main/java/org/onap/dcaegen2/services/pmmapper/model/MapperConfig.java371
-rw-r--r--src/main/java/org/onap/dcaegen2/services/pmmapper/ssl/SSLContextFactory.java133
-rw-r--r--src/main/java/org/onap/dcaegen2/services/pmmapper/utils/DataRouterUtils.java5
-rw-r--r--src/main/java/org/onap/dcaegen2/services/pmmapper/utils/RequestSender.java19
-rw-r--r--src/test/java/org/onap/dcaegen2/pmmapper/config/util/RequestSenderTests.java1
-rw-r--r--src/test/java/org/onap/dcaegen2/services/pmmapper/ssl/SSLContextFactoryTest.java84
-rw-r--r--src/test/java/org/onap/dcaegen2/services/pmmapper/utils/DataRouterUtilsTest.java68
-rw-r--r--src/test/resources/password1
-rw-r--r--src/test/resources/testkeystore.jks.b6435
-rw-r--r--src/test/resources/valid_mapper_config.json7
18 files changed, 732 insertions, 213 deletions
diff --git a/dpo/blueprints/k8s-pm-mapper.yaml b/dpo/blueprints/k8s-pm-mapper.yaml
index 88fb44a..0944da3 100644
--- a/dpo/blueprints/k8s-pm-mapper.yaml
+++ b/dpo/blueprints/k8s-pm-mapper.yaml
@@ -22,17 +22,17 @@ tosca_definitions_version: cloudify_dsl_1_3
imports:
- "http://www.getcloudify.org/spec/cloudify/3.4/types.yaml"
- - "https://nexus.onap.org/service/local/repositories/raw/content/org.onap.dcaegen2.platform.plugins/R3/k8splugin/1.4.4/k8splugin_types.yaml"
+ - "https://nexus.onap.org/service/local/repositories/raw/content/org.onap.dcaegen2.platform.plugins/R4/k8splugin/1.4.5/k8splugin_types.yaml"
inputs:
service_name:
type: string
description: Name of the serice
- default: "pm-mapper"
+ default: "dcae-pm-mapper"
tag_version:
type: string
description: Docker image to be used
- default: "nexus3.onap.org:10001/onap/org.onap.dcaegen2.services.pm-mapper:1.0-SNAPSHOT"
+ default: "nexus3.onap.org:10001/onap/org.onap.dcaegen2.services.pm-mapper:latest"
replicas:
type: integer
description: Number of instances
@@ -55,11 +55,11 @@ inputs:
default: "ves-pub-1"
dmaap_dr_username:
type: string
- description: dmaap datarouter user name
+ description: DMAAP Data Router user name
default: "username"
dmaap_dr_password:
type: string
- description: dmaap datarouter password
+ description: DMAAP Data Router password
default: "password"
dcae_location:
type: string
@@ -69,42 +69,54 @@ inputs:
type: string
description: Subscriber id in Data Router
default: ""
+ pm_mapper_service_protocol:
+ type: string
+ description: PM Mapper protocol
+ default: "https"
+ pm_mapper_service_port:
+ type: string
+ description: PM Mapper host port
+ default: "8443"
dmaap_buscontroller_service_host:
type: string
description: DMAAP Bus Controller host address
default: "dmaap-bc.onap.svc.cluster.local"
dmaap_buscontroller_service_port:
type: string
- description: DMAAP bus Controller host port
+ description: DMAAP Bus Controller host port
default: "8080"
dmaap_dr_feed_id:
type: string
- description: ID of the data router feed that the PM Mapper will subscribe to
+ description: ID of the Data Router feed that the PM Mapper will subscribe to
default: "1"
dmaap_dr_service_host:
type: string
description: DMAAP Data Router host address
- default: "dmaap-dr-node.onap.svc.cluster.local"
+ default: "dmaap-dr-node"
dmaap_dr_service_port:
type: string
description: DMAAP Data Router host port
default: "8443"
dmaap_mr_service_host:
type: string
- description: DMAAP Data Router host address
- default: "message-router.onap.svc.cluster.local"
+ description: DMAAP Message Router host address
+ default: "dmaap-mr"
dmaap_mr_service_port:
type: string
- description: DMAAP Data Router host port
- default: "3904"
+ description: DMAAP Message Router host port
+ default: "3905"
dmaap_mr_topic_name:
type: string
- description: Name of MR topic events will be published to
+ description: Name of Message Router topic events will be published to
default: "pm-mapper-ves"
filter:
type: string
- description: PM mapper filter on measInfo, measInfoId, measType, instanceId
+ description: PM Mapper filter on measInfo, measInfoId, measType, instanceId
default: "{ \"filters\":[]}"
+ enable_http:
+ type: boolean
+ description: Option to turn on HTTP connections
+ default: false
node_templates:
pm-mapper:
@@ -113,18 +125,25 @@ node_templates:
start:
inputs:
ports:
- - '8080:0'
+ - '8443:0'
+ - '8081:0'
properties:
application_config:
+ enable_http:
+ { get_input: enable_http }
+ trust_store_path: "/opt/app/pm-mapper/etc/cert/trust.jks.b64"
+ trust_store_pass_path: "/opt/app/pm-mapper/etc/cert/trust.pass"
+ key_store_path: "/opt/app/pm-mapper/etc/cert/cert.jks.b64"
+ key_store_pass_path: "/opt/app/pm-mapper/etc/cert/cert.pass"
buscontroller_feed_subscription_endpoint:
{ concat: ["http://", { get_input: dmaap_buscontroller_service_host },
":", { get_input: dmaap_buscontroller_service_port}, "/webapi/dr_subs"]}
dmaap_dr_feed_id:
get_input: dmaap_dr_feed_id
dmaap_dr_delete_endpoint:
- { concat: ["http://", { get_input: dmaap_dr_service_host },
+ { concat: ["https://", { get_input: dmaap_dr_service_host },
":", { get_input: dmaap_dr_service_port}, "/delete"]}
- filters:
+ pm-mapper-filter:
get_input: filter
streams_subscribes:
dmaap_subscriber:
@@ -140,8 +159,8 @@ node_templates:
subscriber_id:
get_input: subscriber_id
delivery_url:
- { concat: ["http://", { get_input: service_name }, ".onap.svc.cluster.local",
- ":8081/delivery"]}
+ { concat: [{ get_input: pm_mapper_service_protocol },"://", { get_input: service_name }, ".onap.svc.cluster.local",
+ ":", { get_input: pm_mapper_service_port }, "/delivery"]}
streams_publishes:
dmaap_publisher:
aaf_username:
@@ -156,7 +175,7 @@ node_templates:
client_id:
get_input: client_id
topic_url:
- { concat: ["http://", { get_input: dmaap_mr_service_host },
+ { concat: ["https://", { get_input: dmaap_mr_service_host },
":", { get_input: dmaap_mr_service_port }, "/events/", { get_input: dmaap_mr_topic_name }]}
location:
get_input: dcae_location
@@ -165,7 +184,7 @@ node_templates:
endpoint: /healthcheck
interval: 15s
timeout: 1s
- type: http
+ type: https
image:
get_input: tag_version
replicas: { get_input: replicas }
@@ -173,4 +192,7 @@ node_templates:
dns_name: { get_input: service_name }
log_info:
log_directory: "/var/log/ONAP/dcaegen2/services/pm-mapper"
+ tls_info:
+ cert_directory: "/opt/app/pm-mapper/etc/cert/"
+ use_tls: true
type: dcae.nodes.ContainerizedPlatformComponent \ No newline at end of file
diff --git a/src/main/java/org/onap/dcaegen2/services/pmmapper/App.java b/src/main/java/org/onap/dcaegen2/services/pmmapper/App.java
index b52a5f1..25e3918 100644
--- a/src/main/java/org/onap/dcaegen2/services/pmmapper/App.java
+++ b/src/main/java/org/onap/dcaegen2/services/pmmapper/App.java
@@ -42,6 +42,7 @@ import org.onap.dcaegen2.services.pmmapper.messagerouter.VESPublisher;
import org.onap.dcaegen2.services.pmmapper.model.Event;
import org.onap.dcaegen2.services.pmmapper.model.MapperConfig;
import org.onap.dcaegen2.services.pmmapper.healthcheck.HealthCheckHandler;
+import org.onap.dcaegen2.services.pmmapper.ssl.SSLContextFactory;
import org.onap.dcaegen2.services.pmmapper.utils.DataRouterUtils;
import org.onap.dcaegen2.services.pmmapper.utils.MeasConverter;
import org.onap.dcaegen2.services.pmmapper.utils.MeasSplitter;
@@ -53,6 +54,8 @@ import reactor.core.publisher.Flux;
import reactor.core.publisher.FluxSink;
import reactor.core.scheduler.Schedulers;
+import javax.net.ssl.SSLContext;
+import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
@@ -64,7 +67,7 @@ public class App {
private static Path xmlSchema = Paths.get("/opt/app/pm-mapper/etc/measCollec_plusString.xsd");
private static FluxSink<Event> fluxSink;
- public static void main(String[] args) throws InterruptedException, TooManyTriesException, CBSConfigException, EnvironmentConfigException, CBSServerError, MapperConfigException {
+ public static void main(String[] args) throws InterruptedException, TooManyTriesException, CBSConfigException, EnvironmentConfigException, CBSServerError, MapperConfigException, IOException {
Flux<Event> flux = Flux.create(eventFluxSink -> fluxSink = eventFluxSink);
HealthCheckHandler healthCheckHandler = new HealthCheckHandler();
MapperConfig mapperConfig = new ConfigHandler().getMapperConfig();
@@ -89,7 +92,7 @@ public class App {
.filter(events -> App.filter(filterHandler, events, mapperConfig))
.concatMap(events -> App.map(mapper, events, mapperConfig))
.concatMap(vesPublisher::publish)
- .subscribe(events -> logger.unwrap().info("Event Processed"));
+ .subscribe(event -> App.sendEventProcessed(mapperConfig, event));
DataRouterSubscriber dataRouterSubscriber = new DataRouterSubscriber(fluxSink::next, mapperConfig);
dataRouterSubscriber.start();
@@ -98,8 +101,17 @@ public class App {
configurables.add(mapperConfig);
DynamicConfiguration dynamicConfiguration = new DynamicConfiguration(configurables, mapperConfig);
- Undertow.builder()
- .addHttpListener(8081, "0.0.0.0")
+ Undertow.Builder builder = Undertow.builder();
+
+ SSLContextFactory sslContextFactory = new SSLContextFactory(mapperConfig);
+ SSLContext sslContext = sslContextFactory.createSSLContext(mapperConfig);
+ SSLContext.setDefault(sslContext);
+
+ if(mapperConfig.getEnableHttp()) {
+ builder.addHttpListener(8081, "0.0.0.0");
+ }
+
+ builder.addHttpsListener(8443, "0.0.0.0", sslContext)
.setHandler(Handlers.routing()
.add("put", "/delivery/{filename}", dataRouterSubscriber)
.add("get", "/healthcheck", healthCheckHandler)
diff --git a/src/main/java/org/onap/dcaegen2/services/pmmapper/datarouter/DataRouterSubscriber.java b/src/main/java/org/onap/dcaegen2/services/pmmapper/datarouter/DataRouterSubscriber.java
index 19a4750..a0a8eaf 100644
--- a/src/main/java/org/onap/dcaegen2/services/pmmapper/datarouter/DataRouterSubscriber.java
+++ b/src/main/java/org/onap/dcaegen2/services/pmmapper/datarouter/DataRouterSubscriber.java
@@ -85,7 +85,7 @@ public class DataRouterSubscriber implements HttpHandler, Configurable {
private Random jitterGenerator;
private Gson metadataBuilder;
private MapperConfig config;
- private String subscriberId;
+ public static String subscriberId;
@NonNull
private EventReceiver eventReceiver;
diff --git a/src/main/java/org/onap/dcaegen2/services/pmmapper/exceptions/CreateContextException.java b/src/main/java/org/onap/dcaegen2/services/pmmapper/exceptions/CreateContextException.java
new file mode 100644
index 0000000..a5a230c
--- /dev/null
+++ b/src/main/java/org/onap/dcaegen2/services/pmmapper/exceptions/CreateContextException.java
@@ -0,0 +1,27 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2019 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=========================================================
+ */
+
+package org.onap.dcaegen2.services.pmmapper.exceptions;
+
+public class CreateContextException extends RuntimeException {
+ public CreateContextException(String message, Throwable cause) {
+ super(message, cause);
+ }
+} \ No newline at end of file
diff --git a/src/main/java/org/onap/dcaegen2/services/pmmapper/exceptions/KeyManagerException.java b/src/main/java/org/onap/dcaegen2/services/pmmapper/exceptions/KeyManagerException.java
new file mode 100644
index 0000000..d123991
--- /dev/null
+++ b/src/main/java/org/onap/dcaegen2/services/pmmapper/exceptions/KeyManagerException.java
@@ -0,0 +1,27 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2019 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=========================================================
+ */
+
+package org.onap.dcaegen2.services.pmmapper.exceptions;
+
+public class KeyManagerException extends RuntimeException {
+ public KeyManagerException(String message, Throwable cause) {
+ super(message, cause);
+ }
+} \ No newline at end of file
diff --git a/src/main/java/org/onap/dcaegen2/services/pmmapper/exceptions/LoadKeyStoreException.java b/src/main/java/org/onap/dcaegen2/services/pmmapper/exceptions/LoadKeyStoreException.java
new file mode 100644
index 0000000..96bfad5
--- /dev/null
+++ b/src/main/java/org/onap/dcaegen2/services/pmmapper/exceptions/LoadKeyStoreException.java
@@ -0,0 +1,27 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2019 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=========================================================
+ */
+
+package org.onap.dcaegen2.services.pmmapper.exceptions;
+
+public class LoadKeyStoreException extends RuntimeException {
+ public LoadKeyStoreException(String message, Throwable cause) {
+ super(message, cause);
+ }
+} \ No newline at end of file
diff --git a/src/main/java/org/onap/dcaegen2/services/pmmapper/exceptions/ServerResponseException.java b/src/main/java/org/onap/dcaegen2/services/pmmapper/exceptions/ServerResponseException.java
new file mode 100644
index 0000000..b52e2d4
--- /dev/null
+++ b/src/main/java/org/onap/dcaegen2/services/pmmapper/exceptions/ServerResponseException.java
@@ -0,0 +1,27 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2019 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=========================================================
+ */
+
+package org.onap.dcaegen2.services.pmmapper.exceptions;
+
+public class ServerResponseException extends Exception {
+ public ServerResponseException(String message, Throwable cause) {
+ super(message, cause);
+ }
+} \ No newline at end of file
diff --git a/src/main/java/org/onap/dcaegen2/services/pmmapper/exceptions/TrustManagerException.java b/src/main/java/org/onap/dcaegen2/services/pmmapper/exceptions/TrustManagerException.java
new file mode 100644
index 0000000..75ce61d
--- /dev/null
+++ b/src/main/java/org/onap/dcaegen2/services/pmmapper/exceptions/TrustManagerException.java
@@ -0,0 +1,27 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2019 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=========================================================
+ */
+
+package org.onap.dcaegen2.services.pmmapper.exceptions;
+
+public class TrustManagerException extends RuntimeException {
+ public TrustManagerException(String message, Throwable cause) {
+ super(message, cause);
+ }
+} \ No newline at end of file
diff --git a/src/main/java/org/onap/dcaegen2/services/pmmapper/model/MapperConfig.java b/src/main/java/org/onap/dcaegen2/services/pmmapper/model/MapperConfig.java
index bd4eafb..b9d58ee 100644
--- a/src/main/java/org/onap/dcaegen2/services/pmmapper/model/MapperConfig.java
+++ b/src/main/java/org/onap/dcaegen2/services/pmmapper/model/MapperConfig.java
@@ -1,176 +1,197 @@
-/*-
- * ============LICENSE_START=======================================================
- * Copyright (C) 2019 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=========================================================
- */
-package org.onap.dcaegen2.services.pmmapper.model;
-
-import java.net.MalformedURLException;
-import java.net.URL;
-
-import org.onap.dcaegen2.services.pmmapper.config.Configurable;
-import org.onap.dcaegen2.services.pmmapper.utils.GSONRequired;
-import com.google.gson.annotations.SerializedName;
-import lombok.Getter;
-import lombok.AccessLevel;
-import lombok.EqualsAndHashCode;
-import lombok.NoArgsConstructor;
-
-@Getter
-@EqualsAndHashCode
-@NoArgsConstructor
-public class MapperConfig implements Configurable{
-
- public static final String CLIENT_NAME = "pm-mapper";
-
- @GSONRequired
- @Getter(AccessLevel.PRIVATE)
- @SerializedName("streams_subscribes")
- private StreamsSubscribes streamsSubscribes;
-
- @GSONRequired
- @Getter(AccessLevel.PRIVATE)
- @SerializedName("streams_publishes")
- private StreamsPublishes streamsPublishes;
-
- @GSONRequired
- @SerializedName("buscontroller_feed_subscription_endpoint")
- private String busControllerSubscriptionEndpoint;
-
- @GSONRequired
- @SerializedName("dmaap_dr_feed_id")
- private String dmaapDRFeedId;
-
- @GSONRequired
- @SerializedName("dmaap_dr_delete_endpoint")
- private String dmaapDRDeleteEndpoint;
-
- public String getBusControllerDeliveryUrl() {
- return this.getStreamsSubscribes().getDmaapSubscriber().getDmaapInfo().getDeliveryUrl();
- }
-
- public String getDcaeLocation() {
- return this.getStreamsSubscribes().getDmaapSubscriber().getDmaapInfo().getLocation();
- }
-
- public String getBusControllerUserName() {
- return this.getStreamsSubscribes().getDmaapSubscriber().getDmaapInfo().getUsername();
- }
-
- public String getBusControllerPassword() {
- return this.getStreamsSubscribes().getDmaapSubscriber().getDmaapInfo().getPassword();
- }
-
- public URL getBusControllerSubscriptionUrl() throws MalformedURLException {
- return new URL(this.getBusControllerSubscriptionEndpoint());
- }
-
- public String getSubscriberIdentity(){
- return this.getStreamsSubscribes().getDmaapSubscriber().getDmaapInfo().getSubscriberId();
- }
-
- public String getSubscriberDcaeLocation() {
- return this.getStreamsSubscribes().getDmaapSubscriber().getDmaapInfo().getLocation();
- }
-
- public String getPublisherTopicUrl() {
- return this.getStreamsPublishes().getDmaapPublisher().getDmaapInfo().getTopicUrl();
- }
-
- public boolean dmaapInfoEquals(MapperConfig mapperConfig){
- return this
- .getStreamsSubscribes()
- .getDmaapSubscriber()
- .getDmaapInfo()
- .equals(mapperConfig.getStreamsSubscribes().getDmaapSubscriber().getDmaapInfo());
- }
-
- @Getter
- @EqualsAndHashCode
- private class StreamsSubscribes {
- @GSONRequired
- @SerializedName("dmaap_subscriber")
- DmaapSubscriber dmaapSubscriber;
- }
-
- @Getter
- @EqualsAndHashCode
- class DmaapSubscriber {
- @GSONRequired
- @SerializedName("dmaap_info")
- DmaapInfo dmaapInfo;
- }
-
- @Getter
- @EqualsAndHashCode
- private class StreamsPublishes {
- @GSONRequired
- @SerializedName("dmaap_publisher")
- DmaapPublisher dmaapPublisher;
- }
-
- @Getter
- @EqualsAndHashCode
- class DmaapPublisher {
- @GSONRequired
- @SerializedName("dmaap_info")
- DmaapInfo dmaapInfo;
- }
-
- @Getter
- @EqualsAndHashCode
- class DmaapInfo {
- private String location;
- private String username;
- private String password;
-
- @SerializedName("delivery_url")
- private String deliveryUrl;
-
- @SerializedName("subscriber_id")
- private String subscriberId;
-
- @SerializedName("aaf_username")
- private String aafUsername;
-
- @SerializedName("aaf_password")
- private String aafPassword;
-
- @SerializedName("client_role")
- private String clientRole;
-
- @SerializedName("client_id")
- private String clientId;
-
- @SerializedName("topic_url")
- private String topicUrl;
- }
-
- @SerializedName("pm-mapper-filter")
- MeasFilterConfig filterConfig;
-
- @Override
- public void reconfigure(MapperConfig mapperConfig) {
- if(!this.equals(mapperConfig)) {
- this.streamsSubscribes = mapperConfig.getStreamsSubscribes();
- this.streamsPublishes = mapperConfig.getStreamsPublishes();
- this.busControllerSubscriptionEndpoint = mapperConfig.getBusControllerSubscriptionEndpoint();
- this.dmaapDRFeedId = mapperConfig.getDmaapDRFeedId();
- this.dmaapDRDeleteEndpoint = mapperConfig.getDmaapDRDeleteEndpoint();
- }
- }
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2019 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=========================================================
+ */
+package org.onap.dcaegen2.services.pmmapper.model;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+
+import org.onap.dcaegen2.services.pmmapper.config.Configurable;
+import org.onap.dcaegen2.services.pmmapper.utils.GSONRequired;
+import com.google.gson.annotations.SerializedName;
+import lombok.Getter;
+import lombok.AccessLevel;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+
+@Getter
+@EqualsAndHashCode
+@NoArgsConstructor
+public class MapperConfig implements Configurable{
+
+ public static final String CLIENT_NAME = "pm-mapper";
+
+ @GSONRequired
+ @SerializedName("enable_http")
+ private Boolean enableHttp;
+
+ @GSONRequired
+ @SerializedName("key_store_path")
+ private String keyStorePath;
+
+ @GSONRequired
+ @SerializedName("key_store_pass_path")
+ private String keyStorePassPath;
+
+ @GSONRequired
+ @SerializedName("trust_store_path")
+ private String trustStorePath;
+
+ @GSONRequired
+ @SerializedName("trust_store_pass_path")
+ private String trustStorePassPath;
+
+ @GSONRequired
+ @Getter(AccessLevel.PRIVATE)
+ @SerializedName("streams_subscribes")
+ private StreamsSubscribes streamsSubscribes;
+
+ @GSONRequired
+ @Getter(AccessLevel.PRIVATE)
+ @SerializedName("streams_publishes")
+ private StreamsPublishes streamsPublishes;
+
+ @GSONRequired
+ @SerializedName("buscontroller_feed_subscription_endpoint")
+ private String busControllerSubscriptionEndpoint;
+
+ @GSONRequired
+ @SerializedName("dmaap_dr_feed_id")
+ private String dmaapDRFeedId;
+
+ @GSONRequired
+ @SerializedName("dmaap_dr_delete_endpoint")
+ private String dmaapDRDeleteEndpoint;
+
+ @GSONRequired
+ @SerializedName("pm-mapper-filter")
+ private MeasFilterConfig filterConfig;
+
+ public String getBusControllerDeliveryUrl() {
+ return this.getStreamsSubscribes().getDmaapSubscriber().getDmaapInfo().getDeliveryUrl();
+ }
+
+ public String getDcaeLocation() {
+ return this.getStreamsSubscribes().getDmaapSubscriber().getDmaapInfo().getLocation();
+ }
+
+ public String getBusControllerUserName() {
+ return this.getStreamsSubscribes().getDmaapSubscriber().getDmaapInfo().getUsername();
+ }
+
+ public String getBusControllerPassword() {
+ return this.getStreamsSubscribes().getDmaapSubscriber().getDmaapInfo().getPassword();
+ }
+
+ public URL getBusControllerSubscriptionUrl() throws MalformedURLException {
+ return new URL(this.getBusControllerSubscriptionEndpoint());
+ }
+
+ public String getSubscriberIdentity(){
+ return this.getStreamsSubscribes().getDmaapSubscriber().getDmaapInfo().getSubscriberId();
+ }
+
+ public String getSubscriberDcaeLocation() {
+ return this.getStreamsSubscribes().getDmaapSubscriber().getDmaapInfo().getLocation();
+ }
+
+ public String getPublisherTopicUrl() {
+ return this.getStreamsPublishes().getDmaapPublisher().getDmaapInfo().getTopicUrl();
+ }
+
+ public boolean dmaapInfoEquals(MapperConfig mapperConfig){
+ return this
+ .getStreamsSubscribes()
+ .getDmaapSubscriber()
+ .getDmaapInfo()
+ .equals(mapperConfig.getStreamsSubscribes().getDmaapSubscriber().getDmaapInfo());
+ }
+
+ @Getter
+ @EqualsAndHashCode
+ private class StreamsSubscribes {
+ @GSONRequired
+ @SerializedName("dmaap_subscriber")
+ DmaapSubscriber dmaapSubscriber;
+ }
+
+ @Getter
+ @EqualsAndHashCode
+ class DmaapSubscriber {
+ @GSONRequired
+ @SerializedName("dmaap_info")
+ DmaapInfo dmaapInfo;
+ }
+
+ @Getter
+ @EqualsAndHashCode
+ private class StreamsPublishes {
+ @GSONRequired
+ @SerializedName("dmaap_publisher")
+ DmaapPublisher dmaapPublisher;
+ }
+
+ @Getter
+ @EqualsAndHashCode
+ class DmaapPublisher {
+ @GSONRequired
+ @SerializedName("dmaap_info")
+ DmaapInfo dmaapInfo;
+ }
+
+ @Getter
+ @EqualsAndHashCode
+ class DmaapInfo {
+ private String location;
+ private String username;
+ private String password;
+
+ @SerializedName("delivery_url")
+ private String deliveryUrl;
+
+ @SerializedName("subscriber_id")
+ private String subscriberId;
+
+ @SerializedName("aaf_username")
+ private String aafUsername;
+
+ @SerializedName("aaf_password")
+ private String aafPassword;
+
+ @SerializedName("client_role")
+ private String clientRole;
+
+ @SerializedName("client_id")
+ private String clientId;
+
+ @SerializedName("topic_url")
+ private String topicUrl;
+ }
+
+ @Override
+ public void reconfigure(MapperConfig mapperConfig) {
+ if(!this.equals(mapperConfig)) {
+ this.streamsSubscribes = mapperConfig.getStreamsSubscribes();
+ this.streamsPublishes = mapperConfig.getStreamsPublishes();
+ this.busControllerSubscriptionEndpoint = mapperConfig.getBusControllerSubscriptionEndpoint();
+ this.dmaapDRFeedId = mapperConfig.getDmaapDRFeedId();
+ this.dmaapDRDeleteEndpoint = mapperConfig.getDmaapDRDeleteEndpoint();
+ }
+ }
} \ No newline at end of file
diff --git a/src/main/java/org/onap/dcaegen2/services/pmmapper/ssl/SSLContextFactory.java b/src/main/java/org/onap/dcaegen2/services/pmmapper/ssl/SSLContextFactory.java
new file mode 100644
index 0000000..68e63f5
--- /dev/null
+++ b/src/main/java/org/onap/dcaegen2/services/pmmapper/ssl/SSLContextFactory.java
@@ -0,0 +1,133 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2019 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=========================================================
+ */
+package org.onap.dcaegen2.services.pmmapper.ssl;
+
+import org.onap.dcaegen2.services.pmmapper.exceptions.CreateContextException;
+import org.onap.dcaegen2.services.pmmapper.exceptions.KeyManagerException;
+import org.onap.dcaegen2.services.pmmapper.exceptions.LoadKeyStoreException;
+import org.onap.dcaegen2.services.pmmapper.exceptions.TrustManagerException;
+import org.onap.dcaegen2.services.pmmapper.model.MapperConfig;
+import org.onap.logging.ref.slf4j.ONAPLogAdapter;
+import org.slf4j.LoggerFactory;
+
+import javax.net.ssl.KeyManager;
+import javax.net.ssl.KeyManagerFactory;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.TrustManagerFactory;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.file.Paths;
+import java.security.KeyManagementException;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.UnrecoverableKeyException;
+import java.security.cert.CertificateException;
+import java.util.Base64;
+
+import static java.nio.file.Files.readAllBytes;
+
+public class SSLContextFactory {
+ private static final ONAPLogAdapter logger = new ONAPLogAdapter(LoggerFactory.getLogger(SSLContextFactory.class));
+ private static MapperConfig mapperConfig;
+
+ public SSLContextFactory(MapperConfig config) {
+ mapperConfig = config;
+ }
+
+ public SSLContext createSSLContext(MapperConfig mapperConfig) throws IOException {
+ SSLContext sslContext = null;
+
+ try {
+ KeyStore keyStore = loadKeyStore(mapperConfig.getKeyStorePath(), mapperConfig.getKeyStorePassPath());
+ KeyManager[] keyManagers = createKeyManager(keyStore);
+
+ KeyStore trustStore = loadKeyStore(mapperConfig.getTrustStorePath(), mapperConfig.getTrustStorePassPath());
+ TrustManager[] trustManagers = createTrustManager(trustStore);
+
+ sslContext = SSLContext.getInstance("TLSv1.2");
+ sslContext.init(keyManagers, trustManagers, null);
+ } catch(KeyManagementException | NoSuchAlgorithmException e) {
+ logger.unwrap().error("Failed to create SSL Context.", e);
+ throw new CreateContextException("Failed to create SSL Context", e);
+ }
+ return sslContext;
+ }
+
+ private KeyManager[] createKeyManager(KeyStore keyStore) throws NoSuchAlgorithmException, IOException {
+ KeyManager[] keyManager;
+ KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
+
+ try {
+ keyManagerFactory.init(keyStore, getPassword(mapperConfig.getKeyStorePassPath()).toCharArray());
+ } catch (KeyStoreException | UnrecoverableKeyException e) {
+ logger.unwrap().error("Failed to initialize keystore.", e);
+ throw new KeyManagerException("Failed to create KeyManager from Keystore", e);
+ }
+ keyManager = keyManagerFactory.getKeyManagers();
+
+ return keyManager;
+ }
+
+ private TrustManager[] createTrustManager(KeyStore trustStore) throws NoSuchAlgorithmException {
+ TrustManager[] trustManagers;
+ TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
+ try {
+ trustManagerFactory.init(trustStore);
+ } catch (KeyStoreException e) {
+ throw new TrustManagerException("Failed to create TrustManager from Truststore", e);
+ }
+ trustManagers = trustManagerFactory.getTrustManagers();
+
+ return trustManagers;
+ }
+
+ private KeyStore loadKeyStore(String path, String passwordPath) throws IOException, NoSuchAlgorithmException {
+ String type = "JKS";
+ String encodedKeystore = new String(readAllBytes(Paths.get(path)));
+ String password = getPassword(passwordPath);
+
+ KeyStore keyStore = null;
+
+ try {
+ keyStore = KeyStore.getInstance(type);
+ byte[] decodedKeystore = Base64.getMimeDecoder().decode(encodedKeystore);
+ InputStream stream = new ByteArrayInputStream(decodedKeystore);
+ keyStore.load(stream, password.toCharArray());
+ } catch(KeyStoreException | CertificateException e) {
+ logger.unwrap().error("Failed to load Keystore from given configuration.", e);
+ throw new LoadKeyStoreException("Failed to load Keystore from given configuration", e);
+ }
+ return keyStore;
+ }
+
+ private String getPassword(String passwordPath) throws IOException {
+ try {
+ String password = new String(readAllBytes(Paths.get(passwordPath)));
+ password = password.replace("\n", "").replace("\r", "");
+ return password;
+ } catch (IOException e) {
+ logger.unwrap().error("Could not read password from: {}.", passwordPath, e);
+ throw new IOException("Password not found");
+ }
+ }
+}
diff --git a/src/main/java/org/onap/dcaegen2/services/pmmapper/utils/DataRouterUtils.java b/src/main/java/org/onap/dcaegen2/services/pmmapper/utils/DataRouterUtils.java
index f30fb96..5147863 100644
--- a/src/main/java/org/onap/dcaegen2/services/pmmapper/utils/DataRouterUtils.java
+++ b/src/main/java/org/onap/dcaegen2/services/pmmapper/utils/DataRouterUtils.java
@@ -20,6 +20,7 @@
package org.onap.dcaegen2.services.pmmapper.utils;
+import org.onap.dcaegen2.services.pmmapper.datarouter.DataRouterSubscriber;
import org.onap.dcaegen2.services.pmmapper.exceptions.ProcessEventException;
import org.onap.dcaegen2.services.pmmapper.model.Event;
import org.onap.dcaegen2.services.pmmapper.model.MapperConfig;
@@ -41,7 +42,7 @@ public class DataRouterUtils {
public static String processEvent(MapperConfig config, Event event){
logger.unwrap().info("Sending processed to DataRouter");
String baseDelete = config.getDmaapDRDeleteEndpoint();
- String subscriberIdentity = config.getSubscriberIdentity();
+ String subscriberIdentity = DataRouterSubscriber.subscriberId;
String delete = String.format("%s/%s/%s", baseDelete, subscriberIdentity, event.getPublishIdentity());
try {
return new RequestSender().send("DELETE", delete);
@@ -50,4 +51,4 @@ public class DataRouterUtils {
throw new ProcessEventException("Process event failure", exception);
}
}
-}
+} \ No newline at end of file
diff --git a/src/main/java/org/onap/dcaegen2/services/pmmapper/utils/RequestSender.java b/src/main/java/org/onap/dcaegen2/services/pmmapper/utils/RequestSender.java
index 658f820..fdbae59 100644
--- a/src/main/java/org/onap/dcaegen2/services/pmmapper/utils/RequestSender.java
+++ b/src/main/java/org/onap/dcaegen2/services/pmmapper/utils/RequestSender.java
@@ -30,11 +30,15 @@ import java.nio.charset.StandardCharsets;
import java.util.UUID;
import java.util.stream.Collectors;
+import org.onap.dcaegen2.services.pmmapper.exceptions.ServerResponseException;
import org.onap.dcaegen2.services.pmmapper.model.MapperConfig;
import org.onap.logging.ref.slf4j.ONAPLogAdapter;
import org.onap.logging.ref.slf4j.ONAPLogConstants;
import org.slf4j.LoggerFactory;
+import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.SSLContext;
+
public class RequestSender {
private static final int MAX_RETRIES = 5;
private static final int RETRY_INTERVAL = 1000;
@@ -79,9 +83,16 @@ public class RequestSender {
for (int i = 1; i <= MAX_RETRIES; i++) {
final URL url = new URL(urlString);
final HttpURLConnection connection = getHttpURLConnection(method, url, invocationID, requestID);
+
+
+ if("https".equalsIgnoreCase(url.getProtocol())) {
+ HttpsURLConnection.setDefaultSSLSocketFactory(SSLContext.getDefault().getSocketFactory());
+ }
+
if(!body.isEmpty()) {
setMessageBody(connection, body);
}
+
logger.unwrap().info("Sending {} request to {}.", method, urlString);
try (InputStream is = connection.getInputStream();
@@ -90,13 +101,13 @@ public class RequestSender {
.collect(Collectors.joining("\n"));
int responseCode = connection.getResponseCode();
if (!(isWithinErrorRange(responseCode))) {
- logger.unwrap().info("Server Response Received:\n{}", result);
+ logger.unwrap().info("Response code: {}, Server Response Received:\n{}",responseCode, result);
break;
}
} catch (Exception e) {
if (retryLimitReached(i)) {
- logger.unwrap().error("Execution error: "+connection.getResponseMessage(), e);
- throw new Exception(SERVER_ERROR_MESSAGE + ": " + connection.getResponseMessage(), e);
+ logger.unwrap().error("Execution error: {}", connection.getResponseMessage(), e);
+ throw new ServerResponseException(SERVER_ERROR_MESSAGE + ": " + connection.getResponseMessage(), e);
}
}
@@ -105,7 +116,7 @@ public class RequestSender {
return result;
}
- private HttpURLConnection getHttpURLConnection(String method, URL url, UUID invocationID, UUID requestID) throws Exception {
+ private HttpURLConnection getHttpURLConnection(String method, URL url, UUID invocationID, UUID requestID) throws IOException {
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setReadTimeout(DEFAULT_READ_TIMEOUT);
connection.setRequestProperty(ONAPLogConstants.Headers.REQUEST_ID, requestID.toString());
diff --git a/src/test/java/org/onap/dcaegen2/pmmapper/config/util/RequestSenderTests.java b/src/test/java/org/onap/dcaegen2/pmmapper/config/util/RequestSenderTests.java
index 770ae43..b349b80 100644
--- a/src/test/java/org/onap/dcaegen2/pmmapper/config/util/RequestSenderTests.java
+++ b/src/test/java/org/onap/dcaegen2/pmmapper/config/util/RequestSenderTests.java
@@ -26,7 +26,6 @@ import static org.mockserver.integration.ClientAndServer.startClientAndServer;
import static org.mockserver.model.HttpRequest.request;
import static org.mockserver.model.HttpResponse.response;
-import java.io.IOException;
import java.net.URL;
import java.net.UnknownHostException;
diff --git a/src/test/java/org/onap/dcaegen2/services/pmmapper/ssl/SSLContextFactoryTest.java b/src/test/java/org/onap/dcaegen2/services/pmmapper/ssl/SSLContextFactoryTest.java
new file mode 100644
index 0000000..6f5cee9
--- /dev/null
+++ b/src/test/java/org/onap/dcaegen2/services/pmmapper/ssl/SSLContextFactoryTest.java
@@ -0,0 +1,84 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2019 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=========================================================
+ */
+
+package org.onap.dcaegen2.services.pmmapper.ssl;
+
+import com.google.gson.Gson;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import org.junit.Rule;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.junit.rules.ExpectedException;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.onap.dcaegen2.services.pmmapper.model.MapperConfig;
+
+import javax.net.ssl.*;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+import static org.junit.Assert.assertNotNull;
+
+@ExtendWith(MockitoExtension.class)
+
+public class SSLContextFactoryTest {
+
+ @Rule
+ public ExpectedException exception = ExpectedException.none();
+
+ private static String validConfigFileContents;
+ private static MapperConfig validConfig;
+ private static MapperConfig inValidConfig;
+
+
+ private static final Path validConfigPath = Paths.get("src/test/resources/valid_mapper_config.json");
+
+ private SSLContextFactory objUnderTest;
+
+ @BeforeEach
+ void setUp() throws Exception {
+ validConfigFileContents = new String(Files.readAllBytes(validConfigPath));
+ JsonObject configObject = new JsonParser().parse(validConfigFileContents).getAsJsonObject();
+ validConfig = new Gson().fromJson(configObject, MapperConfig.class);
+
+ objUnderTest = new SSLContextFactory(validConfig);
+ }
+
+ @Test
+ void testCreateSSLContext() throws IOException {
+ SSLContext sslContext = objUnderTest.createSSLContext(validConfig);
+
+ assertNotNull(sslContext);
+ }
+
+ @Test
+ void testCreateSSLContextInvalidPassword() {
+ JsonObject configObject = new JsonParser().parse(validConfigFileContents).getAsJsonObject();
+ configObject.addProperty("key_store_pass_path", "src/test/resources/nopassword");
+ inValidConfig = new Gson().fromJson(configObject, MapperConfig.class);
+
+ assertThrows(IOException.class, () -> objUnderTest.createSSLContext(inValidConfig));
+ }
+} \ No newline at end of file
diff --git a/src/test/java/org/onap/dcaegen2/services/pmmapper/utils/DataRouterUtilsTest.java b/src/test/java/org/onap/dcaegen2/services/pmmapper/utils/DataRouterUtilsTest.java
index 73967c2..9975849 100644
--- a/src/test/java/org/onap/dcaegen2/services/pmmapper/utils/DataRouterUtilsTest.java
+++ b/src/test/java/org/onap/dcaegen2/services/pmmapper/utils/DataRouterUtilsTest.java
@@ -31,25 +31,74 @@ import static org.mockito.Mockito.when;
import java.io.ByteArrayInputStream;
import java.net.HttpURLConnection;
import java.net.URL;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+import com.google.gson.Gson;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.onap.dcaegen2.services.pmmapper.datarouter.DataRouterSubscriber;
import org.onap.dcaegen2.services.pmmapper.exceptions.ProcessEventException;
import org.onap.dcaegen2.services.pmmapper.model.Event;
import org.onap.dcaegen2.services.pmmapper.model.EventMetadata;
import org.onap.dcaegen2.services.pmmapper.model.MapperConfig;
+import org.onap.dcaegen2.services.pmmapper.ssl.SSLContextFactory;
import org.powermock.api.mockito.PowerMockito;
+import org.powermock.core.classloader.annotations.PowerMockIgnore;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import org.powermock.reflect.Whitebox;
import utils.EventUtils;
+import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.SSLContext;
+@PowerMockIgnore({"org.apache.http.conn.ssl.*", "javax.net.ssl.*" , "javax.crypto.*"})
+@PrepareForTest({RequestSender.class,DataRouterSubscriber.class})
@RunWith(PowerMockRunner.class)
-@PrepareForTest(RequestSender.class)
public class DataRouterUtilsTest {
+ private static String validConfigFileContents;
+ private static MapperConfig validConfig;
+ private SSLContextFactory sslContextFactory;
+ private static final Path validConfigPath = Paths.get("src/test/resources/valid_mapper_config.json");
+
@Test
public void processEventSuccessful() throws Exception {
+ validConfigFileContents = new String(Files.readAllBytes(validConfigPath));
+ JsonObject configObject = new JsonParser().parse(validConfigFileContents).getAsJsonObject();
+ validConfig = new Gson().fromJson(configObject, MapperConfig.class);
+ sslContextFactory = new SSLContextFactory(validConfig);
+
+ SSLContext sslContext = sslContextFactory.createSSLContext(validConfig);
+ SSLContext.setDefault(sslContext);
+
+ String serviceResponse = "I'm a service response ;)";
+ String publishIdentity = "12";
+ PowerMockito.mockStatic(Thread.class);
+ MapperConfig mockMapperConfig = mock(MapperConfig.class);
+ URL mockURL = mock(URL.class);
+ HttpsURLConnection mockConnection = mock(HttpsURLConnection.class, RETURNS_DEEP_STUBS);
+ when(mockConnection.getResponseCode()).thenReturn(200);
+ when(mockConnection.getInputStream()).thenReturn(new ByteArrayInputStream(serviceResponse.getBytes()));
+
+ when(mockURL.openConnection()).thenReturn(mockConnection);
+ when(mockURL.getProtocol()).thenReturn("https");
+ when(mockMapperConfig.getDmaapDRDeleteEndpoint()).thenReturn("https://dmaap-dr-node/delete/");
+ when(mockMapperConfig.getSubscriberIdentity()).thenReturn("12");
+
+ PowerMockito.whenNew(URL.class).withAnyArguments().thenReturn(mockURL);
+
+ Event testEvent = EventUtils.makeMockEvent("", mock(EventMetadata.class), publishIdentity);
+ assertEquals(serviceResponse, DataRouterUtils.processEvent(mockMapperConfig, testEvent));
+ verify(mockConnection, times(1)).setRequestMethod(RequestSender.DELETE);
+ }
+
+ @Test
+ public void processEventSuccessfulHttp() throws Exception {
String serviceResponse = "I'm a service response ;)";
String publishIdentity = "12";
PowerMockito.mockStatic(Thread.class);
@@ -60,7 +109,8 @@ public class DataRouterUtilsTest {
when(mockConnection.getInputStream()).thenReturn(new ByteArrayInputStream(serviceResponse.getBytes()));
when(mockURL.openConnection()).thenReturn(mockConnection);
- when(mockMapperConfig.getDmaapDRDeleteEndpoint()).thenReturn("dmaap-dr-node/delete/");
+ when(mockURL.getProtocol()).thenReturn("http");
+ when(mockMapperConfig.getDmaapDRDeleteEndpoint()).thenReturn("http://dmaap-dr-node/delete/");
when(mockMapperConfig.getSubscriberIdentity()).thenReturn("12");
PowerMockito.whenNew(URL.class).withAnyArguments().thenReturn(mockURL);
@@ -72,17 +122,26 @@ public class DataRouterUtilsTest {
@Test
public void testNegativeResponse() throws Exception {
+ validConfigFileContents = new String(Files.readAllBytes(validConfigPath));
+ JsonObject configObject = new JsonParser().parse(validConfigFileContents).getAsJsonObject();
+ validConfig = new Gson().fromJson(configObject, MapperConfig.class);
+ sslContextFactory = new SSLContextFactory(validConfig);
+
+ SSLContext sslContext = sslContextFactory.createSSLContext(validConfig);
+ SSLContext.setDefault(sslContext);
+
String serviceResponse = "I'm a negative service response ;)";
String publishIdentity = "12";
PowerMockito.mockStatic(Thread.class);
MapperConfig mockMapperConfig = mock(MapperConfig.class);
URL mockURL = mock(URL.class);
- HttpURLConnection mockConnection = mock(HttpURLConnection.class, RETURNS_DEEP_STUBS);
+ HttpsURLConnection mockConnection = mock(HttpsURLConnection.class, RETURNS_DEEP_STUBS);
when(mockConnection.getResponseCode()).thenReturn(503);
when(mockConnection.getInputStream())
.thenAnswer(invocationOnMock -> new ByteArrayInputStream(serviceResponse.getBytes()));
when(mockURL.openConnection()).thenReturn(mockConnection);
+ when(mockURL.getProtocol()).thenReturn("https");
when(mockMapperConfig.getDmaapDRDeleteEndpoint()).thenReturn("dmaap-dr-node/delete/");
when(mockMapperConfig.getSubscriberIdentity()).thenReturn("12");
@@ -102,10 +161,11 @@ public class DataRouterUtilsTest {
PowerMockito.mockStatic(Thread.class);
MapperConfig mockMapperConfig = mock(MapperConfig.class);
URL mockURL = mock(URL.class);
- HttpURLConnection mockConnection = mock(HttpURLConnection.class, RETURNS_DEEP_STUBS);
+ HttpsURLConnection mockConnection = mock(HttpsURLConnection.class, RETURNS_DEEP_STUBS);
when(mockConnection.getResponseCode()).thenReturn(503);
when(mockURL.openConnection()).thenReturn(mockConnection);
+ when(mockURL.getProtocol()).thenReturn("https");
when(mockMapperConfig.getDmaapDRDeleteEndpoint()).thenReturn("dmaap-dr-node/delete/");
when(mockMapperConfig.getSubscriberIdentity()).thenReturn("12");
diff --git a/src/test/resources/password b/src/test/resources/password
new file mode 100644
index 0000000..547d6c7
--- /dev/null
+++ b/src/test/resources/password
@@ -0,0 +1 @@
+pmmapper \ No newline at end of file
diff --git a/src/test/resources/testkeystore.jks.b64 b/src/test/resources/testkeystore.jks.b64
new file mode 100644
index 0000000..f466fce
--- /dev/null
+++ b/src/test/resources/testkeystore.jks.b64
@@ -0,0 +1,35 @@
+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
diff --git a/src/test/resources/valid_mapper_config.json b/src/test/resources/valid_mapper_config.json
index 040406f..e37b77e 100644
--- a/src/test/resources/valid_mapper_config.json
+++ b/src/test/resources/valid_mapper_config.json
@@ -30,5 +30,10 @@
"dmaap_dr_feed_id": "2",
"buscontroller_feed_subscription_endpoint": "http://dmaap-bc.onap.svc.cluster.local:8080/webapi/dr_subs",
"dmaap_dr_delete_endpoint": "http://dmaap-dr-node.onap.svc.cluster.local:8443/delete",
- "services_calls": {}
+ "services_calls": {},
+ "key_store_path": "src/test/resources/testkeystore.jks.b64",
+ "key_store_pass_path": "src/test/resources/password",
+ "trust_store_path": "src/test/resources/testkeystore.jks.b64",
+ "trust_store_pass_path": "src/test/resources/password",
+ "enable_http": false
} \ No newline at end of file