1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
|
/*-
* ============LICENSE_START=======================================================
* Copyright (C) 2016-2018 Ericsson. All rights reserved.
* Modifications Copyright (C) 2021-2022 Bell Canada. All rights reserved.
* Modifications Copyright (C) 2021 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=========================================================
*/
package org.onap.policy.apex.plugins.event.protocol.xml;
import java.io.ByteArrayInputStream;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map.Entry;
import javax.xml.XMLConstants;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.SchemaFactory;
import org.onap.policy.apex.plugins.event.protocol.xml.jaxb.ObjectFactory;
import org.onap.policy.apex.plugins.event.protocol.xml.jaxb.XMLApexEvent;
import org.onap.policy.apex.plugins.event.protocol.xml.jaxb.XMLApexEventData;
import org.onap.policy.apex.service.engine.event.ApexEvent;
import org.onap.policy.apex.service.engine.event.ApexEventException;
import org.onap.policy.apex.service.engine.event.ApexEventProtocolConverter;
import org.onap.policy.apex.service.engine.event.ApexEventRuntimeException;
import org.onap.policy.apex.service.parameters.eventprotocol.EventProtocolParameters;
import org.onap.policy.common.utils.resources.ResourceUtils;
import org.xml.sax.SAXException;
/**
* The Class Apex2XMLEventConverter converts {@link ApexEvent} instances into string instances of {@link XMLApexEvent}
* that are XML representations of Apex events defined in JAXB.
*
* @author Liam Fallon (liam.fallon@ericsson.com)
*/
public final class Apex2XmlEventConverter implements ApexEventProtocolConverter {
private static final String MODEL_SCHEMA_NAME = "xml/apex-event.xsd";
// XML Unmarshaller and marshaller and object factory for events
private Unmarshaller unmarshaller;
private Marshaller marshaller;
private ObjectFactory objectFactory = new ObjectFactory();
/**
* Constructor to create the Apex to XML converter.
*
* @throws ApexEventException the apex event exception
*/
public Apex2XmlEventConverter() throws ApexEventException {
try {
final var schemaUrl = ResourceUtils.getUrlResource(MODEL_SCHEMA_NAME);
final var apexEventSchema =
SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI).newSchema(schemaUrl);
final var jaxbContext = JAXBContext.newInstance(XMLApexEvent.class);
// Set up the unmarshaller to carry out validation
unmarshaller = jaxbContext.createUnmarshaller();
unmarshaller.setEventHandler(new javax.xml.bind.helpers.DefaultValidationEventHandler());
unmarshaller.setSchema(apexEventSchema);
// Set up the marshaller
marshaller = jaxbContext.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.setSchema(apexEventSchema);
} catch (JAXBException | SAXException e) {
throw new ApexEventException("Unable to set up marshalling and unmarshalling for XML events", e);
}
}
/**
* {@inheritDoc}.
*/
@Override
public void init(final EventProtocolParameters parameters) {
// No initialization necessary on this class
}
/**
* {@inheritDoc}.
*/
@Override
public List<ApexEvent> toApexEvent(final String eventName, final Object eventObject) throws ApexEventException {
// Check the XML event
if (eventObject == null) {
throw new ApexEventException("event processing failed, XML event is null");
}
// Cast the event to a string, if our conversion is correctly configured, this cast should always work
String xmlEventString = null;
try {
xmlEventString = (String) eventObject;
} catch (final Exception e) {
final String errorMessage = "error converting event \"" + eventObject + "\" to a string";
throw new ApexEventRuntimeException(errorMessage, e);
}
// The XML event
XMLApexEvent xmlApexEvent = null;
// Use JAXB to read and verify the event from the XML string
try {
final var source = new StreamSource(new ByteArrayInputStream(xmlEventString.getBytes()));
final JAXBElement<XMLApexEvent> rootElement = unmarshaller.unmarshal(source, XMLApexEvent.class);
xmlApexEvent = rootElement.getValue();
} catch (final JAXBException e) {
throw new ApexEventException("Unable to unmarshal Apex XML event\n" + xmlEventString, e);
}
// Create the Apex event
// FIXME: Introduce new AxEvent field for APEX to Xml conversion
final var apexEvent = new ApexEvent(xmlApexEvent.getName(), xmlApexEvent.getVersion(),
xmlApexEvent.getNameSpace(), xmlApexEvent.getSource(), xmlApexEvent.getTarget(), "");
// Set the data on the apex event
for (final XMLApexEventData xmlData : xmlApexEvent.getData()) {
apexEvent.put(xmlData.getKey(), xmlData.getValue());
}
// Return the event in a single element
final ArrayList<ApexEvent> eventList = new ArrayList<>();
eventList.add(apexEvent);
return eventList;
}
/**
* {@inheritDoc}.
*/
@Override
public String fromApexEvent(final ApexEvent apexEvent) throws ApexEventException {
// Check the Apex event
if (apexEvent == null) {
throw new ApexEventException("event processing failed, Apex event is null");
}
// Get the Apex event data
final List<XMLApexEventData> xmlDataList = new ArrayList<>();
try {
for (final Entry<String, Object> apexDataEntry : apexEvent.entrySet()) {
// Add an XML event data item
if (apexDataEntry.getValue() != null) {
xmlDataList.add(new XMLApexEventData(apexDataEntry.getKey(), apexDataEntry.getValue().toString()));
} else {
xmlDataList.add(new XMLApexEventData(apexDataEntry.getKey(), ""));
}
}
} catch (final Exception e) {
throw new ApexEventException("Unable to transfer Apex event data to XML\n" + apexEvent, e);
}
// Create the XML event
final var xmlApexEvent = new XMLApexEvent(apexEvent.getName(), apexEvent.getVersion(),
apexEvent.getNameSpace(), apexEvent.getSource(), apexEvent.getTarget(), xmlDataList);
// Write the event into a DOM document
try {
// Marshal the event into XML
final var writer = new StringWriter();
marshaller.marshal(objectFactory.createXmlApexEvent(xmlApexEvent), writer);
// Return the event as XML in a string
return writer.toString();
} catch (final JAXBException e) {
throw new ApexEventException("Unable to unmarshal Apex event to XML\n" + apexEvent, e);
}
}
}
|