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 io.swagger.annotations.ApiModelProperty;
25 import java.nio.charset.StandardCharsets;
26 import java.util.ArrayList;
27 import java.util.Date;
28 import java.util.List;
29 import javax.xml.bind.annotation.XmlRootElement;
30 import org.json.simple.JSONObject;
31 import org.json.simple.parser.JSONParser;
32 import org.json.simple.parser.ParseException;
33 import org.onap.dmaap.dbcapi.service.DmaapService;
34 import org.onap.dmaap.dbcapi.util.DmaapConfig;
38 public class Topic extends DmaapObject {
40 @ApiModelProperty( value="Fully Qualified Topic Name constructed by dbcapi, following the rules for `fqtnStyle`")
42 @ApiModelProperty( value="the short name used by humans, and utilized to construct the `FQTN`")
43 private String topicName;
44 @ApiModelProperty( value="a description of what this Topic is used for")
45 private String topicDescription;
46 private String tnxEnabled;
47 @ApiModelProperty( value="a label used to identify who requested this `Topic` to be provisioned. In the future this "
48 + "may be an AAF Identity.")
50 @ApiModelProperty( value="a reference to an identifier that describes a data format used for this `Topic`")
51 private String formatUuid;
52 @ApiModelProperty( value="An indicator for how this `Topic` should be replicated when there are more than one `MR_Cluster` instances")
53 private ReplicationType replicationCase;
54 @ApiModelProperty( value="the URL of an outside MR instance")
55 private String globalMrURL; // optional: URL of global MR to replicate to/from
56 @ApiModelProperty( value="the construction rule for the `fqtn` field")
57 private FqtnType fqtnStyle;
58 @ApiModelProperty( value="a hook for any versioning needed for managing a `Topic` over time")
59 private String version;
60 @ApiModelProperty( value="the kafka attribute for specifying the number of partitions")
61 private String partitionCount;
62 @ApiModelProperty( value="the kafka attribute for specifying replication within an `MR_Cluster` instance")
63 private String replicationCount;
64 @ApiModelProperty( value="a value generated by dbcapi, this AAF Role has permission to publish to this `Topic`")
65 private String publisherRole;
66 @ApiModelProperty( value="a value generated by dbcapi, this AAF Role has permission to subscribe to this `Topic`")
67 private String subscriberRole;
69 @ApiModelProperty( value="an array of `MR_Client` objects associated to this `Topic`")
70 private List<MR_Client> clients;
74 private static Dmaap dmaap = new DmaapService().getDmaap();
76 private static String defaultPartitionCount;
77 private static String defaultReplicationCount;
79 // during unit testing, discovered that presence of dots in some values
80 // creates an unplanned topic namespace as we compose the FQTN.
81 // this may create sensitivity (i.e. 403) for subsequent creation of AAF perms, so best to not allow it
82 private static String removeDots( String source, String def ) {
83 if ( source == null || source.isEmpty()) {
86 return source.replaceAll("\\.", "_");
89 // utility function to generate the FQTN of a topic
90 public String genFqtn( ) {
91 DmaapConfig dc = (DmaapConfig)DmaapConfig.getConfig();
92 String projectId = dc.getProperty("MR.projectID", "99999");
93 CharSequence signal = ".";
95 if ( this.getTopicName().contains( signal )) {
96 // presence of a dot indicates the name is already fully qualified
97 ret = this.getTopicName();
99 // these vars may not contain dots
100 String p = removeDots( projectId, "90909");
101 String v = removeDots( this.getVersion(), "v1");
102 switch( this.getFqtnStyle() ) {
103 case FQTN_PROJECTID_VERSION_FORMAT:
105 ret = dmaap.getTopicNsRoot() + "." + dmaap.getDmaapName() + "." + p + "-" + this.getTopicName() + "-" + v;
108 case FQTN_PROJECTID_FORMAT:
110 ret = dmaap.getTopicNsRoot() + "." + dmaap.getDmaapName() + "." + p + "-" + this.getTopicName();
113 case FQTN_LEGACY_FORMAT:
114 default: // for backwards compatibility
115 ret = dmaap.getTopicNsRoot() + "." + dmaap.getDmaapName() + "." + this.getTopicName();
129 this.clients = new ArrayList<>();
130 this.lastMod = new Date();
131 this.replicationCase = ReplicationType.Validator("none");
133 logger.debug( "Topic constructor " + this.lastMod );
135 public Topic(String fqtn, String topicName, String topicDescription,
136 String tnxEnabled, String owner) {
139 this.topicName = topicName;
140 this.topicDescription = topicDescription;
141 this.tnxEnabled = tnxEnabled;
145 logger.debug( "Topic constructor w args " + this.getLastMod() );
148 public Topic init() {
149 DmaapConfig p = (DmaapConfig)DmaapConfig.getConfig();
151 defaultPartitionCount = p.getProperty( "MR.partitionCount", "2");
152 defaultReplicationCount = p.getProperty( "MR.replicationCount", "1");
154 this.setStatus( DmaapObject_Status.NEW );
155 this.replicationCase = ReplicationType.Validator("none");
156 this.fqtnStyle = FqtnType.Validator("none");
157 this.setPartitionCount( defaultPartitionCount );
158 this.setReplicationCount( defaultReplicationCount );
163 // expects a String in JSON format, with known fields to populate Topic object
164 public Topic ( String json ) {
165 JSONParser parser = new JSONParser();
168 jsonObj = (JSONObject) parser.parse( json );
169 } catch ( ParseException pe ) {
170 logger.error( "Error parsing provisioning data: " + json );
171 this.setStatus( DmaapObject_Status.INVALID );
174 this.setFqtn( (String) jsonObj.get( "fqtn" ) );
175 this.setTopicName( (String) jsonObj.get( "topicName" ) );
176 this.setTopicDescription( (String) jsonObj.get( "topicDescription" ));
177 this.setOwner( (String) jsonObj.get( "owner" ) );
178 this.setStatus( (String) jsonObj.get( "status" ) );
179 this.setReplicationCase( ReplicationType.Validator( (String) jsonObj.get( "replicationCase" ) ));
180 this.setFqtnStyle( FqtnType.Validator( (String) jsonObj.get( "fqtnStyle" ) ) );
181 this.setPartitionCount( (String) jsonObj.get("partitionCount"));
184 public String getFqtn() {
187 public void setFqtn(String fqtn) {
190 public String getTopicName() {
193 public void setTopicName(String topicName) {
194 this.topicName = topicName;
196 public String getTopicDescription() {
197 return topicDescription;
199 public void setTopicDescription(String topicDescription) {
200 this.topicDescription = topicDescription;
203 public String getTnxEnabled() {
206 public void setTnxEnabled(String tnxEnabled) {
207 this.tnxEnabled = tnxEnabled;
209 public String getOwner() {
212 public void setOwner(String owner) {
215 public String getPartitionCount() {
216 return partitionCount;
218 public void setPartitionCount(String partitions) {
219 this.partitionCount = partitions;
221 public String getReplicationCount() {
222 return replicationCount;
224 public void setReplicationCount(String replicationCount) {
225 this.replicationCount = replicationCount;
229 public void setClients(List<MR_Client> clients) {
230 this.clients = clients;
233 public List<MR_Client> getClients() {
237 @ApiModelProperty( hidden=true )
238 public int getNumClients() {
239 if ( this.clients == null ) {
242 return this.clients.size();
248 public String getFormatUuid() {
254 public void setFormatUuid(String formatUuid) {
255 this.formatUuid = formatUuid;
259 public ReplicationType getReplicationCase() {
260 return replicationCase;
264 public void setReplicationCase(ReplicationType t) {
265 this.replicationCase = t;
267 public FqtnType getFqtnStyle() {
272 public void setFqtnStyle(FqtnType t) {
276 public String getGlobalMrURL() {
282 public void setGlobalMrURL(String globalMrURL) {
283 this.globalMrURL = globalMrURL;
288 public String getVersion() {
294 public void setVersion(String version) {
295 this.version = version;
300 public String getPublisherRole() {
301 return publisherRole;
303 public void setPublisherRole(String publisherRole) {
304 this.publisherRole = publisherRole;
306 public String getSubscriberRole() {
307 return subscriberRole;
309 public void setSubscriberRole(String subscriberRole) {
310 this.subscriberRole = subscriberRole;
312 public String toProvJSON() {
313 StringBuilder str = new StringBuilder();
314 str.append("{ \"topicName\": \"");
315 str.append( this.getFqtn() );
316 str.append( "\", \"topicDescription\": \"");
317 str.append( this.getTopicDescription());
318 str.append( "\", \"partitionCount\": \"");
319 str.append( this.getPartitionCount());
320 str.append( "\", \"replicationCount\": \"");
321 str.append( this.getReplicationCount());
322 str.append( "\" } ");
324 logger.info( str.toString() );
325 return str.toString();
327 @ApiModelProperty( hidden=true )
328 public byte[] getBytes() {
329 return toProvJSON().getBytes(StandardCharsets.UTF_8);
334 public boolean equals(Object o) {
338 if (o == null || getClass() != o.getClass()) {
341 Topic topic = (Topic) o;
342 return Objects.equal(fqtn, topic.fqtn) &&
343 Objects.equal(topicName, topic.topicName) &&
344 Objects.equal(tnxEnabled, topic.tnxEnabled) &&
345 Objects.equal(owner, topic.owner);
349 public int hashCode() {
350 return Objects.hashCode(fqtn, topicName, tnxEnabled, owner);