/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.
*/
package org.apache.tuscany.sca.vtest.javaapi.annotations.service;
import static org.junit.Assert.fail;
import junit.framework.Assert;
import org.apache.tuscany.sca.vtest.javaapi.annotations.service.impl.AObject;
import org.apache.tuscany.sca.vtest.javaapi.annotations.service.impl.FServiceImpl2;
import org.apache.tuscany.sca.vtest.utilities.ServiceFinder;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
/**
* This test class tests the Service annotation described in section 1.2.1
* including 1.3.1, 1.8.1, 1.8.3, 1.8.6, 1.8.15 and 1.8.17
* but not..
*
Lines 1531 to 1534
*/
public class ServiceAnnotationTestCase {
protected static String compositeName = "service.composite";
protected static AService aService = null;
protected static BService bService = null;
protected static BService bService1 = null;
protected static HService hService = null;
protected static IService iService = null;
@BeforeClass
public static void init() throws Exception {
try {
System.out.println("Setting up");
ServiceFinder.init(compositeName);
aService = ServiceFinder.getService(AService.class, "AComponent");
bService = ServiceFinder.getService(BService.class, "BComponent");
bService1 = ServiceFinder.getService(BService.class, "BComponent1");
hService = ServiceFinder.getService(HService.class, "HComponent");
iService = ServiceFinder.getService(IService.class, "IComponent");
} catch (Exception ex) {
ex.printStackTrace();
}
}
@AfterClass
public static void destroy() throws Exception {
System.out.println("Cleaning up");
ServiceFinder.cleanup();
}
/**
* Line 215:
* As a Java interface
*
* Line 1622 to 1623:
* The
*
* @Service annotation type is used on a component implementation class to
* specify the SCA services offered by the implementation.
*/
@Test
public void atService1() throws Exception {
Assert.assertEquals("AService", aService.getName());
}
/**
* Line 216:
*
As a Java class
*
* Line 1631:
*
value – A shortcut for the case when the class provides only a
* single service interface.
*/
@Test
public void atService2() throws Exception {
Assert.assertEquals("BService", bService.getName());
}
/**
* Lines 222 to 224:
* A remotable service is defined using the "@Remotable" annotation on the
* Java interface that defines the service. Remotable services are intended
* to be used for coarse grained services, and the parameters are passed
* by-value.
*
* Lines 321 to 323:
* The "@Remotable" annotation on a Java interface indicates that the
* interface is designed to be used for remote communication. Remotable
* interfaces are intended to be used for coarse grained services.
* Operations parameters and return values are passed by-value.
*/
@Test
public void atService3() throws Exception {
AObject o = new AObject();
Assert.assertEquals("AService", aService.setAObject(o));
Assert.assertNull(o.aString);
}
/**
* Lines 227 to 242:
* A local service can only be called by clients that are deployed within
* the same address space as the component implementing the local service.
* ...
* The data exchange semantic for calls to local services is by-reference.
* ...
* Lines 996 to 1028:
* 1.8.1 "@AllowsPassByReference"
* ...
* Lines 1535 to 1540:
* Independent of whether the remotable service is called from outside of
* the composite that contains it or from another component in the same
* composite, the data exchange semantics are by-value.
* Implementations of remotable services may modify input data during or
* after an invocation and may modify return data after the invocation. If a
* remotable service is called locally or remotely, the SCA container is
* responsible for making sure that no modification of input data or
* post-invocation modifications to return data are seen by the caller.
*
* Test under Non-SCA <-> SCA
*
BService is local service to test by reference
* HService is remotable service to test "@AllowsPassByReference" at
* method level
* IService is remotable service to test "@AllowsPassByReference" at
* class level
*/
@Test
public void atService4() throws Exception {
AObject b = new AObject();
Assert.assertEquals("BService", bService.setAObject(b));
Assert.assertEquals("BService", b.aString);
AObject h1 = new AObject();
Assert.assertEquals("HService", hService.setAObject1(h1));
Assert.assertEquals("HService", h1.aString);
h1.aString = "atService4";
Assert.assertEquals("atService4", hService.getAObject1String());
AObject h2 = new AObject();
Assert.assertEquals("HService", hService.setAObject2(h2));
Assert.assertNull(h2.aString);
h2.aString = "atService4";
Assert.assertEquals("HService", hService.getAObject2String());
AObject h3 = hService.getAObject3();
h3.aString = "atService4";
Assert.assertEquals("HService", hService.getAObject3String());
AObject i1 = new AObject();
Assert.assertEquals("IService", iService.setAObject1(i1));
Assert.assertEquals("IService", i1.aString);
i1.aString = "atService4";
Assert.assertEquals("atService4", iService.getAObject1String());
AObject i2 = new AObject();
Assert.assertEquals("IService", iService.setAObject2(i2));
Assert.assertEquals("IService", i2.aString);
i2.aString = "atService4";
Assert.assertEquals("atService4", iService.getAObject2String());
AObject i3 = iService.getAObject3();
i3.aString = "atService4";
Assert.assertEquals("atService4", iService.getAObject3String());
}
/**
* Line 1624 to 1627:
* A class used as the implementation of a service is not required to have
* an "@Service" annotation. If a class has no "@Service" annotation, then
* the rules determining which services are offered and what interfaces
* those services have are determined by the specific implementation type.
*
*/
@Test
public void atService5() throws Exception {
CService cService = ServiceFinder.getService(CService.class, "CComponent");
Assert.assertEquals("CService", cService.getName());
}
/**
* Line 1623 to 1624:
* The class need not be declared as implementing all of the interfaces
* implied by the services, but all methods of the service interfaces must
* be present.
*
* Line 1629 to 1630:
*
interfaces – The value is an array of interface or class objects
* that should be exposed as services by this component.
*/
@Test
public void atService6() throws Exception {
DService1 dService1 = ServiceFinder.getService(DService1.class, "DComponent/DService1");
Assert.assertEquals("DService1", dService1.getName1());
DService2 dService2 = ServiceFinder.getService(DService2.class, "DComponent/DService2");
Assert.assertEquals("DService2", dService2.getName2());
try {
ServiceFinder.getService(DService3.class, "DComponent/DService3");
fail("Should have failed to get this service");
} catch (Exception e) {
// Expect an exception
}
}
/**
* Line 1635 to 1636:
* A "@Service" annotation with no attributes is meaningless, it is the same
* as not having the annotation there at all.
*/
@Test
public void atService7() throws Exception {
EService eService = ServiceFinder.getService(EService.class, "EComponent");
Assert.assertEquals("EService", eService.getName());
}
/**
* Line 1637 to 1638:
* The service names of the defined services default to the names of the
* interfaces or class, without the package name.
*/
@Test
public void atService8() throws Exception {
FService fService = ServiceFinder.getService(FService.class, "FComponent");
Assert.assertEquals("FService", fService.getName());
FServiceImpl2 fServiceImpl2 = ServiceFinder.getService(FServiceImpl2.class, "FComponent2");
Assert.assertEquals("FServiceImpl2", fServiceImpl2.getName());
fService = ServiceFinder.getService(FService.class, "FComponent2");
Assert.assertEquals("FServiceImpl2", fService.getName());
}
/**
* Line 1639 to 1641:
* If a Java implementation needs to realize two services with the same
* interface, then this is achieved through subclassing of the interface.
* The subinterface must not add any methods. Both interfaces are listed in
* the "@Service" annotation of the Java implementation class.
*/
@Test
public void atService9() throws Exception {
GService1 gService1 = ServiceFinder.getService(GService1.class, "GComponent/GService1");
GService2 gService2 = ServiceFinder.getService(GService2.class, "GComponent/GService2");
Assert.assertEquals("GService", gService1.getName());
Assert.assertEquals("GService1", gService1.getServiceName());
Assert.assertEquals("GService", gService2.getName());
Assert.assertEquals("GService2", gService2.getServiceName());
}
/**
* Lines 227 to 242:
* A local service can only be called by clients that are deployed within
* the same address space as the component implementing the local service.
* ...
* The data exchange semantic for calls to local services is by-reference.
* ...
* Lines 996 to 1028:
* 1.8.1 "@AllowsPassByReference"
* ...
* Lines 1535 to 1540:
* Independent of whether the remotable service is called from outside of
* the composite that contains it or from another component in the same
* composite, the data exchange semantics are by-value.
* Implementations of remotable services may modify input data during or
* after an invocation and may modify return data after the invocation. If a
* remotable service is called locally or remotely, the SCA container is
* responsible for making sure that no modification of input data or
* post-invocation modifications to return data are seen by the caller.
*
* Test under SCA <-> SCA
*
AService is remotable service to test by value
* CService is local service to test by-reference
* HService is remotable service to test "@AllowsPassByReference" at
* method level
* IService is remotable service to test "@AllowsPassByReference" at
* class level
*/
@Test
public void atService10() throws Exception {
Assert.assertEquals("None", bService1.testServices());
}
/**
* Lines 1095 to 1124:
* 1.8.3. "@ComponentName"
* ...
* The "@ComponentName" annotation type is used to annotate a Java class
* field or setter method that is used to inject the component name.
* ...
*/
@Test
public void atService11() throws Exception {
Assert.assertEquals("HComponent", hService.getComponentName());
Assert.assertNull(iService.getComponentName1());
Assert.assertEquals("IComponent", iService.getComponentName2());
}
/**
* Lines 1164 to 1187:
* 1.8.6. "@Context"
* ...
* The "@Context" annotation type is used to annotate a Java class field or
* a setter method that is used to inject a composite context for the
* component. The type of context to be injected is defined by the type of
* the Java class field or type of the setter method input argument, the
* type is either ComponentContext or RequestContext.
* ...
*
* HService - "@Context" is used to annotate setter methods
* IService - "@Context" is used to annotate class fields
*
*/
@Test
public void atService12() throws Exception {
Assert.assertEquals("HService", hService.getServiceName1());
Assert.assertEquals("HService", hService.getServiceName2());
Assert.assertEquals("IService", iService.getServiceName1());
Assert.assertEquals("IService", iService.getServiceName2());
}
}