2 * Copyright (c) 2016 Cisco and/or its affiliates.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at:
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
18 * Modifications copyright (c) 2018 AT&T Intellectual Property
21 package org.onap.vnf.health.read;
23 import org.onap.vnf.health.CrudService;
24 import org.onap.vnf.health.RESTManager;
25 import org.onap.vnf.health.RESTManager.Pair;
27 import io.fd.honeycomb.translate.read.ReadContext;
28 import io.fd.honeycomb.translate.read.ReadFailedException;
29 import io.fd.honeycomb.translate.spi.read.Initialized;
30 import io.fd.honeycomb.translate.spi.read.InitializingReaderCustomizer;
32 import java.io.BufferedReader;
33 import java.io.FileInputStream;
34 import java.io.FileReader;
35 import java.io.IOException;
36 import java.io.InputStream;
37 import java.text.SimpleDateFormat;
38 import java.util.ArrayList;
39 import java.util.Date;
40 import java.util.HashMap;
41 import java.util.List;
43 import java.util.Properties;
45 import javax.annotation.Nonnull;
47 import org.onap.vnf.health.CrudService;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.health.vnf.onap.plugin.rev160918.HealthVnfOnapPluginStateBuilder;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.health.vnf.onap.plugin.rev160918.health.vnf.onap.plugin.params.HealthCheckBuilder;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.health.vnf.onap.plugin.rev160918.health.vnf.onap.plugin.params.health.check.FaultsBuilder;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.health.vnf.onap.plugin.rev160918.health.vnf.onap.plugin.params.health.check.faults.Fault;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.health.vnf.onap.plugin.rev160918.health.vnf.onap.plugin.params.health.check.faults.FaultBuilder;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.health.vnf.onap.plugin.rev160918.health.vnf.onap.plugin.params.health.check.faults.FaultKey;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.health.vnf.onap.plugin.rev160918.health.vnf.onap.plugin.params.HealthCheck;
55 import org.opendaylight.yangtools.concepts.Builder;
56 import org.opendaylight.yangtools.yang.binding.DataObject;
57 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
59 import org.slf4j.Logger;
60 import org.slf4j.LoggerFactory;
64 * Reader for {@link Element} list node from our YANG model.
66 public final class ElementStateCustomizer implements InitializingReaderCustomizer<HealthCheck, HealthCheckBuilder> {
68 private final CrudService<HealthCheck> crudService;
69 private static final Logger LOG = LoggerFactory.getLogger(ElementStateCustomizer.class);
70 private final String SCRIPT;
71 private final String OUTPUT;
72 private final String VNFC;
73 private final Boolean PRIMARY;
74 private static SimpleDateFormat SDF;
76 public ElementStateCustomizer(final CrudService<HealthCheck> crudService) throws IOException {
77 this.crudService = crudService;
79 // initialize data format
80 SDF = new SimpleDateFormat("MM-dd-yyyy:HH.mm.ss");
82 // read properties from file
83 String path = "/opt/config/properties.conf";
84 Properties prop = new Properties();
85 InputStream prop_file = new FileInputStream(path);
87 SCRIPT = prop.getProperty("script");
88 OUTPUT = prop.getProperty("output");
89 VNFC = prop.getProperty("vnfc");
90 PRIMARY = Boolean.parseBoolean(prop.getProperty("primary"));
95 public void merge(@Nonnull final Builder<? extends DataObject> builder, @Nonnull final HealthCheck readData) {
96 // merge children data to parent builder
97 // used by infrastructure to merge data loaded in separated customizers
98 ((HealthVnfOnapPluginStateBuilder) builder).setHealthCheck(readData);
103 public HealthCheckBuilder getBuilder(@Nonnull final InstanceIdentifier<HealthCheck> id) {
104 // return new builder for this data node
105 return new HealthCheckBuilder();
109 public void readCurrentAttributes(@Nonnull final InstanceIdentifier<HealthCheck> id,
110 @Nonnull final HealthCheckBuilder builder,
111 @Nonnull final ReadContext ctx) throws ReadFailedException {
113 List<String> ipAddr = new ArrayList<String>();
115 String ret = readFromFile("/opt/config/oam_vpktgen_ip.txt");
119 ret = readFromFile("/opt/config/oam_vdns_ip.txt");
125 // assess the health status of the local service (try at most three times, otherwise return an error).
127 String [] cmdArgs = {"/bin/bash", "-c", SCRIPT};
133 Process child = Runtime.getRuntime().exec(cmdArgs);
134 // wait for child process to terminate
135 ret = child.waitFor();
138 catch (IOException e) {
139 LOG.error("Command: [" + SCRIPT + "] returned an error.");
142 catch (InterruptedException e) {
143 LOG.error("Child process: [" + SCRIPT + "] returned an error. Error code: " + ret);
146 } while(ret != 0 && attempts < 3);
149 healthStatus = readFromFile(OUTPUT);
150 if(healthStatus == null) {
151 healthStatus = "unhealthy";
153 LOG.info("Assessing the health status of the local component... Return status = \"" + healthStatus + "\"");
156 healthStatus = "unhealthy";
157 LOG.info("Failed to assess the health status of the local component. Return status = \"unhealthy\"");
160 // perform read of details of data specified by key of Element in id
161 // final HealthCheck data = crudService.readSpecific(id);
163 // check the status of other VNF components, if any
165 for(int i = 0; i < ipAddr.size(); i++) {
166 if(!getRemoteVnfcHealthStatus(ipAddr.get(i))) {
167 healthStatus = "unhealthy";
172 // and sets it to builder
173 builder.setState(healthStatus);
174 builder.setVnfName(VNFC);
175 builder.setTime(SDF.format(new Date().getTime()));
177 if(healthStatus.equals("unhealthy")) {
178 List<Fault> faultList = new ArrayList<Fault>();
179 // build a FaultBuilder object in case of one or more VNF components are reporting faults
180 FaultBuilder faultBuilder = new FaultBuilder();
181 faultBuilder.setVnfComponent(VNFC);
182 faultBuilder.setMessage("The VNF is not running correctly");
183 faultBuilder.setKey(new FaultKey(faultBuilder.getVnfComponent()));
184 faultList.add(faultBuilder.build());
186 // build a FaultsBuilder object that contains a list of Fault instances
187 FaultsBuilder faultsBuilder = new FaultsBuilder();
188 faultsBuilder.setInfo("One or more VNF components are unreachable");
189 faultsBuilder.setFault(faultList);
191 // add the Faults object to HealthCheckBuilder
192 builder.setFaults(faultsBuilder.build());
195 // create the final HealthCheck object
200 * Initialize configuration data based on operational data.
202 * Very useful when a plugin is initiated but the underlying layer already contains some operation state.
203 * Deriving the configuration from existing operational state enables reconciliation in case when
204 * Honeycomb's persistence is not available to do the work for us.
208 public Initialized<? extends DataObject> init(@Nonnull final InstanceIdentifier<HealthCheck> id,
209 @Nonnull final HealthCheck readValue,
210 @Nonnull final ReadContext ctx) {
211 return Initialized.create(id, readValue);
214 private String readFromFile(String path) {
215 // auto close the file reader
216 try (BufferedReader br = new BufferedReader(new FileReader(path))) {
218 while ((line = br.readLine()) != null) {
221 } catch (IOException e) {
227 private boolean getRemoteVnfcHealthStatus(String ipAddr) {
228 // set up the REST manager
229 RESTManager mgr = new RESTManager();
230 Map<String, String> headers = new HashMap<String, String>();
231 headers.put("Content-Type", "application/json");
232 headers.put("Accept", "application/json");
234 // execute the request
235 String URI = "http://" + ipAddr + ":8183/restconf/operational/health-vnf-onap-plugin:health-vnf-onap-plugin-state/health-check";
236 Pair<Integer, String> result = mgr.get(URI, "admin", "admin", headers);
238 return (!result.b.contains("unhealthy"));