import org.onap.policy.common.endpoints.http.client.HttpClientFactoryInstance;
import org.onap.policy.common.utils.coder.StandardCoder;
import org.onap.policy.common.utils.coder.StandardCoderObject;
-import org.onap.policy.controlloop.actorserviceprovider.Operation;
import org.onap.policy.controlloop.actorserviceprovider.OperationOutcome;
import org.onap.policy.controlloop.actorserviceprovider.Util;
+import org.onap.policy.controlloop.actorserviceprovider.impl.HttpOperation;
import org.onap.policy.controlloop.actorserviceprovider.impl.HttpOperator;
import org.onap.policy.controlloop.actorserviceprovider.parameters.ControlLoopOperationParams;
import org.onap.policy.controlloop.actorserviceprovider.parameters.HttpConfig;
}
@Override
- public Operation buildOperation(ControlLoopOperationParams params) {
+ public HttpOperation<?> buildOperation(ControlLoopOperationParams params) {
return new AaiGetTenantOperation(params, getCurrentConfig());
}
#
actors:
CDS:
- any:
- timeout: 10
- port: 6700
- host: my-host
- username: my-user
- password: my-pass
+ operations:
+ any:
+ timeout: 10
+ port: 6700
+ host: my-host
+ username: my-user
+ password: my-pass
* <dd>generated</dd>
* </dl>
*/
-public class GuardOperation extends HttpOperation<DecisionResponse> {
- private static final Logger logger = LoggerFactory.getLogger(GuardOperation.class);
+public class DecisionOperation extends HttpOperation<DecisionResponse> {
+ private static final Logger logger = LoggerFactory.getLogger(DecisionOperation.class);
// operation name
public static final String NAME = OperationPartial.GUARD_OPERATION_NAME;
* @param params operation parameters
* @param config configuration for this operation
*/
- public GuardOperation(ControlLoopOperationParams params, HttpConfig config) {
+ public DecisionOperation(ControlLoopOperationParams params, HttpConfig config) {
super(params, config, DecisionResponse.class);
this.config = (GuardConfig) config;
}
/**
* Guard Operator.
*/
-public class GuardOperator extends HttpOperator {
+public class DecisionOperator extends HttpOperator {
- public GuardOperator(String actorName, String name,
- @SuppressWarnings("rawtypes") OperationMaker<HttpConfig, HttpOperation> operationMaker) {
+ public DecisionOperator(String actorName, String name,
+ OperationMaker<HttpConfig, HttpOperation<?>> operationMaker) {
super(actorName, name, operationMaker);
}
public GuardActorServiceProvider() {
super(NAME, GuardActorParams.class);
- addOperator(new GuardOperator(NAME, GuardOperation.NAME, GuardOperation::new));
+ addOperator(new DecisionOperator(NAME, DecisionOperation.NAME, DecisionOperation::new));
}
}
import org.onap.policy.models.decisions.concepts.DecisionResponse;
import org.onap.policy.simulators.GuardSimulatorJaxRs;
-public class GuardOperationTest extends BasicHttpOperation<DecisionRequest> {
+public class DecisionOperationTest extends BasicHttpOperation<DecisionRequest> {
@Mock
private Consumer<OperationOutcome> started;
private Consumer<OperationOutcome> completed;
private GuardConfig guardConfig;
- private GuardOperation oper;
+ private DecisionOperation oper;
/**
* Starts the simulator.
params = params.toBuilder().startCallback(started).completeCallback(completed).build();
- oper = new GuardOperation(params, config);
+ oper = new DecisionOperation(params, config);
}
/**
config = new GuardConfig(blockingExecutor, opParams, HttpClientFactoryInstance.getClientFactory());
params = params.toBuilder().retry(0).timeoutSec(5).executor(blockingExecutor).build();
- oper = new GuardOperation(params, config);
+ oper = new DecisionOperation(params, config);
outcome = oper.start().get();
assertEquals(PolicyResult.SUCCESS, outcome.getResult());
params = params.toBuilder().retry(0).timeoutSec(5).executor(blockingExecutor)
.payload(Map.of("clname", GuardSimulatorJaxRs.DENY_CLNAME)).build();
- oper = new GuardOperation(params, config);
+ oper = new DecisionOperation(params, config);
outcome = oper.start().get();
assertEquals(PolicyResult.FAILURE, outcome.getResult());
assertFalse(future2.isDone());
DecisionResponse resp = new DecisionResponse();
- resp.setStatus(GuardOperation.PERMIT);
+ resp.setStatus(DecisionOperation.PERMIT);
when(rawResponse.readEntity(String.class)).thenReturn(Util.translate("", resp, String.class));
verify(client).post(callbackCaptor.capture(), any(), requestCaptor.capture(), any());
// null payload - start with fresh parameters and operation
params = params.toBuilder().payload(null).build();
- oper = new GuardOperation(params, config);
+ oper = new DecisionOperation(params, config);
assertThatIllegalArgumentException().isThrownBy(() -> oper.makeRequest());
}
import org.onap.policy.controlloop.actorserviceprovider.Util;
import org.onap.policy.controlloop.actorserviceprovider.parameters.ParameterValidationRuntimeException;
-public class GuardOperatorTest {
+public class DecisionOperatorTest {
private static final String ACTOR = "my-actor";
private static final String OPERATION = "my-name";
private static final String CLIENT = "my-client";
private HttpClientFactory factory;
- private GuardOperator oper;
+ private DecisionOperator oper;
/**
* Initializes fields, including {@link #oper}, and resets the static fields used by
}
- private class MyOperator extends GuardOperator {
+ private class MyOperator extends DecisionOperator {
public MyOperator() {
super(ACTOR, OPERATION, null);
}
import org.junit.Test;
import org.onap.policy.common.parameters.ValidationResult;
import org.onap.policy.controlloop.actorserviceprovider.Util;
-import org.onap.policy.controlloop.actorserviceprovider.parameters.CommonActorParams;
+import org.onap.policy.controlloop.actorserviceprovider.parameters.ActorParams;
public class GuardActorParamsTest {
private static final String CONTAINER = "my-container";
assertTrue(params.validate(CONTAINER).isValid());
// only a few fields are required
- GuardActorParams sparse = Util.translate(CONTAINER, Map.of(CommonActorParams.OPERATIONS_FIELD, operations),
+ GuardActorParams sparse = Util.translate(CONTAINER, Map.of(ActorParams.OPERATIONS_FIELD, operations),
GuardActorParams.class);
assertTrue(sparse.validate(CONTAINER).isValid());
assertEquals(GuardActorParams.DEFAULT_ACTION, sparse.getAction());
// check fields from superclass
- testValidateField(CommonActorParams.OPERATIONS_FIELD, "null", params2 -> params2.setOperations(null));
+ testValidateField(ActorParams.OPERATIONS_FIELD, "null", params2 -> params2.setOperations(null));
testValidateField("timeoutSec", "minimum", params2 -> params2.setTimeoutSec(-1));
}
final GuardActorServiceProvider prov = new GuardActorServiceProvider();
// verify that it has the operators we expect
- var expected = Arrays.asList(GuardOperation.NAME).stream().sorted().collect(Collectors.toList());
+ var expected = Arrays.asList(DecisionOperation.NAME).stream().sorted().collect(Collectors.toList());
var actual = prov.getOperationNames().stream().sorted().collect(Collectors.toList());
assertEquals(expected.toString(), actual.toString());
// verify that it all plugs into the ActorService
verifyActorService(GuardActorServiceProvider.NAME, "service.yaml");
- assertTrue(prov.getOperator(GuardOperation.NAME) instanceof GuardOperator);
+ assertTrue(prov.getOperator(DecisionOperation.NAME) instanceof DecisionOperator);
}
}
import static org.junit.Assert.assertTrue;
import java.time.Instant;
+import java.util.Arrays;
import java.util.HashMap;
import java.util.UUID;
+import java.util.stream.Collectors;
import org.junit.Test;
import org.onap.policy.controlloop.ControlLoopEventStatus;
import org.onap.policy.controlloop.ControlLoopOperation;
import org.onap.policy.controlloop.ControlLoopResponse;
import org.onap.policy.controlloop.ControlLoopTargetType;
import org.onap.policy.controlloop.VirtualControlLoopEvent;
+import org.onap.policy.controlloop.actor.test.BasicActor;
import org.onap.policy.controlloop.actorserviceprovider.Operator;
import org.onap.policy.controlloop.policy.Policy;
import org.onap.policy.controlloop.policy.Target;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-public class SdnrActorServiceProviderTest {
+public class SdnrActorServiceProviderTest extends BasicActor {
private static final String MODIFY_CONFIG = "ModifyConfig";
}
+ @Test
+ public void testConstructor() {
+ SdnrActorServiceProvider prov = new SdnrActorServiceProvider();
+ assertEquals(0, prov.getSequenceNumber());
+
+ // verify that it has the operators we expect
+ var expected = Arrays.asList(SdnrOperation.NAME).stream().sorted().collect(Collectors.toList());
+ var actual = prov.getOperationNames().stream().sorted().collect(Collectors.toList());
+
+ assertEquals(expected.toString(), actual.toString());
+ }
+
+ @Test
+ public void testActorService() {
+ // verify that it all plugs into the ActorService
+ verifyActorService(SdnrActorServiceProvider.NAME, "service.yaml");
+ }
+
@Test
public void testGetOperator() {
SdnrActorServiceProvider sp = new SdnrActorServiceProvider();
--- /dev/null
+#
+# ============LICENSE_START======================================================
+# ONAP
+# ===============================================================================
+# Copyright (C) 2020 AT&T Intellectual Property. All rights reserved.
+# ===============================================================================
+# 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========================================================
+#
+topics:
+ topicSources:
+ - topicCommInfrastructure: NOOP
+ topic: my-source
+ servers:
+ - localhost
+ managed: true
+ topicSinks:
+ - topicCommInfrastructure: NOOP
+ topic: my-sink
+ servers:
+ - localhost
+ managed: true
+actors:
+ SDNR:
+ sinkTopic: my-sink
+ sourceTopic: my-source
+ operations:
+ any: {}
import org.onap.policy.controlloop.ControlLoopOperation;
import org.onap.policy.controlloop.VirtualControlLoopEvent;
import org.onap.policy.controlloop.actorserviceprovider.impl.HttpActor;
+import org.onap.policy.controlloop.actorserviceprovider.impl.HttpPollingOperator;
+import org.onap.policy.controlloop.actorserviceprovider.parameters.HttpPollingActorParams;
import org.onap.policy.controlloop.policy.Policy;
import org.onap.policy.so.SoCloudConfiguration;
import org.onap.policy.so.SoManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-public class SoActorServiceProvider extends HttpActor<SoActorParams> {
+public class SoActorServiceProvider extends HttpActor<HttpPollingActorParams> {
private static final Logger logger = LoggerFactory.getLogger(SoActorServiceProvider.class);
public static final String NAME = "SO";
* Constructs the object.
*/
public SoActorServiceProvider() {
- super(NAME, SoActorParams.class);
+ super(NAME, HttpPollingActorParams.class);
- addOperator(new SoOperator(NAME, VfModuleCreate.NAME, VfModuleCreate::new));
- addOperator(new SoOperator(NAME, VfModuleDelete.NAME, VfModuleDelete::new));
+ addOperator(new HttpPollingOperator(NAME, VfModuleCreate.NAME, VfModuleCreate::new));
+ addOperator(new HttpPollingOperator(NAME, VfModuleDelete.NAME, VfModuleDelete::new));
}
// TODO old code: remove lines down to **HERE**
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.TimeUnit;
-import java.util.function.Function;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
-import lombok.Getter;
import org.onap.aai.domain.yang.CloudRegion;
import org.onap.aai.domain.yang.GenericVnf;
import org.onap.aai.domain.yang.ServiceInstance;
import org.onap.aai.domain.yang.Tenant;
import org.onap.policy.aai.AaiConstants;
import org.onap.policy.aai.AaiCqResponse;
-import org.onap.policy.common.endpoints.event.comm.Topic.CommInfrastructure;
-import org.onap.policy.common.endpoints.utils.NetLoggerUtil.EventType;
import org.onap.policy.common.gson.GsonMessageBodyHandler;
import org.onap.policy.common.utils.coder.Coder;
import org.onap.policy.common.utils.coder.CoderException;
import org.onap.policy.controlloop.actorserviceprovider.OperationOutcome;
import org.onap.policy.controlloop.actorserviceprovider.impl.HttpOperation;
import org.onap.policy.controlloop.actorserviceprovider.parameters.ControlLoopOperationParams;
-import org.onap.policy.controlloop.actorserviceprovider.parameters.HttpConfig;
+import org.onap.policy.controlloop.actorserviceprovider.parameters.HttpPollingConfig;
import org.onap.policy.controlloop.policy.PolicyResult;
import org.onap.policy.controlloop.policy.Target;
import org.onap.policy.so.SoCloudConfiguration;
import org.onap.policy.so.SoRequestStatus;
import org.onap.policy.so.SoResponse;
import org.onap.policy.so.util.SoLocalDateTimeTypeAdapter;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
/**
- * Superclass for SDNC Operators. Note: subclasses should invoke {@link #resetGetCount()}
+ * Superclass for SDNC Operators. Note: subclasses should invoke {@link #resetPollCount()}
* each time they issue an HTTP request.
*/
public abstract class SoOperation extends HttpOperation<SoResponse> {
- private static final Logger logger = LoggerFactory.getLogger(SoOperation.class);
private static final Coder coder = new SoCoder();
public static final String PAYLOAD_KEY_VF_COUNT = "vfCount";
public static final String REQ_PARAM_NM = "requestParameters";
public static final String CONFIG_PARAM_NM = "configurationParameters";
- private final SoConfig config;
-
// values extracted from the parameter Target
private final String modelCustomizationId;
private final String modelInvariantId;
private final String vfCountKey;
- /**
- * Number of "get" requests issued so far, on the current operation attempt.
- */
- @Getter
- private int getCount;
-
/**
* Constructs the object.
* @param params operation parameters
* @param config configuration for this operation
*/
- public SoOperation(ControlLoopOperationParams params, HttpConfig config) {
+ public SoOperation(ControlLoopOperationParams params, HttpPollingConfig config) {
super(params, config, SoResponse.class);
- this.config = (SoConfig) config;
+
+ setUsePolling();
verifyNotNull("Target information", params.getTarget());
+ modelVersionId + "]";
}
- /**
- * Subclasses should invoke this before issuing their first HTTP request.
- */
- protected void resetGetCount() {
- getCount = 0;
+ @Override
+ protected void resetPollCount() {
+ super.resetPollCount();
setSubRequestId(null);
}
params.getContext().setProperty(vfCountKey, vfCount);
}
- /**
- * If the response does not indicate that the request has been completed, then sleep a
- * bit and issue a "get".
- */
@Override
- protected CompletableFuture<OperationOutcome> postProcessResponse(OperationOutcome outcome, String url,
- Response rawResponse, SoResponse response) {
-
- // see if the request has "completed", whether or not it was successful
+ protected Status detmStatus(Response rawResponse, SoResponse response) {
if (rawResponse.getStatus() == 200) {
String requestState = getRequestState(response);
if (COMPLETE.equalsIgnoreCase(requestState)) {
extractSubRequestId(response);
- successfulCompletion();
- return CompletableFuture
- .completedFuture(setOutcome(outcome, PolicyResult.SUCCESS, rawResponse, response));
+ return Status.SUCCESS;
}
if (FAILED.equalsIgnoreCase(requestState)) {
extractSubRequestId(response);
- return CompletableFuture
- .completedFuture(setOutcome(outcome, PolicyResult.FAILURE, rawResponse, response));
+ return Status.FAILURE;
}
}
throw new IllegalArgumentException("missing request ID in response");
}
- // see if the limit for the number of "gets" has been reached
- if (getCount++ >= getMaxGets()) {
- logger.warn("{}: execeeded 'get' limit {} for {}", getFullName(), getMaxGets(), params.getRequestId());
- setOutcome(outcome, PolicyResult.FAILURE_TIMEOUT);
- outcome.setResponse(response);
- outcome.setMessage(SO_RESPONSE_CODE + " " + outcome.getMessage());
- return CompletableFuture.completedFuture(outcome);
- }
+ return Status.STILL_WAITING;
+ }
- // sleep and then perform a "get" operation
- Function<Void, CompletableFuture<OperationOutcome>> doGet = unused -> issueGet(outcome);
- return sleep(getWaitMsGet(), TimeUnit.MILLISECONDS).thenComposeAsync(doGet);
+ @Override
+ protected String getPollingPath() {
+ return super.getPollingPath() + getSubRequestId();
}
@Override
return true;
}
- /**
- * Invoked when a request completes successfully.
- */
- protected void successfulCompletion() {
- // do nothing
- }
-
- /**
- * Issues a "get" request to see if the original request is complete yet.
- *
- * @param outcome outcome to be populated with the response
- * @return a future that can be used to cancel the "get" request or await its response
- */
- private CompletableFuture<OperationOutcome> issueGet(OperationOutcome outcome) {
- String path = getPathGet() + getSubRequestId();
- String url = getClient().getBaseUrl() + path;
-
- logger.debug("{}: 'get' count {} for {}", getFullName(), getCount, params.getRequestId());
-
- logMessage(EventType.OUT, CommInfrastructure.REST, url, null);
-
- return handleResponse(outcome, url, callback -> getClient().get(callback, path, null));
- }
-
/**
* Gets the request state of a response.
*
// set default result and message
setOutcome(outcome, result);
+ int code = (result == PolicyResult.FAILURE_TIMEOUT ? SO_RESPONSE_CODE : rawResponse.getStatus());
+
outcome.setResponse(response);
- outcome.setMessage(rawResponse.getStatus() + " " + outcome.getMessage());
+ outcome.setMessage(code + " " + outcome.getMessage());
return outcome;
}
// these may be overridden by junit tests
- /**
- * Gets the wait time, in milliseconds, between "get" requests.
- *
- * @return the wait time, in milliseconds, between "get" requests
- */
- public long getWaitMsGet() {
- return TimeUnit.MILLISECONDS.convert(getWaitSecGet(), TimeUnit.SECONDS);
- }
-
- public int getMaxGets() {
- return config.getMaxGets();
- }
-
- public String getPathGet() {
- return config.getPathGet();
- }
-
- public int getWaitSecGet() {
- return config.getWaitSecGet();
- }
-
@Override
protected Coder getCoder() {
return coder;
+++ /dev/null
-/*-
- * ============LICENSE_START=======================================================
- * ONAP
- * ================================================================================
- * Copyright (C) 2020 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * 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.policy.controlloop.actor.so;
-
-import java.util.Map;
-import org.onap.policy.common.parameters.ValidationResult;
-import org.onap.policy.controlloop.actorserviceprovider.Util;
-import org.onap.policy.controlloop.actorserviceprovider.impl.HttpOperation;
-import org.onap.policy.controlloop.actorserviceprovider.impl.HttpOperator;
-import org.onap.policy.controlloop.actorserviceprovider.impl.OperationMaker;
-import org.onap.policy.controlloop.actorserviceprovider.parameters.HttpConfig;
-import org.onap.policy.controlloop.actorserviceprovider.parameters.ParameterValidationRuntimeException;
-
-/**
- * SO Operator.
- */
-public class SoOperator extends HttpOperator {
-
- public SoOperator(String actorName, String name,
- @SuppressWarnings("rawtypes") OperationMaker<HttpConfig, HttpOperation> operationMaker) {
- super(actorName, name, operationMaker);
- }
-
- @Override
- protected HttpConfig makeConfiguration(Map<String, Object> parameters) {
- SoParams params = Util.translate(getFullName(), parameters, SoParams.class);
- ValidationResult result = params.validate(getFullName());
- if (!result.isValid()) {
- throw new ParameterValidationRuntimeException("invalid parameters", result);
- }
-
- return new SoConfig(getBlockingExecutor(), params, getClientFactory());
- }
-}
import java.util.concurrent.CompletableFuture;
import javax.ws.rs.client.Entity;
import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
import org.apache.commons.lang3.tuple.Pair;
import org.onap.aai.domain.yang.CloudRegion;
import org.onap.aai.domain.yang.GenericVnf;
import org.onap.policy.common.endpoints.utils.NetLoggerUtil.EventType;
import org.onap.policy.controlloop.actorserviceprovider.OperationOutcome;
import org.onap.policy.controlloop.actorserviceprovider.parameters.ControlLoopOperationParams;
-import org.onap.policy.controlloop.actorserviceprovider.parameters.HttpConfig;
+import org.onap.policy.controlloop.actorserviceprovider.parameters.HttpPollingConfig;
import org.onap.policy.so.SoModelInfo;
import org.onap.policy.so.SoOperationType;
import org.onap.policy.so.SoRelatedInstance;
import org.onap.policy.so.SoRequest;
import org.onap.policy.so.SoRequestDetails;
import org.onap.policy.so.SoRequestParameters;
+import org.onap.policy.so.SoResponse;
/**
* Operation to create a VF Module. This gets the VF count from the A&AI Custom Query
* @param params operation parameters
* @param config configuration for this operation
*/
- public VfModuleCreate(ControlLoopOperationParams params, HttpConfig config) {
+ public VfModuleCreate(ControlLoopOperationParams params, HttpPollingConfig config) {
super(params, config);
// ensure we have the necessary parameters
protected CompletableFuture<OperationOutcome> startOperationAsync(int attempt, OperationOutcome outcome) {
// starting a whole new attempt - reset the count
- resetGetCount();
+ resetPollCount();
Pair<String, SoRequest> pair = makeRequest();
String path = getPath() + pair.getLeft();
}
/**
- * Increments the VF count that's stored in the context.
+ * Increments the VF count that's stored in the context, if the request was
+ * successful.
*/
@Override
- protected void successfulCompletion() {
- setVfCount(getVfCount() + 1);
+ protected Status detmStatus(Response rawResponse, SoResponse response) {
+ Status status = super.detmStatus(rawResponse, response);
+
+ if (status == Status.SUCCESS) {
+ setVfCount(getVfCount() + 1);
+ }
+
+ return status;
}
/**
import org.onap.policy.common.endpoints.utils.NetLoggerUtil.EventType;
import org.onap.policy.controlloop.actorserviceprovider.OperationOutcome;
import org.onap.policy.controlloop.actorserviceprovider.parameters.ControlLoopOperationParams;
-import org.onap.policy.controlloop.actorserviceprovider.parameters.HttpConfig;
+import org.onap.policy.controlloop.actorserviceprovider.parameters.HttpPollingConfig;
import org.onap.policy.controlloop.actorserviceprovider.pipeline.PipelineControllerFuture;
import org.onap.policy.so.SoModelInfo;
import org.onap.policy.so.SoOperationType;
import org.onap.policy.so.SoRequest;
import org.onap.policy.so.SoRequestDetails;
+import org.onap.policy.so.SoResponse;
/**
* Operation to delete a VF Module. This gets the VF count from the A&AI Custom Query
* @param params operation parameters
* @param config configuration for this operation
*/
- public VfModuleDelete(ControlLoopOperationParams params, HttpConfig config) {
+ public VfModuleDelete(ControlLoopOperationParams params, HttpPollingConfig config) {
super(params, config);
// ensure we have the necessary parameters
protected CompletableFuture<OperationOutcome> startOperationAsync(int attempt, OperationOutcome outcome) {
// starting a whole new attempt - reset the count
- resetGetCount();
+ resetPollCount();
Pair<String, SoRequest> pair = makeRequest();
SoRequest request = pair.getRight();
return builder.header("Authorization", "Basic " + encoded);
}
+
/**
- * Decrements the VF count that's stored in the context.
+ * Decrements the VF count that's stored in the context, if the request was
+ * successful.
*/
@Override
- protected void successfulCompletion() {
- setVfCount(getVfCount() - 1);
+ protected Status detmStatus(Response rawResponse, SoResponse response) {
+ Status status = super.detmStatus(rawResponse, response);
+
+ if (status == Status.SUCCESS) {
+ setVfCount(getVfCount() - 1);
+ }
+
+ return status;
}
/**
import org.onap.policy.common.endpoints.http.server.HttpServletServerFactoryInstance;
import org.onap.policy.controlloop.actor.test.BasicHttpOperation;
import org.onap.policy.controlloop.actorserviceprovider.Util;
+import org.onap.policy.controlloop.actorserviceprovider.parameters.HttpPollingConfig;
import org.onap.policy.controlloop.policy.Target;
import org.onap.policy.simulators.SoSimulatorJaxRs;
import org.onap.policy.so.SoRequest;
public static final String MODEL_VERS_ID = "my-model-version-id";
public static final String SUBSCRIPTION_SVC_TYPE = "my-subscription-service-type";
public static final String MY_PATH = "my-path";
- public static final String PATH_GET = "my-path-get/";
- public static final int MAX_GETS = 3;
- public static final int WAIT_SEC_GETS = 20;
+ public static final String POLL_PATH = "my-poll-path/";
+ public static final int MAX_POLLS = 3;
+ public static final int POLL_WAIT_SEC = 20;
public static final Integer VF_COUNT = 10;
@Mock
- protected SoConfig config;
+ protected HttpPollingConfig config;
protected Target target;
protected SoResponse response;
super.initConfig();
when(config.getClient()).thenReturn(client);
when(config.getPath()).thenReturn(MY_PATH);
- when(config.getMaxGets()).thenReturn(MAX_GETS);
- when(config.getPathGet()).thenReturn(PATH_GET);
- when(config.getWaitSecGet()).thenReturn(WAIT_SEC_GETS);
+ when(config.getMaxPolls()).thenReturn(MAX_POLLS);
+ when(config.getPollPath()).thenReturn(POLL_PATH);
+ when(config.getPollWaitSec()).thenReturn(POLL_WAIT_SEC);
}
@Override
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
-import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.ForkJoinPool;
-import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
import java.util.function.Supplier;
import org.junit.Before;
import org.onap.policy.so.SoModelInfo;
import org.onap.policy.so.SoRequest;
import org.onap.policy.so.SoRequestInfo;
-import org.onap.policy.so.SoRequestReferences;
import org.onap.policy.so.SoRequestStatus;
import org.onap.policy.so.SoResponse;
}
@Test
- public void testConstructor_testGetWaitMsGet() {
+ public void testConstructor() {
assertEquals(DEFAULT_ACTOR, oper.getActorName());
assertEquals(DEFAULT_OPERATION, oper.getName());
assertSame(config, oper.getConfig());
- assertEquals(1000 * WAIT_SEC_GETS, oper.getWaitMsGet());
+ assertTrue(oper.isUsePolling());
// check when Target is null
params = params.toBuilder().target(null).build();
assertNull(oper.obtainVfCount());
}
- @Test
- public void testPostProcess() throws Exception {
- // completed
- oper.generateSubRequestId(2);
- assertNull(oper.getSubRequestId());
- CompletableFuture<OperationOutcome> future2 = oper.postProcessResponse(outcome, PATH, rawResponse, response);
- assertTrue(future2.isDone());
- assertSame(outcome, future2.get());
- assertEquals(PolicyResult.SUCCESS, outcome.getResult());
- assertNotNull(oper.getSubRequestId());
- assertSame(response, outcome.getResponse());
-
- // failed
- oper.generateSubRequestId(2);
- assertNull(oper.getSubRequestId());
- response.getRequest().getRequestStatus().setRequestState(SoOperation.FAILED);
- future2 = oper.postProcessResponse(outcome, PATH, rawResponse, response);
- assertTrue(future2.isDone());
- assertSame(outcome, future2.get());
- assertEquals(PolicyResult.FAILURE, outcome.getResult());
- assertNotNull(oper.getSubRequestId());
- assertSame(response, outcome.getResponse());
-
- // no request id in the response
- oper.generateSubRequestId(2);
- assertNull(oper.getSubRequestId());
- response.getRequestReferences().setRequestId(null);
- response.getRequest().getRequestStatus().setRequestState("unknown");
- assertThatIllegalArgumentException()
- .isThrownBy(() -> oper.postProcessResponse(outcome, PATH, rawResponse, response))
- .withMessage("missing request ID in response");
- response.getRequestReferences().setRequestId(REQ_ID.toString());
-
- // status = 500
- when(rawResponse.getStatus()).thenReturn(500);
-
- // null request reference
- SoRequestReferences ref = response.getRequestReferences();
- response.setRequestReferences(null);
- assertThatIllegalArgumentException()
- .isThrownBy(() -> oper.postProcessResponse(outcome, PATH, rawResponse, response))
- .withMessage("missing request ID in response");
- response.setRequestReferences(ref);
- }
-
- /**
- * Tests postProcess() when the "get" is repeated a couple of times.
- */
- @Test
- public void testPostProcessRepeated_testResetGetCount() throws Exception {
- /*
- * Two failures and then a success - should result in two "get" calls.
- *
- * Note: getStatus() is invoked twice during each call, so have to double up the
- * return values.
- */
- when(rawResponse.getStatus()).thenReturn(500, 500, 500, 500, 200, 200);
-
- when(client.get(any(), any(), any())).thenAnswer(provideResponse(rawResponse));
-
- // use a real executor
- params = params.toBuilder().executor(ForkJoinPool.commonPool()).build();
-
- oper = new SoOperation(params, config) {
- @Override
- public long getWaitMsGet() {
- return 1;
- }
- };
-
- CompletableFuture<OperationOutcome> future2 = oper.postProcessResponse(outcome, PATH, rawResponse, response);
-
- assertSame(outcome, future2.get(5, TimeUnit.SECONDS));
- assertEquals(PolicyResult.SUCCESS, outcome.getResult());
- assertEquals(2, oper.getGetCount());
-
- /*
- * repeat - this time, the "get" operations will be exhausted, so it should fail
- */
- when(rawResponse.getStatus()).thenReturn(500);
-
- future2 = oper.postProcessResponse(outcome, PATH, rawResponse, response);
-
- assertSame(outcome, future2.get(5, TimeUnit.SECONDS));
- assertEquals(PolicyResult.FAILURE_TIMEOUT, outcome.getResult());
- assertEquals(MAX_GETS + 1, oper.getGetCount());
-
- oper.resetGetCount();
- assertEquals(0, oper.getGetCount());
- assertNull(oper.getSubRequestId());
- }
-
@Test
public void testGetRequestState() {
SoResponse resp = new SoResponse();
import org.onap.policy.common.utils.coder.CoderException;
import org.onap.policy.controlloop.actorserviceprovider.OperationOutcome;
import org.onap.policy.controlloop.actorserviceprovider.parameters.ControlLoopOperationParams;
+import org.onap.policy.controlloop.actorserviceprovider.parameters.HttpPollingConfig;
+import org.onap.policy.controlloop.actorserviceprovider.parameters.HttpPollingParams;
import org.onap.policy.controlloop.policy.PolicyResult;
import org.onap.policy.so.SoRequest;
import org.onap.policy.so.SoResponse;
*/
@Test
public void testSuccess() throws Exception {
- SoParams opParams = SoParams.builder().clientName(MY_CLIENT).path("serviceInstantiation/v7/serviceInstances")
- .pathGet("orchestrationRequests/v5/").maxGets(2).build();
- config = new SoConfig(blockingExecutor, opParams, HttpClientFactoryInstance.getClientFactory());
+ HttpPollingParams opParams = HttpPollingParams.builder().clientName(MY_CLIENT)
+ .path("serviceInstantiation/v7/serviceInstances").pollPath("orchestrationRequests/v5/")
+ .maxPolls(2).build();
+ config = new HttpPollingConfig(blockingExecutor, opParams, HttpClientFactoryInstance.getClientFactory());
params = params.toBuilder().retry(0).timeoutSec(5).executor(blockingExecutor).build();
+
oper = new VfModuleCreate(params, config);
outcome = oper.start().get();
oper = new VfModuleCreate(params, config) {
@Override
- public long getWaitMsGet() {
+ protected long getPollWaitMs() {
return 1;
}
};
}
/**
- * Tests startOperationAsync() when "get" operations are required.
+ * Tests startOperationAsync() when polling is required.
*/
@Test
- public void testStartOperationAsyncWithGets() throws Exception {
+ public void testStartOperationAsyncWithPolling() throws Exception {
when(rawResponse.getStatus()).thenReturn(500, 500, 500, 500, 200, 200);
when(client.post(any(), any(), any(), any())).thenAnswer(provideResponse(rawResponse));
oper = new VfModuleCreate(params, config) {
@Override
- public long getWaitMsGet() {
+ public long getPollWaitMs() {
return 1;
}
};
import org.onap.policy.common.utils.coder.CoderException;
import org.onap.policy.controlloop.actorserviceprovider.OperationOutcome;
import org.onap.policy.controlloop.actorserviceprovider.parameters.ControlLoopOperationParams;
-import org.onap.policy.controlloop.actorserviceprovider.parameters.HttpConfig;
+import org.onap.policy.controlloop.actorserviceprovider.parameters.HttpPollingConfig;
+import org.onap.policy.controlloop.actorserviceprovider.parameters.HttpPollingParams;
import org.onap.policy.controlloop.policy.PolicyResult;
import org.onap.policy.so.SoRequest;
import org.onap.policy.so.SoResponse;
*/
@Test
public void testSuccess() throws Exception {
- SoParams opParams = SoParams.builder().clientName(MY_CLIENT).path("serviceInstances/v7")
- .pathGet("orchestrationRequests/v5/").maxGets(2).build();
- config = new SoConfig(blockingExecutor, opParams, HttpClientFactoryInstance.getClientFactory());
+ HttpPollingParams opParams = HttpPollingParams.builder().clientName(MY_CLIENT).path("serviceInstances/v7")
+ .pollPath("orchestrationRequests/v5/").maxPolls(2).build();
+ config = new HttpPollingConfig(blockingExecutor, opParams, HttpClientFactoryInstance.getClientFactory());
params = params.toBuilder().retry(0).timeoutSec(5).executor(blockingExecutor).build();
+
oper = new VfModuleDelete(params, config);
outcome = oper.start().get();
// verify that target validation is done
params = params.toBuilder().target(null).build();
- assertThatIllegalArgumentException().isThrownBy(() -> new VfModuleDelete(params, config))
+ assertThatIllegalArgumentException().isThrownBy(() -> new MyOperation(params, config))
.withMessageContaining("Target information");
}
oper = new MyOperation(params, config) {
@Override
- public long getWaitMsGet() {
+ public long getPollWaitMs() {
return 1;
}
};
}
/**
- * Tests startOperationAsync() when "get" operations are required.
+ * Tests startOperationAsync() when polling is required.
*/
@Test
- public void testStartOperationAsyncWithGets() throws Exception {
+ public void testStartOperationAsyncWithPolling() throws Exception {
// indicate that the response was incomplete
configureResponse(coder.encode(response).replace("COMPLETE", "incomplete"));
oper = new MyOperation(params, config) {
@Override
- public long getWaitMsGet() {
+ public long getPollWaitMs() {
return 1;
}
};
@Test
public void testMakeHttpClient() {
// must use a real operation to invoke this method
- assertNotNull(new VfModuleDelete(params, config).makeHttpClient());
+ assertNotNull(new MyOperation(params, config).makeHttpClient());
}
private class MyOperation extends VfModuleDelete {
- public MyOperation(ControlLoopOperationParams params, HttpConfig config) {
+ public MyOperation(ControlLoopOperationParams params, HttpPollingConfig config) {
super(params, config);
}
actors:
SO:
clientName: my-client
+ pollPath: orchestrationRequests/v5
+ pollWaitSec: 20
+ maxPolls: 20
operations:
VF Module Create:
path: serviceInstantiation/v7/serviceInstances
VF Module Delete:
- path: serviceInstances/v7
\ No newline at end of file
+ path: serviceInstances/v7
#
actors:
MyActor:
- MyOperationA: {}
- MyOperationB: {}
\ No newline at end of file
+ operations:
+ MyOperationA: {}
+ MyOperationB: {}
managed: true
actors:
MyActor:
- MyOperationA: {}
- MyOperationB: {}
\ No newline at end of file
+ operations:
+ MyOperationA: {}
+ MyOperationB: {}
managed: true
actors:
MyActor:
- MyOperationA: {}
- MyOperationB: {}
\ No newline at end of file
+ operations:
+ MyOperationA: {}
+ MyOperationB: {}
protected CompletableFuture<OperationOutcome> startOperationAsync(int attempt, OperationOutcome outcome) {
// starting a whole new attempt - reset the count
- resetGetCount();
+ resetPollCount();
Pair<String, VfcRequest> pair = makeRequest();
Entity<VfcRequest> entity = Entity.entity(pair.getRight(), MediaType.APPLICATION_JSON);
import org.onap.policy.aai.AaiCqResponse;
import org.onap.policy.controlloop.ControlLoopOperation;
import org.onap.policy.controlloop.VirtualControlLoopEvent;
-import org.onap.policy.controlloop.actorserviceprovider.impl.ActorImpl;
+import org.onap.policy.controlloop.actorserviceprovider.impl.HttpActor;
+import org.onap.policy.controlloop.actorserviceprovider.impl.HttpPollingOperator;
+import org.onap.policy.controlloop.actorserviceprovider.parameters.HttpPollingActorParams;
import org.onap.policy.controlloop.policy.Policy;
import org.onap.policy.vfc.VfcHealActionVmInfo;
import org.onap.policy.vfc.VfcHealAdditionalParams;
import org.onap.policy.vfc.VfcHealRequest;
import org.onap.policy.vfc.VfcRequest;
-public class VfcActorServiceProvider extends ActorImpl {
+public class VfcActorServiceProvider extends HttpActor<HttpPollingActorParams> {
private static final String GENERIC_VNF_ID = "generic-vnf.vnf-id";
// TODO old code: remove lines down to **HERE**
* Constructor.
*/
public VfcActorServiceProvider() {
- super(NAME);
+ super(NAME, HttpPollingActorParams.class);
- addOperator(new VfcOperator(NAME, Restart.NAME, Restart::new));
+ addOperator(new HttpPollingOperator(NAME, Restart.NAME, Restart::new));
}
// TODO old code: remove lines down to **HERE**
+++ /dev/null
-/*-
- * ============LICENSE_START=======================================================
- * ONAP
- * ================================================================================
- * Copyright (C) 2020 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * 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.policy.controlloop.actor.vfc;
-
-import java.util.concurrent.Executor;
-import lombok.Getter;
-import org.onap.policy.common.endpoints.http.client.HttpClient;
-import org.onap.policy.common.endpoints.http.client.HttpClientFactory;
-import org.onap.policy.controlloop.actorserviceprovider.parameters.HttpConfig;
-
-@Getter
-public class VfcConfig extends HttpConfig {
-
- /**
- * Path to use for the "get" request. A trailing "/" is added, if it is missing.
- */
- private String pathGet;
-
- /**
- * Maximum number of "get" requests permitted, after the initial request, to retrieve
- * the response.
- */
- private int maxGets;
-
- /**
- * Time, in seconds, to wait between issuing "get" requests.
- */
- private int waitSecGet;
-
- /**
- * Constructor.
- *
- * @param blockingExecutor executor to be used for tasks that may perform blocking I/O
- * @param params operator parameters
- * @param clientFactory factory from which to obtain the {@link HttpClient}
- */
- public VfcConfig(Executor blockingExecutor, VfcParams params, HttpClientFactory clientFactory) {
- super(blockingExecutor, params, clientFactory);
-
- this.pathGet = params.getPathGet() + (params.getPathGet().endsWith("/") ? "" : "/");
- this.maxGets = params.getMaxGets();
- this.waitSecGet = params.getWaitSecGet();
- }
-
-}
package org.onap.policy.controlloop.actor.vfc;
import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.TimeUnit;
-import java.util.function.Function;
import javax.ws.rs.core.Response;
-import lombok.Getter;
import org.apache.commons.lang3.StringUtils;
-import org.onap.policy.common.endpoints.event.comm.Topic.CommInfrastructure;
-import org.onap.policy.common.endpoints.utils.NetLoggerUtil.EventType;
import org.onap.policy.controlloop.actorserviceprovider.OperationOutcome;
import org.onap.policy.controlloop.actorserviceprovider.controlloop.ControlLoopEventContext;
import org.onap.policy.controlloop.actorserviceprovider.impl.HttpOperation;
import org.onap.policy.vfc.VfcHealRequest;
import org.onap.policy.vfc.VfcRequest;
import org.onap.policy.vfc.VfcResponse;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
public abstract class VfcOperation extends HttpOperation<VfcResponse> {
- private static final Logger logger = LoggerFactory.getLogger(VfcOperation.class);
-
public static final String FAILED = "FAILED";
public static final String COMPLETE = "COMPLETE";
public static final int VFC_RESPONSE_CODE = 999;
public static final String REQ_PARAM_NM = "requestParameters";
public static final String CONFIG_PARAM_NM = "configurationParameters";
- private final VfcConfig config;
-
/**
- * Number of "get" requests issued so far, on the current operation attempt.
+ * Job ID extracted from the first response.
*/
- @Getter
- private int getCount;
+ private String jobId;
+
/**
* Constructs the object.
*/
public VfcOperation(ControlLoopOperationParams params, HttpConfig config) {
super(params, config, VfcResponse.class);
- this.config = (VfcConfig) config;
+
+ setUsePolling();
}
- /**
- * Subclasses should invoke this before issuing their first HTTP request.
- */
- protected void resetGetCount() {
- getCount = 0;
+ @Override
+ protected void resetPollCount() {
+ super.resetPollCount();
+ jobId = null;
+ }
+
+ @Override
+ protected String getPollingPath() {
+ return super.getPollingPath() + jobId;
}
/**
return startGuardAsync();
}
- /**
- * If the response does not indicate that the request has been completed, then sleep a
- * bit and issue a "get".
- */
@Override
- protected CompletableFuture<OperationOutcome> postProcessResponse(OperationOutcome outcome, String url,
- Response rawResponse, VfcResponse response) {
- // Determine if the request has "completed" and determine if it was successful
+ protected Status detmStatus(Response rawResponse, VfcResponse response) {
if (rawResponse.getStatus() == 200) {
String requestState = getRequestState(response);
if ("finished".equalsIgnoreCase(requestState)) {
- return CompletableFuture
- .completedFuture(setOutcome(outcome, PolicyResult.SUCCESS, rawResponse, response));
+ extractJobId(response);
+ return Status.SUCCESS;
}
if ("error".equalsIgnoreCase(requestState)) {
- return CompletableFuture
- .completedFuture(setOutcome(outcome, PolicyResult.FAILURE, rawResponse, response));
+ extractJobId(response);
+ return Status.FAILURE;
}
}
// still incomplete
- // need a request ID with which to query
- if (response == null || response.getJobId() == null) {
+ // need a job ID with which to query
+ if (jobId == null && !extractJobId(response)) {
throw new IllegalArgumentException("missing job ID in response");
}
- // see if the limit for the number of "gets" has been reached
- if (getCount++ >= getMaxGets()) {
- logger.warn("{}: execeeded 'get' limit {} for {}", getFullName(), getMaxGets(), params.getRequestId());
- setOutcome(outcome, PolicyResult.FAILURE_TIMEOUT);
- outcome.setResponse(response);
- outcome.setMessage(VFC_RESPONSE_CODE + " " + outcome.getMessage());
- return CompletableFuture.completedFuture(outcome);
- }
-
- // sleep and then perform a "get" operation
- Function<Void, CompletableFuture<OperationOutcome>> doGet = unused -> issueGet(outcome, response);
- return sleep(getWaitMsGet(), TimeUnit.MILLISECONDS).thenComposeAsync(doGet);
+ return Status.STILL_WAITING;
}
- /**
- * Issues a "get" request to see if the original request is complete yet.
- *
- * @param outcome outcome to be populated with the response
- * @param response previous response
- * @return a future that can be used to cancel the "get" request or await its response
- */
- private CompletableFuture<OperationOutcome> issueGet(OperationOutcome outcome, VfcResponse response) {
- String path = getPathGet() + response.getJobId();
- String url = getClient().getBaseUrl() + path;
-
- logger.debug("{}: 'get' count {} for {}", getFullName(), getCount, params.getRequestId());
-
- logMessage(EventType.OUT, CommInfrastructure.REST, url, null);
+ private boolean extractJobId(VfcResponse response) {
+ if (response == null || response.getJobId() == null) {
+ return false;
+ }
- return handleResponse(outcome, url, callback -> getClient().get(callback, path, null));
+ jobId = response.getJobId();
+ return true;
}
/**
// set default result and message
setOutcome(outcome, result);
+ int code = (result == PolicyResult.FAILURE_TIMEOUT ? VFC_RESPONSE_CODE : rawResponse.getStatus());
+
outcome.setResponse(response);
- outcome.setMessage(rawResponse.getStatus() + " " + outcome.getMessage());
+ outcome.setMessage(code + " " + outcome.getMessage());
return outcome;
}
return request;
}
-
- // These may be overridden by jUnit tests
-
- /**
- * Gets the wait time, in milliseconds, between "get" requests.
- *
- * @return the wait time, in milliseconds, between "get" requests
- */
- public long getWaitMsGet() {
- return TimeUnit.MILLISECONDS.convert(getWaitSecGet(), TimeUnit.SECONDS);
- }
-
- public int getMaxGets() {
- return config.getMaxGets();
- }
-
- public String getPathGet() {
- return config.getPathGet();
- }
-
- public int getWaitSecGet() {
- return config.getWaitSecGet();
- }
}
+++ /dev/null
-/*-
- * ============LICENSE_START=======================================================
- * ONAP
- * ================================================================================
- * Copyright (C) 2020 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * 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.policy.controlloop.actor.vfc;
-
-import java.util.Map;
-import org.onap.policy.common.parameters.ValidationResult;
-import org.onap.policy.controlloop.actorserviceprovider.Util;
-import org.onap.policy.controlloop.actorserviceprovider.impl.HttpOperation;
-import org.onap.policy.controlloop.actorserviceprovider.impl.HttpOperator;
-import org.onap.policy.controlloop.actorserviceprovider.impl.OperationMaker;
-import org.onap.policy.controlloop.actorserviceprovider.parameters.HttpConfig;
-import org.onap.policy.controlloop.actorserviceprovider.parameters.ParameterValidationRuntimeException;
-
-public class VfcOperator extends HttpOperator {
-
- public VfcOperator(String actorName, String name,
- @SuppressWarnings("rawtypes") OperationMaker<HttpConfig, HttpOperation> operationMaker) {
- super(actorName, name, operationMaker);
- }
-
- @Override
- protected HttpConfig makeConfiguration(Map<String, Object> parameters) {
- VfcParams params = Util.translate(getFullName(), parameters, VfcParams.class);
- ValidationResult result = params.validate(getFullName());
- if (!result.isValid()) {
- throw new ParameterValidationRuntimeException("invalid parameters", result);
- }
-
- return new VfcConfig(getBlockingExecutor(), params, getClientFactory());
- }
-}
+++ /dev/null
-/*-
- * ============LICENSE_START=======================================================
- * ONAP
- * ================================================================================
- * Copyright (C) 2020 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * 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.policy.controlloop.actor.vfc;
-
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-import lombok.experimental.SuperBuilder;
-import org.onap.policy.common.parameters.annotations.Min;
-import org.onap.policy.common.parameters.annotations.NotBlank;
-import org.onap.policy.common.parameters.annotations.NotNull;
-import org.onap.policy.controlloop.actorserviceprovider.parameters.HttpParams;
-
-@NotNull
-@NotBlank
-@Data
-@EqualsAndHashCode(callSuper = true)
-@SuperBuilder(toBuilder = true)
-public class VfcParams extends HttpParams {
-
- /**
- * Path to use for the "get" request.
- */
- private String pathGet;
-
- /**
- * Maximum number of "get" requests permitted, after the initial request, to retrieve
- * the response.
- */
- @Min(0)
- private int maxGets;
-
- /**
- * Time, in seconds, to wait between issuing "get" requests.
- */
- @Min(1)
- private int waitSecGet;
-}
import org.onap.policy.common.endpoints.http.client.HttpClientFactoryInstance;
import org.onap.policy.common.endpoints.http.server.HttpServletServerFactoryInstance;
import org.onap.policy.controlloop.actor.test.BasicHttpOperation;
+import org.onap.policy.controlloop.actorserviceprovider.parameters.HttpPollingConfig;
import org.onap.policy.simulators.Util;
import org.onap.policy.vfc.VfcRequest;
import org.onap.policy.vfc.VfcResponse;
public abstract class BasicVfcOperation extends BasicHttpOperation<VfcRequest> {
- public static final String PATH_GET = "my-path-get/";
- public static final int MAX_GETS = 3;
- public static final int WAIT_SEC_GETS = 20;
+ public static final String POLL_PATH = "my-path-get/";
+ public static final int MAX_POLLS = 3;
+ public static final int POLL_WAIT_SEC = 20;
@Mock
- protected VfcConfig config;
+ protected HttpPollingConfig config;
protected VfcResponse response;
protected void initConfig() {
super.initConfig();
when(config.getClient()).thenReturn(client);
- when(config.getMaxGets()).thenReturn(MAX_GETS);
- when(config.getPathGet()).thenReturn(PATH_GET);
- when(config.getWaitSecGet()).thenReturn(WAIT_SEC_GETS);
+ when(config.getMaxPolls()).thenReturn(MAX_POLLS);
+ when(config.getPollPath()).thenReturn(POLL_PATH);
+ when(config.getPollWaitSec()).thenReturn(POLL_WAIT_SEC);
}
}
import org.junit.Test;
import org.onap.policy.common.endpoints.http.client.HttpClientFactoryInstance;
import org.onap.policy.controlloop.actorserviceprovider.OperationOutcome;
+import org.onap.policy.controlloop.actorserviceprovider.parameters.HttpPollingConfig;
+import org.onap.policy.controlloop.actorserviceprovider.parameters.HttpPollingParams;
import org.onap.policy.controlloop.policy.PolicyResult;
import org.onap.policy.vfc.VfcRequest;
import org.onap.policy.vfc.VfcResponse;
*/
@Test
public void testSuccess() throws Exception {
- VfcParams opParams = VfcParams.builder().clientName(MY_CLIENT).path("ns").pathGet("jobs").maxGets(1).build();
- config = new VfcConfig(blockingExecutor, opParams, HttpClientFactoryInstance.getClientFactory());
+ HttpPollingParams opParams = HttpPollingParams.builder().clientName(MY_CLIENT).path("ns").pollPath("jobs")
+ .maxPolls(1).build();
+ config = new HttpPollingConfig(blockingExecutor, opParams, HttpClientFactoryInstance.getClientFactory());
params = params.toBuilder().retry(0).timeoutSec(5).executor(blockingExecutor).build();
+
restartOper = new Restart(params, config);
outcome = restartOper.start().get();
public void testConstructor() {
CompletableFuture<OperationOutcome> futureRes = restartOper.startOperationAsync(1, outcome);
assertNotNull(futureRes);
- assertEquals(0, restartOper.getGetCount());
+ assertEquals(0, restartOper.getPollCount());
}
@Test
import java.io.IOException;
import java.nio.charset.StandardCharsets;
+import java.util.Arrays;
import java.util.Objects;
import java.util.UUID;
+import java.util.stream.Collectors;
import org.apache.commons.io.IOUtils;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.onap.policy.common.endpoints.http.server.HttpServletServerFactoryInstance;
import org.onap.policy.controlloop.ControlLoopOperation;
import org.onap.policy.controlloop.VirtualControlLoopEvent;
+import org.onap.policy.controlloop.actor.test.BasicActor;
import org.onap.policy.controlloop.policy.Policy;
import org.onap.policy.simulators.Util;
import org.onap.policy.vfc.VfcRequest;
-public class VfcActorServiceProviderTest {
+public class VfcActorServiceProviderTest extends BasicActor {
private static final String DOROTHY_GALE_1939 = "dorothy.gale.1939";
private static final String CQ_RESPONSE_JSON = "aai/AaiCqResponse.json";
HttpServletServerFactoryInstance.getServerFactory().destroy();
}
+ @Test
+ public void testConstructor() {
+ VfcActorServiceProvider prov = new VfcActorServiceProvider();
+ assertEquals(0, prov.getSequenceNumber());
+
+ // verify that it has the operators we expect
+ var expected = Arrays.asList(Restart.NAME).stream().sorted().collect(Collectors.toList());
+ var actual = prov.getOperationNames().stream().sorted().collect(Collectors.toList());
+
+ assertEquals(expected.toString(), actual.toString());
+ }
+
+ @Test
+ public void testActorService() {
+ // verify that it all plugs into the ActorService
+ verifyActorService(VfcActorServiceProvider.NAME, "service.yaml");
+ }
+
@Test
public void testMethods() {
VfcActorServiceProvider sp = new VfcActorServiceProvider();
+++ /dev/null
-/*-
- * ============LICENSE_START=======================================================
- * ONAP
- * ================================================================================
- * Copyright (C) 2020 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * 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.policy.controlloop.actor.vfc;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertSame;
-import static org.mockito.Mockito.when;
-
-import java.util.concurrent.Executor;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.onap.policy.common.endpoints.http.client.HttpClient;
-import org.onap.policy.common.endpoints.http.client.HttpClientFactory;
-
-public class VfcConfigTest {
- private static final String MY_CLIENT = "my-client";
- private static final String MY_PATH = "my-path";
- private static final String GET_PATH = "get-path";
- private static final int TIMEOUT_SEC = 10;
- private static final int MAX_GETS = 20;
- private static final int WAIT_SEC = 30;
-
- @Mock
- private HttpClient client;
- @Mock
- private HttpClientFactory factory;
- @Mock
- private Executor executor;
-
- private VfcParams params;
- private VfcConfig config;
-
- /**
- * Setup.
- *
- * @throws Exception Exception
- */
- @Before
- public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
-
- when(factory.get(MY_CLIENT)).thenReturn(client);
-
- params = VfcParams.builder().maxGets(MAX_GETS).pathGet(GET_PATH).waitSecGet(WAIT_SEC).clientName(MY_CLIENT)
- .path(MY_PATH).timeoutSec(TIMEOUT_SEC).build();
- config = new VfcConfig(executor, params, factory);
- }
-
- @Test
- public void test() {
- assertEquals(GET_PATH + "/", config.getPathGet());
- assertEquals(MAX_GETS, config.getMaxGets());
- assertEquals(WAIT_SEC, config.getWaitSecGet());
-
- // check value from superclass
- assertSame(executor, config.getBlockingExecutor());
- assertSame(client, config.getClient());
-
- // path with trailing "/"
- params = params.toBuilder().pathGet(GET_PATH + "/").build();
- config = new VfcConfig(executor, params, factory);
- assertEquals(GET_PATH + "/", config.getPathGet());
- }
-
-}
package org.onap.policy.controlloop.actor.vfc;
-import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
-import java.util.concurrent.CompletableFuture;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mockito;
-import org.onap.policy.controlloop.actorserviceprovider.OperationOutcome;
-import org.onap.policy.controlloop.policy.PolicyResult;
import org.onap.policy.vfc.VfcResponse;
import org.onap.policy.vfc.VfcResponseDescriptor;
}
@Test
- public void testConstructor_testGetWaitMsGet() {
+ public void testConstructor() {
assertEquals(DEFAULT_ACTOR, oper.getActorName());
assertEquals(DEFAULT_OPERATION, oper.getName());
assertSame(config, oper.getConfig());
- assertEquals(1000 * WAIT_SEC_GETS, oper.getWaitMsGet());
+ assertTrue(oper.isUsePolling());
}
@Test
}
@Test
- public void testResetGetCount() {
- oper.resetGetCount();
- assertEquals(0, oper.getGetCount());
- }
-
- @Test
- public void testPostProcess() throws Exception {
-
- assertThatExceptionOfType(IllegalArgumentException.class).isThrownBy(() -> {
- oper.postProcessResponse(outcome, PATH, rawResponse, response);
- });
-
- response.setResponseDescriptor(new VfcResponseDescriptor());
- response.setJobId("sampleJobId");
-
- // null status
- CompletableFuture<OperationOutcome> future2 = oper.postProcessResponse(outcome, PATH, rawResponse, response);
- assertFalse(future2.isDone());
-
- response.getResponseDescriptor().setStatus("FinisHeD");
- future2 = oper.postProcessResponse(outcome, PATH, rawResponse, response);
- assertTrue(future2.isDone());
- assertSame(outcome, future2.get());
- assertEquals(PolicyResult.SUCCESS, outcome.getResult());
- assertSame(response, outcome.getResponse());
-
- // failed
- response.getResponseDescriptor().setStatus("eRRor");
- future2 = oper.postProcessResponse(outcome, PATH, rawResponse, response);
- assertTrue(future2.isDone());
- assertSame(outcome, future2.get());
- assertEquals(PolicyResult.FAILURE, outcome.getResult());
- assertSame(response, outcome.getResponse());
-
- // unfinished
- response.getResponseDescriptor().setStatus("anything but finished");
- future2 = oper.postProcessResponse(outcome, PATH, rawResponse, response);
- assertFalse(future2.isDone());
+ public void testResetPollCount() {
+ oper.resetPollCount();
+ assertEquals(0, oper.getPollCount());
}
@Test
+++ /dev/null
-/*-
- * ============LICENSE_START=======================================================
- * ONAP
- * ================================================================================
- * Copyright (C) 2020 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * 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.policy.controlloop.actor.vfc;
-
-import static org.assertj.core.api.Assertions.assertThatThrownBy;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Mockito.when;
-
-import java.util.Map;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.onap.policy.common.endpoints.http.client.HttpClient;
-import org.onap.policy.common.endpoints.http.client.HttpClientFactory;
-import org.onap.policy.controlloop.actorserviceprovider.Util;
-import org.onap.policy.controlloop.actorserviceprovider.parameters.ParameterValidationRuntimeException;
-
-public class VfcOperatorTest {
- private static final String ACTOR = "my-actor";
- private static final String OPERATION = "my-name";
- private static final String CLIENT = "my-client";
- private static final String PATH = "/my-path";
- private static final String PATH_GET = "my-path-get/";
- private static final int MAX_GETS = 3;
- private static final int WAIT_SEC_GETS = 20;
- private static final int TIMEOUT = 100;
-
- private VfcOperator oper;
-
- @Mock
- private HttpClient client;
-
- @Mock
- private HttpClientFactory factory;
-
- /**
- * setUp.
- *
- * @throws Exception exception
- */
- @Before
- public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
-
- when(factory.get(CLIENT)).thenReturn(client);
-
- oper = new MyOperator();
-
- VfcParams params = VfcParams.builder().pathGet(PATH_GET).maxGets(MAX_GETS).waitSecGet(WAIT_SEC_GETS)
- .clientName(CLIENT).path(PATH).timeoutSec(TIMEOUT).build();
- Map<String, Object> paramMap = Util.translateToMap(OPERATION, params);
- oper.configure(paramMap);
- }
-
- @Test
- public void testConstructor() {
- assertEquals(ACTOR, oper.getActorName());
- assertEquals(OPERATION, oper.getName());
- assertEquals(ACTOR + "." + OPERATION, oper.getFullName());
- }
-
- @Test
- public void testDoConfigure_testGetters() {
- assertTrue(oper.getCurrentConfig() instanceof VfcConfig);
-
- // test invalid parameters
- Map<String, Object> paramMap2 = Util.translateToMap(OPERATION, VfcParams.builder().build());
- assertThatThrownBy(() -> oper.configure(paramMap2)).isInstanceOf(ParameterValidationRuntimeException.class);
- }
-
- private class MyOperator extends VfcOperator {
-
- public MyOperator() {
- super(ACTOR, OPERATION, null);
- }
-
- @Override
- protected HttpClientFactory getClientFactory() {
- return factory;
- }
- }
-}
+++ /dev/null
-/*-
- * ============LICENSE_START=======================================================
- * ONAP
- * ================================================================================
- * Copyright (C) 2020 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * 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.policy.controlloop.actor.vfc;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-import java.util.function.Function;
-import org.junit.Before;
-import org.junit.Test;
-import org.onap.policy.common.parameters.ValidationResult;
-import org.onap.policy.controlloop.actor.vfc.VfcParams.VfcParamsBuilder;
-import org.onap.policy.controlloop.actorserviceprovider.parameters.HttpParams.HttpParamsBuilder;
-
-public class VfcParamsTest {
- private static final String CONTAINER = "my-container";
- private static final String CLIENT = "my-client";
- private static final String PATH = "my-path";
- private static final String PATH_GET = "my-path-get";
- private static final int MAX_GETS = 3;
- private static final int WAIT_SEC_GETS = 20;
- private static final int TIMEOUT = 10;
-
- private VfcParams params;
-
- @Before
- public void setUp() throws Exception {
- params = VfcParams.builder().pathGet(PATH_GET).maxGets(MAX_GETS).waitSecGet(WAIT_SEC_GETS).clientName(CLIENT)
- .path(PATH).timeoutSec(TIMEOUT).build();
- }
-
- @Test
- public void testValidate() {
- assertTrue(params.validate(CONTAINER).isValid());
-
- testValidateField("pathGet", "null", bldr -> bldr.pathGet(null));
- testValidateField("maxGets", "minimum", bldr -> bldr.maxGets(-1));
- testValidateField("waitSecGet", "minimum", bldr -> bldr.waitSecGet(-1));
-
- // validate one of the superclass fields
- testValidateField("clientName", "null", bldr -> bldr.clientName(null));
-
- // check edge cases
- assertTrue(params.toBuilder().maxGets(0).build().validate(CONTAINER).isValid());
- assertFalse(params.toBuilder().waitSecGet(0).build().validate(CONTAINER).isValid());
- assertTrue(params.toBuilder().waitSecGet(1).build().validate(CONTAINER).isValid());
- }
-
- @Test
- public void testBuilder_testToBuilder() {
- assertEquals(CLIENT, params.getClientName());
-
- assertEquals(PATH_GET, params.getPathGet());
- assertEquals(MAX_GETS, params.getMaxGets());
- assertEquals(WAIT_SEC_GETS, params.getWaitSecGet());
-
- assertEquals(params, params.toBuilder().build());
- }
-
- private void testValidateField(String fieldName, String expected,
- @SuppressWarnings("rawtypes") Function<VfcParamsBuilder, HttpParamsBuilder> makeInvalid) {
-
- // original params should be valid
- ValidationResult result = params.validate(CONTAINER);
- assertTrue(fieldName, result.isValid());
-
- // make invalid params
- result = makeInvalid.apply(params.toBuilder()).build().validate(CONTAINER);
- assertFalse(fieldName, result.isValid());
- assertThat(result.getResult()).contains(fieldName).contains(expected);
- }
-
-}
--- /dev/null
+#
+# ============LICENSE_START======================================================
+# ONAP
+# ===============================================================================
+# Copyright (C) 2020 AT&T Intellectual Property. All rights reserved.
+# ===============================================================================
+# 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========================================================
+#
+httpClients:
+- clientName: my-client
+ hostname: localhost
+ port: 80
+ basePath: base-url/
+ managed: true
+actors:
+ VFC:
+ clientName: my-client
+ pollPath: jobs
+ pollWaitSec: 20
+ maxPolls: 20
+ operations:
+ Restart:
+ path: ns
+ timeoutSec: 60
import java.util.function.Function;
import org.onap.policy.controlloop.actorserviceprovider.Operator;
import org.onap.policy.controlloop.actorserviceprovider.Util;
+import org.onap.policy.controlloop.actorserviceprovider.parameters.ActorParams;
import org.onap.policy.controlloop.actorserviceprovider.parameters.ParameterValidationRuntimeException;
import org.onap.policy.controlloop.actorserviceprovider.spi.Actor;
import org.slf4j.Logger;
/**
* Extracts the operator parameters from the actor parameters, for a given operator.
- * This method assumes each operation has its own set of parameters.
+ * This method translates the parameters to an {@link ActorParams} and then creates a function
+ * that will extract operator-specific parameters.
*
* @param actorParameters actor parameters
* @return a function to extract the operator parameters from the actor parameters.
* the given operation name
*/
protected Function<String, Map<String, Object>> makeOperatorParameters(Map<String, Object> actorParameters) {
+ String actorName = getName();
- return operName -> Util.translateToMap(getName() + "." + operName, actorParameters.get(operName));
+ // @formatter:off
+ return Util.translate(actorName, actorParameters, ActorParams.class)
+ .doValidation(actorName)
+ .makeOperationParameters(actorName);
+ // @formatter:on
}
/**
import java.util.Arrays;
import java.util.List;
import java.util.Map;
-import lombok.Getter;
import org.onap.policy.common.parameters.ValidationResult;
-import org.onap.policy.controlloop.actorserviceprovider.Operation;
import org.onap.policy.controlloop.actorserviceprovider.Util;
import org.onap.policy.controlloop.actorserviceprovider.parameters.BidirectionalTopicConfig;
import org.onap.policy.controlloop.actorserviceprovider.parameters.BidirectionalTopicParams;
-import org.onap.policy.controlloop.actorserviceprovider.parameters.ControlLoopOperationParams;
-import org.onap.policy.controlloop.actorserviceprovider.parameters.HttpParams;
import org.onap.policy.controlloop.actorserviceprovider.parameters.ParameterValidationRuntimeException;
import org.onap.policy.controlloop.actorserviceprovider.topic.BidirectionalTopicHandler;
import org.onap.policy.controlloop.actorserviceprovider.topic.BidirectionalTopicManager;
* Operator that uses a bidirectional topic. Topic operators may share a
* {@link BidirectionalTopicHandler}.
*/
-public class BidirectionalTopicOperator extends OperatorPartial {
-
- /**
- * Function to make an operation.
- */
- @SuppressWarnings("rawtypes")
- private final OperationMaker<BidirectionalTopicConfig, BidirectionalTopicOperation> operationMaker;
+public class BidirectionalTopicOperator
+ extends TypedOperator<BidirectionalTopicConfig, BidirectionalTopicOperation<?, ?>> {
/**
* Manager from which to get the topic handlers.
*/
private final List<SelectorKey> selectorKeys;
- /**
- * Current configuration. This is set by {@link #doConfigure(Map)}.
- */
- @Getter
- private BidirectionalTopicConfig currentConfig;
-
/**
* Constructs the object.
* @param selectorKeys keys used to extract the fields used to select responses for
* this operator
*/
- // @formatter:off
public BidirectionalTopicOperator(String actorName, String name, BidirectionalTopicManager topicManager,
List<SelectorKey> selectorKeys,
- @SuppressWarnings("rawtypes") OperationMaker<BidirectionalTopicConfig, BidirectionalTopicOperation>
- operationMaker) {
- // @formatter:on
+ OperationMaker<BidirectionalTopicConfig, BidirectionalTopicOperation<?, ?>> operationMaker) {
- super(actorName, name);
+ super(actorName, name, operationMaker);
this.topicManager = topicManager;
this.selectorKeys = selectorKeys;
- this.operationMaker = operationMaker;
}
/**
* @param selectorKeys keys used to extract the fields used to select responses for
* this operator
*/
- // @formatter:off
public BidirectionalTopicOperator(String actorName, String name, BidirectionalTopicManager topicManager,
- @SuppressWarnings("rawtypes") OperationMaker<BidirectionalTopicConfig, BidirectionalTopicOperation>
- operationMaker,
+ OperationMaker<BidirectionalTopicConfig, BidirectionalTopicOperation<?, ?>> operationMaker,
SelectorKey... selectorKeys) {
- // @formatter:on
this(actorName, name, topicManager, Arrays.asList(selectorKeys), operationMaker);
}
- /**
- * Translates the parameters to an {@link HttpParams} and then extracts the relevant
- * values.
- */
- @Override
- protected void doConfigure(Map<String, Object> parameters) {
- currentConfig = makeConfiguration(parameters);
- }
-
/**
* Makes a new configuration using the specified parameters.
*
return new BidirectionalTopicConfig(getBlockingExecutor(), params, topicManager, selectorKeys);
}
-
- @Override
- public Operation buildOperation(ControlLoopOperationParams params) {
- if (operationMaker == null) {
- throw new UnsupportedOperationException("cannot make operation for " + getFullName());
- }
-
- verifyRunning();
-
- return operationMaker.apply(params, currentConfig);
- }
}
public class HttpActor<P extends HttpActorParams> extends ActorImpl {
/**
- * Class of parameters.
+ * Class of Actor parameters.
*/
private final Class<P> paramsClass;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import javax.ws.rs.client.InvocationCallback;
import javax.ws.rs.core.Response;
import org.onap.policy.controlloop.actorserviceprovider.parameters.ControlLoopOperationParams;
import org.onap.policy.controlloop.actorserviceprovider.parameters.HttpConfig;
import org.onap.policy.controlloop.actorserviceprovider.parameters.HttpParams;
+import org.onap.policy.controlloop.actorserviceprovider.parameters.HttpPollingConfig;
import org.onap.policy.controlloop.actorserviceprovider.pipeline.PipelineControllerFuture;
import org.onap.policy.controlloop.policy.PolicyResult;
import org.slf4j.Logger;
public abstract class HttpOperation<T> extends OperationPartial {
private static final Logger logger = LoggerFactory.getLogger(HttpOperation.class);
+ /**
+ * Response status.
+ */
+ public enum Status {
+ SUCCESS, FAILURE, STILL_WAITING
+ }
+
/**
* Configuration for this operation.
*/
*/
private final Class<T> responseClass;
+ /**
+ * {@code True} to use polling, {@code false} otherwise.
+ */
+ @Getter
+ private boolean usePolling;
+
+ /**
+ * Number of polls issued so far, on the current operation attempt.
+ */
+ @Getter
+ private int pollCount;
+
/**
* Constructs the object.
this.responseClass = clazz;
}
+ /**
+ * Indicates that polling should be used.
+ */
+ protected void setUsePolling() {
+ if (!(config instanceof HttpPollingConfig)) {
+ throw new IllegalStateException("cannot poll without polling parameters");
+ }
+
+ usePolling = true;
+ }
+
public HttpClient getClient() {
return config.getClient();
}
return (getClient().getBaseUrl() + getPath());
}
+ /**
+ * Resets the polling count
+ *
+ * <p/>
+ * Note: This should be invoked at the start of each operation (i.e., in
+ * {@link #startOperationAsync(int, OperationOutcome)}.
+ */
+ protected void resetPollCount() {
+ pollCount = 0;
+ }
+
/**
* Arranges to handle a response.
*
protected CompletableFuture<OperationOutcome> postProcessResponse(OperationOutcome outcome, String url,
Response rawResponse, T response) {
- return CompletableFuture.completedFuture(outcome);
+ if (!usePolling) {
+ // doesn't use polling - just return the completed future
+ return CompletableFuture.completedFuture(outcome);
+ }
+
+ HttpPollingConfig cfg = (HttpPollingConfig) config;
+
+ switch (detmStatus(rawResponse, response)) {
+ case SUCCESS:
+ logger.info("{}.{} request succeeded for {}", params.getActor(), params.getOperation(),
+ params.getRequestId());
+ return CompletableFuture
+ .completedFuture(setOutcome(outcome, PolicyResult.SUCCESS, rawResponse, response));
+
+ case FAILURE:
+ logger.info("{}.{} request failed for {}", params.getActor(), params.getOperation(),
+ params.getRequestId());
+ return CompletableFuture
+ .completedFuture(setOutcome(outcome, PolicyResult.FAILURE, rawResponse, response));
+
+ case STILL_WAITING:
+ default:
+ logger.info("{}.{} request incomplete for {}", params.getActor(), params.getOperation(),
+ params.getRequestId());
+ break;
+ }
+
+ // still incomplete
+
+ // see if the limit for the number of polls has been reached
+ if (pollCount++ >= cfg.getMaxPolls()) {
+ logger.warn("{}: execeeded 'poll' limit {} for {}", getFullName(), cfg.getMaxPolls(),
+ params.getRequestId());
+ setOutcome(outcome, PolicyResult.FAILURE_TIMEOUT);
+ return CompletableFuture.completedFuture(outcome);
+ }
+
+ // sleep and then poll
+ Function<Void, CompletableFuture<OperationOutcome>> doPoll = unused -> issuePoll(outcome);
+ return sleep(getPollWaitMs(), TimeUnit.MILLISECONDS).thenComposeAsync(doPoll);
+ }
+
+ /**
+ * Polls to see if the original request is complete. This method polls using an HTTP
+ * "get" request whose URL is constructed by appending the extracted "poll ID" to the
+ * poll path from the configuration data.
+ *
+ * @param outcome outcome to be populated with the response
+ * @return a future that can be used to cancel the poll or await its response
+ */
+ protected CompletableFuture<OperationOutcome> issuePoll(OperationOutcome outcome) {
+ String path = getPollingPath();
+ String url = getClient().getBaseUrl() + path;
+
+ logger.debug("{}: 'poll' count {} for {}", getFullName(), pollCount, params.getRequestId());
+
+ logMessage(EventType.OUT, CommInfrastructure.REST, url, null);
+
+ return handleResponse(outcome, url, callback -> getClient().get(callback, path, null));
+ }
+
+ /**
+ * Determines the status of the response. This particular method simply throws an
+ * exception.
+ *
+ * @param rawResponse raw response
+ * @param response decoded response
+ * @return the status of the response
+ */
+ protected Status detmStatus(Response rawResponse, T response) {
+ throw new UnsupportedOperationException("cannot determine response status");
+ }
+
+ /**
+ * Gets the URL to use when polling. Typically, this is some unique ID appended to the
+ * polling path found within the configuration data. This particular method simply
+ * returns the polling path from the configuration data.
+ *
+ * @return the URL to use when polling
+ */
+ protected String getPollingPath() {
+ return ((HttpPollingConfig) config).getPollPath();
}
/**
NetLoggerUtil.log(direction, infra, sink, json);
return json;
}
+
+ // these may be overridden by junit tests
+
+ protected long getPollWaitMs() {
+ HttpPollingConfig cfg = (HttpPollingConfig) config;
+
+ return TimeUnit.MILLISECONDS.convert(cfg.getPollWaitSec(), TimeUnit.SECONDS);
+ }
}
package org.onap.policy.controlloop.actorserviceprovider.impl;
import java.util.Map;
-import lombok.Getter;
import org.onap.policy.common.endpoints.http.client.HttpClientFactory;
import org.onap.policy.common.endpoints.http.client.HttpClientFactoryInstance;
import org.onap.policy.common.parameters.ValidationResult;
-import org.onap.policy.controlloop.actorserviceprovider.Operation;
import org.onap.policy.controlloop.actorserviceprovider.Util;
-import org.onap.policy.controlloop.actorserviceprovider.parameters.ControlLoopOperationParams;
import org.onap.policy.controlloop.actorserviceprovider.parameters.HttpConfig;
import org.onap.policy.controlloop.actorserviceprovider.parameters.HttpParams;
import org.onap.policy.controlloop.actorserviceprovider.parameters.ParameterValidationRuntimeException;
/**
* Operator that uses HTTP. The operator's parameters must be an {@link HttpParams}.
*/
-public class HttpOperator extends OperatorPartial {
-
- /**
- * Function to make an operation.
- */
- @SuppressWarnings("rawtypes")
- private final OperationMaker<HttpConfig, HttpOperation> operationMaker;
-
- /**
- * Current configuration. This is set by {@link #doConfigure(Map)}.
- */
- @Getter
- private HttpConfig currentConfig;
-
+public class HttpOperator extends TypedOperator<HttpConfig,HttpOperation<?>> {
/**
* Constructs the object.
* @param operationMaker function to make an operation
*/
public HttpOperator(String actorName, String name,
- @SuppressWarnings("rawtypes") OperationMaker<HttpConfig, HttpOperation> operationMaker) {
- super(actorName, name);
- this.operationMaker = operationMaker;
- }
-
- /**
- * Translates the parameters to an {@link HttpParams} and then extracts the relevant
- * values.
- */
- @Override
- protected void doConfigure(Map<String, Object> parameters) {
- currentConfig = makeConfiguration(parameters);
+ OperationMaker<HttpConfig, HttpOperation<?>> operationMaker) {
+ super(actorName, name, operationMaker);
}
/**
return new HttpConfig(getBlockingExecutor(), params, getClientFactory());
}
- @Override
- public Operation buildOperation(ControlLoopOperationParams params) {
- if (operationMaker == null) {
- throw new UnsupportedOperationException("cannot make operation for " + getFullName());
- }
-
- verifyRunning();
-
- return operationMaker.apply(params, currentConfig);
- }
-
// these may be overridden by junit tests
protected HttpClientFactory getClientFactory() {
--- /dev/null
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP
+ * ================================================================================
+ * Copyright (C) 2020 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * 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.policy.controlloop.actorserviceprovider.impl;
+
+import java.util.Map;
+import org.onap.policy.common.endpoints.http.client.HttpClientFactory;
+import org.onap.policy.common.endpoints.http.client.HttpClientFactoryInstance;
+import org.onap.policy.common.parameters.ValidationResult;
+import org.onap.policy.controlloop.actorserviceprovider.Util;
+import org.onap.policy.controlloop.actorserviceprovider.parameters.HttpPollingConfig;
+import org.onap.policy.controlloop.actorserviceprovider.parameters.HttpPollingParams;
+import org.onap.policy.controlloop.actorserviceprovider.parameters.ParameterValidationRuntimeException;
+
+/**
+ * Operator that uses HTTP and polls for the request completion status. The operator's
+ * parameters must be an {@link HttpPollingParams}.
+ */
+public class HttpPollingOperator extends TypedOperator<HttpPollingConfig, HttpOperation<?>> {
+
+ /**
+ * Constructs the object.
+ *
+ * @param actorName name of the actor with which this operator is associated
+ * @param name operation name
+ */
+ protected HttpPollingOperator(String actorName, String name) {
+ this(actorName, name, null);
+ }
+
+ /**
+ * Constructs the object.
+ *
+ * @param actorName name of the actor with which this operator is associated
+ * @param name operation name
+ * @param operationMaker function to make an operation
+ */
+ public HttpPollingOperator(String actorName, String name,
+ OperationMaker<HttpPollingConfig, HttpOperation<?>> operationMaker) {
+ super(actorName, name, operationMaker);
+ }
+
+ /**
+ * Makes a new configuration using the specified parameters.
+ *
+ * @param parameters operator parameters
+ * @return a new configuration
+ */
+ protected HttpPollingConfig makeConfiguration(Map<String, Object> parameters) {
+ HttpPollingParams params = Util.translate(getFullName(), parameters, HttpPollingParams.class);
+ ValidationResult result = params.validate(getFullName());
+ if (!result.isValid()) {
+ throw new ParameterValidationRuntimeException("invalid parameters", result);
+ }
+
+ return new HttpPollingConfig(getBlockingExecutor(), params, getClientFactory());
+ }
+
+ // these may be overridden by junit tests
+
+ protected HttpClientFactory getClientFactory() {
+ return HttpClientFactoryInstance.getClientFactory();
+ }
+}
--- /dev/null
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP
+ * ================================================================================
+ * Copyright (C) 2020 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * 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.policy.controlloop.actorserviceprovider.impl;
+
+import java.util.Map;
+import lombok.Getter;
+import org.onap.policy.controlloop.actorserviceprovider.Operation;
+import org.onap.policy.controlloop.actorserviceprovider.parameters.ControlLoopOperationParams;
+import org.onap.policy.controlloop.actorserviceprovider.parameters.HttpParams;
+
+/**
+ * Operator with typed parameter information.
+ *
+ * @param <C> type of configuration data
+ * @param <T> type of operation that the operator creates
+ */
+public abstract class TypedOperator<C, T extends Operation> extends OperatorPartial {
+
+ /**
+ * Function to make an operation.
+ */
+ private final OperationMaker<C, T> operationMaker;
+
+ /**
+ * Current configuration. This is set by {@link #doConfigure(Map)}.
+ */
+ @Getter
+ private C currentConfig;
+
+
+ /**
+ * Constructs the object.
+ *
+ * @param actorName name of the actor with which this operator is associated
+ * @param name operation name
+ */
+ protected TypedOperator(String actorName, String name) {
+ this(actorName, name, null);
+ }
+
+ /**
+ * Constructs the object.
+ *
+ * @param actorName name of the actor with which this operator is associated
+ * @param name operation name
+ * @param operationMaker function to make an operation
+ */
+ public TypedOperator(String actorName, String name, OperationMaker<C, T> operationMaker) {
+ super(actorName, name);
+ this.operationMaker = operationMaker;
+ }
+
+ /**
+ * Translates the parameters, saving the relevant configuration data.
+ */
+ @Override
+ protected void doConfigure(Map<String, Object> parameters) {
+ currentConfig = makeConfiguration(parameters);
+ }
+
+ /**
+ * Makes a new configuration using the specified parameters.
+ *
+ * @param parameters operator parameters
+ * @return a new configuration
+ */
+ protected abstract C makeConfiguration(Map<String, Object> parameters);
+
+ @Override
+ public T buildOperation(ControlLoopOperationParams params) {
+ if (operationMaker == null) {
+ throw new UnsupportedOperationException("cannot make operation for " + getFullName());
+ }
+
+ verifyRunning();
+
+ return operationMaker.apply(params, currentConfig);
+ }
+}
@Getter
@Setter
@EqualsAndHashCode
-public class CommonActorParams {
+public class ActorParams {
/**
* Name of the "operations" field contained within actor parameters.
*/
* @return "this"
* @throws IllegalArgumentException if the parameters are invalid
*/
- public CommonActorParams doValidation(String name) {
+ public ActorParams doValidation(String name) {
ValidationResult result = validate(name);
if (!result.isValid()) {
throw new ParameterValidationRuntimeException("invalid parameters", result);
@Getter
@Setter
@EqualsAndHashCode(callSuper = true)
-public class BidirectionalTopicActorParams extends CommonActorParams {
+public class BidirectionalTopicActorParams extends ActorParams {
/*
* Optional, default values that are used if missing from the operation-specific
@Getter
@Setter
@EqualsAndHashCode(callSuper = true)
-public class HttpActorParams extends CommonActorParams {
+public class HttpActorParams extends ActorParams {
/*
* Optional, default values that are used if missing from the operation-specific
* ============LICENSE_END=========================================================
*/
-package org.onap.policy.controlloop.actor.so;
+package org.onap.policy.controlloop.actorserviceprovider.parameters;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import org.onap.policy.common.parameters.annotations.Min;
import org.onap.policy.controlloop.actorserviceprovider.parameters.HttpActorParams;
+/**
+ * Parameters used by Actors that, after issuing an HTTP request, must poll the target
+ * server to determine the request completion status.
+ */
@Getter
@Setter
@EqualsAndHashCode(callSuper = true)
-public class SoActorParams extends HttpActorParams {
+public class HttpPollingActorParams extends HttpActorParams {
/*
* Optional, default values that are used if missing from the operation-specific
*/
/**
- * Path to use for the "get" request.
+ * Path to use when polling for request completion.
*/
- private String pathGet = "/orchestrationRequests/v5/";
+ private String pollPath;
/**
- * Maximum number of "get" requests permitted, after the initial request, to retrieve
- * the response.
+ * Maximum number of times to poll to retrieve the response.
*/
@Min(0)
- private int maxGets = 20;
+ private int maxPolls = 3;
/**
- * Time, in seconds, to wait between issuing "get" requests.
+ * Time, in seconds, to wait between polling.
*/
@Min(1)
- private int waitSecGet = 20;
+ private int pollWaitSec = 20;
}
* ============LICENSE_END=========================================================
*/
-package org.onap.policy.controlloop.actor.so;
+package org.onap.policy.controlloop.actorserviceprovider.parameters;
import java.util.concurrent.Executor;
import lombok.Getter;
import org.onap.policy.common.endpoints.http.client.HttpClient;
import org.onap.policy.common.endpoints.http.client.HttpClientFactory;
-import org.onap.policy.controlloop.actorserviceprovider.parameters.HttpConfig;
+/**
+ * Configuration for HTTP Operators that, after issuing a request, must poll the target
+ * server to determine the request completion status.
+ */
@Getter
-public class SoConfig extends HttpConfig {
+public class HttpPollingConfig extends HttpConfig {
/**
- * Path to use for the "get" request. A trailing "/" is added, if it is missing.
+ * Path to use when polling for request completion. A trailing "/" is added, if it is
+ * missing.
*/
- private String pathGet;
+ private String pollPath;
/**
- * Maximum number of "get" requests permitted, after the initial request, to retrieve
- * the response.
+ * Maximum number of times to poll to retrieve the response.
*/
- private int maxGets;
+ private int maxPolls;
/**
- * Time, in seconds, to wait between issuing "get" requests.
+ * Time, in seconds, to wait between polling.
*/
- private int waitSecGet;
+ private int pollWaitSec;
/**
* @param params operator parameters
* @param clientFactory factory from which to obtain the {@link HttpClient}
*/
- public SoConfig(Executor blockingExecutor, SoParams params, HttpClientFactory clientFactory) {
+ public HttpPollingConfig(Executor blockingExecutor, HttpPollingParams params, HttpClientFactory clientFactory) {
super(blockingExecutor, params, clientFactory);
- this.pathGet = params.getPathGet() + (params.getPathGet().endsWith("/") ? "" : "/");
- this.maxGets = params.getMaxGets();
- this.waitSecGet = params.getWaitSecGet();
+ this.pollPath = params.getPollPath() + (params.getPollPath().endsWith("/") ? "" : "/");
+ this.maxPolls = params.getMaxPolls();
+ this.pollWaitSec = params.getPollWaitSec();
}
}
* ============LICENSE_END=========================================================
*/
-package org.onap.policy.controlloop.actor.so;
+package org.onap.policy.controlloop.actorserviceprovider.parameters;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.onap.policy.common.parameters.annotations.NotNull;
import org.onap.policy.controlloop.actorserviceprovider.parameters.HttpParams;
+/**
+ * Parameters used by Operators that, after issuing an HTTP request, must poll the target
+ * server to determine the request completion status.
+ */
@NotNull
@NotBlank
@Data
@EqualsAndHashCode(callSuper = true)
@SuperBuilder(toBuilder = true)
-public class SoParams extends HttpParams {
+public class HttpPollingParams extends HttpParams {
/**
- * Path to use for the "get" request.
+ * Path to use when polling for request completion.
*/
- private String pathGet;
+ private String pollPath;
/**
- * Maximum number of "get" requests permitted, after the initial request, to retrieve
- * the response.
+ * Maximum number of times to poll to retrieve the response.
*/
@Min(0)
- private int maxGets;
+ private int maxPolls;
/**
- * Time, in seconds, to wait between issuing "get" requests.
+ * Time, in seconds, to wait between polling.
*/
@Min(1)
- private int waitSecGet;
+ private int pollWaitSec;
}
import java.util.Arrays;
import java.util.Collection;
+import java.util.Collections;
import java.util.Iterator;
import java.util.Map;
import java.util.TreeMap;
import org.onap.policy.common.parameters.ObjectValidationResult;
import org.onap.policy.common.parameters.ValidationStatus;
import org.onap.policy.controlloop.actorserviceprovider.impl.ActorImpl;
+import org.onap.policy.controlloop.actorserviceprovider.parameters.ActorParams;
import org.onap.policy.controlloop.actorserviceprovider.parameters.ParameterValidationRuntimeException;
import org.onap.policy.controlloop.actorserviceprovider.spi.Actor;
actor3 = spy(new ActorImpl(ACTOR3));
actor4 = spy(new ActorImpl(ACTOR4));
- sub1 = Map.of("sub A", "value A");
- sub2 = Map.of("sub B", "value B");
- sub3 = Map.of("sub C", "value C");
- sub4 = Map.of("sub D", "value D");
+ sub1 = Map.of("sub A", "value A", ActorParams.OPERATIONS_FIELD, Collections.emptyMap());
+ sub2 = Map.of("sub B", "value B", ActorParams.OPERATIONS_FIELD, Collections.emptyMap());
+ sub3 = Map.of("sub C", "value C", ActorParams.OPERATIONS_FIELD, Collections.emptyMap());
+ sub4 = Map.of("sub D", "value D", ActorParams.OPERATIONS_FIELD, Collections.emptyMap());
params = Map.of(ACTOR1, sub1, ACTOR2, sub2, ACTOR3, sub3, ACTOR4, sub4);
import java.util.Iterator;
import java.util.Map;
-import java.util.TreeMap;
import java.util.stream.Collectors;
import org.junit.Before;
import org.junit.Test;
import org.onap.policy.common.parameters.ValidationStatus;
import org.onap.policy.controlloop.actorserviceprovider.Operation;
import org.onap.policy.controlloop.actorserviceprovider.Operator;
+import org.onap.policy.controlloop.actorserviceprovider.parameters.ActorParams;
import org.onap.policy.controlloop.actorserviceprovider.parameters.ControlLoopOperationParams;
import org.onap.policy.controlloop.actorserviceprovider.parameters.ParameterValidationRuntimeException;
sub3 = Map.of("sub C", "value C");
sub4 = Map.of("sub D", "value D");
- params = Map.of(OPER1, sub1, OPER2, sub2, OPER3, sub3, OPER4, sub4);
+ params = Map.of(ActorParams.OPERATIONS_FIELD, Map.of(OPER1, sub1, OPER2, sub2, OPER3, sub3, OPER4, sub4));
actor = makeActor(oper1, oper2, oper3, oper4);
}
*/
@Test
public void testDoConfigureConfigure() {
- // need mutable parameters
- params = new TreeMap<>(params);
-
// configure one operator
oper1.configure(sub1);
// configure another and remove its parameters
oper2.configure(sub2);
- params.remove(OPER2);
+ params = Map.of(ActorParams.OPERATIONS_FIELD, Map.of(OPER1, sub1, OPER3, sub3, OPER4, sub4));
// create a new, unconfigured actor
Operator oper5 = spy(new MyOper("UNCONFIGURED"));
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
-import org.onap.policy.controlloop.actorserviceprovider.Operation;
import org.onap.policy.controlloop.actorserviceprovider.Util;
import org.onap.policy.controlloop.actorserviceprovider.parameters.BidirectionalTopicConfig;
import org.onap.policy.controlloop.actorserviceprovider.parameters.BidirectionalTopicParams;
AtomicReference<BidirectionalTopicConfig> configRef = new AtomicReference<>();
// @formatter:off
- @SuppressWarnings("rawtypes")
- OperationMaker<BidirectionalTopicConfig, BidirectionalTopicOperation> maker =
+ OperationMaker<BidirectionalTopicConfig, BidirectionalTopicOperation<?,?>> maker =
(params, config) -> {
paramsRef.set(params);
configRef.set(config);
}
@Override
- public Operation buildOperation(ControlLoopOperationParams params) {
+ public BidirectionalTopicOperation<?,?> buildOperation(ControlLoopOperationParams params) {
return null;
}
}
--- /dev/null
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP
+ * ================================================================================
+ * Copyright (C) 2020 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * 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.policy.controlloop.actorserviceprovider.impl;
+
+import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ForkJoinPool;
+import java.util.concurrent.TimeUnit;
+import javax.ws.rs.client.InvocationCallback;
+import javax.ws.rs.core.Response;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.mockito.stubbing.Answer;
+import org.onap.policy.common.endpoints.http.client.HttpClient;
+import org.onap.policy.controlloop.actorserviceprovider.OperationOutcome;
+import org.onap.policy.controlloop.actorserviceprovider.parameters.ControlLoopOperationParams;
+import org.onap.policy.controlloop.actorserviceprovider.parameters.HttpConfig;
+import org.onap.policy.controlloop.actorserviceprovider.parameters.HttpPollingConfig;
+import org.onap.policy.controlloop.policy.PolicyResult;
+
+/**
+ * Tests HttpOperation when polling is enabled.
+ */
+public class HttpPollingOperationTest {
+ private static final String BASE_URI = "http://my-host:6969/base-uri/";
+ private static final String MY_PATH = "my-path";
+ private static final String FULL_PATH = BASE_URI + MY_PATH;
+ private static final int MAX_POLLS = 3;
+ private static final int POLL_WAIT_SEC = 20;
+ private static final String POLL_PATH = "my-poll-path";
+ private static final String MY_ACTOR = "my-actor";
+ private static final String MY_OPERATION = "my-operation";
+ private static final String MY_RESPONSE = "my-response";
+ private static final int RESPONSE_ACCEPT = 100;
+ private static final int RESPONSE_SUCCESS = 200;
+ private static final int RESPONSE_FAILURE = 500;
+
+ @Mock
+ private HttpPollingConfig config;
+ @Mock
+ private HttpClient client;
+ @Mock
+ private Response rawResponse;
+
+ protected ControlLoopOperationParams params;
+ private String response;
+ private OperationOutcome outcome;
+
+ private HttpOperation<String> oper;
+
+ /**
+ * Sets up.
+ */
+ @Before
+ public void setUp() throws Exception {
+ MockitoAnnotations.initMocks(this);
+
+ when(client.getBaseUrl()).thenReturn(BASE_URI);
+
+ when(config.getClient()).thenReturn(client);
+ when(config.getPath()).thenReturn(MY_PATH);
+ when(config.getMaxPolls()).thenReturn(MAX_POLLS);
+ when(config.getPollPath()).thenReturn(POLL_PATH);
+ when(config.getPollWaitSec()).thenReturn(POLL_WAIT_SEC);
+
+ response = MY_RESPONSE;
+
+ when(rawResponse.getStatus()).thenReturn(RESPONSE_SUCCESS);
+ when(rawResponse.readEntity(String.class)).thenReturn(response);
+
+ params = ControlLoopOperationParams.builder().actor(MY_ACTOR).operation(MY_OPERATION).build();
+ outcome = params.makeOutcome();
+
+ oper = new MyOper(params, config);
+ }
+
+ @Test
+ public void testConstructor_testGetWaitMsGet() {
+ assertEquals(MY_ACTOR, oper.getActorName());
+ assertEquals(MY_OPERATION, oper.getName());
+ assertSame(config, oper.getConfig());
+ assertEquals(1000 * POLL_WAIT_SEC, oper.getPollWaitMs());
+ }
+
+ @Test
+ public void testSetUsePollExceptions() {
+ // should be no exception
+ oper.setUsePolling();
+
+ // should throw an exception if we pass a plain HttpConfig
+ HttpConfig config2 = mock(HttpConfig.class);
+ when(config2.getClient()).thenReturn(client);
+ when(config2.getPath()).thenReturn(MY_PATH);
+
+ assertThatIllegalStateException().isThrownBy(() -> new MyOper(params, config2).setUsePolling());
+ }
+
+ @Test
+ public void testPostProcess() throws Exception {
+ // completed
+ oper.generateSubRequestId(2);
+ CompletableFuture<OperationOutcome> future2 =
+ oper.postProcessResponse(outcome, FULL_PATH, rawResponse, response);
+ assertTrue(future2.isDone());
+ assertSame(outcome, future2.get());
+ assertEquals(PolicyResult.SUCCESS, outcome.getResult());
+ assertNotNull(oper.getSubRequestId());
+ assertSame(response, outcome.getResponse());
+
+ // failed
+ oper.generateSubRequestId(2);
+ when(rawResponse.getStatus()).thenReturn(RESPONSE_FAILURE);
+ future2 = oper.postProcessResponse(outcome, FULL_PATH, rawResponse, response);
+ assertTrue(future2.isDone());
+ assertSame(outcome, future2.get());
+ assertEquals(PolicyResult.FAILURE, outcome.getResult());
+ assertNotNull(oper.getSubRequestId());
+ assertSame(response, outcome.getResponse());
+ }
+
+ /**
+ * Tests postProcess() when the poll is repeated a couple of times.
+ */
+ @Test
+ public void testPostProcessRepeated_testResetGetCount() throws Exception {
+ /*
+ * Two accepts and then a success - should result in two polls.
+ */
+ when(rawResponse.getStatus()).thenReturn(RESPONSE_ACCEPT, RESPONSE_ACCEPT, RESPONSE_SUCCESS, RESPONSE_SUCCESS);
+
+ when(client.get(any(), any(), any())).thenAnswer(provideResponse(rawResponse));
+
+ // use a real executor
+ params = params.toBuilder().executor(ForkJoinPool.commonPool()).build();
+
+ oper = new MyOper(params, config) {
+ @Override
+ public long getPollWaitMs() {
+ return 1;
+ }
+ };
+
+ CompletableFuture<OperationOutcome> future2 =
+ oper.postProcessResponse(outcome, FULL_PATH, rawResponse, response);
+
+ assertSame(outcome, future2.get(5, TimeUnit.SECONDS));
+ assertEquals(PolicyResult.SUCCESS, outcome.getResult());
+ assertEquals(2, oper.getPollCount());
+
+ /*
+ * repeat - this time, the "poll" count will be exhausted, so it should fail
+ */
+ when(rawResponse.getStatus()).thenReturn(RESPONSE_ACCEPT);
+
+ future2 = oper.postProcessResponse(outcome, FULL_PATH, rawResponse, response);
+
+ assertSame(outcome, future2.get(5, TimeUnit.SECONDS));
+ assertEquals(PolicyResult.FAILURE_TIMEOUT, outcome.getResult());
+ assertEquals(MAX_POLLS + 1, oper.getPollCount());
+
+ oper.resetPollCount();
+ assertEquals(0, oper.getPollCount());
+ assertNull(oper.getSubRequestId());
+ }
+
+ @Test
+ public void testDetmStatus() {
+ // make an operation that does NOT override detmStatus()
+ oper = new HttpOperation<String>(params, config, String.class) {};
+
+ assertThatThrownBy(() -> oper.detmStatus(rawResponse, response))
+ .isInstanceOf(UnsupportedOperationException.class);
+ }
+
+ /**
+ * Provides a response to an asynchronous HttpClient call.
+ *
+ * @param response response to be provided to the call
+ * @return a function that provides the response to the call
+ */
+ protected Answer<CompletableFuture<Response>> provideResponse(Response response) {
+ return provideResponse(response, 0);
+ }
+
+ /**
+ * Provides a response to an asynchronous HttpClient call.
+ *
+ * @param response response to be provided to the call
+ * @param index index of the callback within the arguments
+ * @return a function that provides the response to the call
+ */
+ protected Answer<CompletableFuture<Response>> provideResponse(Response response, int index) {
+ return args -> {
+ InvocationCallback<Response> cb = args.getArgument(index);
+ cb.completed(response);
+ return CompletableFuture.completedFuture(response);
+ };
+ }
+
+ private static class MyOper extends HttpOperation<String> {
+
+ public MyOper(ControlLoopOperationParams params, HttpConfig config) {
+ super(params, config, String.class);
+
+ setUsePolling();
+ }
+
+ @Override
+ protected Status detmStatus(Response rawResponse, String response) {
+ switch (rawResponse.getStatus()) {
+ case RESPONSE_ACCEPT:
+ return Status.STILL_WAITING;
+ case RESPONSE_SUCCESS:
+ return Status.SUCCESS;
+ default:
+ return Status.FAILURE;
+ }
+ }
+
+ @Override
+ protected boolean isSuccess(Response rawResponse, String response) {
+ return true;
+ }
+ }
+}
* ============LICENSE_END=========================================================
*/
-package org.onap.policy.controlloop.actor.so;
+package org.onap.policy.controlloop.actorserviceprovider.impl;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.when;
import org.onap.policy.common.endpoints.http.client.HttpClient;
import org.onap.policy.common.endpoints.http.client.HttpClientFactory;
import org.onap.policy.controlloop.actorserviceprovider.Util;
+import org.onap.policy.controlloop.actorserviceprovider.parameters.ControlLoopOperationParams;
+import org.onap.policy.controlloop.actorserviceprovider.parameters.HttpConfig;
+import org.onap.policy.controlloop.actorserviceprovider.parameters.HttpPollingConfig;
+import org.onap.policy.controlloop.actorserviceprovider.parameters.HttpPollingParams;
import org.onap.policy.controlloop.actorserviceprovider.parameters.ParameterValidationRuntimeException;
-public class SoOperatorTest {
+public class HttpPollingOperatorTest {
private static final String ACTOR = "my-actor";
private static final String OPERATION = "my-name";
private static final String CLIENT = "my-client";
private static final String PATH = "/my-path";
- private static final String PATH_GET = "my-path-get/";
- private static final int MAX_GETS = 3;
- private static final int WAIT_SEC_GETS = 20;
+ private static final String POLL_PATH = "my-path-get/";
+ private static final int MAX_POLLS = 3;
+ private static final int POLL_WAIT_SEC = 20;
private static final int TIMEOUT = 100;
@Mock
private HttpClient client;
-
@Mock
private HttpClientFactory factory;
-
- private SoOperator oper;
+ private HttpPollingOperator oper;
/**
* Initializes fields, including {@link #oper}, and resets the static fields used by
oper = new MyOperator();
- SoParams params = SoParams.builder().pathGet(PATH_GET).maxGets(MAX_GETS).waitSecGet(WAIT_SEC_GETS)
- .clientName(CLIENT).path(PATH).timeoutSec(TIMEOUT).build();
+ HttpPollingParams params = HttpPollingParams.builder().pollPath(POLL_PATH).maxPolls(MAX_POLLS)
+ .pollWaitSec(POLL_WAIT_SEC).clientName(CLIENT).path(PATH).timeoutSec(TIMEOUT).build();
Map<String, Object> paramMap = Util.translateToMap(OPERATION, params);
oper.configure(paramMap);
}
@Test
public void testDoConfigure_testGetters() {
- assertTrue(oper.getCurrentConfig() instanceof SoConfig);
+ assertTrue(oper.getCurrentConfig() instanceof HttpPollingConfig);
// test invalid parameters
- Map<String, Object> paramMap2 = Util.translateToMap(OPERATION, SoParams.builder().build());
+ Map<String, Object> paramMap2 = Util.translateToMap(OPERATION, HttpPollingParams.builder().build());
assertThatThrownBy(() -> oper.configure(paramMap2)).isInstanceOf(ParameterValidationRuntimeException.class);
}
+ @Test
+ public void testGetClientFactory() {
+ HttpPollingOperator oper2 = new HttpPollingOperator(ACTOR, OPERATION);
+ assertNotNull(oper2.getClientFactory());
+ }
+
- private class MyOperator extends SoOperator {
+ private class MyOperator extends HttpPollingOperator {
public MyOperator() {
- super(ACTOR, OPERATION, null);
+ super(ACTOR, OPERATION, MyOperation::new);
}
@Override
return factory;
}
}
+
+ private static class MyOperation extends HttpOperation<String> {
+ public MyOperation(ControlLoopOperationParams params, HttpConfig config) {
+ super(params, config, String.class);
+ }
+ }
}
import org.onap.policy.common.parameters.ValidationResult;
import org.onap.policy.controlloop.actorserviceprovider.Util;
-public class CommonActorParamsTest {
+public class ActorParamsTest {
private static final String CONTAINER = "my-container";
private static final String TEXT2B = "bye";
private Map<String, Map<String, Object>> operations;
- private CommonActorParams params;
+ private ActorParams params;
/**
* Initializes {@link #operations} with two items and {@link params} with a fully
operations.put(PATH1, Map.of("path", URI1));
operations.put(PATH2, Map.of("path", URI2, "text2", TEXT2B));
- params = makeCommonActorParams();
+ params = makeActorParams();
}
@Test
assertTrue(params.validate(CONTAINER).isValid());
// only a few fields are required
- CommonActorParams sparse = Util.translate(CONTAINER,
- Map.of(CommonActorParams.OPERATIONS_FIELD, operations, "timeoutSec", 1),
- CommonActorParams.class);
+ ActorParams sparse = Util.translate(CONTAINER,
+ Map.of(ActorParams.OPERATIONS_FIELD, operations, "timeoutSec", 1),
+ ActorParams.class);
assertTrue(sparse.validate(CONTAINER).isValid());
- testValidateField(CommonActorParams.OPERATIONS_FIELD, "null", params2 -> params2.setOperations(null));
+ testValidateField(ActorParams.OPERATIONS_FIELD, "null", params2 -> params2.setOperations(null));
}
- private void testValidateField(String fieldName, String expected, Consumer<CommonActorParams> makeInvalid) {
+ private void testValidateField(String fieldName, String expected, Consumer<ActorParams> makeInvalid) {
// original params should be valid
ValidationResult result = params.validate(CONTAINER);
assertTrue(fieldName, result.isValid());
// make invalid params
- CommonActorParams params2 = makeCommonActorParams();
+ ActorParams params2 = makeActorParams();
makeInvalid.accept(params2);
result = params2.validate(CONTAINER);
assertFalse(fieldName, result.isValid());
assertThat(result.getResult()).contains(CONTAINER).contains(fieldName).contains(expected);
}
- private CommonActorParams makeCommonActorParams() {
+ private ActorParams makeActorParams() {
MyParams params2 = new MyParams();
params2.setOperations(operations);
params2.setText1(TEXT1);
}
@Setter
- public static class MyParams extends CommonActorParams {
+ public static class MyParams extends ActorParams {
@SuppressWarnings("unused")
private String text1;
// only a few fields are required
BidirectionalTopicActorParams sparse =
- Util.translate(CONTAINER, Map.of(CommonActorParams.OPERATIONS_FIELD, operMap, "timeoutSec", 1),
+ Util.translate(CONTAINER, Map.of(ActorParams.OPERATIONS_FIELD, operMap, "timeoutSec", 1),
BidirectionalTopicActorParams.class);
assertTrue(sparse.validate(CONTAINER).isValid());
- testValidateField(CommonActorParams.OPERATIONS_FIELD, "null", params2 -> params2.setOperations(null));
+ testValidateField(ActorParams.OPERATIONS_FIELD, "null", params2 -> params2.setOperations(null));
testValidateField("timeoutSec", "minimum", params2 -> params2.setTimeoutSec(-1));
// check edge cases
// only a few fields are required
HttpActorParams sparse = Util.translate(CONTAINER,
- Map.of(CommonActorParams.OPERATIONS_FIELD, operations, "timeoutSec", 1), HttpActorParams.class);
+ Map.of(ActorParams.OPERATIONS_FIELD, operations, "timeoutSec", 1), HttpActorParams.class);
assertTrue(sparse.validate(CONTAINER).isValid());
- testValidateField(CommonActorParams.OPERATIONS_FIELD, "null", params2 -> params2.setOperations(null));
+ testValidateField(ActorParams.OPERATIONS_FIELD, "null", params2 -> params2.setOperations(null));
testValidateField("timeoutSec", "minimum", params2 -> params2.setTimeoutSec(-1));
// check edge cases
* ============LICENSE_END=========================================================
*/
-package org.onap.policy.controlloop.actor.so;
+package org.onap.policy.controlloop.actorserviceprovider.parameters;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.assertFalse;
import org.junit.Test;
import org.onap.policy.common.parameters.ValidationResult;
import org.onap.policy.controlloop.actorserviceprovider.Util;
-import org.onap.policy.controlloop.actorserviceprovider.parameters.CommonActorParams;
+import org.onap.policy.controlloop.actorserviceprovider.parameters.ActorParams;
-public class SoActorParamsTest {
+public class HttpPollingActorParamsTest {
private static final String CONTAINER = "my-container";
private static final String CLIENT = "my-client";
- private static final String PATH_GET = "my-path-get";
- private static final int MAX_GETS = 3;
- private static final int WAIT_SEC_GETS = 20;
+ private static final String POLL_PATH = "my-poll-path";
+ private static final int MAX_POLLS = 3;
+ private static final int POLL_WAIT_SEC = 20;
private static final int TIMEOUT = 10;
private static final String PATH1 = "path #1";
private static final String URI2 = "uri #2";
private Map<String, Map<String, Object>> operations;
- private SoActorParams params;
+ private HttpPollingActorParams params;
/**
* Initializes {@link #operations} with two items and {@link params} with a fully
operations.put(PATH1, Map.of("path", URI1));
operations.put(PATH2, Map.of("path", URI2));
- params = makeSoActorParams();
+ params = makeHttpPollingActorParams();
}
@Test
assertTrue(params.validate(CONTAINER).isValid());
// only a few fields are required
- SoActorParams sparse = Util.translate(CONTAINER, Map.of(CommonActorParams.OPERATIONS_FIELD, operations),
- SoActorParams.class);
+ HttpPollingActorParams sparse = Util.translate(CONTAINER, Map.of(ActorParams.OPERATIONS_FIELD, operations),
+ HttpPollingActorParams.class);
assertTrue(sparse.validate(CONTAINER).isValid());
- testValidateField("maxGets", "minimum", params2 -> params2.setMaxGets(-1));
- testValidateField("waitSecGet", "minimum", params2 -> params2.setWaitSecGet(0));
+ testValidateField("maxPolls", "minimum", params2 -> params2.setMaxPolls(-1));
+ testValidateField("pollWaitSec", "minimum", params2 -> params2.setPollWaitSec(0));
// check fields from superclass
- testValidateField(CommonActorParams.OPERATIONS_FIELD, "null", params2 -> params2.setOperations(null));
+ testValidateField(ActorParams.OPERATIONS_FIELD, "null", params2 -> params2.setOperations(null));
testValidateField("timeoutSec", "minimum", params2 -> params2.setTimeoutSec(-1));
// check edge cases
- params.setMaxGets(0);
+ params.setMaxPolls(0);
assertTrue(params.validate(CONTAINER).isValid());
- params.setMaxGets(MAX_GETS);
+ params.setMaxPolls(MAX_POLLS);
- params.setWaitSecGet(1);
+ params.setPollWaitSec(1);
assertTrue(params.validate(CONTAINER).isValid());
- params.setWaitSecGet(WAIT_SEC_GETS);
+ params.setPollWaitSec(POLL_WAIT_SEC);
}
- private void testValidateField(String fieldName, String expected, Consumer<SoActorParams> makeInvalid) {
+ private void testValidateField(String fieldName, String expected, Consumer<HttpPollingActorParams> makeInvalid) {
// original params should be valid
ValidationResult result = params.validate(CONTAINER);
assertTrue(fieldName, result.isValid());
// make invalid params
- SoActorParams params2 = makeSoActorParams();
+ HttpPollingActorParams params2 = makeHttpPollingActorParams();
makeInvalid.accept(params2);
result = params2.validate(CONTAINER);
assertFalse(fieldName, result.isValid());
assertThat(result.getResult()).contains(CONTAINER).contains(fieldName).contains(expected);
}
- private SoActorParams makeSoActorParams() {
- SoActorParams params2 = new SoActorParams();
+ private HttpPollingActorParams makeHttpPollingActorParams() {
+ HttpPollingActorParams params2 = new HttpPollingActorParams();
params2.setClientName(CLIENT);
params2.setTimeoutSec(TIMEOUT);
params2.setOperations(operations);
- params2.setWaitSecGet(WAIT_SEC_GETS);
- params2.setMaxGets(MAX_GETS);
- params2.setPathGet(PATH_GET);
+ params2.setPollWaitSec(POLL_WAIT_SEC);
+ params2.setMaxPolls(MAX_POLLS);
+ params2.setPollPath(POLL_PATH);
return params2;
}
* ============LICENSE_END=========================================================
*/
-package org.onap.policy.controlloop.actor.so;
+package org.onap.policy.controlloop.actorserviceprovider.parameters;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertSame;
import org.onap.policy.common.endpoints.http.client.HttpClient;
import org.onap.policy.common.endpoints.http.client.HttpClientFactory;
-public class SoConfigTest {
+public class HttpPollingConfigTest {
private static final String MY_CLIENT = "my-client";
private static final String MY_PATH = "my-path";
- private static final String GET_PATH = "get-path";
+ private static final String POLL_PATH = "poll-path";
private static final int TIMEOUT_SEC = 10;
- private static final int MAX_GETS = 20;
+ private static final int MAX_POLLS = 20;
private static final int WAIT_SEC = 30;
@Mock
@Mock
private Executor executor;
- private SoParams params;
- private SoConfig config;
+ private HttpPollingParams params;
+ private HttpPollingConfig config;
/**
* Sets up.
when(factory.get(MY_CLIENT)).thenReturn(client);
- params = SoParams.builder().maxGets(MAX_GETS).pathGet(GET_PATH).waitSecGet(WAIT_SEC).clientName(MY_CLIENT)
- .path(MY_PATH).timeoutSec(TIMEOUT_SEC).build();
- config = new SoConfig(executor, params, factory);
+ params = HttpPollingParams.builder().maxPolls(MAX_POLLS).pollPath(POLL_PATH).pollWaitSec(WAIT_SEC)
+ .clientName(MY_CLIENT).path(MY_PATH).timeoutSec(TIMEOUT_SEC).build();
+ config = new HttpPollingConfig(executor, params, factory);
}
@Test
public void test() {
- assertEquals(GET_PATH + "/", config.getPathGet());
- assertEquals(MAX_GETS, config.getMaxGets());
- assertEquals(WAIT_SEC, config.getWaitSecGet());
+ assertEquals(POLL_PATH + "/", config.getPollPath());
+ assertEquals(MAX_POLLS, config.getMaxPolls());
+ assertEquals(WAIT_SEC, config.getPollWaitSec());
// check value from superclass
assertSame(executor, config.getBlockingExecutor());
assertSame(client, config.getClient());
// path with trailing "/"
- params = params.toBuilder().pathGet(GET_PATH + "/").build();
- config = new SoConfig(executor, params, factory);
- assertEquals(GET_PATH + "/", config.getPathGet());
+ params = params.toBuilder().pollPath(POLL_PATH + "/").build();
+ config = new HttpPollingConfig(executor, params, factory);
+ assertEquals(POLL_PATH + "/", config.getPollPath());
}
}
* ============LICENSE_END=========================================================
*/
-package org.onap.policy.controlloop.actor.so;
+package org.onap.policy.controlloop.actorserviceprovider.parameters;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.assertEquals;
import org.junit.Before;
import org.junit.Test;
import org.onap.policy.common.parameters.ValidationResult;
-import org.onap.policy.controlloop.actor.so.SoParams.SoParamsBuilder;
-import org.onap.policy.controlloop.actorserviceprovider.parameters.HttpParams.HttpParamsBuilder;
+import org.onap.policy.controlloop.actorserviceprovider.parameters.HttpPollingParams.HttpPollingParamsBuilder;
-public class SoParamsTest {
+public class HttpPollingParamsTest {
private static final String CONTAINER = "my-container";
private static final String CLIENT = "my-client";
private static final String PATH = "my-path";
- private static final String PATH_GET = "my-path-get";
- private static final int MAX_GETS = 3;
- private static final int WAIT_SEC_GETS = 20;
+ private static final String POLL_PATH = "my-poll-path";
+ private static final int MAX_POLLS = 3;
+ private static final int POLL_WAIT_SEC = 20;
private static final int TIMEOUT = 10;
- private SoParams params;
+ private HttpPollingParams params;
@Before
public void setUp() {
- params = SoParams.builder().pathGet(PATH_GET).maxGets(MAX_GETS).waitSecGet(WAIT_SEC_GETS).clientName(CLIENT)
- .path(PATH).timeoutSec(TIMEOUT).build();
+ params = HttpPollingParams.builder().pollPath(POLL_PATH).maxPolls(MAX_POLLS).pollWaitSec(POLL_WAIT_SEC)
+ .clientName(CLIENT).path(PATH).timeoutSec(TIMEOUT).build();
}
@Test
public void testValidate() {
assertTrue(params.validate(CONTAINER).isValid());
- testValidateField("pathGet", "null", bldr -> bldr.pathGet(null));
- testValidateField("maxGets", "minimum", bldr -> bldr.maxGets(-1));
- testValidateField("waitSecGet", "minimum", bldr -> bldr.waitSecGet(-1));
+ testValidateField("pollPath", "null", bldr -> bldr.pollPath(null));
+ testValidateField("maxPolls", "minimum", bldr -> bldr.maxPolls(-1));
+ testValidateField("pollWaitSec", "minimum", bldr -> bldr.pollWaitSec(-1));
// validate one of the superclass fields
testValidateField("clientName", "null", bldr -> bldr.clientName(null));
// check edge cases
- assertTrue(params.toBuilder().maxGets(0).build().validate(CONTAINER).isValid());
- assertFalse(params.toBuilder().waitSecGet(0).build().validate(CONTAINER).isValid());
- assertTrue(params.toBuilder().waitSecGet(1).build().validate(CONTAINER).isValid());
+ assertTrue(params.toBuilder().maxPolls(0).build().validate(CONTAINER).isValid());
+ assertFalse(params.toBuilder().pollWaitSec(0).build().validate(CONTAINER).isValid());
+ assertTrue(params.toBuilder().pollWaitSec(1).build().validate(CONTAINER).isValid());
}
@Test
public void testBuilder_testToBuilder() {
assertEquals(CLIENT, params.getClientName());
- assertEquals(PATH_GET, params.getPathGet());
- assertEquals(MAX_GETS, params.getMaxGets());
- assertEquals(WAIT_SEC_GETS, params.getWaitSecGet());
+ assertEquals(POLL_PATH, params.getPollPath());
+ assertEquals(MAX_POLLS, params.getMaxPolls());
+ assertEquals(POLL_WAIT_SEC, params.getPollWaitSec());
assertEquals(params, params.toBuilder().build());
}
private void testValidateField(String fieldName, String expected,
- @SuppressWarnings("rawtypes") Function<SoParamsBuilder, HttpParamsBuilder> makeInvalid) {
+ Function<HttpPollingParamsBuilder<?,?>, HttpPollingParamsBuilder<?,?>> makeInvalid) {
// original params should be valid
ValidationResult result = params.validate(CONTAINER);
<!--
============LICENSE_START=======================================================
Copyright (C) 2017-2020 AT&T Intellectual Property. All rights reserved.
- Modifications Copyright (C) 2019 Nordix Foundation.
+ Modifications Copyright (C) 2020 Nordix Foundation.
================================================================================
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<packaging>pom</packaging>
-
+
<parent>
<groupId>org.onap.policy.models</groupId>
<artifactId>policy-models-interactions</artifactId>
<version>2.3.0-SNAPSHOT</version>
</parent>
-
+
<groupId>org.onap.policy.models.policy-models-interactions.model-actors</groupId>
<artifactId>model-actors</artifactId>
<properties>
- <jacoco.dataFile>${project.basedir}/../../../../target/code-coverage/jacoco-ut.exec</jacoco.dataFile>
+ <jacoco.dataFile>${project.basedir}/../../../target/code-coverage/jacoco-ut.exec</jacoco.dataFile>
</properties>
<modules>
controlloop-model-impl
================================================================================
Copyright (C) 2017-2020 AT&T Intellectual Property. All rights reserved.
- Modifications Copyright (C) 2019 Nordix Foundation
+ Modifications Copyright (C) 2020 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.
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<packaging>pom</packaging>
-
+
<parent>
<groupId>org.onap.policy.models</groupId>
<artifactId>policy-models-interactions</artifactId>
<version>2.3.0-SNAPSHOT</version>
</parent>
-
+
<groupId>org.onap.policy.models.policy-models-interactions.model-impl</groupId>
<artifactId>model-impl</artifactId>
<properties>
- <jacoco.dataFile>${project.basedir}/../../../../target/code-coverage/jacoco-ut.exec</jacoco.dataFile>
+ <jacoco.dataFile>${project.basedir}/../../../target/code-coverage/jacoco-ut.exec</jacoco.dataFile>
</properties>
<modules>
#
# ============LICENSE_START=======================================================
# Copyright (C) 2019 Nordix Foundation.
+# Modifications copyright (C) 2020 Bell Canada. All rights reserved.
# ================================================================================
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
-Djavax.net.ssl.keyStorePassword="$KEYSTORE_PASSWD" \
-Djavax.net.ssl.trustStore="$TRUSTSTORE" \
-Djavax.net.ssl.trustStorePassword="$TRUSTSTORE_PASSWD" \
- -Dlogback.configurationFile=$DMAAP_SIM_HOME/etc/logback.xml \
org.onap.policy.models.sim.dmaap.startstop.Main \
-c $CONFIG_FILE
<!--
============LICENSE_START=======================================================
Copyright (C) 2019 Nordix Foundation.
+ Modifications copyright (C) 2020 Bell Canada. All rights reserved.
================================================================================
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
<lineEnding>unix</lineEnding>
<fileMode>755</fileMode>
</fileSet>
- <fileSet>
- <directory>${project.basedir}/src/main/resources
- </directory>
- <includes>
- <include>logback.xml</include>
- </includes>
- <outputDirectory>etc</outputDirectory>
- <lineEnding>unix</lineEnding>
- </fileSet>
<fileSet>
<directory>${project.basedir}/src/main/resources/etc
</directory>
+++ /dev/null
-<!--
- ============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=========================================================
--->
-
-<configuration scan="true" scanPeriod="30 seconds" debug="false">
-
- <contextName>DMaaPSim</contextName>
- <statusListener class="ch.qos.logback.core.status.OnConsoleStatusListener" />
- <property name="LOG_DIR" value="${java.io.tmpdir}/pf_logging/" />
-
- <!-- USE FOR STD OUT ONLY -->
- <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
- <encoder>
- <Pattern>%d %contextName [%t] %level %logger{36} - %msg%n</Pattern>
- </encoder>
- </appender>
-
- <root level="info">
- <appender-ref ref="STDOUT" />
- </root>
-
- <logger name="org.eclipse.jetty" level="info" additivity="false">
- <appender-ref ref="STDOUT" />
- </logger>
-
- <logger name="org.onap.policy.models.sim.dmaap" level="debug" additivity="false">
- <appender-ref ref="STDOUT" />
- </logger>
-
-</configuration>
/*-
* ============LICENSE_START=======================================================
* Copyright (C) 2019 Nordix Foundation.
- * Modifications Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * Modifications Copyright (C) 2019, 2020 AT&T Intellectual Property. All rights reserved.
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
import org.apache.commons.cli.Option;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
-import org.apache.log4j.chainsaw.Main;
import org.onap.policy.common.utils.resources.ResourceUtils;
import org.onap.policy.models.sim.pdp.exception.PdpSimulatorException;
}
if (commandLine.hasOption('h')) {
- return help(Main.class.getName());
+ return help(PdpSimulatorMain.class.getName());
}
if (commandLine.hasOption('v')) {
#
# ============LICENSE_START=======================================================
# Copyright (C) 2019-2020 Nordix Foundation.
+# Modifications copyright (C) 2020 Bell Canada. All rights reserved.
# ================================================================================
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
-Djavax.net.ssl.keyStorePassword="$KEYSTORE_PASSWD" \
-Djavax.net.ssl.trustStore="$TRUSTSTORE" \
-Djavax.net.ssl.trustStorePassword="$TRUSTSTORE_PASSWD" \
- -Dlogback.configurationFile=$PDP_SIM_HOME/etc/logback.xml \
org.onap.policy.models.sim.pdp.PdpSimulatorMain \
-c $CONFIG_FILE
<!--
============LICENSE_START=======================================================
Copyright (C) 2019 Nordix Foundation.
+ Modifications copyright (C) 2020 Bell Canada. All rights reserved.
================================================================================
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
</dependencySet>
</dependencySets>
<fileSets>
- <fileSet>
- <directory>${project.basedir}/src/main/resources
- </directory>
- <includes>
- <include>logback.xml</include>
- </includes>
- <outputDirectory>etc</outputDirectory>
- <lineEnding>unix</lineEnding>
- </fileSet>
<fileSet>
<directory>${project.basedir}/src/main/resources/config
</directory>
+++ /dev/null
-<!--
- ============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=========================================================
--->
-
-<configuration scan="true" scanPeriod="30 seconds" debug="false">
-
- <contextName>DMaaPSim</contextName>
- <statusListener class="ch.qos.logback.core.status.OnConsoleStatusListener" />
- <property name="LOG_DIR" value="${java.io.tmpdir}/pf_logging/" />
-
- <!-- USE FOR STD OUT ONLY -->
- <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
- <encoder>
- <Pattern>%d %contextName [%t] %level %logger{36} - %msg%n</Pattern>
- </encoder>
- </appender>
-
- <root level="info">
- <appender-ref ref="STDOUT" />
- </root>
-
- <logger name="org.eclipse.jetty" level="info" additivity="false">
- <appender-ref ref="STDOUT" />
- </logger>
-
- <logger name="org.onap.policy.models.sim.pdp" level="debug" additivity="false">
- <appender-ref ref="STDOUT" />
- </logger>
-
-</configuration>
# ONAP
# ================================================================================
# Copyright (C) 2020 AT&T Intellectual Property. All rights reserved.
+# Modifications copyright (C) 2020 Bell Canada. All rights reserved.
# ================================================================================
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
${JAVA_HOME}/bin/java \
-cp "${SIMULATOR_HOME}/etc:${SIMULATOR_HOME}/lib/*" \
- -Dlogback.configurationFile=${SIMULATOR_HOME}/etc/logback.xml \
-Djavax.net.ssl.keyStore="${KEYSTORE}" \
-Djavax.net.ssl.keyStorePassword="${KEYSTORE_PASSWD}" \
-Djavax.net.ssl.trustStore="${TRUSTSTORE}" \
<!--
============LICENSE_START=======================================================
Copyright (C) 2020 AT&T Intellectual Property. All rights reserved.
+ Modifications copyright (C) 2020 Bell Canada. All rights reserved.
================================================================================
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
</dependencySet>
</dependencySets>
<fileSets>
- <fileSet>
- <directory>${project.basedir}/src/main/resources</directory>
- <includes>
- <include>logback.xml</include>
- </includes>
- <outputDirectory>etc</outputDirectory>
- <lineEnding>unix</lineEnding>
- </fileSet>
<fileSet>
<directory>${project.basedir}/src/main/resources/ssl
</directory>
+++ /dev/null
-<!--
- ============LICENSE_START=======================================================
- Copyright (C) 2020 AT&T Intellectual Property. All rights reserved.
- ================================================================================
- 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=========================================================
--->
-
-<configuration scan="true" scanPeriod="30 seconds" debug="false">
-
- <contextName>Simulators</contextName>
- <statusListener class="ch.qos.logback.core.status.OnConsoleStatusListener" />
- <property name="logDir" value="${POLICY_LOGS}" />
-
- <appender name="DebugOut"
- class="ch.qos.logback.core.rolling.RollingFileAppender">
- <file>${logDir}/debug.log</file>
- <rollingPolicy
- class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
- <fileNamePattern>${logDir}/debug.%d{yyyy-MM-dd}.%i.log.zip
- </fileNamePattern>
- <maxFileSize>50MB</maxFileSize>
- <maxHistory>10</maxHistory>
- <totalSizeCap>500MB</totalSizeCap>
- </rollingPolicy>
- <encoder>
- <Pattern>%d %contextName [%t] %level %logger{36} - %msg%n
- </Pattern>
- </encoder>
- </appender>
-
- <root level="info">
- <appender-ref ref="DebugOut" />
- </root>
-
- <logger name="org.eclipse.jetty" level="info" additivity="false">
- <appender-ref ref="DebugOut" />
- </logger>
-
- <logger name="org.onap.policy.models.sim.dmaap" level="debug" additivity="false">
- <appender-ref ref="DebugOut" />
- </logger>
-
-</configuration>
* ONAP Policy Models
* ================================================================================
* Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * Modifications Copyright (C) 2020 Nordix Foundation.
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
return ObjectUtils.compare(getVersion(), other.getVersion());
}
+
+ @Override
+ public String toString() {
+ return this.name + " " + this.version;
+ }
}
* ONAP Policy Models
* ================================================================================
* Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * Modifications Copyright (C) 2020 Nordix Foundation.
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
return ObjectUtils.compare(getVersion(), other.getVersion());
}
+
+ @Override
+ public String toString() {
+ return this.name + " " + this.version;
+ }
}
* ONAP Policy Models
* ================================================================================
* Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * Modifications Copyright (C) 2020 Nordix Foundation.
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
return ObjectUtils.compare(getVersion(), other.getVersion());
}
+
+ @Override
+ public String toString() {
+ return this.name + " " + this.version;
+ }
}