summaryrefslogtreecommitdiffstats
path: root/grpc-resource/provider/src/main/java
diff options
context:
space:
mode:
authorAlexis de Talhouët <adetalhouet89@gmail.com>2019-01-18 15:14:23 -0500
committerAlexis de Talhouët <adetalhouet89@gmail.com>2019-01-29 04:00:59 +0000
commitafde732d7244f4016248cc080e63fe4e29465396 (patch)
tree02c1855eb224822deaa9c514d93abe0466796a67 /grpc-resource/provider/src/main/java
parent9d88d3f3f4791ea83f996032b64faed2a30735eb (diff)
Client for BluePrintProcessingServiceGrpc
Change-Id: I32d3bd80b9004d98c3c34f73081c156192fb4432 Issue-ID: CCSDK-947 Signed-off-by: Alexis de Talhouët <adetalhouet89@gmail.com>
Diffstat (limited to 'grpc-resource/provider/src/main/java')
-rw-r--r--grpc-resource/provider/src/main/java/org/onap/ccsdk/sli/adaptors/grpc/GrpcClient.java21
-rw-r--r--grpc-resource/provider/src/main/java/org/onap/ccsdk/sli/adaptors/grpc/GrpcProperties.java114
-rw-r--r--grpc-resource/provider/src/main/java/org/onap/ccsdk/sli/adaptors/grpc/Utils.java34
-rw-r--r--grpc-resource/provider/src/main/java/org/onap/ccsdk/sli/adaptors/grpc/cds/BlueprintProcessingClient.java76
-rw-r--r--grpc-resource/provider/src/main/java/org/onap/ccsdk/sli/adaptors/grpc/cds/BlueprintProcessingHandler.java152
5 files changed, 388 insertions, 9 deletions
diff --git a/grpc-resource/provider/src/main/java/org/onap/ccsdk/sli/adaptors/grpc/GrpcClient.java b/grpc-resource/provider/src/main/java/org/onap/ccsdk/sli/adaptors/grpc/GrpcClient.java
index c70bcec46..917882746 100644
--- a/grpc-resource/provider/src/main/java/org/onap/ccsdk/sli/adaptors/grpc/GrpcClient.java
+++ b/grpc-resource/provider/src/main/java/org/onap/ccsdk/sli/adaptors/grpc/GrpcClient.java
@@ -15,15 +15,18 @@
*/
package org.onap.ccsdk.sli.adaptors.grpc;
-public class GrpcClient {
+import java.util.Map;
+import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
+import org.onap.ccsdk.sli.core.sli.SvcLogicJavaPlugin;
+import org.onap.ccsdk.sli.core.sli.SvcLogicResource.QueryStatus;
-// ManagedChannel channel = ManagedChannelBuilder
-// .forAddress("localhost", 8080)
-// .executor(Executors.newSingleThreadExecutor())
-// .intercept()
-// .userAgent("CCSDK gRPC Client")
-// .usePlaintext()
-// //.useTransportSecurity()
-// .build();
+public interface GrpcClient extends SvcLogicJavaPlugin {
+ /**
+ * Send a request to process to a gRPC server.
+ *
+ * @param parameters HashMap<String,String> of parameters passed by the DG to this function.
+ * Required parameters are defined in implemention.
+ */
+ QueryStatus sendRequest(Map<String, String> parameters, SvcLogicContext ctx);
}
diff --git a/grpc-resource/provider/src/main/java/org/onap/ccsdk/sli/adaptors/grpc/GrpcProperties.java b/grpc-resource/provider/src/main/java/org/onap/ccsdk/sli/adaptors/grpc/GrpcProperties.java
new file mode 100644
index 000000000..fef1a5963
--- /dev/null
+++ b/grpc-resource/provider/src/main/java/org/onap/ccsdk/sli/adaptors/grpc/GrpcProperties.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2018 Bell Canada.
+ *
+ * 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.
+ */
+package org.onap.ccsdk.sli.adaptors.grpc;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.util.HashSet;
+import java.util.Optional;
+import java.util.Properties;
+import java.util.Set;
+import org.onap.ccsdk.sli.core.utils.JREFileResolver;
+import org.onap.ccsdk.sli.core.utils.KarafRootFileResolver;
+import org.onap.ccsdk.sli.core.utils.PropertiesFileResolver;
+import org.onap.ccsdk.sli.core.utils.common.BundleContextFileResolver;
+import org.onap.ccsdk.sli.core.utils.common.SdncConfigEnvVarFileResolver;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Responsible for determining the properties file to use.
+ *
+ * <ol>
+ * <li>A directory identified by the system environment variable <code>SDNC_CONFIG_DIR</code></li>
+ * <li>A directory identified by the JRE argument <code>grpc.properties</code></li>
+ * <li>A <code>grpc.properties</code> file located in the karaf root directory</li>
+ * </ol>
+ *
+ * Partial copy and adaptation of org.onap.ccsdk.sli.adaptors.aai.AAIServiceProvider
+ */
+public class GrpcProperties {
+
+ private static final Logger LOG = LoggerFactory.getLogger(GrpcProperties.class);
+
+ private static final String GRPC_PROPERTY_FILE_NAME = "grpc.properties";
+ private static final String MISSING_PROPERTY_FILE =
+ "Missing configuration properties resource for GRPC: " + GRPC_PROPERTY_FILE_NAME;
+ private static final String BLUEPRINT_PROCESSOR_URL_PROP = "org.onap.ccsdk.sli.adaptors.grpc.blueprint.processor.url";
+ private static final String BLUEPRINT_PROCESSOR_PORT_PROP = "org.onap.ccsdk.sli.adaptors.grpc.blueprint.processor.port";
+
+ private Set<PropertiesFileResolver> fileResolvers = new HashSet<>();
+ private Properties properties;
+
+ public GrpcProperties() {
+ fileResolvers.add(new SdncConfigEnvVarFileResolver("Using property file (1) from environment variable"));
+ fileResolvers.add(new BundleContextFileResolver("Using property file (2) from BundleContext property",
+ GrpcProperties.class));
+ fileResolvers.add(new JREFileResolver("Using property file (3) from JRE argument", GrpcProperties.class));
+ fileResolvers.add(new KarafRootFileResolver("Using property file (4) from karaf root", this));
+
+ loadProps();
+ }
+
+ public String getUrl() {
+ checkArgument(properties != null);
+ return properties.getProperty(BLUEPRINT_PROCESSOR_URL_PROP);
+ }
+
+ public int getPort() {
+ checkArgument(properties != null);
+ return Integer.parseInt(properties.getProperty(BLUEPRINT_PROCESSOR_PORT_PROP));
+ }
+
+ private void checkArgument(final boolean argument) {
+ if (!argument) {
+ LOG.info("Propety file {} was missing, trying to reload it", GRPC_PROPERTY_FILE_NAME);
+ loadProps();
+ if (properties == null) {
+ throw new IllegalArgumentException(MISSING_PROPERTY_FILE);
+ }
+ }
+ }
+
+ private void loadProps() {
+ // determines properties file as according to the priority described in the class header comment
+ final File propertiesFile = determinePropertiesFile();
+ if (propertiesFile != null) {
+ try (FileInputStream fileInputStream = new FileInputStream(propertiesFile)) {
+ properties = new Properties();
+ properties.load(fileInputStream);
+ } catch (final IOException e) {
+ String errorMsg = "Failed to load properties for file: " + propertiesFile.toString();
+ LOG.error(errorMsg, errorMsg);
+ }
+ }
+ }
+
+ private File determinePropertiesFile() {
+ for (final PropertiesFileResolver resolver : fileResolvers) {
+ final Optional<File> fileOptional = resolver.resolveFile(GRPC_PROPERTY_FILE_NAME);
+ if (fileOptional.isPresent()) {
+ final File file = fileOptional.get();
+ LOG.info("{} {}", resolver.getSuccessfulResolutionMessage(), file.getPath());
+ return file;
+ }
+ }
+
+ LOG.error(MISSING_PROPERTY_FILE);
+ return null;
+ }
+}
diff --git a/grpc-resource/provider/src/main/java/org/onap/ccsdk/sli/adaptors/grpc/Utils.java b/grpc-resource/provider/src/main/java/org/onap/ccsdk/sli/adaptors/grpc/Utils.java
new file mode 100644
index 000000000..831f09eaa
--- /dev/null
+++ b/grpc-resource/provider/src/main/java/org/onap/ccsdk/sli/adaptors/grpc/Utils.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2019 Bell Canada.
+ *
+ * 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.
+ */
+package org.onap.ccsdk.sli.adaptors.grpc;
+
+import java.time.LocalDateTime;
+import java.time.ZoneId;
+import java.time.format.DateTimeFormatter;
+
+public final class Utils {
+
+ private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
+
+ private Utils() {
+ throw new AssertionError("Utility class");
+ }
+
+ public static String timestamp() {
+ LocalDateTime now = LocalDateTime.now(ZoneId.systemDefault());
+ return formatter.format(now);
+ }
+}
diff --git a/grpc-resource/provider/src/main/java/org/onap/ccsdk/sli/adaptors/grpc/cds/BlueprintProcessingClient.java b/grpc-resource/provider/src/main/java/org/onap/ccsdk/sli/adaptors/grpc/cds/BlueprintProcessingClient.java
new file mode 100644
index 000000000..33fb8fa2f
--- /dev/null
+++ b/grpc-resource/provider/src/main/java/org/onap/ccsdk/sli/adaptors/grpc/cds/BlueprintProcessingClient.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2019 Bell Canada.
+ *
+ * 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.
+ */
+package org.onap.ccsdk.sli.adaptors.grpc.cds;
+
+import io.grpc.ManagedChannel;
+import io.grpc.internal.DnsNameResolverProvider;
+import io.grpc.netty.NettyChannelBuilder;
+import java.util.Map;
+import org.onap.ccsdk.sli.adaptors.grpc.GrpcClient;
+import org.onap.ccsdk.sli.adaptors.grpc.GrpcProperties;
+import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
+import org.onap.ccsdk.sli.core.sli.SvcLogicResource.QueryStatus;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class BlueprintProcessingClient implements GrpcClient {
+
+ private static final Logger log = LoggerFactory.getLogger(BlueprintProcessingClient.class);
+
+ private ManagedChannel channel;
+ private BlueprintProcessingHandler handler;
+
+ public BlueprintProcessingClient(BlueprintProcessingHandler handler, GrpcProperties props) {
+ this.channel = NettyChannelBuilder
+ .forAddress(props.getUrl(), props.getPort())
+ .usePlaintext()
+ .nameResolverFactory(new DnsNameResolverProvider())
+ .build();
+ this.handler = handler;
+ }
+
+ // Used by blueprint
+ public void start() {
+ log.info("BlueprintProcessingClient started");
+ }
+
+ // Used by blueprint
+ public void stop() {
+ if (channel != null) {
+ channel.shutdown();
+ }
+ log.info("BlueprintProcessingClient stopped");
+ }
+
+ /*
+ * @param parameters HashMap<String,String> of parameters passed by the DG to this function.
+ * <table border="1">
+ * <thead><th>parameter</th><th>Mandatory/Optional</th><th>description</th></thead>
+ * <tbody>
+ * <tr><td>is_force</td><td>Optional</td><td>Whether to force or not the request.</td></tr>
+ * <tr><td>ttl</td><td>Optional</td><td>Duration of the request.</td></tr>
+ * <tr><td>blueprint_name</td><td>Mandatory</td><td>Name of the blueprint to process.</td></tr>
+ * <tr><td>blueprint_version</td><td>Mandatory</td><td>Version of the blueprint to process.</td></tr>
+ * <tr><td>action</td><td>Mandatory</td><td>Action of the blueprint to process.</td></tr>
+ * <tr><td>mode</td><td>Mandatory</td><td>Mode to operate the transaction.</td></tr>
+ * </tbody>
+ * </table>
+ */
+ @Override
+ public QueryStatus sendRequest(Map<String, String> parameters, SvcLogicContext ctx) {
+ return handler.process(parameters, channel);
+ }
+} \ No newline at end of file
diff --git a/grpc-resource/provider/src/main/java/org/onap/ccsdk/sli/adaptors/grpc/cds/BlueprintProcessingHandler.java b/grpc-resource/provider/src/main/java/org/onap/ccsdk/sli/adaptors/grpc/cds/BlueprintProcessingHandler.java
new file mode 100644
index 000000000..6a618fb32
--- /dev/null
+++ b/grpc-resource/provider/src/main/java/org/onap/ccsdk/sli/adaptors/grpc/cds/BlueprintProcessingHandler.java
@@ -0,0 +1,152 @@
+/*
+ * Copyright (C) 2019 Bell Canada.
+ *
+ * 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.
+ */
+package org.onap.ccsdk.sli.adaptors.grpc.cds;
+
+import com.google.protobuf.InvalidProtocolBufferException;
+import com.google.protobuf.Struct;
+import io.grpc.ManagedChannel;
+import io.grpc.Status;
+import io.grpc.stub.StreamObserver;
+import java.util.Map;
+import java.util.UUID;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicReference;
+import org.onap.ccsdk.apps.controllerblueprints.common.api.ActionIdentifiers;
+import org.onap.ccsdk.apps.controllerblueprints.common.api.CommonHeader;
+import org.onap.ccsdk.apps.controllerblueprints.common.api.Flag;
+import org.onap.ccsdk.apps.controllerblueprints.processing.api.BluePrintProcessingServiceGrpc;
+import org.onap.ccsdk.apps.controllerblueprints.processing.api.BluePrintProcessingServiceGrpc.BluePrintProcessingServiceStub;
+import org.onap.ccsdk.apps.controllerblueprints.processing.api.ExecutionServiceInput;
+import org.onap.ccsdk.apps.controllerblueprints.processing.api.ExecutionServiceOutput;
+import org.onap.ccsdk.sli.adaptors.grpc.Utils;
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+import org.onap.ccsdk.sli.core.sli.SvcLogicResource.QueryStatus;
+import org.onap.ccsdk.sli.core.slipluginutils.SliPluginUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class BlueprintProcessingHandler {
+
+ private static final Logger log = LoggerFactory.getLogger(BlueprintProcessingHandler.class);
+
+ private static final String CCSDK_ORIGINATOR = "CCSDK";
+ private static final String IS_FORCE_PROP = "is_force";
+ private static final String TTL_PROP = "ttl";
+ private static final String BLUEPRINT_NAME_PROP = "blueprint_name";
+ private static final String BLUEPRINT_VERSION_PROP = "blueprint_version";
+ private static final String ACTION_PROP = "action";
+ private static final String MODE_PROP = "mode";
+ private static final String PAYLOAD_PROP = "payload";
+
+ QueryStatus process(final Map<String, String> parameters, final ManagedChannel channel) {
+ try {
+ SliPluginUtils.checkParameters(parameters,
+ new String[]{BLUEPRINT_NAME_PROP, BLUEPRINT_VERSION_PROP, ACTION_PROP, MODE_PROP}, log);
+ } catch (SvcLogicException e) {
+ return QueryStatus.FAILURE;
+ }
+
+ final boolean isForce = Boolean.getBoolean(parameters.get(IS_FORCE_PROP));
+ final int ttl = Integer.parseInt(parameters.get(TTL_PROP));
+ final String blueprintName = parameters.get(BLUEPRINT_NAME_PROP);
+ final String blueprintVersion = parameters.get(BLUEPRINT_VERSION_PROP);
+ final String action = parameters.get(ACTION_PROP);
+ final String mode = parameters.get(MODE_PROP);
+ final String payload = parameters.get(PAYLOAD_PROP);
+
+ log.info("Processing blueprint({}:{}) for action({})", blueprintVersion, blueprintName, action);
+
+ final AtomicReference<QueryStatus> responseStatus = new AtomicReference<>();
+ final CountDownLatch finishLatch = new CountDownLatch(1);
+
+ final BluePrintProcessingServiceStub asyncStub = BluePrintProcessingServiceGrpc.newStub(channel);
+
+ final StreamObserver<ExecutionServiceOutput> responseObserver = new StreamObserver<ExecutionServiceOutput>() {
+ @Override
+ public void onNext(ExecutionServiceOutput output) {
+ log.info("onNext: {}", output);
+ }
+
+ @Override
+ public void onError(Throwable t) {
+ Status status = Status.fromThrowable(t);
+ log.error("Failed processing blueprint({}:{}) for action({}). {}", blueprintVersion, blueprintName,
+ action, status);
+ responseStatus.compareAndSet(null, QueryStatus.FAILURE);
+ finishLatch.countDown();
+ }
+
+ @Override
+ public void onCompleted() {
+ log.info("Completed blueprint({}:{}) for action({})", blueprintVersion, blueprintName, action);
+ responseStatus.compareAndSet(null, QueryStatus.SUCCESS);
+ finishLatch.countDown();
+ }
+ };
+
+ final CommonHeader commonHeader = CommonHeader.newBuilder()
+ .setOriginatorId(CCSDK_ORIGINATOR)
+ .setRequestId(UUID.randomUUID().toString())
+ .setTimestamp(Utils.timestamp())
+ .setFlag(Flag.newBuilder()
+ .setIsForce(isForce)
+ .setTtl(ttl)
+ .build())
+ .build();
+ final ActionIdentifiers actionIdentifiers = ActionIdentifiers.newBuilder()
+ .setActionName(action)
+ .setBlueprintName(blueprintName)
+ .setBlueprintVersion(blueprintVersion)
+ .setMode(mode)
+ .build();
+
+ Struct struct;
+ try {
+ struct = Struct.newBuilder().mergeFrom(payload.getBytes()).build();
+ } catch (InvalidProtocolBufferException e) {
+ log.error("Failed converting payload for blueprint({}:{}) for action({}). {}", blueprintVersion,
+ blueprintName, action, e);
+ return QueryStatus.FAILURE;
+ }
+
+ final ExecutionServiceInput request = ExecutionServiceInput.newBuilder()
+ .setActionIdentifiers(actionIdentifiers)
+ .setPayload(struct)
+ .setCommonHeader(commonHeader).build();
+
+ final StreamObserver<ExecutionServiceInput> requestObserver = asyncStub.process(responseObserver);
+
+ try {
+ requestObserver.onNext(request);
+ } catch (RuntimeException e) {
+ requestObserver.onError(e);
+ return QueryStatus.FAILURE;
+ }
+
+ requestObserver.onCompleted();
+ try {
+ finishLatch.await(1, TimeUnit.MINUTES);
+ } catch (InterruptedException e) {
+ log.error("Failed processing blueprint({}:{}) for action({}). {}", blueprintVersion, blueprintName, action,
+ e);
+ Thread.currentThread().interrupt();
+ return QueryStatus.FAILURE;
+ }
+
+ return responseStatus.get();
+ }
+} \ No newline at end of file