Let's take a look at the Tuscany introduction and briefly understand what Tuscany is.
The basic concepts of SCA and the specific content of SCA specifications are not within the scope of this article. Interested readers can learn the relevant content through some relevant documents, which is also the basis for reading this article. Next, we will first introduce the Tuscany framework.
Tuscany is an open-source project of Apache. It is an SCA framework developed by the SOA Standardization Organization (osoa) jointly established by IBM, Oracle, sap, and other vendors. It is a touchstone for open-source SCA, it is also one of the most mature SCA frameworks in the Open Source Field.
Tuscany is an open-source SCA framework model and is the basic architecture for SOA.
What is SCA?
SCA provides a programming model for building SOA-based applications and solutions. It is based on the concept that it provides business functions as a series of services, and the solutions assembled by these services to meet specific business needs. These combined applications include both specific services newly created for the application and business logic derived from existing systems and applications, which are reused as part of the Composition component. SCA provides a model for both service composition and service component creation, including reusing existing application functions in SCA group composition components.
The basic component of SCA is component, which is the component unit of SCA. A component is composed of an implemented implementation instance. In this component, the implementation is a program code snippet that provides business functions. This service is provided as a service and used by other components. Implementation may depend on the services provided by other components, which are called reference ). The implementation can have a configurable property, which is a data value that can affect business function operations. The component is configured and implemented by providing the attribute value and wire to reference services provided by other components.
Let's take a look at the functions implemented by SCA through examples!
Let's take a look at the release of a basic example of addition, subtraction, multiplication, division. This is the official Tuscany example.
Define an interface to implement basic calculator Functions
Defines the calculatorservice interface to implement basic addition, subtraction, multiplication, division
public interface CalculatorService { double add(double n1, double n2); double subtract(double n1, double n2); double multiply(double n1, double n2); double divide(double n1, double n2);}
The implementation class calls the corresponding interfaces addservice, divideservice, multiplyservice, and subtractservice respectively.
The corresponding interfaces are called in calculatorserviceimpl.
public class CalculatorServiceImpl implements CalculatorService { private AddService addService; private SubtractService subtractService; private MultiplyService multiplyService; private DivideService divideService; @Reference public void setAddService(AddService addService) { this.addService = addService; } @Reference public void setSubtractService(SubtractService subtractService) { this.subtractService = subtractService; } @Reference public void setDivideService(DivideService divideService) { this.divideService = divideService; } @Reference public void setMultiplyService(MultiplyService multiplyService) { this.multiplyService = multiplyService; } public double add(double n1, double n2) { return addService.add(n1, n2); } public double subtract(double n1, double n2) { return subtractService.subtract(n1, n2); } public double multiply(double n1, double n2) { return multiplyService.multiply(n1, n2); } public double divide(double n1, double n2) { return divideService.divide(n1, n2); }}
Use @ reference for injection. Let's take a look at the function definitions of each interface.
Addservice
public interface AddService { double add(double n1, double n2);}
Addserviceimpl
public class AddServiceImpl implements AddService { public double add(double n1, double n2) { Logger logger = Logger.getLogger("calculator"); logger.log(Level.FINEST, "Adding " + n1 + " and " + n2); return n1 + n2; }}
Divideservice
public interface DivideService { double divide(double n1, double n2);}
Divideserviceimpl
public class DivideServiceImpl implements DivideService { public double divide(double n1, double n2) { Logger logger = Logger.getLogger("calculator"); logger.log(Level.FINEST, "Dividing " + n1 + " with " + n2); return n1 / n2; }}
Multiplyservice
public interface MultiplyService { double multiply(double n1, double n2);}
Multiplyserviceimpl
public class MultiplyServiceImpl implements MultiplyService { public double multiply(double n1, double n2) { Logger logger = Logger.getLogger("calculator"); logger.log(Level.FINEST, "Multiplying " + n1 + " with " + n2); return n1 * n2; }}
Subtractservice
public interface SubtractService { double subtract(double n1, double n2);}
Subtractserviceimpl
public class SubtractServiceImpl implements SubtractService { public double subtract(double n1, double n2) { Logger logger = Logger.getLogger("calculator"); logger.log(Level.FINEST, "Subtracting " + n1 + " from " + n2); return n1 - n2; }}
View the code called by the client
SCANodeFactory factory = SCANodeFactory.newInstance(); SCANode node = factory.createSCANodeFromClassLoader("Calculator.composite", CalculatorClient.class.getClassLoader()); node.start(); CalculatorService calculatorService = ((SCAClient)node).getService(CalculatorService.class, "CalculatorServiceComponent"); // Calculate System.out.println("3 + 2=" + calculatorService.add(3, 2)); System.out.println("3 - 2=" + calculatorService.subtract(3, 2)); System.out.println("3 * 2=" + calculatorService.multiply(3, 2)); System.out.println("3 / 2=" + calculatorService.divide(3, 2)); node.stop();
The program reads the calculator. Composite configuration file. This is the function implemented by the core configuration file.
Let's take a look at the definition in the configuration file.
<composite xmlns="http://www.osoa.org/xmlns/sca/1.0" targetNamespace="http://sample" xmlns:sample="http://sample" name="Calculator"> <component name="CalculatorServiceComponent"><implementation.java class="calculator.CalculatorServiceImpl"/> <reference name="addService" target="AddServiceComponent" /> <reference name="subtractService" target="SubtractServiceComponent" /> <reference name="multiplyService" target="MultiplyServiceComponent" /> <reference name="divideService" target="DivideServiceComponent" /> </component> <component name="AddServiceComponent"> <implementation.java class="calculator.AddServiceImpl"/> </component> <component name="SubtractServiceComponent"> <implementation.java class="calculator.SubtractServiceImpl"/> </component> <component name="MultiplyServiceComponent"> <implementation.java class="calculator.MultiplyServiceImpl"/> </component> <component name="DivideServiceComponent"> <implementation.java class="calculator.DivideServiceImpl"/> </component></composite>
The published service is named calculatorservicecomponent.
You can find the corresponding service name through the client calling program.
Calculatorservice = (scaclient) node). getservice (calculatorservice. class, "calculatorservicecomponent ");
Then call the corresponding method
The program execution result is as follows:
2011-10-31 15:44:14 Org. apache. tuscany. SCA. node. impl. nodeimpl <init> information: Creating node: calculator. composite2011-10-31 15:44:16 Org. apache. tuscany. SCA. node. impl. nodeimpl implements Enode information: loading contribution: file:/D:/Java/workspace/SCA/calculator/target/classes/2011-10-31 15:44:18 Org. apache. tuscany. SCA. node. impl. nodeimpl start information: Starting node: calculator. composite3 + 2 = 5.02011-10-31 15:44:18 Org. apache. tuscany. SCA. node. impl. nodeimpl stop information: Stopping node: calculator. composite3-2 = 1.03*2 = 6.03/2 = 1.5
You can also call the remote implementation using the CORBA method, corresponding to the server configuration, to find the local service published on port 5080.
<component name="CalculatorServiceComponent"><implementation.java class="calculator.CalculatorServiceImpl"/><reference name="addService"> <tuscany:binding.corba uri="corbaname::localhost:5080#CalculatorCORBAService"/></reference> <reference name="subtractService"> <tuscany:binding.corba uri="corbaname::localhost:5080#CalculatorCORBAService"/> </reference> <reference name="multiplyService"> <tuscany:binding.corba uri="corbaname::localhost:5080#CalculatorCORBAService"/> </reference> <reference name="divideService"> <tuscany:binding.corba uri="corbaname::localhost:5080#CalculatorCORBAService"/> </reference> </component>
The code implementation in the test case is as follows:
public class CalculatorCORBAReferenceTestCase extends TestCase { private SCADomain scaDomain; private CalculatorService calculatorService; private TransientNameServer server; private void bindObject(String name, org.omg.CORBA.Object object) throws Exception { ORB orb = server.getORB(); org.omg.CORBA.Object objRef = orb.resolve_initial_references("NameService"); NamingContext ncRef = NamingContextHelper.narrow(objRef); NameComponent nc = new NameComponent(name, ""); NameComponent path[] = {nc}; ncRef.rebind(path, object); } @BeforeClass protected void setUp() throws Exception { // create name service server = new TransientNameServer("localhost", 5080, TransientNameService.DEFAULT_SERVICE_NAME); Thread t = server.start(); if (t == null) { Assert.fail("The naming server cannot be started"); } else { // create CORBA object which will be accessible by SCA CORBA binding bindObject("CalculatorCORBAService", new CalculatorCORBAServant()); scaDomain = SCADomain.newInstance("CalculatorCORBAReference.composite"); calculatorService = scaDomain.getService(CalculatorService.class, "CalculatorServiceComponent"); } } @AfterClass protected void tearDown() throws Exception { scaDomain.close(); server.stop(); } @Test public void testCalculator() throws Exception { assertEquals(5.0, calculatorService.add(3, 2)); assertEquals(1.0, calculatorService.subtract(3, 2)); assertEquals(6.0, calculatorService.multiply(3, 2)); assertEquals(1.5, calculatorService.divide(3, 2)); }}
Services are the core of SOA. They represent reusable code units that can be combined into applications or business processes.
Osgi explicitly uses Java as the target platform and provides a modular framework for creating components and runtime containers for running these components. Osgi itself does not provide the functional features that can be directly used for SOA services.
With SCA, you can build functional units or components in different programming languages and expose them as services through soap, JMS, RMI, rest, or other protocols.
In addition, these components can be connected internally to Form high-level services or combinations at that time. Services can be run in a distributed manner and managed as virtual clouds.