/**
* Licensed to The Apereo Foundation under one or more contributor license
* agreements. See the NOTICE file distributed with this work for additional
* information regarding copyright ownership.
*
*
* The Apereo Foundation licenses this file to you under the Educational
* Community 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://opensource.org/licenses/ecl2.txt
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*
*/
package org.opencastproject.serviceregistry.impl;
import static org.easymock.EasyMock.anyObject;
import static org.easymock.EasyMock.expect;
import org.opencastproject.job.api.Job;
import org.opencastproject.job.api.Job.Status;
import org.opencastproject.security.api.DefaultOrganization;
import org.opencastproject.security.api.JaxbOrganization;
import org.opencastproject.security.api.JaxbRole;
import org.opencastproject.security.api.JaxbUser;
import org.opencastproject.security.api.Organization;
import org.opencastproject.security.api.OrganizationDirectoryService;
import org.opencastproject.security.api.SecurityService;
import org.opencastproject.security.api.User;
import org.opencastproject.serviceregistry.api.HostRegistration;
import org.opencastproject.serviceregistry.api.ServiceRegistration;
import org.opencastproject.serviceregistry.api.ServiceState;
import org.opencastproject.serviceregistry.api.SystemLoad;
import org.opencastproject.serviceregistry.impl.jpa.ServiceRegistrationJpaImpl;
import org.opencastproject.util.UrlSupport;
import org.opencastproject.util.persistence.PersistenceUtil;
import org.easymock.EasyMock;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import java.util.ArrayList;
import java.util.List;
public class ServiceRegistrationTest {
private static final String JOB_TYPE_1 = "testing1";
private static final String OPERATION_NAME_1 = "op1";
private static final String OPERATION_NAME_2 = "op2";
private static final String LOCALHOST = UrlSupport.DEFAULT_BASE_URL;
private static final String REMOTEHOST_1 = "http://remotehost1:8080";
private static final String REMOTEHOST_2 = "http://remotehost2:8080";
private static final String PATH_1 = "/path1";
private static final String PATH_2 = "/path2";
private ServiceRegistryJpaImpl serviceRegistry = null;
private ServiceRegistrationJpaImpl regType1Localhost = null;
private ServiceRegistrationJpaImpl regType1Remotehost1 = null;
private ServiceRegistrationJpaImpl regType1Remotehost2 = null;
@Before
public void setUp() throws Exception {
serviceRegistry = new ServiceRegistryJpaImpl();
serviceRegistry.setEntityManagerFactory(PersistenceUtil
.newTestEntityManagerFactory(ServiceRegistryJpaImpl.PERSISTENCE_UNIT));
serviceRegistry.activate(null);
Organization organization = new DefaultOrganization();
OrganizationDirectoryService organizationDirectoryService = EasyMock.createMock(OrganizationDirectoryService.class);
expect(organizationDirectoryService.getOrganization((String) anyObject())).andReturn(organization).anyTimes();
EasyMock.replay(organizationDirectoryService);
serviceRegistry.setOrganizationDirectoryService(organizationDirectoryService);
JaxbOrganization jaxbOrganization = JaxbOrganization.fromOrganization(organization);
User anonymous = new JaxbUser("anonymous", "test", jaxbOrganization, new JaxbRole(
jaxbOrganization.getAnonymousRole(), jaxbOrganization));
SecurityService securityService = EasyMock.createNiceMock(SecurityService.class);
expect(securityService.getUser()).andReturn(anonymous).anyTimes();
expect(securityService.getOrganization()).andReturn(organization).anyTimes();
EasyMock.replay(securityService);
serviceRegistry.setSecurityService(securityService);
// The service registry will automatically register this host with the available number of processors.
// This is potentially ruining our test setup.
serviceRegistry.unregisterHost(LOCALHOST);
// register the hosts
serviceRegistry.registerHost(LOCALHOST, "127.0.0.1", 1024, 1, 1);
serviceRegistry.registerHost(REMOTEHOST_1, "127.0.0.1", 1024, 1, 1);
serviceRegistry.registerHost(REMOTEHOST_2, "127.0.0.1", 1024, 1, 1);
// register some service instances
regType1Localhost = (ServiceRegistrationJpaImpl) serviceRegistry.registerService(JOB_TYPE_1, LOCALHOST, PATH_1);
regType1Remotehost1 = (ServiceRegistrationJpaImpl) serviceRegistry
.registerService(JOB_TYPE_1, REMOTEHOST_1, PATH_1);
regType1Remotehost2 = (ServiceRegistrationJpaImpl) serviceRegistry
.registerService(JOB_TYPE_1, REMOTEHOST_2, PATH_2);
}
@After
public void tearDown() throws Exception {
serviceRegistry.unRegisterService(JOB_TYPE_1, LOCALHOST);
serviceRegistry.unRegisterService(JOB_TYPE_1, REMOTEHOST_1);
serviceRegistry.unRegisterService(JOB_TYPE_1, REMOTEHOST_2);
serviceRegistry.deactivate();
}
@Test
public void testServiceRegistrationsByLoad() throws Exception {
List<ServiceRegistration> services = serviceRegistry.getServiceRegistrations();
List<HostRegistration> hosts = serviceRegistry.getHostRegistrations();
SystemLoad hostLoads = serviceRegistry.getHostLoads(serviceRegistry.emf.createEntityManager(), true);
List<ServiceRegistration> availableServices = serviceRegistry.getServiceRegistrationsByLoad(JOB_TYPE_1, services,
hosts, hostLoads);
// Make sure all hosts are available for processing
Assert.assertEquals(3, availableServices.size());
// Create a job and mark it as running.
Job job = serviceRegistry.createJob(regType1Localhost.getHost(), regType1Localhost.getServiceType(),
OPERATION_NAME_1, null, null, false, null);
job.setStatus(Job.Status.RUNNING);
job = serviceRegistry.updateJob(job);
// Recalculate the number of available services
hostLoads = serviceRegistry.getHostLoads(serviceRegistry.emf.createEntityManager(), true);
availableServices = serviceRegistry.getServiceRegistrationsByLoad(JOB_TYPE_1, services, hosts, hostLoads);
// Since the host load is not taken into account, still all tree services should show up
Assert.assertEquals(3, availableServices.size());
// Recalculate the number of available services after ignoring a host
hosts.remove(regType1Remotehost1.getHostRegistration());
availableServices = serviceRegistry.getServiceRegistrationsByLoad(JOB_TYPE_1, services, hosts, hostLoads);
// Since host 1 is now ignored, only two more services should show up
Assert.assertEquals(2, availableServices.size());
}
@Test
public void testHostCapacity() throws Exception {
List<ServiceRegistration> services = serviceRegistry.getServiceRegistrations();
List<HostRegistration> hosts = serviceRegistry.getHostRegistrations();
SystemLoad hostLoads = serviceRegistry.getHostLoads(serviceRegistry.emf.createEntityManager(), true);
List<ServiceRegistration> availableServices = serviceRegistry.getServiceRegistrationsWithCapacity(JOB_TYPE_1,
services, hosts, hostLoads);
// Make sure all hosts are available for processing
Assert.assertEquals(3, availableServices.size());
// Create a job and mark it as running.
Job job = serviceRegistry.createJob(regType1Localhost.getHost(), regType1Localhost.getServiceType(), OPERATION_NAME_1, null,
null, false, null);
job.setStatus(Job.Status.RUNNING);
job = serviceRegistry.updateJob(job);
// Recalculate the number of available services
hostLoads = serviceRegistry.getHostLoads(serviceRegistry.emf.createEntityManager(), true);
availableServices = serviceRegistry.getServiceRegistrationsWithCapacity(JOB_TYPE_1, services, hosts, hostLoads);
// Since host 1 is now maxed out, only two more services should show up
Assert.assertEquals(2, availableServices.size());
// Recalculate the number of available services after ignoring a host
hosts.remove(regType1Remotehost1.getHostRegistration());
availableServices = serviceRegistry.getServiceRegistrationsWithCapacity(JOB_TYPE_1, services, hosts, hostLoads);
// Since remote host 1 is now ignored, only one more service should show up
Assert.assertEquals(1, availableServices.size());
}
@Test
public void testScenarioOneJobOneService() throws Exception {
Job jobTry1 = serviceRegistry.createJob(regType1Localhost.getHost(),
regType1Localhost.getServiceType(), OPERATION_NAME_1, null, null, true, null);
Job jobTry2 = serviceRegistry.createJob(regType1Localhost.getHost(),
regType1Localhost.getServiceType(), OPERATION_NAME_1, null, null, true, null);
Job jobTry3 = serviceRegistry.createJob(regType1Localhost.getHost(),
regType1Localhost.getServiceType(), OPERATION_NAME_1, null, null, true, null);
ServiceRegistrationJpaImpl updatedService;
// 1st try, failed on localhost
jobTry1.setStatus(Status.FAILED);
jobTry1.setJobType(regType1Localhost.getServiceType());
jobTry1.setProcessingHost(regType1Localhost.getHost());
jobTry1 = serviceRegistry.updateJob(jobTry1);
updatedService = getUpdatedService(regType1Localhost);
Assert.assertEquals(ServiceState.WARNING, updatedService.getServiceState());
Assert.assertEquals(0, updatedService.getErrorStateTrigger());
// 2nd try, failed on localhost
jobTry2.setStatus(Status.FAILED);
jobTry2.setJobType(regType1Localhost.getServiceType());
jobTry2.setProcessingHost(regType1Localhost.getHost());
jobTry2 = serviceRegistry.updateJob(jobTry2);
updatedService = getUpdatedService(regType1Localhost);
Assert.assertEquals(ServiceState.WARNING, updatedService.getServiceState());
Assert.assertEquals(0, updatedService.getErrorStateTrigger());
// 3rd try, finished on localhost
jobTry3.setStatus(Status.FINISHED);
jobTry3.setJobType(regType1Localhost.getServiceType());
jobTry3.setProcessingHost(regType1Localhost.getHost());
jobTry3 = serviceRegistry.updateJob(jobTry3);
updatedService = getUpdatedService(regType1Localhost);
Assert.assertEquals(ServiceState.NORMAL, updatedService.getServiceState());
Assert.assertEquals(0, updatedService.getErrorStateTrigger());
}
@Test
public void testScenarioManyJobsManyServices() throws Exception {
Job job1Try1 = serviceRegistry.createJob(regType1Localhost.getHost(),
regType1Localhost.getServiceType(), OPERATION_NAME_1, null, null, true, null);
Job job1Try2 = serviceRegistry.createJob(regType1Localhost.getHost(),
regType1Localhost.getServiceType(), OPERATION_NAME_1, null, null, true, null);
Job job1Try3 = serviceRegistry.createJob(regType1Localhost.getHost(),
regType1Localhost.getServiceType(), OPERATION_NAME_1, null, null, true, null);
Job job1Try4 = serviceRegistry.createJob(regType1Localhost.getHost(),
regType1Localhost.getServiceType(), OPERATION_NAME_1, null, null, true, null);
List<String> list = new ArrayList<String>();
list.add("test");
Job job2Try1 = serviceRegistry.createJob(regType1Localhost.getHost(),
regType1Localhost.getServiceType(), OPERATION_NAME_2, list, null, true, null);
Job job2Try2 = serviceRegistry.createJob(regType1Localhost.getHost(),
regType1Localhost.getServiceType(), OPERATION_NAME_2, list, null, true, null);
Job job2Try3 = serviceRegistry.createJob(regType1Localhost.getHost(),
regType1Localhost.getServiceType(), OPERATION_NAME_2, list, null, true, null);
serviceRegistry.maxAttemptsBeforeErrorState = 0;
ServiceRegistrationJpaImpl updatedService1;
ServiceRegistrationJpaImpl updatedService2;
ServiceRegistrationJpaImpl updatedService3;
// 1st try for job 1, failed on localhost
job1Try1.setStatus(Status.FAILED);
job1Try1.setJobType(regType1Localhost.getServiceType());
job1Try1.setProcessingHost(regType1Localhost.getHost());
job1Try1 = serviceRegistry.updateJob(job1Try1);
updatedService1 = getUpdatedService(regType1Localhost);
updatedService2 = getUpdatedService(regType1Remotehost1);
updatedService3 = getUpdatedService(regType1Remotehost2);
Assert.assertEquals(ServiceState.WARNING, updatedService1.getServiceState());
Assert.assertEquals(ServiceState.NORMAL, updatedService2.getServiceState());
Assert.assertEquals(ServiceState.NORMAL, updatedService3.getServiceState());
Assert.assertEquals(0, updatedService1.getErrorStateTrigger());
// 1st try for job 2, failed on localhost
job2Try1.setStatus(Status.FAILED);
job2Try1.setJobType(regType1Localhost.getServiceType());
job2Try1.setProcessingHost(regType1Localhost.getHost());
serviceRegistry.updateJob(job2Try1);
updatedService1 = getUpdatedService(regType1Localhost);
updatedService2 = getUpdatedService(regType1Remotehost1);
updatedService3 = getUpdatedService(regType1Remotehost2);
Assert.assertEquals(ServiceState.ERROR, updatedService1.getServiceState());
Assert.assertEquals(ServiceState.NORMAL, updatedService2.getServiceState());
Assert.assertEquals(ServiceState.NORMAL, updatedService3.getServiceState());
// 2nd try for job 1, failed on remotehost1
job1Try2.setStatus(Status.FAILED);
job1Try2.setJobType(regType1Remotehost1.getServiceType());
job1Try2.setProcessingHost(regType1Remotehost1.getHost());
serviceRegistry.updateJob(job1Try2);
updatedService1 = getUpdatedService(regType1Localhost);
updatedService2 = getUpdatedService(regType1Remotehost1);
updatedService3 = getUpdatedService(regType1Remotehost2);
Assert.assertEquals(ServiceState.ERROR, updatedService1.getServiceState());
Assert.assertEquals(ServiceState.WARNING, updatedService2.getServiceState());
Assert.assertEquals(ServiceState.NORMAL, updatedService3.getServiceState());
updatedService2.getWarningStateTrigger();
Assert.assertEquals(0, updatedService2.getErrorStateTrigger());
// 2nd try for job 2, failed on remotehost1
job2Try2.setStatus(Status.FINISHED);
job2Try2.setJobType(regType1Remotehost1.getServiceType());
job2Try2.setProcessingHost(regType1Remotehost1.getHost());
serviceRegistry.updateJob(job2Try2);
updatedService1 = getUpdatedService(regType1Localhost);
updatedService2 = getUpdatedService(regType1Remotehost1);
updatedService3 = getUpdatedService(regType1Remotehost2);
Assert.assertEquals(ServiceState.ERROR, updatedService1.getServiceState());
Assert.assertEquals(ServiceState.NORMAL, updatedService2.getServiceState());
Assert.assertEquals(ServiceState.NORMAL, updatedService3.getServiceState());
Assert.assertEquals(0, updatedService2.getErrorStateTrigger());
// 3rd try for job 1, failed on remotehost2
job1Try3.setStatus(Status.FINISHED);
job1Try3.setJobType(regType1Remotehost2.getServiceType());
job1Try3.setProcessingHost(regType1Remotehost2.getHost());
serviceRegistry.updateJob(job1Try3);
updatedService1 = getUpdatedService(regType1Localhost);
updatedService2 = getUpdatedService(regType1Remotehost1);
updatedService3 = getUpdatedService(regType1Remotehost2);
Assert.assertEquals(ServiceState.ERROR, updatedService1.getServiceState());
Assert.assertEquals(ServiceState.NORMAL, updatedService2.getServiceState());
Assert.assertEquals(ServiceState.NORMAL, updatedService3.getServiceState());
Assert.assertEquals(0, updatedService3.getWarningStateTrigger());
Assert.assertEquals(0, updatedService2.getErrorStateTrigger());
// 3rd try for job2, failed on remotehost2
job2Try3.setStatus(Status.FAILED);
job2Try3.setJobType(regType1Remotehost2.getServiceType());
job2Try3.setProcessingHost(regType1Remotehost2.getHost());
serviceRegistry.updateJob(job2Try3);
updatedService1 = getUpdatedService(regType1Localhost);
updatedService2 = getUpdatedService(regType1Remotehost1);
updatedService3 = getUpdatedService(regType1Remotehost2);
Assert.assertEquals(ServiceState.WARNING, updatedService1.getServiceState());
Assert.assertEquals(ServiceState.NORMAL, updatedService2.getServiceState());
Assert.assertEquals(ServiceState.NORMAL, updatedService3.getServiceState());
// 4rd try for job1, failed on remotehost2
job1Try4.setStatus(Status.FAILED);
job1Try4.setJobType(regType1Remotehost2.getServiceType());
job1Try4.setProcessingHost(regType1Remotehost2.getHost());
serviceRegistry.updateJob(job1Try4);
updatedService1 = getUpdatedService(regType1Localhost);
updatedService2 = getUpdatedService(regType1Remotehost1);
updatedService3 = getUpdatedService(regType1Remotehost2);
Assert.assertEquals(ServiceState.NORMAL, updatedService1.getServiceState());
Assert.assertEquals(ServiceState.NORMAL, updatedService2.getServiceState());
Assert.assertEquals(ServiceState.NORMAL, updatedService3.getServiceState());
}
@Test
public void testScenarioOneJobManyServices() throws Exception {
Job jobTry1 = serviceRegistry.createJob(regType1Localhost.getHost(),
regType1Localhost.getServiceType(), OPERATION_NAME_1, null, null, true, null);
Job jobTry2 = serviceRegistry.createJob(regType1Localhost.getHost(),
regType1Localhost.getServiceType(), OPERATION_NAME_1, null, null, true, null);
Job jobTry3 = serviceRegistry.createJob(regType1Localhost.getHost(),
regType1Localhost.getServiceType(), OPERATION_NAME_1, null, null, true, null);
Job jobTry4 = serviceRegistry.createJob(regType1Localhost.getHost(),
regType1Localhost.getServiceType(), OPERATION_NAME_1, null, null, true, null);
ServiceRegistrationJpaImpl updatedService1;
ServiceRegistrationJpaImpl updatedService2;
ServiceRegistrationJpaImpl updatedService3;
// 1st try, failed on localhost
jobTry1.setStatus(Status.FAILED);
jobTry1.setJobType(regType1Localhost.getServiceType());
jobTry1.setProcessingHost(regType1Localhost.getHost());
jobTry1 = serviceRegistry.updateJob(jobTry1);
updatedService1 = (ServiceRegistrationJpaImpl) serviceRegistry.getServiceRegistration(JOB_TYPE_1,
regType1Localhost.getHost());
Assert.assertEquals(ServiceState.WARNING, updatedService1.getServiceState());
Assert.assertEquals(0, updatedService1.getErrorStateTrigger());
// 2nd try, failed on remotehost1
jobTry2.setStatus(Status.FAILED);
jobTry2.setJobType(regType1Remotehost1.getServiceType());
jobTry2.setProcessingHost(regType1Remotehost1.getHost());
jobTry2 = serviceRegistry.updateJob(jobTry2);
updatedService1 = getUpdatedService(regType1Localhost);
updatedService2 = getUpdatedService(regType1Remotehost1);
Assert.assertEquals(ServiceState.NORMAL, updatedService1.getServiceState());
Assert.assertEquals(ServiceState.NORMAL, updatedService2.getServiceState());
Assert.assertEquals(0, updatedService2.getWarningStateTrigger());
Assert.assertEquals(0, updatedService2.getErrorStateTrigger());
// 3rd try, failed on remotehost2
jobTry3.setStatus(Status.FAILED);
jobTry3.setJobType(regType1Remotehost2.getServiceType());
jobTry3.setProcessingHost(regType1Remotehost2.getHost());
jobTry3 = serviceRegistry.updateJob(jobTry3);
updatedService1 = getUpdatedService(regType1Localhost);
updatedService2 = getUpdatedService(regType1Remotehost1);
updatedService3 = getUpdatedService(regType1Remotehost2);
Assert.assertEquals(ServiceState.NORMAL, updatedService1.getServiceState());
Assert.assertEquals(ServiceState.NORMAL, updatedService2.getServiceState());
Assert.assertEquals(ServiceState.WARNING, updatedService3.getServiceState());
Assert.assertEquals(0, updatedService2.getErrorStateTrigger());
// 4th try, finished on localhost
jobTry4.setStatus(Status.FINISHED);
jobTry4.setJobType(regType1Localhost.getServiceType());
jobTry4.setProcessingHost(regType1Localhost.getHost());
jobTry4 = serviceRegistry.updateJob(jobTry4);
updatedService1 = getUpdatedService(regType1Localhost);
updatedService2 = getUpdatedService(regType1Remotehost1);
updatedService3 = getUpdatedService(regType1Remotehost2);
Assert.assertEquals(ServiceState.NORMAL, updatedService1.getServiceState());
Assert.assertEquals(ServiceState.NORMAL, updatedService2.getServiceState());
Assert.assertEquals(ServiceState.ERROR, updatedService3.getServiceState());
}
/**
* Gets the updated given service
*
* @param service
* The service to get
* @return The updated servce.
*/
private ServiceRegistrationJpaImpl getUpdatedService(ServiceRegistrationJpaImpl service) {
return (ServiceRegistrationJpaImpl) serviceRegistry.getServiceRegistration(service.getServiceType(),
service.getHost());
}
}