package org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.onap.core.SelfRegistrationManager;
+import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.util.SystemFunctions;
import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.vnfm.JobManager;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.event.ContextClosedEvent;
import org.springframework.stereotype.Component;
+import static java.util.concurrent.Executors.newCachedThreadPool;
+
+import static org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.util.SystemFunctions.systemFunctions;
import static org.slf4j.LoggerFactory.getLogger;
/**
* @param args arguments for the application (not used)
*/
public static void main(String[] args) {
- SpringApplication.run(NokiaSvnfmApplication.class, args);
+ systemFunctions().newSpringApplication(NokiaSvnfmApplication.class).run(args);
}
/**
@Component
@Profile("!test")
public static class SelfRegistrationTrigger implements ApplicationListener<ApplicationReadyEvent> {
+ private final SelfRegistrationManager selfRegistrationManager;
+ private final JobManager jobManager;
+ /**
+ * Runs the registration process
+ */
+ private ExecutorService executorService = newCachedThreadPool();
+
@Autowired
- private SelfRegistrationManager selfRegistrationManager;
+ SelfRegistrationTrigger(SelfRegistrationManager selfRegistrationManager, JobManager jobManager){
+ this.jobManager = jobManager;
+ this.selfRegistrationManager = selfRegistrationManager;
+ }
@Override
public void onApplicationEvent(ApplicationReadyEvent contextRefreshedEvent) {
- logger.info("Self registration started");
- try {
- selfRegistrationManager.register();
- logger.info("Self registration finished");
- } catch (RuntimeException e) {
- logger.error("Self registration failed", e);
- throw e;
- }
+ Callable<Boolean> singleRegistration = () -> {
+ logger.info("Self registration started");
+ try {
+ selfRegistrationManager.register();
+ logger.info("Self registration finished");
+ } catch (RuntimeException e) {
+ logger.error("Self registration failed", e);
+ throw e;
+ }
+ return true;
+ };
+ executorService.submit(() -> {
+ while(!jobManager.isPreparingForShutDown()){
+ try{
+ executorService.submit(singleRegistration).get();
+ //registration successful
+ return;
+ }
+ catch (Exception e){
+ logger.warn("Unable to execute self registration process", e);
+ }
+ systemFunctions().sleep(5000);
+ }
+ });
}
}
@Component
@Profile("!test")
public static class SelfDeRegistrationTrigger implements ApplicationListener<ContextClosedEvent> {
+ private final SelfRegistrationManager selfRegistrationManager;
+ private final JobManager jobManager;
+
@Autowired
- private SelfRegistrationManager selfRegistrationManager;
- @Autowired
- private JobManager jobManager;
+ SelfDeRegistrationTrigger(SelfRegistrationManager selfRegistrationManager, JobManager jobManager){
+ this.jobManager = jobManager;
+ this.selfRegistrationManager = selfRegistrationManager;
+ }
@Override
public void onApplicationEvent(ContextClosedEvent contextClosedEvent) {
public class SelfRegistrationManager {
public static final String DRIVER_VERSION = "v1";
public static final String SERVICE_NAME = "NokiaSVNFM";
- // 1 means internal 0 means core :)
- public static final String INTERNAL_SERVICE = "1";
public static final String SWAGGER_API_DEFINITION = "self.swagger.json";
private static Logger logger = getLogger(SelfRegistrationManager.class);
private final DriverProperties driverProperties;
private final MsbApiProvider msbApiProvider;
private final CbamRestApiProvider cbamRestApiProvider;
-
@Value("${driverMsbExternalIp}")
private String driverMsbExternalIp;
@Value("${driverVnfmExternalIp}")
import java.io.PrintStream;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
+import org.springframework.boot.SpringApplication;
/**
* Wrapper class for static method calls to core or core libraries.
public CloseableHttpClient getHttpClient() {
return HttpClients.createDefault();
}
+
+ /**
+ * @param clazz the main source of the Spring application
+ * @return a new Spring application
+ */
+ public SpringApplication newSpringApplication(Class clazz){
+ return new SpringApplication(clazz);
+ }
}
\ No newline at end of file
return jobId.getAsString();
}
+ /**
+ * @return is the component preparing for shutdown
+ */
+ public boolean isPreparingForShutDown(){
+ return preparingForShutDown;
+ }
+
/**
* Throws an exception in case the service is not ready to serve requests due to
* not being able to register to MSB or to subscribe to CBAM LCNs
},
"delete": {
"tags": [
- "SO VNFM driver"
+ "SO VNFM Adaptor"
],
"summary": "Deletes VNF",
"description": "Deletes the VNF. If the VNF was instantiated VNF termination must be called before VNF deletion",
"/so/{vnfmId}/vnfs/{vnfId}/heal": {
"post": {
"tags": [
- "SO VNFM driver"
+ "SO VNFM Adaptor"
],
"summary": "VNF heal",
"description": "VNF heal",
"/so/{vnfmId}/vnfs/{vnfId}/terminate": {
"post": {
"tags": [
- "SO VNFM driver"
+ "SO VNFM Adaptor"
],
"summary": "VNF terminate",
"description": "VNF terminate",
"/so/{vnfmId}/jobs/{jobId}": {
"get": {
"tags": [
- "SO VNFM driver"
+ "SO VNFM Adaptor"
],
"summary": "Query job status",
"description": "Query the job status",
*/
package org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia;
+import java.util.HashSet;
+import java.util.Set;
import junit.framework.TestCase;
import org.junit.Before;
import org.junit.Test;
import org.mockito.*;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.onap.core.SelfRegistrationManager;
+import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.util.SystemFunctions;
+import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.util.TestUtil;
import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.vnfm.JobManager;
+import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.vnfm.TestBase;
import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.vnfm.Useless;
import org.slf4j.Logger;
+import org.springframework.boot.SpringApplication;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.event.ContextClosedEvent;
import org.springframework.test.util.ReflectionTestUtils;
import static junit.framework.TestCase.assertEquals;
import static junit.framework.TestCase.assertTrue;
-import static org.mockito.Mockito.verify;
+import static junit.framework.TestCase.fail;
+import static org.mockito.Mockito.*;
+import static org.springframework.test.util.ReflectionTestUtils.setField;
-public class TestNokiaSvnfmApplication {
- @Mock
- private SelfRegistrationManager selfRegistrationManager;
+public class TestNokiaSvnfmApplication extends TestBase {
@Mock
private JobManager jobManager;
- @Mock
- private Logger logger;
- @InjectMocks
+
private NokiaSvnfmApplication.SelfRegistrationTrigger selfRegistrationTriggerer;
- @InjectMocks
private NokiaSvnfmApplication.SelfDeRegistrationTrigger selfUnregistrationTriggerer;
@Before
public void initMocks() throws Exception {
- MockitoAnnotations.initMocks(this);
- ReflectionTestUtils.setField(NokiaSvnfmApplication.class, "logger", logger);
+ selfRegistrationTriggerer = new NokiaSvnfmApplication.SelfRegistrationTrigger(selfRegistrationManager, jobManager);
+ selfUnregistrationTriggerer = new NokiaSvnfmApplication.SelfDeRegistrationTrigger(selfRegistrationManager, jobManager);
+ setField(NokiaSvnfmApplication.class, "logger", logger);
}
/**
* Assert that the self registration process is started after the servlet is up and is able to answer REST requests.
*/
@Test
+ @SuppressWarnings("squid:S2925") //the execution is asynchronous no other way to wait
public void testRegistrationIsCalledAfterComponentIsUp() throws Exception {
//given
ApplicationReadyEvent event = Mockito.mock(ApplicationReadyEvent.class);
//when
selfRegistrationTriggerer.onApplicationEvent(event);
//verify
- verify(selfRegistrationManager).register();
- verify(logger).info("Self registration started");
- verify(logger).info("Self registration finished");
+ boolean success = false;
+ while(!success)
+ {
+ try {
+ verify(selfRegistrationManager).register();
+ verify(logger).info("Self registration started");
+ verify(logger).info("Self registration finished");
+ success = true;
+ }
+ catch (Error e){
+
+ }
+ Thread.sleep(10);
+ }
// this forces the event to be fired after the servlet is up (prevents refactor)
assertTrue(ApplicationReadyEvent.class.isAssignableFrom(event.getClass()));
}
assertTrue(ContextClosedEvent.class.isAssignableFrom(event.getClass()));
}
+ /**
+ * Assert that the self registration process is started after the servlet is up and is able to answer REST requests.
+ */
+ @Test
+ public void testPreparingForShutdownDoesNotStartRegistration() throws Exception {
+ //given
+ ApplicationReadyEvent event = Mockito.mock(ApplicationReadyEvent.class);
+ when(jobManager.isPreparingForShutDown()).thenReturn(true);
+ //when
+ selfRegistrationTriggerer.onApplicationEvent(event);
+ //verify
+ verify(selfRegistrationManager, never()).register();
+ }
+
/**
* Failures in registration is logged and propagated
*/
@Test
- public void failedRegistration() {
+ @SuppressWarnings("squid:S2925") //the execution is asynchronous no other way to wait
+ public void failedFirstRegistration() {
//given
- RuntimeException expectedException = new RuntimeException();
- Mockito.doThrow(expectedException).when(selfRegistrationManager).register();
+ Set<RuntimeException> expectedException = new HashSet<>();
+ doAnswer(new Answer() {
+ @Override
+ public Object answer(InvocationOnMock invocationOnMock) throws Throwable {
+ if(expectedException.size() == 0){
+ RuntimeException e = new RuntimeException();
+ expectedException.add(e);
+ throw e;
+ }
+ return null;
+ }
+ }).when(selfRegistrationManager).register();
ApplicationReadyEvent event = Mockito.mock(ApplicationReadyEvent.class);
//when
- try {
- selfRegistrationTriggerer.onApplicationEvent(event);
- //verify
- TestCase.fail();
- } catch (RuntimeException e) {
- assertEquals(e, expectedException);
+ selfRegistrationTriggerer.onApplicationEvent(event);
+ //verify
+ //wait for the registration to succeed
+ boolean success = false;
+ while(!success){
+ try{
+ verify(logger).info("Self registration finished");
+ success = true;
+ Thread.sleep(10);
+ }
+ catch (Exception e2){}
+ catch (Error e){}
}
- verify(logger).error("Self registration failed", expectedException);
+ verify(logger, times(2)).info("Self registration started");
+ verify(logger).error("Self registration failed", expectedException.iterator().next());
}
/**
try {
selfUnregistrationTriggerer.onApplicationEvent(event);
//verify
- TestCase.fail();
+ fail();
} catch (RuntimeException e) {
assertEquals(e, expectedException);
}
}
/**
- * static entry point calling an other static entry point can not be tested
- * only using powermock
+ * test spring application bootstrapping
*/
@Test
- @Useless
public void useless() throws Exception {
- try {
- NokiaSvnfmApplication.main(null);
- } catch (Exception e) {
-
- }
+ String[] args = new String [0];
+ SpringApplication springApplicaiton = Mockito.mock(SpringApplication.class);
+ SystemFunctions systemFunctions = SystemFunctions.systemFunctions();
+ when(this.systemFunctions.newSpringApplication(NokiaSvnfmApplication.class)).thenReturn(springApplicaiton);
+ //when
+ NokiaSvnfmApplication.main(args);
+ //verify
+ verify(springApplicaiton).run(args);
}
}
import java.util.HashSet;
import java.util.Set;
import org.junit.Test;
+import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.NokiaSvnfmApplication;
import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.vnfm.Useless;
+import org.springframework.boot.SpringApplication;
import static org.junit.Assert.*;
public void testHttp() {
assertNotNull(SystemFunctions.systemFunctions().getHttpClient());
}
+
+ /**
+ * Test spring application wrapping
+ */
+ @Test
+ public void testSpring(){
+ SpringApplication springApplication = SystemFunctions.systemFunctions().newSpringApplication(NokiaSvnfmApplication.class);
+
+ assertEquals(1, springApplication.getAllSources().size());
+ }
}
JobDetailInfo job = jobManager.getJob(VNFM_ID, jobId);
//verify
assertResult(jobId, job, JobStatus.FINISHED, "100", "Operation finished");
+ assertEquals(false, jobManager.isPreparingForShutDown());
}
/**
} catch (Exception e) {
verify(logger).error("The service is preparing to shut down");
}
+ assertEquals(true, jobManager.isPreparingForShutDown());
}
/**
},
"delete": {
"tags": [
- "SO VNFM driver"
+ "SO VNFM Adaptor"
],
"summary": "Deletes VNF",
"description": "Deletes the VNF. If the VNF was instantiated VNF termination must be called before VNF deletion",
"/so/{vnfmId}/vnfs/{vnfId}/heal": {
"post": {
"tags": [
- "SO VNFM driver"
+ "SO VNFM Adaptor"
],
"summary": "VNF heal",
"description": "VNF heal",
"/so/{vnfmId}/vnfs/{vnfId}/terminate": {
"post": {
"tags": [
- "SO VNFM driver"
+ "SO VNFM Adaptor"
],
"summary": "VNF terminate",
"description": "VNF terminate",
"/so/{vnfmId}/jobs/{jobId}": {
"get": {
"tags": [
- "SO VNFM driver"
+ "SO VNFM Adaptor"
],
"summary": "Query job status",
"description": "Query the job status",