2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6 * ================================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * ============LICENSE_END=========================================================
21 package org.onap.dmaap.dbcapi.model;
23 import com.google.common.base.Objects;
24 import java.nio.charset.StandardCharsets;
25 import java.util.ArrayList;
26 import java.util.Date;
27 import java.util.List;
29 import org.json.simple.*;
30 import org.json.simple.parser.*;
31 import javax.xml.bind.annotation.XmlRootElement;
34 import org.onap.dmaap.dbcapi.util.DmaapConfig;
36 import io.swagger.annotations.ApiModelProperty;
38 import org.onap.dmaap.dbcapi.service.DmaapService;
39 import org.onap.dmaap.dbcapi.service.TopicService;
43 public class Topic extends DmaapObject {
45 @ApiModelProperty( value="Fully Qualified Topic Name constructed by dbcapi, following the rules for `fqtnStyle`")
47 @ApiModelProperty( value="the short name used by humans, and utilized to construct the `FQTN`")
48 private String topicName;
49 @ApiModelProperty( value="a description of what this Topic is used for")
50 private String topicDescription;
51 private String tnxEnabled;
52 @ApiModelProperty( value="a label used to identify who requested this `Topic` to be provisioned. In the future this "
53 + "may be an AAF Identity.")
55 @ApiModelProperty( value="a reference to an identifier that describes a data format used for this `Topic`")
56 private String formatUuid;
57 @ApiModelProperty( value="An indicator for how this `Topic` should be replicated when there are more than one `MR_Cluster` instances")
58 private ReplicationType replicationCase;
59 @ApiModelProperty( value="the URL of an outside MR instance")
60 private String globalMrURL; // optional: URL of global MR to replicate to/from
61 @ApiModelProperty( value="the construction rule for the `fqtn` field")
62 private FqtnType fqtnStyle;
63 @ApiModelProperty( value="a hook for any versioning needed for managing a `Topic` over time")
64 private String version;
65 @ApiModelProperty( value="the kafka attribute for specifying the number of partitions")
66 private String partitionCount;
67 @ApiModelProperty( value="the kafka attribute for specifying replication within an `MR_Cluster` instance")
68 private String replicationCount;
69 @ApiModelProperty( value="a value generated by dbcapi, this AAF Role has permission to publish to this `Topic`")
70 private String publisherRole;
71 @ApiModelProperty( value="a value generated by dbcapi, this AAF Role has permission to subscribe to this `Topic`")
72 private String subscriberRole;
74 @ApiModelProperty( value="an array of `MR_Client` objects associated to this `Topic`")
75 private List<MR_Client> clients;
79 private static Dmaap dmaap = new DmaapService().getDmaap();
81 private static String defaultPartitionCount;
82 private static String defaultReplicationCount;
84 // during unit testing, discovered that presence of dots in some values
85 // creates an unplanned topic namespace as we compose the FQTN.
86 // this may create sensitivity (i.e. 403) for subsequent creation of AAF perms, so best to not allow it
87 private static String removeDots( String source, String def ) {
88 if ( source == null || source.isEmpty()) {
91 return source.replaceAll("\\.", "_");
94 // utility function to generate the FQTN of a topic
95 public String genFqtn( ) {
96 DmaapConfig dc = (DmaapConfig)DmaapConfig.getConfig();
97 String projectId = dc.getProperty("MR.projectID", "99999");
98 CharSequence signal = ".";
100 if ( this.getTopicName().contains( signal )) {
101 // presence of a dot indicates the name is already fully qualified
102 ret = this.getTopicName();
104 // these vars may not contain dots
105 String p = removeDots( projectId, "90909");
106 String v = removeDots( this.getVersion(), "v1");
107 switch( this.getFqtnStyle() ) {
108 case FQTN_PROJECTID_VERSION_FORMAT:
110 ret = dmaap.getTopicNsRoot() + "." + dmaap.getDmaapName() + "." + p + "-" + this.getTopicName() + "-" + v;
113 case FQTN_PROJECTID_FORMAT:
115 ret = dmaap.getTopicNsRoot() + "." + dmaap.getDmaapName() + "." + p + "-" + this.getTopicName();
118 case FQTN_LEGACY_FORMAT:
119 default: // for backwards compatibility
120 ret = dmaap.getTopicNsRoot() + "." + dmaap.getDmaapName() + "." + this.getTopicName();
134 this.clients = new ArrayList<>();
135 this.lastMod = new Date();
136 this.replicationCase = ReplicationType.Validator("none");
138 logger.debug( "Topic constructor " + this.lastMod );
140 public Topic(String fqtn, String topicName, String topicDescription,
141 String tnxEnabled, String owner) {
144 this.topicName = topicName;
145 this.topicDescription = topicDescription;
146 this.tnxEnabled = tnxEnabled;
150 logger.debug( "Topic constructor w args " + this.getLastMod() );
153 public Topic init() {
154 DmaapConfig p = (DmaapConfig)DmaapConfig.getConfig();
156 defaultPartitionCount = p.getProperty( "MR.partitionCount", "2");
157 defaultReplicationCount = p.getProperty( "MR.replicationCount", "1");
159 this.setStatus( DmaapObject_Status.NEW );
160 this.replicationCase = ReplicationType.Validator("none");
161 this.fqtnStyle = FqtnType.Validator("none");
162 this.setPartitionCount( defaultPartitionCount );
163 this.setReplicationCount( defaultReplicationCount );
168 // expects a String in JSON format, with known fields to populate Topic object
169 public Topic ( String json ) {
170 JSONParser parser = new JSONParser();
173 jsonObj = (JSONObject) parser.parse( json );
174 } catch ( ParseException pe ) {
175 logger.error( "Error parsing provisioning data: " + json );
176 this.setStatus( DmaapObject_Status.INVALID );
179 this.setFqtn( (String) jsonObj.get( "fqtn" ) );
180 this.setTopicName( (String) jsonObj.get( "topicName" ) );
181 this.setTopicDescription( (String) jsonObj.get( "topicDescription" ));
182 this.setOwner( (String) jsonObj.get( "owner" ) );
183 this.setStatus( (String) jsonObj.get( "status" ) );
184 this.setReplicationCase( ReplicationType.Validator( (String) jsonObj.get( "replicationCase" ) ));
185 this.setFqtnStyle( FqtnType.Validator( (String) jsonObj.get( "fqtnStyle" ) ) );
186 this.setPartitionCount( (String) jsonObj.get("partitionCount"));
189 public String getFqtn() {
192 public void setFqtn(String fqtn) {
195 public String getTopicName() {
198 public void setTopicName(String topicName) {
199 this.topicName = topicName;
201 public String getTopicDescription() {
202 return topicDescription;
204 public void setTopicDescription(String topicDescription) {
205 this.topicDescription = topicDescription;
208 public String getTnxEnabled() {
211 public void setTnxEnabled(String tnxEnabled) {
212 this.tnxEnabled = tnxEnabled;
214 public String getOwner() {
217 public void setOwner(String owner) {
220 public String getPartitionCount() {
221 return partitionCount;
223 public void setPartitionCount(String partitions) {
224 this.partitionCount = partitions;
226 public String getReplicationCount() {
227 return replicationCount;
229 public void setReplicationCount(String replicationCount) {
230 this.replicationCount = replicationCount;
234 public void setClients(List<MR_Client> clients) {
235 this.clients = clients;
238 public List<MR_Client> getClients() {
242 @ApiModelProperty( hidden=true )
243 public int getNumClients() {
244 if ( this.clients == null ) {
247 return this.clients.size();
253 public String getFormatUuid() {
259 public void setFormatUuid(String formatUuid) {
260 this.formatUuid = formatUuid;
264 public ReplicationType getReplicationCase() {
265 return replicationCase;
269 public void setReplicationCase(ReplicationType t) {
270 this.replicationCase = t;
272 public FqtnType getFqtnStyle() {
277 public void setFqtnStyle(FqtnType t) {
281 public String getGlobalMrURL() {
287 public void setGlobalMrURL(String globalMrURL) {
288 this.globalMrURL = globalMrURL;
293 public String getVersion() {
299 public void setVersion(String version) {
300 this.version = version;
305 public String getPublisherRole() {
306 return publisherRole;
308 public void setPublisherRole(String publisherRole) {
309 this.publisherRole = publisherRole;
311 public String getSubscriberRole() {
312 return subscriberRole;
314 public void setSubscriberRole(String subscriberRole) {
315 this.subscriberRole = subscriberRole;
317 public String toProvJSON() {
318 StringBuilder str = new StringBuilder();
319 str.append("{ \"topicName\": \"");
320 str.append( this.getFqtn() );
321 str.append( "\", \"topicDescription\": \"");
322 str.append( this.getTopicDescription());
323 str.append( "\", \"partitionCount\": \"");
324 str.append( this.getPartitionCount());
325 str.append( "\", \"replicationCount\": \"");
326 str.append( this.getReplicationCount());
327 str.append( "\" } ");
329 logger.info( str.toString() );
330 return str.toString();
332 @ApiModelProperty( hidden=true )
333 public byte[] getBytes() {
334 return toProvJSON().getBytes(StandardCharsets.UTF_8);
339 public boolean equals(Object o) {
343 if (o == null || getClass() != o.getClass()) {
346 Topic topic = (Topic) o;
347 return Objects.equal(fqtn, topic.fqtn) &&
348 Objects.equal(topicName, topic.topicName) &&
349 Objects.equal(tnxEnabled, topic.tnxEnabled) &&
350 Objects.equal(owner, topic.owner);
354 public int hashCode() {
355 return Objects.hashCode(fqtn, topicName, tnxEnabled, owner);