Commit 6 for Define OPtimizer API mS 85/83585/1
authorJerry Flood <jflood@att.com>
Thu, 28 Mar 2019 09:53:39 +0000 (05:53 -0400)
committerJerry Flood <jflood@att.com>
Thu, 28 Mar 2019 10:01:19 +0000 (06:01 -0400)
Multiple commits required due to commit size limitation.

Change-Id: I55747dccb6bb63dcd838ae7fe30d686832516e83
Issue-ID: OPTFRA-437
Signed-off-by: Jerry Flood <jflood@att.com>
cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/clients/topology/models/TopologyResponse.java [new file with mode: 0644]
cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/common/Availability.java [new file with mode: 0644]
cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/common/LogMessages.java [new file with mode: 0644]
cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/core/OptimizerManager.java [new file with mode: 0644]
cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/filters/CmsoClientFilters.java [new file with mode: 0644]
cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/filters/CmsoContainerFilters.java [new file with mode: 0644]
cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/model/Optimizer.java [new file with mode: 0644]
cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/model/Request.java [new file with mode: 0644]

diff --git a/cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/clients/topology/models/TopologyResponse.java b/cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/clients/topology/models/TopologyResponse.java
new file mode 100644 (file)
index 0000000..2b4a726
--- /dev/null
@@ -0,0 +1,130 @@
+/*
+ * Copyright © 2017-2018 AT&T Intellectual Property. Modifications Copyright © 2018 IBM.
+ *
+ * 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.
+ *
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed under the Creative
+ * Commons License, Attribution 4.0 Intl. (the "License"); you may not use this documentation except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation 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.optf.cmso.optimizer.clients.topology.models;
+
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+@ApiModel(value = "Topology Response", description = "Response to topology query for the requested elements.")
+public class TopologyResponse implements Serializable {
+    private static final long serialVersionUID = 1L;
+    private static EELFLogger log = EELFManager.getInstance().getLogger(TopologyResponse.class);
+
+    public enum TopologyRequestStatus {
+        IN_PROGRESS, COMPLETED, FAILED,
+    }
+
+    @ApiModelProperty(value = "Unique Id of the request")
+    private String requestId;
+
+    @ApiModelProperty(value = "List of elements for for which topology has been requested.")
+    private List<TopologyElementInfo> elements = new ArrayList<>();
+
+    @ApiModelProperty(value = "List of referenced elements representing the topology that has been requested.")
+    private List<ReferencedElementInfo> referencedElements = new ArrayList<>();
+
+    @ApiModelProperty(value = "Status of asynchronous request. COMPLETED is returned on initial synchonous request. "
+                    + "If IN_PROGRESS is returned, the optimizer will enter asynchronous polling mode.")
+    private TopologyRequestStatus status;
+
+    @ApiModelProperty(value = "If request is asynchronous (IN_PROGRESS), suggested interval to the next poll.")
+    private Integer pollingSeconds;
+
+    private String errorMessage;
+
+    public TopologyRequestStatus getStatus() {
+        return status;
+    }
+
+    public void setStatus(TopologyRequestStatus status) {
+        this.status = status;
+    }
+
+    public Integer getPollingSeconds() {
+        return pollingSeconds;
+    }
+
+    public void setPollingSeconds(Integer pollingSeconds) {
+        this.pollingSeconds = pollingSeconds;
+    }
+
+    public String getRequestId() {
+        return requestId;
+    }
+
+    public void setRequestId(String requestId) {
+        this.requestId = requestId;
+    }
+
+    public List<TopologyElementInfo> getElements() {
+        return elements;
+    }
+
+    public void setElements(List<TopologyElementInfo> elements) {
+        this.elements = elements;
+    }
+
+    public List<ReferencedElementInfo> getReferencedElements() {
+        return referencedElements;
+    }
+
+    public void setReferencedElements(List<ReferencedElementInfo> referencedElements) {
+        this.referencedElements = referencedElements;
+    }
+
+    public String getErrorMessage() {
+        return errorMessage;
+    }
+
+    public void setErrorMessage(String errorMessage) {
+        this.errorMessage = errorMessage;
+    }
+
+    /**
+     * To string.
+     *
+     * @return the string
+     */
+    @Override
+    public String toString() {
+        ObjectMapper mapper = new ObjectMapper();
+        try {
+            return mapper.writeValueAsString(this);
+        } catch (JsonProcessingException e) {
+            log.debug("Error in toString()", e);
+        }
+        return "";
+    }
+
+}
diff --git a/cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/common/Availability.java b/cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/common/Availability.java
new file mode 100644 (file)
index 0000000..81cebaf
--- /dev/null
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ *
+ * Copyright © 2019 AT&T Intellectual Property.
+ *
+ * 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.
+ *
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed under the Creative
+ * Commons License, Attribution 4.0 Intl. (the "License"); you may not use this documentation except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation 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.optf.cmso.optimizer.common;
+
+public enum Availability {
+    full, partial, unavailable
+}
diff --git a/cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/common/LogMessages.java b/cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/common/LogMessages.java
new file mode 100644 (file)
index 0000000..ce1c389
--- /dev/null
@@ -0,0 +1,223 @@
+/*******************************************************************************
+ *
+ * Copyright © 2019 AT&T Intellectual Property.
+ *
+ * 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.
+ *
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed under the Creative
+ * Commons License, Attribution 4.0 Intl. (the "License"); you may not use this documentation except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation 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.optf.cmso.optimizer.common;
+
+import com.att.eelf.configuration.EELFManager;
+import com.att.eelf.i18n.EELFResourceManager;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import javax.ws.rs.core.Response.Status;
+import org.apache.log4j.Level;
+import org.onap.observations.ObservationInterface;
+
+public enum LogMessages implements ObservationInterface {
+
+    OPTIMIZE_SCHEDULE("Optimize schedule {0} : {1}: {2} : {3}", Status.OK, Level.INFO),
+    GET_POLICIES("Get active tickets {0} : {1}: {2} : {3}", Status.OK, Level.INFO),
+    GET_SCHEDULE("Get optimized schedule {0} : {1}: {2} : {3}", Status.OK, Level.INFO),
+    DELETE_SCHEDULE("Delete optimized schedule {0} : {1}: {2} : {3}", Status.OK, Level.INFO),
+
+    INVALID_ATTRIBUTE("Invalid attribute {0}={1}", Status.BAD_REQUEST, Level.INFO),
+    MISSING_REQUIRED_ATTRIBUTE("Missing required attribute '{0}'", Status.BAD_REQUEST, Level.INFO),
+    INVALID_REQUEST("The input data structure is incorrect", Status.BAD_REQUEST, Level.INFO),
+    REQUEST_TIMED_OUT("Request timed out.", Status.INTERNAL_SERVER_ERROR, Level.ERROR),
+    UNEXPECTED_EXCEPTION("Unexpected exception encountered during processing. Please contact support : {0}",
+                    Status.INTERNAL_SERVER_ERROR, Level.ERROR),
+
+    UNDEFINED_FILTER_ATTRIBUTE("Undefined filter attribute {0}", Status.BAD_REQUEST, Level.INFO),
+    INVALID_DATE_FILTER("Invalid date filter provided {0}=(1}", Status.BAD_REQUEST, Level.INFO),
+
+    INCOMING_MESSAGE("Incoming message method={0} path={1}", Status.OK, Level.INFO, true, false),
+    INCOMING_MESSAGE_RESPONSE("Message response method={0} path={1} status={2}", Status.OK, Level.INFO, true, false),
+    OUTGOING_MESSAGE("Outgoing message method={0} path={1}", Status.OK, Level.INFO, true, false),
+    OUTGOING_MESSAGE_RETURNED("Outgoing message returned method={0} path={1} status={2}", Status.OK, Level.INFO, true,
+                    false),
+
+    UNEXPECTED_RESPONSE("Unexpected response from URL {0} : HTTP Status={1}", Status.INTERNAL_SERVER_ERROR , Level.ERROR),
+    INVALID_CHANGE_WINDOW("Change window end time {0} must be after start time {1}", Status.OK, Level.INFO),
+    EXPECTED_EXCEPTION("Expected exception encountered during processing. {0}", Status.OK, Level.INFO),
+    UNABLE_TO_UPDATE_TICKET("Unable to update change ticket in TM: Schedule ID: {0} : changeid: {1} :  Reason: {2}",
+                    Status.OK, Level.INFO),
+    UNAUTHORIZED("Authorization failed.", Status.FORBIDDEN, Level.INFO),
+    UNAUTHENTICATED("Authentication failed.", Status.UNAUTHORIZED, Level.INFO),
+    EXPECTED_DATA_NOT_FOUND("Retrieve of {0} from {1} failed. Not found.", Status.INTERNAL_SERVER_ERROR, Level.ERROR),
+    DUPLICATE_REQUEST_ID("Request id {0} already exists", Status.BAD_REQUEST, Level.INFO),
+    TOPOLOGY_REQUEST("Topology request {0} for {1} URL: {1}", Status.OK, Level.INFO),
+    OPTIMIZER_REQUEST("OPtimizer request {0} for {1} Command: {1}", Status.OK, Level.INFO),
+    TICKETS_REQUEST("Tickets request {0} for {1} URL: {1}", Status.OK, Level.INFO),
+
+    ;
+    private final String defaultId;
+    private final String defaultMessage;
+    private final String defaultResolution;
+    private final String defaultAction;
+
+    private final Status status;
+    private final Level level;
+    private final Boolean audit;
+    private final Boolean metric;
+
+
+    private LogMessages(String message, Status code, Level lev) {
+        defaultMessage         = message;
+        level                  = lev;
+        status                 = code;
+        this.defaultId         = this.name();
+        this.defaultResolution = "No resolution needed";
+        this.defaultAction     = "No action is required";
+        this.audit             = false;
+        this.metric            = false;
+    }
+
+    private LogMessages(String message, Status code, Level lev, Boolean audit, Boolean metric) {
+        defaultMessage         = message;
+        level                  = lev;
+        status                 = code;
+        this.audit             = audit;
+        this.metric            = metric;
+        this.defaultId         = this.name();
+        this.defaultResolution = "No resolution needed";
+        this.defaultAction     = "No action is required";
+    }
+
+    private LogMessages(String message, Status code, Level lev, String id, String resolution, String action) {
+        level                  = lev;
+        status                 = code;
+        defaultMessage         = message;
+        this.defaultId         = id;
+        this.defaultResolution = resolution;
+        this.defaultAction     = action;
+        this.audit             = false;
+        this.metric            = false;
+    }
+
+    static {
+        EELFResourceManager.loadMessageBundle("logmessages");
+    }
+
+    /**
+     * Gen properties.
+     *
+     * @return the string
+     */
+    public String genProperties() {
+        // Use this to regenerate properties file. The desire to change messages without updating code is
+        // well understood, but the developer should be able to code the defaults without having to update 2
+        // different files and
+        // get it wrong.
+        StringBuilder sb = new StringBuilder();
+        sb.append("# Generated from ").append(this.getClass().getName()).append("\n");
+        for (LogMessages lm : values()) {
+            sb.append(lm.name());
+            sb.append(" ").append(lm.defaultId);
+            sb.append("|").append(lm.defaultMessage);
+            sb.append("|").append(lm.defaultResolution);
+            sb.append("|").append(lm.defaultAction);
+            sb.append("\n");
+        }
+        return sb.toString();
+    }
+
+
+    // interface methods
+    @Override
+    public Level getLevel() {
+        return level;
+    }
+
+    @Override
+    public String getMessage() {
+        return defaultMessage;
+    }
+
+    @Override
+    public Status getStatus() {
+        return status;
+    }
+
+    @Override
+    public Enum<?> getValue() {
+        return this;
+    }
+
+    @Override
+    public String getDomain() {
+        return this.getClass().getSimpleName();
+    }
+
+    @Override
+    public Boolean getAudit() {
+        return audit;
+    }
+
+    @Override
+    public Boolean getMetric() {
+        return metric;
+    }
+
+    /**
+     * The main method.
+     *
+     * @param argv the arguments
+     */
+    public static void main(String[] argv) {
+        System.out.println(LogMessages.UNEXPECTED_EXCEPTION.genProperties());
+        try {
+            Files.write(Paths.get("src/main/resources/logmessages.properties"),
+                            LogMessages.UNEXPECTED_EXCEPTION.genProperties().getBytes());
+        } catch (IOException e) {
+            EELFManager.getInstance().getDebugLogger().debug("Failed to update properties file.", e);
+
+        }
+        StringBuilder sb = new StringBuilder();
+        sb.append("<html><body><h1>Cell Site Selection Scheduler mS Observations</h1>\n<table border=\"1\">\n<tr>");
+        sb.append("<td>Code</td> ");
+        sb.append("<td>Log Level</td> ");
+        sb.append("<td>Message</td> ");
+        sb.append("</tr>\n");
+        for (LogMessages m : LogMessages.values()) {
+            if (m.level == Level.ERROR || m.level == Level.WARN || m.level == Level.FATAL) {
+                sb.append("<tr>");
+                sb.append("<td>").append(m.name()).append("</td> ");
+                sb.append("<td>").append(m.level).append("</td> ");
+                sb.append("<td>").append(m.defaultMessage).append("</td> ");
+                sb.append("</tr>\n");
+            }
+        }
+        try {
+            Files.write(Paths.get("logmessages.html"), sb.toString().getBytes());
+        } catch (IOException e) {
+            EELFManager.getInstance().getDebugLogger().debug("Failed to update properties html file.", e);
+
+        }
+
+    }
+
+}
diff --git a/cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/core/OptimizerManager.java b/cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/core/OptimizerManager.java
new file mode 100644 (file)
index 0000000..5289dae
--- /dev/null
@@ -0,0 +1,173 @@
+/*
+ * ============LICENSE_START==============================================
+ * Copyright (c) 2019 AT&T Intellectual Property.
+ * =======================================================================
+ * 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.
+ * ============LICENSE_END=================================================
+ *
+ */
+
+package org.onap.optf.cmso.optimizer.core;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import java.util.List;
+import java.util.Optional;
+import java.util.UUID;
+import javax.ws.rs.core.Response.Status;
+import org.onap.optf.cmso.common.exceptions.CmsoException;
+import org.onap.optf.cmso.optimizer.clients.topology.TopologyRequestManager;
+import org.onap.optf.cmso.optimizer.clients.topology.models.TopologyResponse;
+import org.onap.optf.cmso.optimizer.common.LogMessages;
+import org.onap.optf.cmso.optimizer.model.Request;
+import org.onap.optf.cmso.optimizer.model.dao.RequestDao;
+import org.onap.optf.cmso.optimizer.service.rs.models.ChangeWindow;
+import org.onap.optf.cmso.optimizer.service.rs.models.ElementInfo;
+import org.onap.optf.cmso.optimizer.service.rs.models.OptimizerRequest;
+import org.onap.optf.cmso.optimizer.service.rs.models.OptimizerResponse;
+import org.onap.optf.cmso.optimizer.service.rs.models.OptimizerResponse.OptimizeScheduleStatus;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+@Component
+public class OptimizerManager {
+
+    @Autowired
+    RequestDao requestDao;
+
+    @Autowired
+    TopologyRequestManager topologyRequestManager;
+
+    /**
+     * Validate optimizer request.
+     *
+     * @param request the request
+     * @throws CmsoException cmso exception
+     */
+    public void validate(OptimizerRequest request) throws CmsoException {
+        if (request.getRequestId() == null) {
+            reportRequiredMissing("requestId");
+        }
+        if (request.getConcurrencyLimit() == null) {
+            reportRequiredMissing("concurrencyLimit");
+        }
+        if (request.getChangeWindows() == null || request.getChangeWindows().size() < 1) {
+            reportRequiredMissing("changeWindows");
+        }
+        if (request.getElements() == null || request.getElements().size() < 1) {
+            reportRequiredMissing("elements");
+        }
+        if (request.getNormalDuration() == null) {
+            reportRequiredMissing("normalDuration");
+        }
+        validateElements(request.getElements());
+        validateChangeWindows(request.getChangeWindows());
+    }
+
+    private void validateChangeWindows(List<ChangeWindow> changeWindows) throws CmsoException {
+        for (ChangeWindow changeWindow : changeWindows) {
+            validateChangeWindow(changeWindow);
+        }
+    }
+
+    private void validateChangeWindow(ChangeWindow changeWindow) throws CmsoException {
+        if (changeWindow.getStartTime() == null) {
+            reportRequiredMissing("startTime");
+        }
+        if (changeWindow.getEndTime() == null) {
+            reportRequiredMissing("endTime");
+        }
+        if (!changeWindow.getEndTime().after(changeWindow.getStartTime())) {
+            throw new CmsoException(Status.BAD_REQUEST, LogMessages.INVALID_CHANGE_WINDOW,
+                            changeWindow.getEndTime().toString(), changeWindow.getStartTime().toString());
+        }
+
+    }
+
+    private void validateElements(List<ElementInfo> elements) throws CmsoException {
+        // Perhaps check for duplicate elements....
+        for (ElementInfo element : elements) {
+            validateElement(element);
+        }
+    }
+
+    private void validateElement(ElementInfo element) throws CmsoException {
+        if (element.getElementId() == null || element.getElementId().equals("")) {
+            reportRequiredMissing("elementId");
+        }
+    }
+
+    private void reportRequiredMissing(String name) throws CmsoException {
+        throw new CmsoException(Status.BAD_REQUEST, LogMessages.MISSING_REQUIRED_ATTRIBUTE, name);
+    }
+
+    public OptimizerResponse processOptimizerRequest(OptimizerRequest request) throws CmsoException {
+        UUID uuid = UUID.fromString(request.getRequestId());
+        Request requestRow = null;
+        Optional<Request> rrOptional = requestDao.findById(uuid);
+        if (rrOptional.isPresent())
+        {
+            requestRow = rrOptional.get();
+        }
+        OptimizerResponse optimizerResponse = new OptimizerResponse();
+        optimizerResponse.setRequestId(request.getRequestId());
+        if (requestRow != null) {
+            throw new CmsoException(Status.BAD_REQUEST, LogMessages.DUPLICATE_REQUEST_ID, request.getRequestId());
+        }
+        requestRow = new Request();
+        requestRow.setUuid(uuid);
+        requestRow.setCreatedTime(System.currentTimeMillis());
+        ObjectMapper om = new ObjectMapper();
+        try {
+            requestRow.setRequest(om.writeValueAsString(request));
+        } catch (JsonProcessingException e) {
+            throw new CmsoException(Status.BAD_REQUEST, LogMessages.INVALID_REQUEST, e.getMessage());
+        }
+        requestRow.setStatus(OptimizeScheduleStatus.FAILED.toString());
+        requestDao.save(requestRow);
+        TopologyResponse topologyResponse = topologyRequestManager.createTopologyRequest(uuid);
+        if (topologyResponse != null) {
+            switch (topologyResponse.getStatus())
+            {
+                case COMPLETED:
+                    requestRow.setRequestStart(System.currentTimeMillis());
+                    requestRow.setStatus(OptimizeScheduleStatus.PENDING_TICKETS.toString());
+                    optimizerResponse.setStatus(OptimizeScheduleStatus.PENDING_TICKETS);
+
+                    break;
+                case FAILED:
+                    requestRow.setRequestStart(System.currentTimeMillis());
+                    requestRow.setRequestEnd(System.currentTimeMillis());
+                    requestRow.setStatus(OptimizeScheduleStatus.FAILED.toString());
+                    optimizerResponse.setStatus(OptimizeScheduleStatus.FAILED);
+                    optimizerResponse.setErrorMessage(topologyResponse.getErrorMessage());
+                    break;
+                case IN_PROGRESS:
+                    requestRow.setRequestStart(System.currentTimeMillis());
+                    requestRow.setStatus(OptimizeScheduleStatus.PENDING_TOPOLOGY.toString());
+                    optimizerResponse.setStatus(OptimizeScheduleStatus.PENDING_TOPOLOGY);
+                    break;
+            }
+        } else {
+            requestRow.setRequestStart(System.currentTimeMillis());
+            requestRow.setStatus(OptimizeScheduleStatus.PENDING_TOPOLOGY.toString());
+            requestDao.save(requestRow);
+            return null;
+        }
+        requestDao.save(requestRow);
+        return optimizerResponse;
+    }
+
+
+
+}
diff --git a/cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/filters/CmsoClientFilters.java b/cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/filters/CmsoClientFilters.java
new file mode 100644 (file)
index 0000000..fffd53e
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ * Copyright © 2017-2019 AT&T Intellectual Property. Modifications Copyright © 2018 IBM.
+ *
+ * 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.
+ *
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed under the Creative
+ * Commons License, Attribution 4.0 Intl. (the "License"); you may not use this documentation except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation 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.optf.cmso.optimizer.filters;
+
+import static com.att.eelf.configuration.Configuration.MDC_KEY_REQUEST_ID;
+
+import java.io.IOException;
+import javax.ws.rs.client.ClientRequestContext;
+import javax.ws.rs.client.ClientRequestFilter;
+import javax.ws.rs.client.ClientResponseContext;
+import javax.ws.rs.client.ClientResponseFilter;
+import javax.ws.rs.core.MultivaluedMap;
+import org.onap.observations.Mdc;
+import org.onap.observations.MessageHeaders;
+import org.onap.observations.MessageHeaders.HeadersEnum;
+import org.onap.observations.Observation;
+import org.onap.optf.cmso.optimizer.common.LogMessages;
+import org.slf4j.MDC;
+import org.springframework.stereotype.Component;
+
+// @SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection")
+@Component
+public class CmsoClientFilters implements ClientRequestFilter, ClientResponseFilter {
+
+    private static String appId = "cmso";
+
+    @Override
+    public void filter(ClientRequestContext requestContext, ClientResponseContext responseContext) throws IOException {
+        // On the way back
+        Mdc.metricEnd(responseContext);
+        Mdc.setCaller(17);
+        Observation.report(LogMessages.OUTGOING_MESSAGE_RETURNED, requestContext.getMethod(),
+                        requestContext.getUri().getPath().toString(), responseContext.getStatusInfo().toString());
+    }
+
+    @Override
+    public void filter(ClientRequestContext requestContext) throws IOException {
+        // On the way out
+        Mdc.metricStart(requestContext);
+        Mdc.setCaller(17);
+        Observation.report(LogMessages.OUTGOING_MESSAGE, requestContext.getMethod(),
+                        requestContext.getUri().getPath().toString());
+        MultivaluedMap<String, Object> headers = requestContext.getHeaders();
+
+        String transactionId = (String) headers.getFirst(MessageHeaders.HeadersEnum.TransactionID.toString());
+        String mdcId = MDC.get(MDC_KEY_REQUEST_ID);
+        if (transactionId == null || transactionId.equals("")) {
+            if (mdcId != null) {
+                headers.add(HeadersEnum.TransactionID.toString(), mdcId);
+            }
+        }
+        headers.add(HeadersEnum.FromAppID.toString(), appId);
+    }
+
+}
diff --git a/cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/filters/CmsoContainerFilters.java b/cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/filters/CmsoContainerFilters.java
new file mode 100644 (file)
index 0000000..e8fe5f0
--- /dev/null
@@ -0,0 +1,134 @@
+/*
+ * Copyright © 2017-2019 AT&T Intellectual Property. Modifications Copyright © 2018 IBM.
+ *
+ * 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.
+ *
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed under the Creative
+ * Commons License, Attribution 4.0 Intl. (the "License"); you may not use this documentation except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation 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.optf.cmso.optimizer.filters;
+
+import java.io.IOException;
+import java.util.UUID;
+import javax.annotation.Priority;
+import javax.servlet.http.HttpServletRequest;
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.container.ContainerRequestContext;
+import javax.ws.rs.container.ContainerRequestFilter;
+import javax.ws.rs.container.ContainerResponseContext;
+import javax.ws.rs.container.ContainerResponseFilter;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.Response.ResponseBuilder;
+import javax.ws.rs.ext.Provider;
+import org.onap.observations.Mdc;
+import org.onap.observations.MessageHeaders;
+import org.onap.observations.MessageHeaders.HeadersEnum;
+import org.onap.observations.Observation;
+import org.onap.optf.cmso.optimizer.common.LogMessages;
+import org.springframework.stereotype.Component;
+
+@Priority(1)
+@Provider
+@Component
+public class CmsoContainerFilters implements ContainerRequestFilter, ContainerResponseFilter {
+
+
+    @Context
+    private HttpServletRequest servletRequest;
+
+    @Override
+    public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext)
+                    throws IOException {
+        try {
+            Mdc.auditEnd(requestContext, responseContext);
+            Observation.report(LogMessages.INCOMING_MESSAGE_RESPONSE, requestContext.getMethod(),
+                            requestContext.getUriInfo().getPath().toString(),
+                            responseContext.getStatusInfo().toString());
+            MultivaluedMap<String, String> reqHeaders = requestContext.getHeaders();
+            MultivaluedMap<String, Object> respHeaders = responseContext.getHeaders();
+            String minorVersion = reqHeaders.getFirst(HeadersEnum.MinorVersion.toString());
+            respHeaders.add(HeadersEnum.MinorVersion.toString(), minorVersion);
+            respHeaders.add(HeadersEnum.LatestVersion.toString(), MessageHeaders.latestVersion);
+            respHeaders.add(HeadersEnum.PatchVersion.toString(), MessageHeaders.patchVersion);
+
+        } catch (Exception e) {
+            if (e instanceof WebApplicationException) {
+                Observation.report(LogMessages.EXPECTED_EXCEPTION, e.getMessage());
+            } else {
+                Observation.report(LogMessages.UNEXPECTED_EXCEPTION, e.getMessage());
+            }
+        }
+    }
+
+    @Override
+    public void filter(ContainerRequestContext requestContext) throws IOException {
+        try {
+            // On the way in
+            Mdc.auditStart(requestContext, servletRequest);
+            Observation.report(LogMessages.INCOMING_MESSAGE, requestContext.getMethod(),
+                            requestContext.getUriInfo().getPath().toString());
+
+            String majorVersion = requestContext.getUriInfo().getPath();
+            if (majorVersion != null) {
+
+                if (majorVersion.startsWith("dispatch/")) {
+                    return;
+                }
+                majorVersion = majorVersion.replaceAll("/.*$", "");
+            }
+            if (!MessageHeaders.validateMajorVersion(majorVersion)) {
+                ResponseBuilder builder = null;
+                String response = "Unsupported Major version";
+                builder = Response.status(Response.Status.NOT_FOUND).entity(response);
+                throw new WebApplicationException(builder.build());
+            }
+            MultivaluedMap<String, String> headers = requestContext.getHeaders();
+            String transactionId = headers.getFirst(HeadersEnum.TransactionID.toString());
+            if (transactionId == null) {
+                transactionId = UUID.randomUUID().toString();
+                headers.add(HeadersEnum.TransactionID.toString(), transactionId);
+            }
+            String minorVersion = headers.getFirst(HeadersEnum.MinorVersion.toString());
+            if (minorVersion == null) {
+                minorVersion = MessageHeaders.supportedMajorVersions.get(majorVersion);
+                headers.add(HeadersEnum.MinorVersion.toString(), minorVersion);
+            }
+            if (!MessageHeaders.validateMajorMinorVersion(majorVersion, minorVersion)) {
+                ResponseBuilder builder = null;
+                String response = "Unsupported API version";
+                builder = Response.status(Response.Status.NOT_FOUND).entity(response);
+                throw new WebApplicationException(builder.build());
+
+            }
+        } catch (Exception e) {
+            if (e instanceof WebApplicationException) {
+                Observation.report(LogMessages.EXPECTED_EXCEPTION, e.getMessage());
+                throw e;
+            } else {
+                Observation.report(LogMessages.UNEXPECTED_EXCEPTION, e.getMessage());
+            }
+        }
+
+    }
+
+}
diff --git a/cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/model/Optimizer.java b/cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/model/Optimizer.java
new file mode 100644 (file)
index 0000000..880992c
--- /dev/null
@@ -0,0 +1,109 @@
+/*
+ * ============LICENSE_START==============================================
+ * Copyright (c) 2019 AT&T Intellectual Property.
+ * =======================================================================
+ * 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.
+ * ============LICENSE_END=================================================
+ *
+ */
+
+package org.onap.optf.cmso.optimizer.model;
+
+import java.io.Serializable;
+import java.util.UUID;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.Lob;
+import javax.persistence.NamedQuery;
+
+
+/**
+ * The persistent class for the optimizer database table.
+ *
+ */
+@Entity
+@NamedQuery(name = "Optimizer.findAll", query = "SELECT o FROM Optimizer o")
+public class Optimizer implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    @Id
+    private UUID uuid;
+
+    @Column(name = "optimize_end")
+    private Long optimizeEnd;
+
+    @Column(name = "optimize_polling_interval")
+    private Integer optimizePollingInterval;
+
+    @Lob
+    @Column(name = "optimize_response")
+    private String optimizeResponse;
+
+    @Column(name = "optimize_retries")
+    private Integer optimizeRetries;
+
+    @Column(name = "optimize_start")
+    private Long optimizeStart;
+
+    public Optimizer() {}
+
+    public UUID getUuid() {
+        return this.uuid;
+    }
+
+    public void setUuid(UUID uuid) {
+        this.uuid = uuid;
+    }
+
+    public Long getOptimizeEnd() {
+        return this.optimizeEnd;
+    }
+
+    public void setOptimizeEnd(Long optimizeEnd) {
+        this.optimizeEnd = optimizeEnd;
+    }
+
+    public Integer getOptimizePollingInterval() {
+        return this.optimizePollingInterval;
+    }
+
+    public void setOptimizePollingInterval(Integer optimizePollingInterval) {
+        this.optimizePollingInterval = optimizePollingInterval;
+    }
+
+    public String getOptimizeResponse() {
+        return this.optimizeResponse;
+    }
+
+    public void setOptimizeResponse(String optimizeResponse) {
+        this.optimizeResponse = optimizeResponse;
+    }
+
+    public Integer getOptimizeRetries() {
+        return this.optimizeRetries;
+    }
+
+    public void setOptimizeRetries(Integer optimizeRetries) {
+        this.optimizeRetries = optimizeRetries;
+    }
+
+    public Long getOptimizeStart() {
+        return this.optimizeStart;
+    }
+
+    public void setOptimizeStart(Long optimizeStart) {
+        this.optimizeStart = optimizeStart;
+    }
+
+}
diff --git a/cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/model/Request.java b/cmso-optimizer/src/main/java/org/onap/optf/cmso/optimizer/model/Request.java
new file mode 100644 (file)
index 0000000..3258c15
--- /dev/null
@@ -0,0 +1,107 @@
+/*
+ * ============LICENSE_START==============================================
+ * Copyright (c) 2019 AT&T Intellectual Property.
+ * =======================================================================
+ * 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.
+ * ============LICENSE_END=================================================
+ *
+ */
+
+package org.onap.optf.cmso.optimizer.model;
+
+import java.io.Serializable;
+import java.util.UUID;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.Lob;
+import javax.persistence.NamedQuery;
+
+
+/**
+ * The persistent class for the request database table.
+ *
+ */
+@Entity
+@NamedQuery(name = "Request.findAll", query = "SELECT r FROM Request r")
+public class Request implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    @Id
+    private UUID uuid;
+
+    @Column(name = "created_time")
+    private Long createdTime;
+
+    @Lob
+    private String request;
+
+    @Column(name = "request_end")
+    private Long requestEnd;
+
+    @Column(name = "request_start")
+    private Long requestStart;
+
+    private String status;
+
+    public Request() {}
+
+    public UUID getUuid() {
+        return this.uuid;
+    }
+
+    public void setUuid(UUID uuid) {
+        this.uuid = uuid;
+    }
+
+    public Long getCreatedTime() {
+        return this.createdTime;
+    }
+
+    public void setCreatedTime(Long createdTime) {
+        this.createdTime = createdTime;
+    }
+
+    public String getRequest() {
+        return this.request;
+    }
+
+    public void setRequest(String request) {
+        this.request = request;
+    }
+
+    public Long getRequestEnd() {
+        return this.requestEnd;
+    }
+
+    public void setRequestEnd(Long requestEnd) {
+        this.requestEnd = requestEnd;
+    }
+
+    public Long getRequestStart() {
+        return this.requestStart;
+    }
+
+    public void setRequestStart(Long requestStart) {
+        this.requestStart = requestStart;
+    }
+
+    public String getStatus() {
+        return this.status;
+    }
+
+    public void setStatus(String status) {
+        this.status = status;
+    }
+
+}